simnibs_analyze._config

Pydantic models for pipeline config.yaml validation.

These models mirror the config.yaml structure exactly. Usage (standalone check): python _config.py --config config.yaml

  1"""
  2Pydantic models for pipeline config.yaml validation.
  3
  4These models mirror the config.yaml structure exactly.
  5Usage (standalone check):
  6    python _config.py --config config.yaml
  7"""
  8
  9from __future__ import annotations
 10
 11from pathlib import Path
 12from typing import Annotated, Literal, Optional, Union
 13
 14from pydantic import BaseModel, Field, field_validator, model_validator
 15
 16
 17# ---------------------------------------------------------------------------
 18# ROI definitions  (target_generation.rois)
 19# ---------------------------------------------------------------------------
 20
 21
 22class SphereROI(BaseModel):
 23    """ROI defined by a sphere centred on MNI coordinates."""
 24
 25    method: Literal["sphere"]
 26    coords: Annotated[list[float], Field(min_length=3, max_length=3)]
 27    folder_pattern: Optional[str] = None
 28    """Glob fragment used to find SimNIBS output folders for this ROI.
 29    If omitted, the ROI key name is used (e.g. 'fef' → 'simulation_simulation_fef_*').
 30    Set this when the folder name differs from the ROI key (e.g. ROI 'ips-left' but
 31    folders are named '…ips_left…' → folder_pattern: 'ips_left')."""
 32
 33
 34class AtlasROI(BaseModel):
 35    """ROI defined by one or more parcels from a brain atlas."""
 36
 37    method: Literal["atlas"]
 38    atlas: Literal["harvard-oxford", "aal", "destrieux"]
 39    regions: Union[str, list[str]]
 40    folder_pattern: Optional[str] = None
 41    """See SphereROI.folder_pattern."""
 42
 43
 44# Discriminated union: Pydantic inspects the `method` field to pick the right model.
 45ROIDef = Annotated[Union[SphereROI, AtlasROI], Field(discriminator="method")]
 46
 47
 48# ---------------------------------------------------------------------------
 49# Sections
 50# ---------------------------------------------------------------------------
 51
 52
 53class TargetGenerationConfig(BaseModel):
 54    radius_mm: float = Field(default=10.0, gt=0)
 55    rois: dict[str, ROIDef]
 56
 57    @field_validator("rois")
 58    @classmethod
 59    def _no_underscores_in_roi_names(cls, v: dict) -> dict:
 60        bad = [k for k in v if "_" in k]
 61        if bad:
 62            raise ValueError(
 63                f"ROI names must not contain underscores (use hyphens instead): {bad}"
 64            )
 65        return v
 66
 67
 68class PathsConfig(BaseModel):
 69    # ── Nouvelles clés (préféré) ───────────────────────────────────────────
 70    simnibs_preps: Optional[Path] = None
 71    """Dossier des résultats charm/segmentation  →  {sub}/m2m_{sub}/"""
 72    simnibs_simu: Optional[Path] = None
 73    """Dossier des résultats de simulation/optimisation  →  {sub}/simulations/"""
 74
 75    # ── Compatibilité ascendante (ancien pipeline, un seul dossier racine) ─
 76    simnibs_output: Optional[Path] = None
 77    """Deprecated : utiliser simnibs_preps + simnibs_simu."""
 78
 79    # ── Sorties pipeline ──────────────────────────────────────────────────
 80    results_dir: Path
 81    """Dossier de sortie : CSVs, figures, statistiques."""
 82
 83    # ── Templates ─────────────────────────────────────────────────────────
 84    mni_template: Optional[Path] = None
 85    mni_brain_mask: Optional[Path] = None
 86
 87    @model_validator(mode="after")
 88    def _validate_input_paths(self) -> "PathsConfig":
 89        split = self.simnibs_preps is not None and self.simnibs_simu is not None
 90        legacy = self.simnibs_output is not None
 91        if not split and not legacy:
 92            raise ValueError(
 93                "Specify either 'simnibs_output' (legacy) OR both "
 94                "'simnibs_preps' + 'simnibs_simu'."
 95            )
 96        return self
 97
 98
 99class PreprocessingConfig(BaseModel):
