Reference / API reference / dorothy / dorothy.config / dorothy.config.schema
dorothy.config.schema¶
Pydantic configuration schemas for DOROTHY experiments.
This module defines the configuration structure for all aspects of a DOROTHY experiment, including data loading, model architecture, training parameters, and optional masking strategies.
All configurations use Pydantic v2 for validation and serialization.
Functions
|
Return the first |
|
Return a plot label for a parameter name. |
Classes
|
Supported activation function types. |
|
How to combine multi-survey embeddings. |
|
Configuration for data loading and preprocessing. |
|
Top-level configuration for a DOROTHY experiment. |
|
Configuration for dynamic input (spectrum) masking during training. |
|
Configuration for dynamic label masking during training. |
|
Supported loss function types. |
|
Configuration for the neural network architecture. |
|
Configuration for multi-head MLP architecture. |
|
Supported normalization layer types. |
|
Configuration for optimizers. |
|
Supported optimizer types. |
|
Configuration for learning rate schedulers. |
|
Supported learning rate scheduler types. |
|
Configuration for the training process. |
- class dorothy.config.schema.NormalizationType(*values)[source]¶
Bases:
str,EnumSupported normalization layer types.
- class dorothy.config.schema.ActivationType(*values)[source]¶
Bases:
str,EnumSupported activation function types.
- class dorothy.config.schema.LossType(*values)[source]¶
Bases:
str,EnumSupported loss function types.
- class dorothy.config.schema.OptimizerType(*values)[source]¶
Bases:
str,EnumSupported optimizer types.
- class dorothy.config.schema.SchedulerType(*values)[source]¶
Bases:
str,EnumSupported learning rate scheduler types.
- dorothy.config.schema.default_parameter_names(n_parameters)[source]¶
Return the first
n_parametersstandard names, thenparam_<i>.- Parameters:
n_parameters (int) – Number of model output parameters.
- Returns:
List of
n_parametersparameter names.- Return type:
list[str]
- dorothy.config.schema.parameter_display_name(name)[source]¶
Return a plot label for a parameter name.
Abundance names of the form
x_h/x_febecome[X/H]/[X/Fe](e.g.mg_fe->[Mg/Fe],fe_h->[Fe/H]). Unrecognized names are returned unchanged.- Parameters:
name (str) – Parameter name as stored in the catalogue.
- Returns:
Human-readable (matplotlib mathtext) label.
- Return type:
str
- class dorothy.config.schema.DataConfig(*, catalogue_path, surveys=['boss'], label_sources=['apogee'], train_ratio=0.7, val_ratio=0.2, max_flag_bits=0, duplicate_labels=None, use_dense_loading=False, parameter_names=None, normalize_spectra=True, precision_encoding=True)[source]¶
Bases:
_ConfigModelConfiguration for data loading and preprocessing.
Loads data from the super-catalogue HDF5 file which contains multiple surveys with cross-matched labels from APOGEE and/or GALAH.
Fields¶ Name
Type
Default
Description
catalogue_pathPathrequired
Path to HDF5 super-catalogue
surveyslist['boss']List of input surveys to load (e.g., [‘boss’, ‘lamost_lrs’]). Several surveys give a merged dataset (outer join).
label_sourceslist['apogee']List of label sources for training targets (e.g., [‘apogee’, ‘galah’])
train_ratiofloat0.7Training data fraction
val_ratiofloat0.2Validation data fraction
max_flag_bitsint0Maximum allowed flag bits (0=highest quality, -1=allow all with per-param masking)
duplicate_labelsdict[str, str] | NoneNoneMap target label source to source, to test multi-labelset training when a label source does not exist (e.g., {‘galah’: ‘apogee’} copies the APOGEE labels as GALAH labels)
use_dense_loadingboolFalseWith several label sources, store spectra as dense arrays instead of sparse storage (more memory). No effect with one label source.
parameter_nameslist[str] | NoneNoneLabel parameter names in catalogue order. dorothy train fills them from the catalogue; when None, the first n STELLAR_PARAMETERS (n from the model section) are used, then param_<i>.
normalize_spectraboolTruePer-spectrum median/IQR flux normalization, with ivar rescaled to match. Training and inference must agree; the checkpoint config stores it.
precision_encodingboolTrueReplace the sigma channel of the model inputs with log(1 + 1/sigma) at valid pixels and 0 at masked pixels, after normalization (encode_precision). False keeps sigma and exists only to load checkpoints trained with it; training rejects it.
- property test_ratio: float¶
Compute test ratio from train and validation ratios.
- property is_multi_survey: bool¶
Whether loading from multiple input surveys.
- property is_multi_label: bool¶
Whether training with multiple label sources.
- classmethod accept_singular_keys(values)[source]¶
Accept
survey/label_sourceas aliases of the list fields.A string becomes a one-element list.
- Raises:
ValueError – If a singular key and its plural are both given.
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.ModelConfig(*, hidden_layers=[5000, 2000, 1000, 500, 200, 100], normalization=NormalizationType.LAYERNORM, activation=ActivationType.GELU, dropout=0.0, input_features=15300, output_features=22, label_aware_uncertainty=True)[source]¶
Bases:
_ConfigModelConfiguration for the neural network architecture.
The default architecture follows the standard DOROTHY MLP: input_features -> 5000 -> 2000 -> 1000 -> 500 -> 200 -> 100 -> output_features (15300 and 22 by default).
Fields¶ Name
Type
Default
Description
hidden_layerslist[5000, 2000, 1000, 500, 200, 100]Hidden layer sizes
normalizationNormalizationType<NormalizationType.LAYERNORM: 'layernorm'>Normalization layer type
activationActivationType<ActivationType.GELU: 'gelu'>Activation function
dropoutfloat0.0Dropout probability
input_featuresint15300Number of input features (channels * wavelength_bins)
output_featuresint22Number of outputs (n_params * 2 for mean + uncertainty)
label_aware_uncertaintyboolTruePredict ln s with an error decoder, parallel to the label decoder, from the head’s input and the reported label errors, or a learned missing vector, so that s includes the label noise (see LabelAwareOutput). False builds the output layers of checkpoints trained without it and exists only to load them; training rejects it.
Ensure all hidden layer sizes are positive.
- property n_parameters: int¶
Number of stellar parameters being predicted.
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.CombinationMode(*values)[source]¶
Bases:
str,EnumHow to combine multi-survey embeddings.
- class dorothy.config.schema.MultiHeadModelConfig(*, survey_wavelengths, n_parameters=11, latent_dim=256, encoder_hidden=[1024, 512], trunk_hidden=[512, 256], output_hidden=[64], combination_mode=CombinationMode.CONCAT, label_sources=None, normalization=NormalizationType.LAYERNORM, activation=ActivationType.GELU, dropout=0.0, head_dropout=<factory>, label_aware_uncertainty=True, residual_stream=True)[source]¶
Bases:
_ConfigModelConfiguration for multi-head MLP architecture.
Used when training on multiple surveys with different wavelength grids. Each survey has its own encoder, feeding into a shared trunk. Optionally supports multiple output heads for different label sources.
Examples
>>> config = MultiHeadModelConfig( ... survey_wavelengths={"boss": 4506, "lamost_lrs": 3700}, ... n_parameters=11, ... latent_dim=256, ... label_sources=["apogee", "galah"], # Multi-output heads ... )
Fields¶ Name
Type
Default
Description
survey_wavelengthsdictrequired
Dict mapping survey names to wavelength bin counts
n_parametersint11Number of stellar parameters to predict
latent_dimint256Output dimension of each survey encoder
encoder_hiddenlist[1024, 512]Hidden layer sizes for survey encoders
trunk_hiddenlist[512, 256]Hidden layer sizes for shared trunk
output_hiddenlist[64]Hidden layer sizes of each output head’s label and error decoders
combination_modeCombinationMode<CombinationMode.CONCAT: 'concat'>How to combine multi-survey embeddings
label_sourceslist[str] | NoneNoneLabel sources of the output heads, one head each (e.g., [‘apogee’, ‘galah’]). None or an empty list gives one head, named after the first of data.label_sources.
normalizationNormalizationType<NormalizationType.LAYERNORM: 'layernorm'>Normalization layer type
activationActivationType<ActivationType.GELU: 'gelu'>Activation function
dropoutfloat0.0Dropout probability
head_dropoutdict{}Output head dropout per label source, e.g. {“galah”: 0.2}; sources not listed use dropout
label_aware_uncertaintyboolTruePredict ln s with an error decoder, parallel to the label decoder, from the head’s input and the reported label errors, or a learned missing vector, so that s includes the label noise (see LabelAwareOutput). False builds the output layers of checkpoints trained without it and exists only to load them; training rejects it.
residual_streamboolTrueBuild the trunk and the output heads’ hidden layers as a residual stream of width latent_dim, with one residual block per trunk_hidden and output_hidden size; False builds plain blocks. Checkpoints saved before this option load with False.
- property is_multi_label: bool¶
Whether using multiple output heads for different label sources.
- property output_features: int¶
Number of output features (2 * n_parameters).
- property survey_names: list[str]¶
List of survey names.
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.SchedulerConfig(*, type=SchedulerType.ONE_CYCLE, base_lr=1e-06, max_lr=0.001, step_size_up=250, step_size_down=650, gamma=0.9995, patience=10, factor=0.5, pct_start=0.3, div_factor=25.0, final_div_factor=10000.0, anneal_strategy='cos')[source]¶
Bases:
_ConfigModelConfiguration for learning rate schedulers.
Fields¶ Name
Type
Default
Description
typeSchedulerType<SchedulerType.ONE_CYCLE: 'one_cycle'>Scheduler type
base_lrfloat1e-06Minimum learning rate (cyclic)
max_lrfloat0.001Learning rate: the peak of one_cycle and cyclic, the initial rate of reduce_on_plateau and cosine_annealing, and the constant rate of none
step_size_upint250Steps to rise from base_lr to max_lr (cyclic)
step_size_downint650Steps to fall from max_lr to base_lr (cyclic)
gammafloat0.9995Multiplicative factor of the exp_range mode (cyclic)
patienceint10Epochs to wait before reducing the LR (reduce_on_plateau)
factorfloat0.5Factor to reduce the LR by (reduce_on_plateau)
pct_startfloat0.3Fraction of the cycle spent increasing the LR (one_cycle)
div_factorfloat25.0Initial LR = max_lr / div_factor (one_cycle)
final_div_factorfloat10000.0Final LR = initial LR / final_div_factor (one_cycle)
anneal_strategyLiteral'cos'Annealing strategy (one_cycle)
- validate_lr_range()[source]¶
Ensure base_lr <= max_lr for the cyclic schedule, the one that uses both.
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.OptimizerConfig(*, type=OptimizerType.ADAMW, weight_decay=0.01, betas=(0.9, 0.999), momentum=0.9, nesterov=False)[source]¶
Bases:
_ConfigModelConfiguration for optimizers.
Fields¶ Name
Type
Default
Description
typeOptimizerType<OptimizerType.ADAMW: 'adamw'>Optimizer type
weight_decayfloat0.01Weight decay of the weight matrices. Biases and normalization weights are not decayed.
betastuple(0.9, 0.999)Coefficients for running averages (Adam/AdamW). The one_cycle scheduler replaces the first: it cycles it between 0.85 and 0.95.
momentumfloat0.9Momentum factor (SGD only). The one_cycle scheduler replaces it: it cycles it between 0.85 and 0.95.
nesterovboolFalseUse Nesterov momentum (SGD only)
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.TrainingConfig(*, epochs=300, batch_size=1024, loss=LossType.HETEROSCEDASTIC, optimizer=<factory>, scheduler=<factory>, gradient_clip=10.0, save_every=0, early_stopping_patience=0, scatter_floor=0.01, nll_warmup_fraction=0.1, label_error_dropout=0.5, calibrate_uncertainties=True, label_source_weighting='per_label', label_source_weights=<factory>, amp=False, amp_dtype='bfloat16', ema_decay=None, ema_cpu_every=None)[source]¶
Bases:
_ConfigModelConfiguration for the training process.
Fields¶ Name
Type
Default
Description
epochsint300Number of epochs
batch_sizeint1024Batch size
lossLossType<LossType.HETEROSCEDASTIC: 'heteroscedastic'>Loss function
optimizerOptimizerConfigOptimizerConfig(type=<OptimizerType.ADAMW: 'adamw'>, weight_decay=0.01, betas=(0.9, 0.999), momentum=0.9, nesterov=False)Optimizer configuration
schedulerSchedulerConfigSchedulerConfig(type=<SchedulerType.ONE_CYCLE: 'one_cycle'>, base_lr=1e-06, max_lr=0.001, step_size_up=250, step_size_down=650, gamma=0.9995, patience=10, factor=0.5, pct_start=0.3, div_factor=25.0, final_div_factor=10000.0, anneal_strategy='cos')LR scheduler
gradient_clipfloat10.0Max gradient norm (0=disabled)
save_everyint0Save a checkpoint every N epochs (0 = only the final one)
early_stopping_patienceint0Epochs without a lower validation loss before training stops, counted after the β-NLL warm-up; 0 turns early stopping off
scatter_floorfloat0.01Minimum scatter floor for heteroscedastic loss
nll_warmup_fractionfloat0.1Fraction of the optimizer steps of the run over which β of the β-NLL loss falls linearly from 1 (mean-squared-error gradients for the means) to 0 (the plain negative log-likelihood); 0 turns this warm-up off. Applies to the heteroscedastic loss only.
label_error_dropoutfloat0.5Fraction of training stars whose label errors are replaced by the learned missing vector, drawn per batch and output head. Validation, evaluation and prediction always use the missing vector, so the fraction must be above 0.
calibrate_uncertaintiesboolTrueAfter training, fit one factor per output head and parameter that scales the predicted scatter so that the validation z-scores of the best epoch have unit robust spread, and save the factors in calibration.json. loss: mse has no scatter, so it saves no factors.
label_source_weightingLiteral'per_label'How the losses of the label sources (output heads) combine, for training and for selecting the best epoch. per_label gives every valid label equal weight; per_source averages each head’s mean loss, so a smaller label source gets as much total weight as a larger one.
label_source_weightsdict{}Relative loss weight per label source, e.g. {“galah”: 0.5}; sources not listed have weight 1.0
ampboolFalseRun the training forward pass in amp_dtype on CUDA. CPU and MPS train in float32.
amp_dtypeLiteral'bfloat16'Precision of the forward pass with amp. bfloat16 needs a GPU with compute capability 8.0 or higher; float16 uses a gradient scaler.
ema_decayfloat | NoneNoneDecay per optimizer step of the exponential moving average of the weights, which validation, the best epoch and the saved weights then use (null: no average)
ema_cpu_everyint | NoneNoneKeep the weight average in CPU memory and update it every this many optimizer steps (null: on the training device, every step)
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.LabelMaskingConfig(*, enabled=False, p_labelset_min=0.3, p_labelset_max=1.0, p_label_min=0.3, p_label_max=1.0)[source]¶
Bases:
_ConfigModelConfiguration for dynamic label masking during training.
Label masking is a training-time augmentation that randomly masks labels to improve model robustness when not all labels are available. This uses a hierarchical scheme:
Labelset level: Which label sources (apogee, galah, etc.) to include
Label level: Which parameters (teff, logg, feh, etc.) within each set
All probabilities are sampled fresh per batch from uniform ranges to ensure the model sees diverse masking conditions during training.
A guaranteed keeper mechanism ensures at least one labelset and one label per labelset are always kept, preventing complete masking.
Fields¶ Name
Type
Default
Description
enabledboolFalseEnable label masking augmentation
p_labelset_minfloat0.3Minimum probability of keeping each labelset (sampled per batch)
p_labelset_maxfloat1.0Maximum probability of keeping each labelset (sampled per batch)
p_label_minfloat0.3Minimum probability of keeping each label within kept labelsets (sampled per batch)
p_label_maxfloat1.0Maximum probability of keeping each label within kept labelsets (sampled per batch)
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.InputMaskingConfig(*, enabled=False, p_survey_min=0.3, p_survey_max=1.0, f_min_override=None, f_max=0.5, p_block_min=0.3, p_block_max=1.0)[source]¶
Bases:
_ConfigModelConfiguration for dynamic input (spectrum) masking during training.
Input masking is a training-time augmentation that randomly masks portions of input spectra to improve model robustness. This uses a hierarchical scheme:
Survey level: Which surveys to include (for multi-survey training)
Block level: Which wavelength blocks within each kept survey
Block sizes are sampled log-uniformly to explore all scales from single pixels up to large spectral regions. All probabilities are sampled fresh per batch from uniform ranges.
A guaranteed keeper mechanism ensures at least one survey and one block per survey are always kept, preventing complete masking.
Fields¶ Name
Type
Default
Description
enabledboolFalseEnable input masking augmentation
p_survey_minfloat0.3Minimum probability of keeping each survey (sampled per batch)
p_survey_maxfloat1.0Maximum probability of keeping each survey (sampled per batch)
f_min_overridefloat | NoneNoneOverride for minimum block size fraction. If None, defaults to 1/N_wavelengths (single pixel).
f_maxfloat0.5Maximum block size as fraction of spectrum
p_block_minfloat0.3Minimum probability of keeping each block (sampled per batch)
p_block_maxfloat1.0Maximum probability of keeping each block (sampled per batch)
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dorothy.config.schema.ExperimentConfig(*, name, description='', data, model=None, multi_head_model=None, training=<factory>, label_masking=<factory>, input_masking=<factory>, output_dir=PosixPath('outputs'), seed=42, device='auto')[source]¶
Bases:
_ConfigModelTop-level configuration for a DOROTHY experiment.
This is the main configuration class that combines all sub-configurations and provides the complete specification for training a model.
For single-survey training, use the
modelconfig (MLP). For multi-survey training, use themulti_head_modelconfig (MultiHeadMLP).Fields¶ Name
Type
Default
Description
namestrrequired
Experiment name
descriptionstr''Experiment description
dataDataConfigrequired
Data configuration
modeldorothy.config.schema.ModelConfig | NoneNoneStandard MLP configuration (single-survey)
multi_head_modeldorothy.config.schema.MultiHeadModelConfig | NoneNoneMulti-head MLP configuration (multi-survey)
trainingTrainingConfigTrainingConfig(epochs=300, batch_size=1024, loss=<LossType.HETEROSCEDASTIC: 'heteroscedastic'>, optimizer=OptimizerConfig(type=<OptimizerType.ADAMW: 'adamw'>, weight_decay=0.01, betas=(0.9, 0.999), momentum=0.9, nesterov=False), scheduler=SchedulerConfig(type=<SchedulerType.ONE_CYCLE: 'one_cycle'>, base_lr=1e-06, max_lr=0.001, step_size_up=250, step_size_down=650, gamma=0.9995, patience=10, factor=0.5, pct_start=0.3, div_factor=25.0, final_div_factor=10000.0, anneal_strategy='cos'), gradient_clip=10.0, save_every=0, early_stopping_patience=0, scatter_floor=0.01, nll_warmup_fraction=0.1, label_error_dropout=0.5, calibrate_uncertainties=True, label_source_weighting='per_label', label_source_weights={}, amp=False, amp_dtype='bfloat16', ema_decay=None, ema_cpu_every=None)Training configuration
label_maskingLabelMaskingConfigLabelMaskingConfig(enabled=False, p_labelset_min=0.3, p_labelset_max=1.0, p_label_min=0.3, p_label_max=1.0)Dynamic label masking configuration
input_maskingInputMaskingConfigInputMaskingConfig(enabled=False, p_survey_min=0.3, p_survey_max=1.0, f_min_override=None, f_max=0.5, p_block_min=0.3, p_block_max=1.0)Dynamic input masking configuration
output_dirPathPosixPath('outputs')Directory for outputs (checkpoints, logs)
seedint42Random seed
deviceLiteral'auto'Compute device (mps for Apple Silicon)
- property is_multi_head: bool¶
Whether using multi-head architecture.
- property parameter_names: list[str]¶
Names of the predicted parameters, in model output order.
Uses
data.parameter_nameswhen set (populated from the catalogue), otherwise the first nSTELLAR_PARAMETERS, followed byparam_<i>for each output beyond that list.
- get_output_path()[source]¶
Get the output directory of this experiment.
- Returns:
output_dir / name.- Return type:
Path
- get_checkpoint_path(epoch=None)[source]¶
Get the directory of a checkpoint.
- Parameters:
epoch (int | None) – Epoch number, or None for the final checkpoint.
- Returns:
<output path>/epoch_<epoch>, or<output path>/<name>_finalwhen epoch is None.- Return type:
Path
- save_yaml(path)[source]¶
Save configuration to a YAML file.
- Parameters:
path (str | Path) – Path to save the YAML file.
- classmethod load_checkpoint_config(path)[source]¶
Load the
config.yamlsaved alongside a trained checkpoint.Unlike
load_yaml(), this accepts the Python-specific tags (e.g. tuples) written bysave_yaml(), and fills in defaults that keep older checkpoints reproducible. A config withoutdata.normalize_spectrawas trained on un-normalized catalogue spectra, so the flag defaults to False, except for configs from thedorothy_updatebranch, recognizable by amulti_head_model.head_dropoutentry or 20 predicted parameters, whose sparse and single-survey loaders already normalized spectra. A warning is issued either way. A model section withoutlabel_aware_uncertainty, a multi-head model section withoutresidual_streamand a data section withoutprecision_encodingget False for that flag. Atraining.learning_ratebecomesscheduler.max_lrfor the schedules it set (none, reduce_on_plateau, cosine_annealing). Amodelsection with several label sources keeps only the first, the one it trained on. Settings this version no longer has are ignored with a warning.- Parameters:
path (str | Path) – Path to the checkpoint’s
config.yaml.- Returns:
ExperimentConfig instance.
- Raises:
pydantic.ValidationError – If the settings are invalid.
- Return type:
- classmethod load_yaml(path)[source]¶
Load configuration from a YAML file.
- Parameters:
path (str | Path) – Path to the YAML file.
- Returns:
ExperimentConfig instance.
- Return type:
- model_config = {'extra': 'forbid'}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].