|
1 | 1 | """Test absorbance reader initilize command."""
|
| 2 | +import math |
| 3 | +from typing import Dict, List, Optional |
2 | 4 | import pytest
|
3 | 5 | from decoy import Decoy
|
4 | 6 |
|
|
12 | 14 | from opentrons.protocol_engine.execution import EquipmentHandler
|
13 | 15 | from opentrons.protocol_engine.resources import FileProvider
|
14 | 16 | from opentrons.protocol_engine.state import update_types
|
| 17 | +from opentrons.protocol_engine.state.modules import ModuleView |
15 | 18 | from opentrons.protocol_engine.state.state import StateView
|
16 | 19 | from opentrons.protocol_engine.state.module_substates import (
|
17 | 20 | AbsorbanceReaderSubState,
|
|
27 | 30 | )
|
28 | 31 |
|
29 | 32 |
|
| 33 | +def _get_absorbance_map(data: Optional[List[float]] = None) -> Dict[str, float]: |
| 34 | + raw_values = (data or [0] * 96).copy() |
| 35 | + raw_values.reverse() |
| 36 | + well_map: Dict[str, float] = {} |
| 37 | + for i, value in enumerate(raw_values): |
| 38 | + row = chr(ord("A") + i // 12) # Convert index to row (A-H) |
| 39 | + col = (i % 12) + 1 # Convert index to column (1-12) |
| 40 | + well_key = f"{row}{col}" |
| 41 | + # Truncate the value to the third decimal place |
| 42 | + well_map[well_key] = math.floor(value * 1000) / 1000 |
| 43 | + return well_map |
| 44 | + |
| 45 | + |
30 | 46 | async def test_absorbance_reader_implementation(
|
31 | 47 | decoy: Decoy,
|
32 | 48 | state_view: StateView,
|
@@ -88,6 +104,48 @@ async def test_absorbance_reader_implementation(
|
88 | 104 | )
|
89 | 105 |
|
90 | 106 |
|
| 107 | +async def test_convert_absorbance_reader_data_points() -> None: |
| 108 | + """It should validate and convert the absorbance reader values.""" |
| 109 | + # Test valid values |
| 110 | + raw_data = ( |
| 111 | + [0.04877041280269623, 0.046341221779584885] |
| 112 | + + [0.43] * 92 # fill rest of the values with 0.43 |
| 113 | + + [0.03789025545120239, 2.8744750022888184] |
| 114 | + ) |
| 115 | + expected = _get_absorbance_map(raw_data) |
| 116 | + converted = ModuleView.convert_absorbance_reader_data_points(raw_data) |
| 117 | + assert len(converted) == 96 |
| 118 | + assert converted == expected |
| 119 | + assert converted["A1"] == 2.874 |
| 120 | + assert converted["A2"] == 0.037 |
| 121 | + assert converted["E1"] == 0.43 |
| 122 | + assert converted["H12"] == 0.048 # the data is flipped, so arr[0] == H12 |
| 123 | + |
| 124 | + # Test near-zero values in scientic notation |
| 125 | + raw_data = ( |
| 126 | + [0.24877041280269623, -9.5000e-9] |
| 127 | + + [0.11] * 92 # fill rest of the values with 0.11 |
| 128 | + + [1.3489025545120239, 8.2987e-9] |
| 129 | + ) |
| 130 | + expected = _get_absorbance_map(raw_data) |
| 131 | + converted = ModuleView.convert_absorbance_reader_data_points(raw_data) |
| 132 | + assert len(converted) == 96 |
| 133 | + assert converted == expected |
| 134 | + assert converted["A1"] == 0.0 |
| 135 | + assert converted["A2"] == 1.348 |
| 136 | + assert converted["E1"] == 0.11 |
| 137 | + assert converted["H11"] == -0.001 |
| 138 | + assert converted["H12"] == 0.248 # the data is flipped, so arr[0] == H12 |
| 139 | + |
| 140 | + # Test invalid data len 1 |
| 141 | + with pytest.raises(ValueError): |
| 142 | + ModuleView.convert_absorbance_reader_data_points([0]) |
| 143 | + |
| 144 | + # Test invalid data len 107 |
| 145 | + with pytest.raises(ValueError): |
| 146 | + ModuleView.convert_absorbance_reader_data_points([1] * 107) |
| 147 | + |
| 148 | + |
91 | 149 | async def test_read_raises_cannot_preform_action(
|
92 | 150 | decoy: Decoy,
|
93 | 151 | state_view: StateView,
|
|
0 commit comments