How to store/retrieve a Detector object#

In this how-to guide we will see how to store an existing Detector object (e.g. a CCD detector) into a file (e.g. hdf5) and how to load a file into a new Detector object.

By the end of the lesson you will know how to:

  • Save a CCD detector object into a HDF5 file with method Detector.to_hdf5

  • Load a CCD detector object from a HDF5 file with method Detector.from_hdf5

To create the CCD detector object, we will run the simple pipeline from the first simulation pipeline.

Get a new CCD detector object#

We are going to create a new CCD detector object based on our first simulation pipeline.

Run a simple pipeline#

Run a simple pipeline to create a new CCDDetector object.

# Create a temporary output folder. This is optional
from pathlib import Path
from tempfile import TemporaryDirectory

temp_output_folder = Path(TemporaryDirectory().name) / "output"

temp_output_folder
PosixPath('/tmp/tmpkz7gqumc/output')
import pyxel

# Load the configuration file
config = pyxel.load("exposure.yaml")

config.running_mode.outputs.output_folder = temp_output_folder

config.running_mode.outputs
ExposureOutputs<NO OUTPUT DIR, num_files=3>
# Run the pipeline
result = pyxel.run_mode(
    mode=config.running_mode,
    detector=config.ccd_detector,
    pipeline=config.pipeline,
)

print(f"output folder: {config.running_mode.outputs.current_output_folder}")


result
output folder: /tmp/tmpkz7gqumc/output/run_20250417_070653
<xarray.DatasetView> Size: 21MB
Dimensions:  (time: 3, y: 450, x: 450)
Coordinates:
  * y        (y) int64 4kB 0 1 2 3 4 5 6 7 8 ... 442 443 444 445 446 447 448 449
  * x        (x) int64 4kB 0 1 2 3 4 5 6 7 8 ... 442 443 444 445 446 447 448 449
  * time     (time) float64 24B 1.0 5.0 7.0
Data variables:
    photon   (time, y, x) float64 5MB 1.432e+04 1.321e+04 ... 2.964e+04
    charge   (time, y, x) float64 5MB 1.432e+04 1.321e+04 ... 2.964e+04
    pixel    (time, y, x) float64 5MB 1.432e+04 1.321e+04 ... 2.964e+04
    signal   (time, y, x) float64 5MB 1.432 1.321 1.309 ... 2.792 2.807 2.964
    image    (time, y, x) uint16 1MB 9386 8654 8576 8619 ... 18298 18398 19422
Attributes:
    pyxel version:  2.9
    running mode:   Exposure
# Get the detector object
detector = config.ccd_detector

detector
<pyxel.detectors.ccd.ccd.CCD at 0x7d583ef59c10>

Display detector#

pyxel.display_detector(detector)

Store ‘detector’ into a HDF5 file#

def get_file_size(filename):
    """Display filename's size."""

    size = Path(filename).stat().st_size / 1024 / 1024
    print(f"Size of file {filename!r}: {size:.2f} MB")
ccd_filename = temp_output_folder / "ccd.h5"

detector.to_hdf5(ccd_filename)
get_file_size(ccd_filename)
Size of file PosixPath('/tmp/tmpkz7gqumc/output/ccd.h5'): 81.27 MB

Create a new detector from the HDF5 file#

from pyxel.detectors import Detector

new_detector = Detector.from_hdf5(ccd_filename)

new_detector
<pyxel.detectors.ccd.ccd.CCD at 0x7d58320b42f0>

Check if the detector is valid#

detector == new_detector
True

Display the new detector#

pyxel.display_detector(new_detector)

Open the HDF5 file#

import h5py

f = h5py.File(ccd_filename)

f
<HDF5 file "ccd.h5" (mode r)>
# Get attributes
dict(f.attrs)
{'pyxel-version': '2.9', 'type': 'CCD', 'version': np.int64(1)}
# Get list of datasets
list(f)
['characteristics', 'data', 'environment', 'geometry']
list(f["/data"])
['charge', 'data', 'image', 'photon', 'pixel', 'scene', 'signal']
# Get a dataset
f["/data/image"]
<HDF5 dataset "image": shape (450, 450), type "<u2">
import numpy as np

np.array(f["/data/image"])
array([[18830, 17375, 17778, ..., 18017, 18161, 19374],
       [17411, 15558, 15438, ..., 16334, 16553, 18224],
       [17342, 15539, 15450, ..., 16160, 16429, 18130],
       ...,
       [17718, 15828, 15474, ..., 16249, 16393, 17979],
       [17920, 16169, 16411, ..., 16588, 16716, 18165],
       [19899, 18605, 17814, ..., 18298, 18398, 19422]],
      shape=(450, 450), dtype=uint16)
f.close()