sasdata.metadata module¶
Contains classes describing the metadata for a scattering run
The metadata is structures around the CANSas format version 1.1, found at https://www.cansas.org/formats/canSAS1d/1.1/doc/specification.html
Metadata from other file formats should be massaged to fit into the data classes presented here. Any useful metadata which cannot be included in these classes represent a bug in the CANSas format.
- class sasdata.metadata.Aperture(*, distance: sasdata.quantities.quantity.Quantity[float] | None, size: sasdata.metadata.Vec3 | None, size_name: str | None, name: str | None, type_: str | None)¶
Bases:
object- as_h5(group: Group)¶
Export data onto an HDF5 group
- static from_json(obj)¶
- name: str | None¶
- size_name: str | None¶
- summary()¶
- type_: str | None¶
- class sasdata.metadata.BeamSize(*, name: str | None, size: sasdata.metadata.Vec3 | None)¶
Bases:
object- as_h5(group: Group)¶
Export data onto an HDF5 group
- static from_json(obj)¶
- name: str | None¶
- class sasdata.metadata.Collimation(*, length: Quantity[float] | None, apertures: list[Aperture])¶
Bases:
objectClass to hold collimation information
- as_h5(group: Group)¶
Export data onto an HDF5 group
- static from_json(obj)¶
- summary()¶
- class sasdata.metadata.Detector(*, name: str | None, distance: Quantity[float] | None, offset: Vec3 | None, orientation: Rot3 | None, beam_center: Vec3 | None, pixel_size: Vec3 | None, slit_length: Quantity[float] | None)¶
Bases:
objectDetector information
- as_h5(group: Group)¶
Export data onto an HDF5 group
- static from_json(obj)¶
- name: str | None¶
- summary()¶
- class sasdata.metadata.Instrument(collimations: list[sasdata.metadata.Collimation], source: sasdata.metadata.Source | None, detector: list[sasdata.metadata.Detector])¶
Bases:
object- as_h5(group: Group)¶
Export data onto an HDF5 group
- collimations: list[Collimation]¶
- static from_json(obj)¶
- summary()¶
- class sasdata.metadata.MetaNode(*, name: str, attrs: dict[str, str], contents: str | sasdata.quantities.quantity.Quantity | numpy.ndarray | list['MetaNode'])¶
Bases:
object- attrs: dict[str, str]¶
- static from_json(obj)¶
- name: str¶
- to_string(header='')¶
Convert node to pretty printer string
- class sasdata.metadata.Metadata(*, title: str | None, run: list[str], definition: str | None, process: list[sasdata.metadata.Process], sample: sasdata.metadata.Sample | None, instrument: sasdata.metadata.Instrument | None, raw: sasdata.metadata.MetaNode)¶
Bases:
object- as_h5(f: Group)¶
Export data onto an HDF5 group
- definition: str | None¶
- static from_json(obj)¶
- instrument: Instrument | None¶
- run: list[str]¶
- summary()¶
- title: str | None¶
- class sasdata.metadata.MetadataEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)¶
Bases:
JSONEncoder- default(obj)¶
Implement this method in a subclass such that it returns a serializable object for
o, or calls the base implementation (to raise aTypeError).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return super().default(o)
- class sasdata.metadata.Process(*, name: str | None, date: str | None, description: str | None, terms: dict[str, str | Quantity[float]], notes: list[str])¶
Bases:
objectClass that holds information about the processes performed on the data.
- as_h5(group: Group)¶
Export data onto an HDF5 group
- date: str | None¶
- description: str | None¶
- static from_json(obj)¶
- name: str | None¶
- notes: list[str]¶
- single_line_desc()¶
Return a single line string representing the process
- summary()¶
- class sasdata.metadata.Rot3(*, roll: Quantity[float] | None, pitch: Quantity[float] | None, yaw: Quantity[float] | None)¶
Bases:
objectA measured rotation in 3-space
- as_h5(f: Group)¶
Export data onto an HDF5 group
- class sasdata.metadata.Sample(*, name: str | None, sample_id: str | None, thickness: Quantity[float] | None, transmission: float | None, temperature: Quantity[float] | None, position: Vec3 | None, orientation: Rot3 | None, details: list[str])¶
Bases:
objectClass to hold the sample description
- as_h5(f: Group)¶
Export data onto an HDF5 group
- details: list[str]¶
- static from_json(obj)¶
- name: str | None¶
- sample_id: str | None¶
- summary() str¶
- transmission: float | None¶
- class sasdata.metadata.Source(*, radiation: str | None, beam_shape: str | None, beam_size: sasdata.metadata.BeamSize | None, wavelength: sasdata.quantities.quantity.Quantity[float] | None, wavelength_min: sasdata.quantities.quantity.Quantity[float] | None, wavelength_max: sasdata.quantities.quantity.Quantity[float] | None, wavelength_spread: sasdata.quantities.quantity.Quantity[float] | None)¶
Bases:
object- as_h5(group: Group)¶
Export data onto an HDF5 group
- beam_shape: str | None¶
- static from_json(obj)¶
- radiation: str | None¶
- summary() str¶
- class sasdata.metadata.TagCollection(*, singular: set[str] = <factory>, variable: set[str] = <factory>)¶
Bases:
objectThe collected tags and their variability.
- singular: set[str]¶
- variable: set[str]¶
- class sasdata.metadata.Vec3(*, x: Quantity[float] | None, y: Quantity[float] | None, z: Quantity[float] | None)¶
Bases:
objectA three-vector of measured quantities
- as_h5(f: Group)¶
Export data onto an HDF5 group
- sasdata.metadata.access_meta(obj: dataclass, key: str) Any | None¶
Use a string accessor to locate a key from within the data object.
The basic grammar of these accessors explicitly match the python syntax for accessing the data. For example, to access the name field within the object person, you would call access_meta(person, “.name”). Similarly, lists and dicts are access with square brackets.
> assert access_meta(person, ‘.name’) == person.name > assert access_meta(person, ‘.phone.home’) == person.phone.home > assert access_meta(person, ‘.addresses[0].postal_code’) == person.address[0].postal_code > assert access_meta(person, ‘.children[“Taylor”]’) == person.children[“Taylor”]
Obviously, when the accessor is know ahead of time, access_meta provides no benefit over directly retrieving the data. However, when a data structure is loaded at runtime (e.g. the metadata of a neutron scattering file), then it isn’t possible to know in advance the location of the specific value that the user desires. access_meta allows the user to provide the location at runtime.
This function returns None when the key is not a valid address for any data within the structure. Since the leaf could be any type that is not a list, dict, or dataclass, the return type of the function is Any | None.
The list of locations within a structure is given by the meta_tags function.
- sasdata.metadata.collect_tags(objs: list[dataclass]) TagCollection¶
Identify uniform and varying data within a groups of data objects
The resulting TagCollection contains every accessor string that is valid for every object in the objs list. For example, if obj.name is a string for every obj in objs, then the string “.name” will be present in one of the two sets in the tags collection.
To be more specific, if obj.name exists and has the same value for every obj in objs, the string “.name” will be included in the singular set. If there are at least two distinct values for obj.name, then “.name” will be in the variable set.
- sasdata.metadata.meta_tags(obj: dataclass) list[str]¶
Find all leaf accessors from a data object.
The function treats the passed in object as a tree. Lists, dicts, and dataclasses are all treated as branches on the tree and any other type is treated as a leaf. The function then returns a list of strings, where each string is a “path” from the root of the tree to one leaf. The structure of the path is designed to mimic the python code to access that specific leaf value.
These accessors allow us to treat accessing entries within a structure as first class values. This list can then be presented to the user to allow them to select specific information within the larger structure. This is particularly important when plotting against a specific date value within the structure.
Example:
- >@dataclass
- class Thermometer:
temperature: float units: str params: list
> item = Example() > item.temperature = 273 > item.units = “K” > item.old_values = [{‘date’: ‘2025-08-12’, ‘temperature’: 300’}] > assert meta_tags(item) = [‘.temperature’, ‘.units’, ‘.old_values[0][“date”]’, ‘.old_values[0][“temperature”]’]
The actual value of the leaf object specified by a path can be retrieved with the access_meta function.