From bfb382b9668cc4ddd4f682d2f0e38f674d31ad2c Mon Sep 17 00:00:00 2001 From: Micah Woodard Date: Tue, 24 Mar 2026 11:59:04 -0700 Subject: [PATCH 1/6] sets file format to mkv --- src/foraging_gui/Foraging.py | 18 +- src/foraging_gui/settings_model.py | 3 + src/workflows/foraging.bonsai | 216 +++++++- src/workflows/foraging.bonsai.layout | 746 +++++++++++++++++++++++++-- 4 files changed, 917 insertions(+), 66 deletions(-) diff --git a/src/foraging_gui/Foraging.py b/src/foraging_gui/Foraging.py index 520bfe341..583ff07ad 100644 --- a/src/foraging_gui/Foraging.py +++ b/src/foraging_gui/Foraging.py @@ -88,6 +88,8 @@ PlotV, ) from foraging_gui.warning_widget import WarningWidget +import csv + logger = logging.getLogger(__name__) logger.root.handlers.clear() # clear handlers so console output can be configured @@ -1824,17 +1826,11 @@ def _GetApprovedAINDProjectNames(self): ) return [] - def parse_setting_csv_file(self, csv_file) -> dict: - settings = {} - with open(csv_file, 'r', encoding='utf-8') as f: - for line in f: - line = line.strip() - if not line: - continue - if ',' in line: - key, value = line.split(',', 1) - settings[key.strip()] = value.strip() - return settings + def parse_setting_csv_file(self, csv_file: str) -> dict: + with open(csv_file, newline='') as csvfile: + reader = csv.reader(csvfile) + return {rows[0]:rows[1] for rows in reader} + def _GetSettings(self): """ Load the settings that are specific to this computer diff --git a/src/foraging_gui/settings_model.py b/src/foraging_gui/settings_model.py index c04e72e26..a2f2edfc0 100644 --- a/src/foraging_gui/settings_model.py +++ b/src/foraging_gui/settings_model.py @@ -135,6 +135,9 @@ class BonsaiSettingsModel(BaseModel): default=8, description="Gain for the body camera" ) + + video_file_format: Literal["mp4", "mkv"] = Field(default="mkv", description="File format to write video files to.") + ffmpeg_output_args: str = Field() # required field so no default ffmpeg_input_args: str = Field() # required field so no default diff --git a/src/workflows/foraging.bonsai b/src/workflows/foraging.bonsai index 77cac7884..81f1c9d9d 100644 --- a/src/workflows/foraging.bonsai +++ b/src/workflows/foraging.bonsai @@ -8404,10 +8404,47 @@ + + ComPorts + + + + video_file_format + + + + ComPorts + + + + video_file_format + + + + + + + Source1 + + + + + + + + + + + + + + + + BehaviorVideos SideCameraLeft - mp4 + mkv -vf "scale=out_color_matrix=bt709:out_range=full,format=bgr24,scale=out_range=full" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -metadata author="Allen Institute for Neural Dynamics" -maxrate 700M -bufsize 350M -colorspace bt709 -color_primaries bt709 -color_range full -color_trc linear Verbose @@ -8433,13 +8470,20 @@ - + - + - + - + + + + + + + + @@ -8588,10 +8632,47 @@ + + ComPorts + + + + video_file_format + + + + ComPorts + + + + video_file_format + + + + + + + Source1 + + + + + + + + + + + + + + + + BehaviorVideos BottomCamera - mp4 + mkv -vf "scale=out_color_matrix=bt709:out_range=full,format=bgr24,scale=out_range=full" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -metadata author="Allen Institute for Neural Dynamics" -maxrate 700M -bufsize 350M -colorspace bt709 -color_primaries bt709 -color_range full -color_trc linear Verbose @@ -8617,13 +8698,20 @@ - + - + - + - + + + + + + + + @@ -8775,10 +8863,47 @@ + + ComPorts + + + + video_file_format + + + + ComPorts + + + + video_file_format + + + + + + + Source1 + + + + + + + + + + + + + + + + BehaviorVideos SideCameraRight - mp4 + mkv -vf "scale=out_color_matrix=bt709:out_range=full,format=bgr24,scale=out_range=full" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -metadata author="Allen Institute for Neural Dynamics" -maxrate 700M -bufsize 350M -colorspace bt709 -color_primaries bt709 -color_range full -color_trc linear Verbose @@ -8804,13 +8929,20 @@ - + - + - + - + + + + + + + + @@ -8962,10 +9094,47 @@ + + ComPorts + + + + video_file_format + + + + ComPorts + + + + video_file_format + + + + + + + Source1 + + + + + + + + + + + + + + + + BehaviorVideos BodyCamera - mp4 + mkv -vf "scale=out_color_matrix=bt709:out_range=full,format=bgr24,scale=out_range=full" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -metadata author="Allen Institute for Neural Dynamics" -maxrate 700M -bufsize 350M -colorspace bt709 -color_primaries bt709 -color_range full -color_trc linear Verbose @@ -8991,13 +9160,20 @@ - + - + - + - + + + + + + + + diff --git a/src/workflows/foraging.bonsai.layout b/src/workflows/foraging.bonsai.layout index 0bf0a6445..d49c31f10 100644 --- a/src/workflows/foraging.bonsai.layout +++ b/src/workflows/foraging.bonsai.layout @@ -52,12 +52,12 @@ true - 3 - 3 + 4 + 4 - 550 - 491 + 298 + 691 Normal @@ -76,12 +76,12 @@ true - 3 - 3 + 4 + 4 - 550 - 491 + 298 + 691 Normal @@ -2588,12 +2588,12 @@ true - 3 - 3 + 4 + 4 - 550 - 491 + 1979 + 1284 Normal @@ -3452,6 +3452,224 @@ Normal + + false + + 0 + 0 + + + 0 + 0 + + Normal + + true + + 4 + 4 + + + 1979 + 1284 + + Normal + + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + false @@ -3540,12 +3758,12 @@ true - 327 - 199 + -2407 + 340 - 316 - 239 + 948 + 730 Normal @@ -4140,12 +4358,12 @@ true - 3 - 3 + 4 + 4 290 - 165 + 166 Normal @@ -4164,12 +4382,12 @@ true - 3 - 3 + 4 + 4 - 290 - 165 + 924 + 658 Normal @@ -4462,7 +4680,7 @@ Normal - + false 0 @@ -4473,6 +4691,18 @@ 0 Normal + + false + + -1664 + 353 + + + 861 + 964 + + Normal + false @@ -4534,7 +4764,7 @@ Normal - + false 0 @@ -4545,6 +4775,18 @@ 0 Normal + + false + + -2808 + 78 + + + 1184 + 1013 + + Normal + false @@ -4618,7 +4860,7 @@ Normal - + false 0 @@ -4629,6 +4871,428 @@ 0 Normal + + true + + -2760 + 130 + + + 1145 + 990 + + Normal + + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + + false + + 0 + 0 + + + 0 + 0 + + Normal + + false @@ -4702,7 +5366,7 @@ Normal - + false 0 @@ -4713,6 +5377,18 @@ 0 Normal + + false + + -2784 + 104 + + + 979 + 1002 + + Normal + false @@ -5241,12 +5917,12 @@ true - 3 - 3 + 4 + 4 - 550 - 491 + 298 + 691 Normal @@ -5495,12 +6171,12 @@ true - 3 - 3 + 4 + 4 - 550 - 491 + 298 + 691 Normal From f35a5d9c5ff87635a61eb7915824c3989edc65e4 Mon Sep 17 00:00:00 2001 From: Micah Woodard Date: Tue, 24 Mar 2026 14:10:40 -0700 Subject: [PATCH 2/6] adds user_email to manifest --- src/foraging_gui/Foraging.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/foraging_gui/Foraging.py b/src/foraging_gui/Foraging.py index 520bfe341..d7801d618 100644 --- a/src/foraging_gui/Foraging.py +++ b/src/foraging_gui/Foraging.py @@ -7275,6 +7275,10 @@ def _generate_upload_manifest(self): self.VideoFolder.replace("\\", "/") ] + # Determine sci email + sci = self._GetInfoFromSchedule(self.behavior_session_model.subject, "PI") + sci_email = None if not sci else get_user_email(sci) + # Define contents of manifest file contents = { "acquisition_datetime": self.behavior_session_model.date, @@ -7299,6 +7303,7 @@ def _generate_upload_manifest(self): "schedule_time": schedule_time, "project_name": self.Metadata_dialog.ProjectName.currentText(), "script": {}, + "user_email": sci_email } # Define filename of manifest @@ -7324,6 +7329,20 @@ def _generate_upload_manifest(self): + "Please alert the mouse owner, and report on github.", ) +def get_user_email(username: str) -> str: + domain = ms_active_directory.ADDomain("corp.alleninstitute.org") + session = domain.create_session_as_user( + "svc_mpe", + authentication_mechanism=ldap3.ASL, + sasl_mechanism=ldap3.GSSAPI, + ) + + ad_user = session.find_user_by_name(username, attributes_to_lookup=["mail"]) + if ad_user is None: + raise ValueError(f"User '{username}' not found in Active Directory.") + return ad_user.all_attributes["mail"] + + def validate_aind_username( username: str, domain: str = "corp.alleninstitute.org", From 057c42347c9e1fd12d22c87a5b4d25ae7d09b341 Mon Sep 17 00:00:00 2001 From: Micah Woodard Date: Tue, 24 Mar 2026 14:18:09 -0700 Subject: [PATCH 3/6] indents reader --- src/foraging_gui/Foraging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/foraging_gui/Foraging.py b/src/foraging_gui/Foraging.py index 583ff07ad..c344b5752 100644 --- a/src/foraging_gui/Foraging.py +++ b/src/foraging_gui/Foraging.py @@ -1829,7 +1829,7 @@ def _GetApprovedAINDProjectNames(self): def parse_setting_csv_file(self, csv_file: str) -> dict: with open(csv_file, newline='') as csvfile: reader = csv.reader(csvfile) - return {rows[0]:rows[1] for rows in reader} + return {rows[0]:rows[1] for rows in reader} def _GetSettings(self): """ From 69c47fdfa7e627b7af1e247096f2ebaf3facc4e5 Mon Sep 17 00:00:00 2001 From: Micah Woodard Date: Tue, 24 Mar 2026 15:08:33 -0700 Subject: [PATCH 4/6] creats user domain --- src/foraging_gui/Foraging.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/foraging_gui/Foraging.py b/src/foraging_gui/Foraging.py index d7801d618..def7baa37 100644 --- a/src/foraging_gui/Foraging.py +++ b/src/foraging_gui/Foraging.py @@ -7331,9 +7331,10 @@ def _generate_upload_manifest(self): def get_user_email(username: str) -> str: domain = ms_active_directory.ADDomain("corp.alleninstitute.org") + domain_username = getpass.getuser() session = domain.create_session_as_user( - "svc_mpe", - authentication_mechanism=ldap3.ASL, + domain_username, + authentication_mechanism=ldap3.SASL, sasl_mechanism=ldap3.GSSAPI, ) From 36916d9ab97ba447cb53a7ff7cf23a2ff268d6b3 Mon Sep 17 00:00:00 2001 From: rachelstephlee Date: Tue, 24 Mar 2026 16:34:00 -0700 Subject: [PATCH 5/6] Fix heading formatting in README.md just an empty change so i can create a PR --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c4f464fa..e0cd043e9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Dynamic Foraging Task +# Dynamic Foraging Task A [Bonsai](https://bonsai-rx.org/) workflow for lick-based foraging experiments, with a [PyQt](https://wiki.python.org/moin/PyQt) frontend for visualizing performance and modifying task parameters. From 8677103c5945f0b489ff803577d252db3c11c967 Mon Sep 17 00:00:00 2001 From: Micah Woodard Date: Tue, 31 Mar 2026 15:43:21 -0700 Subject: [PATCH 6/6] defaults to behavior account --- src/foraging_gui/Foraging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/foraging_gui/Foraging.py b/src/foraging_gui/Foraging.py index def7baa37..7eb389393 100644 --- a/src/foraging_gui/Foraging.py +++ b/src/foraging_gui/Foraging.py @@ -7277,7 +7277,7 @@ def _generate_upload_manifest(self): # Determine sci email sci = self._GetInfoFromSchedule(self.behavior_session_model.subject, "PI") - sci_email = None if not sci else get_user_email(sci) + sci_email = "svc_aind_behavior@alleninstitute.org" if not sci else get_user_email(sci) # Define contents of manifest file contents = {