.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/core/containers.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_core_containers.py: Using Container classes ======================= ``ctapipe.core.Container`` is the base class for all event-wise data classes in ctapipe. It works like a object-relational mapper, in that it defines a set of ``Fields`` along with their metadata (description, unit, default), which can be later translated automatically into an output table using a ``ctapipe.io.TableWriter``. .. GENERATED FROM PYTHON SOURCE LINES 12-21 .. code-block:: Python :lineno-start: 13 from functools import partial import numpy as np from astropy import units as u from ctapipe.containers import SimulatedShowerContainer from ctapipe.core import Container, Field, Map .. GENERATED FROM PYTHON SOURCE LINES 22-24 Let’s define a few example containers with some dummy fields in them: .. GENERATED FROM PYTHON SOURCE LINES 24-61 .. code-block:: Python :lineno-start: 26 class SubContainer(Container): junk = Field(-1, "Some junk") value = Field(0.0, "some value", unit=u.deg) class TelContainer(Container): # defaults should match the other requirements, e.g. the defaults # should have the correct unit. It most often also makes sense to use # an invalid value marker like nan for floats or -1 for positive integers # as default tel_id = Field(-1, "telescope ID number") # For mutable structures like lists, arrays or containers, use a `default_factory` function or class # not an instance to assure each container gets a fresh instance and there is no hidden # shared state between containers. image = Field(default_factory=lambda: np.zeros(10), description="camera pixel data") class EventContainer(Container): event_id = Field(-1, "event id number") tels_with_data = Field( default_factory=list, description="list of telescopes with data" ) sub = Field( default_factory=SubContainer, description="stuff" ) # a sub-container in the hierarchy # A Map is like a defaultdictionary with a specific container type as default. # This can be used to e.g. store a container per telescope # we use partial here to automatically get a function that creates a map with the correct container type # as default tel = Field(default_factory=partial(Map, TelContainer), description="telescopes") .. GENERATED FROM PYTHON SOURCE LINES 62-65 Basic features -------------- .. GENERATED FROM PYTHON SOURCE LINES 65-69 .. code-block:: Python :lineno-start: 66 ev = EventContainer() .. GENERATED FROM PYTHON SOURCE LINES 70-72 Check that default values are automatically filled in .. GENERATED FROM PYTHON SOURCE LINES 72-82 .. code-block:: Python :lineno-start: 73 print(ev.event_id) print(ev.sub) print(ev.tel) print(ev.tel.keys()) # default dict access will create container: print(ev.tel[1]) .. rst-class:: sphx-glr-script-out .. code-block:: none -1 {'junk': -1, 'value': 0.0} Map(__main__.TelContainer, {}) dict_keys([]) {'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'tel_id': -1} .. GENERATED FROM PYTHON SOURCE LINES 83-85 print the dict representation .. GENERATED FROM PYTHON SOURCE LINES 85-89 .. code-block:: Python :lineno-start: 86 print(ev) .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': -1, 'sub': {'junk': -1, 'value': 0.0}, 'tel': {1: {'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'tel_id': -1}}, 'tels_with_data': []} .. GENERATED FROM PYTHON SOURCE LINES 90-92 We also get docstrings “for free” .. GENERATED FROM PYTHON SOURCE LINES 92-94 .. code-block:: Python :lineno-start: 92 help(EventContainer) .. rst-class:: sphx-glr-script-out .. code-block:: none Help on class EventContainer in module __main__: class EventContainer(ctapipe.core.container.Container) | EventContainer(prefix=None, **fields) | | Attributes | ---------- | event_id : Field(default=-1) | event id number | tels_with_data : Field(default=builtins.list) | list of telescopes with data | sub : Field(default=__main__.SubContainer) | stuff | tel : Field(default=Map(__main__.TelContainer)) | telescopes | meta : dict | dict of attached metadata | prefix : str | Prefix attached to column names when saved to a table or file | | Method resolution order: | EventContainer | ctapipe.core.container.Container | builtins.object | | Data descriptors defined here: | | event_id | | meta | | prefix | | sub | | tel | | tels_with_data | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | default_prefix = 'event' | | fields = {'event_id': Field(default=-1), 'sub': Field(default=__main__... | | ---------------------------------------------------------------------- | Methods inherited from ctapipe.core.container.Container: | | __getitem__(self, key) | | __init__(self, prefix=None, **fields) | Initialize self. See help(type(self)) for accurate signature. | | __repr__(self) | Return repr(self). | | __setitem__(self, key, value) | | __str__(self) | Return str(self). | | as_dict(self, recursive=False, flatten=False, add_prefix=False, add_key=False) | Convert the `Container` into a dictionary | | Parameters | ---------- | recursive: bool | sub-Containers should also be converted to dicts | flatten: type | return a flat dictionary, with any sub-field keys generated | by appending the sub-Container name. | add_prefix: bool | include the container's prefix in the name of each item | add_key: bool | include map key | | items(self, add_prefix=False) | Generator over (key, value) pairs for the items | | keys(self) | Get the keys of the container | | reset(self) | Reset all values back to their default values | | Parameters | ---------- | recursive: bool | If true, also reset all sub-containers | | update(self, **values) | update more than one parameter at once (e.g. ``update(x=3,y=4)`` | or ``update(**dict_of_values)``) | | validate(self) | Check that all fields in the Container have the expected characteristics (as | defined by the Field metadata). This is not intended to be run every time a | Container is filled, since it is slow, only for testing a first event. | | Raises | ------ | ValueError: | if the Container's values are not valid | | values(self) | Get the values of the container .. GENERATED FROM PYTHON SOURCE LINES 95-97 .. code-block:: Python :lineno-start: 95 help(SubContainer) .. rst-class:: sphx-glr-script-out .. code-block:: none Help on class SubContainer in module __main__: class SubContainer(ctapipe.core.container.Container) | SubContainer(prefix=None, **fields) | | Attributes | ---------- | junk : Field(default=-1) | Some junk | value : Field(default=0.0, unit=deg) | some value | meta : dict | dict of attached metadata | prefix : str | Prefix attached to column names when saved to a table or file | | Method resolution order: | SubContainer | ctapipe.core.container.Container | builtins.object | | Data descriptors defined here: | | junk | | meta | | prefix | | value | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | default_prefix = 'sub' | | fields = {'junk': Field(default=-1), 'value': Field(default=0.0, unit=... | | ---------------------------------------------------------------------- | Methods inherited from ctapipe.core.container.Container: | | __getitem__(self, key) | | __init__(self, prefix=None, **fields) | Initialize self. See help(type(self)) for accurate signature. | | __repr__(self) | Return repr(self). | | __setitem__(self, key, value) | | __str__(self) | Return str(self). | | as_dict(self, recursive=False, flatten=False, add_prefix=False, add_key=False) | Convert the `Container` into a dictionary | | Parameters | ---------- | recursive: bool | sub-Containers should also be converted to dicts | flatten: type | return a flat dictionary, with any sub-field keys generated | by appending the sub-Container name. | add_prefix: bool | include the container's prefix in the name of each item | add_key: bool | include map key | | items(self, add_prefix=False) | Generator over (key, value) pairs for the items | | keys(self) | Get the keys of the container | | reset(self) | Reset all values back to their default values | | Parameters | ---------- | recursive: bool | If true, also reset all sub-containers | | update(self, **values) | update more than one parameter at once (e.g. ``update(x=3,y=4)`` | or ``update(**dict_of_values)``) | | validate(self) | Check that all fields in the Container have the expected characteristics (as | defined by the Field metadata). This is not intended to be run every time a | Container is filled, since it is slow, only for testing a first event. | | Raises | ------ | ValueError: | if the Container's values are not valid | | values(self) | Get the values of the container .. GENERATED FROM PYTHON SOURCE LINES 98-100 values can be set as normal for a class: .. GENERATED FROM PYTHON SOURCE LINES 100-104 .. code-block:: Python :lineno-start: 101 ev.event_id = 100 ev.event_id .. rst-class:: sphx-glr-script-out .. code-block:: none 100 .. GENERATED FROM PYTHON SOURCE LINES 105-107 .. code-block:: Python :lineno-start: 105 ev.as_dict() # by default only shows the bare items, not sub-containers (See later) .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': 100, 'tels_with_data': [], 'sub': __main__.SubContainer: junk: Some junk with default -1 value: some value with default 0.0 [deg], 'tel': Map(__main__.TelContainer, {1: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None})} .. GENERATED FROM PYTHON SOURCE LINES 108-111 .. code-block:: Python :lineno-start: 108 ev.as_dict(recursive=True) .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': 100, 'tels_with_data': [], 'sub': {'junk': -1, 'value': 0.0}, 'tel': {1: {'tel_id': -1, 'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])}}} .. GENERATED FROM PYTHON SOURCE LINES 112-115 and we can add a few of these to the parent container inside the tel dict: .. GENERATED FROM PYTHON SOURCE LINES 115-120 .. code-block:: Python :lineno-start: 116 ev.tel[10] = TelContainer() ev.tel[5] = TelContainer() ev.tel[42] = TelContainer() .. GENERATED FROM PYTHON SOURCE LINES 121-122 because we are using a default_factory to handle mutable defaults, the images are actually different: .. GENERATED FROM PYTHON SOURCE LINES 122-125 .. code-block:: Python :lineno-start: 122 ev.tel[42].image is ev.tel[32] .. rst-class:: sphx-glr-script-out .. code-block:: none False .. GENERATED FROM PYTHON SOURCE LINES 126-129 Be careful to use the ``default_factory`` mechanism for mutable fields, see this **negative** example: .. GENERATED FROM PYTHON SOURCE LINES 129-149 .. code-block:: Python :lineno-start: 131 class DangerousContainer(Container): image = Field( np.zeros(10), description=( "Attention!!!! Globally mutable shared state. Use default_factory instead" ), ) c1 = DangerousContainer() c2 = DangerousContainer() c1.image[5] = 9999 print(c1.image) print(c2.image) print(c1.image is c2.image) .. rst-class:: sphx-glr-script-out .. code-block:: none [ 0. 0. 0. 0. 0. 9999. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 9999. 0. 0. 0. 0.] True .. GENERATED FROM PYTHON SOURCE LINES 150-153 .. code-block:: Python :lineno-start: 150 ev.tel .. rst-class:: sphx-glr-script-out .. code-block:: none Map(__main__.TelContainer, {1: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 10: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 5: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 42: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 32: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None}) .. GENERATED FROM PYTHON SOURCE LINES 154-157 Conversion to dictionaries -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 157-160 .. code-block:: Python :lineno-start: 158 ev.as_dict() .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': 100, 'tels_with_data': [], 'sub': __main__.SubContainer: junk: Some junk with default -1 value: some value with default 0.0 [deg], 'tel': Map(__main__.TelContainer, {1: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 10: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 5: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 42: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None, 32: __main__.TelContainer: tel_id: telescope ID number with default -1 image: camera pixel data with default None})} .. GENERATED FROM PYTHON SOURCE LINES 161-164 .. code-block:: Python :lineno-start: 161 ev.as_dict(recursive=True, flatten=False) .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': 100, 'tels_with_data': [], 'sub': {'junk': -1, 'value': 0.0}, 'tel': {1: {'tel_id': -1, 'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])}, 10: {'tel_id': -1, 'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])}, 5: {'tel_id': -1, 'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])}, 42: {'tel_id': -1, 'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])}, 32: {'tel_id': -1, 'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])}}} .. GENERATED FROM PYTHON SOURCE LINES 165-168 for serialization to a table, we can even flatten the output into a single set of columns .. GENERATED FROM PYTHON SOURCE LINES 168-172 .. code-block:: Python :lineno-start: 169 ev.as_dict(recursive=True, flatten=True) .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': 100, 'tels_with_data': [], 'junk': -1, 'value': 0.0, 'tel_id': -1, 'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])} .. GENERATED FROM PYTHON SOURCE LINES 173-176 Setting and clearing values --------------------------- .. GENERATED FROM PYTHON SOURCE LINES 176-180 .. code-block:: Python :lineno-start: 177 ev.tel[5].image[:] = 9 print(ev) .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': 100, 'sub': {'junk': -1, 'value': 0.0}, 'tel': {1: {'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'tel_id': -1}, 5: {'image': array([9., 9., 9., 9., 9., 9., 9., 9., 9., 9.]), 'tel_id': -1}, 10: {'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'tel_id': -1}, 32: {'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'tel_id': -1}, 42: {'image': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'tel_id': -1}}, 'tels_with_data': []} .. GENERATED FROM PYTHON SOURCE LINES 181-185 .. code-block:: Python :lineno-start: 181 ev.reset() ev.as_dict(recursive=True) .. rst-class:: sphx-glr-script-out .. code-block:: none {'event_id': -1, 'tels_with_data': [], 'sub': {'junk': -1, 'value': 0.0}, 'tel': {}} .. GENERATED FROM PYTHON SOURCE LINES 186-189 look at a pre-defined Container ------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 189-193 .. code-block:: Python :lineno-start: 191 help(SimulatedShowerContainer) .. rst-class:: sphx-glr-script-out .. code-block:: none Help on class SimulatedShowerContainer in module ctapipe.containers: class SimulatedShowerContainer(ctapipe.core.container.Container) | SimulatedShowerContainer(prefix=None, **fields) | | Attributes | ---------- | energy : Field(default=nan TeV, unit=TeV) | Simulated Energy | alt : Field(default=nan deg, unit=deg) | Simulated altitude | az : Field(default=nan deg, unit=deg) | Simulated azimuth | core_x : Field(default=nan m, unit=m) | Simulated core position (x) | core_y : Field(default=nan m, unit=m) | Simulated core position (y) | h_first_int : Field(default=nan m, unit=m) | Height of first interaction | x_max : Field(default=nan g / cm2, unit=g / cm2) | Simulated Xmax value | starting_grammage : Field(default=nan g / cm2, unit=g / cm2) | Grammage (mass overburden) where the particle was injected into the atmosphere | shower_primary_id : Field(default=32767) | Simulated shower primary ID 0 (gamma), 1(e-),2(mu-), 100*A+Z for nucleons and nuclei,negative for antimatter. | meta : dict | dict of attached metadata | prefix : str | Prefix attached to column names when saved to a table or file | | Method resolution order: | SimulatedShowerContainer | ctapipe.core.container.Container | builtins.object | | Data descriptors defined here: | | alt | | az | | core_x | | core_y | | energy | | h_first_int | | meta | | prefix | | shower_primary_id | | starting_grammage | | x_max | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __slotnames__ = ['energy', 'alt', 'az', 'core_x', 'core_y', 'h_first_i... | | default_prefix = 'true' | | fields = {'alt': Field(default=nan deg, unit=deg), 'az': Field(default... | | ---------------------------------------------------------------------- | Methods inherited from ctapipe.core.container.Container: | | __getitem__(self, key) | | __init__(self, prefix=None, **fields) | Initialize self. See help(type(self)) for accurate signature. | | __repr__(self) | Return repr(self). | | __setitem__(self, key, value) | | __str__(self) | Return str(self). | | as_dict(self, recursive=False, flatten=False, add_prefix=False, add_key=False) | Convert the `Container` into a dictionary | | Parameters | ---------- | recursive: bool | sub-Containers should also be converted to dicts | flatten: type | return a flat dictionary, with any sub-field keys generated | by appending the sub-Container name. | add_prefix: bool | include the container's prefix in the name of each item | add_key: bool | include map key | | items(self, add_prefix=False) | Generator over (key, value) pairs for the items | | keys(self) | Get the keys of the container | | reset(self) | Reset all values back to their default values | | Parameters | ---------- | recursive: bool | If true, also reset all sub-containers | | update(self, **values) | update more than one parameter at once (e.g. ``update(x=3,y=4)`` | or ``update(**dict_of_values)``) | | validate(self) | Check that all fields in the Container have the expected characteristics (as | defined by the Field metadata). This is not intended to be run every time a | Container is filled, since it is slow, only for testing a first event. | | Raises | ------ | ValueError: | if the Container's values are not valid | | values(self) | Get the values of the container .. GENERATED FROM PYTHON SOURCE LINES 194-198 .. code-block:: Python :lineno-start: 194 shower = SimulatedShowerContainer() shower .. rst-class:: sphx-glr-script-out .. code-block:: none ctapipe.containers.SimulatedShowerContainer: energy: Simulated Energy with default nan TeV [TeV] alt: Simulated altitude with default nan deg [deg] az: Simulated azimuth with default nan deg [deg] core_x: Simulated core position (x) with default nan m [m] core_y: Simulated core position (y) with default nan m [m] h_first_int: Height of first interaction with default nan m [m] x_max: Simulated Xmax value with default nan g / cm2 [g / cm2] starting_grammage: Grammage (mass overburden) where the particle was injected into the atmosphere with default nan g / cm2 [g / cm2] shower_primary_id: Simulated shower primary ID 0 (gamma), 1(e-),2(mu-), 100*A+Z for nucleons and nuclei,negative for antimatter. with default 32767 .. GENERATED FROM PYTHON SOURCE LINES 199-205 Container prefixes ------------------ To store the same container in the same table in a file or give more information, containers support setting a custom prefix: .. GENERATED FROM PYTHON SOURCE LINES 205-213 .. code-block:: Python :lineno-start: 206 c1 = SubContainer(junk=5, value=3, prefix="foo") c2 = SubContainer(junk=10, value=9001, prefix="bar") # create a common dict with data from both containers: d = c1.as_dict(add_prefix=True) d.update(c2.as_dict(add_prefix=True)) d .. rst-class:: sphx-glr-script-out .. code-block:: none {'foo_junk': 5, 'foo_value': 3, 'bar_junk': 10, 'bar_value': 9001} .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.016 seconds) .. _sphx_glr_download_auto_examples_core_containers.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: containers.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: containers.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: containers.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_