Source code for src.common.config.global_config

import datetime
import os
import sys
from typing import Any

from torchvision import transforms

from src.common.config.cli_parser import get_args
from src.common.config.util import Config

cfg = None
adv_cfg = None


def __set_config(key: str, value: Any):
    """ Update config entry. You should not use this function in your code, once the cfg is set up it should not be changed again!

    Args:
        key: name of config entry
        value: new value
    """
    print('update ', (key, value), ' config')
    setattr(cfg, key, value)


[docs]def process_modes(): """ handling of special runtime modes """ if not cfg.mode: raise Exception('select mode') if cfg.mode in ['test', 'preview', 'prod', 'benchmark']: print(f'Special mode {cfg.mode} selected, this will override some of your config settings.') if cfg.mode == 'test': if not cfg.test_txt or not cfg.test_validation_data: raise Exception('test_txt and test_validation_data has to be specified for testing mode') __set_config('input_mode', 'images') __set_config('output_mode', ['test']) elif cfg.mode == 'preview': if not cfg.test_txt: raise Exception('test_txt has to be specified for testing mode') __set_config('input_mode', 'images') __set_config('output_mode', ['video']) __set_config('video_out_enable_live_video', True) __set_config('batch_size', 1) elif cfg.mode == 'prod': __set_config('input_mode', 'camera') __set_config('output_mode', ['prod']) elif cfg.mode == 'benchmark': __set_config('input_mode', 'images') __set_config('output_mode', ['json']) __set_config('measure_time', True) cfg.mode = 'runtime'
[docs]def merge_config() -> Config: """ combines default and user-config and cli arguments """ args = get_args().parse_args() user_cfg = Config.fromfile(args.config) cfg = Config.fromfile('configs/default.py') # override default cfg with values from user cfg for item in [(k, v) for k, v in user_cfg.items() if v]: cfg[item[0]] = item[1] for k, v in vars(args).items(): if v is not None: print('update ', (k, v), ' config') setattr(cfg, k, v) return cfg
[docs]class AdvancedConfig: """ This class provides "advanced config values" meaning it calculates some values which depend on other cfg values They are calculated here to - keep the configs clean - prevent calculating them multiple times during runtime which should make your code cleaner and improve performance """
[docs] @staticmethod def gen_train_dir(cfg): now = datetime.datetime.now().strftime('%Y%m%d_%H%M%S') hyper_param_str = '_lr_%1.0e_b_%d' % (cfg.learning_rate, cfg.batch_size) work_dir = os.path.join(cfg.work_dir, now + hyper_param_str + cfg.note) return work_dir
def __init__(self): # import pdb;pdb.set_trace() self.cls_num_per_lane = len(cfg.h_samples) self.scaled_h_samples = [int(round(x * cfg.img_height)) for x in cfg.h_samples] self.train_h_samples = [x * cfg.train_img_height for x in cfg.h_samples] self.img_transform = transforms.Compose([ transforms.Resize((cfg.train_img_height, cfg.train_img_width)), transforms.ToTensor(), transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), ]) self.train_dir = self.gen_train_dir(cfg)
[docs]def init(): """ in the good old times this was a simple import and forget, but this behaviour breaks sphinx :/ Now the config has to be initialized once at start """ global cfg, adv_cfg if not cfg: cfg = merge_config() process_modes() adv_cfg = AdvancedConfig()
[docs]class Dummy: """ This is a simple dummy class (mock) which will always return a dummy string for every value its asked for This prevents errors if this applications is run under unusual circumstances (eg doc generation) """ def __init__(self, name): """ Args: name: Name of the class/object this instantiation will replace. eg 'cfg' """ self.name = name def __getattribute__(self, item): return f"{object.__getattribute__(self, 'name')}.{item}"
# Use mock class if this file is called during doc generation if 'sphinx' in sys.modules and not cfg: cfg = Dummy('cfg') adv_cfg = Dummy('adv_cfg')