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.
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
scan_meta.META_TIMING.PREPARED
- 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":
{"@NX_class":"NXattenuator",
"status": "in",
"type": "aluminium",
"thickness": 20.,
"thickness@units": "um")
Note
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.
Note
Do not forget to remove items, if they are not needed. This can be done with .remove()
on
the different categories.