Skip to content

187 adding catalogs section in the pyaml configuration file new implementation#234

Open
gupichon wants to merge 28 commits intomainfrom
187-adding-catalogs-section-in-the-pyaml-configuration-file-new-implementation
Open

187 adding catalogs section in the pyaml configuration file new implementation#234
gupichon wants to merge 28 commits intomainfrom
187-adding-catalogs-section-in-the-pyaml-configuration-file-new-implementation

Conversation

@gupichon
Copy link
Copy Markdown
Contributor

@gupichon gupichon commented Apr 20, 2026

Description

Add named Catalog objects to the PyAML configuration so device references can be resolved by key at control-system attachment time.

The implementation present on this branch is intentionally narrower than the original idea:

  • catalogs are available at accelerator level as named objects;
  • a control system may reference one named catalog, or still provide one inline catalog;
  • base PyAML provides a static catalog implementation backed by explicit typed entries;
  • BPM models use catalog keys instead of embedded DeviceAccess objects;
  • the rest of PyAML keeps direct DeviceAccess configuration for now.

The goal of this work is still to extend the same mechanism to all PyAML devices over time, not only BPMs.

The catalog API keeps a control-system attachment hook so catalog implementations can be specialized by inheritance. Base PyAML provides StaticCatalog as the default implementation, but the API is intentionally open to additional catalog classes built in PyAML or external projects.

Related Issue

Features implemented on this branch are:

  • new feature: introduce top-level named catalogs in pyaml.accelerator.ConfigModel
  • new feature: define a minimal catalog abstraction centered on resolve(key) -> DeviceAccess
  • new feature: define CatalogResolver so one shared catalog can produce a resolver bound to each control system
  • new feature: provide a built-in static catalog based on explicit typed entries
  • new feature: provide a typed StaticCatalogEntry object so catalog entries are built through the factory like the rest of the configuration
  • new feature: keep the catalog API extensible by inheritance so additional catalog implementations can be introduced beyond the default static catalog
  • new feature: allow a ControlSystem to declare catalog: str | Catalog | None
  • new feature: resolve BPM device keys through the configured catalog at control-system attachment time
  • new feature: support loading catalog fragments through ConfigurationManager

This PR does not close #187. It only implements the BPM step of the catalog mechanism. The issue remains open until the same approach is extended to the other PyAML device-bearing object families.

Scope and Non-Goals

The implementation on this branch stays within the following scope:

  • catalogs only resolve keys to DeviceAccess
  • catalog resolution happens lazily in ControlSystem, immediately before BPM attachment
  • BPM support is limited to pyaml.bpm.bpm models currently implemented in base PyAML
  • BPM configuration now uses catalog keys, not direct DeviceAccess
  • the catalog infrastructure remains generic so the feature can later be extended to other PyAML object families
  • BPM support is the first application step, not the final target

Expected Design

The implementation currently present on the branch follows this design:

  • Catalog and CatalogResolver live under pyaml.configuration
  • Catalog.name is part of the catalog object itself
  • Catalog.attach_control_system() returns a resolver bound to one control system; the default implementation returns self
  • StaticCatalog is the built-in catalog implementation provided by base PyAML
  • other catalog implementations may be introduced later by inheriting from Catalog
  • StaticCatalog stores entries: list[StaticCatalogEntry]
  • Accelerator.ConfigModel exposes catalogs: list[Catalog] | None
  • Accelerator stores named catalogs and resolves controlsystem.catalog before calling fill_device()
  • ControlSystem stores both the configured catalog object and the bound resolver
  • BPM runtime paths use resolve_device() / resolve_devices() to turn BPM keys into DeviceAccess
  • non-BPM runtime paths still attach concrete DeviceAccess objects directly

Changes to existing functionality

