2121 assert_not_none ,
2222 try_float_or_none ,
2323)
24- from allotropy .types import DictType
2524
2625
2726@dataclass (frozen = True )
@@ -35,6 +34,7 @@ class ChipData:
3534
3635 @staticmethod
3736 def create (chip_data : DictData ) -> ChipData :
37+ chip_data .mark_read_deep ({"IFCType" , "OSType" , "OSVersion" })
3838 return ChipData (
3939 sensor_chip_identifier = assert_not_none (chip_data .get (str , "Id" ), "Chip ID" ),
4040 sensor_chip_type = chip_data .get (str , "Name" ),
@@ -46,7 +46,7 @@ def create(chip_data: DictData) -> ChipData:
4646 "last modified time" : chip_data .get (str , "LastModTime" ),
4747 "last use time" : chip_data .get (str , "LastUseTime" ),
4848 "first dock date" : chip_data .get (str , "FirstDockDate" ),
49- ** chip_data .get_unread ( skip = { "IFCType" , "OSType" , "OSVersion" } ),
49+ ** chip_data .get_unread_deep ( ),
5050 },
5151 )
5252
@@ -203,16 +203,31 @@ class ReportPointData:
203203 absolute_resonance : float
204204 relative_resonance : float | None
205205 time_setting : float
206- custom_info : DictType
206+ custom_info : dict [ str , Any ]
207207 min_resonance : float
208208 max_resonance : float
209209 lrsd : float
210210 slope : float
211211 sd : float
212+ sample_custom_info : dict [str , Any ]
213+ measurement_aggregate_custom_info : dict [str , Any ]
212214
213215 @staticmethod
214216 def create (data : SeriesData ) -> ReportPointData :
215- return ReportPointData (
217+ # This is to mark the keys as read so they don't get added to the custom_info, which has to use a regex
218+ # because some keys look like 'Sample1_Ligand'
219+ for key in (
220+ "FlowRate" ,
221+ "ContactTime" ,
222+ "Chip" ,
223+ "Ligand" ,
224+ "Method" ,
225+ "Fc" ,
226+ "Sample" ,
227+ ):
228+ data .get_unread (f".*{ key } .*" )
229+
230+ report_point_data = ReportPointData (
216231 identifier = random_uuid_str (),
217232 identifier_role = data [str , "Id" ],
218233 absolute_resonance = data [float , "AbsResp" ],
@@ -236,8 +251,15 @@ def create(data: SeriesData) -> ReportPointData:
236251 "assay_step_purpose" : data .get (str , "AssayStepPurpose" ),
237252 "buffer" : data .get (str , "Buffer" ),
238253 },
254+ sample_custom_info = data .get_custom_keys ({"Cycle" }),
255+ measurement_aggregate_custom_info = data .get_custom_keys ({"Procedure" }),
239256 )
240257
258+ unread_data = data .get_unread ()
259+ for key in list (unread_data .keys ()):
260+ report_point_data .custom_info [key ] = unread_data [key ]
261+ return report_point_data
262+
241263
242264@dataclass (frozen = True )
243265class MeasurementData :
@@ -259,7 +281,7 @@ class MeasurementData:
259281 flow_rate : float | None
260282 contact_time : float | None
261283 dilution : float | None
262- custom_info : dict [str , Any ]
284+ sample_custom_info : dict [str , Any ]
263285
264286
265287@dataclass (frozen = True )
@@ -268,15 +290,15 @@ class SampleData:
268290 custom_info : dict [str , Any ]
269291
270292 @staticmethod
271- def create (intermediate_structured_data : DictData ) -> SampleData :
272- application_template_details = intermediate_structured_data .get_nested (
273- "application_template_details"
274- )
293+ def create (
294+ intermediate_structured_data : DictData , application_template_details : DictData
295+ ) -> SampleData :
275296 measurements : dict [str , list [MeasurementData ]] = defaultdict (list )
276297 total_cycles = assert_not_none (
277298 intermediate_structured_data .get (int , "total_cycles" ),
278299 "total_cycles" ,
279300 )
301+
280302 for idx in range (total_cycles ):
281303 flowcell_cycle_json = application_template_details .get_nested (
282304 f"Flowcell { idx + 1 } "
@@ -324,15 +346,33 @@ def create(intermediate_structured_data: DictData) -> SampleData:
324346 flow_rate = flowcell_cycle_json .get (float , "Flow" ),
325347 contact_time = flowcell_cycle_json .get (float , "ContactTime" ),
326348 dilution = flowcell_cycle_json .get (float , "DilutePercent" ),
327- custom_info = {},
349+ sample_custom_info = {},
328350 )
329351 # group sensorgram data by Flow Cell Number (Fc in rpoint data)
330352 for flow_cell , sensorgram_df in sensorgram_data .groupby (
331353 "Flow Cell Number"
332354 )
333355 ]
334- custom_info : dict [str , Any ] = {}
335- return SampleData (measurements , custom_info )
356+ # Add custom info from report point data
357+ for measurement_data in measurements [sample_location_key ]:
358+ if measurement_data .report_point_data :
359+ for report_point_data_item in measurement_data .report_point_data :
360+ measurement_data .sample_custom_info .update (
361+ report_point_data_item .sample_custom_info
362+ )
363+ break
364+ return SampleData (measurements , {})
365+
366+ def get_measurement_aggregate_custom_info (self ) -> dict [str , Any ]:
367+ measurement_aggregate_custom_info : dict [str , Any ] = {}
368+ for measurements_by_sample_location_key in self .measurements .values ():
369+ for measurement_data in measurements_by_sample_location_key :
370+ if measurement_data .report_point_data :
371+ for report_point_data_item in measurement_data .report_point_data :
372+ measurement_aggregate_custom_info .update (
373+ report_point_data_item .measurement_aggregate_custom_info
374+ )
375+ return measurement_aggregate_custom_info
336376
337377
338378@dataclass (frozen = True )
@@ -360,9 +400,15 @@ def create(intermediate_structured_data: DictData) -> Data:
360400 system_information = SystemInformation .create (system_information_dictdata )
361401 chip_data_dictdata = intermediate_structured_data .get_nested ("chip" )
362402 chip_data = ChipData .create (chip_data_dictdata )
363- sample_data = SampleData .create (intermediate_structured_data )
403+ sample_data = SampleData .create (
404+ intermediate_structured_data , application_template_details
405+ )
406+
407+ system_information .measurement_aggregate_custom_info .update (
408+ sample_data .get_measurement_aggregate_custom_info ()
409+ )
364410
365- # This has to be called later because in SampleData.create some of the unread keys are called
411+ # This has to be called later because SampleData.create uses some of the unread keys
366412 run_metadata .set_device_custom_info (application_template_details )
367413
368414 return Data (
0 commit comments