100    smooth_fwhm: float = Field(default=2.0, ge=0)
101    outlier_method: Literal["iqr", "zscore"] = "iqr"
102    portion: Optional[float] = Field(default=None, gt=0, le=1)
103
104
105class FeatureExtractionConfig(BaseModel):
106    metrics: list[str] = ["mean", "median", "std", "min", "max"]
107
108
109class ClusteringConfig(BaseModel):
110    method: str = "mean"
111    specificity_threshold: float = Field(default=1.5, gt=0)
112    intensity_col: str = "mean"
113
114
115class AnalysisConfig(BaseModel):
116    metric: str = "mean"
117    subject_col: str = "subject"
118    condition_col: str = "condition"
119    clustering: ClusteringConfig = ClusteringConfig()
120
121
122class RunningConfig(BaseModel):
123    if_exists: Literal["skip", "overwrite", "error"] = "skip"
124
125
126# ---------------------------------------------------------------------------
127# Root model
128# ---------------------------------------------------------------------------
129
130
131class PipelineConfig(BaseModel):
132    subjects: list[str]
133    stim_conditions: list[str]
134    mode: list[Literal["simulation", "optimization"]]
135    space: Literal["mni", "native"] = "mni"
136    running: RunningConfig = RunningConfig()
137    target_generation: TargetGenerationConfig
138    paths: PathsConfig
139    preprocessing: PreprocessingConfig = PreprocessingConfig()
140    feature_extraction: FeatureExtractionConfig = FeatureExtractionConfig()
141    analysis: AnalysisConfig = AnalysisConfig()
142
143    @model_validator(mode="after")
144    def _stim_conditions_match_rois(self) -> "PipelineConfig":
145        """Every stim_condition must have a matching ROI key (used to find the mask file)."""
146        roi_names = set(self.target_generation.rois)
147        missing = [c for c in self.stim_conditions if c not in roi_names]
148        if missing:
149            raise ValueError(
150                f"stim_conditions {missing} have no matching entry in target_generation.rois. "
151                f"Available ROI keys: {sorted(roi_names)}"
152            )
153        return self
154
155
156# ---------------------------------------------------------------------------
157# Helper
158# ---------------------------------------------------------------------------
159
160
161def load_and_validate(config_path: Path) -> PipelineConfig:
162    """Load a YAML config file and return a validated PipelineConfig."""
163    import yaml
164
165    with open(config_path) as f:
166        raw = yaml.safe_load(f)
167    return PipelineConfig.model_validate(raw)
168
169
170# ---------------------------------------------------------------------------
171# CLI — standalone validation
172# ---------------------------------------------------------------------------
173
174if __name__ == "__main__":
175    import argparse
176    import sys
177
178    parser = argparse.ArgumentParser(description="Validate a pipeline config.yaml")
179    parser.add_argument(
180        "--config", type=Path, default=Path(__file__).parent / "config.yaml"
181    )
182    args = parser.parse_args()
183
184    try:
185        cfg = load_and_validate(args.config)
186        print(
187            f"✓ Config valid — {len(cfg.subjects)} subject(s), "
188            f"{len(cfg.target_generation.rois)} ROI(s), space={cfg.space}"
189        )
190    except Exception as e:
191        print(f"✗ Invalid config:\n{e}", file=sys.stderr)
192        sys.exit(1)
class SphereROI(pydantic.main.BaseModel):
23class SphereROI(BaseModel):
24    """ROI defined by a sphere centred on MNI coordinates."""
25
26    method: Literal["sphere"]
27    coords: Annotated[list[float], Field(min_length=3, max_length=3)]
28    folder_pattern: Optional[str] = None
29    """Glob fragment used to find SimNIBS output folders for this ROI.
30    If omitted, the ROI key name is used (e.g. 'fef' → 'simulation_simulation_fef_*').
31    Set this when the folder name differs from the ROI key (e.g. ROI 'ips-left' but
32    folders are named '…ips_left…' → folder_pattern: 'ips_left')."""

ROI defined by a sphere centred on MNI coordinates.

method: Literal['sphere'] = PydanticUndefined
coords: typing.Annotated[list[float], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=3), MaxLen(max_length=3)])] = PydanticUndefined
folder_pattern: Optional[str] = None

Glob fragment used to find SimNIBS output folders for this ROI. If omitted, the ROI key name is used (e.g. 'fef' → 'simulation_simulation_fef_*'). Set this when the folder name differs from the ROI key (e.g. ROI 'ips-left' but folders are named '…ips_left…' → folder_pattern: 'ips_left').

