I am trying to implement a schedule that lets me control when and how much alternative media is added to my pioreactor, but I seem to be having an issue with defining the variable and passing it through DosingController to my custom class (at least I think that is what is going wrong).
I run the code by instantiating dc = DosingController( …, duration = 20, array=[[5, 10, 20, 40, 60, 80], [0.5, 0, 1.0, 0, 1.5, 0]], … ), where array is a list in the format:
array[0][:] # when the change is supposed to take place
array[1][:] # the new dosage at that point in the schedule. Currently these are test/debug values.
I am getting an error saying ERROR [app] [dosing_automation] name 'alt_dosing_schedule' is not defined
and I am not sure how to resolve this. Can I resolve this issue by modifying chemostat_alt_media_2.py, or will I have to make this fix somewhere in pioreactor/automations/dosing/base.py DosingAutomationJobContrib
?
chemostat_alt_media_2.py
# -*- coding: utf-8 -*-
from __future__ import annotations
from pioreactor.automations import events
from pioreactor.automations.dosing.base import DosingAutomationJobContrib
from pioreactor.exc import CalibrationError
from pioreactor.utils import local_persistant_storage
class ChemostatAltMedia(DosingAutomationJobContrib):
"""
Chemostat mode - try to keep [nutrient] constant.
"""
automation_name = "scheduled_chemostat_alt_media"
published_settings = {
"volume": {"datatype": "float", "settable": True, "unit": "mL"},
"fraction_alt_media": {"datatype": "float", "settable": True, "unit": "%"},
"duration": {"datatype": "float", "settable": True, "unit": "min"},
"array": {"datatype": "array", "settable": True, "unit": "N/A, mL"},
}
def __init__(self, media_ml: float, fraction_alt_media: float, array, **kwargs):
super(ChemostatAltMedia, self).__init__(**kwargs)
self.volume = float(media_ml)
self.counter = 0
self.index = 0
self.alt_media_ml = 0
self.media_ml = float(media_ml)
alt_dosing_schedule = array
def check_for_update(self):
if self.counter >= alt_dosing_schedule[0][self.index]: # This checks if counter has reached the next scheduled update
# This code should loop the index counter back to zero when it reaches the end of the array
if self.index >= len(alt_dosing_schedule[0]) - 1:
self.index = 0 # reset the index counter to zero
self.counter = 0 # reset the counter back to zero
else:
self.index += 1
# If it is time to update the amount of alternate media, then this updates it
self.alt_media_ml = alt_dosing_schedule[1][self.index]
def execute(self) -> events.DilutionEvent:
self.check_for_update()
self.volume = self.media_ml + self.alt_media_ml
volume_actually_cycled = self.execute_io_action(alt_media_ml=self.alt_media_ml, media_ml=media_ml, waste_ml=self.volume)
self.counter += 1
return events.DilutionEvent(
f"exchanged {volume_actually_cycled[0]}mL",
data={"volume_actually_cycled": volume_actually_cycled[0]},
)
if __name__ == "__main__":
from pioreactor.background_jobs.dosing_control import DosingController
dc = DosingController(
"scheduled_chemostat_alt_media",
duration=20,
fraction_alt_media=0,
media_ml = 1.0,
volume=1.0,
array=[[5, 10, 20, 40, 60, 80], [0.5, 0, 1.0, 0, 1.5, 0]],
unit="test_unit",
experiment="test_experiment"
)
dc.block_until_disconnected()
Log File of Error
pioreactor@pioreactor1:~ $ python chemostat_alt_media_2.py
2023-01-04T22:35:53+0000 DEBUG [app] [dosing_control] Init.
2023-01-04T22:35:53+0000 INFO [app] [dosing_control] Starting scheduled_chemostat_alt_media(duration=20, fraction_alt_media=0, media_ml=1.0, volume=1.0, array=[[5, 10, 20, 40, 60, 80], [0.5, 0, 1.0, 0, 1.5, 0]]).
2023-01-04T22:35:54+0000 DEBUG [app] [dosing_automation] Init.
2023-01-04T22:35:55+0000 DEBUG [app] [dosing_automation] Ready.
2023-01-04T22:35:55+0000 INFO [app] [dosing_control] Ready.
2023-01-04T22:35:55+0000 DEBUG [app] [dosing_control] dosing_control is blocking until disconnected.
2023-01-04T22:35:57+0000 DEBUG [app] [dosing_automation] name ‘alt_dosing_schedule’ is not defined
Traceback (most recent call last):
File “/usr/local/lib/python3.9/dist-packages/pioreactor/automations/dosing/base.py”, line 255, in run
event = self.execute()
File “/home/pioreactor/chemostat_alt_media_2.py”, line 56, in execute
self.check_for_update()
File “/home/pioreactor/chemostat_alt_media_2.py”, line 42, in check_for_update
if self.counter >= alt_dosing_schedule[0][self.index]: # This checks if counter has reached the next scheduled update
NameError: name ‘alt_dosing_schedule’ is not defined
2023-01-04T22:35:57+0000 ERROR [app] [dosing_automation] name ‘alt_dosing_schedule’ is not defined
2023-01-04T22:35:57+0000 INFO [app] [dosing_automation] ErrorOccurred: name ‘alt_dosing_schedule’ is not defined