schrodinger.application.transforms.alpareto module¶
Active learning with Pareto selection for multi-objective molecule selection.
Combines ML model training (TrainModel/PredictProperties) with
Pareto ranking (ParetoRank) for iterative, multi-objective molecule
selection. Each cycle scores a batch of molecules, trains an ML model on
all scored data, uses predictions + Pareto ranking to select the next
batch, and repeats.
- class schrodinger.application.transforms.alpareto.ObjectivePropertyConfig(*, prefer_smaller_values: bool = True)¶
Bases:
BaseModelPer-property optimization metadata.
- Parameters:
prefer_smaller_values – Whether smaller values are better for this property. Used by Pareto ranking to orient objectives.
- prefer_smaller_values: bool¶
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- class schrodinger.application.transforms.alpareto.ScoringStage¶
Bases:
StrEnumWhen in the pipeline a scorer runs.
- PRE_AL = 'pre_active_learning'¶
- AL = 'active_learning'¶
- POST_AL = 'post_active_learning'¶
- class schrodinger.application.transforms.alpareto.GenMLConfig(*, mode: Literal['once', 'every_cycle'], train_prior: TrainPriorConfig = TrainPriorConfig(num_epoch_smiles=2000000, batch_size=128), generate_from_prior: GenerateFromPriorConfig = GenerateFromPriorConfig(profile={}, required_smarts=[], cpu_hours=20, n_steps=200, n_compounds=20000, config_override={}), rdesign_config_path: Optional[Path] = None)¶
Bases:
BaseModelConfiguration for generative ML in the AL loop.
- Parameters:
mode – When to generate molecules —
'once'(after cycle 0 only) or'every_cycle'.train_prior – Configuration for prior training.
generate_from_prior – Configuration for molecule generation.
rdesign_config_path – Optional path to an rdesign config YAML for post-processing generated molecules.
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- mode: Literal['once', 'every_cycle']¶
- train_prior: TrainPriorConfig¶
- generate_from_prior: GenerateFromPriorConfig¶
- rdesign_config_path: Optional[Path]¶
- class schrodinger.application.transforms.alpareto.ScorerSpec(*, scorer_id: str, stage: ~schrodinger.application.transforms.alpareto.ScoringStage = ScoringStage.AL, config: dict[str, typing.Any] = <factory>, objectives: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], schrodinger.application.transforms.alpareto.ObjectivePropertyConfig] = <factory>, filter_ranges: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], typing.Annotated[tuple[int | float, int | float], AfterValidator(func=<function _range_validator at 0x77a3d50acb80>)]] = <factory>)¶
Bases:
BaseModelSpecification for a single scoring endpoint.
Co-locates scorer identity, configuration, the objective properties used for Pareto ranking, and optional filter ranges.
- Parameters:
scorer_id – Scorer identifier from
SCORER_REGISTRY.stage – When in the pipeline this scorer runs.
active_learning(default) scores the selected batch each cycle,pre_active_learningscores the full pool upfront,post_active_learningre-scores the post-active-learning selection at higher fidelity.config – Scorer-specific configuration passed to the scorer.
objectives – Map of property names to optimization metadata for Pareto ranking. Keys must be valid
r_ori_prefixed property names that the scorer’sgetProperties()returns.filter_ranges – Map of property names to allowed ranges for filtering. Keys must be valid property names from the scorer.
- scorer_id: str¶
- stage: ScoringStage¶
- config: dict[str, Any]¶
- objectives: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], schrodinger.application.transforms.alpareto.ObjectivePropertyConfig]¶
- filter_ranges: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], typing.Annotated[tuple[int | float, int | float], AfterValidator(func=<function _range_validator at 0x77a3d50acb80>)]]¶
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- validate_spec() ScorerSpec¶
Validate the scorer spec.
At least one of
objectivesorfilter_rangesmust be set.The scorer must exist in
SCORER_REGISTRY.All declared property names must be available from the scorer.
- class schrodinger.application.transforms.alpareto.PreprocessorSpec(*, id: str, before: list[str], config: dict[str, typing.Any] = <factory>)¶
Bases:
BaseModelSpecification for a single preprocessor.
A preprocessor is a transform that runs before its dependent scorers. It may run a side effect (e.g. force-field parameterization) or modify the structures it passes downstream; either way its dependent scorers are gated on its completion. It runs once before each stage and, in
active_learning, before every round, on the batch about to be scored.- Parameters:
id – Preprocessor identifier from
PREPROCESSOR_REGISTRY.before – Scorer ids this preprocessor must precede. The preprocessor runs whenever any of these scorers is scheduled.
config – Preprocessor-specific configuration.
- id: str¶
- before: list[str]¶
- config: dict[str, Any]¶
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- validate_spec() PreprocessorSpec¶
Validate the preprocessor id and that its config constructs.
- class schrodinger.application.transforms.alpareto.ParetoActiveLearningConfig(*, preprocessors: list[schrodinger.application.transforms.alpareto.PreprocessorSpec] = <factory>, scorers: list[schrodinger.application.transforms.alpareto.ScorerSpec], num_cycles: int = 3, sample_size: int = 100, train_time_hr: float = 1.0, frac_train: float = 0.9, seed: int | None = None, post_al_filters: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], typing.Annotated[tuple[int | float, int | float], AfterValidator(func=<function _range_validator at 0x77a3d50acb80>)]] | None = None, post_al_select_size: ~typing.Optional[int] = None, final_select_size: ~typing.Optional[int] = None, genml: schrodinger.application.transforms.alpareto.GenMLConfig | None = None)¶
Bases:
BaseModelConfiguration for
ParetoActiveLearning.- Parameters:
preprocessors – List of preprocessor specifications. Each runs before its dependent scorers (declared via
before).scorers – List of scorer specifications, each with its own objectives and
stage.num_cycles – Number of active learning cycles to run. Defaults to 3.
sample_size – Structures to select per round. Defaults to 100.
train_time_hr – Training time limit in hours. Defaults to 1.0.
frac_train – Fraction for training vs holdout. Defaults to 0.9.
seed – Random seed for initial sample. Defaults to None.
post_al_filters – Optional property-to-range filters applied after all active learning cycles complete. Independent of re-ranking. Defaults to None.
post_al_select_size – If set, Pareto re-rank all scored structures after active learning and select this many for
post_active_learningrescoring. Defaults to None.final_select_size – If set, apply a final Pareto re-rank and select this many structures as the pipeline output. Defaults to None.
genml – Optional generative ML configuration. When set, molecules are generated and merged into the remaining pool during active learning cycles.
- preprocessors: list[PreprocessorSpec]¶
- scorers: list[ScorerSpec]¶
- num_cycles: int¶
- sample_size: int¶
- train_time_hr: float¶
- frac_train: float¶
- seed: int | None¶
- post_al_filters: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], typing.Annotated[tuple[int | float, int | float], AfterValidator(func=<function _range_validator at 0x77a3d50acb80>)]] | None¶
- post_al_select_size: Optional[int]¶
- final_select_size: Optional[int]¶
- genml: GenMLConfig | None¶
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- classmethod validate_scorers_nonempty(v)¶
Validate that at least one scorer is specified.
- validate_properties() ParetoActiveLearningConfig¶
Validate property declarations across scorers.
Duplicate objectives within the same stage are rejected.
Cross-stage objective duplicates are allowed only if they declare identical
ObjectivePropertyConfig.POST_AL objectives must be a subset of earlier stages.
At least one objective must be declared across all scorers.
post_al_filterskeys must be declared by some scorer.
- classmethod fromYaml(path: str) ParetoActiveLearningConfig¶
Load a configuration from a YAML file.
- Parameters:
path – Path to the YAML configuration file.
- Returns:
Parsed
ParetoActiveLearningConfiginstance.
- scorers_for(stage: ScoringStage) list[ScorerSpec]¶
Scorers matching the given
stage.
- preprocessors_for(scorer_specs: list[ScorerSpec]) list[PreprocessorSpec]¶
Preprocessors that must precede any of the given scorers.
Returned in configuration order, which is the order they run in.
- objective_properties_for(stage: ScoringStage) set[str]¶
Objective property names for scorers matching the given
stage.
- property objectives: dict[str, ObjectivePropertyConfig]¶
All objectives across all scorers.
Cross-stage duplicates are guaranteed identical by validation, so the merge order does not matter.
- property properties: set[str]¶
All declared property names (objectives + filter_ranges).
- class schrodinger.application.transforms.alpareto.ParetoSelectConfig(*, objectives: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], schrodinger.application.transforms.alpareto.ObjectivePropertyConfig], select_size: int)¶
Bases:
BaseModelConfiguration for
ParetoSelect.- Parameters:
objectives – Map of property names to optimization metadata.
select_size – Number of top structures to select after ranking.
- objectives: dict[typing.Annotated[str, AfterValidator(func=<function _number_property_validator at 0x77a3d50accc0>)], schrodinger.application.transforms.alpareto.ObjectivePropertyConfig]¶
- select_size: int¶
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [
ConfigDict][pydantic.config.ConfigDict].
- class schrodinger.application.transforms.alpareto.ParetoSelect(**kwargs)¶
Bases:
PTransformWithConfigPareto-rank structures and select the top N.
Ranks by Pareto front with deterministic within-front ordering and selects the top
select_sizestructures.Returns a
(picked, notpicked)tuple ofStructurePCollections.- config_class¶
alias of
ParetoSelectConfig
- class schrodinger.application.transforms.alpareto.ScoreAndFilter(scorer_specs: list[ScorerSpec])¶
Bases:
PTransformScore all structures with the given scorers, applying property filters.
For each scorer spec, runs the scorer on all input structures, then drops structures whose property values fall outside the spec’s
filter_ranges. Scorers are applied sequentially, so earlier scorers can reduce the pool for later ones.- Parameters:
scorer_specs – Scorer specifications to run.
- __init__(scorer_specs: list[ScorerSpec])¶
- class schrodinger.application.transforms.alpareto.Preprocess(preprocessor_specs: list[PreprocessorSpec])¶
Bases:
PTransformRun the given preprocessors on the input structures, in the order the specs are given.
Each preprocessor either runs a side effect or modifies the structures it passes downstream, with the next preprocessor (and the downstream scorers) gated on its completion. With no specs, the structures pass through unchanged.
- Parameters:
preprocessor_specs – Preprocessor specifications to run.
- __init__(preprocessor_specs: list[PreprocessorSpec])¶
- class schrodinger.application.transforms.alpareto.ParetoActiveLearning(genml_post_process: apache_beam.transforms.ptransform.PTransform | None = None, **kwargs)¶
Bases:
PTransformWithConfigActive learning pipeline with Pareto-based selection.
Iteratively selects molecules for scoring using a multi-objective Pareto strategy. Round 0 uses random selection; subsequent rounds train an ML model on all scored data and use Pareto ranking of predicted properties to select the next batch.
When
genmlis configured, a generative prior is trained on the input molecules before the AL loop. During configured cycles, novel molecules are generated and merged into the remaining pool.- Parameters:
genml_post_process – Optional
PTransformapplied to generated molecules (e.g., rdesign’sStrictFilterCascade). Passed through toMoleculeGeneratoraspost_process.
- config_class¶
alias of
ParetoActiveLearningConfig
- __init__(genml_post_process: apache_beam.transforms.ptransform.PTransform | None = None, **kwargs)¶
Initialize the transform with configuration.
All keyword arguments are passed to the config_class constructor to create a validated configuration instance stored as self.config.
- Parameters:
kwargs – Configuration parameters for the config_class
- Raises:
AttributeError – If config_class is not defined on the subclass
ValidationError – If the configuration parameters are invalid