class AtlasROI(pydantic.main.BaseModel):
35class AtlasROI(BaseModel):
36    """ROI defined by one or more parcels from a brain atlas."""
37
38    method: Literal["atlas"]
39    atlas: Literal["harvard-oxford", "aal", "destrieux"]
40    regions: Union[str, list[str]]
41    folder_pattern: Optional[str] = None
42    """See SphereROI.folder_pattern."""

ROI defined by one or more parcels from a brain atlas.

method: Literal['atlas'] = PydanticUndefined
atlas: Literal['harvard-oxford', 'aal', 'destrieux'] = PydanticUndefined
regions: Union[str, list[str]] = PydanticUndefined
folder_pattern: Optional[str] = None
ROIDef = typing.Annotated[typing.Union[SphereROI, AtlasROI], FieldInfo(annotation=NoneType, required=True, discriminator='method')]
class TargetGenerationConfig(pydantic.main.BaseModel):
54class TargetGenerationConfig(BaseModel):
55    radius_mm: float = Field(default=10.0, gt=0)
56    rois: dict[str, ROIDef]
57
58    @field_validator("rois")
59    @classmethod
60    def _no_underscores_in_roi_names(cls, v: dict) -> dict:
61        bad = [k for k in v if "_" in k]
62        if bad:
63            raise ValueError(
64                f"ROI names must not contain underscores (use hyphens instead): {bad}"
65            )
66        return v

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
radius_mm: float = 10.0
rois: dict[str, typing.Annotated[typing.Union[SphereROI, AtlasROI], FieldInfo(annotation=NoneType, required=True, discriminator='method')]] = PydanticUndefined
class PathsConfig(pydantic.main.BaseModel):
69class PathsConfig(BaseModel):
70    # ── Nouvelles clés (préféré) ───────────────────────────────────────────
71    simnibs_preps: Optional[Path] = None
72    """Dossier des résultats charm/segmentation  →  {sub}/m2m_{sub}/"""
73    simnibs_simu: Optional[Path] = None
74    """Dossier des résultats de simulation/optimisation  →  {sub}/simulations/"""
75
76    # ── Compatibilité ascendante (ancien pipeline, un seul dossier racine) ─
77    simnibs_output: Optional[Path] = None
78    """Deprecated : utiliser simnibs_preps + simnibs_simu."""
79
80    # ── Sorties pipeline ──────────────────────────────────────────────────
81    results_dir: Path
82    """Dossier de sortie : CSVs, figures, statistiques."""
83
84    # ── Templates ─────────────────────────────────────────────────────────
85    mni_template: Optional[Path] = None
86    mni_brain_mask: Optional[Path] = None
87
88    @model_validator(mode="after")
89    def _validate_input_paths(self) -> "PathsConfig":
90        split = self.simnibs_preps is not None and self.simnibs_simu is not None
91        legacy = self.simnibs_output is not None
92        if not split and not legacy:
93            raise ValueError(
94                "Specify either 'simnibs_output' (legacy) OR both "
95                "'simnibs_preps' + 'simnibs_simu'."
96            )
97        return self

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
simnibs_preps: Optional[pathlib.Path] = None

Dossier des résultats charm/segmentation → {sub}/m2m_{sub}/

simnibs_simu: Optional[pathlib.Path] = None

Dossier des résultats de simulation/optimisation → {sub}/simulations/

simnibs_output: Optional[pathlib.Path] = None

Deprecated : utiliser simnibs_preps + simnibs_simu.

results_dir: pathlib.Path = PydanticUndefined

Dossier de sortie : CSVs, figures, statistiques.

