ts_ids_components.xrd.datacube module#
Two-theta scan datacube components for XRD IDSs.
The scan modes where 2-theta is the varying dimension are called 2-Theta
Scans (e.g. coupled reflection, grazing incidence, reflectivity,
transmission) – as opposed to modes like rocking curves, pole figures, or
reciprocal space maps, whose primary scan variable is a different axis
entirely (see below). TwoThetaScanDatacube models one 2-Theta
Scan’s raw per-point data: every value recorded at each step, not just a
2-theta/intensity pair:
Bruker D8 Advance
RawData0.xml: eachDatumrow iseffective_time_per_step, scan_point_index, 2Theta, Theta, Intensity(5 values).Thetamoves in lockstep with2Thetain the D8 Advance’s coupled Theta/Theta scan.Malvern Panalytical Empyrean
.xrdml: a coupled scan varies both2ThetaandOmegasimultaneously, withPhifixed.Rigaku
Profile*.txt: each row is2Theta, Intensity, Weight(3 values);Weightis the RAS-format attenuation/correction factor applied when an attenuator is switched in near the direct beam. Rigaku’s widerMesurementConditions*.xmlaxis table also listsOmega,Chi, and other hardware axes available on the same platform.
Every 2-Theta Scan mode – regardless of vendor or specific
application – varies 2-theta as its dimension with intensity as a measure;
that dimension/measure shape, not “pharma powder XRD” as such, is the precise
criterion TwoThetaScanDatacube supports. Scan modes with a
different primary scan variable (rocking curves, pole figures, reciprocal
space maps – primary dimension is omega, phi, or a reciprocal-space grid,
not 2-theta) aren’t 2-Theta Scans, so they don’t fit this shape and have no
datacube component defined here yet. If a customer needs one of those modes,
it should get its own datacube class following the same fixed-length/
vendor-subclass pattern as TwoThetaScanDatacube below, not a
variant of TwoThetaScanDatacube itself. So TwoThetaScanDatacube’s
one Dimension is
2-theta itself (name="two_theta", unit="DegreeAngle", real angle
values), not a synthetic index. Every other per-point column –
Theta/Omega (which covary 1:1 with 2-theta rather than varying
independently of it) and ancillary fields like Weight or
effective_time_per_step – becomes one named XrdMeasure
sharing that one 2-theta dimension: no DataCube subclass anywhere in this
repo or the wider platform models a quantity that covaries with the primary
axis as a second Dimension – that’s reserved for genuinely independent
grid axes (e.g. chromatography’s wavelength x time PDA cube), which this
data isn’t.
intensity is a required measure on every TwoThetaScanDatacube,
and (as counts) a mandatory, non-optional element in Empyrean’s own XRDML
schema regardless of scan mode.
ts_ids_core.schema.DataCube’s measures/dimensions fixed_length
is a whole-class constant, not additive across inheritance: a vendor
subclass can’t “add more measures” to an inherited count, it must restate its
own total. So TwoThetaScanDatacube fixes dimensions at
exactly 1 (identical for every vendor, never restated by subclasses) and
provides fk_method/fk_run/fk_system/fk_sample/name/
description once for everyone, but each vendor’s own subclass still
restates measures with
its own total fixed_length (e.g. 4 for Bruker’s remaining Datum
columns once 2-theta becomes the dimension) – the two_theta dimension
name and intensity measure presence checks run on every subclass
regardless, since they’re a validator, not a structural constraint:
class VendorTwoThetaScanDatacube(TwoThetaScanDatacube):
# one XrdMeasure per raw per-point column for this vendor, other
# than 2-theta itself (the dimension), e.g. for Bruker: theta,
# intensity, effective_time_per_step, scan_point_index
measures: Required[Annotated[List[XrdMeasure], fixed_length(4)]]
Every other axis is still trivially found by looking up measures by
name.
See ts_ids_components.xrd.datacube_raw for
RawTwoThetaScanDatacube,
which preserves each datacube’s untouched raw text alongside it.
- TWO_THETA_SCAN_DIMENSION_NAME = 'two theta'#
Standard name for a
TwoThetaScanDatacube’s one required dimension. See the module docstring above for why 2-theta – not a synthetic index – is the dimension every vendor’s datacube shares.
- Model XrdMeasure[source]#
Bases:
MeasureBaseA single named per-point quantity in a
TwoThetaScanDatacube(e.g."theta","omega","intensity","weight","effective_time_per_step"), sharing the datacube’s oneTWO_THETA_SCAN_DIMENSION_NAMEdimension. See the module docstring above for why any axis that covaries with 2-theta – rather than varying independently of it – is modeled as a measure rather than a second dimension.Show JSON schema
{ "description": "A single named per-point quantity in a :py:class:`TwoThetaScanDatacube`\n(e.g. ``\"theta\"``, ``\"omega\"``, ``\"intensity\"``, ``\"weight\"``,\n``\"effective_time_per_step\"``), sharing the datacube's one\n:py:data:`TWO_THETA_SCAN_DIMENSION_NAME` dimension. See the module\ndocstring above for why any axis that covaries with 2-theta -- rather\nthan varying independently of it -- is modeled as a measure rather than\na second dimension.", "type": "object", "properties": { "name": { "type": [ "string", "null" ] }, "unit": { "type": [ "string", "null" ] }, "value": { "items": { "type": [ "number", "null" ] }, "type": "array" } }, "additionalProperties": false, "required": [ "name", "unit", "value" ] }
- Validators:
validate_value_shape»value
- Model TwoThetaScanDatacube[source]#
Bases:
DataCubeBase for 2-Theta Scan datacubes. See the module docstring above for the raw file evidence behind this shape. Carries a pk so its raw counterpart (RawTwoThetaScanDatacube <ts_ids_components.xrd.datacube_raw.RawTwoThetaScanDatacube>) can link directly back to it – see
ts_ids_components.xrd.datacube_raw. Also carries four foreign keys, linking each datacube to the scan (in methods, seets_ids_components.xrd.method) via fk_method, the run (in runs, seets_ids_components.xrd.run) via fk_run, the system (in systems, seets_ids_components.xrd.system) via fk_system, and the sample (in samples, seets_ids_components.xrd.sample) via fk_sample.Show JSON schema
{ "description": "Base for 2-Theta Scan datacubes. See the module docstring above for the\nraw file evidence behind this shape. Carries a `pk` so its raw\ncounterpart (`RawTwoThetaScanDatacube\n<ts_ids_components.xrd.datacube_raw.RawTwoThetaScanDatacube>`) can link\ndirectly back to it -- see :py:mod:`ts_ids_components.xrd.datacube_raw`.\nAlso carries four foreign keys, linking each datacube to the scan (in\n`methods`, see :py:mod:`ts_ids_components.xrd.method`) via `fk_method`,\nthe run (in `runs`, see :py:mod:`ts_ids_components.xrd.run`) via\n`fk_run`, the system (in `systems`, see\n:py:mod:`ts_ids_components.xrd.system`) via `fk_system`, and the sample\n(in `samples`, see :py:mod:`ts_ids_components.xrd.sample`) via\n`fk_sample`.", "type": "object", "properties": { "name": { "type": "string" }, "measures": { "items": { "$ref": "#/definitions/XrdMeasure" }, "maxItems": 1, "minItems": 1, "type": "array" }, "dimensions": { "items": { "$ref": "#/definitions/Dimension" }, "maxItems": 1, "minItems": 1, "type": "array" }, "pk": { "@primary_key": true, "description": "Primary key for this datacube, referenced by the raw datacube (in `datacubes_raw`) preserving its untouched source text.", "type": "string" }, "fk_method": { "@foreign_key": "/properties/methods/items/properties/pk", "description": "Foreign key to the scan (in `methods`) that produced this datacube. A single raw file can contain multiple independent scans, e.g. repeat measurements sharing one autosampler batch submission.", "type": "string" }, "fk_run": { "@foreign_key": "/properties/runs/items/properties/pk", "description": "Foreign key to the run (in `runs`) that produced this datacube.", "type": "string" }, "fk_system": { "@foreign_key": "/properties/systems/items/properties/pk", "description": "Foreign key to the system (in `systems`) that produced this datacube.", "type": "string" }, "fk_sample": { "@foreign_key": "/properties/samples/items/properties/pk", "description": "Foreign key to the sample (in `samples`) this datacube was measured on.", "type": "string" }, "description": { "type": [ "string", "null" ] } }, "additionalProperties": false, "required": [ "name", "measures", "dimensions", "pk", "fk_method", "fk_run", "fk_system", "fk_sample" ], "definitions": { "Dimension": { "additionalProperties": false, "description": "A dimension of a DataCube", "properties": { "name": { "type": [ "string", "null" ] }, "unit": { "type": [ "string", "null" ] }, "scale": { "items": { "type": [ "number", "null" ] }, "type": "array" } }, "required": [ "name", "unit", "scale" ], "type": "object" }, "XrdMeasure": { "additionalProperties": false, "description": "A single named per-point quantity in a :py:class:`TwoThetaScanDatacube`\n(e.g. ``\"theta\"``, ``\"omega\"``, ``\"intensity\"``, ``\"weight\"``,\n``\"effective_time_per_step\"``), sharing the datacube's one\n:py:data:`TWO_THETA_SCAN_DIMENSION_NAME` dimension. See the module\ndocstring above for why any axis that covaries with 2-theta -- rather\nthan varying independently of it -- is modeled as a measure rather than\na second dimension.", "properties": { "name": { "type": [ "string", "null" ] }, "unit": { "type": [ "string", "null" ] }, "value": { "items": { "type": [ "number", "null" ] }, "type": "array" } }, "required": [ "name", "unit", "value" ], "type": "object" } } }
- Validators:
two_theta_dimension_and_intensity_measure_present»all fields
- field fk_method: str#
Foreign key to the scan (in methods) that produced this datacube. A single raw file can contain multiple independent scans, e.g. repeat measurements sharing one autosampler batch submission.
- Constraints:
func = <function validate_uuid at 0x7f1493ac61f0>
json_schema_input_type = PydanticUndefined
ids_field_arg = primary_key
pk_reference_field = @foreign_key
- field fk_run: str#
Foreign key to the run (in runs) that produced this datacube.
- Constraints:
func = <function validate_uuid at 0x7f1493ac61f0>
json_schema_input_type = PydanticUndefined
ids_field_arg = primary_key
pk_reference_field = @foreign_key
- field fk_sample: str#
Foreign key to the sample (in samples) this datacube was measured on.
- Constraints:
func = <function validate_uuid at 0x7f1493ac61f0>
json_schema_input_type = PydanticUndefined
ids_field_arg = primary_key
pk_reference_field = @foreign_key
- field fk_system: str#
Foreign key to the system (in systems) that produced this datacube.
- Constraints:
func = <function validate_uuid at 0x7f1493ac61f0>
json_schema_input_type = PydanticUndefined
ids_field_arg = primary_key
pk_reference_field = @foreign_key
- field measures: List[XrdMeasure]#
- Constraints:
min_length = 1
max_length = 1
- field pk: str#
Primary key for this datacube, referenced by the raw datacube (in datacubes_raw) preserving its untouched source text.
- Constraints:
func = <function validate_uuid at 0x7f1493ac61f0>
json_schema_input_type = PydanticUndefined
- validator two_theta_dimension_and_intensity_measure_present » all fields[source]#
Every TwoThetaScanDatacube’s one dimension must be two_theta, and intensity must be present as a measure. This is the precise criterion for what this component supports: any 2-Theta Scan, i.e. any scan with 2-theta as its dimension and intensity as a measure, not specifically pharma powder XRD. See the module docstring above for the scan modes (rocking curves, pole figures, reciprocal space maps – primary dimension is omega, phi, or a reciprocal-space grid, not 2-theta) this intentionally doesn’t support.
- Validates:
all fields