Describe the changes that had to be made to an existing functionality.

  • Accelerator now builds and stores named catalogs before devices are attached to control systems
  • ControlSystem now binds one catalog resolver per control system, even when several control systems share the same catalog object
  • BPMSimpleModel and BPMTiltOffsetModel now require catalog keys for BPM device fields
  • BPM attachment and BPM aggregators now resolve catalog keys through the bound control-system catalog
  • magnets, RF, tune monitors, and the rest of PyAML continue to use direct DeviceAccess configuration
  • the API is kept generic so the same catalog mechanism can later be extended to all device-bearing PyAML objects
  • test YAML files were reworked so shared BPM catalogs live in accelerator-level catalog fragments

Implementation Notes

Use these constraints when discussing or extending the implementation:

  • keep the catalog API generic even if only BPM consumes it today
  • keep one catalog per control system
  • preserve support for sharing one catalog object across several control systems
  • preserve the attach_control_system() hook so inherited catalog implementations can provide contextual resolvers
  • fail fast on duplicate top-level catalog names
  • fail fast on duplicate keys inside StaticCatalog.entries
  • treat BPM catalog keys as mandatory on this branch
  • keep the implementation structured so catalog-backed resolution can later be applied to all device-bearing PyAML objects

Recommended areas to review:

  • pyaml/accelerator.py
  • pyaml/control/controlsystem.py
  • pyaml/configuration/catalog.py
  • pyaml/configuration/static_catalog.py
  • pyaml/configuration/static_catalog_entry.py
  • pyaml/bpm/bpm_model.py
  • pyaml/bpm/bpm_simple_model.py
  • pyaml/bpm/bpm_tiltoffset_model.py

Impacted PyAML Objects

Directly impacted objects and models on this branch:

  • Accelerator
  • ControlSystem
  • Catalog
  • CatalogResolver
  • StaticCatalog
  • StaticCatalogEntry
  • BPMModel
  • BPMSimpleModel
  • BPMTiltOffsetModel

Directly impacted runtime paths:

  • BPM attachment in ControlSystem.fill_device()
  • BPM aggregators in ControlSystem.create_bpm_aggregators()

Objects intentionally left unchanged by this branch:

  • magnet models and magnet attachment
  • RFPlant
  • RFTransmitter
  • BetatronTuneMonitor
  • simulator-side BPM attachment
  • arrays, tools, and yellow pages except through normal regression coverage

Configuration Examples

Accelerator-level static catalog:

type: pyaml.accelerator
facility: SOLEIL
machine: StorageRing
energy: 2.75e9
data_folder: .

catalogs:
  - type: pyaml.configuration.static_catalog
    name: bpm-common
    entries:
      - type: pyaml.configuration.static_catalog_entry
        key: BPM_C01-01/x
        device:
          type: tango.pyaml.attribute_read_only
          attribute: srdiag/bpm/c01-01/XPosSA
          unit: mm
      - type: pyaml.configuration.static_catalog_entry
        key: BPM_C01-01/y
        device:
          type: tango.pyaml.attribute_read_only
          attribute: srdiag/bpm/c01-01/YPosSA
          unit: mm
      - type: pyaml.configuration.static_catalog_entry
        key: BPM_C01-01/tilt
        device:
          type: tango.pyaml.attribute
          attribute: srdiag/bpm/c01-01/Tilt
          unit: rad

Control systems referencing the same named catalog:

controls:
  - type: tango.pyaml.controlsystem
    name: live
    catalog: bpm-common

  - type: tango.pyaml.controlsystem
    name: ops
    catalog: bpm-common

BPM using catalog keys:

devices:
  - type: pyaml.bpm.bpm
    name: BPM_C01-01
    model:
      type: pyaml.bpm.bpm_tiltoffset_model
      x_pos: BPM_C01-01/x
      y_pos: BPM_C01-01/y
      x_offset: BPM_C01-01/x_offset
      y_offset: BPM_C01-01/y_offset
      tilt: BPM_C01-01/tilt

Inline catalog still supported on one control system:

