From 9ac6fd10997ea12d5da0f9ded571cf62d3885c87 Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Sun, 27 Jul 2025 16:11:24 -0700 Subject: [PATCH 1/9] PEP-8 the imports of 3 gui_* modules Also, from __future__ import annotations --- LabGym/gui_analyzer.py | 36 ++++++++++++++++++++++++------------ LabGym/gui_categorizer.py | 37 +++++++++++++++++++++++++------------ LabGym/gui_detector.py | 39 +++++++++++++++++++++++++++------------ 3 files changed, 76 insertions(+), 36 deletions(-) diff --git a/LabGym/gui_analyzer.py b/LabGym/gui_analyzer.py index d7e67fe2..000b8493 100644 --- a/LabGym/gui_analyzer.py +++ b/LabGym/gui_analyzer.py @@ -16,26 +16,38 @@ Email: bingye@umich.edu ''' -# Log the load of this module (by the module loader, on first import). -# Intentionally positioning these statements before other imports, against the -# guidance of PEP-8, to log the load before other imports log messages. -import logging -logger = logging.getLogger(__name__) -logger.debug('loading %s', __file__) - +# Allow use of newer syntax Python 3.10 type hints in Python 3.9. +from __future__ import annotations +# Standard library imports. +import json +import logging +import os +from pathlib import Path -import wx -import os +# Log the load of this module (by the module loader, on first import). +# +# These statements are intentionally positioned before this module's +# other imports (against the guidance of PEP 8), to log the load of this +# module before other import statements are executed and potentially +# produce their own log messages. +# pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('%s', f'loading {__file__}') +# pylint: enable=wrong-import-position + + +# Related third party imports. import matplotlib as mpl -from pathlib import Path import pandas as pd import torch -import json +import wx + +# Local application/library specific imports. from .analyzebehavior import AnalyzeAnimal from .analyzebehavior_dt import AnalyzeAnimalDetector -from .tools import plot_events,parse_all_events_file,calculate_distances +from .tools import plot_events, parse_all_events_file, calculate_distances from .minedata import data_mining diff --git a/LabGym/gui_categorizer.py b/LabGym/gui_categorizer.py index f6dabcd4..d43757f2 100644 --- a/LabGym/gui_categorizer.py +++ b/LabGym/gui_categorizer.py @@ -16,32 +16,45 @@ Email: bingye@umich.edu ''' -# Log the load of this module (by the module loader, on first import). -# Intentionally positioning these statements before other imports, against the -# guidance of PEP-8, to log the load before other imports log messages. +# Allow use of newer syntax Python 3.10 type hints in Python 3.9. +from __future__ import annotations + +# Standard library imports. +import json import logging -logger = logging.getLogger(__name__) -logger.debug('loading %s', __file__) +import os +from pathlib import Path +import shutil +# Log the load of this module (by the module loader, on first import). +# +# These statements are intentionally positioned before this module's +# other imports (against the guidance of PEP 8), to log the load of this +# module before other import statements are executed and potentially +# produce their own log messages. +# +# Log the load of this module (by the module loader, on first import). +# Intentionally positioning these statements before other imports, against the +# guidance of PEP-8, to log the load before other imports log messages. +# pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('%s', f'loading {__file__}') +# pylint: enable=wrong-import-position -import wx -import os -import shutil -from pathlib import Path -import json +# Related third party imports. import cv2 import numpy as np +import wx +# Local application/library specific imports. logger.debug('importing %s ...', '.analyzebehavior') from .analyzebehavior import AnalyzeAnimal logger.debug('importing %s done', '.analyzebehavior') - logger.debug('importing %s ...', '.analyzebehavior_dt') from .analyzebehavior_dt import AnalyzeAnimalDetector logger.debug('importing %s done', '.analyzebehavior_dt') - from .categorizer import Categorizers from .tools import sort_examples_from_csv diff --git a/LabGym/gui_detector.py b/LabGym/gui_detector.py index 5d0a32bc..736890b3 100644 --- a/LabGym/gui_detector.py +++ b/LabGym/gui_detector.py @@ -16,26 +16,41 @@ Email: bingye@umich.edu ''' +# Allow use of newer syntax Python 3.10 type hints in Python 3.9. +from __future__ import annotations + +# Standard library imports. +import json +import logging +import os +from pathlib import Path +import shutil + + +# Log the load of this module (by the module loader, on first import). +# +# These statements are intentionally positioned before this module's +# other imports (against the guidance of PEP 8), to log the load of this +# module before other import statements are executed and potentially +# produce their own log messages. +# # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -import logging -logger = logging.getLogger(__name__) -logger.debug('loading %s', __file__) - +# pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('%s', f'loading {__file__}') +# pylint: enable=wrong-import-position -from .tools import extract_frames -from .detector import Detector -from pathlib import Path -import wx -import os +# Related third party imports. import cv2 -import json -import shutil import torch +import wx - +# Local application/library specific imports. +from .tools import extract_frames +from .detector import Detector the_absolute_current_path=str(Path(__file__).resolve().parent) From a3bd0d14a0308f102ddcc8d77e331bef57f30e9d Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Sun, 27 Jul 2025 16:14:18 -0700 Subject: [PATCH 2/9] Get detectors dir and models dir from config. Implement configurable detectors dir and models dir, with default defined in config.py. --- LabGym/config.py | 3 +++ LabGym/gui_analyzer.py | 10 +++++++--- LabGym/gui_categorizer.py | 22 +++++++++++++++++----- LabGym/gui_detector.py | 13 +++++++++++-- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/LabGym/config.py b/LabGym/config.py index 591ec34b..cfb3c15c 100644 --- a/LabGym/config.py +++ b/LabGym/config.py @@ -67,6 +67,9 @@ }, 'anonymous': False, + + 'detectors': Path(__file__).parent.joinpath('detectors') + 'models': Path(__file__).parent.joinpath('models') } logger = logging.getLogger(__name__) diff --git a/LabGym/gui_analyzer.py b/LabGym/gui_analyzer.py index 000b8493..8a303c30 100644 --- a/LabGym/gui_analyzer.py +++ b/LabGym/gui_analyzer.py @@ -49,7 +49,7 @@ from .analyzebehavior_dt import AnalyzeAnimalDetector from .tools import plot_events, parse_all_events_file, calculate_distances from .minedata import data_mining - +from LabGym import config the_absolute_current_path=str(Path(__file__).resolve().parent) @@ -95,6 +95,10 @@ class WindowLv2_AnalyzeBehaviors(wx.Frame): def __init__(self,title): super(WindowLv2_AnalyzeBehaviors,self).__init__(parent=None,title=title,size=(1000,530)) + + # Get all of the values needed from config.get_config(). + self._config = config.get_config() + self.behavior_mode=0 # 0--non-interactive, 1--interactive basic, 2--interactive advanced, 3--static images self.use_detector=False # whether the Detector is used self.detector_path=None # the 'LabGym/detectors' folder, which stores all the trained Detectors @@ -257,7 +261,7 @@ def display_window(self): def select_categorizer(self,event): if self.model_path is None: - self.model_path=os.path.join(the_absolute_current_path,'models') + self.model_path = self._config['models'] categorizers=[i for i in os.listdir(self.model_path) if os.path.isdir(os.path.join(self.model_path,i))] if '__pycache__' in categorizers: @@ -567,7 +571,7 @@ def select_method(self,event): else: self.animal_number={} - self.detector_path=os.path.join(the_absolute_current_path,'detectors') + self.detector_path = self._config['detectors'] self.text_animalnumber.SetLabel('Default: 1.') detectors=[i for i in os.listdir(self.detector_path) if os.path.isdir(os.path.join(self.detector_path,i))] diff --git a/LabGym/gui_categorizer.py b/LabGym/gui_categorizer.py index d43757f2..1fd19531 100644 --- a/LabGym/gui_categorizer.py +++ b/LabGym/gui_categorizer.py @@ -57,7 +57,7 @@ logger.debug('importing %s done', '.analyzebehavior_dt') from .categorizer import Categorizers from .tools import sort_examples_from_csv - +from LabGym import config the_absolute_current_path=str(Path(__file__).resolve().parent) @@ -73,6 +73,10 @@ class WindowLv2_GenerateExamples(wx.Frame): def __init__(self,title): super(WindowLv2_GenerateExamples,self).__init__(parent=None,title=title,size=(1000,530)) + + # Get all of the values needed from config.get_config(). + self._config = config.get_config() + self.behavior_mode=0 # 0: non-interactive behavior; 1: interact basic; 2: interact advanced; 3: static images self.use_detector=False # whether the Detector is used self.detector_path=None # the 'LabGym/detectors' folder, which stores all the trained Detectors @@ -389,7 +393,7 @@ def select_method(self,event): self.use_detector=True self.animal_number={} - self.detector_path=os.path.join(the_absolute_current_path,'detectors') + self.detector_path = self._config['detectors'] detectors=[i for i in os.listdir(self.detector_path) if os.path.isdir(os.path.join(self.detector_path,i))] if '__pycache__' in detectors: @@ -1070,6 +1074,10 @@ class WindowLv2_TrainCategorizers(wx.Frame): def __init__(self,title): super(WindowLv2_TrainCategorizers,self).__init__(parent=None,title=title,size=(1000,540)) + + # Get all of the values needed from config.get_config(). + _config = config.get_config() + self.file_path=None # the folder that stores sorted, unprepared behavior examples (each category is a subfolder) self.new_path=None # the folder that stores prepared behavior examples (contains all examples with a category tag in their names) self.behavior_mode=0 # 0--non-interactive, 1--interactive basic, 2--interactive advanced, 3--static images @@ -1083,8 +1091,8 @@ def __init__(self,title): self.aug_methods=[] # the methods for augment training and validation examples self.augvalid=True # whether to perform augmentation for validation data as well self.data_path=None # the folder that stores prepared behavior examples - self.model_path=os.path.join(the_absolute_current_path,'models') # the 'LabGym/models' folder, which stores all the trained Categorizers - self.path_to_categorizer=os.path.join(the_absolute_current_path,'models','New_model') # path to the Categorizer + self.model_path = _config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers + self.path_to_categorizer = _config['models'].joinpath('New_model') # path to the Categorizer self.out_path=None # the folder for storing the training reports self.include_bodyparts=False # whether to include body parts in the pattern images self.std=0 # a value between 0 and 255, higher value, less body parts will be included in the pattern images @@ -1582,8 +1590,12 @@ class WindowLv2_TestCategorizers(wx.Frame): def __init__(self,title): super(WindowLv2_TestCategorizers,self).__init__(parent=None,title=title,size=(1000,260)) + + # Get all of the values needed from config.get_config(). + _config = config.get_config() + self.file_path=None # the folder that stores the ground-truth examples (each subfolder is a behavior category) - self.model_path=os.path.join(the_absolute_current_path,'models') # the 'LabGym/models' folder, which stores all the trained Categorizers + self.model_path = _config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers self.path_to_categorizer=None # path to the Categorizer self.out_path=None # for storing the testing reports diff --git a/LabGym/gui_detector.py b/LabGym/gui_detector.py index 736890b3..282a4233 100644 --- a/LabGym/gui_detector.py +++ b/LabGym/gui_detector.py @@ -51,6 +51,7 @@ # Local application/library specific imports. from .tools import extract_frames from .detector import Detector +from LabGym import config the_absolute_current_path=str(Path(__file__).resolve().parent) @@ -250,11 +251,15 @@ class WindowLv2_TrainDetectors(wx.Frame): def __init__(self,title): super(WindowLv2_TrainDetectors,self).__init__(parent=None,title=title,size=(1000,300)) + + # Get all of the values needed from config.get_config(). + _config = config.get_config() + self.path_to_trainingimages=None # the folder that stores all the training images self.path_to_annotation=None # the path to the .json file that stores the annotations in coco format self.inference_size=480 # the Detector inferencing frame size self.iteration_num=200 # the number of training iterations - self.detector_path=os.path.join(the_absolute_current_path,'detectors') # the 'LabGym/detectors' folder, which stores all the trained Detectors + self.detector_path = _config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors self.path_to_detector=None # path to the Detector self.display_window() @@ -403,9 +408,13 @@ class WindowLv2_TestDetectors(wx.Frame): def __init__(self,title): super(WindowLv2_TestDetectors,self).__init__(parent=None,title=title,size=(1000,300)) + + # Get all of the values needed from config.get_config(). + _config = config.get_config() + self.path_to_testingimages=None # the folder that stores all the testing images self.path_to_annotation=None # the path to the .json file that stores the annotations in coco format - self.detector_path=os.path.join(the_absolute_current_path,'detectors') # the 'LabGym/detectors' folder, which stores all the trained Detectors + self.detector_path = _config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors self.path_to_detector=None # path to the Detector self.output_path=None # the folder that stores the testing images with annotations From 39a33e727b3763bcaab6fbbb0be9fd23aa8c4675 Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Sun, 27 Jul 2025 16:30:25 -0700 Subject: [PATCH 3/9] Fix a syntax typo in config.py --- LabGym/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LabGym/config.py b/LabGym/config.py index cfb3c15c..2a462025 100644 --- a/LabGym/config.py +++ b/LabGym/config.py @@ -68,8 +68,8 @@ 'anonymous': False, - 'detectors': Path(__file__).parent.joinpath('detectors') - 'models': Path(__file__).parent.joinpath('models') + 'detectors': Path(__file__).parent.joinpath('detectors'), + 'models': Path(__file__).parent.joinpath('models'), } logger = logging.getLogger(__name__) From 53755baf48ce6b829ea50b3f8f7c168808869d30 Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Wed, 17 Sep 2025 10:20:35 -0600 Subject: [PATCH 4/9] change default detectors/models to str objects. --- LabGym/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LabGym/config.py b/LabGym/config.py index bf9ab1c6..beab7a84 100644 --- a/LabGym/config.py +++ b/LabGym/config.py @@ -67,8 +67,8 @@ 'anonymous': False, - 'detectors': Path(__file__).parent.joinpath('detectors'), - 'models': Path(__file__).parent.joinpath('models'), + 'detectors': str(Path(__file__).parent.joinpath('detectors')), + 'models': str(Path(__file__).parent.joinpath('models')), } logger = logging.getLogger(__name__) From 476a2e166d5c60bc0032cc42c211d966cbd6e4b6 Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Wed, 17 Sep 2025 10:35:21 -0600 Subject: [PATCH 5/9] Added shadow logger.debug statement to detectors & models statements. Also eliminate the_absolute_current_path module variable (no longer in use). --- LabGym/gui_analyzer.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/LabGym/gui_analyzer.py b/LabGym/gui_analyzer.py index 48ae6a25..9de8e854 100644 --- a/LabGym/gui_analyzer.py +++ b/LabGym/gui_analyzer.py @@ -43,9 +43,6 @@ from .tools import plot_events, parse_all_events_file, calculate_distances -the_absolute_current_path=str(Path(__file__).resolve().parent) - - class ColorPicker(wx.Dialog): ''' @@ -253,6 +250,7 @@ def select_categorizer(self,event): if self.model_path is None: self.model_path = self._config['models'] + logger.debug('%s: %r', 'self.model_path', self.model_path) categorizers=[i for i in os.listdir(self.model_path) if os.path.isdir(os.path.join(self.model_path,i))] if '__pycache__' in categorizers: @@ -563,6 +561,7 @@ def select_method(self,event): self.animal_number={} self.detector_path = self._config['detectors'] + logger.debug('%s: %r', 'self.detector_path', self.detector_path) self.text_animalnumber.SetLabel('Default: 1.') detectors=[i for i in os.listdir(self.detector_path) if os.path.isdir(os.path.join(self.detector_path,i))] From 0faf8e413d6a0c2ce95d4d8c6640867df957b53d Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Thu, 18 Sep 2025 07:56:18 -0600 Subject: [PATCH 6/9] Add args to config.get_config(). --- LabGym/config.py | 28 +++++++++++++++++++++++----- LabGym/gui_analyzer.py | 6 +++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/LabGym/config.py b/LabGym/config.py index beab7a84..7d0e5f85 100644 --- a/LabGym/config.py +++ b/LabGym/config.py @@ -8,13 +8,14 @@ Notes * Environment variables and command-line options can be used to - override the location of the configuration file, so determine the - configuration file location before reading it. + override the location of the configuration file, so its location is + determined (from defaults, environment variables, and command-line + options) before reading it. * Typical LabGym configdir organization is ~/.labgym/config.toml (optional) logging.yaml (optional) - registration.done (created at registration) + registration.yaml (created at registration) To use a different configfile only (without changing the references to other configdir files), @@ -132,8 +133,25 @@ def get_config_from_configfile(configfile: Path) -> dict: return result -def get_config(): - """Return a cached config dict. Construct it if necessary. +def get_config(*args) -> dict: + """Return a copy of the cached config dict (or a subset of its pairs). + + If args are passed, then return a new dict of only those keys and + their values from the cached config dict. + """ + + fullconfig = get_fullconfig() + + if len(args) == 0: + result = fullconfig + else: + result = {key: fullconfig[key] for key in args} + + return copy.deepcopy(result) + + +def get_fullconfig() -> dict: + """Return a copy of the cached config dict. Construct it if necessary. Strengths * Instead of reconstructing the config dict each time this diff --git a/LabGym/gui_analyzer.py b/LabGym/gui_analyzer.py index 9de8e854..8fb4b152 100644 --- a/LabGym/gui_analyzer.py +++ b/LabGym/gui_analyzer.py @@ -85,7 +85,7 @@ def __init__(self, parent): self.notebook = parent # Get all of the values needed from config.get_config(). - self._config = config.get_config() + self.config = config.get_config('detectors', 'models') self.behavior_mode=0 # 0--non-interactive, 1--interactive basic, 2--interactive advanced, 3--static images self.use_detector=False # whether the Detector is used @@ -249,7 +249,7 @@ def display_window(self): def select_categorizer(self,event): if self.model_path is None: - self.model_path = self._config['models'] + self.model_path = self.config['models'] logger.debug('%s: %r', 'self.model_path', self.model_path) categorizers=[i for i in os.listdir(self.model_path) if os.path.isdir(os.path.join(self.model_path,i))] @@ -560,7 +560,7 @@ def select_method(self,event): else: self.animal_number={} - self.detector_path = self._config['detectors'] + self.detector_path = self.config['detectors'] logger.debug('%s: %r', 'self.detector_path', self.detector_path) self.text_animalnumber.SetLabel('Default: 1.') From f30c02c857307787f995b09234c5dda0e6eb8478 Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Thu, 18 Sep 2025 08:34:49 -0600 Subject: [PATCH 7/9] Use config.get_config() with args --- LabGym/gui_categorizer.py | 17 +++++++---------- LabGym/gui_detector.py | 11 ++++------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/LabGym/gui_categorizer.py b/LabGym/gui_categorizer.py index fda42405..9ded6a03 100644 --- a/LabGym/gui_categorizer.py +++ b/LabGym/gui_categorizer.py @@ -48,9 +48,6 @@ from .gui_utils import add_or_select_notebook_page -the_absolute_current_path=str(Path(__file__).resolve().parent) - - class PanelLv2_GenerateExamples(wx.Panel): ''' @@ -63,7 +60,7 @@ def __init__(self, parent): self.notebook = parent # Get all of the values needed from config.get_config(). - self._config = config.get_config() + self.config = config.get_config('detectors', 'models') self.behavior_mode=0 # 0: non-interactive behavior; 1: interact basic; 2: interact advanced; 3: static images self.use_detector=False # whether the Detector is used @@ -381,7 +378,7 @@ def select_method(self,event): self.use_detector=True self.animal_number={} - self.detector_path = self._config['detectors'] + self.detector_path = self.config['detectors'] detectors=[i for i in os.listdir(self.detector_path) if os.path.isdir(os.path.join(self.detector_path,i))] if '__pycache__' in detectors: @@ -1070,7 +1067,7 @@ def __init__(self, parent): self.notebook = parent # Get all of the values needed from config.get_config(). - _config = config.get_config() + self.config = config.get_config('models') self.file_path=None # the folder that stores sorted, unprepared behavior examples (each category is a subfolder) self.new_path=None # the folder that stores prepared behavior examples (contains all examples with a category tag in their names) @@ -1085,8 +1082,8 @@ def __init__(self, parent): self.aug_methods=[] # the methods for augment training and validation examples self.augvalid=True # whether to perform augmentation for validation data as well self.data_path=None # the folder that stores prepared behavior examples - self.model_path = _config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers - self.path_to_categorizer = _config['models'].joinpath('New_model') # path to the Categorizer + self.model_path = self.config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers + self.path_to_categorizer = self.config['models'].joinpath('New_model') # path to the Categorizer self.out_path=None # the folder for storing the training reports self.include_bodyparts=False # whether to include body parts in the pattern images self.std=0 # a value between 0 and 255, higher value, less body parts will be included in the pattern images @@ -1587,10 +1584,10 @@ def __init__(self, parent): self.notebook = parent # Get all of the values needed from config.get_config(). - _config = config.get_config() + self.config = config.get_config('models') self.file_path=None # the folder that stores the ground-truth examples (each subfolder is a behavior category) - self.model_path = _config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers + self.model_path = self.config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers self.path_to_categorizer=None # path to the Categorizer self.out_path=None # for storing the testing reports diff --git a/LabGym/gui_detector.py b/LabGym/gui_detector.py index f9faaebe..82e88b65 100644 --- a/LabGym/gui_detector.py +++ b/LabGym/gui_detector.py @@ -39,9 +39,6 @@ from .tools import extract_frames -the_absolute_current_path=str(Path(__file__).resolve().parent) - - class PanelLv2_GenerateImages(wx.Panel): ''' @@ -239,13 +236,13 @@ def __init__(self, parent): self.notebook = parent # Get all of the values needed from config.get_config(). - _config = config.get_config() + self.config = config.get_config('detectors') self.path_to_trainingimages=None # the folder that stores all the training images self.path_to_annotation=None # the path to the .json file that stores the annotations in coco format self.inference_size=480 # the Detector inferencing frame size self.iteration_num=200 # the number of training iterations - self.detector_path = _config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors + self.detector_path = self.config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors self.path_to_detector=None # path to the Detector self.display_window() @@ -397,11 +394,11 @@ def __init__(self, parent): self.notebook = parent # Get all of the values needed from config.get_config(). - _config = config.get_config() + self.config = config.get_config('detectors') self.path_to_testingimages=None # the folder that stores all the testing images self.path_to_annotation=None # the path to the .json file that stores the annotations in coco format - self.detector_path = _config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors + self.detector_path = self.config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors self.path_to_detector=None # path to the Detector self.output_path=None # the folder that stores the testing images with annotations From 0aec0850b9b7a7fdd85a18c7f1f481f126b2bc6a Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Thu, 18 Sep 2025 08:49:13 -0600 Subject: [PATCH 8/9] Add shadow logging statements to detectors and models assignments. --- LabGym/gui_categorizer.py | 4 ++++ LabGym/gui_detector.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/LabGym/gui_categorizer.py b/LabGym/gui_categorizer.py index 9ded6a03..cb3e901a 100644 --- a/LabGym/gui_categorizer.py +++ b/LabGym/gui_categorizer.py @@ -379,6 +379,7 @@ def select_method(self,event): self.use_detector=True self.animal_number={} self.detector_path = self.config['detectors'] + logger.debug('%s: %r', 'self.detector_path', self.detector_path) detectors=[i for i in os.listdir(self.detector_path) if os.path.isdir(os.path.join(self.detector_path,i))] if '__pycache__' in detectors: @@ -1083,7 +1084,9 @@ def __init__(self, parent): self.augvalid=True # whether to perform augmentation for validation data as well self.data_path=None # the folder that stores prepared behavior examples self.model_path = self.config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers + logger.debug('%s: %r', 'self.model_path', self.model_path) self.path_to_categorizer = self.config['models'].joinpath('New_model') # path to the Categorizer + logger.debug('%s: %r', 'self.path_to_categorizer', self.path_to_categorizer) self.out_path=None # the folder for storing the training reports self.include_bodyparts=False # whether to include body parts in the pattern images self.std=0 # a value between 0 and 255, higher value, less body parts will be included in the pattern images @@ -1588,6 +1591,7 @@ def __init__(self, parent): self.file_path=None # the folder that stores the ground-truth examples (each subfolder is a behavior category) self.model_path = self.config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers + logger.debug('%s: %r', 'self.model_path', self.model_path) self.path_to_categorizer=None # path to the Categorizer self.out_path=None # for storing the testing reports diff --git a/LabGym/gui_detector.py b/LabGym/gui_detector.py index 82e88b65..ce726d7f 100644 --- a/LabGym/gui_detector.py +++ b/LabGym/gui_detector.py @@ -243,6 +243,7 @@ def __init__(self, parent): self.inference_size=480 # the Detector inferencing frame size self.iteration_num=200 # the number of training iterations self.detector_path = self.config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors + logger.debug('%s: %r', 'self.detector_path', self.detector_path) self.path_to_detector=None # path to the Detector self.display_window() @@ -399,6 +400,7 @@ def __init__(self, parent): self.path_to_testingimages=None # the folder that stores all the testing images self.path_to_annotation=None # the path to the .json file that stores the annotations in coco format self.detector_path = self.config['detectors'] # the 'LabGym/detectors' folder, which stores all the trained Detectors + logger.debug('%s: %r', 'self.detector_path', self.detector_path) self.path_to_detector=None # path to the Detector self.output_path=None # the folder that stores the testing images with annotations From ddc5d9cb50ac531bc8054c70f364156ce7bae22a Mon Sep 17 00:00:00 2001 From: ruck94301 Date: Thu, 18 Sep 2025 09:31:42 -0600 Subject: [PATCH 9/9] Fix joinpath needs to be os.path.join --- LabGym/gui_categorizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LabGym/gui_categorizer.py b/LabGym/gui_categorizer.py index cb3e901a..41763070 100644 --- a/LabGym/gui_categorizer.py +++ b/LabGym/gui_categorizer.py @@ -1085,7 +1085,7 @@ def __init__(self, parent): self.data_path=None # the folder that stores prepared behavior examples self.model_path = self.config['models'] # the 'LabGym/models' folder, which stores all the trained Categorizers logger.debug('%s: %r', 'self.model_path', self.model_path) - self.path_to_categorizer = self.config['models'].joinpath('New_model') # path to the Categorizer + self.path_to_categorizer = os.path.join(self.config['models'], 'New_model') # path to the Categorizer logger.debug('%s: %r', 'self.path_to_categorizer', self.path_to_categorizer) self.out_path=None # the folder for storing the training reports self.include_bodyparts=False # whether to include body parts in the pattern images