Skip to content

Commit

Permalink
merge Definition and CollectionDefinition back into Definition
Browse files Browse the repository at this point in the history
  • Loading branch information
gilesknap committed May 11, 2024
1 parent e3fa27a commit f941f3c
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 171 deletions.
33 changes: 0 additions & 33 deletions src/ibek/collection.py

This file was deleted.

7 changes: 7 additions & 0 deletions src/ibek/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from .args import Arg, IdArg, Value
from .globals import BaseSettings
from .sub_entity import SubEntity


def default(T: type):
Expand Down Expand Up @@ -149,6 +150,12 @@ class Definition(BaseSettings):
description="PVI definition for Entity", default=None
)

# list of additional entities to instantiate for each instance of this definition
sub_entities: Sequence[SubEntity] = Field(
description="The sub-entity instances that this collection is to instantiate",
default=(),
)

def _get_id_arg(self):
"""Returns the name of the ID argument for this definition, if it exists"""
for arg in self.args:
Expand Down
40 changes: 19 additions & 21 deletions src/ibek/ioc_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from ibek.utils import UTILS

from .args import EnumArg, IdArg, ObjectArg
from .collection import CollectionDefinition
from .ioc import IOC, Entity, EnumVal, clear_entity_model_ids, get_entity_by_id
from .support import Definition, Support

Expand Down Expand Up @@ -89,30 +88,29 @@ def _process_collections(self, ioc_instance: IOC):

for entity in ioc_instance.entities:
definition = entity.__definition__
if isinstance(definition, CollectionDefinition):
# this is a collection - process all the sub-entities and throw
# away the root entity
for sub_entity in definition.entities:
# find the Entity Class that the SubEntity represents
entity_cls = self._entity_classes[sub_entity.type]
# get the SubEntity arguments
sub_args_dict = sub_entity.model_dump()
# jinja render any references to parent Args in the SubEntity Args
for key, arg in sub_args_dict.items():
sub_args_dict[key] = UTILS.render(entity, arg)
# cast the SubEntity to its concrete Entity subclass
cast_entity = entity_cls(**sub_args_dict)
# add it to the IOCs entity list
all_entities.append(cast_entity)
else:
# a standard entity - just add it to the list
all_entities.append(entity)

# add the parent standard entity - just add it to the list
all_entities.append(entity)

# add in SubEntities if any
for sub_entity in definition.sub_entities:
# find the Entity Class that the SubEntity represents
entity_cls = self._entity_classes[sub_entity.type]
# get the SubEntity arguments
sub_args_dict = sub_entity.model_dump()
# jinja render any references to parent Args in the SubEntity Args
for key, arg in sub_args_dict.items():
sub_args_dict[key] = UTILS.render(entity, arg)
# cast the SubEntity to its concrete Entity subclass
cast_entity = entity_cls(**sub_args_dict)
# add it to the IOCs entity list
all_entities.append(cast_entity)

ioc_instance.entities = all_entities

def _make_entity_model(
self, definition: Definition | CollectionDefinition, support: Support
) -> Type[Entity | CollectionDefinition]:
self, definition: Definition, support: Support
) -> Type[Entity]:
"""
Create an Entity Model from a Definition instance and a Support instance.
"""
Expand Down
3 changes: 2 additions & 1 deletion src/ibek/sub_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
class SubEntity(BaseModel, extra="allow"):
"""
A loosely defined class to declare the Entities
in an ibek.support.yaml file in the CollectionDefinition section
in an ibek.support.yaml file in the 'sub_entities' property of an Entity
section
"""

type: str = Field(description="The type of this entity")
Expand Down
3 changes: 1 addition & 2 deletions src/ibek/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from pydantic import Field

from .collection import CollectionDefinition
from .definition import Definition
from .globals import BaseSettings

