data_models.features.api

data_models.features.api

Classes

Name Description
CategoricalInput Base class for all categorical input features.
CategoricalOutput
ContinuousInput Base class for all continuous input features.
ContinuousOutput The base class for a continuous output feature
DiscreteInput Feature with discretized ordinal values allowed in the optimization.
Descriptors A rectangular block of per-level descriptor data.
TaskInput Abstract base class for task-encoding inputs.

CategoricalInput

data_models.features.api.CategoricalInput()

Base class for all categorical input features.

A categorical input has one descriptor level per category, so each column of the optional descriptors block holds one value per category, in the same order as categories::

solvent = CategoricalInput(
    key="solvent",
    categories=["water", "ethanol", "thf"],
    descriptors=Descriptors(
        columns={"logP": [-1.4, -0.3, 0.5], "MW": [18.0, 46.0, 72.0]},
        structure=["O", "CCO", "C1CCOC1"],   # one SMILES per category
    ),
)

How those descriptors are turned into model columns is not fixed here: it is chosen per surrogate via categorical_encodings (e.g. OneHotEncoding or a DescriptorEncoding selecting columns and/or running descriptor generators on the structure).

Attributes

Name Type Description
categories List[str] Names of the categories.
allowed List[bool] List of bools indicating if a category is allowed within the optimization.
descriptors Descriptors Per-category descriptor data — numeric columns and/or a SMILES structure column. Defaults to None.
key str, inherited from Feature The unique name of the feature.
context str, optional, inherited from Feature Free-text context for the feature. Defaults to None.

Methods

Name Description
fixed_value Returns the categories to which the feature is fixed, None if the feature is not fixed
from_encoding Back-transform encoded columns to categories with the given encoding.
generate_allowed Generates the list of allowed categories if not provided.
get_allowed_categories Returns the allowed categories.
get_forbidden_categories Returns the non-allowed categories
get_possible_categories Return the superset of categories that have been used in the experimental dataset and
is_fixed Returns True if there is only one allowed category.
is_fulfilled Method to check if the values are all allowed categories.
sample Draw random samples from the feature.
to_encoding Encode a series of categories with the given encoding.
to_pydantic_field Return (Literal[...], Field(description=...)) with allowed categories.
valid_transform_types Valid encoding classes for this feature.
validate_candidental Method to validate the suggested candidates
validate_experimental Method to validate the experimental dataFrame
fixed_value
data_models.features.api.CategoricalInput.fixed_value(transform_type=None)

Returns the categories to which the feature is fixed, None if the feature is not fixed

Returns
Name Type Description
Union[List[str], List[float], None] List[str]: List of categories or None
from_encoding
data_models.features.api.CategoricalInput.from_encoding(encoding, values)

Back-transform encoded columns to categories with the given encoding.

generate_allowed
data_models.features.api.CategoricalInput.generate_allowed(allowed, info)

Generates the list of allowed categories if not provided.

get_allowed_categories
data_models.features.api.CategoricalInput.get_allowed_categories()

Returns the allowed categories.

Returns
Name Type Description
list[str] list of str: The allowed categories
get_forbidden_categories
data_models.features.api.CategoricalInput.get_forbidden_categories()

Returns the non-allowed categories

Returns
Name Type Description
List[str]: List of the non-allowed categories
get_possible_categories
data_models.features.api.CategoricalInput.get_possible_categories(values)

Return the superset of categories that have been used in the experimental dataset and that can be used in the optimization

Parameters
Name Type Description Default
values pd.Series Series with the values for this feature required
Returns
Name Type Description
list list list of possible categories
is_fixed
data_models.features.api.CategoricalInput.is_fixed()

Returns True if there is only one allowed category.

Returns
Name Type Description
bool [bool]: True if there is only one allowed category
is_fulfilled
data_models.features.api.CategoricalInput.is_fulfilled(values)

Method to check if the values are all allowed categories.

Parameters
Name Type Description Default
values pd.Series A series with values for the input feature. required
Returns
Name Type Description
pd.Series A series with boolean values indicating if the input feature is fulfilled.
sample
data_models.features.api.CategoricalInput.sample(n, seed=None)

Draw random samples from the feature.

Parameters
Name Type Description Default
n int number of samples. required
seed int random seed. Defaults to None. None
Returns
Name Type Description
pd.Series pd.Series: drawn samples.
to_encoding
data_models.features.api.CategoricalInput.to_encoding(encoding, values)

