Skip to content
Open
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
Binary file not shown.
21 changes: 16 additions & 5 deletions mtphandler/readers/biotek.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,22 @@ def read_biotek(

wavelengths = extract_integers(wavelengths_cell)

measurement_int_cell = str(df.iloc[15, 1])
if "add final component" in measurement_int_cell.lower():
measurement_int_cell = str(df.iloc[16, 1])

measurement_interval = parse_measurement_interval(measurement_int_cell)
measurement_interval = None
for index, row_value in df.iloc[:, 0].items():
if isinstance(row_value, str) and "start kinetic" in row_value.lower(): # this is the start of a kinetic read block
interval_candidate = str(df.iloc[index, 1])
try:
measurement_interval = parse_measurement_interval(interval_candidate)
break # Found a valid interval, stop searching. Note that there could be more kinetic intervals later.
except ValueError:
continue # Keep searching if this one fails

if measurement_interval is None:
# Fallback to original logic if 'Start Kinetic' not found or parsed
measurement_int_cell = str(df.iloc[15, 1])
if "add final component" in measurement_int_cell.lower():
measurement_int_cell = str(df.iloc[16, 1])
measurement_interval = parse_measurement_interval(measurement_int_cell)

plate = Plate(
date_measured=timestamp,
Expand Down
40 changes: 40 additions & 0 deletions tests/unit_tests/test_readers/test_biotek_epoch_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,43 @@ def test_read_biotek_epoch_2():

if well.id == "D9":
assert well.measurements[0].absorption[-1] == pytest.approx(0.226, rel=1e-2)

# Test another BioTek plate example
"""Tests that read_biotek can correctly parse the gen5 data file with dynamic kinetic interval detection."""
test_file_path = "docs/examples/data/gen5_data_export_test_12-1-2025.xlsx"

# Ensure the test file exists
#assert os.path.exists(test_file_path), f"Test file not found: {test_file_path}"

# Use the read_biotek function with the test file
# This should now run without raising a ValueError due to the fix
plate = read_biotek(path=test_file_path, ph=7.4)

# Assert that a Plate object is returned
assert isinstance(plate, Plate)

# Assert that the plate contains wells and measurements
assert len(plate.wells) > 0
assert len(plate.wells[0].measurements) > 0

# Get the first measurement from the first well
first_measurement = plate.wells[0].measurements[0]

# Assert that the time data is populated and has more than one point
assert len(first_measurement.time) > 1

# The expected interval from the file is 'Interval 0:08:00', which is 8 minutes.
# As currently implemented, `np.arange` uses this minute value directly
# to generate the time series, even though `time_unit='s'` is specified.
expected_interval_minutes = 8.0
actual_interval = first_measurement.time[1] - first_measurement.time[0]

# Assert that the actual interval matches the expected 8.0 minutes
assert actual_interval == pytest.approx(expected_interval_minutes)

# Note: There's a potential inconsistency in the read_biotek function
# where time points are generated using 'minutes' but `time_unit` is set to 's' (seconds).
# This test validates the numerical interval extracted, but a future enhancement
# might involve ensuring strict unit consistency (e.g., converting minutes to seconds
# before generating the time array if time_unit is 's').