Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9ac6fd1
PEP-8 the imports of 3 gui_* modules
ruck94301 Jul 27, 2025
a3bd0d1
Get detectors dir and models dir from config.
ruck94301 Jul 27, 2025
39a33e7
Fix a syntax typo in config.py
ruck94301 Jul 27, 2025
e684749
Merge branch 'master' into relocate-data-dirs
ruck94301 Jul 29, 2025
72b46ee
Merge branch 'master' into relocate-data-dirs
ruck94301 Jul 31, 2025
ddd6185
Merge branch 'master' into relocate-data-dirs
ruck94301 Aug 7, 2025
5f11c67
Merge branch 'master' into relocate-data-dirs
ruck94301 Aug 10, 2025
101f1e4
Merge branch 'master' into relocate-data-dirs
ruck94301 Aug 14, 2025
778dd9b
Merge branch 'master' into relocate-data-dirs
ruck94301 Aug 24, 2025
8a3b76e
Merge branch 'master' into relocate-data-dirs
ruck94301 Aug 26, 2025
922e9c5
Merge branch 'master' into relocate-data-dirs
ruck94301 Aug 27, 2025
1d6bc68
Merge branch 'master' into relocate-data-dirs
ruck94301 Aug 29, 2025
3d9ee33
Merge branch 'master' into relocate-data-dirs
ruck94301 Sep 3, 2025
3eb1949
Merge branch 'master' into relocate-data-dirs
ruck94301 Sep 9, 2025
e40f158
Merge branch 'master' into relocate-data-dirs
ruck94301 Sep 12, 2025
53755ba
change default detectors/models to str objects.
ruck94301 Sep 17, 2025
476a2e1
Added shadow logger.debug statement to detectors & models statements.
ruck94301 Sep 17, 2025
0faf8e4
Add args to config.get_config().
ruck94301 Sep 18, 2025
f30c02c
Use config.get_config() with args
ruck94301 Sep 18, 2025
0aec085
Add shadow logging statements to detectors and models assignments.
ruck94301 Sep 18, 2025
ddc5d9c
Fix joinpath needs to be os.path.join
ruck94301 Sep 18, 2025
4fc291c
Merge branch 'master' into relocate-data-dirs
ruck94301 Sep 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions LabGym/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -66,6 +67,9 @@
},

'anonymous': False,

'detectors': str(Path(__file__).parent.joinpath('detectors')),
'models': str(Path(__file__).parent.joinpath('models')),
}

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -129,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
Expand Down
18 changes: 11 additions & 7 deletions LabGym/gui_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@


# Standard library imports.
import logging
import json
import logging
import os
from pathlib import Path

Expand All @@ -38,11 +38,9 @@
# Local application/library specific imports.
from .analyzebehavior import AnalyzeAnimal
from .analyzebehavior_dt import AnalyzeAnimalDetector
from LabGym import config
from .minedata import data_mining
from .tools import plot_events,parse_all_events_file,calculate_distances


the_absolute_current_path=str(Path(__file__).resolve().parent)
from .tools import plot_events, parse_all_events_file, calculate_distances


class ColorPicker(wx.Dialog):
Expand Down Expand Up @@ -85,6 +83,10 @@ def __init__(self, parent):

super().__init__(parent)
self.notebook = parent

# Get all of the values needed from 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
self.detector_path=None # the 'LabGym/detectors' folder, which stores all the trained Detectors
Expand Down Expand Up @@ -247,7 +249,8 @@ 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']
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:
Expand Down Expand Up @@ -557,7 +560,8 @@ 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']
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))]
Expand Down
28 changes: 21 additions & 7 deletions LabGym/gui_categorizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,11 @@
from .analyzebehavior_dt import AnalyzeAnimalDetector
logger.debug('importing %s done', '.analyzebehavior_dt')
from .categorizer import Categorizers
from LabGym import config
from .tools import sort_examples_from_csv
from .gui_utils import add_or_select_notebook_page


the_absolute_current_path=str(Path(__file__).resolve().parent)


class PanelLv2_GenerateExamples(wx.Panel):

'''
Expand All @@ -60,6 +58,10 @@ def __init__(self, parent):

super().__init__(parent)
self.notebook = parent

# Get all of the values needed from 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
self.detector_path=None # the 'LabGym/detectors' folder, which stores all the trained Detectors
Expand Down Expand Up @@ -376,7 +378,8 @@ 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']
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:
Expand Down Expand Up @@ -1063,6 +1066,10 @@ def __init__(self, parent):

super().__init__(parent)
self.notebook = parent

# Get all of the values needed from 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)
self.behavior_mode=0 # 0--non-interactive, 1--interactive basic, 2--interactive advanced, 3--static images
Expand All @@ -1076,8 +1083,10 @@ 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=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 = 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 = 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
self.std=0 # a value between 0 and 255, higher value, less body parts will be included in the pattern images
Expand Down Expand Up @@ -1576,8 +1585,13 @@ def __init__(self, parent):

super().__init__(parent)
self.notebook = parent

# Get all of the values needed from 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=os.path.join(the_absolute_current_path,'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
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

Expand Down
20 changes: 14 additions & 6 deletions LabGym/gui_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
# Standard library imports.
import json
import logging
from pathlib import Path
import os
from pathlib import Path
import shutil

# Log the load of this module (by the module loader, on first import).
Expand All @@ -34,13 +34,11 @@
import wx

# Local application/library specific imports.
from LabGym import config
from .detector import Detector
from .tools import extract_frames


the_absolute_current_path=str(Path(__file__).resolve().parent)


class PanelLv2_GenerateImages(wx.Panel):

'''
Expand Down Expand Up @@ -236,11 +234,16 @@ def __init__(self, parent):

super().__init__(parent)
self.notebook = parent

# Get all of the values needed from 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=os.path.join(the_absolute_current_path,'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
logger.debug('%s: %r', 'self.detector_path', self.detector_path)
self.path_to_detector=None # path to the Detector

self.display_window()
Expand Down Expand Up @@ -390,9 +393,14 @@ def __init__(self, parent):

super().__init__(parent)
self.notebook = parent

# Get all of the values needed from 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=os.path.join(the_absolute_current_path,'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
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

Expand Down
Loading