Encode a series of categories with the given encoding.

Generic pandas entry point: the encoding object owns the actual transform.

to_pydantic_field
data_models.features.api.CategoricalInput.to_pydantic_field()

Return (Literal[...], Field(description=...)) with allowed categories.

When the number of allowed categories exceeds LLM_ENUM_SCHEMA_THRESHOLD the type falls back to str (the allowed values stay in the description). See the module-level comment on the constant for the reason.

Subclasses customize the output by overriding _description_prefix and/or _extra_description_parts.

Example::

>>> feat = CategoricalInput(key="solvent", categories=["water", "ethanol", "toluene"])
>>> field_type, _ = feat.to_pydantic_field()
>>> # field_type = Literal['water', 'ethanol', 'toluene']
valid_transform_types
data_models.features.api.CategoricalInput.valid_transform_types()

Valid encoding classes for this feature.

One-hot and ordinal are always valid; DescriptorEncoding is valid when the feature carries a descriptor block, since the encoding can read either its numeric columns or its structure.

validate_candidental
data_models.features.api.CategoricalInput.validate_candidental(values)

Method to validate the suggested candidates

Parameters
Name Type Description Default
values pd.Series A dataFrame with candidates required
Raises
Name Type Description
ValueError when not all values for a feature are one of the allowed categories
Returns
Name Type Description
pd.Series pd.Series: The passed dataFrame with candidates
validate_experimental
data_models.features.api.CategoricalInput.validate_experimental(
    values,
    strict=False,
)

Method to validate the experimental dataFrame

Parameters
Name Type Description Default
values pd.Series A dataFrame with experiments required
strict bool Boolean to distinguish if the occurrence of fixed features in the dataset should be considered or not. Defaults to False. False
Raises
Name Type Description
ValueError when an entry is not in the list of allowed categories
ValueError when there is no variation in a feature provided by the experimental data
Returns
Name Type Description
pd.Series pd.Series: A dataFrame with experiments

CategoricalOutput

data_models.features.api.CategoricalOutput()

Methods

Name Description
validate_objective_categories Validates that objective categories match the output categories
validate_objective_categories
data_models.features.api.CategoricalOutput.validate_objective_categories()

Validates that objective categories match the output categories

Raises
Name Type Description
ValueError when categories do not match objective categories
Returns
Name Type Description
self

ContinuousInput

data_models.features.api.ContinuousInput()

Base class for all continuous input features.

A continuous input is a single descriptor component: it has exactly one descriptor level (the feature itself), so each column of the optional descriptors block holds exactly one value. This is what lets a continuous feature act as one component of a mixture, blended by a WeightedSumFeature — on its own the block has no effect on the feature’s own encoding::

ethanol = ContinuousInput(
    key="ethanol",
    bounds=(0, 1),
    descriptors=Descriptors(
        columns={"logP": [-0.3], "MW": [46.0]},   # one value per column
        structure=["CCO"],                        # one SMILES
    ),
)

Attributes

Name Type Description
bounds Tuple[float, float] A tuple that stores the lower and upper bound of the feature.
stepsize PositiveFloat Float indicating the allowed stepsize between lower and upper. Defaults to None.
local_relative_bounds Tuple[float, float] A tuple that stores the lower and upper bounds relative to a reference value. Defaults to None.
allow_zero bool A boolean indicating if the input feature can take inactive values. Useful for features that take values between bounds, but can also take a value of 0. One may choose to use a conditional kernel for this, if taking a value of 0 represents a distinct behaviour from non-zero values.
descriptors Descriptors Descriptor data for the single component — numeric columns holding one value each, and/or a one-element SMILES structure. Consumed by N-arity engineered features, not by this feature’s own encoding. Defaults to None.
unit str, optional, inherited from NumericalInput The unit of the feature. Defaults to None.
key str, inherited from Feature The unique name of the feature.
context str, optional, inherited from Feature Free-text context for the feature. Defaults to None.

Methods

