44
55import enum
66from datetime import datetime
7+ from typing import Annotated , Any
78
9+ import scipp as sc
810import scippnexus as snx
911from dateutil .parser import parse as parse_datetime
10- from pydantic import BaseModel , EmailStr
12+ from pydantic import BaseModel , BeforeValidator , EmailStr
1113
1214from ._orcid import ORCIDiD
1315
1416
17+ def _unpack_variable (value : object ) -> Any :
18+ """Before validator to support passing scalar scipp variables as inputs."""
19+ if isinstance (value , sc .Variable ):
20+ if value .dims :
21+ raise ValueError ("Must be a scalar" )
22+ if value .unit and value .unit != '' :
23+ raise ValueError ("Must be dimensionless or have no unit at all" )
24+ return value .value
25+ return value
26+
27+
1528class Beamline (BaseModel ):
1629 """A beamline / instrument.
1730
@@ -39,13 +52,13 @@ class Beamline(BaseModel):
3952 which version of the beamline was used.
4053 """
4154
42- name : str
55+ name : Annotated [ str , BeforeValidator ( _unpack_variable )]
4356 """Name of the beamline."""
44- facility : str | None = None
57+ facility : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
4558 """Facility where the beamline is located."""
46- site : str | None = None
59+ site : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
4760 """Site where the facility is located."""
48- revision : str | None = None
61+ revision : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
4962 """Revision of the beamline in case of upgrades."""
5063
5164 @classmethod
@@ -105,14 +118,16 @@ class Measurement(BaseModel):
105118 ``start_time`` and ``end_time``.
106119 """
107120
108- title : str | None
121+ title : Annotated [ str | None , BeforeValidator ( _unpack_variable )]
109122 """The title of the measurement."""
110- run_number : str | None = None
123+ run_number : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
111124 """Run number of the measurement."""
112- experiment_id : str | None = None
125+ experiment_id : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
113126 """An ID for the experiment that this measurement is part of, e.g., proposal ID."""
114- experiment_doi : str | None = None
127+ experiment_doi : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
115128 """A DOI for the experiment that this measurement is part of."""
129+ # These do not support conversion from variables because variables are naive w.r.t.
130+ # timezones and converting them to datetime.datetime would require extra info.
116131 start_time : datetime | None = None
117132 """Date and time when the measurement started."""
118133 end_time : datetime | None = None
@@ -164,16 +179,16 @@ class Person(BaseModel):
164179 and can usually be omitted when an ORCID iD is provided.
165180 """
166181
167- name : str
182+ name : Annotated [ str , BeforeValidator ( _unpack_variable )]
168183 """Free form name of the person."""
169- orcid_id : ORCIDiD | None = None
184+ orcid_id : Annotated [ ORCIDiD | None , BeforeValidator ( _unpack_variable )] = None
170185 """ORCID iD of the person."""
171186
172187 corresponding : bool = False
173188 """Whether the person is the corresponding / contact author."""
174189 owner : bool = True
175190 """Whether the person owns the data."""
176- role : str | None = None
191+ role : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
177192 """The role that the person played in collecting / processing the data.
178193
179194 `NeXus <https://manual.nexusformat.org/classes/base_classes/NXuser.html#nxuser>`_
@@ -182,11 +197,11 @@ class Person(BaseModel):
182197 list possible roles.
183198 """
184199
185- address : str | None = None
200+ address : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
186201 """Physical (work) address of the person."""
187- email : EmailStr | None = None
202+ email : Annotated [ EmailStr | None , BeforeValidator ( _unpack_variable )] = None
188203 """Email address of the person."""
189- affiliation : str | None = None
204+ affiliation : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
190205 """Affiliation of the person."""
191206
192207
@@ -350,7 +365,7 @@ class Source(BaseModel):
350365 The ESS source is provided as ``scippneutron.metadata.ESS_SOURCE``.
351366 """
352367
353- name : str | None = None
368+ name : Annotated [ str | None , BeforeValidator ( _unpack_variable )] = None
354369 """Name of the source."""
355370 source_type : SourceType
356371 """Type of this source."""
0 commit comments