controls:
  - type: tango.pyaml.controlsystem
    name: live
    catalog:
      type: pyaml.configuration.static_catalog
      name: local-bpm
      entries:
        - type: pyaml.configuration.static_catalog_entry
          key: BPM_C02-01/x
          device:
            type: tango.pyaml.attribute_read_only
            attribute: srdiag/bpm/c02-01/SA_HPosition
            unit: mm
        - type: pyaml.configuration.static_catalog_entry
          key: BPM_C02-01/y
          device:
            type: tango.pyaml.attribute_read_only
            attribute: srdiag/bpm/c02-01/SA_VPosition
            unit: mm

Testing

The following tests are covered on this branch:

  • load an accelerator with top-level named catalogs and resolve BPM keys from a control system
  • share one named catalog between several control systems and verify they reference the same catalog object
  • verify that one shared catalog can bind different resolvers per control system
  • load a control system with an inline catalog and resolve BPM keys
  • fail clearly on unknown catalog name referenced by a control system
  • fail clearly on unresolved BPM key
  • fail clearly on duplicate top-level catalog names
  • fail clearly on duplicate keys inside a static catalog
  • verify that ConfigurationManager tracks catalogs as a named category
  • verify that ConfigurationManager can add a catalog-only fragment

Verify that your checklist complies with the project

  • New and existing unit tests pass locally
  • Tests were added to prove that all implemented features are effective
  • The document only describes functionality actually present on the branch

…ection-in-the-pyaml-configuration-file-new-implementation

# Conflicts:
#	pyaml/accelerator.py
#	pyaml/configuration/__init__.py
@gupichon gupichon self-assigned this Apr 20, 2026
@gupichon gupichon linked an issue Apr 20, 2026 that may be closed by this pull request
@JeanLucPons
Copy link
Copy Markdown
Contributor

What is the DeviceAccesRef ? I expect a simple string using catalog ?

@JeanLucPons
Copy link
Copy Markdown
Contributor

Would it be possible to try to cut this kind of PR into several tasks and PRs ?
The code review will be very difficult...

@gupichon
Copy link
Copy Markdown
Contributor Author

What is the DeviceAccesRef ? I expect a simple string using catalog ?

I'm still hesitating about whether we should let the user provide a DeviceAccess object or a DeviceAccess key only. This approach allows for both. It also prevents regressions in existing configuration files, even if that isn't a strict requirement in the current development phase.

@gupichon
Copy link
Copy Markdown
Contributor Author

Would it be possible to try to cut this kind of PR into several tasks and PRs ?
The code review will be very difficult...

It's quite heavy to split it, as I want to be sure that I cover every use case. It’s debatable...

@gupichon
Copy link
Copy Markdown
Contributor Author

@JeanLucPons, I’m still in the middle of a major development phase. I’ve created this draft PR to show you and others the early progress.

@gupichon
Copy link
Copy Markdown
Contributor Author

At the same time, I'm developing the dynamic catalog in tango-pyaml.

@JeanLucPons
Copy link
Copy Markdown
Contributor

Please make separate issues.
Few things has nothing to do here and are even not documented.
Otherwise code review will be a nightmare.

@gupichon
Copy link
Copy Markdown
Contributor Author

Few things has nothing to do here and are even not documented.

Such as ?

@JeanLucPons
Copy link
Copy Markdown
Contributor

Written in the review

@gupichon-soleil
Copy link
Copy Markdown
Contributor

Usually, I can see your reviews, but I don’t see anything on my end this time... Maybe the review is still in 'Pending' mode?

Comment thread pyaml/bpm/bpm_model.py
Comment thread pyaml/configuration/factory.py
Comment thread pyaml/configuration/fileloader.py
Comment thread pyaml/diagnostics/tune_monitor.py
@JeanLucPons
Copy link
Copy Markdown
Contributor

Yes it was still pending, sorry

@gupichon gupichon requested a review from JeanLucPons April 20, 2026 15:09
@gupichon
Copy link
Copy Markdown
Contributor Author

@JeanLucPons, I received your comment via email regarding pyaml/diagnostics/tune_monitor.py. However, since that file is no longer within the scope of this PR, I cannot reply to it directly here.

I am working on reducing the impact of the changes by reverting some modifications (even if I have to re-introduce them later). Please note that several of the new files are actually dedicated to tests.