Name Description
is_fulfilled Method to check if the values are within the bounds of the feature.
round Round values to the stepsize of the feature. If no stepsize is provided return the
sample Draw random samples from the feature.
to_pydantic_field Return ``(float, Field(ge=…, le=…, description=…))```.
validate_candidental Method to validate the suggested candidates
is_fulfilled
data_models.features.api.ContinuousInput.is_fulfilled(values, noise=1e-05)

Method to check if the values are within the bounds of the feature.

Parameters
Name Type Description Default
values pd.Series A series with values for the input feature. required
noise float A small value to allow for numerical errors. Defaults to 10e-6. 1e-05
Returns
Name Type Description
pd.Series A series with boolean values indicating if the input feature is fulfilled.
round
data_models.features.api.ContinuousInput.round(values)

Round values to the stepsize of the feature. If no stepsize is provided return the provided values.

Parameters
Name Type Description Default
values pd.Series The values that should be rounded. required
Returns
Name Type Description
pd.Series pd.Series: The rounded values
sample
data_models.features.api.ContinuousInput.sample(n, seed=None)

Draw random samples from the feature.

Parameters
Name Type Description Default
n int number of samples. required
seed int random seed. Defaults to None. None
Returns
Name Type Description
pd.Series pd.Series: drawn samples.
to_pydantic_field
data_models.features.api.ContinuousInput.to_pydantic_field()

Return ``(float, Field(ge=…, le=…, description=…))```.

Subclasses customize the output by overriding _description_prefix and/or _extra_description_parts.

Example::

>>> feat = ContinuousInput(key="temp", bounds=(20.0, 200.0), context="Temperature in C")
>>> field_type, field_info = feat.to_pydantic_field()
>>> # field_type = float
>>> # field_info has ge=20.0, le=200.0
>>> # description = "Continuous, bounds [20.0, 200.0] — Temperature in C"
validate_candidental
data_models.features.api.ContinuousInput.validate_candidental(values)

Method to validate the suggested candidates

Parameters
Name Type Description Default
values pd.Series A dataFrame with candidates required
Raises
Name Type Description
ValueError when non numerical values are passed
ValueError when values are larger than the upper bound of the feature
ValueError when values are lower than the lower bound of the feature
Returns
Name Type Description
pd.Series pd.Series: The passed dataFrame with candidates

ContinuousOutput

data_models.features.api.ContinuousOutput()

The base class for a continuous output feature

Attributes

Name Type Description
objective objective objective of the feature indicating in which direction it should be optimized. Defaults to MaximizeObjective.

Methods

Name Description
to_description Return a human-readable description combining objective and context.
to_description
data_models.features.api.ContinuousOutput.to_description()

Return a human-readable description combining objective and context.

Example::

>>> feat = ContinuousOutput(key="yield", objective=MaximizeObjective(w=1.0), context="Target >90%")
>>> feat.to_description()
'yield: Maximize — Target >90%'

DiscreteInput

data_models.features.api.DiscreteInput()

Feature with discretized ordinal values allowed in the optimization.

Like ContinuousInput, a discrete input is a single descriptor component: the allowed values are not descriptor levels, so each descriptors column and the structure column hold exactly one value (a restricted amount of a substance still describes one substance).

Attributes

Name Type Description
key(str) key of the feature.
values(List[float]) the discretized allowed values during the optimization.
descriptors Descriptors Descriptor data for the single component — numeric columns holding one value each, and/or a one-element SMILES structure. Defaults to None.
unit str, optional, inherited from NumericalInput The unit of the feature. Defaults to None.
context str, optional, inherited from Feature Free-text context for the feature. Defaults to None.

Methods

Name Description
from_continuous Rounds continuous values to the closest discrete ones.
is_fulfilled Method to check if the values are close to the discrete values.
sample Draw random samples from the feature.
to_pydantic_field Return (Literal[...], Field(description=...)) with allowed values.
validate_candidental Method to validate the provided candidates.
validate_values_unique Validates that provided values are unique.
from_continuous
data_models.features.api.DiscreteInput.from_continuous(values)

Rounds continuous values to the closest discrete ones.

Parameters
Name Type Description Default
values pd.DataFrame Dataframe with continuous entries. required
Returns
Name Type Description
pd.Series pd.Series: Series with discrete values.
is_fulfilled
data_models.features.api.DiscreteInput.is_fulfilled(values)

Method to check if the values are close to the discrete values.

Parameters
Name Type Description Default
values pd.Series A series with values for the input feature. required
Returns
Name Type Description
pd.Series A series with boolean values indicating if the input feature is fulfilled.
sample
data_models.features.api.DiscreteInput.sample(n, seed=None)

