Skip to content

Commit ecd5c87

Browse files
add unread data to plate reader asm
1 parent 3c0a571 commit ecd5c87

2 files changed

Lines changed: 49 additions & 2 deletions

File tree

src/allotropy/parsers/moldev_softmax_pro/softmax_pro_data_creator.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ def _create_measurements(plate_block: PlateBlock, position: str) -> list[Measure
249249

250250

251251
def _create_measurement_group(
252-
plate_block: PlateBlock, position: str, date_last_saved: str | None
252+
plate_block: PlateBlock,
253+
position: str,
254+
date_last_saved: str | None,
255+
structure_data: StructureData,
253256
) -> MeasurementGroup | None:
254257

255258
if not (measurements := _create_measurements(plate_block, position)):
@@ -260,10 +263,41 @@ def _create_measurement_group(
260263
delta = datetime.timedelta(seconds=plate_block.header.read_time or 0)
261264
measurement_time = (parser.parse(date_last_saved) + delta).isoformat()
262265

266+
# Gather unread group fields for this plate/position
267+
unread_rows: list[dict[str, float | str | None]] = []
268+
single_plate_name: str | None = None
269+
if len(structure_data.block_list.plate_blocks) == 1:
270+
single_plate_name = next(iter(structure_data.block_list.plate_blocks.keys()))
271+
272+
for group_block in structure_data.block_list.group_blocks:
273+
for group_sample_data in group_block.group_data.sample_data:
274+
for (
275+
plate_key,
276+
positions_map,
277+
) in group_sample_data.unread_by_plate_and_position.items():
278+
effective_plate = (
279+
plate_key if plate_key is not None else single_plate_name
280+
)
281+
# filters out unread entries that do not belong to the current plate
282+
if effective_plate != plate_block.header.name:
283+
continue
284+
if position in positions_map:
285+
unread_rows.extend(positions_map[position])
286+
287+
# Flatten unread rows into a single custom_info dict
288+
custom_info = None
289+
if unread_rows:
290+
merged = {}
291+
for row_dict in unread_rows:
292+
# Only include keys with non-None values
293+
merged.update({k: v for k, v in row_dict.items() if v is not None})
294+
custom_info = merged
295+
263296
return MeasurementGroup(
264297
measurements=measurements,
265298
plate_well_count=plate_block.header.num_wells,
266299
measurement_time=measurement_time,
300+
custom_info=custom_info,
267301
)
268302

269303

@@ -274,7 +308,7 @@ def create_measurement_groups(data: StructureData) -> list[MeasurementGroup]:
274308
for position in plate_block.iter_wells()
275309
if (
276310
measurement_group := _create_measurement_group(
277-
plate_block, position, data.date_last_saved
311+
plate_block, position, data.date_last_saved, data
278312
)
279313
)
280314
]

src/allotropy/parsers/moldev_softmax_pro/softmax_pro_structure.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ class GroupDataElement:
128128
class GroupSampleData:
129129
identifier: str
130130
data_elements: list[GroupDataElement]
131+
# Capture unread fields per plate and well position. The None key is used when plate is unspecified.
132+
unread_by_plate_and_position: dict[
133+
str | None, dict[str, list[dict[str, float | str | None]]]
134+
]
131135

132136
@classmethod
133137
def create(cls, data: pd.DataFrame, calc_data_cols: list[str]) -> GroupSampleData:
@@ -141,6 +145,9 @@ def create(cls, data: pd.DataFrame, calc_data_cols: list[str]) -> GroupSampleDat
141145
data_elements: dict[str, list[GroupDataElement]] = {
142146
column: [] for column in data_columns
143147
}
148+
unread_by_plate_and_position: dict[
149+
str | None, dict[str, list[dict[str, float | str | None]]]
150+
] = {}
144151
for row in row_data:
145152
row_results = cls._get_row_results(row, data_columns)
146153
position = row[str, ["Well", "Wells"]]
@@ -170,12 +177,18 @@ def create(cls, data: pd.DataFrame, calc_data_cols: list[str]) -> GroupSampleDat
170177
)
171178
elif data_elements[column]:
172179
data_elements[column][-1].positions.append(position)
180+
row.mark_read("Sample")
181+
unread = row.get_unread()
182+
if unread:
183+
by_position = unread_by_plate_and_position.setdefault(plate, {})
184+
by_position.setdefault(str(position), []).append(unread)
173185

174186
return GroupSampleData(
175187
identifier=identifier,
176188
data_elements=[
177189
elem for elements in data_elements.values() for elem in elements
178190
],
191+
unread_by_plate_and_position=unread_by_plate_and_position,
179192
)
180193

181194
@classmethod

0 commit comments

Comments
 (0)