Skip to content

Commit 347232e

Browse files
re-structure custom fields within ASM
1 parent 1e6ca16 commit 347232e

4 files changed

Lines changed: 248 additions & 167 deletions

File tree

src/allotropy/allotrope/schema_mappers/adm/flow_cytometry/benchling/_2025/_03/flow_cytometry.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class MeasurementGroup:
140140
measurement_time: str | None = None
141141
experimental_data_identifier: str | None = None
142142
experiment_identifier: str | None = None
143+
measurement_aggregate_custom_info: dict[str, Any] | None = None
143144
custom_info: dict[str, Any] | None = None
144145

145146

@@ -201,19 +202,22 @@ def _get_technique_document(
201202
) -> FlowCytometryDocumentItem:
202203
return add_custom_information_document(
203204
FlowCytometryDocumentItem(
204-
measurement_aggregate_document=MeasurementAggregateDocument(
205-
measurement_document=[
206-
self._get_measurement_document(measurement)
207-
for measurement in measurement_group.measurements
208-
],
209-
analyst=measurement_group.analyst,
210-
measurement_time=self.get_date_time(
211-
measurement_group.measurement_time
212-
)
213-
if measurement_group.measurement_time
214-
else None,
215-
experimental_data_identifier=measurement_group.experimental_data_identifier,
216-
experiment_identifier=measurement_group.experiment_identifier,
205+
measurement_aggregate_document=add_custom_information_document(
206+
MeasurementAggregateDocument(
207+
measurement_document=[
208+
self._get_measurement_document(measurement)
209+
for measurement in measurement_group.measurements
210+
],
211+
analyst=measurement_group.analyst,
212+
measurement_time=self.get_date_time(
213+
measurement_group.measurement_time
214+
)
215+
if measurement_group.measurement_time
216+
else None,
217+
experimental_data_identifier=measurement_group.experimental_data_identifier,
218+
experiment_identifier=measurement_group.experiment_identifier,
219+
),
220+
measurement_group.measurement_aggregate_custom_info,
217221
),
218222
compensation_matrix_aggregate_document=CompensationMatrixAggregateDocument(
219223
compensation_matrix_document=[

src/allotropy/parsers/bd_biosciences_facsdiva/bd_biosciences_facsdiva_structure.py

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,25 @@
7777
"Time",
7878
]
7979

80+
FIELDS_TO_SKIP = {
81+
"$OP", # Already captured as analyst
82+
}
83+
84+
# Fields for device control document
85+
DEVICE_CONTROL_FIELDS = {
86+
"CST SETUP STATUS",
87+
"CST BEADS LOT ID",
88+
"CYTOMETER CONFIG NAME",
89+
"CYTOMETER CONFIG CREATE DATE",
90+
"CST SETUP DATE",
91+
"CST BASELINE DATE",
92+
"CST BEADS EXPIRED",
93+
}
94+
95+
MEASUREMENT_AGGREGATE_FIELDS = {
96+
"$BTIM",
97+
}
98+
8099

81100
def _filter_unread_data(unread_data: dict[str, str | None]) -> dict[str, str | None]:
82101
"""Filter out empty, null, or whitespace-only values from unread data."""
@@ -91,6 +110,26 @@ def _filter_unread_data(unread_data: dict[str, str | None]) -> dict[str, str | N
91110
}
92111

93112

113+
def _separate_custom_fields(
114+
custom_info: dict[str, str]
115+
) -> tuple[dict[str, str], dict[str, str], dict[str, str]]:
116+
device_control_info = {}
117+
measurement_aggregate_info = {}
118+
other_info = {}
119+
120+
for key, value in custom_info.items():
121+
if key in FIELDS_TO_SKIP:
122+
continue
123+
elif key in DEVICE_CONTROL_FIELDS:
124+
device_control_info[key] = value
125+
elif key in MEASUREMENT_AGGREGATE_FIELDS:
126+
measurement_aggregate_info[key] = value
127+
else:
128+
other_info[key] = value
129+
130+
return device_control_info, measurement_aggregate_info, other_info
131+
132+
94133
class RegionType(Enum):
95134
POLYGON = "POLYGON"
96135
RECTANGLE = "RECTANGLE"
@@ -533,15 +572,15 @@ def _create_compensation_matrix_groups(
533572

534573
def _process_tube(
535574
tube: StrictXmlElement, specimen_name: str | None, data_processing_time: str | None
536-
) -> list[Measurement]:
575+
) -> tuple[list[Measurement], dict[str, str]]:
537576
"""
538577
Process a tube element to create measurements.
539578
540579
Args:
541580
tube: The tube element to process
542581
543582
Returns:
544-
list[Measurement]: List containing a single Measurement
583+
tuple: (measurements, measurement_aggregate_custom_info)
545584
"""
546585
tube_name = tube.get_attr("name")
547586

@@ -562,6 +601,12 @@ def _process_tube(
562601
if keyword_value:
563602
custom_info[keyword_name] = keyword_value
564603

604+
(
605+
device_control_info,
606+
measurement_aggregate_info,
607+
other_info,
608+
) = _separate_custom_fields(custom_info)
609+
565610
# Create populations and data regions
566611
populations = _create_populations(tube)
567612
data_regions = _create_data_regions(tube)
@@ -574,10 +619,11 @@ def _process_tube(
574619
processed_data_identifier=processed_data_id,
575620
populations=populations,
576621
data_regions=data_regions,
577-
custom_info=custom_info if custom_info else None,
622+
device_control_custom_info=device_control_info if device_control_info else None,
623+
custom_info=other_info if other_info else None,
578624
)
579625

580-
return [measurement]
626+
return [measurement], measurement_aggregate_info
581627

582628

583629
def create_measurement_groups(root_element: StrictXmlElement) -> list[MeasurementGroup]:
@@ -608,7 +654,7 @@ def create_measurement_groups(root_element: StrictXmlElement) -> list[Measuremen
608654
tubes = specimen.findall("tube")
609655
for tube in tubes:
610656
experimental_data_identifier = tube.find_or_none("data_filename")
611-
measurements = _process_tube(
657+
measurements, measurement_aggregate_custom_info = _process_tube(
612658
tube,
613659
specimen_name,
614660
export_time.get_text_or_none() if export_time else None,
@@ -626,6 +672,9 @@ def create_measurement_groups(root_element: StrictXmlElement) -> list[Measuremen
626672
compensation_matrix_groups=compensation_matrix_groups,
627673
measurements=measurements,
628674
experiment_identifier=experiment_identifier,
675+
measurement_aggregate_custom_info=measurement_aggregate_custom_info
676+
if measurement_aggregate_custom_info
677+
else None,
629678
)
630679

631680
result.append(measurement_group)

0 commit comments

Comments
 (0)