Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardise handling of Read, Config and Hinted signals for StandardDetector #282

Closed
DiamondJoseph opened this issue May 2, 2024 · 4 comments · Fixed by #468
Closed
Assignees

Comments

@DiamondJoseph
Copy link
Contributor

Extension of #223 #240, partially covered by #213

StandardDetector requires configuration in multiple ways:

  • Scalar datasets which are passed to the HDFWriter and assumed to exist: these should be either be validated prior to trying to run a scan, to ensure that the plugin chain is still configured such that those fields will be readable, or fetched from the plugin chains once they are configurable with Create class for the areaDetector statistics plugin. #213
  • Exposing Config signals to be read once per scan: currently this is left to implementations of StandardDetector, with the current assumption that this will be acquire_time and any number of fields on FooDriver for FooDetector
  • Fetching hints from the underlying HDFWriter is done manually if the StandardDetector implementation chooses to implement HasHints
@coretl
Copy link
Collaborator

coretl commented May 3, 2024

To summarize the meeting we just had:

  • We want to expand the concept of scalar_sigs so that the HDFWriter knows not just the name, but how to ensure that it is going to be written
  • I suggest we rip up the NDAttributesXML class and replace it with some dataclasses:
@dataclass
class NDAttributePv:
    name: str  # name of attribute stamped on array, also scientifically useful name when appended to device.name
    signal: SignalR  # caget the pv given by signal.source and attach to each frame
    datatype: Optional[NDAttributeDataType] = None  # An override datatype, otherwise will use native EPICS type
    description: str = ""  # A description that appears in the HDF file as an attribute

@datackass
class NDAttributeParam:
    name: str  # name of attribute stamped on array, also scientifically useful name when appended to device.name
    param: str  # The parameter string as seen in the INP link of the record
    datatype: NDAttributeDataType  # The datatype of the parameter
    addr: int = 0  # The address as seen in the INP link of the record
    description: str = ""  # A description that appears in the HDF file as an attribute
  • Then we can pass something like Dict[NDArrayBase, Sequence[NDAttributePv | NDAttributeParam]] to HDFWriter.__init__, and it should make the XML and set the nd_attributes_file of given NDArrayBase to it
  • This will give us equivalent behaviour to what we currently have, i.e. PVs to be captured specified at device init
  • If we want to specify per-scan what PVs to grab then maybe we could hook this to prepare later

@DiamondJoseph
Copy link
Contributor Author

RE: Hints, if we add HasHints to DetectorWriter, we can propagate through to StandardDetector as well.

DiamondJoseph added a commit that referenced this issue May 3, 2024
…mplementations (#281)

* Remove ScalarSigs (see issue #282)
@coretl
Copy link
Collaborator

coretl commented Jun 24, 2024

Needs #314

@coretl
Copy link
Collaborator

coretl commented Jul 15, 2024

After discussing this with @DiamondJoseph @ZohebShaikh @abbiemery, we decided we need per-scan behaviour, but instead of hooking prepare we will use load/save.

We have tweaked the above plan to be:

  • On StandardDetector subclass __init__, pass references to the driver and plugins into HDFWriter.__init__
  • We will load the NDAttributeXML for given plugins in a plan stub either when setting up the beamline (possibly in dodal), or at the beginning of a custom scan plan
  • In HDFWriter.open then look at the NDAttributeXML for each plugin, and publish StreamResource for each entry within it. Assume the names are scientifically important

To do this:

@dataclass
class NDAttributePv:
    name: str  # name of attribute stamped on array, also scientifically useful name when appended to device.name
    signal: SignalR  # caget the pv given by signal.source and attach to each frame
    datatype: Optional[NDAttributeDataType] = None  # An override datatype, otherwise will use native EPICS type
    description: str = ""  # A description that appears in the HDF file as an attribute

@datackass
class NDAttributeParam:
    name: str  # name of attribute stamped on array, also scientifically useful name when appended to device.name
    param: str  # The parameter string as seen in the INP link of the record
    datatype: NDAttributeDataType  # The datatype of the parameter
    addr: int = 0  # The address as seen in the INP link of the record
    description: str = ""  # A description that appears in the HDF file as an attribute
  • Create a generic plan stub setup_ndattributes(device: NDArrayBase, ndattributes: Sequence[NDAttributePv | NDAttributeParam]) that creates the XML text in memory, and yield from bps.abs_set(device.nd_attributes_file, xml_text)
  • Create a specific plan stub setup_ndstats_sum(stats: NDStats) that enables NDStats sum and calls setup_ndattributes with a suitable NDAttributeParam(name=f"{stats.parent.name}-sum", ...)
  • Make HDFWriter.__init__ take and store plugins: Sequence[NDArrayBase] rather than scalar_sigs
  • In HDFWriter.open then instead of using scalar_sigs to make _HDFDatasets, then read the nd_attribute_xml of each plugin, try to load it as XML, and publish the name of each NDAttribute within it as an _HDFDataset instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants