DiamondLightSource/dodal

Standard way to define device once that is shared between multiple end statations

Open

#1.530 geöffnet am 15. Sept. 2025

Auf GitHub ansehen
 (21 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)Python (12 Forks)auto 404
DesignDeveloper Experiencedocumentationhelp wantedstandarisation

Repository-Metriken

Stars
 (4 Stars)
PR-Merge-Metriken
 (PR-Metriken ausstehend)

Beschreibung

It is common for branched beamlines to have shared components, e.g PGM is used by I06 and I06-1.

In dodal, we don't seem to have a standard way of doing this as of yet. At the moment, we have dodal/beamlines/i05.py, dodal/beamlines/i05_1.py and dodal/beamlines/beamline_specific_util/i05_shared.py. However, i05.py and i05_1.py both redefine the pgm which defeats the purpose were trying to achieve.

from dodal.beamline_specific_utils.i05_shared import pgm as i05_pgm

@device_factory()
def pgm() -> PGM:
    return i05_pgm()

In other situations, we have I09 defined DCM in two different places when it's the same device i09.py and i09_1.py.

This should be defined once in it's own module. This seems to be what I19 have done with i19_1.py, i19_2.py and i19_optics.py, though I think this is slightly different use case as this is a way for access control and has its own BlueAPI service. However, I believe all beamlines, if has shared endstations, should have devices defined once in a shared module. This way, we get BlueAPI to pull devices from beamline iXX and iXX_shared to be into a single environment e.g

worker:
    env:
      sources:
        - kind: planFunctions
          module: sm_bluesky.beamlines.i05.plans
        - kind: planFunctions
          module: sm_bluesky.common.plan_stubs
        - kind: planFunctions
          module: sm_bluesky.common.plans
        - kind: planFunctions
          module: dodal.plans
        - kind: dodal
          module: "dodal.beamlines.i05"
        - kind: dodal
          module: "dodal.beamlines.i05_shared"

I think we can also go further and maybe define a dodal/beamlines/core.py as well because almost every beamline defines Synchrotron device, we can remove this duplication.

Finally, as this makes beamlines more modular and we want to test using dodal connect iXX for a whole beamline, I suggest the following change be made to dodal connect:

We define some config in dodal e.g

_BEAMLINE_SHARED = {
    "i09": ["i09", "i09_1_shared", "i09_2_shared"]
    ...
}

This config defines the whole beamline so when running dodal connect i09, we get:

(venv) root ➜ /workspaces/dodal (fix_test_motor_limits_with_new_ophyd_async ✗) 
$ dodal connect i09 -s
====================================================================================================
Attempting connection to i09 (using dodal.beamlines.i09)
2 devices connected (sim mode):
        analyser_driver
        synchrotron
====================================================================================================
Attempting connection to i09_1_shared (using dodal.beamlines.i09_1_shared)
1 devices connected (sim mode):
        dcm
====================================================================================================
Attempting connection to i09_2_shared (using dodal.beamlines.i09_2_shared)
1 devices connected (sim mode):
        pgm

We can also add a flag to test the individual beamline only

(venv) root ➜ /workspaces/dodal (fix_test_motor_limits_with_new_ophyd_async ✗) 
$ dodal connect i09 -s -i
====================================================================================================
Attempting connection to i09 (using dodal.beamlines.i09)
2 devices connected (sim mode):
        analyser_driver
        synchrotron

Acceptance Criteria

  • Documentation added on standard for shared modules
  • Beamlines conform to standard.
  • Dodal connect command adjusted

Contributor Guide