Source code for config.defaults

"""
defaults
========

Default configuration settings for NEMA phantom analysis tools.

This module establishes the default configuration hierarchy for NEMA (National
Electrical Manufacturers Association) phantom analysis using the yacs (Yet Another
Configuration System) library. It provides sensible defaults for acquisition
parameters, activity measurements, phantom geometry, ROI definitions, file patterns,
and visualization styles that can be easily overridden for different datasets and
use cases.

The configuration is organized into logical sections using nested CfgNode objects,
enabling hierarchical access and modification of settings without affecting other
configuration areas.

Configuration Sections
----------------------
ACQUISITION : CfgNode
    Acquisition parameters for PET imaging.

    EMMISION_IMAGE_TIME_MINUTES : int
        Duration of emission image acquisition in minutes (default: 10).

ACTIVITY : CfgNode
    Activity concentration measurements for phantom calibration.

    HOT : float
        Activity concentration in hot sphere regions (default: 0.79 mCi/mL).
    BACKGROUND : float
        Activity concentration in background region (default: 0.079 mCi/mL).
    RATIO : float
        Ratio of hot to background activity (default: 9.91).
    UNITS : str
        Activity measurement units (default: "mCi").
    ACTIVITY_TOTAL : str
        Total activity in the phantom (default: "29.24 MBq").

PHANTHOM : CfgNode
    EARL NEMA phantom geometry and ROI definitions.

    ROI_DEFINITIONS_MM : list of dict
        List of 6 hot sphere definitions with keys:

        - center_yx : tuple of int
            Center position in (y, x) image coordinates
        - diameter_mm : float
            Sphere diameter in millimeters
        - color : str
            Visualization color name
        - alpha : float
            Transparency value [0, 1]
        - name : str
            Descriptive sphere identifier

ROIS : CfgNode
    Region of Interest specifications for analysis.

    CENTRAL_SLICE : int
        Central axial slice index for analysis (default: 172).
    BACKGROUND_OFFSET_YX : list of tuple
        12 background sampling positions as (y, x) offsets from phantom center.
    ORIENTATION_YX : list of int
        Image orientation indicators [y_orient, x_orient] (default: [1, 1]).
    ORIENTATION_Z : int
        Z-axis orientation indicator (default: 1).
    SPACING : float
        Pixel spacing in mm (default: 2.0644).
    PHANTOM_CENTER_METHOD : str
        Method for phantom center detection ("weighted_slices" or "max_slice", default: "weighted_slices").
    PHANTOM_CENTER_THRESHOLD_FRACTION : float
        Threshold fraction for phantom center detection (0.0-1.0, default: 0.41).
    UNIFORM_RADIUS_MM : float
        Uniform cylinder radius in mm (default: 11.25).
    UNIFORM_HEIGHT_MM : float
        Uniform cylinder height in mm (default: 10.0).
    AIR_RADIUS_MM : float
        Air cylinder radius in mm (default: 2.0).
    AIR_HEIGHT_MM : float
        Air cylinder height in mm (default: 7.5).
    WATER_RADIUS_MM : float
        Water cylinder radius in mm (default: 2.0).
    WATER_HEIGHT_MM : float
        Water cylinder height in mm (default: 7.5).
    UNIFORM_OFFSET_MM : float
        Offset from phantom center to uniform region in mm (default: 5.0).
    AIRWATER_OFFSET_MM : float
        Offset from phantom center to air/water regions in mm (default: 10.0).
    AIRWATER_SEPARATION_MM : float
        Separation between air and water cylinders in mm (default: 7.5).

FILE : CfgNode
    File naming patterns and identifiers.

    USER_PATTERN : str
        Regular expression to extract frame numbers from filenames
        (default: r"frame(\\d+)").
    CASE : str
        Case identifier for output labeling (default: "Test").

STYLE : CfgNode
    Visualization and matplotlib styling parameters.

    COLORS : list of str
        List of 8 hex color codes for plot series.
    PLT_STYLE : str
        Matplotlib style template (default: "seaborn-v0_8-talk").
    RCPARAMS : list of tuple
        Matplotlib rcParams as (key, value) pairs for font sizes,
        line widths, and font family.
    PLOT : CfgNode
        Plot styling with DEFAULT and ENHANCED substyles.

        DEFAULT : CfgNode
            Base plot styling (dashed lines, lower alpha).
        ENHANCED : CfgNode
            Highlighted plot styling (solid lines, full opacity).

Functions
---------
get_cfg_defaults()
    Returns a cloned copy of the default configuration object.

Returns
-------
CfgNode
    A yacs CfgNode object containing all default configuration values.

Notes
-----
- All configuration values are stored in the module-level `_C` variable
- Use `get_cfg_defaults()` to obtain a modifiable clone rather than the
  original `_C` object
- Hot spheres follow EARL NEMA IQ phantom specification (6 spheres: 37, 28,
  22, 17, 13, 10 mm diameters)
- Background sampling uses 12 distributed offset positions around phantom center
- Visualization colors use 8-digit hex format (#RRGGBBAA) with alpha channel
- ROI positions use (y, x) convention to match NumPy array indexing

Examples
--------
Access default configuration:

    >>> from src.config.defaults import get_cfg_defaults
    >>> cfg = get_cfg_defaults()
    >>> acquisition_time = cfg.ACQUISITION.EMMISION_IMAGE_TIME_MINUTES
    >>> print(acquisition_time)
    10

Modify configuration:

    >>> cfg.ACQUISITION.EMMISION_IMAGE_TIME_MINUTES = 20
    >>> cfg.ACTIVITY.UNITS = "MBq/mL"
    >>> num_spheres = len(cfg.PHANTHOM.ROI_DEFINITIONS_MM)
    >>> print(num_spheres)
    6

Access nested styling parameters:

    >>> default_color = cfg.STYLE.PLOT.DEFAULT.COLOR
    >>> enhanced_linewidth = cfg.STYLE.PLOT.ENHANCED.LINEWIDTH

References
----------
- NEMA NU 2-2018 Standard for PET imaging performance
- EARL NEMA IQ phantom specifications
- yacs documentation: https://github.com/rbgirshick/yacs

See Also
--------
yacs.config.CfgNode : Base configuration node class
src.config : Package containing all configuration modules

"""