@JeanLucPons
Copy link
Copy Markdown
Contributor

The difficulty will be in the backend in order to avoid duplication of DeviceProxy or OphydSignal for DeviceAccess that share the same Attribute or PV with different index. A DeviceAccess call that return a unique ref (corresponding to the DeviceProxy) will also be necessary for aggregators.
This is to avoid this unnecessary additional layer seen by the user.

@JeanLucPons
Copy link
Copy Markdown
Contributor

from pyaml.common.abstract import ReadWriteFloatScalar
from pyaml.common.element import Element, ElementConfigModel
from pyaml.control.deviceaccess import DeviceAccess
from pyaml.control.controlsystem import ControlSystem
import numpy as np

PYAMLCLASS = "ID"

class ConfigModel(ElementConfigModel):
    gap: DeviceAccess | None

class ID(Element):
    """
    Class providing access to an insertion device
    """
    def __init__(self, cs:ControlSystem, cfg: ConfigModel):
        super().__init__(cfg.name)
        self.device = cs.attach([cfg.gap])[0] # Retrieve device handle

    @property
    def gap(self) -> ReadWriteFloatScalar:
        class GapRW(ReadWriteFloatScalar):
            def __init__(self, parent: ID):
                self.parent = parent

            def get(self) -> np.array:
                return self.parent.device.get()

            def set(self, value: float):
                """Set the values"""
                self.parent.device.set(value)

            def set_and_wait(self, value: float):
                ...

            def unit(self) -> str:
                return "mm"
            
        return GapRW(self)

Please also think to this use case where the

cs.attach([cfg.gap])[0] # Retrieve device handle

is not very user friendly,

I would like to have something like:

cs.get_device(cfg.gap) # Retrieve device handle

Where the get_device call should return the appropriate DeviceAcess from either a static or dynamic Catalog.

@gupichon
Copy link
Copy Markdown
Contributor Author

DeviceAccessKey is confusing and complexify the config.

It is supposed to be hidden from the user by the validator, which will allow the keys as you requested. This configuration will be accepted:

- type: pyaml.bpm.bpm
  name: BPMZ7T3R
  model:
    type: pyaml.bpm.bpm_simple_model
    # Will work with all catalogs types
    x_pos: ORBITCC:rdPos@82
    y_pos: ORBITCC:rdPos@83

In general, the catalog should only care about the link with the backend, not about how it is used (with a specific index, for instance). Moreover, if you switch between two catalogs (one static and another dynamic), you would have to deal with different behaviors.
DeviceAccessKey only exists during the parsing phase, and ResolvedDeviceAccess remains internal to the attachment process, undistinguishable from DeviceAccess via inheritance. In the end, both are completely transparent to the end user.

You use case work also if I adapt it to my proposal:

from pyaml.common.abstract import ReadWriteFloatScalar
from pyaml.common.element import Element, ElementConfigModel
from pyaml.control.deviceaccess import DeviceAccess
from pyaml.control.deviceaccesskey import DeviceAccessKey 
from pyaml.control.controlsystem import ControlSystem
import numpy as np

PYAMLCLASS = "ID"

class ConfigModel(ElementConfigModel):
    gap: DeviceAccessKey | None

class ID(Element):
    """
    Class providing access to an insertion device
    """
    def __init__(self, cs:ControlSystem, cfg: ConfigModel):
        super().__init__(cfg.name)
        self.device:DeviceAccess | None = cs.attach(cfg.gap) # Return a ResolvedDeviceAccess which is a DeviceAccess

    @property
    def gap(self) -> ReadWriteFloatScalar:
        class GapRW(ReadWriteFloatScalar):
            def __init__(self, parent: ID):
                self.parent = parent

            def get(self) -> np.array:
                return self.parent.device.get()

            def set(self, value: float):
                """Set the values"""
                self.parent.device.set(value)

            def set_and_wait(self, value: float):
                ...

            def unit(self) -> str:
                return "mm"
            
        return GapRW(self)