Draw random samples from the feature.

Parameters
Name Type Description Default
n int number of samples. required
seed int random seed. Defaults to None. None
Returns
Name Type Description
pd.Series pd.Series: drawn samples.
to_pydantic_field
data_models.features.api.DiscreteInput.to_pydantic_field()

Return (Literal[...], Field(description=...)) with allowed values.

Subclasses customize the output by overriding _description_prefix and/or _extra_description_parts.

Example::

>>> feat = DiscreteInput(key="n_steps", values=[1.0, 2.0, 5.0])
>>> field_type, _ = feat.to_pydantic_field()
>>> # field_type = Literal[1.0, 2.0, 5.0]
validate_candidental
data_models.features.api.DiscreteInput.validate_candidental(values)

Method to validate the provided candidates.

Parameters
Name Type Description Default
values pd.Series suggested candidates for the feature required
Raises
Name Type Description
ValueError Raises error when one of the provided values is not contained in the list of allowed values.
Returns
Name Type Description
pd.Series pd.Series: suggested candidates for the feature
validate_values_unique
data_models.features.api.DiscreteInput.validate_values_unique(values)

Validates that provided values are unique.

Parameters
Name Type Description Default
values List[float] List of values required
Raises
Name Type Description
ValueError when values are non-unique.
ValueError when values contains only one entry.
ValueError when values is empty.
Returns
Name Type Description
List[values]: Sorted list of values

Descriptors

data_models.features.api.Descriptors()

A rectangular block of per-level descriptor data.

A “level” is a row of the block. What the levels are depends on the feature the block is attached to, and is the feature’s business, not this class’s:

CategoricalInputone level per category, so the block picks the row of the chosen category (select-row)::

CategoricalInput(
    key="solvent",
    categories=["water", "ethanol", "thf"],
    descriptors=Descriptors(
        columns={"logP": [-1.4, -0.3, 0.5], "MW": [18.0, 46.0, 72.0]},
        structure=["O", "CCO", "C1CCOC1"],
    ),
)

ContinuousInput / DiscreteInputa single level, the feature itself. It is one component of a mixture whose amount weights its row, so each column holds one value. For a discrete input the allowed values are not levels: a restricted amount of a substance still describes one substance::

ContinuousInput(
    key="ethanol",
    bounds=(0, 1),
    descriptors=Descriptors(columns={"logP": [-0.3]}, structure=["CCO"]),
)

Attributes

Name Type Description
columns Dict[str, List[float]] Numeric property columns, each with one value per level.
structure Optional[List[str]] Optional structure identifiers (SMILES), one per level.

Methods

Name Description
concat Stack blocks row-wise into a single block.
table Per-level table (rows = index, columns = columns or all of them).
validate_fit Check that this block describes exactly levels.
validate_rectangular Every column and the structure must describe the same levels.
concat
data_models.features.api.Descriptors.concat(blocks)

Stack blocks row-wise into a single block.

Used to turn the one-row blocks of the components of a mixture into one block the weighted sum can read, so that both descriptor scopes end up as “a block plus an index”. The blocks must describe the same thing: same column names and either all or none carrying a structure.

Column order follows the first block, which keeps static columns ahead of generated ones — :func:filter_correlated keeps the first of each correlated group, so the order is load-bearing.

table
data_models.features.api.Descriptors.table(index, columns=None)

Per-level table (rows = index, columns = columns or all of them).

validate_fit
data_models.features.api.Descriptors.validate_fit(levels)

Check that this block describes exactly levels.

The block itself only guarantees internal consistency; how many levels there should be is the feature’s business, so the feature calls this from its own model validator.

Parameters
Name Type Description Default
levels List The levels the feature carrying this block declares. required
Raises
Name Type Description
ValueError If the block describes a different number of levels.
validate_rectangular
data_models.features.api.Descriptors.validate_rectangular()

Every column and the structure must describe the same levels.

TaskInput

data_models.features.api.TaskInput()

Abstract base class for task-encoding inputs.

This class is not directly instantiable and is not part of any AnyFeature/AnyInput union. Use :class:CategoricalTaskInput or :class:ContinuousTaskInput instead. It exists solely so that strategies can use isinstance(feat, TaskInput) to detect either flavour.

Task inputs carry no descriptor data: both flavours narrow descriptors to None, so it cannot be set.