From 309218f46eb6b121d3dac152f4751c308b379f87 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Mon, 19 Oct 2026 13:12:25 +0100 Subject: [PATCH 1/9] Add Abstract Base Class for Metadata serialisation information --- sasdata/metadata.py | 61 +++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/sasdata/metadata.py b/sasdata/metadata.py index 7a7084c7..59c3daec 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -9,12 +9,13 @@ """ +import abc import base64 import json import re from dataclasses import dataclass, field, fields, is_dataclass from textwrap import dedent -from typing import Any +from typing import Any, Self import h5py import numpy as np @@ -32,19 +33,41 @@ def from_json_quantity(obj: dict) -> Quantity | None: return Quantity(obj["value"], parse_unit(obj["units"])) +class MetadataSerial(abc.ABC): + """Abstract class for metadata which can be serialisaed and deserialised""" + + @classmethod + @abc.abstractmethod + def from_json(cls, obj: dict) -> Self | None: + """Load this metadata from a JSON dict""" + return None + + @abc.abstractmethod + def as_h5(self, f: h5py.Group): + """Export data onto an HDF5 group""" + pass + + +class MetadataSummarisable(MetadataSerial): + + @abc.abstractmethod + def summary(self) -> str: + return "" + + @dataclass(kw_only=True) -class Vec3: +class Vec3(MetadataSerial): """A three-vector of measured quantities""" x: Quantity[float] | None y: Quantity[float] | None z: Quantity[float] | None - @staticmethod - def from_json(obj: dict) -> Quantity | None: + @classmethod + def from_json(cls, obj: dict) -> Self | None: if obj is None: return None - return Vec3( + return cls( x=from_json_quantity(obj["x"]), y=from_json_quantity(obj["y"]), z=from_json_quantity(obj["z"]), @@ -61,7 +84,7 @@ def as_h5(self, f: h5py.Group): @dataclass(kw_only=True) -class Rot3: +class Rot3(MetadataSerial): """A measured rotation in 3-space""" roll: Quantity[float] | None @@ -95,11 +118,11 @@ def serialise_json(self): data["yaw"] = self.yaw.serialise_json() return data - @staticmethod - def from_json(obj: dict) -> Quantity | None: + @classmethod + def from_json(cls, obj: dict) -> Self | None: if obj is None: return None - return Rot3( + return cls( roll=from_json_quantity(obj["roll"]), pitch=from_json_quantity(obj["pitch"]), yaw=from_json_quantity(obj["yaw"]), @@ -116,7 +139,7 @@ def as_h5(self, f: h5py.Group): @dataclass(kw_only=True) -class Detector: +class Detector(MetadataSummarisable): """ Detector information """ @@ -172,7 +195,7 @@ def as_h5(self, group: h5py.Group): @dataclass(kw_only=True) -class Aperture: +class Aperture(MetadataSummarisable): distance: Quantity[float] | None size: Vec3 | None size_name: str | None @@ -213,7 +236,7 @@ def as_h5(self, group: h5py.Group): @dataclass(kw_only=True) -class Collimation: +class Collimation(MetadataSummarisable): """ Class to hold collimation information """ @@ -240,7 +263,7 @@ def as_h5(self, group: h5py.Group): @dataclass(kw_only=True) -class BeamSize: +class BeamSize(MetadataSerial): name: str | None size: Vec3 | None @@ -257,7 +280,7 @@ def as_h5(self, group: h5py.Group): @dataclass(kw_only=True) -class Source: +class Source(MetadataSummarisable): radiation: str | None beam_shape: str | None beam_size: BeamSize | None @@ -309,7 +332,7 @@ def as_h5(self, group: h5py.Group): @dataclass(kw_only=True) -class Sample: +class Sample(MetadataSummarisable): """ Class to hold the sample description """ @@ -368,7 +391,7 @@ def as_h5(self, f: h5py.Group): @dataclass(kw_only=True) -class Process: +class Process(MetadataSummarisable): """ Class that holds information about the processes performed on the data. @@ -438,7 +461,7 @@ def as_h5(self, group: h5py.Group): @dataclass -class Instrument: +class Instrument(MetadataSummarisable): collimations: list[Collimation] source: Source | None detector: list[Detector] @@ -468,7 +491,7 @@ def as_h5(self, group: h5py.Group): d.as_h5(group.create_group(f"sasdetector{idx:02d}")) @dataclass(kw_only=True) -class Magnetic: +class Magnetic(MetadataSummarisable): applied_magnetic_field: Quantity[float] | None saturation_magnetization: Quantity[float] | None demagnetizing_field: Quantity[float] | None @@ -584,7 +607,7 @@ def from_content(con): @dataclass(kw_only=True, eq=True) -class Metadata: +class Metadata(MetadataSummarisable): title: str | None run: list[str] definition: str | None From 8549985624b0d6af165d95119e60d36d98df3cb9 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Mon, 19 Oct 2026 13:43:02 +0100 Subject: [PATCH 2/9] Create simple summary from fields --- sasdata/metadata.py | 71 +++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/sasdata/metadata.py b/sasdata/metadata.py index 59c3daec..44363e2c 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -54,6 +54,42 @@ class MetadataSummarisable(MetadataSerial): def summary(self) -> str: return "" + @staticmethod + def summarize_join(x, between : str="") -> str: + match x: + case None: + return "" + case MetadataSummarisable(): + return x.summary() + case list(): + return between.join([MetadataSummarisable.summarize_join(i, between) for i in x]) + case (list(), str()): + return MetadataSummarisable.summarize_join(x[0], x[1]) + case _: + return str(x) + + + def _pretty_field(self, x: str) -> str: + match x: + case "sample_id": + return "ID" + case _: + return x.capitalize().replace("_", " ") + + def introspect_summary(self, name:str | None, indent:int=0, adjust=0, skip=[]) -> str: + if name is None: + result = "" + else: + result = " "*indent + name + ":\n" + spacing = max(map(len, self.__dataclass_fields__)) + 2 + + for key in self.__dataclass_fields__: + if key in skip: continue + pretty = self._pretty_field(key) + result += " "*(indent+3) + pretty + ":" + " " * (spacing - len(pretty) + adjust) + str(getattr(self, key)) + "\n" + return result + + @dataclass(kw_only=True) class Vec3(MetadataSerial): @@ -153,16 +189,7 @@ class Detector(MetadataSummarisable): slit_length: Quantity[float] | None def summary(self): - return ( - f"Detector:\n" - f" Name: {self.name}\n" - f" Distance: {self.distance}\n" - f" Offset: {self.offset}\n" - f" Orientation: {self.orientation}\n" - f" Beam center: {self.beam_center}\n" - f" Pixel size: {self.pixel_size}\n" - f" Slit length: {self.slit_length}\n" - ) + return self.introspect_summary("Detector") @staticmethod def from_json(obj): @@ -245,7 +272,7 @@ class Collimation(MetadataSummarisable): apertures: list[Aperture] def summary(self): - return f"Collimation:\n Length: {self.length}\n" + "".join([a.summary() for a in self.apertures]) + return f"Collimation:\n Length: {self.length}\n" + self.summarize_join(self.apertures) @staticmethod def from_json(obj): @@ -339,23 +366,15 @@ class Sample(MetadataSummarisable): name: str | None sample_id: str | None - thickness: Quantity[float] | None transmission: float | None + thickness: Quantity[float] | None temperature: Quantity[float] | None position: Vec3 | None orientation: Rot3 | None details: list[str] def summary(self) -> str: - return ( - f"Sample:\n" - f" ID: {self.sample_id}\n" - f" Transmission: {self.transmission}\n" - f" Thickness: {self.thickness}\n" - f" Temperature: {self.temperature}\n" - f" Position: {self.position}\n" - f" Orientation: {self.orientation}\n" - ) + return self.introspect_summary("Sample", adjust=-1, skip=["name", "details"]) @staticmethod def from_json(obj): @@ -467,11 +486,7 @@ class Instrument(MetadataSummarisable): detector: list[Detector] def summary(self): - return ( - "\n".join([c.summary() for c in self.collimations]) - + "".join([d.summary() for d in self.detector]) - + (self.source.summary() if self.source is not None else "") - ) + return self.summarize_join([(self.collimations, "\n") , self.detector , self.source]) @staticmethod def from_json(obj): @@ -627,9 +642,7 @@ def summary(self): + "=" * len(run_string) + "\n\n" + f"Definition: {self.title}\n" - + "".join([p.summary() for p in self.process]) - + (self.sample.summary() if self.sample else "") - + (self.instrument.summary() if self.instrument else "") + + self.summarize_join([self.process, self.sample, self.instrument]) ) @staticmethod From ab155e9c7d3a49bd00683fe9583c78f570bbf56f Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Mon, 19 Oct 2026 15:31:31 +0100 Subject: [PATCH 3/9] Start normalising test files --- sasdata/metadata.py | 140 ++++++++++-------- test/test_files/reference/14250.txt | 16 +- test/test_files/reference/33837.txt | 16 +- test/test_files/reference/33837_v3.txt | 4 +- test/test_files/reference/BAM.txt | 16 +- test/test_files/reference/ISIS_1_0.txt | 50 +++---- test/test_files/reference/ISIS_1_1.txt | 50 +++---- .../reference/ISIS_1_1_doubletrans.txt | 50 +++---- .../test_files/reference/ISIS_1_1_notrans.txt | 50 +++---- test/test_files/reference/MAR07232_rest.txt | 32 ++-- test/test_files/reference/TestExtensions.txt | 50 +++---- test/test_files/reference/cansas1d.txt | 56 +++---- .../reference/cansas1d_badunits.txt | 56 +++---- .../test_files/reference/cansas1d_notitle.txt | 56 +++---- test/test_files/reference/cansas1d_slit.txt | 56 +++---- test/test_files/reference/cansas1d_units.txt | 56 +++---- test/test_files/reference/cansas_test.txt | 36 ++--- .../reference/cansas_test_modified.txt | 36 ++--- .../cansas_xml_multisasentry_multisasdata.txt | 40 ++--- .../nxcansas_1Dand2D_multisasdata.txt | 50 +++---- .../nxcansas_1Dand2D_multisasentry.txt | 100 ++++++------- test/test_files/reference/sphere2micron.txt | 16 +- test/test_files/reference/sphere_isis.txt | 16 +- .../test_files/reference/valid_cansas_xml.txt | 50 +++---- test/test_files/reference/x25000_no_di.txt | 4 +- 25 files changed, 563 insertions(+), 539 deletions(-) diff --git a/sasdata/metadata.py b/sasdata/metadata.py index 44363e2c..4d4b69fd 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -14,7 +14,6 @@ import json import re from dataclasses import dataclass, field, fields, is_dataclass -from textwrap import dedent from typing import Any, Self import h5py @@ -55,42 +54,56 @@ def summary(self) -> str: return "" @staticmethod - def summarize_join(x, between : str="") -> str: + def summarize_join(x, between: str = "") -> str: match x: case None: return "" case MetadataSummarisable(): return x.summary() case list(): - return between.join([MetadataSummarisable.summarize_join(i, between) for i in x]) + return between.join( + [MetadataSummarisable.summarize_join(i, between) for i in x] + ) case (list(), str()): return MetadataSummarisable.summarize_join(x[0], x[1]) case _: return str(x) - def _pretty_field(self, x: str) -> str: match x: case "sample_id": return "ID" + case "wavelength_min": + return "Min. Wavelength" + case "wavelength_max": + return "Max. Wavelength" + case "beam_shape": + return "Shape" case _: return x.capitalize().replace("_", " ") - def introspect_summary(self, name:str | None, indent:int=0, adjust=0, skip=[]) -> str: + def introspect_summary(self, name: str | None, indent: int = 0, skip=[]) -> str: if name is None: result = "" else: - result = " "*indent + name + ":\n" - spacing = max(map(len, self.__dataclass_fields__)) + 2 + result = " " * indent + name + ":\n" + spacing = max(map(len, self.__dataclass_fields__)) + 1 for key in self.__dataclass_fields__: - if key in skip: continue + if key in skip: + continue pretty = self._pretty_field(key) - result += " "*(indent+3) + pretty + ":" + " " * (spacing - len(pretty) + adjust) + str(getattr(self, key)) + "\n" + result += ( + " " * (indent + 4) + + pretty + + ":" + + " " * (spacing - len(pretty)) + + str(getattr(self, key)) + + "\n" + ) return result - @dataclass(kw_only=True) class Vec3(MetadataSerial): """A three-vector of measured quantities""" @@ -141,11 +154,7 @@ def deserialise_json(json_data: dict): return Rot3(roll=roll, pitch=pitch, yaw=yaw) def serialise_json(self): - data = { - "roll": None, - "pitch": None, - "yaw": None - } + data = {"roll": None, "pitch": None, "yaw": None} if self.roll is not None: data["roll"] = self.roll.serialise_json() if self.pitch is not None: @@ -223,18 +232,15 @@ def as_h5(self, group: h5py.Group): @dataclass(kw_only=True) class Aperture(MetadataSummarisable): - distance: Quantity[float] | None + name: str | None size: Vec3 | None + distance: Quantity[float] | None size_name: str | None - name: str | None type_: str | None def summary(self): - return ( - f" Aperture:\n" - f" Name: {self.name}\n" - f" Aperture size: {self.size}\n" - f" Aperture distance: {self.distance}\n" + return self.introspect_summary( + "Aperture", indent=4, skip=["type_", "size_name"] ) @staticmethod @@ -272,7 +278,9 @@ class Collimation(MetadataSummarisable): apertures: list[Aperture] def summary(self): - return f"Collimation:\n Length: {self.length}\n" + self.summarize_join(self.apertures) + return f"Collimation:\n Length: {self.length}\n" + self.summarize_join( + self.apertures + ) @staticmethod def from_json(obj): @@ -310,30 +318,23 @@ def as_h5(self, group: h5py.Group): class Source(MetadataSummarisable): radiation: str | None beam_shape: str | None - beam_size: BeamSize | None wavelength: Quantity[float] | None wavelength_min: Quantity[float] | None wavelength_max: Quantity[float] | None wavelength_spread: Quantity[float] | None + beam_size: BeamSize | None def summary(self) -> str: - return ( - f"Source:\n" - f" Radiation: {self.radiation}\n" - f" Shape: {self.beam_shape}\n" - f" Wavelength: {self.wavelength}\n" - f" Min. Wavelength: {self.wavelength_min}\n" - f" Max. Wavelength: {self.wavelength_max}\n" - f" Wavelength Spread: {self.wavelength_spread}\n" - f" Beam Size: {self.beam_size}\n" - ) + return self.introspect_summary("Source") @staticmethod def from_json(obj): return Source( radiation=obj["radiation"], beam_shape=obj["beam_shape"], - beam_size=BeamSize.from_json(obj["beam_size"]) if obj["beam_size"] else None, + beam_size=( + BeamSize.from_json(obj["beam_size"]) if obj["beam_size"] else None + ), wavelength=obj["wavelength"], wavelength_min=obj["wavelength_min"], wavelength_max=obj["wavelength_max"], @@ -374,7 +375,7 @@ class Sample(MetadataSummarisable): details: list[str] def summary(self) -> str: - return self.introspect_summary("Sample", adjust=-1, skip=["name", "details"]) + return self.introspect_summary("Sample", skip=["name", "details"]) @staticmethod def from_json(obj): @@ -430,22 +431,27 @@ def single_line_desc(self): def summary(self): if self.terms: - termInfo = " Terms:\n" + "\n".join([f" {k}: {v}" for k, v in self.terms.items()]) + "\n" + termInfo = ( + " Terms:\n" + + "\n".join([f" {k}: {v}" for k, v in self.terms.items()]) + + "\n" + ) else: termInfo = "" if self.notes: - noteInfo = " Notes:\n" + "\n".join([f" {note}" for note in self.notes]) + "\n" + noteInfo = ( + " Notes:\n" + + "\n".join([f" {note}" for note in self.notes]) + + "\n" + ) else: noteInfo = "" return ( - f"Process:\n" - f" Name: {self.name}\n" - f" Date: {self.date}\n" - f" Description: {self.description}\n" - f"{termInfo}" - f"{noteInfo}" + self.introspect_summary("Process", skip=["terms", "notes"]) + + termInfo + + noteInfo ) @staticmethod @@ -486,7 +492,9 @@ class Instrument(MetadataSummarisable): detector: list[Detector] def summary(self): - return self.summarize_join([(self.collimations, "\n") , self.detector , self.source]) + return self.summarize_join( + [(self.collimations, "\n"), self.detector, self.source] + ) @staticmethod def from_json(obj): @@ -505,6 +513,7 @@ def as_h5(self, group: h5py.Group): for idx, d in enumerate(self.detector): d.as_h5(group.create_group(f"sasdetector{idx:02d}")) + @dataclass(kw_only=True) class Magnetic(MetadataSummarisable): applied_magnetic_field: Quantity[float] | None @@ -515,15 +524,15 @@ def single_line_desc(self): return f"Applied Magnetic Field: {self.applied_magnetic_field}, Saturation Magnetization: {self.saturation_magnetization}, Demagnetizing Field: {self.demagnetizing_field}" def summary(self): - return dedent(f"""Applied Magnetic Field: {self.applied_magnetic_field} - Saturation Magnetization: {self.saturation_magnetization} - Demagnetizing Field: {self.demagnetizing_field}""") + return self.introspect_summary(None) @staticmethod def from_json(obj): return Magnetic( applied_magnetic_field=from_json_quantity(obj["applied_magnetic_field"]), - saturation_magnetization=from_json_quantity(obj["saturation_magnetization"]), + saturation_magnetization=from_json_quantity( + obj["saturation_magnetization"] + ), demagnetizing_field=from_json_quantity(obj["demagnetizing_field"]), ) @@ -567,7 +576,9 @@ def filter(self, name: str) -> list[ndarray | Quantity | str]: case list(): return [y for x in self.contents for y in x.filter(name)] case _: - raise RuntimeError(f"Cannot filter contents of type {type(self.contents)}: {self.contents}") + raise RuntimeError( + f"Cannot filter contents of type {type(self.contents)}: {self.contents}" + ) return [] def __eq__(self, other) -> bool: @@ -608,9 +619,13 @@ def from_content(con): "contents": contents, "shape": shape, }: - return np.frombuffer(base64.b64decode(contents), dtype=dtype).reshape(shape) + return np.frombuffer( + base64.b64decode(contents), dtype=dtype + ).reshape(shape) case {"value": value, "units": units}: - return from_json_quantity({"value": from_content(value), "units": from_content(units)}) + return from_json_quantity( + {"value": from_content(value), "units": from_content(units)} + ) case _: return con @@ -653,8 +668,12 @@ def from_json(obj): definition=obj["definition"] if obj["definition"] else None, process=[Process.from_json(p) for p in obj["process"]], sample=Sample.from_json(obj["sample"]) if obj["sample"] else None, - instrument=Instrument.from_json(obj["instrument"]) if obj["instrument"] else None, - magnetic=Magnetic.from_json(obj["magnetic"]) if obj.get("magnetic") else None, + instrument=( + Instrument.from_json(obj["instrument"]) if obj["instrument"] else None + ), + magnetic=( + Magnetic.from_json(obj["magnetic"]) if obj.get("magnetic") else None + ), raw=MetaNode.from_json(obj["raw"]), ) @@ -668,7 +687,7 @@ def initialise_empty(): sample=None, instrument=None, magnetic=None, - raw=None + raw=None, ) def serialise_json(self): @@ -678,7 +697,7 @@ def serialise_json(self): "sample": None, "title": self.title, "run": self.run, - "definition": self.definition + "definition": self.definition, } if self.sample is not None: serialized["sample"] = self.sample.serialise_json() @@ -862,10 +881,14 @@ def access_meta(obj: dataclass, key: str) -> Any | None: key = accessor[len(field_string) :] result = getattr(result, fld.name) break - case index if (type(result) is list) and (matches := re.match(r"\[(\d+?)\](.*)", index)): + case index if (type(result) is list) and ( + matches := re.match(r"\[(\d+?)\](.*)", index) + ): result = result[int(matches[1])] key = matches[2] - case name if (type(result) is dict) and (matches := re.match(r'\["(.+)"\](.*)', name)): + case name if (type(result) is dict) and ( + matches := re.match(r'\["(.+)"\](.*)', name) + ): result = result[matches[1]] key = matches[2] case _: @@ -968,5 +991,6 @@ def collect_tags(objs: list[dataclass]) -> TagCollection: return result + class DerivedMetadata(Metadata): pass diff --git a/test/test_files/reference/14250.txt b/test/test_files/reference/14250.txt index 6f11aba7..8068d6a9 100644 --- a/test/test_files/reference/14250.txt +++ b/test/test_files/reference/14250.txt @@ -15,12 +15,12 @@ Process: Term: None Notes: None Sample: - ID: None - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: None + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Aperture: Name: None Aperture size: None @@ -41,8 +41,8 @@ Source: Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None Transmission Spectrum: Name: None Timestamp: None diff --git a/test/test_files/reference/33837.txt b/test/test_files/reference/33837.txt index 26f36b96..f8cc6540 100644 --- a/test/test_files/reference/33837.txt +++ b/test/test_files/reference/33837.txt @@ -14,12 +14,12 @@ Process: Term: None Notes: None Sample: - ID: None - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: None + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Aperture: Name: None Aperture size: None @@ -40,8 +40,8 @@ Source: Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None Transmission Spectrum: Name: None Timestamp: None diff --git a/test/test_files/reference/33837_v3.txt b/test/test_files/reference/33837_v3.txt index f4d205b2..80dec592 100644 --- a/test/test_files/reference/33837_v3.txt +++ b/test/test_files/reference/33837_v3.txt @@ -40,8 +40,8 @@ Source: Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None Transmission Spectrum: Name: None Timestamp: None diff --git a/test/test_files/reference/BAM.txt b/test/test_files/reference/BAM.txt index bf6328b1..be1b6f7e 100644 --- a/test/test_files/reference/BAM.txt +++ b/test/test_files/reference/BAM.txt @@ -15,12 +15,12 @@ Process: Term: None Notes: None Sample: - ID: None - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: None + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Aperture: Name: None Aperture size: None @@ -41,8 +41,8 @@ Source: Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None Transmission Spectrum: Name: None Timestamp: None diff --git a/test/test_files/reference/ISIS_1_0.txt b/test/test_files/reference/ISIS_1_0.txt index 57ff7ed2..fa8aa6ce 100644 --- a/test/test_files/reference/ISIS_1_0.txt +++ b/test/test_files/reference/ISIS_1_0.txt @@ -8,42 +8,42 @@ Metadata: Definition: TK49 c10_SANS Process: - Name: Mantid generated CanSAS1D XML - Date: 02-Aug-2013 16:54:14 + Name: Mantid generated CanSAS1D XML + Date: 02-Aug-2013 16:54:14 Description: None Terms: svn: 2.5.3 user_file: K:/masks/MASKLOQ_MAN_132E_Lu_Banjo_12mm.txt Sample: - ID: TK49 c10_SANS - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: TK49 c10_SANS + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: HAB - Distance: 0.575 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: HAB + Distance: 0.575 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: main-detector-bank - Distance: 4.14502 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: main-detector-bank + Distance: 4.14502 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: neutron Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/ISIS_1_1.txt b/test/test_files/reference/ISIS_1_1.txt index 48df868f..174e5daa 100644 --- a/test/test_files/reference/ISIS_1_1.txt +++ b/test/test_files/reference/ISIS_1_1.txt @@ -8,42 +8,42 @@ Metadata: Definition: TK49 c10_SANS Process: - Name: Mantid generated CanSAS1D XML - Date: 02-Aug-2013 16:53:56 + Name: Mantid generated CanSAS1D XML + Date: 02-Aug-2013 16:53:56 Description: None Terms: svn: 2.5.3 user_file: K:/masks/MASKLOQ_MAN_132E_Lu_Banjo_12mm.txt Sample: - ID: TK49 c10_SANS - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: TK49 c10_SANS + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: HAB - Distance: 0.575 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: HAB + Distance: 0.575 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: main-detector-bank - Distance: 4.14502 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: main-detector-bank + Distance: 4.14502 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: neutron Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/ISIS_1_1_doubletrans.txt b/test/test_files/reference/ISIS_1_1_doubletrans.txt index 48df868f..174e5daa 100644 --- a/test/test_files/reference/ISIS_1_1_doubletrans.txt +++ b/test/test_files/reference/ISIS_1_1_doubletrans.txt @@ -8,42 +8,42 @@ Metadata: Definition: TK49 c10_SANS Process: - Name: Mantid generated CanSAS1D XML - Date: 02-Aug-2013 16:53:56 + Name: Mantid generated CanSAS1D XML + Date: 02-Aug-2013 16:53:56 Description: None Terms: svn: 2.5.3 user_file: K:/masks/MASKLOQ_MAN_132E_Lu_Banjo_12mm.txt Sample: - ID: TK49 c10_SANS - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: TK49 c10_SANS + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: HAB - Distance: 0.575 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: HAB + Distance: 0.575 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: main-detector-bank - Distance: 4.14502 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: main-detector-bank + Distance: 4.14502 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: neutron Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/ISIS_1_1_notrans.txt b/test/test_files/reference/ISIS_1_1_notrans.txt index 48df868f..174e5daa 100644 --- a/test/test_files/reference/ISIS_1_1_notrans.txt +++ b/test/test_files/reference/ISIS_1_1_notrans.txt @@ -8,42 +8,42 @@ Metadata: Definition: TK49 c10_SANS Process: - Name: Mantid generated CanSAS1D XML - Date: 02-Aug-2013 16:53:56 + Name: Mantid generated CanSAS1D XML + Date: 02-Aug-2013 16:53:56 Description: None Terms: svn: 2.5.3 user_file: K:/masks/MASKLOQ_MAN_132E_Lu_Banjo_12mm.txt Sample: - ID: TK49 c10_SANS - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: TK49 c10_SANS + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: HAB - Distance: 0.575 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: HAB + Distance: 0.575 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: main-detector-bank - Distance: 4.14502 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: main-detector-bank + Distance: 4.14502 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: neutron Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/MAR07232_rest.txt b/test/test_files/reference/MAR07232_rest.txt index e98b20bd..1cf6ab80 100644 --- a/test/test_files/reference/MAR07232_rest.txt +++ b/test/test_files/reference/MAR07232_rest.txt @@ -9,27 +9,27 @@ Metadata: Definition: MAR07232_rest_out.dat Sample: - ID: - Transmission: 0.84357 - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: + Transmission: 0.84357 + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: - Distance: None - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: + Distance: None + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: neutron Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/TestExtensions.txt b/test/test_files/reference/TestExtensions.txt index e833c9da..58b2f627 100644 --- a/test/test_files/reference/TestExtensions.txt +++ b/test/test_files/reference/TestExtensions.txt @@ -8,42 +8,42 @@ Metadata: Definition: TK49 c10_SANS Process: - Name: Mantid generated CanSAS1D XML - Date: 02-Aug-2013 16:53:56 + Name: Mantid generated CanSAS1D XML + Date: 02-Aug-2013 16:53:56 Description: Terms: svn: 2.5.3 user_file: K:/masks/MASKLOQ_MAN_132E_Lu_Banjo_12mm.txt Sample: - ID: TK49 c10_SANS - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: TK49 c10_SANS + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: HAB - Distance: 575.0 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: HAB + Distance: 575.0 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: main-detector-bank - Distance: 4145.02 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: main-detector-bank + Distance: 4145.02 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: neutron Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/cansas1d.txt b/test/test_files/reference/cansas1d.txt index e16366bb..980429df 100644 --- a/test/test_files/reference/cansas1d.txt +++ b/test/test_files/reference/cansas1d.txt @@ -8,8 +8,8 @@ Metadata: Definition: Test title Process: - Name: spol - Date: 04-Sep-2007 18:35:02 + Name: spol + Date: 04-Sep-2007 18:35:02 Description: None Terms: radialstep: 10.0 mm @@ -23,8 +23,8 @@ Process: H2O Buffer V... 13552 3 1.00E+00 H2O5m Process: - Name: NCNR-IGOR - Date: 03-SEP-2006 11:42:47 + Name: NCNR-IGOR + Date: 03-SEP-2006 11:42:47 Description: Terms: average_type: Circular @@ -40,35 +40,35 @@ Process: Notes: No Information Sample: - ID: SI600-new-long - Transmission: 0.327 - Thickness: 1.03 mm - Temperature: 0.0 K - Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) - Orientation: Rot3(roll=22.5 deg, pitch=0.02 deg, yaw=None) + ID: SI600-new-long + Transmission: 0.327 + Thickness: 1.03 mm + Temperature: 0.0 K + Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) + Orientation: Rot3(roll=22.5 deg, pitch=0.02 deg, yaw=None) Collimation: - Length: 123.0 mm - Aperture: - Name: source - Aperture size: Vec3(x=50.0 mm, y=None, z=None) - Aperture distance: 11.0 m - Aperture: - Name: sample - Aperture size: Vec3(x=1.0 mm, y=None, z=None) - Aperture distance: None + Length: 123.0 mm + Aperture: + Name: source + Size: Vec3(x=50.0 mm, y=None, z=None) + Distance: 11.0 m + Aperture: + Name: sample + Size: Vec3(x=1.0 mm, y=None, z=None) + Distance: None Detector: - Name: fictional hybrid - Distance: 4.15 m - Offset: Vec3(x=1.0 mm, y=2.0 mm, z=None) - Orientation: Rot3(roll=1.0 deg, pitch=0.0 deg, yaw=0.0 deg) - Beam center: Vec3(x=322.64 mm, y=327.68 mm, z=None) - Pixel size: Vec3(x=5.0 mm, y=5.0 mm, z=None) - Slit length: None + Name: fictional hybrid + Distance: 4.15 m + Offset: Vec3(x=1.0 mm, y=2.0 mm, z=None) + Orientation: Rot3(roll=1.0 deg, pitch=0.0 deg, yaw=0.0 deg) + Beam center: Vec3(x=322.64 mm, y=327.68 mm, z=None) + Pixel size: Vec3(x=5.0 mm, y=5.0 mm, z=None) + Slit length: None Source: Radiation: neutron Shape: disc Wavelength: 6.0 Å Min. Wavelength: 0.22 nm Max. Wavelength: 1.0 nm - Wavelength Spread: 14.3 % - Beam Size: BeamSize(name='bm', size=Vec3(x=12.0 mm, y=13.0 mm, z=None)) + Wavelength spread: 14.3 % + Beam size: BeamSize(name='bm', size=Vec3(x=12.0 mm, y=13.0 mm, z=None)) diff --git a/test/test_files/reference/cansas1d_badunits.txt b/test/test_files/reference/cansas1d_badunits.txt index 4c61f204..4526781b 100644 --- a/test/test_files/reference/cansas1d_badunits.txt +++ b/test/test_files/reference/cansas1d_badunits.txt @@ -8,8 +8,8 @@ Metadata: Definition: Test title Process: - Name: spol - Date: 04-Sep-2007 18:35:02 + Name: spol + Date: 04-Sep-2007 18:35:02 Description: None Terms: radialstep: 10.0 mm @@ -23,8 +23,8 @@ Process: H2O Buffer V... 13552 3 1.00E+00 H2O5m Process: - Name: NCNR-IGOR - Date: 03-SEP-2006 11:42:47 + Name: NCNR-IGOR + Date: 03-SEP-2006 11:42:47 Description: Terms: average_type: Circular @@ -38,35 +38,35 @@ Process: ABS:IZERO: 230.09 ABS:XSECT: 1.0 mm Sample: - ID: SI600-new-long - Transmission: 0.327 - Thickness: 0.00103 none - Temperature: 0.0 K - Position: Vec3(x=10000000.0 nm, y=0.0 mm, z=None) - Orientation: Rot3(roll=0.39269908 rad, pitch=0.00034906585 rad, yaw=None) + ID: SI600-new-long + Transmission: 0.327 + Thickness: 0.00103 none + Temperature: 0.0 K + Position: Vec3(x=10000000.0 nm, y=0.0 mm, z=None) + Orientation: Rot3(roll=0.39269908 rad, pitch=0.00034906585 rad, yaw=None) Collimation: - Length: 0.123 m - Aperture: - Name: source - Aperture size: Vec3(x=50000.0 µm, y=None, z=None) - Aperture distance: 1100.0 cm - Aperture: - Name: sample - Aperture size: Vec3(x=0.1 cm, y=None, z=None) - Aperture distance: None + Length: 0.123 m + Aperture: + Name: source + Size: Vec3(x=50000.0 µm, y=None, z=None) + Distance: 1100.0 cm + Aperture: + Name: sample + Size: Vec3(x=0.1 cm, y=None, z=None) + Distance: None Detector: - Name: fictional hybrid - Distance: 4.15 m - Offset: Vec3(x=1000000.0 nm, y=2000.0 µm, z=None) - Orientation: Rot3(roll=0.0174533 rad, pitch=0.0 rad, yaw=0.0 rad) - Beam center: Vec3(x=0.32264 m, y=0.32768 m, z=None) - Pixel size: Vec3(x=0.5 cm, y=0.5 cm, z=None) - Slit length: None + Name: fictional hybrid + Distance: 4.15 m + Offset: Vec3(x=1000000.0 nm, y=2000.0 µm, z=None) + Orientation: Rot3(roll=0.0174533 rad, pitch=0.0 rad, yaw=0.0 rad) + Beam center: Vec3(x=0.32264 m, y=0.32768 m, z=None) + Pixel size: Vec3(x=0.5 cm, y=0.5 cm, z=None) + Slit length: None Source: Radiation: neutron Shape: disc Wavelength: 0.6 nm Min. Wavelength: 2.2 Å Max. Wavelength: 10.0 Å - Wavelength Spread: 14.3 % - Beam Size: BeamSize(name='bm', size=Vec3(x=0.012 m, y=13000.0 µm, z=None)) + Wavelength spread: 14.3 % + Beam size: BeamSize(name='bm', size=Vec3(x=0.012 m, y=13000.0 µm, z=None)) diff --git a/test/test_files/reference/cansas1d_notitle.txt b/test/test_files/reference/cansas1d_notitle.txt index ca8abac2..0a4ecb00 100644 --- a/test/test_files/reference/cansas1d_notitle.txt +++ b/test/test_files/reference/cansas1d_notitle.txt @@ -8,8 +8,8 @@ Metadata: Definition: None Process: - Name: spol - Date: 04-Sep-2007 18:35:02 + Name: spol + Date: 04-Sep-2007 18:35:02 Description: None Terms: radialstep: 10.0 mm @@ -23,8 +23,8 @@ Process: H2O Buffer V... 13552 3 1.00E+00 H2O5m Process: - Name: NCNR-IGOR - Date: 03-SEP-2006 11:42:47 + Name: NCNR-IGOR + Date: 03-SEP-2006 11:42:47 Description: Terms: average_type: Circular @@ -40,35 +40,35 @@ Process: Notes: No Information Sample: - ID: SI600-new-long - Transmission: 0.327 - Thickness: 1.03 mm - Temperature: 0.0 K - Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) - Orientation: Rot3(roll=22.5 deg, pitch=0.02 deg, yaw=None) + ID: SI600-new-long + Transmission: 0.327 + Thickness: 1.03 mm + Temperature: 0.0 K + Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) + Orientation: Rot3(roll=22.5 deg, pitch=0.02 deg, yaw=None) Collimation: - Length: 123.0 mm - Aperture: - Name: source - Aperture size: Vec3(x=50.0 mm, y=None, z=None) - Aperture distance: 11.0 m - Aperture: - Name: sample - Aperture size: Vec3(x=1.0 mm, y=None, z=None) - Aperture distance: None + Length: 123.0 mm + Aperture: + Name: source + Size: Vec3(x=50.0 mm, y=None, z=None) + Distance: 11.0 m + Aperture: + Name: sample + Size: Vec3(x=1.0 mm, y=None, z=None) + Distance: None Detector: - Name: fictional hybrid - Distance: 4.15 m - Offset: Vec3(x=1.0 mm, y=2.0 mm, z=None) - Orientation: Rot3(roll=1.0 deg, pitch=0.0 deg, yaw=0.0 deg) - Beam center: Vec3(x=322.64 mm, y=327.68 mm, z=None) - Pixel size: Vec3(x=5.0 mm, y=5.0 mm, z=None) - Slit length: None + Name: fictional hybrid + Distance: 4.15 m + Offset: Vec3(x=1.0 mm, y=2.0 mm, z=None) + Orientation: Rot3(roll=1.0 deg, pitch=0.0 deg, yaw=0.0 deg) + Beam center: Vec3(x=322.64 mm, y=327.68 mm, z=None) + Pixel size: Vec3(x=5.0 mm, y=5.0 mm, z=None) + Slit length: None Source: Radiation: neutron Shape: disc Wavelength: 6.0 Å Min. Wavelength: 0.22 nm Max. Wavelength: 1.0 nm - Wavelength Spread: 14.3 % - Beam Size: BeamSize(name='bm', size=Vec3(x=12.0 mm, y=13.0 mm, z=None)) + Wavelength spread: 14.3 % + Beam size: BeamSize(name='bm', size=Vec3(x=12.0 mm, y=13.0 mm, z=None)) diff --git a/test/test_files/reference/cansas1d_slit.txt b/test/test_files/reference/cansas1d_slit.txt index cbc9bdcf..1a0bd145 100644 --- a/test/test_files/reference/cansas1d_slit.txt +++ b/test/test_files/reference/cansas1d_slit.txt @@ -10,8 +10,8 @@ Metadata: Definition: Test title Process: - Name: spol - Date: 04-Sep-2007 18:35:02 + Name: spol + Date: 04-Sep-2007 18:35:02 Description: None Terms: radialstep: 10.0 mm @@ -25,8 +25,8 @@ Process: H2O Buffer V... 13552 3 1.00E+00 H2O5m Process: - Name: NCNR-IGOR - Date: 03-SEP-2006 11:42:47 + Name: NCNR-IGOR + Date: 03-SEP-2006 11:42:47 Description: Terms: average_type: Circular @@ -40,35 +40,35 @@ Process: ABS:IZERO: 230.09 ABS:XSECT: 1.0 mm Sample: - ID: SI600-new-long - Transmission: 0.327 - Thickness: 1.03 mm - Temperature: 0.0 K - Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) - Orientation: Rot3(roll=22.5 deg, pitch=0.02 deg, yaw=None) + ID: SI600-new-long + Transmission: 0.327 + Thickness: 1.03 mm + Temperature: 0.0 K + Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) + Orientation: Rot3(roll=22.5 deg, pitch=0.02 deg, yaw=None) Collimation: - Length: 123.0 mm - Aperture: - Name: source - Aperture size: Vec3(x=50.0 mm, y=None, z=None) - Aperture distance: 11.0 m - Aperture: - Name: sample - Aperture size: Vec3(x=1.0 mm, y=None, z=None) - Aperture distance: None + Length: 123.0 mm + Aperture: + Name: source + Size: Vec3(x=50.0 mm, y=None, z=None) + Distance: 11.0 m + Aperture: + Name: sample + Size: Vec3(x=1.0 mm, y=None, z=None) + Distance: None Detector: - Name: fictional hybrid - Distance: 4.15 m - Offset: Vec3(x=1.0 mm, y=2.0 mm, z=None) - Orientation: Rot3(roll=1.0 deg, pitch=0.0 deg, yaw=0.0 deg) - Beam center: Vec3(x=322.64 mm, y=327.68 mm, z=None) - Pixel size: Vec3(x=5.0 mm, y=5.0 mm, z=None) - Slit length: None + Name: fictional hybrid + Distance: 4.15 m + Offset: Vec3(x=1.0 mm, y=2.0 mm, z=None) + Orientation: Rot3(roll=1.0 deg, pitch=0.0 deg, yaw=0.0 deg) + Beam center: Vec3(x=322.64 mm, y=327.68 mm, z=None) + Pixel size: Vec3(x=5.0 mm, y=5.0 mm, z=None) + Slit length: None Source: Radiation: neutron Shape: disc Wavelength: 6.0 Å Min. Wavelength: 0.22 nm Max. Wavelength: 1.0 nm - Wavelength Spread: 14.3 % - Beam Size: BeamSize(name='bm', size=Vec3(x=12.0 mm, y=13.0 mm, z=None)) + Wavelength spread: 14.3 % + Beam size: BeamSize(name='bm', size=Vec3(x=12.0 mm, y=13.0 mm, z=None)) diff --git a/test/test_files/reference/cansas1d_units.txt b/test/test_files/reference/cansas1d_units.txt index 68db7bc4..42dad65e 100644 --- a/test/test_files/reference/cansas1d_units.txt +++ b/test/test_files/reference/cansas1d_units.txt @@ -8,8 +8,8 @@ Metadata: Definition: Test title Process: - Name: spol - Date: 04-Sep-2007 18:35:02 + Name: spol + Date: 04-Sep-2007 18:35:02 Description: None Terms: radialstep: 10.0 mm @@ -23,8 +23,8 @@ Process: H2O Buffer V... 13552 3 1.00E+00 H2O5m Process: - Name: NCNR-IGOR - Date: 03-SEP-2006 11:42:47 + Name: NCNR-IGOR + Date: 03-SEP-2006 11:42:47 Description: Terms: average_type: Circular @@ -38,35 +38,35 @@ Process: ABS:IZERO: 230.09 ABS:XSECT: 1.0 mm Sample: - ID: SI600-new-long - Transmission: 0.327 - Thickness: 0.00103 m - Temperature: 0.0 K - Position: Vec3(x=10000000.0 nm, y=0.0 mm, z=None) - Orientation: Rot3(roll=0.39269908 rad, pitch=0.00034906585 rad, yaw=None) + ID: SI600-new-long + Transmission: 0.327 + Thickness: 0.00103 m + Temperature: 0.0 K + Position: Vec3(x=10000000.0 nm, y=0.0 mm, z=None) + Orientation: Rot3(roll=0.39269908 rad, pitch=0.00034906585 rad, yaw=None) Collimation: - Length: 0.123 m - Aperture: - Name: source - Aperture size: Vec3(x=50000.0 µm, y=None, z=None) - Aperture distance: 1100.0 cm - Aperture: - Name: sample - Aperture size: Vec3(x=0.1 cm, y=None, z=None) - Aperture distance: None + Length: 0.123 m + Aperture: + Name: source + Size: Vec3(x=50000.0 µm, y=None, z=None) + Distance: 1100.0 cm + Aperture: + Name: sample + Size: Vec3(x=0.1 cm, y=None, z=None) + Distance: None Detector: - Name: fictional hybrid - Distance: 4.15 m - Offset: Vec3(x=1000000.0 nm, y=2000.0 µm, z=None) - Orientation: Rot3(roll=0.0174533 rad, pitch=0.0 rad, yaw=0.0 rad) - Beam center: Vec3(x=0.32264 m, y=0.32768 m, z=None) - Pixel size: Vec3(x=0.5 cm, y=0.5 cm, z=None) - Slit length: None + Name: fictional hybrid + Distance: 4.15 m + Offset: Vec3(x=1000000.0 nm, y=2000.0 µm, z=None) + Orientation: Rot3(roll=0.0174533 rad, pitch=0.0 rad, yaw=0.0 rad) + Beam center: Vec3(x=0.32264 m, y=0.32768 m, z=None) + Pixel size: Vec3(x=0.5 cm, y=0.5 cm, z=None) + Slit length: None Source: Radiation: neutron Shape: disc Wavelength: 0.6 nm Min. Wavelength: 2.2 Å Max. Wavelength: 10.0 Å - Wavelength Spread: 14.3 % - Beam Size: BeamSize(name='bm', size=Vec3(x=0.012 m, y=13000.0 µm, z=None)) + Wavelength spread: 14.3 % + Beam size: BeamSize(name='bm', size=Vec3(x=0.012 m, y=13000.0 µm, z=None)) diff --git a/test/test_files/reference/cansas_test.txt b/test/test_files/reference/cansas_test.txt index 60333cc0..431dc255 100644 --- a/test/test_files/reference/cansas_test.txt +++ b/test/test_files/reference/cansas_test.txt @@ -8,8 +8,8 @@ Metadata: Definition: ILL-D11 example1: 2A 5mM 0%D2O Process: - Name: spol - Date: 04-Sep-2007 18:12:27 + Name: spol + Date: 04-Sep-2007 18:12:27 Description: None Terms: radialstep: 10.0 mm @@ -23,27 +23,27 @@ Process: S... 13586 0 5.63E+01 2A 5mM 0%D2O Sbak 13567 0 1.88E+01 H2O buffer Sbak 13533 0 7.49E+00 H2O buffer V... 13552 1 1.00E+00 Normal 10m from Sample: - ID: None - Transmission: 0.0 - Thickness: 0.0 mm - Temperature: 32.0 K - Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) - Orientation: Rot3(roll=0.02 deg, pitch=None, yaw=None) + ID: None + Transmission: 0.0 + Thickness: 0.0 mm + Temperature: 32.0 K + Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) + Orientation: Rot3(roll=0.02 deg, pitch=None, yaw=None) Collimation: - Length: None + Length: None Detector: - Name: - Distance: 10.0 m - Offset: None - Orientation: Rot3(roll=0.0 deg, pitch=None, yaw=None) - Beam center: Vec3(x=311.0 mm, y=315.0 mm, z=None) - Pixel size: Vec3(x=10.0 mm, y=10.0 mm, z=None) - Slit length: None + Name: + Distance: 10.0 m + Offset: None + Orientation: Rot3(roll=0.0 deg, pitch=None, yaw=None) + Beam center: Vec3(x=311.0 mm, y=315.0 mm, z=None) + Pixel size: Vec3(x=10.0 mm, y=10.0 mm, z=None) + Slit length: None Source: Radiation: neutron Shape: None Wavelength: 6.0 Å Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 0.0 Å - Beam Size: BeamSize(name=None, size=Vec3(x=30.0 mm, y=0.0 mm, z=None)) + Wavelength spread: 0.0 Å + Beam size: BeamSize(name=None, size=Vec3(x=30.0 mm, y=0.0 mm, z=None)) diff --git a/test/test_files/reference/cansas_test_modified.txt b/test/test_files/reference/cansas_test_modified.txt index 9ccd51e7..3fbdc81e 100644 --- a/test/test_files/reference/cansas_test_modified.txt +++ b/test/test_files/reference/cansas_test_modified.txt @@ -8,8 +8,8 @@ Metadata: Definition: ILL-D11 example1: 2A 5mM 0%D2O Process: - Name: spol - Date: 04-Sep-2007 18:12:27 + Name: spol + Date: 04-Sep-2007 18:12:27 Description: None Terms: radialstep: 10.0 mm @@ -23,27 +23,27 @@ Process: S... 13586 0 5.63E+01 2A 5mM 0%D2O Sbak 13567 0 1.88E+01 H2O buffer Sbak 13533 0 7.49E+00 H2O buffer V... 13552 1 1.00E+00 Normal 10m from Sample: - ID: This is a test file - Transmission: 0.0 - Thickness: 0.0 mm - Temperature: 32.0 K - Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) - Orientation: Rot3(roll=0.02 deg, pitch=None, yaw=None) + ID: This is a test file + Transmission: 0.0 + Thickness: 0.0 mm + Temperature: 32.0 K + Position: Vec3(x=10.0 mm, y=0.0 mm, z=None) + Orientation: Rot3(roll=0.02 deg, pitch=None, yaw=None) Collimation: - Length: 10.0 m + Length: 10.0 m Detector: - Name: - Distance: 10.0 m - Offset: None - Orientation: Rot3(roll=0.0 deg, pitch=None, yaw=None) - Beam center: Vec3(x=311.0 mm, y=315.0 mm, z=None) - Pixel size: Vec3(x=10.0 mm, y=10.0 mm, z=None) - Slit length: None + Name: + Distance: 10.0 m + Offset: None + Orientation: Rot3(roll=0.0 deg, pitch=None, yaw=None) + Beam center: Vec3(x=311.0 mm, y=315.0 mm, z=None) + Pixel size: Vec3(x=10.0 mm, y=10.0 mm, z=None) + Slit length: None Source: Radiation: neutron Shape: None Wavelength: 6.0 Å Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 0.0 Å - Beam Size: BeamSize(name=None, size=Vec3(x=30.0 mm, y=0.0 mm, z=None)) + Wavelength spread: 0.0 Å + Beam size: BeamSize(name=None, size=Vec3(x=30.0 mm, y=0.0 mm, z=None)) diff --git a/test/test_files/reference/cansas_xml_multisasentry_multisasdata.txt b/test/test_files/reference/cansas_xml_multisasentry_multisasdata.txt index a968b1af..c3c4cfcf 100644 --- a/test/test_files/reference/cansas_xml_multisasentry_multisasdata.txt +++ b/test/test_files/reference/cansas_xml_multisasentry_multisasdata.txt @@ -30,8 +30,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:1h Q I @@ -64,8 +64,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:20 Q I @@ -98,8 +98,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:2h Q I @@ -132,8 +132,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:50 Q I @@ -166,8 +166,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:5h Q I @@ -200,8 +200,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:8h Q I @@ -234,8 +234,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:cc Q I @@ -268,8 +268,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:hf Q I @@ -302,8 +302,8 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None AF1410:qu Q I @@ -336,5 +336,5 @@ Source: Wavelength: 0.85 nm Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: 25.0 % - Beam Size: None + Wavelength spread: 25.0 % + Beam size: None diff --git a/test/test_files/reference/nxcansas_1Dand2D_multisasdata.txt b/test/test_files/reference/nxcansas_1Dand2D_multisasdata.txt index ad56786d..820609c9 100644 --- a/test/test_files/reference/nxcansas_1Dand2D_multisasdata.txt +++ b/test/test_files/reference/nxcansas_1Dand2D_multisasdata.txt @@ -9,39 +9,39 @@ Metadata: Definition: MH4_5deg_16T_SLOW Process: - Name: Mantid generated CanSAS1D XML - Date: 11-May-2016 12:15:34 + Name: Mantid generated CanSAS1D XML + Date: 11-May-2016 12:15:34 Description: None Sample: - ID: - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: front-detector - Distance: 2845.26 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: front-detector + Distance: 2845.26 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: rear-detector - Distance: 4385.28 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: rear-detector + Distance: 4385.28 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: Spallation Neutron Source Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/nxcansas_1Dand2D_multisasentry.txt b/test/test_files/reference/nxcansas_1Dand2D_multisasentry.txt index 9353db92..a40fb7bb 100644 --- a/test/test_files/reference/nxcansas_1Dand2D_multisasentry.txt +++ b/test/test_files/reference/nxcansas_1Dand2D_multisasentry.txt @@ -9,42 +9,42 @@ Metadata: Definition: MH4_5deg_16T_SLOW Process: - Name: Mantid generated CanSAS1D XML - Date: 11-May-2016 12:15:34 + Name: Mantid generated CanSAS1D XML + Date: 11-May-2016 12:15:34 Description: None Sample: - ID: - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: front-detector - Distance: 2845.26 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: front-detector + Distance: 2845.26 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: rear-detector - Distance: 4385.28 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: rear-detector + Distance: 4385.28 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: Spallation Neutron Source Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None sasentry02 Qy Qx @@ -56,39 +56,39 @@ Metadata: Definition: MH4_5deg_16T_SLOW Process: - Name: Mantid generated CanSAS1D XML - Date: 11-May-2016 12:15:34 + Name: Mantid generated CanSAS1D XML + Date: 11-May-2016 12:15:34 Description: None Sample: - ID: - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: front-detector - Distance: 2845.26 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: front-detector + Distance: 2845.26 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: rear-detector - Distance: 4385.28 mm - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: rear-detector + Distance: 4385.28 mm + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: Spallation Neutron Source Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/sphere2micron.txt b/test/test_files/reference/sphere2micron.txt index 3df15c42..11c34a85 100644 --- a/test/test_files/reference/sphere2micron.txt +++ b/test/test_files/reference/sphere2micron.txt @@ -10,17 +10,17 @@ Metadata: Definition: Polystyrene of Markus Strobl, Full Sine, ++ only Process: - Name: SESANS Processing - Date: None + Name: SESANS Processing + Date: None Description: Polarisation measurement through a SESANS instrument Terms: ymax: 0.0168 rad zmax: 0.0168 rad orientation: Z Sample: - ID: None - Transmission: None - Thickness: 0.2 cm - Temperature: None - Position: None - Orientation: None + ID: None + Transmission: None + Thickness: 0.2 cm + Temperature: None + Position: None + Orientation: None diff --git a/test/test_files/reference/sphere_isis.txt b/test/test_files/reference/sphere_isis.txt index e92cfbf3..65c76e26 100644 --- a/test/test_files/reference/sphere_isis.txt +++ b/test/test_files/reference/sphere_isis.txt @@ -9,17 +9,17 @@ Metadata: Definition: PMMA in Mixed Deuterated decalin Process: - Name: SESANS Processing - Date: None + Name: SESANS Processing + Date: None Description: Polarisation measurement through a SESANS instrument Terms: ymax: 0.09 rad zmax: 0.09 rad orientation: Z Sample: - ID: None - Transmission: None - Thickness: 2.0 mm - Temperature: None - Position: None - Orientation: None + ID: None + Transmission: None + Thickness: 2.0 mm + Temperature: None + Position: None + Orientation: None diff --git a/test/test_files/reference/valid_cansas_xml.txt b/test/test_files/reference/valid_cansas_xml.txt index 3b3993ab..29e3dc1c 100644 --- a/test/test_files/reference/valid_cansas_xml.txt +++ b/test/test_files/reference/valid_cansas_xml.txt @@ -8,42 +8,42 @@ Metadata: Definition: LOQ_Standard_TK49_SANS Process: - Name: Mantid generated CanSAS1D XML - Date: 10-Oct-2013 16:00:29 + Name: Mantid generated CanSAS1D XML + Date: 10-Oct-2013 16:00:29 Description: None Terms: svn: 2.6.20130902.1504 user_file: K:/masks/MASKLOQ_MAN_133D_Xpress_8mm.txt Sample: - ID: LOQ_Standard_TK49_SANS - Transmission: None - Thickness: None - Temperature: None - Position: None - Orientation: None + ID: LOQ_Standard_TK49_SANS + Transmission: None + Thickness: None + Temperature: None + Position: None + Orientation: None Collimation: - Length: None + Length: None Detector: - Name: HAB - Distance: 0.579 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: HAB + Distance: 0.579 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Detector: - Name: main-detector-bank - Distance: 4.14902 m - Offset: None - Orientation: None - Beam center: None - Pixel size: None - Slit length: None + Name: main-detector-bank + Distance: 4.14902 m + Offset: None + Orientation: None + Beam center: None + Pixel size: None + Slit length: None Source: Radiation: Spallation Neutron Source Shape: None Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None diff --git a/test/test_files/reference/x25000_no_di.txt b/test/test_files/reference/x25000_no_di.txt index 00d3c9df..f7fb560a 100644 --- a/test/test_files/reference/x25000_no_di.txt +++ b/test/test_files/reference/x25000_no_di.txt @@ -32,5 +32,5 @@ Source: Wavelength: None Min. Wavelength: None Max. Wavelength: None - Wavelength Spread: None - Beam Size: None + Wavelength spread: None + Beam size: None From 2b238b3dcec7a479264d4226abc045eae468c971 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Mon, 19 Oct 2026 16:34:50 +0100 Subject: [PATCH 4/9] Clean up typing issues --- sasdata/metadata.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sasdata/metadata.py b/sasdata/metadata.py index 4d4b69fd..da1a8266 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -14,7 +14,7 @@ import json import re from dataclasses import dataclass, field, fields, is_dataclass -from typing import Any, Self +from typing import TYPE_CHECKING, Any, Self import h5py import numpy as np @@ -24,6 +24,11 @@ from sasdata.quantities.unit_parser import parse_unit from sasdata.quantities.units import NamedUnit +if TYPE_CHECKING: + from _typeshed import DataclassInstance +else: + DataclassInstance = object + def from_json_quantity(obj: dict) -> Quantity | None: if obj is None: @@ -32,8 +37,8 @@ def from_json_quantity(obj: dict) -> Quantity | None: return Quantity(obj["value"], parse_unit(obj["units"])) -class MetadataSerial(abc.ABC): - """Abstract class for metadata which can be serialisaed and deserialised""" +class MetadataSerial(abc.ABC, DataclassInstance): + """Abstract class for metadata which can be serialised and deserialised""" @classmethod @abc.abstractmethod @@ -48,7 +53,6 @@ def as_h5(self, f: h5py.Group): class MetadataSummarisable(MetadataSerial): - @abc.abstractmethod def summary(self) -> str: return "" @@ -840,7 +844,7 @@ def default(self, obj): return super().default(obj) -def access_meta(obj: dataclass, key: str) -> Any | None: +def access_meta(obj: DataclassInstance, key: str) -> Any | None: """Use a string accessor to locate a key from within the data object. @@ -896,7 +900,7 @@ def access_meta(obj: dataclass, key: str) -> Any | None: return result -def meta_tags(obj: dataclass) -> list[str]: +def meta_tags(obj: DataclassInstance) -> list[str]: """Find all leaf accessors from a data object. The function treats the passed in object as a tree. Lists, dicts, @@ -929,7 +933,7 @@ class Thermometer: retrieved with the `access_meta` function. """ - result = [] + result : list[str] = [] items = [("", obj)] while items: path, item = items.pop() @@ -956,7 +960,7 @@ class TagCollection: variable: set[str] = field(default_factory=set) -def collect_tags(objs: list[dataclass]) -> TagCollection: +def collect_tags(objs: list[DataclassInstance]) -> TagCollection: """Identify uniform and varying data within a groups of data objects The resulting TagCollection contains every accessor string that is @@ -972,7 +976,7 @@ def collect_tags(objs: list[dataclass]) -> TagCollection: """ if not objs: - return ([], []) + return TagCollection() first = objs.pop() terms = set(meta_tags(first)) for obj in objs: From 7c3dda015ffddd26e281a30dc4853e3fc330c725 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 22 Oct 2026 12:29:51 +0100 Subject: [PATCH 5/9] Don't place write unit name if unit is nameless --- sasdata/metadata.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sasdata/metadata.py b/sasdata/metadata.py index da1a8266..65a26430 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -482,7 +482,8 @@ def as_h5(self, group: h5py.Group): node.attrs["name"] = term if type(value) is Quantity: node.attrs["value"] = value.value - node.attrs["unit"] = value.units.symbol + if isinstance(value.units, NamedUnit): + node.attrs["unit"] = value.units.symbol else: node.attrs["value"] = value for idx, note in enumerate(self.notes): From 091a9320261d2b7db41993111cc69d11a9b89195 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 22 Oct 2026 12:47:44 +0100 Subject: [PATCH 6/9] Use proper units.none as starting parsed_unit --- sasdata/quantities/unit_parser.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sasdata/quantities/unit_parser.py b/sasdata/quantities/unit_parser.py index a264489d..4fa70910 100644 --- a/sasdata/quantities/unit_parser.py +++ b/sasdata/quantities/unit_parser.py @@ -1,5 +1,6 @@ from re import findall, fullmatch +import sasdata.quantities.units as units from sasdata.quantities.units import Dimensions, NamedUnit, Unit, UnitGroup, symbol_lookup, unit_groups # TODO: This shouldn't be in this file but I don't want to edit Lucas' code before he is finished. @@ -128,7 +129,7 @@ def parse_unit(unit_str: str, longest_unit: bool = True) -> Unit: try: if not validate_unit_str(unit_str): raise ValueError(f"unit_str ({unit_str}) contains forbidden characters.") - parsed_unit = Unit(1, Dimensions()) + parsed_unit = units.none unit_stack = parse_unit_stack(unit_str, longest_unit) for unit in unit_stack: # parsed_unit = combine_units(parsed_unit, unit) From 98f08a1c58ba8bb35e9d6e967fac1fc52108b1ad Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 22 Oct 2026 12:56:02 +0100 Subject: [PATCH 7/9] Throw an exception when calling abstract base class methods --- sasdata/metadata.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sasdata/metadata.py b/sasdata/metadata.py index 65a26430..a112caa6 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -44,12 +44,12 @@ class MetadataSerial(abc.ABC, DataclassInstance): @abc.abstractmethod def from_json(cls, obj: dict) -> Self | None: """Load this metadata from a JSON dict""" - return None + raise NotImplementedError("Attempted to convert an abstract class to JSON") @abc.abstractmethod def as_h5(self, f: h5py.Group): """Export data onto an HDF5 group""" - pass + raise NotImplementedError("Attempted to convert an abstract class to HDF5") class MetadataSummarisable(MetadataSerial): From 32120c9fc2c9660f1899406fc390f03baab91ef8 Mon Sep 17 00:00:00 2001 From: Adam Washington Date: Thu, 22 Oct 2026 12:56:02 +0100 Subject: [PATCH 8/9] Create dict of pretty-printing field names --- sasdata/metadata.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/sasdata/metadata.py b/sasdata/metadata.py index a112caa6..60cffc57 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -73,18 +73,8 @@ def summarize_join(x, between: str = "") -> str: case _: return str(x) - def _pretty_field(self, x: str) -> str: - match x: - case "sample_id": - return "ID" - case "wavelength_min": - return "Min. Wavelength" - case "wavelength_max": - return "Max. Wavelength" - case "beam_shape": - return "Shape" - case _: - return x.capitalize().replace("_", " ") + _pretty_field = {"sample_id": "ID", "wavelength_min": "Min. Wavelength", + "wavelength_max": "Max. Wavelength", "beam_shape": "Shape"} def introspect_summary(self, name: str | None, indent: int = 0, skip=[]) -> str: if name is None: @@ -96,7 +86,10 @@ def introspect_summary(self, name: str | None, indent: int = 0, skip=[]) -> str: for key in self.__dataclass_fields__: if key in skip: continue - pretty = self._pretty_field(key) + if key in self._pretty_field: + pretty = self._pretty_field[key] + else: + pretty = key.capitalize().replace("_", " ") result += ( " " * (indent + 4) + pretty From 098d2e3e458edf2c3c3c03d3805758cd278398fe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 15:04:51 +0000 Subject: [PATCH 9/9] [pre-commit.ci lite] apply automatic fixes for ruff linting errors --- sasdata/quantities/unit_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sasdata/quantities/unit_parser.py b/sasdata/quantities/unit_parser.py index 4fa70910..0367d47a 100644 --- a/sasdata/quantities/unit_parser.py +++ b/sasdata/quantities/unit_parser.py @@ -1,7 +1,7 @@ from re import findall, fullmatch import sasdata.quantities.units as units -from sasdata.quantities.units import Dimensions, NamedUnit, Unit, UnitGroup, symbol_lookup, unit_groups +from sasdata.quantities.units import NamedUnit, Unit, UnitGroup, symbol_lookup, unit_groups # TODO: This shouldn't be in this file but I don't want to edit Lucas' code before he is finished.