from yacs.config import CfgNode as CN

_C = CN()

# ---------------------------- #
# Nema Tools Options           #
# ---------------------------- #

_C.RECONSTRUCTION = CN()
_C.RECONSTRUCTION.ALGORITHM = "OSEM"
_C.RECONSTRUCTION.FILTER = "Gaussian"
_C.RECONSTRUCTION.ITERATIONS = 2

_C.ACQUISITION = CN()
_C.ACQUISITION.EMMISION_IMAGE_TIME_MINUTES = 10

_C.ACTIVITY = CN()
_C.ACTIVITY.HOT = 0.79
_C.ACTIVITY.BACKGROUND = 0.079
_C.ACTIVITY.RATIO = 9.91
_C.ACTIVITY.UNITS = "mCi"
_C.ACTIVITY.PHANTOM_ACTIVITY = "10 MBq"
_C.ACTIVITY.ACTIVITY_TIME = "16:20"
_C.ACTIVITY.ACTIVITY_TOTAL = "29.24 MBq"

_C.PHANTHOM = CN()
_C.PHANTHOM.ROI_DEFINITIONS_MM = [
    {
        "center_yx": (211, 171),
        "diameter_mm": 1,
        "color": "red",
        "alpha": 0.18,
        "name": "hot_sphere_1mm",
    },
    {
        "center_yx": (187, 184),
        "diameter_mm": 2,
        "color": "orange",
        "alpha": 0.18,
        "name": "hot_sphere_2mm",
    },
    {
        "center_yx": (187, 212),
        "diameter_mm": 3,
        "color": "gold",
        "alpha": 0.18,
        "name": "hot_sphere_3mm",
    },
    {
        "center_yx": (211, 226),
        "diameter_mm": 4,
        "color": "lime",
        "alpha": 0.18,
        "name": "hot_sphere_4mm",
    },
    {
        "center_yx": (235, 212),
        "diameter_mm": 5,
        "color": "cyan",
        "alpha": 0.18,
        "name": "hot_sphere_5mm",
    },
]

_C.ROIS = CN()
_C.ROIS.CENTRAL_SLICE = 90

_C.ROIS.UNIFORM_RADIUS_MM = 11.25
_C.ROIS.UNIFORM_HEIGHT_MM = 10.0

_C.ROIS.AIR_RADIUS_MM = 2.0
_C.ROIS.AIR_HEIGHT_MM = 7.5

_C.ROIS.WATER_RADIUS_MM = 2.0
_C.ROIS.WATER_HEIGHT_MM = 7.5

_C.ROIS.UNIFORM_OFFSET_MM = 5.0
_C.ROIS.AIRWATER_OFFSET_MM = 10.0
_C.ROIS.AIRWATER_SEPARATION_MM = 7.5

_C.ROIS.BACKGROUND_OFFSET_YX = [
    (-16, -28),
    (-33, -19),
    (-40, -1),
    (-35, 28),
    (-39, 50),
    (-32, 69),
    (-15, 79),
    (3, 76),
    (19, 65),
    (34, 51),
    (38, 28),
    (25, -3),
]
_C.ROIS.ORIENTATION_YX = [1, 1]
_C.ROIS.ORIENTATION_Z = 1

