Skip to content

Commit 76f6e7f

Browse files
authored
Merge pull request #1742 from patricklatimer/replace-slims-with-waterlog-adapter
Replace SLIMS calls with subprocess call to waterlog app
2 parents a063c60 + 0e04b51 commit 76f6e7f

2 files changed

Lines changed: 38 additions & 117 deletions

File tree

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ dependencies = [
2626
"pyOSC3@git+https://github.com/glopesdev/pyosc3.git@master",
2727
"newscale@git+https://github.com/AllenNeuralDynamics/python-newscale@axes-on-target",
2828
"aind-auto-train@git+https://github.com/AllenNeuralDynamics/aind-foraging-behavior-bonsai-automatic-training.git@main",
29-
"aind-slims-api@git+https://github.com/AllenNeuralDynamics/aind-slims-api@main",
3029
"aind-dynamic-foraging-models >= 0.12.2",
3130
"aind-dynamic-foraging-basic-analysis >= 0.3.34",
3231
"aind-behavior-services >=0.8, <0.9",

src/foraging_gui/Foraging.py

Lines changed: 38 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
from aind_auto_train.schema.task import TrainingStage
3434
from aind_behavior_services.session import AindBehaviorSessionModel
3535
from aind_data_schema.core.session import Session
36-
from aind_slims_api import SlimsClient, models
3736
from matplotlib.backends.backend_qt5agg import (
3837
NavigationToolbar2QT as NavigationToolbar,
3938
)
@@ -240,9 +239,6 @@ def __init__(self, parent=None, box_number=1, start_bonsai_ide=True):
240239
# Connect to Bonsai
241240
self._InitializeBonsai()
242241

243-
# connect to Slims
244-
self._ConnectSlims()
245-
246242
# Set up threads
247243
self.threadpool = QThreadPool() # get animal response
248244
self.threadpool2 = QThreadPool() # get animal lick
@@ -1998,6 +1994,7 @@ def _GetSettings(self):
19981994
"clear_figure_after_save": True,
19991995
"add_default_project_name": True,
20001996
"check_schedule": False,
1997+
"waterlog_exe_path": "C://Program Files/AIBS_MPE/waterlog/waterlog.exe",
20011998
}
20021999

20032000
# Try to load the ForagingSettings.json file
@@ -2129,71 +2126,8 @@ def _GetSettings(self):
21292126
]
21302127
self.rig_name = "{}".format(self.current_box)
21312128

2132-
def _ConnectSlims(self):
2133-
"""
2134-
Connect to Slims
2135-
"""
2136-
try:
2137-
logging.info("Attempting to connect to Slims")
2138-
self.slims_client = SlimsClient(
2139-
username=os.environ["SLIMS_USERNAME"],
2140-
password=os.environ["SLIMS_PASSWORD"],
2141-
)
2142-
except KeyError as e:
2143-
raise KeyError(
2144-
"SLIMS_USERNAME and SLIMS_PASSWORD do not exist as "
2145-
f"environment variables on machine. Please add. {e}"
2146-
)
2147-
2148-
try:
2149-
self.slims_client.fetch_model(
2150-
models.SlimsMouseContent, barcode="00000000"
2151-
)
2152-
except Exception as e:
2153-
if "Status 401 – Unauthorized" in str(
2154-
e
2155-
): # catch error if username and password are incorrect
2156-
raise Exception(
2157-
f"Exception trying to read from Slims: {e}.\n"
2158-
f" Please check credentials:\n"
2159-
f"Username: {os.environ['SLIMS_USERNAME']}\n"
2160-
f"Password: {os.environ['SLIMS_PASSWORD']}"
2161-
)
2162-
elif "No record found" not in str(
2163-
e
2164-
): # bypass if mouse doesn't exist
2165-
raise Exception(f"Exception trying to read from Slims: {e}.\n")
2166-
logging.info("Successfully connected to Slims")
2167-
2168-
def _AddWaterLogResult(self, session: Session):
2169-
"""
2170-
Add WaterLogResult to slims based on current state of gui
2171-
2172-
:param session: Session object to pull water information from
2173-
2174-
"""
2175-
2176-
try: # try and find mouse
2177-
logging.info(
2178-
f"Attempting to fetch mouse {session.subject_id} from Slims"
2179-
)
2180-
mouse = self.slims_client.fetch_model(
2181-
models.SlimsMouseContent, barcode=session.subject_id
2182-
)
2183-
except Exception as e:
2184-
if "No record found" in str(
2185-
e
2186-
): # if no mouse found or validation errors on mouse
2187-
logging.warning(
2188-
f'"No record found" error while trying to fetch mouse {session.subject_id}. '
2189-
f"Will not log water."
2190-
)
2191-
return
2192-
else:
2193-
logging.error(
2194-
f"While fetching mouse {session.subject_id} model, unexpected error occurred: {e}"
2195-
)
2196-
raise e
2129+
def _AddWaterlogResult(self, session: Session):
2130+
"""Send weight/water information to databases via waterlog app cli"""
21972131

