retuve.keyphrases.config
The parent class for for Retuve configs
1# Copyright 2024 Adam McArthur 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15""" 16The parent class for for Retuve configs 17""" 18 19import copy 20from typing import List, Tuple 21 22from PIL import ImageFont 23from radstract.data.dicom import DicomTypes 24from torch.types import Device 25 26from retuve.keyphrases.enums import OperationType 27from retuve.keyphrases.subconfig import ( 28 APIConfig, 29 BatchConfig, 30 HipConfig, 31 TrakConfig, 32 VisualsConfig, 33) 34from retuve.logs import ulogger 35from retuve.utils import RETUVE_DIR, register_config_dirs 36 37 38class GlobalConfig: 39 def __init__(self, username: str, password: str): 40 self.username = username 41 self.password = password 42 43 44class Config: 45 """Configuration class.""" 46 47 configs = {} 48 live_config = None 49 50 def __init__( 51 self, 52 dicom_type: DicomTypes, 53 crop_coordinates: Tuple[float], 54 template: bool, 55 min_seg_confidence: float, 56 device: Device, 57 operation_type: OperationType, 58 dev: bool, 59 replace_old: bool, 60 seg_export: bool, 61 test_data_passthrough: bool, 62 subconfig_hip: HipConfig, 63 subconfig_trak: TrakConfig, 64 subconfig_visuals: VisualsConfig, 65 subconfig_api: APIConfig, 66 subconfig_batch: BatchConfig, 67 name=None, 68 ): 69 """ 70 Initialize Config. 71 72 :param dicom_type (DicomTypes): The type of dicom to use. 73 :param crop_coordinates (Tuple[float]): The crop coordinates. 74 :param template (bool): Whether this is a template config. 75 :param min_seg_confidence (float): The minimum segmentation confidence. 76 :param device (Device): The device to use. 77 :param operation_type (OperationType): The operation type. 78 :param dev (bool): Whether to use dev mode. 79 :param replace_old (bool): Whether to replace old files. 80 :param seg_export (bool): Whether to export segmentation. 81 :param test_data_passthrough (bool): Whether to pass through test data. 82 :param subconfig_hip (HipConfig): The hip subconfig. 83 :param subconfig_trak (TrakConfig): The trak subconfig. 84 :param subconfig_visuals (VisualsConfig): The visuals subconfig. 85 :param subconfig_api (APIConfig): The api subconfig. 86 :param subconfig_batch (BatchConfig): The batch subconfig. 87 :param name (str): The name (keyphrase) of the config. 88 """ 89 self.name = name 90 91 if not (template or name): 92 raise ValueError("Template configs must have a name specified.") 93 94 if not template and (name): 95 self.register(name) 96 97 self.dicom_type = dicom_type 98 self.crop_coordinates = crop_coordinates 99 self.min_seg_confidence = min_seg_confidence 100 101 self.device = device 102 self.replace_old = replace_old 103 self.operation_type = operation_type 104 self.dev = dev 105 106 self.seg_export = seg_export 107 108 self.hip: HipConfig = subconfig_hip 109 self.trak: TrakConfig = subconfig_trak 110 self.visuals: VisualsConfig = subconfig_visuals 111 self.api: APIConfig = subconfig_api 112 self.batch: BatchConfig = subconfig_batch 113 114 self.test_data_passthrough = test_data_passthrough 115 116 if operation_type not in [ 117 OperationType.SEG, 118 OperationType.LANDMARK, 119 ]: 120 raise ValueError(f"Invalid operation type: {operation_type}") 121 122 def register( 123 self, 124 name: str, 125 store: bool = True, 126 silent: bool = False, 127 live: bool = False, 128 ): 129 """ 130 Register the config. 131 132 :param name (str): The name of the config. 133 :param store (bool): Whether to store the config 134 for later retrieval. 135 136 """ 137 self.name = name 138 139 # check if config already exists 140 if self.configs.get(name): 141 raise ValueError(f"Config {name} already exists.") 142 143 if not self.configs.get(name) and store: 144 self.configs[name] = {} 145 146 if store: 147 self.configs[name] = self 148 149 if live: 150 Config.live_config = self 151 152 # defaults need registering 153 if self.visuals.default_font_size: 154 self.visuals.font_h1 = ImageFont.truetype( 155 f"{RETUVE_DIR}/files/RobotoMono-Regular.ttf", 156 self.visuals.default_font_size, 157 ) 158 159 self.visuals.font_h2 = ImageFont.truetype( 160 f"{RETUVE_DIR}/files/RobotoMono-Regular.ttf", 161 self.visuals.default_font_size, 162 ) 163 164 self.batch.register() 165 166 register_config_dirs(self) 167 168 if not self.api.api_token: 169 ValueError("API token must be set.") 170 171 if not silent: 172 ulogger.info(f"Registered config for {name}") 173 174 def unregister(self, silent: bool = False): 175 """ 176 Unregister the config. 177 """ 178 if self.name in self.configs: 179 del self.configs[self.name] 180 181 if not silent: 182 ulogger.info(f"Unregistered config for {self.name}") 183 184 def get_copy(self) -> "Config": 185 """ 186 Get a copy of the config. 187 188 :return: A copy of the config. 189 """ 190 return copy.deepcopy(self) 191 192 def inject_global_config(self, username, password): 193 """ 194 Inject the global config into the config. 195 196 :param username (str): The username. 197 :param password (str): The password. 198 """ 199 Config.global_config = GlobalConfig(username, password) 200 201 @classmethod 202 def get_configs(self) -> List[Tuple[str, "Config"]]: 203 """ 204 Get all registered/stored configs. 205 206 :return: A list of tuples of name and config. 207 """ 208 return [(name, config) for name, config, in self.configs.items()] 209 210 @classmethod 211 def get_config(cls, name: str) -> "Config": 212 """ 213 Get a config by name. 214 215 :param name (str): The name of the config. 216 217 :return: The config. 218 """ 219 # check if name is of type Config 220 if isinstance(name, Config): 221 return name 222 223 if not cls.configs.get(name): 224 raise ValueError(f"Config {name} does not exist.") 225 226 return cls.configs[name] 227 228 @classmethod 229 def keyphrase_exists(cls, name: str) -> bool: 230 """ 231 Check if a keyphrase exists in the configs. 232 233 :param name (str): The name of the keyphrase. 234 235 :return: Whether the keyphrase exists. 236 """ 237 lower_keys = [key.lower() for key in cls.configs.keys()] 238 return name.lower() in lower_keys
class
GlobalConfig:
39class GlobalConfig: 40 def __init__(self, username: str, password: str): 41 self.username = username 42 self.password = password
class
Config:
45class Config: 46 """Configuration class.""" 47 48 configs = {} 49 live_config = None 50 51 def __init__( 52 self, 53 dicom_type: DicomTypes, 54 crop_coordinates: Tuple[float], 55 template: bool, 56 min_seg_confidence: float, 57 device: Device, 58 operation_type: OperationType, 59 dev: bool, 60 replace_old: bool, 61 seg_export: bool, 62 test_data_passthrough: bool, 63 subconfig_hip: HipConfig, 64 subconfig_trak: TrakConfig, 65 subconfig_visuals: VisualsConfig, 66 subconfig_api: APIConfig, 67 subconfig_batch: BatchConfig, 68 name=None, 69 ): 70 """ 71 Initialize Config. 72 73 :param dicom_type (DicomTypes): The type of dicom to use. 74 :param crop_coordinates (Tuple[float]): The crop coordinates. 75 :param template (bool): Whether this is a template config. 76 :param min_seg_confidence (float): The minimum segmentation confidence. 77 :param device (Device): The device to use. 78 :param operation_type (OperationType): The operation type. 79 :param dev (bool): Whether to use dev mode. 80 :param replace_old (bool): Whether to replace old files. 81 :param seg_export (bool): Whether to export segmentation. 82 :param test_data_passthrough (bool): Whether to pass through test data. 83 :param subconfig_hip (HipConfig): The hip subconfig. 84 :param subconfig_trak (TrakConfig): The trak subconfig. 85 :param subconfig_visuals (VisualsConfig): The visuals subconfig. 86 :param subconfig_api (APIConfig): The api subconfig. 87 :param subconfig_batch (BatchConfig): The batch subconfig. 88 :param name (str): The name (keyphrase) of the config. 89 """ 90 self.name = name 91 92 if not (template or name): 93 raise ValueError("Template configs must have a name specified.") 94 95 if not template and (name): 96 self.register(name) 97 98 self.dicom_type = dicom_type 99 self.crop_coordinates = crop_coordinates 100 self.min_seg_confidence = min_seg_confidence 101 102 self.device = device 103 self.replace_old = replace_old 104 self.operation_type = operation_type 105 self.dev = dev 106 107 self.seg_export = seg_export 108 109 self.hip: HipConfig = subconfig_hip 110 self.trak: TrakConfig = subconfig_trak 111 self.visuals: VisualsConfig = subconfig_visuals 112 self.api: APIConfig = subconfig_api 113 self.batch: BatchConfig = subconfig_batch 114 115 self.test_data_passthrough = test_data_passthrough 116 117 if operation_type not in [ 118 OperationType.SEG, 119 OperationType.LANDMARK, 120 ]: 121 raise ValueError(f"Invalid operation type: {operation_type}") 122 123 def register( 124 self, 125 name: str, 126 store: bool = True, 127 silent: bool = False, 128 live: bool = False, 129 ): 130 """ 131 Register the config. 132 133 :param name (str): The name of the config. 134 :param store (bool): Whether to store the config 135 for later retrieval. 136 137 """ 138 self.name = name 139 140 # check if config already exists 141 if self.configs.get(name): 142 raise ValueError(f"Config {name} already exists.") 143 144 if not self.configs.get(name) and store: 145 self.configs[name] = {} 146 147 if store: 148 self.configs[name] = self 149 150 if live: 151 Config.live_config = self 152 153 # defaults need registering 154 if self.visuals.default_font_size: 155 self.visuals.font_h1 = ImageFont.truetype( 156 f"{RETUVE_DIR}/files/RobotoMono-Regular.ttf", 157 self.visuals.default_font_size, 158 ) 159 160 self.visuals.font_h2 = ImageFont.truetype( 161 f"{RETUVE_DIR}/files/RobotoMono-Regular.ttf", 162 self.visuals.default_font_size, 163 ) 164 165 self.batch.register() 166 167 register_config_dirs(self) 168 169 if not self.api.api_token: 170 ValueError("API token must be set.") 171 172 if not silent: 173 ulogger.info(f"Registered config for {name}") 174 175 def unregister(self, silent: bool = False): 176 """ 177 Unregister the config. 178 """ 179 if self.name in self.configs: 180 del self.configs[self.name] 181 182 if not silent: 183 ulogger.info(f"Unregistered config for {self.name}") 184 185 def get_copy(self) -> "Config": 186 """ 187 Get a copy of the config. 188 189 :return: A copy of the config. 190 """ 191 return copy.deepcopy(self) 192 193 def inject_global_config(self, username, password): 194 """ 195 Inject the global config into the config. 196 197 :param username (str): The username. 198 :param password (str): The password. 199 """ 200 Config.global_config = GlobalConfig(username, password) 201 202 @classmethod 203 def get_configs(self) -> List[Tuple[str, "Config"]]: 204 """ 205 Get all registered/stored configs. 206 207 :return: A list of tuples of name and config. 208 """ 209 return [(name, config) for name, config, in self.configs.items()] 210 211 @classmethod 212 def get_config(cls, name: str) -> "Config": 213 """ 214 Get a config by name. 215 216 :param name (str): The name of the config. 217 218 :return: The config. 219 """ 220 # check if name is of type Config 221 if isinstance(name, Config): 222 return name 223 224 if not cls.configs.get(name): 225 raise ValueError(f"Config {name} does not exist.") 226 227 return cls.configs[name] 228 229 @classmethod 230 def keyphrase_exists(cls, name: str) -> bool: 231 """ 232 Check if a keyphrase exists in the configs. 233 234 :param name (str): The name of the keyphrase. 235 236 :return: Whether the keyphrase exists. 237 """ 238 lower_keys = [key.lower() for key in cls.configs.keys()] 239 return name.lower() in lower_keys
Configuration class.
Config( dicom_type: radstract.data.dicom.utils.DicomTypes, crop_coordinates: Tuple[float], template: bool, min_seg_confidence: float, device: Union[torch.device, str, int, NoneType], operation_type: retuve.keyphrases.enums.OperationType, dev: bool, replace_old: bool, seg_export: bool, test_data_passthrough: bool, subconfig_hip: retuve.keyphrases.subconfig.HipConfig, subconfig_trak: retuve.keyphrases.subconfig.TrakConfig, subconfig_visuals: retuve.keyphrases.subconfig.VisualsConfig, subconfig_api: retuve.keyphrases.subconfig.APIConfig, subconfig_batch: retuve.keyphrases.subconfig.BatchConfig, name=None)
51 def __init__( 52 self, 53 dicom_type: DicomTypes, 54 crop_coordinates: Tuple[float], 55 template: bool, 56 min_seg_confidence: float, 57 device: Device, 58 operation_type: OperationType, 59 dev: bool, 60 replace_old: bool, 61 seg_export: bool, 62 test_data_passthrough: bool, 63 subconfig_hip: HipConfig, 64 subconfig_trak: TrakConfig, 65 subconfig_visuals: VisualsConfig, 66 subconfig_api: APIConfig, 67 subconfig_batch: BatchConfig, 68 name=None, 69 ): 70 """ 71 Initialize Config. 72 73 :param dicom_type (DicomTypes): The type of dicom to use. 74 :param crop_coordinates (Tuple[float]): The crop coordinates. 75 :param template (bool): Whether this is a template config. 76 :param min_seg_confidence (float): The minimum segmentation confidence. 77 :param device (Device): The device to use. 78 :param operation_type (OperationType): The operation type. 79 :param dev (bool): Whether to use dev mode. 80 :param replace_old (bool): Whether to replace old files. 81 :param seg_export (bool): Whether to export segmentation. 82 :param test_data_passthrough (bool): Whether to pass through test data. 83 :param subconfig_hip (HipConfig): The hip subconfig. 84 :param subconfig_trak (TrakConfig): The trak subconfig. 85 :param subconfig_visuals (VisualsConfig): The visuals subconfig. 86 :param subconfig_api (APIConfig): The api subconfig. 87 :param subconfig_batch (BatchConfig): The batch subconfig. 88 :param name (str): The name (keyphrase) of the config. 89 """ 90 self.name = name 91 92 if not (template or name): 93 raise ValueError("Template configs must have a name specified.") 94 95 if not template and (name): 96 self.register(name) 97 98 self.dicom_type = dicom_type 99 self.crop_coordinates = crop_coordinates 100 self.min_seg_confidence = min_seg_confidence 101 102 self.device = device 103 self.replace_old = replace_old 104 self.operation_type = operation_type 105 self.dev = dev 106 107 self.seg_export = seg_export 108 109 self.hip: HipConfig = subconfig_hip 110 self.trak: TrakConfig = subconfig_trak 111 self.visuals: VisualsConfig = subconfig_visuals 112 self.api: APIConfig = subconfig_api 113 self.batch: BatchConfig = subconfig_batch 114 115 self.test_data_passthrough = test_data_passthrough 116 117 if operation_type not in [ 118 OperationType.SEG, 119 OperationType.LANDMARK, 120 ]: 121 raise ValueError(f"Invalid operation type: {operation_type}")
Initialize Config.
Parameters
- dicom_type (DicomTypes): The type of dicom to use.
- crop_coordinates (Tuple[float]): The crop coordinates.
- template (bool): Whether this is a template config.
- min_seg_confidence (float): The minimum segmentation confidence.
- device (Device): The device to use.
- operation_type (OperationType): The operation type.
- dev (bool): Whether to use dev mode.
- replace_old (bool): Whether to replace old files.
- seg_export (bool): Whether to export segmentation.
- test_data_passthrough (bool): Whether to pass through test data.
- subconfig_hip (HipConfig): The hip subconfig.
- subconfig_trak (TrakConfig): The trak subconfig.
- subconfig_visuals (VisualsConfig): The visuals subconfig.
- subconfig_api (APIConfig): The api subconfig.
- subconfig_batch (BatchConfig): The batch subconfig.
- name (str): The name (keyphrase) of the config.
def
register( self, name: str, store: bool = True, silent: bool = False, live: bool = False):
123 def register( 124 self, 125 name: str, 126 store: bool = True, 127 silent: bool = False, 128 live: bool = False, 129 ): 130 """ 131 Register the config. 132 133 :param name (str): The name of the config. 134 :param store (bool): Whether to store the config 135 for later retrieval. 136 137 """ 138 self.name = name 139 140 # check if config already exists 141 if self.configs.get(name): 142 raise ValueError(f"Config {name} already exists.") 143 144 if not self.configs.get(name) and store: 145 self.configs[name] = {} 146 147 if store: 148 self.configs[name] = self 149 150 if live: 151 Config.live_config = self 152 153 # defaults need registering 154 if self.visuals.default_font_size: 155 self.visuals.font_h1 = ImageFont.truetype( 156 f"{RETUVE_DIR}/files/RobotoMono-Regular.ttf", 157 self.visuals.default_font_size, 158 ) 159 160 self.visuals.font_h2 = ImageFont.truetype( 161 f"{RETUVE_DIR}/files/RobotoMono-Regular.ttf", 162 self.visuals.default_font_size, 163 ) 164 165 self.batch.register() 166 167 register_config_dirs(self) 168 169 if not self.api.api_token: 170 ValueError("API token must be set.") 171 172 if not silent: 173 ulogger.info(f"Registered config for {name}")
Register the config.
Parameters
- name (str): The name of the config.
- store (bool): Whether to store the config for later retrieval.
def
unregister(self, silent: bool = False):
175 def unregister(self, silent: bool = False): 176 """ 177 Unregister the config. 178 """ 179 if self.name in self.configs: 180 del self.configs[self.name] 181 182 if not silent: 183 ulogger.info(f"Unregistered config for {self.name}")
Unregister the config.
185 def get_copy(self) -> "Config": 186 """ 187 Get a copy of the config. 188 189 :return: A copy of the config. 190 """ 191 return copy.deepcopy(self)
Get a copy of the config.
Returns
A copy of the config.
def
inject_global_config(self, username, password):
193 def inject_global_config(self, username, password): 194 """ 195 Inject the global config into the config. 196 197 :param username (str): The username. 198 :param password (str): The password. 199 """ 200 Config.global_config = GlobalConfig(username, password)
Inject the global config into the config.
Parameters
- username (str): The username.
- password (str): The password.
202 @classmethod 203 def get_configs(self) -> List[Tuple[str, "Config"]]: 204 """ 205 Get all registered/stored configs. 206 207 :return: A list of tuples of name and config. 208 """ 209 return [(name, config) for name, config, in self.configs.items()]
Get all registered/stored configs.
Returns
A list of tuples of name and config.
211 @classmethod 212 def get_config(cls, name: str) -> "Config": 213 """ 214 Get a config by name. 215 216 :param name (str): The name of the config. 217 218 :return: The config. 219 """ 220 # check if name is of type Config 221 if isinstance(name, Config): 222 return name 223 224 if not cls.configs.get(name): 225 raise ValueError(f"Config {name} does not exist.") 226 227 return cls.configs[name]
Get a config by name.
Parameters
- name (str): The name of the config.
Returns
The config.
@classmethod
def
keyphrase_exists(cls, name: str) -> bool:
229 @classmethod 230 def keyphrase_exists(cls, name: str) -> bool: 231 """ 232 Check if a keyphrase exists in the configs. 233 234 :param name (str): The name of the keyphrase. 235 236 :return: Whether the keyphrase exists. 237 """ 238 lower_keys = [key.lower() for key in cls.configs.keys()] 239 return name.lower() in lower_keys
Check if a keyphrase exists in the configs.
Parameters
- name (str): The name of the keyphrase.
Returns
Whether the keyphrase exists.