Adding custom metadataΒΆ

Adding custom metadata is possible by adding data or coordinates to the dataset before it is saved.

For example, if we wanted to record the height at which a stage was set during the experiment, we could do so with the following lines of code:

>>> mcam.dataset['z_stage'] = 5E-3
>>> mcam.dataset
<xarray.Dataset>
Dimensions:                                (image_x: 6, image_y: 9, x: 4096, y: 3120)
Coordinates:
  * image_x                                (image_x) int64 0 1 2 3 4 5
  * image_y                                (image_y) int64 0 1 2 3 4 5 6 7 8
  * y                                      (y) int64 0 1 2 3 ... 3117 3118 3119
  * x                                      (x) int64 0 1 2 3 ... 4093 4094 4095
    exif_orientation                       int64 8
Data variables:
    images                                 (image_y, image_x, y, x) uint8 8...
    acquisition_count                      (image_y, image_x) int64 0 0 ... 0
    trigger                                (image_y, image_x) int64 0 0 ... 0
    exposure                               (image_y, image_x) float64 0.0 ....
    bayer_pattern                          (image_y, image_x) <U4 'gbrg' .....
    software_timestamp                     (image_y, image_x) datetime64[ns] ...
    digital_red_gain                       (image_y, image_x) float64 0.0 ....
    digital_green1_gain                    (image_y, image_x) float64 0.0 ....
    digital_blue_gain                      (image_y, image_x) float64 0.0 ....
    digital_green2_gain                    (image_y, image_x) float64 0.0 ....
    analog_gain                            (image_y, image_x) float64 0.0 ....
    digital_gain                           (image_y, image_x) float64 0.0 ....
    acquisition_index                      (image_y, image_x) int64 0 0 ... 0
    latest_acquisition_index               int64 0
    z_stage                                float64 0.005

We notice that a new coordinate z_stage was set and stores the value of 0.005.

Should we wish to add a coordinate that has dimensions that refer to the image_y, or image_x indices, we should first create the appropriate xarray object with the desired coordinates.

>>> import numpy as np
>>> from xarray import DataArray
>>> emission_filters = DataArray(
...     np.zeros(mcam.N_cameras), dims=['image_y', 'image_x'],
...     name='emission_filters')
>>> emission_filters[::2, ::2] = 540E-9
>>> emission_filters[1::2, ::2] = 560E-9
>>> emission_filters[1::2, 1::2] = 570E-9
>>> emission_filters[0::2, 1::2] = 580E-9
>>> mcam.dataset['emission_filters'] = emission_filters
>>> mcam.dataset
<xarray.Dataset>
Dimensions:                                (image_x: 6, image_y: 9, x: 4096, y: 3120)
Coordinates:
  * image_x                               (image_x) int64 0 1 2 3 4 5
  * image_y                               (image_y) int64 0 1 2 3 4 5 6 7 8
  * y                                      (y) int64 0 1 2 3 ... 3117 3118 3119
  * x                                      (x) int64 0 1 2 3 ... 4093 4094 4095
    exif_orientation                       int64 8
Data variables:
    mcam_data                              (image_y, image_x, y, x) uint8 8...
    acquisition_count                      (image_y, image_x) int64 0 0 ... 0
    trigger                                (image_y, image_x) int64 0 0 ... 0
    exposure                               (image_y, image_x) float64 0.0 ....
    bayer_pattern                          (image_y, image_x) <U4 'gbrg' .....
    software_timestamp                     (image_y, image_x) datetime64[ns] ...
    digital_red_gain                       (image_y, image_x) float64 0.0 ....
    digital_green1_gain                    (image_y, image_x) float64 0.0 ....
    digital_blue_gain                      (image_y, image_x) float64 0.0 ....
    digital_green2_gain                    (image_y, image_x) float64 0.0 ....
    analog_gain                            (image_y, image_x) float64 0.0 ....
    digital_gain                           (image_y, image_x) float64 0.0 ....
    acquisition_index                      (image_y, image_x) int64 0 0 ... 0
    latest_acquisition_index               int64 0
    z_stage                                float64 0.005
    emission_filters                       (image_y, image_x) float64 5.4e-...
>>> m.dataset.emission_filters
<xarray.DataArray 'emission_filters' (image_y: 9, image_x: 6)>
array([[5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07],
       [5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07],
       [5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07],
       [5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07],
       [5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07],
       [5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07],
       [5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07],
       [5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07],
       [5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07]])
Coordinates:
  * image_x                               (image_x) int64 0 1 2 3 4 5
  * image_y                               (image_y) int64 0 1 2 3 4 5 6 7 8
    exif_orientation                       int64 8
<xarray.DataArray 'emission_filters' (image_y: 6, image_x: 4)>
array([[5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07],
       [5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07],
       [5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07],
       [5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07],
       [5.4e-07, 5.8e-07, 5.4e-07, 5.8e-07],
       [5.6e-07, 5.7e-07, 5.6e-07, 5.7e-07]])
Coordinates:
  * image_y             (image_y) int64 0 1 2 3 4 5
  * image_x             (image_x) int64 0 1 2 3
    acquisition_count   (image_y, image_x) int64 2 2 2 2 3 3 2 ... 3 3 2 3 3 3
    bayer_pattern       (image_y, image_x) <U4 'bggr' 'bggr' ... 'bggr' 'bggr'
    camera_number       (image_y, image_x) int64 20 21 23 22 16 ... 6 0 1 3 2
    exposure            (image_y, image_x) int64 576 576 576 ... 576 576 576
    exposure_arb_units  (image_y, image_x) int64 576 576 576 ... 576 576 576
    exposure_seconds    (image_y, image_x) float64 0.05925 0.05925 ... 0.05925
    gain                (image_y, image_x) int64 4 4 4 4 4 4 4 ... 4 4 4 4 4 4
    trigger             (image_y, image_x) int64 142 142 142 ... 142 142 142
    z_stage             float64 0.005
    emission_filters    (image_y, image_x) float64 5.4e-07 5.8e-07 ... 5.7e-07

We now notice that our emission_filters coordinate has taken on values for the image_y and image_x coordinates that match the rest our data. If you think these features are useful to your workflow, we suggest you learn more about them by reading through the relevant parts of the xarray documentation.