21982132
# extract water information
21992133
logging.info("Extracting water information from first stimulus epoch")
@@ -2203,53 +2137,41 @@ def _AddWaterLogResult(self, session: Session):
22032137
for k, v in water_json
22042138
}
22052139

2206-
# extract software information
2140+
# extract software information to send to waterlog once it can accept it
22072141
logging.info("Extracting software information from first data stream")
22082142
software = session.stimulus_epochs[0].software[0]
2143+
# Access sw name/version with (software.url, software.version)
2144+
2145+
waterlog_args = [
2146+
self.Settings['waterlog_exe_path'],
2147+
'--username',
2148+
self.behavior_session_model.experimenter[0],
2149+
'--mouse-id',
2150+
session.subject_id,
2151+
'--mouse-weight',
2152+
session.animal_weight_post,
2153+
'--comment',
2154+
session.notes,
2155+
'--earned-water',
2156+
water["water_in_session_total"],
2157+
'--water-supplement-ml',
2158+
water["water_after_session"],
2159+
'--water-supplement-delivered',
2160+
]
22092161

2210-
# create model
2211-
logging.info(
2212-
"Creating SlimsWaterlogResult based on session information."
2213-
)
2214-
print(water)
2215-
model = models.SlimsWaterlogResult(
2216-
mouse_pk=mouse.pk,
2217-
date=datetime.now(),
2218-
weight_g=session.animal_weight_post,
2219-
operator=self.behavior_session_model.experimenter[0],
2220-
water_earned_ml=water["water_in_session_total"],
2221-
water_supplement_delivered_ml=water["water_after_session"],
2222-
water_supplement_recommended_ml=None,
2223-
total_water_ml=water["water_in_session_total"]+water["water_after_session"],
2224-
comments=session.notes,
2225-
workstation=session.rig_id,
2226-
sw_source=software.url,
2227-
sw_version=software.version,
2228-
test_pk=self.slims_client.fetch_pk(
2229-
"Test", test_name="test_waterlog"
2230-
),
2231-
)
2162+
logging.info("Sending water info to waterlog")
2163+
process = subprocess.run([str(arg) for arg in waterlog_args])
22322164

2233-
# check if mouse already has waterlog for at session time and if, so update model
2234-
logging.info(
2235-
f"Fetching previous waterlog for mouse {session.subject_id}"
2236-
)
2237-
waterlog = self.slims_client.fetch_models(
2238-
models.SlimsWaterlogResult, mouse_pk=mouse.pk, start=0, end=1
2239-
)
2240-
if waterlog != [] and waterlog[0].date.strftime(
2241-
"%Y-%m-%d %H:%M:%S"
2242-
) == session.session_start_time.astimezone(timezone.utc).strftime(
2243-
"%Y-%m-%d %H:%M:%S"
2244-
):
2245-
logging.info(
2246-
"Waterlog information already exists for this session. Updating waterlog in Slims."
2247-
)
2248-
model.pk = waterlog[0].pk
2249-
self.slims_client.update_model(model=model)
2250-
else:
2251-
logging.info("Adding waterlog to Slims.")
2252-
self.slims_client.add_model(model)
2165+
QMessageBox.information(self, "Waterlog", "Go to waterlog app to submit water information.")
2166+
2167+
try:
2168+
process.check_returncode()
2169+
except Exception:
2170+
logging.warning(
2171+
f"Waterlog data for mouse {self.behavior_session_model.subject} cannot be sent to waterlog exe"
2172+
f", message: {process.stdout}, {process.stderr}",
2173+
exc_info=True,
2174+
)
22532175

22542176
def _InitializeBonsai(self):
22552177
"""
@@ -4203,7 +4125,7 @@ def _Save(self, ForceSave=0, SaveAs=0, SaveContinue=0, BackupSave=0):
42034125
# save random reward parameters
42044126
Obj['random_reward_par']=self.RandomReward_dialog.random_reward_par
42054127

4206-
# generate the metadata file and update slims
4128+
# generate the metadata file and update waterlog
42074129
try:
42084130
# save the metadata collected in the metadata dialogue
42094131
self.Metadata_dialog._save_metadata_dialog_parameters()
@@ -4250,12 +4172,12 @@ def _Save(self, ForceSave=0, SaveAs=0, SaveContinue=0, BackupSave=0):
42504172
]
42514173
and session is not None
42524174
):
4253-
self._AddWaterLogResult(session)
4175+
self._AddWaterlogResult(session)
42544176
elif self.BaseWeight.text() == "" or self.WeightAfter.text() == "":
4255-
logging.warning(f"Waterlog for mouse {self.behavior_session_model.subject} cannot be added to slims"
4177+
logging.warning(f"Waterlog for mouse {self.behavior_session_model.subject} cannot be added to database"
42564178
f" due do unrecorded weight information.")
42574179
elif session is None:
4258-
logging.warning(f"Waterlog for mouse {self.behavior_session_model.subject} cannot be added to slims"
4180+
logging.warning(f"Waterlog for mouse {self.behavior_session_model.subject} cannot be added to database"
42594181
f" due do metadata generation failure.")
42604182

42614183
# add complete log to lifecycle

0 commit comments

Comments
 (0)