Skip to content

Commit 6250eb3

Browse files
feat: Beckman Vi-Cell XR - Add unread data (#1044)
Update for this ticket: [BNCH-115074](https://jira.benchling.team/browse/BNCH-115074) --------- Co-authored-by: Nathan Stender <nathan.stender@benchling.com>
1 parent bb03a3d commit 6250eb3

14 files changed

Lines changed: 4954 additions & 412 deletions

src/allotropy/allotrope/converter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
"$": "_DOLLAR_",
104104
"~": "_TILDE_",
105105
"?": "_QMARK_",
106+
"^": "_CARET_",
106107
# NOTE: this MUST be at the end, or it will break other key replacements.
107108
" ": "_",
108109
}

src/allotropy/parsers/beckman_vi_cell_xr/vi_cell_xr_structure.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ def create_measurement_group(data: SeriesData) -> MeasurementGroup:
3030
viable_cell_count if viable_cell_count is None else round(viable_cell_count)
3131
)
3232

33+
custom_info_measurement_group = data.get_custom_keys(
34+
{
35+
"experimental data identifier": ["File Name", "File name"],
36+
"log date": ["LogDate", "Log date"],
37+
"file date": ["FileDate", "File date"],
38+
}
39+
)
40+
41+
# Mark unused keys to be ignored
42+
data.mark_read({"Settings:", "Results:", "Settings", "Results"})
43+
3344
return MeasurementGroup(
3445
analyst=DEFAULT_ANALYST,
3546
measurements=[
@@ -45,9 +56,70 @@ def create_measurement_group(data: SeriesData) -> MeasurementGroup:
4556
total_cell_density=data.get(float, "Total cells/ml (x10^6)"),
4657
average_total_cell_diameter=data.get(float, "Avg. diam. (microns)"),
4758
viable_cell_count=viable_cell_count,
59+
dead_cell_count=data.get(float, "Nonviable cells"),
4860
average_total_cell_circularity=data.get(float, "Avg. circ."),
61+
maximum_cell_diameter_setting=data.get(float, "Max diam. (microns)")
62+
or data.get(float, "Maximum diameter (microns)"),
63+
minimum_cell_diameter_setting=data.get(float, "Min diam. (microns)")
64+
or data.get(float, "Minimum diameter (microns)"),
65+
sample_custom_info=data.get_custom_keys(
66+
{
67+
"Internal Dilution",
68+
"Dilution",
69+
}
70+
),
71+
device_control_custom_info=data.get_custom_keys(
72+
{
73+
"Aspirate cycles",
74+
"Probe volume (ml x 10^-6)",
75+
"Trypan blue mixing cycles",
76+
}
77+
),
78+
data_processing_custom_info=data.get_custom_keys(
79+
{
80+
"Decluster degree",
81+
"Viable cell spot area (%)",
82+
"Viable spot area",
83+
"Viable cell spot brightness (%)",
84+
"V. cell spot brightness (%)",
85+
"Cell sharpness",
86+
"Sharpness",
87+
"Cell brightness (%)",
88+
"Brightness (%)",
89+
"Brightness",
90+
"Analysis version",
91+
"Number of bins",
92+
"Minimum circularity",
93+
"Sample depth (microns)",
94+
}
95+
),
96+
image_processing_custom_info=data.get_custom_keys(
97+
{
98+
"Images",
99+
"Saved images",
100+
"ImageBaseName",
101+
"Frames",
102+
"Microns/pixel ratio",
103+
"ImageDirectory",
104+
"Image size",
105+
"Field of view (microns)",
106+
}
107+
),
108+
processed_data_custom_info=data.get_custom_keys(
109+
{
110+
"Avg. cells / image",
111+
"Average cells / image",
112+
"Background intensity sum",
113+
"Total diameter sum",
114+
"Total circularity sum",
115+
"Avg. background intensity",
116+
"Avg. bg intensity",
117+
}
118+
),
119+
custom_info=data.get_unread(),
49120
)
50121
],
122+
custom_info=custom_info_measurement_group,
51123
)
52124

53125

src/allotropy/parsers/utils/pandas.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,29 @@ def _get_matching_keys(self, key_or_keys: str | set[str]) -> set[str]:
287287
}
288288

289289
def get_custom_keys(
290+
self, key_or_keys: str | set[str] | dict[str, list[str]]
291+
) -> dict[str, float | str | None]:
292+
if isinstance(key_or_keys, dict):
293+
return self._get_custom_keys_from_dict(key_or_keys)
294+
return self._get_custom_keys_from_str_or_set(key_or_keys)
295+
296+
def _get_custom_keys_from_dict(
297+
self, key_or_keys: dict[str, list[str]]
298+
) -> dict[str, float | str | None]:
299+
if isinstance(key_or_keys, dict):
300+
result = {}
301+
for output_key, candidate_keys in key_or_keys.items():
302+
for candidate_key in candidate_keys:
303+
value = self._validate_raw(
304+
self._get_custom_key(candidate_key), SeriesData.NOT_NAN
305+
)
306+
if value is not None:
307+
result[output_key] = value
308+
break # Stop iteration once a value is found
309+
# If no value was found for any candidate key, the output_key is excluded
310+
return result
311+
312+
def _get_custom_keys_from_str_or_set(
290313
self, key_or_keys: str | set[str]
291314
) -> dict[str, float | str | None]:
292315
return {

0 commit comments

Comments
 (0)