Attaching Metadata to Data
The DataComponent
class allows attaching arbitrary metadata to any instance of Data
.
The example below demonstrates this by attaching an ImageInfoDataComponent
,
which can hold information such as patient ID, patient name, etc., to Data
, e.g. a SharedImageSet
.
>>> import imfusion
>>> sis = imfusion.SharedImageSet()
>>> sis.components.add(imfusion.ImageInfoDataComponent())
ImageInfoDataComponent(
patient_id="",
patient_name="",
...
)
>>> sis.components.image_info.patient_id = "my_patient_id"
There is a variety of built-in DataComponent
available in the ImFusion SDK. The full list of DataComponent
can be obtained with available_data_components()
.
Note
The available_data_components()
function returns all components that are implemented in the ImFusion C++ SDK,
including those that are not yet available in the Python bindings and hence do not have a corresponding specialized class
in the imfusion
Python module.
Regardless of whether Python bindings exist, create_data_component()
enables creating every
DataComponent
in Python:
>>> prop = imfusion.Properties({"patientId": "my_patient_id"})
>>> image_info_data_comp = imfusion.create_data_component("ImageInfoDataComponent", prop)
>>> image_info_data_comp
ImageInfoDataComponent(
patient_id="my_patient_id",
patient_name="",
...
)
As with any DataComponent
, the actual data fields of ImageInfoDataComponent
are
accessible through Python attributes:
>>> image_info_data_comp.patient_id
'my_patient_id'
Note
There is a difference in naming conventions between the DataComponent
’s Python
attributes (e.g., patient_id) and the corresponding Properties
keys (e.g., patientId).
The former are listed in the documentation of the specific class, e.g., ImageInfoDataComponent
.
To view the keys used in Properties
, you can instantiate the respective data component
with its default constructor and inspect the parameters of its Properties
, as in the example below:
>>> image_info_data_comp = imfusion.create_data_component("ImageInfoDataComponent")
>>> prop: imfusion.Properties = image_info_data_comp.configuration()
>>> prop.params()
['patientId', 'patientName', ...]
Properties
may also be used to modify the data component after it has been created:
>>> image_info_data_comp = imfusion.create_data_component("ImageInfoDataComponent")
>>> prop = imfusion.Properties({"patientId": "my_patient_id"})
>>> image_info_data_comp.configure(prop)
Provided the data component is available in our Python bindings, you can of course also instantiate it directly:
>>> image_info_data_comp = imfusion.ImageInfoDataComponent()
The data component system is also extensible from Python. You can create your own data components by subclassing DataComponent
:
>>> class MyComponent(imfusion.DataComponent, accessor_name="my_component"):
... def __init__(self, custom_info: str=""):
... super().__init__()
... self.custom_info: str = custom_info
...
... def configure(self, properties: imfusion.Properties) -> None:
... self.custom_info = str(properties["custom_info"])
...
... def configuration(self) -> imfusion.Properties:
... return imfusion.Properties({"custom_info": self.custom_info})
...
... def __eq__(self, other: "MyComponent") -> bool:
... return self.custom_info == other.custom_info
...
... def __repr__(self) -> str:
... return f"MyComponent(custom_info={self.custom_info!r})"
With the above class definition, you can attach your customized information to, e.g., any SharedImageSet
:
>>> sis = imfusion.SharedImageSet()
>>> sis.components.add(MyComponent(custom_info="my_custom_info"))
MyComponent(custom_info='my_custom_info')
>>> assert sis.components.my_component.custom_info == "my_custom_info"
The value assigned to accessor_name will be used as the name of the Python attribute that is automatically created on the list of data components, i.e., my_component is now an attribute of sis.components.
The methods configure()
and configuration()
are part of the
Configurable
interface and are required to support serialization/deserialization of the component.
If they are not implemented, the component will not persist when the respective Data
instance is, e.g., written to disk.