_C.ROIS.SPACING = 2.0644

_C.ROIS.PHANTOM_CENTER_METHOD = "weighted_slices"
_C.ROIS.PHANTOM_CENTER_THRESHOLD_FRACTION = 0.41

_C.ROIS.INVERSE_AXES = False

_C.FILE = CN()
_C.FILE.USER_PATTERN = r"frame(\d+)"
_C.FILE.CASE = "Test"

_C.STYLE = CN()
_C.STYLE.COLORS = [
    "#023743FF",
    "#72874EFF",
    "#476F84FF",
    "#A4BED5FF",
    "#453947FF",
    "#8C7A6BFF",
    "#C97D60FF",
    "#F0B533FF",
]
_C.STYLE.PLT_STYLE = "seaborn-v0_8-talk"
_C.STYLE.RCPARAMS = [
    ("figure.dpi", 600),
    ("font.size", 24),
    ("axes.titlesize", 24),
    ("axes.titleweight", "bold"),
    ("axes.labelsize", 24),
    ("axes.labelweight", "bold"),
    ("axes.labelpad", 20),
    ("xtick.labelsize", 24),
    ("ytick.labelsize", 24),
    ("legend.fontsize", 24),
    ("legend.title_fontsize", 24),
    ("lines.linewidth", 4.0),
    ("lines.linestyle", "-"),
    ("lines.marker", "o"),
    ("lines.markersize", 10),
    ("lines.markerfacecolor", "white"),
    ("lines.markeredgewidth", 2.0),
    ("axes.linewidth", 1.2),
    ("font.family", "DejaVu Sans"),
    ("axes.grid", True),
    ("grid.linestyle", "-"),
    ("grid.linewidth", 2.0),
    ("grid.alpha", 0.5),
]

_C.STYLE.PLOT = CN()
_C.STYLE.PLOT.DEFAULT = CN()
_C.STYLE.PLOT.DEFAULT.COLOR = "#666666FF"
_C.STYLE.PLOT.DEFAULT.LINEWIDTH = 1.0
_C.STYLE.PLOT.DEFAULT.ALPHA = 0.6
_C.STYLE.PLOT.DEFAULT.ZORDER = 5
_C.STYLE.PLOT.DEFAULT.LINESTYLE = "--"
_C.STYLE.PLOT.DEFAULT.MARKERSIZE = 4
_C.STYLE.PLOT.DEFAULT.MARKEREDGEWIDTH = 0.5

_C.STYLE.PLOT.ENHANCED = CN()
_C.STYLE.PLOT.ENHANCED.LINEWIDTH = 4.0
_C.STYLE.PLOT.ENHANCED.ALPHA = 1.0
_C.STYLE.PLOT.ENHANCED.ZORDER = 30
_C.STYLE.PLOT.ENHANCED.LINESTYLE = "-"
_C.STYLE.PLOT.ENHANCED.MARKERSIZE = 15
_C.STYLE.PLOT.ENHANCED.MARKEREDGEWIDTH = 2.0

_C.STATISTICS = CN()

# Mode: "empirical", "poisson"
_C.STATISTICS.MODE = "empirical"

# Include covariance between ROIs (advanced)
_C.STATISTICS.ESTIMATE_COVARIANCE = False

# Large-sample SD variance model: "gaussian" or "poisson"
_C.STATISTICS.SD_VARIANCE_MODEL = "gaussian"

# Safety threshold to avoid division by zero
_C.STATISTICS.EPSILON = 1e-12

# Enable fast ROI mask shifting optimization
_C.STATISTICS.FAST_ROI_SHIFT = True


[docs] def get_cfg_defaults(): """ Get a cloned yacs CfgNode object with default values. Returns a deep copy of the module-level default configuration object `_C`, containing all NEMA analysis tool settings. Cloning prevents modifications from affecting the original defaults. Returns ------- CfgNode A cloned configuration node containing: - ACQUISITION: Emission imaging parameters - ACTIVITY: Activity measurements and ratios - PHANTHOM: Phantom geometry and ROI definitions - ROIS: Region of interest specifications - FILE: File pattern matching and naming - STYLE: Visualization and plotting parameters Notes ----- Always use this function rather than accessing `_C` directly to ensure configuration isolation between independent uses. Examples -------- Create independent configuration instances: >>> cfg1 = get_cfg_defaults() >>> cfg2 = get_cfg_defaults() >>> cfg1.ACQUISITION.EMMISION_IMAGE_TIME_MINUTES = 15 >>> cfg2.ACQUISITION.EMMISION_IMAGE_TIME_MINUTES 10 """ return _C.clone()