Skip to content

Commit c73a3cf

Browse files
wip
1 parent 1f84868 commit c73a3cf

File tree

13 files changed

+93
-23
lines changed

13 files changed

+93
-23
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
### Upcoming
2+
3+
- new upload calibration dialog
4+
5+
#### Bug fixes
6+
- stirring calibration was using too many points from the lower bound, this is fixed.
7+
- fix for stirring calibration in the self-test creating an empty file
8+
- Fix custom charts that were not fetching from the database correctly due to the backend table being a sqlite3 view (VIEWs don't have ROWID, which was breaking a filter).
9+
110
### 25.4.11
211

312
#### Bug fixes

config.dev.ini

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,3 @@ ekf_variance_shift_post_dosing_minutes=0.40
169169
ekf_variance_shift_post_dosing_factor=2500
170170
ekf_outlier_std_threshold=3.0
171171
samples_for_od_statistics=35
172-
173-
[pioreactor]
174-
model=pioreactor_20ml
175-
version=1.0

pioreactor/actions/self_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ def test_REF_is_in_correct_position(managed_state, logger: CustomLogger, unit: s
101101
if i == 25:
102102
break
103103

104+
logger.debug(f"{signal1=}, {signal2=}")
105+
104106
norm_variance_per_channel = {
105107
"1": variance(signal1) / trimmed_mean(signal1) ** 2,
106108
"2": variance(signal2) / trimmed_mean(signal2) ** 2,
@@ -375,7 +377,9 @@ def test_run_stirring_calibration(managed_state, logger: CustomLogger, unit: str
375377
from pioreactor.calibrations.stirring_calibration import run_stirring_calibration
376378

377379
cal = run_stirring_calibration()
380+
cal.save_to_disk_for_device("stirring")
378381
cal.set_as_active_calibration_for_device("stirring")
382+
return
379383

380384

381385
def test_positive_correlation_between_temperature_and_heating(

pioreactor/background_jobs/leader/mqtt_to_db_streaming.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def callback(message: pt.MQTTMessage) -> None:
120120
except Exception as e:
121121
self.logger.warning(f"Encountered error in saving to DB: {e}. See logs.")
122122
self.logger.debug(
123-
f"Error in {parser.__name__}. Payload that caused error: `{message.payload.decode()}`",
123+
f"Error in {parser.__name__}. Payload that caused error: `{message.payload.decode()}`. Topic: `{message.topic}`",
124124
exc_info=True,
125125
)
126126
return
@@ -178,7 +178,7 @@ def parse_od(topic: str, payload: pt.MQTTMessagePayload) -> dict:
178178

179179
def parse_raw_od(topic: str, payload: pt.MQTTMessagePayload) -> dict:
180180
metadata = produce_metadata(topic)
181-
od_reading = msgspec_loads(payload, type=structs.ODReading)
181+
od_reading = msgspec_loads(payload, type=structs.RawODReading)
182182
return {
183183
"experiment": metadata.experiment,
184184
"pioreactor_unit": metadata.pioreactor_unit,

pioreactor/calibrations/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def __init_subclass__(cls, **kwargs):
4444
else:
4545
raise ValueError("target_device must be a string or a list of strings")
4646

47-
def run(self, *args, **kwargs):
47+
def run(self, *args, **kwargs) -> structs.CalibrationBase:
4848
raise NotImplementedError("Subclasses must implement this method.")
4949

5050

@@ -128,6 +128,8 @@ def load_calibration(device: Device, calibration_name: str) -> structs.AnyCalibr
128128
raise FileNotFoundError(
129129
f"Calibration {calibration_name} was not found in {CALIBRATION_PATH / device}"
130130
)
131+
elif target_file.stat().st_size == 0:
132+
raise FileNotFoundError(f"Calibration {calibration_name} is empty")
131133

132134
try:
133135
data = yaml_decode(target_file.read_bytes(), type=structs.subclass_union(structs.CalibrationBase))

pioreactor/calibrations/stirring_calibration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def run_stirring_calibration(
3131
if max_dc is None and min_dc is None:
3232
# seed with initial_duty_cycle
3333
config_initial_duty_cycle = config.getfloat("stirring.config", "initial_duty_cycle", fallback=30)
34-
min_dc, max_dc = config_initial_duty_cycle * 0.5, clamp(0, config_initial_duty_cycle * 1.5, 100)
34+
min_dc, max_dc = config_initial_duty_cycle * 0.66, clamp(0, config_initial_duty_cycle * 1.33, 100)
3535
elif (max_dc is not None) and (min_dc is not None):
3636
assert min_dc < max_dc, "min_dc >= max_dc"
3737
else:
@@ -52,7 +52,7 @@ def run_stirring_calibration(
5252
measured_rpms = []
5353

5454
# go up and down to observe any hysteresis.
55-
dcs = linspace(max_dc, min_dc, 5) + linspace(min_dc, min_dc, 5) + linspace(max_dc, min_dc, 5)
55+
dcs = linspace(max_dc, min_dc, 5) + linspace(min_dc, max_dc, 5) + linspace(max_dc, min_dc, 5)
5656
n_samples = len(dcs)
5757

5858
with temporary_config_change(config, "stirring.config", "enable_dodging_od", "False"):

pioreactor/calibrations/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ def curve_callable(x):
6767

6868

6969
def linspace(start: float, stop: float, num: int = 50) -> list[float]:
70+
assert start < stop
71+
assert num > 0
72+
7073
def linspace_(start: float, stop: float, num: int = 50):
7174
num = int(num)
7275
start = start * 1.0

pioreactor/structs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,8 @@ class ODCalibration(CalibrationBase, kw_only=True, tag="od"):
304304
ir_led_intensity: float
305305
angle: t.Literal["45", "90", "135", "180"]
306306
pd_channel: t.Literal["1", "2"]
307-
x: str = "OD600"
308307
y: str = "Voltage"
308+
x: str = "OD600"
309309

310310

311311
class SimplePeristalticPumpCalibration(CalibrationBase, kw_only=True, tag="simple_peristaltic_pump"):

update_scripts/25.4.11/post_update.sh

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,29 @@ if [ "$HOSTNAME" = "$LEADER_HOSTNAME" ]; then
1717
for config_file in "$CONFIG_DIR"/config_*.ini; do
1818
if [[ -f "$config_file" ]]; then
1919
pioreactor_unit=$(basename "$config_file" | sed 's/config_\(.*\)\.ini/\1/')
20+
21+
# Check if the [pioreactor] section exists
22+
if ! crudini --get "$config_file" pioreactor &> /dev/null; then
23+
echo "Skipping $config_file: Missing [pioreactor] section"
24+
continue
25+
fi
26+
27+
# Check if the 'model' and 'version' parameters are present
28+
if ! crudini --get "$config_file" pioreactor model &> /dev/null; then
29+
echo "Skipping $config_file: Missing 'model' parameter in [pioreactor] section"
30+
continue
31+
fi
32+
33+
if ! crudini --get "$config_file" pioreactor version &> /dev/null; then
34+
echo "Skipping $config_file: Missing 'version' parameter in [pioreactor] section"
35+
continue
36+
fi
37+
38+
# Retrieve parameters
2039
model_name=$(crudini --get "$config_file" pioreactor model 2>/dev/null)
2140
model_version=$(crudini --get "$config_file" pioreactor version 2>/dev/null)
2241

42+
# Double-check that both values are non-empty before updating
2343
if [[ -n "$model_name" && -n "$model_version" ]]; then
2444
sqlite3 "$DB_PATH" <<EOF
2545
UPDATE workers SET
@@ -30,10 +50,11 @@ EOF
3050
echo "Updated: $pioreactor_unit ($model_name, $model_version)"
3151
crudini --del "$config_file" pioreactor
3252
else
33-
echo "Skipping $config_file: Missing model or version"
53+
echo "Skipping $config_file: One or more parameter values are empty"
3454
fi
3555
fi
3656
done
57+
3758
sudo -u pioreactor pios sync-configs || :
3859

3960
# restart mqtt to db

update_scripts/25.4.11/update.sql

Whitespace-only changes.

0 commit comments

Comments
 (0)