I prefer to adapt the cs.attach signature to return a single element if it receives a single element instead of a list. It’s very easy to implement. To me, get_device implies that the device is already attached and simply returns it.

If the index were embedded directly inside DeviceAccess (i.e., each instance resolved to a scalar-only device), this link would be invisible: x_dev and y_dev would be two independent objects with no shared reference, and there would be no reliable way to detect that they originate from the same underlying attribute without out-of-band bookkeeping. The separation of DeviceAccess (vector endpoint) and ResolvedDeviceAccess (indexed view) is therefore not only a design choice but a prerequisite for any future read optimisation.

Sorry for the long response, I was updating it while you were posting yours.

@gupichon
Copy link
Copy Markdown
Contributor Author

gupichon commented Apr 23, 2026

In addition, the decorator we considered developing must accept the same entries as the configuration. So this must work:

my_id:ID = get_my_id()
my_id.device= "ORBITCC:rdPos@82" # Replace by a PV that is actually meaningful

It will build the DeviceAccessKey and trigger a call to attach to set the device.

…ne limit change

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@gupichon
Copy link
Copy Markdown
Contributor Author

@JeanLucPons, with the latest merge from main, the number of changed files has dropped to 34!

@JeanLucPons
Copy link
Copy Markdown
Contributor

In general, the catalog should only care about the link with the backend, not about how it is used (with a specific index, for instance). Moreover, if you switch between two catalogs (one static and another dynamic), you would have to deal with different behaviors. DeviceAccessKey only exists during the parsing phase, and ResolvedDeviceAccess remains internal to the attachment process, undistinguishable from DeviceAccess via inheritance. In the end, both are completely transparent to the end user.

Roughly speaking I don't want to be able to see this in the config:
The user see the config.

x_pos:
  type: pyaml.control.device_access_key
  key: srdiag/bpm/c01-04/Position
  index: 0

To me it is more intuitive to have the index the DeviceAccess and you right, the backend will have to deal with shared reference attribute or PV name internally.

If i insist to have it in the backend it is because the advanced syntax will depend on the control system and on the need of the users.

i.e.

- type: pyaml.id
  name: ID24
  gap: R:GAP:ID24, W:GAP:ID24_SET

or

- type: pyaml.id
  name: ID24
  gap: R:GAP:ALL_ID@24, W:GAP:ID24_SET@24

or

- type: pyaml.id
  name: ID24
  gap: id/id/24/gap

or
...

We just need to have a simple catalog with simple string for key in PyAML and well define the DeviceAccess and ControlSystem interface for the needs.

@JeanLucPons
Copy link
Copy Markdown
Contributor

I prefer to adapt the cs.attach signature to return a single element if it receives a single element instead of a list. It’s very easy to implement. To me, get_device implies that the device is already attached and simply returns it.

ControlSystem.get_device(name:str) will return a DeviceAccess from a string.
attach() is a bad name inherited from the very first design when DeviceAccess was created from the factory.

@JeanLucPons
Copy link
Copy Markdown
Contributor

@JeanLucPons, with the latest merge from main, the number of changed files has dropped to 34!

It is good but i still can see changes that I do not expect in magnets.

Comment thread pyaml/control/controlsystem.py
@JeanLucPons
Copy link
Copy Markdown
Contributor

For this PR we will forget the indexed stuff.
At it is now it is good.
When pyaml will be released, we merge this PR.

@gupichon
Copy link
Copy Markdown
Contributor Author

gupichon commented Apr 24, 2026

Thinking about your comment, I agree that we should delegate the entire DeviceAccess to the Control System. The CS side would then implement an object similar to the ResolvedDeviceAccess I suggested.

Furthermore, all catalogs—including the static one—should be handled by the CS. PyAML will simply define an interface that the control system must respect. The CS will handle indices and other specifics, returning a DeviceAccess object to PyAML with full value management.

Consequently, the current StaticCatalog would be moved to tango-pyaml, pyaml-cs-oa, and dummy-cs as specializations. This won't be a major change since the current implementation is actually quite lightweight. The implementation will be the same for Tango, but a more elaborate one will be needed for EPICS, as the keys can be significantly more complex.

