2929 UltravioletAbsorbanceSpectrumDetectionMeasurementDocumentItems ,
3030)
3131from allotropy .allotrope .models .shared .definitions .custom import (
32+ TQuantityValueKiloDalton ,
3233 TQuantityValueMicroliter ,
3334 TQuantityValueMilliAbsorbanceUnit ,
35+ TQuantityValueNanogramPerMicroliter ,
3436 TQuantityValueNanometer ,
37+ TQuantityValuePerMolarPerCentimeter ,
3538 TQuantityValueRelativeFluorescenceUnit ,
3639 TQuantityValueUnitless ,
3740)
@@ -77,6 +80,7 @@ class ProcessedDataFeature:
7780class ProcessedData :
7881 features : list [ProcessedDataFeature ]
7982 identifier : str | None = None
83+ custom_info : dict [str , Any ] | None = None
8084
8185
8286@dataclass
@@ -102,6 +106,8 @@ class Measurement:
102106 original_sample_concentration_unit : str | None = None
103107 baseline_absorbance : float | None = None
104108 electronic_absorbance_reference_wavelength_setting : float | None = None
109+ cursor_position : float | None = None
110+ cursor_absorbance : float | None = None
105111
106112 # Measurements
107113 absorbance : JsonFloat | None = None
@@ -127,6 +133,7 @@ class MeasurementGroup:
127133 container_type : str | None = None
128134
129135 processed_data : ProcessedData | None = None
136+ custom_info : dict [str , Any ] | None = None
130137
131138
132139@dataclass (frozen = True )
@@ -194,16 +201,19 @@ def _get_technique_document(
194201 ) -> SpectrophotometryDocumentItem :
195202 return SpectrophotometryDocumentItem (
196203 analyst = measurement_group .analyst ,
197- measurement_aggregate_document = MeasurementAggregateDocument (
198- measurement_time = self .get_date_time (
199- assert_not_none (measurement_group .measurement_time )
204+ measurement_aggregate_document = add_custom_information_document (
205+ MeasurementAggregateDocument (
206+ measurement_time = self .get_date_time (
207+ assert_not_none (measurement_group .measurement_time )
208+ ),
209+ experiment_type = measurement_group .experiment_type ,
210+ container_type = metadata .container_type ,
211+ measurement_document = [
212+ self ._get_measurement_document_item (measurement , metadata )
213+ for measurement in measurement_group .measurements
214+ ],
200215 ),
201- experiment_type = measurement_group .experiment_type ,
202- container_type = metadata .container_type ,
203- measurement_document = [
204- self ._get_measurement_document_item (measurement , metadata )
205- for measurement in measurement_group .measurements
206- ],
216+ measurement_group .custom_info ,
207217 ),
208218 )
209219
@@ -265,6 +275,14 @@ def _get_ultraviolet_absorbance_measurement_document(
265275 TQuantityValueMilliAbsorbanceUnit ,
266276 measurement .baseline_absorbance ,
267277 ),
278+ "340 raw" : quantity_or_none (
279+ TQuantityValueMilliAbsorbanceUnit ,
280+ (measurement .custom_info or {}).get ("340 raw" ),
281+ ),
282+ "Cursor Abs." : quantity_or_none (
283+ TQuantityValueMilliAbsorbanceUnit ,
284+ measurement .cursor_absorbance ,
285+ ),
268286 }
269287 return add_custom_information_document (doc , custom_info_doc )
270288
@@ -337,6 +355,9 @@ def _get_device_control_custom_document(
337355 "dilution factor" : quantity_or_none (
338356 TQuantityValueUnitless , measurement .dilution_factor_setting
339357 ),
358+ "Cursor Pos." : quantity_or_none (
359+ TQuantityValueNanometer , measurement .cursor_position
360+ ),
340361 }
341362 return (measurement .device_control_custom_info or {}) | custom_info
342363
@@ -359,14 +380,19 @@ def _get_sample_document(self, measurement: Measurement) -> SampleDocument:
359380 measurement .sample_custom_info ["last read standards" ]
360381 )
361382
383+ sample_custom_info = measurement .sample_custom_info or {}
384+ sample_custom_info ["Mol. Wt. kda" ] = quantity_or_none (
385+ TQuantityValueKiloDalton , sample_custom_info .get ("Mol. Wt. kda" )
386+ )
387+
362388 return add_custom_information_document (
363389 SampleDocument (
364390 sample_identifier = measurement .sample_identifier ,
365391 batch_identifier = measurement .batch_identifier ,
366392 location_identifier = measurement .location_identifier ,
367393 well_plate_identifier = measurement .well_plate_identifier ,
368394 ),
369- ( measurement . sample_custom_info or {}) | custom_info_doc ,
395+ sample_custom_info | custom_info_doc ,
370396 )
371397
372398 def _get_processed_data_aggregate_document (
@@ -375,14 +401,38 @@ def _get_processed_data_aggregate_document(
375401 if not data :
376402 return None
377403
404+ # Build custom info for processed data with proper TQuantityValue wrappers
405+ processed_data_custom_info = {}
406+ if data .custom_info :
407+ processed_data_custom_info = {
408+ "E1%" : quantity_or_none (
409+ TQuantityValueUnitless , data .custom_info .get ("E1%" )
410+ ),
411+ "ext. coeff x10e3" : quantity_or_none (
412+ TQuantityValuePerMolarPerCentimeter ,
413+ data .custom_info .get ("ext. coeff x10e3" ),
414+ ),
415+ "ext.c." : quantity_or_none (
416+ TQuantityValuePerMolarPerCentimeter ,
417+ data .custom_info .get ("ext.c. (l/(mol*cm))" ),
418+ ),
419+ "conc. factor" : quantity_or_none (
420+ TQuantityValueNanogramPerMicroliter ,
421+ data .custom_info .get ("conc. factor (ng/ul)" ),
422+ ),
423+ }
424+
378425 return ProcessedDataAggregateDocument (
379426 processed_data_document = [
380- ProcessedDataDocumentItem (
381- # TODO(nstender): figure out how to limit possible classes from get_quantity_class for typing.
382- mass_concentration = quantity_or_none (
383- get_quantity_class (feature .unit ), feature .result # type: ignore[arg-type]
427+ add_custom_information_document (
428+ ProcessedDataDocumentItem (
429+ # TODO(nstender): figure out how to limit possible classes from get_quantity_class for typing.
430+ mass_concentration = quantity_or_none (
431+ get_quantity_class (feature .unit ), feature .result # type: ignore[arg-type]
432+ ),
433+ processed_data_identifier = data .identifier ,
384434 ),
385- processed_data_identifier = data . identifier ,
435+ processed_data_custom_info ,
386436 )
387437 for feature in data .features
388438 ]
0 commit comments