mni_template: Optional[pathlib.Path] = None
mni_brain_mask: Optional[pathlib.Path] = None
class PreprocessingConfig(pydantic.main.BaseModel):
100class PreprocessingConfig(BaseModel):
101    smooth_fwhm: float = Field(default=2.0, ge=0)
102    outlier_method: Literal["iqr", "zscore"] = "iqr"
103    portion: Optional[float] = Field(default=None, gt=0, le=1)

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
smooth_fwhm: float = 2.0
outlier_method: Literal['iqr', 'zscore'] = 'iqr'
portion: Optional[float] = None
class FeatureExtractionConfig(pydantic.main.BaseModel):
106class FeatureExtractionConfig(BaseModel):
107    metrics: list[str] = ["mean", "median", "std", "min", "max"]

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
metrics: list[str] = ['mean', 'median', 'std', 'min', 'max']
class ClusteringConfig(pydantic.main.BaseModel):
110class ClusteringConfig(BaseModel):
111    method: str = "mean"
112    specificity_threshold: float = Field(default=1.5, gt=0)
113    intensity_col: str = "mean"

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
method: str = 'mean'
specificity_threshold: float = 1.5
intensity_col: str = 'mean'
class AnalysisConfig(pydantic.main.BaseModel):
116class AnalysisConfig(BaseModel):
117    metric: str = "mean"
118    subject_col: str = "subject"
119    condition_col: str = "condition"
120    clustering: ClusteringConfig = ClusteringConfig()

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
metric: str = 'mean'
subject_col: str = 'subject'
condition_col: str = 'condition'
clustering: ClusteringConfig = ClusteringConfig(method='mean', specificity_threshold=1.5, intensity_col='mean')
class RunningConfig(pydantic.main.BaseModel):
123class RunningConfig(BaseModel):
124    if_exists: Literal["skip", "overwrite", "error"] = "skip"

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
if_exists: Literal['skip', 'overwrite', 'error'] = 'skip'
class PipelineConfig(pydantic.main.BaseModel):
132class PipelineConfig(BaseModel):
133    subjects: list[str]
134    stim_conditions: list[str]
135    mode: list[Literal["simulation", "optimization"]]
136    space: Literal["mni", "native"] = "mni"
137    running: RunningConfig = RunningConfig()
138    target_generation: TargetGenerationConfig
139    paths: PathsConfig
140    preprocessing: PreprocessingConfig = PreprocessingConfig()
141    feature_extraction: FeatureExtractionConfig = FeatureExtractionConfig()
142    analysis: AnalysisConfig = AnalysisConfig()
143
144    @model_validator(mode="after")
145    def _stim_conditions_match_rois(self) -> "PipelineConfig":
146        """Every stim_condition must have a matching ROI key (used to find the mask file)."""
147        roi_names = set(self.target_generation.rois)
148        missing = [c for c in self.stim_conditions if c not in roi_names]
149        if missing:
150            raise ValueError(
151                f"stim_conditions {missing} have no matching entry in target_generation.rois. "
152                f"Available ROI keys: {sorted(roi_names)}"
153            )
154        return self

!!! abstract "Usage Documentation" Models

A base class for creating Pydantic models.

Attributes: __class_vars__: The names of the class variables defined on the model. __private_attributes__: Metadata about the private attributes of the model. __signature__: The synthesized __init__ [Signature][inspect.Signature] of the model.

__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__: The core schema of the model.
__pydantic_custom_init__: Whether the model has a custom `__init__` function.
__pydantic_decorators__: Metadata containing the decorators defined on the model.
    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
__pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
    and the `parameter` item maps to the `__parameter__` attribute of generic classes.
__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__: The name of the post-init method for the model, if defined.
__pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
__pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
__pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

__pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

__pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
    is set to `'allow'`.
__pydantic_fields_set__: The names of fields explicitly set during instantiation.
__pydantic_private__: Values of private attributes set on the model instance.
subjects: list[str] = PydanticUndefined
stim_conditions: list[str] = PydanticUndefined
mode: list[typing.Literal['simulation', 'optimization']] = PydanticUndefined
space: Literal['mni', 'native'] = 'mni'
running: RunningConfig = RunningConfig(if_exists='skip')
target_generation: TargetGenerationConfig = PydanticUndefined
paths: PathsConfig = PydanticUndefined
preprocessing: PreprocessingConfig = PreprocessingConfig(smooth_fwhm=2.0, outlier_method='iqr', portion=None)
feature_extraction: FeatureExtractionConfig = FeatureExtractionConfig(metrics=['mean', 'median', 'std', 'min', 'max'])
analysis: AnalysisConfig = AnalysisConfig(metric='mean', subject_col='subject', condition_col='condition', clustering=ClusteringConfig(method='mean', specificity_threshold=1.5, intensity_col='mean'))
def load_and_validate(config_path: pathlib.Path) -> PipelineConfig:
162def load_and_validate(config_path: Path) -> PipelineConfig:
163    """Load a YAML config file and return a validated PipelineConfig."""
164    import yaml
165
166    with open(config_path) as f:
167        raw = yaml.safe_load(f)
168    return PipelineConfig.model_validate(raw)

Load a YAML config file and return a validated PipelineConfig.