I can write a full proposal if you want ?

@JeanLucPons
Copy link
Copy Markdown
Contributor

It is fine for me.

@gupichon
Copy link
Copy Markdown
Contributor Author

It is good but i still can see changes that I do not expect in magnets.

Yes, it’s a leftover from a bug fix for serialized magnets that I need to move to another branch. Sorry about that!

@gupichon gupichon marked this pull request as ready for review April 27, 2026 09:35
… and get_devices, and update internal call sites.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand "ORBITCC:rdPos@0" It is already a dynamic catalog ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is. You can take a look at the dedicated branch and the PR on pyaml-cs-oa. There is also a PR for tango-pyaml.

I haven't done much testing yet as there are no unit tests in pyaml-cs-oa, but I've confirmed that the file loads successfully.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I'm afraid that BPM aggregators will not work ex expected....

  2. I expect:

devs = self.get_devices(b.model.get_pos_devices())

instead of:

devs = self.attach(self.get_devices(b.model.get_pos_devices()))

The ControlSystem::get_devices(name:str) should be responsible of attachement.

Later, in an other PR, for BPM refurbishment, we will rename b.model.get_pos_devices() to b.model.get_pos_device_names()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid that BPM aggregators will not work ex expected....

Could you clarify this point?

The ControlSystem::get_devices(name:str) should be responsible of attachement.

So, should it be handled in a single call? I’m fine with that, but I suggest doing it later as other devices (Magnets, RF, etc.) still rely on this method. Once this PR is merged, we can finish refactoring the attachment process within the control systems. This will also involve significant updates across other projects.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Details for aggregator are given in the pyaml-cs-oa corresponding PR
  2. The idea is to get, in a first step, the 2 methods (attach() for old devices and get_device() for BPM). For this PR BPM should no longer access the old DeviceAccess interface.

Copy link
Copy Markdown
Contributor Author

@gupichon gupichon Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to get, in a first step, the 2 methods (attach() for old devices and get_device() for BPM). For this PR BPM should no longer access the old DeviceAccess interface.

Should the get_device(s) methods simply wrap the attach method?

I've pushed a small commit following this approach.

Copy link
Copy Markdown
Contributor

@JeanLucPons JeanLucPons Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was rather to move get_devices() in the backend and to abstract it in pyaml.
At the end, I would like to have only a single string in the config and a get_devices(name:str) method at the ControlSystem level that return a list of DeviceAccess.

BPMs now use get_devices() directly instead of attach(get_devices(...)).
…ection-in-the-pyaml-configuration-file-new-implementation

# Conflicts:
#	examples/SOLEIL_examples/p.yaml
Copy link
Copy Markdown
Contributor

@JeanLucPons JeanLucPons Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was rather to move get_devices() in the backend and to abstract it in pyaml.
At the end, I would like to have only a single string in the config and a get_devices(name:str) method at the ControlSystem level that return a list of DeviceAccess.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attach_control_system() should be removed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it is mandatory for Tango dynamic catalogs. An optional 'connected' mode allows the catalog to perform checks to ensure a correct DeviceAccess is built. Specifically to verify the data type (scalar vs. spectrum), ranges, and units.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still working on it

Comment thread pyaml/accelerator.py
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The catalog config is linked to control system only.
Could the catalogs field be moved in ControlSystem configuration ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to share the catalog between control systems (live and virtual), it would be better to define it at the accelerator level. Otherwise, we would need to update the 'simulators' section to support a more complex structure than just a simple list.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your point, what simulators do here ?
Catalog are control system specific and it would be logical to have it in the Control section whatever the ControlSystem configuration structure.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What prefix does in the catalog, it is very confusing.
Could it explains unwanted creation of unattached object ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I think I understand. The build call is wrong in the dynamic catalog. A catalog should only return a temporary config object.

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 this pull request may close these issues.

Adding catalogs section in the pyaml configuration file

3 participants