""" Central configuration module for the Thyroid Nodule Analysis Pipeline. All constants, model paths, feature definitions, and clinical lookup tables are defined here. """ import os import torch # Environment detection ON_HF_SPACES = os.environ.get("SPACE_ID") is not None # Paths BASE = os.path.dirname(os.path.abspath(__file__)) YOLO_W = os.path.join(BASE, "models", "yolo_finetuned_thyroidxl.pt") UNET_W = os.path.join(BASE, "models", "best_unet_finetuned.pth") RESNET_W = os.path.join(BASE, "models", "resnet50_finetuned_thyroidxl.pth") TIRADS_W = os.path.join(BASE, "models", "best_model_expB_RandomForest.pkl") TRAIN_CSV = os.path.join(BASE, "models", "train_features_patient_level_unetmask.csv") # Device (auto-detected: GPU if available, CPU otherwise) DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Model hyper-parameters YOLO_CONF = 0.35 # YOLO confidence threshold YOLO_IOU_THRESH = 0.50 # YOLO IoU threshold for NMS YOLO_IMGSZ = 640 # YOLO inference image size UNET_IMG_SIZE = 384 # UNet++ input resolution (H = W) RESNET_IMG_SIZE = 224 # ResNet50 input resolution (H = W) IMAGENET_MEAN = [0.485, 0.456, 0.406] # ImageNet normalisation mean IMAGENET_STD = [0.229, 0.224, 0.225] # ImageNet normalisation std # Radiomic feature columns (25 features - match Exp B training order) FEAT_COLS = [ # Morphological / shape "area_px", "aspect_ratio", "solidity", "circularity", "fractal_dim", "cv_radial", "elongation", # Intensity / echogenicity "mean_nodule", "std_nodule", "skewness", "kurt", "entropy_shannon", "cv_intensity", "rer", "solid_fraction", # GLCM texture "glcm_contrast", "glcm_asm", "glcm_idm", "glcm_correlation", "glcm_dissimilarity", "glcm_entropy", # Echogenic foci (calcification proxy) "calcif_density", "n_blobs", "mean_blob_size", "peripheral_ratio", ] # Top-10 features selected from Exp B Random Forest feature importances DISPLAY_FEATURES = [ "aspect_ratio", "rer", "std_nodule", "cv_intensity", "skewness", "elongation", "solid_fraction", "entropy_shannon", "peripheral_ratio", "glcm_correlation", ] FEATURE_LABELS = { "aspect_ratio" : "Aspect Ratio", "rer" : "Relative Echogenicity Ratio", "std_nodule" : "Intensity Std Dev", "cv_intensity" : "CV Intensity", "skewness" : "Skewness", "elongation" : "Elongation", "solid_fraction" : "Solid Fraction", "entropy_shannon" : "Shannon Entropy", "peripheral_ratio": "Peripheral Calcif. Ratio", "glcm_correlation": "GLCM Correlation", } FEATURE_CATEGORY = { "aspect_ratio" : "Shape", "rer" : "Echogenicity", "std_nodule" : "Echogenicity", "cv_intensity" : "Echogenicity", "skewness" : "Intensity", "elongation" : "Shape", "solid_fraction" : "Composition", "entropy_shannon" : "Intensity", "peripheral_ratio": "Echogenic Foci", "glcm_correlation": "Texture (GLCM)", } # Patient-level TI-RADS aggregation strategy # MAX - higher value = more suspicious -> keep worst-case across views TIRADS_AGG_MAX = [ "aspect_ratio", "fractal_dim", "cv_radial", "elongation", "calcif_density", "n_blobs", "mean_blob_size", "peripheral_ratio", "cv_intensity", "skewness", "kurt", ] # MIN - lower value = more suspicious -> keep worst-case across views TIRADS_AGG_MIN = ["solidity", "circularity", "rer"] # MEAN - remaining features (intensity statistics, GLCM) # ACR TI-RADS clinical lookup tables TIRADS_RISK = { 1: "Benign", 2: "Not suspicious", 3: "Mildly suspicious", 4: "Moderately suspicious", 5: "Highly suspicious", } TIRADS_FNAB = { 1: "Not recommended", 2: "Not recommended", 3: "Recommended if ≥ 2.5 cm", 4: "Recommended if ≥ 1.5 cm", 5: "Recommended if ≥ 1.0 cm", } # Accepted image formats for upload validation ACCEPTED_EXTENSIONS = {".png", ".jpg", ".jpeg"} ACCEPTED_MIME_TYPES = {"image/png", "image/jpeg"}