Expand All @@ -22,7 +21,7 @@ class Support(BaseSettings):
"""

module: str = Field(description="Support module name, normally the repo name")
defs: Sequence[Definition | CollectionDefinition] = Field(
defs: Sequence[Definition] = Field(
description="The definitions an IOC can create using this module"
)

Expand Down
7 changes: 7 additions & 0 deletions tests/samples/outputs/quadem/st.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ asynOctetSetOutputEos(XBPM1.DRVip, 0, "\r")

# drvTetrAMMConfigure(portName, IPportName, RingSize)
drvTetrAMMConfigure("XBPM1.DRV", "XBPM1.DRVip", 10000)

################################################################################
# Just demonstrating that Entities can have their own pre_init: AND sub_entities
# This is the pre_init for quadem.Plugins device with id XBPM1
################################################################################

#
# ADCore path for manual NDTimeSeries.template to find base plugin template
epicsEnvSet "EPICS_DB_INCLUDE_PATH", "$(ADCORE)/db"

Expand Down
89 changes: 11 additions & 78 deletions tests/samples/schemas/ibek.support.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,75 +39,6 @@
"title": "BoolArg",
"type": "object"
},
"CollectionDefinition": {
"properties": {
"name": {
"description": "Publish Definition as type <module>.<name> for IOC instances",
"title": "Name",
"type": "string"
},
"description": {
"description": "A description of the Support module defined here",
"title": "Description",
"type": "string"
},
"args": {
"default": [],
"description": "The arguments IOC instance should supply",
"items": {
"anyOf": [
{
"$ref": "#/$defs/FloatArg"
},
{
"$ref": "#/$defs/StrArg"
},
{
"$ref": "#/$defs/IntArg"
},
{
"$ref": "#/$defs/BoolArg"
},
{
"$ref": "#/$defs/ObjectArg"
},
{
"$ref": "#/$defs/IdArg"
},
{
"$ref": "#/$defs/EnumArg"
}
]
},
"title": "Args",
"type": "array"
},
"values": {
"default": [],
"description": "Calculated values to use as additional arguments",
"items": {
"$ref": "#/$defs/Value"
},
"title": "Values",
"type": "array"
},
"entities": {
"default": [],
"description": "The sub-entity instances that this collection is to instantiate",
"items": {
"$ref": "#/$defs/SubEntity"
},
"title": "Entities",
"type": "array"
}
},
"required": [
"name",
"description"
],
"title": "CollectionDefinition",
"type": "object"
},
"Comment": {
"additionalProperties": false,
"description": "A script snippet that will have '# ' prepended to every line\nfor insertion into the startup script",
Expand Down Expand Up @@ -289,6 +220,15 @@
],
"default": null,
"description": "PVI definition for Entity"
},
"sub_entities": {
"default": [],
"description": "The sub-entity instances that this collection is to instantiate",
"items": {
"$ref": "#/$defs/SubEntity"
},
"title": "Sub Entities",
"type": "array"
}
},
"required": [
Expand Down Expand Up @@ -610,7 +550,7 @@
},
"SubEntity": {
"additionalProperties": true,
"description": "A loosely defined class to declare the Entities\nin an ibek.support.yaml file in the CollectionDefinition section",
"description": "A loosely defined class to declare the Entities\nin an ibek.support.yaml file in the 'sub_entities' property of an Entity\nsection",
"properties": {
"type": {
"description": "The type of this entity",
Expand Down Expand Up @@ -704,14 +644,7 @@
"defs": {
"description": "The definitions an IOC can create using this module",
"items": {
"anyOf": [
{
"$ref": "#/$defs/Definition"
},
{
"$ref": "#/$defs/CollectionDefinition"
}
]
"$ref": "#/$defs/Definition"
},
"title": "Defs",
"type": "array"
Expand Down
47 changes: 11 additions & 36 deletions tests/samples/support/quadem.ibek.support.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,17 @@ defs:
length of NDArray queue
default: 16

entities:
pre_init:
- value: |
################################################################################
# Just demonstrating that Entities can have their own pre_init: AND sub_entities
# This is the pre_init for quadem.Plugins device with id {{PORTPREFIX}}
################################################################################
#
sub_entities:
- { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I1", R: Cur1, P: "{{DEVICE.P}}", NCHANS: "{{STAT_NCHAN}}", XSIZE: "{{STAT_XSIZE}}", YSIZE: 0, HIST_SIZE: "{{HIST_SIZE}}", NDARRAY_PORT: "{{DEVICE}}", ENABLED: 1 }
- { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I2", R: Cur2, P: "{{DEVICE.P}}", NCHANS: "{{STAT_NCHAN}}", XSIZE: "{{STAT_XSIZE}}", YSIZE: 0, HIST_SIZE: "{{HIST_SIZE}}", NDARRAY_PORT: "{{DEVICE}}", ENABLED: 1 }
- { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I3", R: Cur3, P: "{{DEVICE.P}}", NCHANS: "{{STAT_NCHAN}}", XSIZE: "{{STAT_XSIZE}}", YSIZE: 0, HIST_SIZE: "{{HIST_SIZE}}", NDARRAY_PORT: "{{DEVICE}}", ENABLED: 1 }
Expand All @@ -123,38 +133,3 @@ defs:
- { type: ADCore.NDStdArrays, PORT: "{{PORTPREFIX}}.ARRAYS.DiffY", R: DiffY, P: "{{DEVICE.P}}", NDARRAY_PORT: "{{DEVICE}}", ENABLED: 1, TYPE: "Float64", FTVL: "DOUBLE", NELEMENTS: "{{STAT_XSIZE}}" }
- { type: ADCore.NDStdArrays, PORT: "{{PORTPREFIX}}.ARRAYS.PosX", R: PosX, P: "{{DEVICE.P}}", NDARRAY_PORT: "{{DEVICE}}", ENABLED: 1, TYPE: "Float64", FTVL: "DOUBLE", NELEMENTS: "{{STAT_XSIZE}}" }
- { type: ADCore.NDStdArrays, PORT: "{{PORTPREFIX}}.ARRAYS.PosY", R: PosY, P: "{{DEVICE.P}}", NDARRAY_PORT: "{{DEVICE}}", ENABLED: 1, TYPE: "Float64", FTVL: "DOUBLE", NELEMENTS: "{{STAT_XSIZE}}" }

# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I1", R: Cur1 }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I1", R: Cur1 }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I2", R: Cur2 }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I3", R: Cur3 }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.I4", R: Cur4 }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.SumX", R: SumX }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.SumY", R: SumY }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.SumAll", R: SumAll }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.DiffX", R: DiffX }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.DiffY", R: DiffY }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.PosX", R: PosX }
# - { type: ADCore.NDStats, PORT: "{{PORTPREFIX}}.STATS.PosY", R: PosY }

# pre_init:
# - when: first
# - value: |
# # NDStatsConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxBuffers, maxMemory, priority, stackSize, maxThreads)
# # NDTimeSeriesConfigure(portName, queueSize, blockingCallbacks, NDArrayPort, NDArrayAddr, maxSignals)

# - value: |
# {% for tab in ["I1", "I2", "I3", "I4" , "SumX", "SumY", "SumAll", "DiffX", "DiffY", "PosX", "PosY"] -%}
# {# support the historical, inconsistent naming of PVs and asyn ports #}
# {%- set r_val_stats = "Cur%d" % loop.index if tab.startswith("I") else tab -%}
# {%- set r_val_array = "ARR%d" % loop.index if tab.startswith("I") else "ARR%s" % tab -%}

# NDStatsConfigure({{PORTPREFIX}}.STATS.{{tab}}, {{QUEUE}}, 0, {{DEVICE.PORT}}, {{loop.index0}}, 0, 0, 0, 0, 1)
# dbLoadRecords("$(ADCORE)/db/NDStats.template", "P={{DEVICE.P}},R=:{{r_val_stats}}:, PORT={{PORTPREFIX}}.STATS.{{tab}}, ADDR=0, NDARRAY_PORT={{DEVICE.PORT}}, NDARRAY_ADDR={{loop.index0}}, NCHANS={{STAT_NCHAN}}, ENABLED=1, XSIZE={{STAT_XSIZE}}, YSIZE=0, HIST_SIZE={{HIST_SIZE}}")

# NDTimeSeriesConfigure({{PORTPREFIX}}.STATS.{{tab}}_TS, {{QUEUE}}, 0, {{PORTPREFIX}}.STATS.{{tab}}, 1, 23)
# dbLoadRecords("$(ADCORE)/db/NDTimeSeries.template", "P={{DEVICE.P}}, R=:{{r_val_stats}}:TS:, PORT={{PORTPREFIX}}.STATS.{{tab}}_TS,ADDR=1, NDARRAY_PORT={{PORTPREFIX}}.{{tab}}, NDARRAY_ADDR=0, NCHANS={{STAT_NCHAN}}, ENABLED=1")

# NDStdArraysConfigure({{PORTPREFIX}}.ARRAYS.{{tab}}, {{QUEUE}}, 0, {{DEVICE.PORT}}, {{loop.index0}}, 0, 0, 0, 0, 1)
# dbLoadRecords("$(ADCORE)/db/NDStdArrays.template", "P={{DEVICE.P}},R=:{{r_val_array}}:, PORT={{PORTPREFIX}}.ARRAYS.{{tab}},ADDR=0, NDARRAY_PORT={{DEVICE.PORT}}, NDARRAY_ADDR={{loop.index0}}, ENABLED=1, FTVL=DOUBLE, TYPE=Float64, NCHANS={{STAT_NCHAN}}, XSIZE={{STAT_XSIZE}}, YSIZE=0, HIST_SIZE={{HIST_SIZE}}, NELEMENTS={{STAT_XSIZE}}")
# {% endfor %}

0 comments on commit f941f3c

Please sign in to comment.