Skip to content

Scan metadata

Detectors publish their own scan metadata in addition to the scan data. Here, we describe how to add scan metadata, which is not automatically provided.

silx metadata screenshot

Refer to the Nexus standard when adding metadata.

Single scan metadata

To add metadata for a specific scan, use the scan_info argument.

loopscan(10, 0.1, diode3, scan_info={"instrument":{"mygroup":{"myvalue":10, "myvalue@units":"mm"}}})

This will create a group called "mygroup" under the "instrument" group of the scan. The group "mygroup" has one dataset which contains a value with a unit, 10 mm in this case.

Global scan metadata

You can register metadata generators in the setup of a BLISS session, which will fill the scan_info dictionary for every scan that runs in that session.

The get_user_scan_meta() function from bliss.scanning.scan_meta returns the scan metadata object. Each metadata category is accessible via the corresponding property.

The metadata category has a timing property, which allows to select when metadata has to be taken. timing can be a combination of:

  • scan_meta.META_TIMING.START
    • will be called at the beginning of the scan
  • scan_meta.META_TIMING.END
    • will be called at the end of the scan
    • will be called when the scan has been prepared (not started yet)

Default timing in general is START. Default timing for instrument category is END.

Then, the .set() method allows associating a name (or an object with a .name property) to a function, that has to return a dictionary to be stored as metadata for the object, for the category.

The following example adds the position label of a Multiple Position object under the ‘Instrument’ category to each scan in the current BLISS session:

from bliss.scanning import scan_meta

scan_meta_obj = scan_meta.get_user_scan_meta()

def generate_label(scan):
    return {"position_label": mp.position}

# mp is a BLISS Multiple Position object
scan_meta_obj.instrument.set(mp, generate_label)

The function receives the scan object as argument. In the example above, this argument is not used.

Each subsequent scan will have an ‘instrument’ section filled with the metadata:


The metadata does not need to be associated to a device. The metadata can also be registered as static information, instead of a metadata generating function. For example:

scan_meta_obj.instrument.set("mymetadata", {"myattenuator":
     "status": "in",
     "type": "aluminium",
     "thickness": 20.,
     "thickness@units": "um")


User scan meta are collected for each scan. In particular, in case of dynamic metadata (when a callback function returns a dictionary), the scan object is passed to be able to select whether metadata has to be returned or not.


Do not forget to remove items, if they are not needed. This can be done with .remove() on the different categories.