Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion SUPPORTED_INSTRUMENT_SOFTWARE.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The parsers follow maturation levels of: Recommended, Candidate Release, Working
|Benchling Thermo Fisher Scientific Chromeleon|Recommended|BENCHLING/2023/09
.2+|Liquid Handler|Beckman Coulter Biomek|Recommended|BENCHLING/2024/11
|Beckman Echo Plate Reformat|Recommended|BENCHLING/2024/11
.2+|Multi Analyte Profiling|Bio-Rad Bio-Plex Manager|Recommended|BENCHLING/2024/01
.2+|Multi Analyte Profiling|Bio-Rad Bio-Plex Manager|Recommended|BENCHLING/2024/09
|Luminex xPONENT|Recommended|BENCHLING/2024/09
.14+|Plate Reader|Agilent Gen5|Recommended|REC/2025/03
|Agilent Gen5 Image|Recommended|BENCHLING/2023/09
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from __future__ import annotations

from allotropy.allotrope.models.adm.multi_analyte_profiling.benchling._2024._01.multi_analyte_profiling import (
from allotropy.allotrope.models.adm.multi_analyte_profiling.benchling._2024._09.multi_analyte_profiling import (
Model,
)
from allotropy.allotrope.schema_mappers.adm.multi_analyte_profiling.benchling._2024._01.multi_analyte_profiling import (
from allotropy.allotrope.schema_mappers.adm.multi_analyte_profiling.benchling._2024._09.multi_analyte_profiling import (
Data,
Mapper,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
import xml.etree.ElementTree as Et

from allotropy.allotrope.models.shared.components.plate_reader import SampleRoleType
from allotropy.allotrope.models.shared.definitions.definitions import (
TStatisticDatumRole,
)
from allotropy.allotrope.schema_mappers.adm.multi_analyte_profiling.benchling._2024._01.multi_analyte_profiling import (
from allotropy.allotrope.schema_mappers.adm.multi_analyte_profiling.benchling._2024._09.multi_analyte_profiling import (
Analyte,
Error,
Measurement,
MeasurementGroup,
Metadata,
StatisticDimension,
StatisticsDocument,
)
from allotropy.exceptions import get_key_or_error
from allotropy.parsers.biorad_bioplex_manager import constants
from allotropy.parsers.constants import NOT_APPLICABLE
from allotropy.parsers.utils.uuids import random_uuid_str
from allotropy.parsers.utils.values import (
num_to_chars,
Expand Down Expand Up @@ -153,15 +153,32 @@ def create_analyte(
) -> Analyte:
# Look up analyte name from sample
assay_bead_identifier = bead_region_xml.attrib["RegionNumber"]

# Create statistics dimensions from available statistics in the XML
statistic_dimensions = []
for statistic_name, statistic_config in constants.STATISTIC_SECTIONS_CONF.items():
statistic_value = get_val_from_xml(bead_region_xml, statistic_name)
statistic_dimensions.append(
StatisticDimension(
value=try_float(statistic_value, f"{statistic_name} statistic"),
unit=statistic_config.unit,
statistic_datum_role=statistic_config.role,
)
)

return Analyte(
identifier=random_uuid_str(),
name=analyte_region_dict[assay_bead_identifier],
value=try_float(get_val_from_xml(bead_region_xml, "Median"), "fluorescence"),
assay_bead_identifier=assay_bead_identifier,
assay_bead_count=try_int(
get_val_from_xml(bead_region_xml, "RegionCount"), "assay_bead_count"
),
statistic_datum_role=TStatisticDatumRole.median_role,
statistics=[
StatisticsDocument(
statistical_feature="fluorescence",
statistic_dimensions=statistic_dimensions,
)
],
)


Expand Down Expand Up @@ -213,15 +230,18 @@ def get_well_name(well_attrib: dict[str, str]) -> str:
def create_metadata(
root_xml: Et.Element, system_metadata: SystemMetadata, file_path: str
) -> Metadata:
path = Path(file_path)
return Metadata(
file_name=Path(file_path).name,
file_name=path.name,
unc_path=file_path,
software_name=constants.SOFTWARE_NAME,
software_version=root_xml.attrib["BioPlexManagerVersion"],
equipment_serial_number=system_metadata.serial_number,
firmware_version=system_metadata.controller_version,
product_manufacturer=constants.PRODUCT_MANUFACTURER,
device_type=constants.DEVICE_TYPE,
asm_file_identifier=path.with_suffix(".json").name,
data_system_instance_identifier=NOT_APPLICABLE,
)


Expand Down
52 changes: 51 additions & 1 deletion src/allotropy/parsers/biorad_bioplex_manager/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from dataclasses import dataclass

from allotropy.allotrope.models.shared.components.plate_reader import SampleRoleType
from allotropy.allotrope.models.shared.definitions.definitions import (
TStatisticDatumRole,
)

SOFTWARE_NAME = "Bio-Plex Manager"
SOFTWARE_NAME = "Bio-Plex Manager"
PRODUCT_MANUFACTURER = "Bio-Rad"
DEVICE_TYPE = "multi analyte profiling analyzer"
CONTAINER_TYPE = "well plate"
Expand All @@ -27,3 +32,48 @@
"PlateDimensions",
"Wells",
]


@dataclass(frozen=True)
class StatisticSectionConfig:
role: TStatisticDatumRole
unit: str


# Statistics mapping for Bio-Rad BioPlex XML elements
STATISTIC_SECTIONS_CONF = {
"Median": StatisticSectionConfig(
role=TStatisticDatumRole.median_role,
unit="RFU",
),
"Mean": StatisticSectionConfig(
role=TStatisticDatumRole.arithmetic_mean_role,
unit="RFU",
),
"CV": StatisticSectionConfig(
role=TStatisticDatumRole.coefficient_of_variation_role,
unit="(unitless)",
),
"StdDev": StatisticSectionConfig(
role=TStatisticDatumRole.standard_deviation_role,
unit="(unitless)",
),
"TrimmedMean": StatisticSectionConfig(
role=TStatisticDatumRole.trimmed_arithmetic_mean_role,
unit="RFU",
),
"TrimmedStdDev": StatisticSectionConfig(
role=TStatisticDatumRole.trimmed_standard_deviation_role,
unit="(unitless)",
),
# "StdErr": StatisticSectionConfig(
# role=TStatisticDatumRole.standard_error_role,
# unit="RFU",
# ),
# "TrimmedCV": StatisticSectionConfig(
# role=TStatisticDatumRole.trimmed_coefficient_of_variation_role,
# unit="(unitless)",
# ),
# Note: StdErr (standard error) and TrimmedCV (trimmed coefficient of variation)
# are not supported yet
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from allotropy.allotrope.models.shared.definitions.definitions import (
TStatisticDatumRole,
)
from allotropy.allotrope.schema_mappers.adm.multi_analyte_profiling.benchling._2024._01.multi_analyte_profiling import (
from allotropy.allotrope.schema_mappers.adm.multi_analyte_profiling.benchling._2024._09.multi_analyte_profiling import (
Analyte,
Error,
StatisticDimension,
StatisticsDocument,
)
from allotropy.parsers.biorad_bioplex_manager.biorad_bioplex_manager_structure import (
AnalyteMetadata,
Expand Down Expand Up @@ -89,13 +91,52 @@ def test_create_analyte_document_data() -> None:
bead_xml,
analyte_region_dict=analyte_region_dict,
)

# Expected statistics from the XML
expected_statistics = [
StatisticsDocument(
statistical_feature="fluorescence",
statistic_dimensions=[
StatisticDimension(
value=992.5,
unit="RFU",
statistic_datum_role=TStatisticDatumRole.median_role,
),
StatisticDimension(
value=983.391296386718750,
unit="RFU",
statistic_datum_role=TStatisticDatumRole.arithmetic_mean_role,
),
StatisticDimension(
value=0.223858922719955440,
unit="(unitless)",
statistic_datum_role=TStatisticDatumRole.coefficient_of_variation_role,
),
StatisticDimension(
value=220.140914916992190,
unit="(unitless)",
statistic_datum_role=TStatisticDatumRole.standard_deviation_role,
),
StatisticDimension(
value=974.904785156250000,
unit="RFU",
statistic_datum_role=TStatisticDatumRole.trimmed_arithmetic_mean_role,
),
StatisticDimension(
value=181.356109619140620,
unit="(unitless)",
statistic_datum_role=TStatisticDatumRole.trimmed_standard_deviation_role,
),
],
)
]

assert analyte_document_data == Analyte(
identifier="dummy_id",
name="Pn4",
value=992.5,
assay_bead_count=46,
assay_bead_identifier="62",
statistic_datum_role=TStatisticDatumRole.median_role,
statistics=expected_statistics,
)


Expand Down
Loading
Loading