diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 71e7e80..0c3d50a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -96,7 +96,7 @@ jobs:
- name: Install packages
shell: bash -l {0}
run: |
- python -m pip install nbmake pytest-asyncio
+ python -m pip install nbmake pytest-asyncio pytest-cov
python -m pip install .
- name: Install additional dependencies if needed
if: steps.find-changes.outputs.feature_names != ''
diff --git a/chemprop_contrib/__init__.py b/chemprop_contrib/__init__.py
index 106bcac..f9a6fe2 100644
--- a/chemprop_contrib/__init__.py
+++ b/chemprop_contrib/__init__.py
@@ -3,6 +3,7 @@
__all__ = [
"moe_regressor",
+ "sklearn_integration",
]
# possibly not working imports, because they have external deps that must be installed
diff --git a/chemprop_contrib/mcp/_cli.py b/chemprop_contrib/mcp/_cli.py
index 3df63ff..0f6480f 100644
--- a/chemprop_contrib/mcp/_cli.py
+++ b/chemprop_contrib/mcp/_cli.py
@@ -1,8 +1,11 @@
from chemprop_contrib import __all__
+
def main():
if "mcp" not in __all__:
- raise RuntimeError("mcp is not available - install it with `pip install 'chemprop_contrib[mcp]'`")
+ raise RuntimeError(
+ "mcp is not available - install it with `pip install 'chemprop_contrib[mcp]'`"
+ )
else:
from chemprop_contrib.mcp.server import main
diff --git a/chemprop_contrib/sklearn_integration/LICENSE b/chemprop_contrib/sklearn_integration/LICENSE
new file mode 100644
index 0000000..c1a8f48
--- /dev/null
+++ b/chemprop_contrib/sklearn_integration/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Chemprop Dev Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/chemprop_contrib/sklearn_integration/__init__.py b/chemprop_contrib/sklearn_integration/__init__.py
new file mode 100644
index 0000000..419e0bf
--- /dev/null
+++ b/chemprop_contrib/sklearn_integration/__init__.py
@@ -0,0 +1,15 @@
+from .chemprop_estimator import (
+ ChempropEnsembleRegressor,
+ ChempropMoleculeTransformer,
+ ChempropMulticomponentTransformer,
+ ChempropReactionTransformer,
+ ChempropRegressor,
+)
+
+__all__ = [
+ "ChempropMoleculeTransformer",
+ "ChempropReactionTransformer",
+ "ChempropMulticomponentTransformer",
+ "ChempropRegressor",
+ "ChempropEnsembleRegressor",
+]
diff --git a/chemprop_contrib/sklearn_integration/chemprop_estimator.py b/chemprop_contrib/sklearn_integration/chemprop_estimator.py
new file mode 100644
index 0000000..bb74277
--- /dev/null
+++ b/chemprop_contrib/sklearn_integration/chemprop_estimator.py
@@ -0,0 +1,746 @@
+from argparse import ArgumentParser, Namespace
+from datetime import datetime
+import logging
+import os
+from os import PathLike
+from pathlib import Path
+from typing import List, Literal, Optional, Sequence
+
+from lightning.pytorch import Trainer
+from lightning.pytorch.callbacks import EarlyStopping
+import numpy as np
+from sklearn.base import BaseEstimator, RegressorMixin, TransformerMixin
+from sklearn.metrics import accuracy_score, mean_absolute_error, r2_score, root_mean_squared_error
+import torch
+
+from chemprop.cli.common import add_common_args, find_models
+from chemprop.cli.train import add_train_args, build_model, normalize_inputs
+from chemprop.cli.utils.parsing import make_datapoints, make_dataset, parse_csv
+from chemprop.data import build_dataloader
+from chemprop.data.datasets import MulticomponentDataset
+from chemprop.featurizers.molgraph.reaction import RxnMode
+from chemprop.models import MPNN, MulticomponentMPNN, utils
+from chemprop.nn.transforms import UnscaleTransform
+
+logger = logging.getLogger(__name__)
+
+NOW = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
+CHEMPROP_TRAIN_DIR = Path(os.getenv("CHEMPROP_TRAIN_DIR", "chemprop_training"))
+
+
+class ChempropMoleculeTransformer(BaseEstimator, TransformerMixin):
+ def __init__(
+ self,
+ keep_h: bool = False,
+ add_h: bool = False,
+ ignore_stereo: bool = False,
+ reorder_atoms: bool = False,
+ smiles_cols: Sequence[str] | None = None,
+ target_cols: Sequence[str] | None = None,
+ ignore_cols: Sequence[str] | None = None,
+ weight_col: str | None = None,
+ bounded: bool = False,
+ no_header_row: bool = False,
+ ):
+ self.keep_h = keep_h
+ self.add_h = add_h
+ self.ignore_stereo = ignore_stereo
+ self.reorder_atoms = reorder_atoms
+ self.smiles_cols = smiles_cols
+ self.target_cols = target_cols
+ self.ignore_cols = ignore_cols
+ self.weight_col = weight_col
+ self.bounded = bounded
+ self.no_header_row = no_header_row
+
+ def fit(self, X, y=None):
+ return self
+
+ def fit_transform(self, X: np.ndarray | Sequence[str] | PathLike, y=None, **_):
+ return self._build_dps(X, y)
+
+ def transform(self, X: np.ndarray | Sequence[str] | PathLike):
+ return self._build_dps(X, None)
+
+ def _build_dps(
+ self,
+ X: np.ndarray | Sequence[str] | PathLike,
+ Y: Optional[np.ndarray],
+ weights=None,
+ lt_mask=None,
+ gt_mask=None,
+ ):
+ if isinstance(X, PathLike):
+ smiss, _, Y, weights, lt_mask, gt_mask, _ = parse_csv(
+ path=X,
+ smiles_cols=self.smiles_cols,
+ rxn_cols=None,
+ target_cols=self.target_cols,
+ ignore_cols=self.ignore_cols,
+ splits_col=None,
+ weight_col=self.weight_col,
+ descriptor_cols=None,
+ bounded=self.bounded,
+ no_header_row=self.no_header_row,
+ )
+ else:
+ smiss = [list(X)]
+ if Y is None:
+ Y = np.zeros((len(X), 1), dtype=float)
+ elif Y.ndim == 1:
+ Y = Y.reshape(-1, 1)
+
+ mol_data, _ = make_datapoints(
+ smiss=smiss,
+ rxnss=None,
+ Y=Y,
+ weights=weights,
+ lt_mask=lt_mask,
+ gt_mask=gt_mask,
+ X_d=None,
+ V_fss=None,
+ E_fss=None,
+ V_dss=None,
+ molecule_featurizers=None,
+ keep_h=self.keep_h,
+ add_h=self.add_h,
+ ignore_stereo=self.ignore_stereo,
+ reorder_atoms=self.reorder_atoms,
+ use_cuikmolmaker_featurization=False,
+ )
+ return mol_data
+
+
+class ChempropReactionTransformer(BaseEstimator, TransformerMixin):
+ def __init__(
+ self,
+ keep_h: bool = False,
+ add_h: bool = False,
+ ignore_stereo: bool = False,
+ reorder_atoms: bool = False,
+ rxn_cols: Sequence[str] | None = None,
+ target_cols: Sequence[str] | None = None,
+ ignore_cols: Sequence[str] | None = None,
+ weight_col: str | None = None,
+ bounded: bool = False,
+ no_header_row: bool = False,
+ ):
+ self.keep_h = keep_h
+ self.add_h = add_h
+ self.ignore_stereo = ignore_stereo
+ self.reorder_atoms = reorder_atoms
+ self.rxn_cols = rxn_cols
+ self.target_cols = target_cols
+ self.ignore_cols = ignore_cols
+ self.weight_col = weight_col
+ self.bounded = bounded
+ self.no_header_row = no_header_row
+
+ def fit(self, X, y=None):
+ return self
+
+ def fit_transform(self, X: np.ndarray | Sequence[str] | PathLike, y=None, **__):
+ return self._build_dps(X, y)
+
+ def transform(self, X: np.ndarray | Sequence[str] | PathLike):
+ return self._build_dps(X, None)
+
+ def _build_dps(
+ self,
+ X: np.ndarray | Sequence[str] | PathLike,
+ Y: Optional[Sequence[float]],
+ weights=None,
+ lt_mask=None,
+ gt_mask=None,
+ ):
+ if isinstance(X, PathLike):
+ _, rxnss, Y, weights, lt_mask, gt_mask, _ = parse_csv(
+ path=X,
+ smiles_cols=None,
+ rxn_cols=self.rxn_cols,
+ target_cols=self.target_cols,
+ ignore_cols=self.ignore_cols,
+ splits_col=None,
+ weight_col=self.weight_col,
+ descriptor_cols=None,
+ bounded=self.bounded,
+ no_header_row=self.no_header_row,
+ )
+ else:
+ rxnss = [list(X)]
+ weights, lt_mask, gt_mask = None, None, None
+ if Y is None:
+ Y = np.zeros((len(X), 1), dtype=float)
+ elif Y.ndim == 1:
+ Y = Y.reshape(-1, 1)
+
+ _, rxn_data = make_datapoints(
+ smiss=None,
+ rxnss=rxnss,
+ Y=Y,
+ weights=weights,
+ lt_mask=lt_mask,
+ gt_mask=gt_mask,
+ X_d=None,
+ V_fss=None,
+ E_fss=None,
+ V_dss=None,
+ molecule_featurizers=None,
+ keep_h=self.keep_h,
+ add_h=self.add_h,
+ ignore_stereo=self.ignore_stereo,
+ reorder_atoms=self.reorder_atoms,
+ use_cuikmolmaker_featurization=False,
+ )
+ return rxn_data
+
+
+class ChempropMulticomponentTransformer(BaseEstimator, TransformerMixin):
+ def __init__(
+ self,
+ component_types: Sequence[Literal["molecule", "reaction"]] | None = None,
+ keep_h: bool = False,
+ add_h: bool = False,
+ ignore_stereo: bool = False,
+ reorder_atoms: bool = False,
+ smiles_cols: Sequence[str] | None = None,
+ rxn_cols: Sequence[str] | None = None,
+ target_cols: Sequence[str] | None = None,
+ ignore_cols: Sequence[str] | None = None,
+ weight_col: str | None = None,
+ bounded: bool = False,
+ no_header_row: bool = False,
+ ):
+ self.component_types = component_types
+ self.keep_h = keep_h
+ self.add_h = add_h
+ self.ignore_stereo = ignore_stereo
+ self.reorder_atoms = reorder_atoms
+ self.smiles_cols = smiles_cols
+ self.rxn_cols = rxn_cols
+ self.target_cols = target_cols
+ self.ignore_cols = ignore_cols
+ self.weight_col = weight_col
+ self.bounded = bounded
+ self.no_header_row = no_header_row
+ self.mol_transformer = ChempropMoleculeTransformer(
+ keep_h=keep_h, add_h=add_h, ignore_stereo=ignore_stereo, reorder_atoms=reorder_atoms
+ )
+ self.rxn_transformer = ChempropReactionTransformer(
+ keep_h=keep_h, add_h=add_h, ignore_stereo=ignore_stereo, reorder_atoms=reorder_atoms
+ )
+
+ def fit(self, X, y=None):
+ return self
+
+ def fit_transform(self, X: np.ndarray | Sequence[Sequence[str]] | PathLike, y=None, **__):
+ return self._build_dps(X, y)
+
+ def transform(self, X: np.ndarray | Sequence[Sequence[str]] | PathLike):
+ return self._build_dps(X, None)
+
+ def _build_dps(
+ self, X: np.ndarray | Sequence[Sequence[str]] | PathLike, Y: Optional[Sequence[float]]
+ ):
+ if isinstance(X, PathLike):
+ smiss, rxnss, Y, weights, lt_mask, gt_mask, _ = parse_csv(
+ path=X,
+ smiles_cols=self.smiles_cols,
+ rxn_cols=self.rxn_cols,
+ target_cols=self.target_cols,
+ ignore_cols=self.ignore_cols,
+ splits_col=None,
+ weight_col=self.weight_col,
+ descriptor_cols=None,
+ bounded=self.bounded,
+ no_header_row=self.no_header_row,
+ )
+ mol_data, rxn_data = make_datapoints(
+ smiss=smiss,
+ rxnss=rxnss,
+ Y=Y,
+ weights=weights,
+ lt_mask=lt_mask,
+ gt_mask=gt_mask,
+ X_d=None,
+ V_fss=None,
+ E_fss=None,
+ V_dss=None,
+ molecule_featurizers=None,
+ keep_h=self.keep_h,
+ add_h=self.add_h,
+ ignore_stereo=self.ignore_stereo,
+ reorder_atoms=self.reorder_atoms,
+ use_cuikmolmaker_featurization=False,
+ )
+ return [*mol_data, *rxn_data]
+ else:
+ if (
+ isinstance(X, (np.ndarray, list))
+ and np.ndim(X) == 2
+ and np.asarray(X).shape[1] == len(self.component_types)
+ ):
+ X = np.asarray(X).T.tolist()
+ else:
+ X = list(X)
+ if len(X) != len(self.component_types):
+ logger.warning(
+ "data dimension and number of component_types inputted are inconsistent"
+ )
+ if Y is None:
+ Y = np.zeros((len(X[0]), 1), dtype=float)
+ elif np.ndim(Y) == 1:
+ Y = np.asarray(Y).reshape(-1, 1)
+ dp_lists = [
+ self.mol_transformer._build_dps(input_col, Y)[0]
+ if type == "molecule"
+ else self.rxn_transformer._build_dps(input_col, Y)[0]
+ for type, input_col in zip(self.component_types, X)
+ ]
+ return dp_lists
+
+
+def add_train_defaults(args: Namespace) -> Namespace:
+ parser = ArgumentParser()
+ parser = add_common_args(parser)
+ parser = add_train_args(parser)
+ defaults = parser.parse_args([])
+ for k, v in vars(defaults).items():
+ if not hasattr(args, k):
+ setattr(args, k, v)
+ return args
+
+
+def _split_indices(n: int, val_size: float, seed=0):
+ if val_size <= 0:
+ return np.arange(n), np.array([], dtype=int)
+ if val_size >= 1:
+ raise ValueError("val_size should be a float between 0 and 1")
+ n_val = int(n * val_size)
+ rng = np.random.RandomState(seed)
+ perm = rng.permutation(n)
+ val_idx = perm[:n_val]
+ train_idx = perm[n_val:]
+ return train_idx, val_idx
+
+
+class ChempropRegressor(BaseEstimator, RegressorMixin):
+ def __init__(
+ self,
+ num_workers: int = 0,
+ batch_size: int = 64,
+ output_dir: Optional[PathLike] = CHEMPROP_TRAIN_DIR / "sklearn_output" / NOW,
+ checkpoint: Optional[List[Path]] = None,
+ molecule_featurizers: Optional[List[str]] = None,
+ no_descriptor_scaling: bool = False,
+ message_hidden_dim: List[int] = [300],
+ depth: List[int] = [3],
+ dropout: float = 0.0,
+ aggregation: str = "norm",
+ ffn_hidden_dim: int = 300,
+ ffn_num_layers: int = 1,
+ batch_norm: bool = False,
+ multiclass_num_classes: int = 3,
+ accelerator: str = "auto",
+ devices: str | int | Sequence[int] = "auto",
+ epochs: int = 50,
+ patience: Optional[int] = None,
+ no_cache: bool = False,
+ task_type: str = "regression",
+ loss_function: Optional[str] = None,
+ metrics: Optional[List[str]] = None,
+ val_size: float = 0,
+ data_seed: int = 0,
+ multi_hot_atom_featurizer_mode: Literal["V1", "V2", "ORGANIC", "RIGR"] = "V2",
+ reaction_mode: RxnMode = RxnMode.REAC_DIFF,
+ ):
+ self.model = None
+ self.args = None
+ for name, value in locals().items():
+ if name not in ["self", "model", "args"]:
+ setattr(self, name, value)
+
+ def __sklearn_is_fitted__(self):
+ return True if self.model else False
+
+ def fit(self, X, y=None):
+ args = Namespace(
+ num_workers=self.num_workers,
+ batch_size=self.batch_size,
+ output_dir=self.output_dir,
+ checkpoint=self.checkpoint,
+ molecule_featurizers=self.molecule_featurizers,
+ no_descriptor_scaling=self.no_descriptor_scaling,
+ message_hidden_dim=self.message_hidden_dim,
+ depth=self.depth,
+ dropout=self.dropout,
+ aggregation=self.aggregation,
+ ffn_hidden_dim=self.ffn_hidden_dim,
+ ffn_num_layers=self.ffn_num_layers,
+ batch_norm=self.batch_norm,
+ multiclass_num_classes=self.multiclass_num_classes,
+ accelerator=self.accelerator,
+ devices=self.devices,
+ epochs=self.epochs,
+ patience=self.patience,
+ no_cache=self.no_cache,
+ task_type=self.task_type,
+ loss_function=self.loss_function,
+ metrics=self.metrics,
+ val_size=self.val_size,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ reaction_mode=self.reaction_mode,
+ )
+ self.args = add_train_defaults(args)
+ if self.checkpoint is not None:
+ model_paths = find_models(self.checkpoint)
+ if len(model_paths) != 1:
+ logger.warning(
+ "More than one model path provided in checkpoint and only the first one is used. Call ChempropEnsembleRegressor instead."
+ )
+ model_path = model_paths[0]
+
+ if len(X) > 1:
+ mpnn_cls = MulticomponentMPNN
+ else:
+ mpnn_cls = MPNN
+
+ self.model = mpnn_cls.load_from_file(model_path)
+ self.model.apply(
+ lambda m: setattr(m, "p", self.dropout) if isinstance(m, torch.nn.Dropout) else None
+ )
+
+ if len(X) > 1:
+ n = len(X[0])
+ train_idx, val_idx = _split_indices(n, self.val_size, self.data_seed)
+
+ train_datasets = []
+ val_datasets = []
+
+ for dp_list in X:
+ train_dps = [dp_list[i] for i in train_idx]
+ val_dps = [dp_list[i] for i in val_idx]
+
+ train_ds = make_dataset(
+ train_dps,
+ reaction_mode=self.reaction_mode,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ )
+ train_datasets.append(train_ds)
+
+ if len(val_dps) > 0:
+ val_ds = make_dataset(
+ val_dps,
+ reaction_mode=self.reaction_mode,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ )
+ val_datasets.append(val_ds)
+
+ train_set = MulticomponentDataset(train_datasets)
+ val_set = MulticomponentDataset(val_datasets) if len(val_datasets) > 0 else None
+
+ else:
+ X = X[0]
+ if not isinstance(X, (list, tuple)):
+ raise ValueError("X must be a list of datapoints for non-multicomponent inputs")
+ n = len(X)
+ train_idx, val_idx = _split_indices(n, self.val_size, self.data_seed)
+ train_dps = [X[i] for i in train_idx]
+ val_dps = [X[i] for i in val_idx]
+ train_set = make_dataset(
+ train_dps,
+ reaction_mode=self.reaction_mode,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ )
+ val_set = None
+ if len(val_dps) > 0:
+ val_set = make_dataset(
+ val_dps,
+ reaction_mode=self.reaction_mode,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ )
+
+ if not self.no_cache:
+ train_set.cache = True
+ if val_set is not None:
+ val_set.cache = True
+
+ if self.model is None:
+ input_transforms = normalize_inputs(train_set, val_set, self.args)
+ output_transform = None
+ if "regression" in self.task_type:
+ output_scaler = train_set.normalize_targets()
+ output_transform = UnscaleTransform.from_standard_scaler(output_scaler)
+ self.model = build_model(self.args, train_set, output_transform, input_transforms)
+
+ train_loader = build_dataloader(
+ train_set, batch_size=self.batch_size, num_workers=self.num_workers
+ )
+ if val_set:
+ val_loader = build_dataloader(
+ val_set, batch_size=self.batch_size, num_workers=self.num_workers, shuffle=False
+ )
+ else:
+ val_loader = None
+
+ patience = self.patience if self.patience else self.epochs
+ metric = "val_loss" if val_loader else "train_loss"
+ trainer = Trainer(
+ accelerator=self.accelerator,
+ devices=self.devices,
+ max_epochs=self.epochs,
+ callbacks=[EarlyStopping(monitor=metric, patience=patience, mode="min")],
+ )
+
+ trainer.fit(self.model, train_dataloaders=train_loader, val_dataloaders=val_loader)
+
+ return self
+
+ def predict(self, X):
+ if self.model is None:
+ raise RuntimeError("The regressor has not been fitted.")
+ if len(X) > 1:
+ test_set = MulticomponentDataset(
+ [
+ make_dataset(
+ dps,
+ reaction_mode=self.reaction_mode,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ )
+ for dps in X
+ ]
+ )
+ self._y = test_set.datasets[0].Y
+ else:
+ X = X[0]
+ test_set = make_dataset(
+ X,
+ reaction_mode=self.reaction_mode,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ )
+ self._y = test_set.Y
+ dl = build_dataloader(
+ test_set, batch_size=self.batch_size, num_workers=self.num_workers, shuffle=False
+ )
+
+ eval_trainer = Trainer(accelerator=self.accelerator, devices=1, enable_progress_bar=True)
+ preds = eval_trainer.predict(self.model, dataloaders=dl)
+ preds = torch.cat(preds, dim=0)
+
+ if preds.ndim == 1:
+ preds = preds.unsqueeze(-1)
+
+ return preds.cpu().numpy()
+
+ def _score(self, y, y_pred, metric):
+ y_true = np.asarray(y)
+ y_pred = np.asarray(y_pred)
+
+ if y_true.ndim == 1:
+ y_true = y_true.reshape(-1, 1)
+ if y_pred.ndim == 1:
+ y_pred = y_pred.reshape(-1, 1)
+
+ if y_true.shape != y_pred.shape:
+ raise ValueError(
+ f"Shape mismatch between y (shape={y_true.shape}) and predictions (shape={y_pred.shape})."
+ )
+
+ scores = []
+ for j in range(y_true.shape[1]):
+ yt = y_true[:, j]
+ yp = y_pred[:, j]
+
+ if metric == "mae":
+ s = mean_absolute_error(yt, yp)
+ elif metric == "rmse":
+ s = root_mean_squared_error(yt, yp)
+ elif metric == "mse":
+ s = root_mean_squared_error(yt, yp) ** 2
+ elif metric == "r2":
+ s = r2_score(yt, yp)
+ elif metric == "accuracy":
+ s = accuracy_score(yt, (yp > 0.5).astype(int))
+ else:
+ raise ValueError(f"Unsupported metric: {metric}")
+
+ scores.append(s)
+
+ return scores
+
+ def score(self, X, y=None, metric: Literal["mae", "rmse", "mse", "r2", "accuracy"] = "rmse"):
+ y_pred = self.predict(X)
+ if y is None:
+ y = self._y
+ return self._score(y, y_pred, metric)
+
+ def save_model(self, output_dir: Optional[PathLike] = None):
+ if output_dir is None:
+ output_dir = self.output_dir
+ output_dir = Path(output_dir)
+ output_dir.mkdir(parents=True, exist_ok=True)
+ utils.save_model(str(output_dir / "best.pt"), self.model, None)
+
+
+class ChempropEnsembleRegressor(BaseEstimator, RegressorMixin):
+ def __init__(
+ self,
+ ensemble_size: int = 5,
+ num_workers: int = 0,
+ batch_size: int = 64,
+ output_dir: Optional[PathLike] = CHEMPROP_TRAIN_DIR / "sklearn_output" / NOW,
+ checkpoint: Optional[List[Path]] = None,
+ molecule_featurizers: Optional[List[str]] = None,
+ no_descriptor_scaling: bool = False,
+ message_hidden_dim: List[int] = [300],
+ depth: List[int] = [3],
+ dropout: float = 0.0,
+ aggregation: str = "norm",
+ ffn_hidden_dim: int = 300,
+ ffn_num_layers: int = 1,
+ batch_norm: bool = False,
+ multiclass_num_classes: int = 3,
+ accelerator: str = "auto",
+ devices: str | int | Sequence[int] = "auto",
+ epochs: int = 50,
+ patience: Optional[int] = None,
+ no_cache: bool = False,
+ task_type: str = "regression",
+ loss_function: Optional[str] = None,
+ metrics: Optional[List[str]] = None,
+ val_size: float = 0,
+ data_seed: int = 0,
+ multi_hot_atom_featurizer_mode: Literal["V1", "V2", "ORGANIC", "RIGR"] = "V2",
+ reaction_mode: RxnMode = RxnMode.REAC_DIFF,
+ ):
+ self.ensemble_size = ensemble_size
+ self.num_workers = num_workers
+ self.batch_size = batch_size
+ self.output_dir = output_dir
+ self.checkpoint = checkpoint
+ self.molecule_featurizers = molecule_featurizers
+ self.no_descriptor_scaling = no_descriptor_scaling
+ self.message_hidden_dim = message_hidden_dim
+ self.depth = depth
+ self.dropout = dropout
+ self.aggregation = aggregation
+ self.ffn_hidden_dim = ffn_hidden_dim
+ self.ffn_num_layers = ffn_num_layers
+ self.batch_norm = batch_norm
+ self.multiclass_num_classes = multiclass_num_classes
+ self.accelerator = accelerator
+ self.devices = devices
+ self.epochs = epochs
+ self.patience = patience
+ self.no_cache = no_cache
+ self.task_type = task_type
+ self.loss_function = loss_function
+ self.metrics = metrics
+ self.val_size = val_size
+ self.data_seed = data_seed
+ self.multi_hot_atom_featurizer_mode = multi_hot_atom_featurizer_mode
+ self.reaction_mode = reaction_mode
+ self.models = []
+
+ def __sklearn_is_fitted__(self):
+ return len(self.models) > 0
+
+ def _base_kwargs(self) -> dict:
+ return dict(
+ num_workers=self.num_workers,
+ batch_size=self.batch_size,
+ output_dir=self.output_dir,
+ checkpoint=None,
+ molecule_featurizers=self.molecule_featurizers,
+ no_descriptor_scaling=self.no_descriptor_scaling,
+ message_hidden_dim=self.message_hidden_dim,
+ depth=self.depth,
+ dropout=self.dropout,
+ aggregation=self.aggregation,
+ ffn_hidden_dim=self.ffn_hidden_dim,
+ ffn_num_layers=self.ffn_num_layers,
+ batch_norm=self.batch_norm,
+ multiclass_num_classes=self.multiclass_num_classes,
+ accelerator=self.accelerator,
+ devices=self.devices,
+ epochs=self.epochs,
+ patience=self.patience,
+ no_cache=self.no_cache,
+ task_type=self.task_type,
+ loss_function=self.loss_function,
+ metrics=self.metrics,
+ val_size=self.val_size,
+ data_seed=self.data_seed,
+ multi_hot_atom_featurizer_mode=self.multi_hot_atom_featurizer_mode,
+ reaction_mode=self.reaction_mode,
+ )
+
+ def fit(self, X, y):
+ self.models = []
+
+ ens_size = self.ensemble_size
+
+ if self.checkpoint is not None:
+ if len(self.checkpoint) != ens_size:
+ logger.warning(
+ f"Conflict between number of checkpoints supplied ({len(self.checkpoint)}) "
+ f"and ensemble_size ({ens_size}). Using len(checkpoint)={len(self.checkpoint)}."
+ )
+ ens_size = len(self.checkpoint)
+
+ for path in self.checkpoint[:ens_size]:
+ args = self._base_kwargs()
+ args["checkpoint"] = [path]
+ model = ChempropRegressor(**args)
+ model.fit(X, y)
+ self.models.append(model)
+ else:
+ for _ in range(ens_size):
+ model = ChempropRegressor(**self._base_kwargs())
+ model.fit(X, y)
+ self.models.append(model)
+
+ return self
+
+ def predict(self, X):
+ if not self.models:
+ raise RuntimeError("The ensemble regressor has not been fitted.")
+ preds = [m.predict(X) for m in self.models]
+ return np.mean(preds, axis=0)
+
+ def score(self, X, y=None, metric: Literal["mae", "rmse", "mse", "r2", "accuracy"] = "rmse"):
+ if not self.models:
+ raise RuntimeError("The ensemble regressor has not been fitted.")
+ y_pred = self.predict(X)
+ if y is None:
+ y = self.models[0]._y
+ return self.models[0]._score(y, y_pred, metric)
+
+ def save_model(self, output_dir: Optional[PathLike] = None):
+ if output_dir is None:
+ output_dir = self.output_dir
+ output_dir = Path(output_dir)
+ output_dir.mkdir(parents=True, exist_ok=True)
+ for idx, model in enumerate(self.models):
+ utils.save_model(str(output_dir / f"best_{idx}.pt"), model.model, None)
+
+
+# microtest
+if __name__ == "__main__":
+ from sklearn.pipeline import Pipeline
+
+ sklearnPipeline = Pipeline(
+ [
+ (
+ "featurizer",
+ ChempropMulticomponentTransformer(
+ smiles_cols=["solvent_smiles"], rxn_cols=["rxn_smiles"], target_cols=["target"]
+ ),
+ ),
+ ("regressor", ChempropRegressor(epochs=100, patience=10)),
+ ]
+ )
+
+ sklearnPipeline.fit(X=Path("tests/data/regression/rxn+mol/rxn+mol.csv"))
+ score = sklearnPipeline.score(X=Path("tests/data/regression/rxn+mol/rxn+mol.csv"))
+ print(f"RMSE: {score}")
diff --git a/chemprop_contrib/sklearn_integration/chemprop_sklearn_example.ipynb b/chemprop_contrib/sklearn_integration/chemprop_sklearn_example.ipynb
new file mode 100644
index 0000000..ea9dcdf
--- /dev/null
+++ b/chemprop_contrib/sklearn_integration/chemprop_sklearn_example.ipynb
@@ -0,0 +1,2789 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "f5a43c9b",
+ "metadata": {},
+ "source": [
+ "# Chemprop scikit-learn Estimator Example\n",
+ "Demonstrating usage of modules in chemprop.sklearn_integration.chemprop_estimator with common scikit-learn workflows including cross-validation and hyperparameter tuning."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "465acb3f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from chemprop_contrib.sklearn_integration import ChempropMoleculeTransformer, ChempropReactionTransformer, ChempropMulticomponentTransformer, ChempropRegressor, ChempropEnsembleRegressor\n",
+ "import numpy as np\n",
+ "\n",
+ "# Sample data\n",
+ "X_mol = np.array([\n",
+ " \"CCO\", \"CCN\", \"CCC\", \"COC\", \"CNC\", \"CCCl\", \"CCBr\", \"CCF\", \"CCI\", \"CC=O\",\n",
+ " \"CC#N\", \"CC(C)O\", \"CC(C)N\", \"CC(C)C\", \"COC(C)\", \"CN(C)C\", \"C1CCCCC1\", \"C1=CC=CC=C1\",\n",
+ " \"CC(C)(C)O\", \"CC(C)(C)N\", \"COCCO\", \"CCOC(=O)C\", \"CCN(CC)CC\", \"CN1CCCC1\", \"C(CO)N\"\n",
+ "])\n",
+ "X_rxn = np.array([\n",
+ " \"CCO>>CC=O\",\"CCBr.CN>>CCN\",\"CC(=O)O.CCO>>CC(=O)OCC\",\"C=CC=C.C=C>>c1ccccc1\",\"CC(=O)Cl.O>>CC(=O)O\",\n",
+ " \"c1ccccc1.BrBr>>c1ccc(Br)cc1\",\"BrCCBr>>BrC#CBr\",\"ClCCCl.O>>ClCCO\",\"CO.O=C=O>>COC(=O)O\",\"CC(C)(C)Br.CN>>CC(C)(C)CN\",\n",
+ " \"C=O.CC>>CCO\",\"CC=O.CC=O>>CC(O)CC=O\",\"CCBr.C#N>>CC#N\",\"O=CC=O.CC>>O=CC(C)O\",\"CC(=O)OCC.CO>>CC(=O)OCO\",\n",
+ " \"c1ccccc1O.ClCl>>c1ccc(Cl)cc1O\",\"CCBr.O>>CCO\",\"C=C.C=C>>C1=CCC=CC1\",\"CC(=O)O.O>>CC(=O)OO\"\n",
+ "])\n",
+ "y = np.array([\n",
+ " 0.50, 0.60, 0.55, 0.58, 0.52, 0.62, 0.65, 0.57, 0.59, 0.61,\n",
+ " 0.56, 0.60, 0.54, 0.53, 0.62, 0.63, 0.45, 0.40,\n",
+ " 0.64, 0.66, 0.59, 0.51, 0.48, 0.46, 0.49\n",
+ "])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7621139f",
+ "metadata": {},
+ "source": [
+ "## Building a pipeline\n",
+ "Pipeline ChempropMoleculeTransformer/ChempropReactionTransformer/ ChempropMulticomponentTransformer and ChempropRegressor together to obtain an sklearn module that encapulates full chemprop capabilities."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "a2f20d81",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Dropping last batch of size 1 to avoid issues with batch normalization (dataset size = 25, batch_size = 8)\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/logger_connector/logger_connector.py:76: Starting from v1.9.0, `tensorboardX` has been removed as a dependency of the `lightning.pytorch` package, due to potential conflicts with other packages in the ML ecosystem. For this reason, `logger=True` will use `CSVLogger` as the default logger, unless the `tensorboard` or `tensorboardX` packages are found. Please `pip install lightning[extra]` or one of them to enable TensorBoard support by default\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (3) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "---------------------------------------------------------------\n",
+ "0 | message_passing | BondMessagePassing | 35.9 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 120 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "---------------------------------------------------------------\n",
+ "156 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "156 K Total params\n",
+ "0.627 Total estimated model params size (MB)\n",
+ "27 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 3/3 [00:00<00:00, 44.51it/s, v_num=169, train_loss_step=0.722, train_loss_epoch=1.020]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 3/3 [00:00<00:00, 33.64it/s, v_num=169, train_loss_step=0.722, train_loss_epoch=1.020]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 94.18it/s] \n",
+ "Predictions: [[0.55784875]\n",
+ " [0.55774605]\n",
+ " [0.557584 ]\n",
+ " [0.55791354]\n",
+ " [0.55776924]]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (1) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "---------------------------------------------------------------\n",
+ "0 | message_passing | BondMessagePassing | 252 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 90.6 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "---------------------------------------------------------------\n",
+ "342 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "342 K Total params\n",
+ "1.372 Total estimated model params size (MB)\n",
+ "25 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 1/1 [00:00<00:00, 18.62it/s, v_num=171, train_loss_step=0.983, train_loss_epoch=0.983]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 1/1 [00:00<00:00, 14.05it/s, v_num=171, train_loss_step=0.983, train_loss_epoch=0.983]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (1) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "---------------------------------------------------------------\n",
+ "0 | message_passing | BondMessagePassing | 252 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 90.6 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "---------------------------------------------------------------\n",
+ "342 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "342 K Total params\n",
+ "1.372 Total estimated model params size (MB)\n",
+ "25 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 1/1 [00:00<00:00, 26.87it/s, v_num=172, train_loss_step=0.987, train_loss_epoch=0.987]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 1/1 [00:00<00:00, 15.88it/s, v_num=172, train_loss_step=0.987, train_loss_epoch=0.987]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (1) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "---------------------------------------------------------------\n",
+ "0 | message_passing | BondMessagePassing | 252 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 90.6 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "---------------------------------------------------------------\n",
+ "342 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "342 K Total params\n",
+ "1.372 Total estimated model params size (MB)\n",
+ "25 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 1/1 [00:00<00:00, 25.66it/s, v_num=173, train_loss_step=0.979, train_loss_epoch=0.979]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 1/1 [00:00<00:00, 16.84it/s, v_num=173, train_loss_step=0.979, train_loss_epoch=0.979]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 129.39it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 107.56it/s]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 183.27it/s]\n",
+ "MSE: [0.04080571091402912]\n"
+ ]
+ }
+ ],
+ "source": [
+ "from sklearn.pipeline import Pipeline\n",
+ "\n",
+ "mol_pipeline = Pipeline([\n",
+ " (\"featurizer\", ChempropMoleculeTransformer(keep_h=True, add_h=True, ignore_stereo=True, reorder_atoms=True)),\n",
+ " (\"regressor\", ChempropRegressor(batch_size=8, message_hidden_dim=[100], depth=[5], ffn_num_layers=2, epochs=5, patience=5))\n",
+ "])\n",
+ "mol_pipeline.fit(X_mol, y)\n",
+ "y_pred = mol_pipeline.predict(X_mol[:5])\n",
+ "print(f\"Predictions: {y_pred}\")\n",
+ "\n",
+ "rxn_pipeline = Pipeline([\n",
+ " (\"featurizer\", ChempropReactionTransformer()),\n",
+ " (\"regressor\", ChempropEnsembleRegressor(ensemble_size=3, epochs=5)) # Enables training an ensemble of chemprop regressors and predicting based on their average\n",
+ "])\n",
+ "rxn_pipeline.fit(X_rxn, y)\n",
+ "scores = rxn_pipeline.score(X_rxn[:5],y[:5], metric=\"mse\") # suppot metrics in [\"mae\", \"rmse\", \"mse\", \"r2\", \"accuracy\"] and defaulted to \"rmse\"\n",
+ "print(f\"MSE: {scores}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ce2c0f78",
+ "metadata": {},
+ "source": [
+ "Alternatively, pass in a path to a csv data file instead of X/y arrays, and include the roles of the columns in arguments of the transformer."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "d2fa92e5",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:13] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (7) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 180 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "660 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "660 K Total params\n",
+ "2.642 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 7/7 [00:00<00:00, 8.31it/s, v_num=177, train_loss_step=1.420, train_loss_epoch=0.972]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 7/7 [00:00<00:00, 7.98it/s, v_num=177, train_loss_step=1.420, train_loss_epoch=0.972]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:18] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 7/7 [00:00<00:00, 16.17it/s]\n",
+ "RMSE: [2.9060591216446485]\n"
+ ]
+ }
+ ],
+ "source": [
+ "from pathlib import Path\n",
+ "multicomponent_pipeline = Pipeline([\n",
+ " (\"featurizer\", ChempropMulticomponentTransformer(\n",
+ " smiles_cols=[\"solvent_smiles\"],\n",
+ " rxn_cols=[\"rxn_smiles\"],\n",
+ " target_cols=[\"target\"],\n",
+ " )),\n",
+ " (\"regressor\", ChempropRegressor(epochs=5))\n",
+ "])\n",
+ "\n",
+ "multicomponent_pipeline.fit(X=Path(\"rxn+mol.csv\")) #substitute with target datapath\n",
+ "score = multicomponent_pipeline.score(X=Path(\"rxn+mol.csv\"))\n",
+ "print(f\"RMSE: {score}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1e8d5310",
+ "metadata": {},
+ "source": [
+ "## Applying the Sklearn Toolbox\n",
+ "You can easily validate the pipeline on your dataset with the sklearn cross_val_score function. However, note that sklearn helpers do not recognize path input, so make sure that the data is inputed as matrix-like X/y."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "c2b83cee",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:19] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 180 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "660 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "660 K Total params\n",
+ "2.642 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:01<00:00, 4.67it/s, v_num=179, train_loss_step=0.734, train_loss_epoch=0.967]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:01<00:00, 4.51it/s, v_num=179, train_loss_step=0.734, train_loss_epoch=0.967]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 2/2 [00:00<00:00, 31.72it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:25] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 180 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "660 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "660 K Total params\n",
+ "2.642 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 8.22it/s, v_num=181, train_loss_step=1.210, train_loss_epoch=0.964]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 7.89it/s, v_num=181, train_loss_step=1.210, train_loss_epoch=0.964]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 2/2 [00:00<00:00, 34.32it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:30] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 180 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "660 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "660 K Total params\n",
+ "2.642 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 5.32it/s, v_num=183, train_loss_step=1.050, train_loss_epoch=0.976]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 5.14it/s, v_num=183, train_loss_step=1.050, train_loss_epoch=0.976]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 2/2 [00:00<00:00, 30.06it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:35] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 180 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "660 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "660 K Total params\n",
+ "2.642 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 10.69it/s, v_num=185, train_loss_step=0.549, train_loss_epoch=0.955]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 10.24it/s, v_num=185, train_loss_step=0.549, train_loss_epoch=0.955]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 2/2 [00:00<00:00, 16.29it/s]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 180 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "660 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "660 K Total params\n",
+ "2.642 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 9.87it/s, v_num=187, train_loss_step=0.767, train_loss_epoch=0.957]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 9.45it/s, v_num=187, train_loss_step=0.767, train_loss_epoch=0.957]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:42] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 2/2 [00:00<00:00, 55.09it/s]\n",
+ "Cross-validation MSE scores: [ 7.02325274 4.83670891 15.6581004 10.84736425 4.4657647 ]\n",
+ "Average MSE: 8.566238199545085\n"
+ ]
+ }
+ ],
+ "source": [
+ "from sklearn.model_selection import cross_val_score\n",
+ "import pandas as pd\n",
+ "\n",
+ "multicomponent_pipeline = Pipeline([\n",
+ " # component_types have to be specified for each input column in order for multicomponent transformer, if input is matrix-like\n",
+ " (\"featurizer\", ChempropMulticomponentTransformer(component_types=[\"reaction\", \"molecule\"])),\n",
+ " (\"regressor\", ChempropRegressor(epochs=5))\n",
+ "])\n",
+ "\n",
+ "df = pd.read_csv(\"rxn+mol.csv\")\n",
+ "X = df[[\"rxn_smiles\",\"solvent_smiles\"]].to_numpy(dtype=str)\n",
+ "y = df[\"target\"].to_numpy(dtype=float)\n",
+ "\n",
+ "scores = cross_val_score(multicomponent_pipeline, X, y, cv=5, scoring='neg_mean_squared_error')\n",
+ "print(\"Cross-validation MSE scores:\", -scores)\n",
+ "print(\"Average MSE:\", -scores.mean())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3bbc8ad9",
+ "metadata": {},
+ "source": [
+ "You can also tune the hyperparameters of the chemprop pipeline with the sklearn GridSearchCV function."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "4e10a2a9",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:43] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 1.4 M | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "1.9 M Trainable params\n",
+ "0 Non-trainable params\n",
+ "1.9 M Total params\n",
+ "7.699 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 10.33it/s, v_num=189, train_loss_step=1.400, train_loss_epoch=0.958]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 9.53it/s, v_num=189, train_loss_step=1.400, train_loss_epoch=0.958]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 20.61it/s]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:47] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 1.4 M | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "1.9 M Trainable params\n",
+ "0 Non-trainable params\n",
+ "1.9 M Total params\n",
+ "7.699 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 9.15it/s, v_num=191, train_loss_step=0.486, train_loss_epoch=0.982]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 8.61it/s, v_num=191, train_loss_step=0.486, train_loss_epoch=0.982]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 32.17it/s]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 1.4 M | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "1.9 M Trainable params\n",
+ "0 Non-trainable params\n",
+ "1.9 M Total params\n",
+ "7.699 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 7.37it/s, v_num=193, train_loss_step=0.759, train_loss_epoch=0.974]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 6.73it/s, v_num=193, train_loss_step=0.759, train_loss_epoch=0.974]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:55] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 32.47it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:56] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 602 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "1.1 M Trainable params\n",
+ "0 Non-trainable params\n",
+ "1.1 M Total params\n",
+ "4.328 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 13.01it/s, v_num=195, train_loss_step=0.581, train_loss_epoch=0.974]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 12.17it/s, v_num=195, train_loss_step=0.581, train_loss_epoch=0.974]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 18.61it/s]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:47:59] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 602 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "1.1 M Trainable params\n",
+ "0 Non-trainable params\n",
+ "1.1 M Total params\n",
+ "4.328 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 8.10it/s, v_num=197, train_loss_step=0.824, train_loss_epoch=0.977]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 7.63it/s, v_num=197, train_loss_step=0.824, train_loss_epoch=0.977]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 36.79it/s]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 602 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "1.1 M Trainable params\n",
+ "0 Non-trainable params\n",
+ "1.1 M Total params\n",
+ "4.328 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 11.59it/s, v_num=199, train_loss_step=2.760, train_loss_epoch=0.972]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 10.93it/s, v_num=199, train_loss_step=2.760, train_loss_epoch=0.972]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:48:06] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 39.01it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:48:06] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 270 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "750 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "750 K Total params\n",
+ "3.004 Total estimated model params size (MB)\n",
+ "36 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 9.84it/s, v_num=201, train_loss_step=0.503, train_loss_epoch=0.991]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 9.44it/s, v_num=201, train_loss_step=0.503, train_loss_epoch=0.991]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 32.77it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:48:11] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 270 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "750 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "750 K Total params\n",
+ "3.004 Total estimated model params size (MB)\n",
+ "36 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 8.47it/s, v_num=203, train_loss_step=1.480, train_loss_epoch=0.997]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 7.66it/s, v_num=203, train_loss_step=1.480, train_loss_epoch=0.997]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 25.98it/s]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (5) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 270 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "750 K Trainable params\n",
+ "0 Non-trainable params\n",
+ "750 K Total params\n",
+ "3.004 Total estimated model params size (MB)\n",
+ "36 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 8.80it/s, v_num=205, train_loss_step=0.580, train_loss_epoch=0.990]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 5/5 [00:00<00:00, 8.35it/s, v_num=205, train_loss_step=0.580, train_loss_epoch=0.990]\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:48:19] WARNING: not removing hydrogen atom without neighbors\n",
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Predicting DataLoader 0: 100%|██████████| 3/3 [00:00<00:00, 29.90it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "[09:48:20] WARNING: not removing hydrogen atom without neighbors\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "💡 Tip: For seamless cloud uploads and versioning, try installing [litmodels](https://pypi.org/project/litmodels/) to enable LitModelCheckpoint, which syncs automatically with the Lightning model registry.\n",
+ "GPU available: False, used: False\n",
+ "TPU available: False, using: 0 TPU cores\n",
+ "HPU available: False, using: 0 HPUs\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/configuration_validator.py:70: You defined a `validation_step` but have no `val_dataloader`. Skipping val loop.\n",
+ "Loading `train_dataloader` to estimate number of stepping batches.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:433: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.\n",
+ "/home/knathan/anaconda3/envs/chemprop_contrib/lib/python3.11/site-packages/lightning/pytorch/loops/fit_loop.py:310: The number of training batches (7) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n",
+ "\n",
+ " | Name | Type | Params | Mode \n",
+ "-------------------------------------------------------------------------\n",
+ "0 | message_passing | MulticomponentMessagePassing | 480 K | train\n",
+ "1 | agg | NormAggregation | 0 | train\n",
+ "2 | bn | Identity | 0 | train\n",
+ "3 | predictor | RegressionFFN | 602 K | train\n",
+ "4 | X_d_transform | Identity | 0 | train\n",
+ "5 | metrics | ModuleList | 0 | train\n",
+ "-------------------------------------------------------------------------\n",
+ "1.1 M Trainable params\n",
+ "0 Non-trainable params\n",
+ "1.1 M Total params\n",
+ "4.328 Total estimated model params size (MB)\n",
+ "34 Modules in train mode\n",
+ "0 Modules in eval mode\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 7/7 [00:00<00:00, 10.67it/s, v_num=207, train_loss_step=1.940, train_loss_epoch=0.916]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "`Trainer.fit` stopped: `max_epochs=5` reached.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 4: 100%|██████████| 7/7 [00:00<00:00, 10.19it/s, v_num=207, train_loss_step=1.940, train_loss_epoch=0.916]\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "
RandomizedSearchCV(cv=3,\n",
+ " estimator=Pipeline(steps=[('featurizer',\n",
+ " ChempropMulticomponentTransformer(component_types=['reaction',\n",
+ " 'molecule'])),\n",
+ " ('regressor',\n",
+ " ChempropRegressor(epochs=5))]),\n",
+ " n_iter=3,\n",
+ " param_distributions={'regressor__depth': [[3], [6]],\n",
+ " 'regressor__dropout': [0, 0.2],\n",
+ " 'regressor__ffn_hidden_dim': [300, 1000,\n",
+ " 1700,\n",
+ " 2400],\n",
+ " 'regressor__ffn_num_layers': [1, 2]},\n",
+ " scoring='neg_mean_squared_error') In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org. \n",
+ "
\n",
+ "
\n",
+ " Parameters \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " estimator \n",
+ " Pipeline(step...r(epochs=5))]) \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " param_distributions \n",
+ " {'regressor__depth': [[3], [6]], 'regressor__dropout': [0, 0.2], 'regressor__ffn_hidden_dim': [300, 1000, ...], 'regressor__ffn_num_layers': [1, 2]} \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " n_iter \n",
+ " 3 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " scoring \n",
+ " 'neg_mean_squared_error' \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " n_jobs \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " refit \n",
+ " True \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " cv \n",
+ " 3 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " verbose \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " pre_dispatch \n",
+ " '2*n_jobs' \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " random_state \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " error_score \n",
+ " nan \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " return_train_score \n",
+ " False \n",
+ " \n",
+ " \n",
+ " \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
ChempropMulticomponentTransformer
\n",
+ "
\n",
+ "
\n",
+ " Parameters \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " component_types \n",
+ " ['reaction', 'molecule'] \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " keep_h \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " add_h \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " ignore_stereo \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " reorder_atoms \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " smiles_cols \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " rxn_cols \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " target_cols \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " ignore_cols \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " weight_col \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " bounded \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " no_header_row \n",
+ " False \n",
+ " \n",
+ " \n",
+ " \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ " Parameters \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " num_workers \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " batch_size \n",
+ " 64 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " output_dir \n",
+ " PosixPath('ch...-26T09-47-07') \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " checkpoint \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " molecule_featurizers \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " no_descriptor_scaling \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " message_hidden_dim \n",
+ " [300] \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " depth \n",
+ " [3] \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " dropout \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " aggregation \n",
+ " 'norm' \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " ffn_hidden_dim \n",
+ " 1000 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " ffn_num_layers \n",
+ " 1 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " batch_norm \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " multiclass_num_classes \n",
+ " 3 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " accelerator \n",
+ " 'auto' \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " devices \n",
+ " 'auto' \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " epochs \n",
+ " 5 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " patience \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " no_cache \n",
+ " False \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " task_type \n",
+ " 'regression' \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " loss_function \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " metrics \n",
+ " None \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " val_size \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " data_seed \n",
+ " 0 \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " multi_hot_atom_featurizer_mode \n",
+ " 'V2' \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " reaction_mode \n",
+ " <RxnMode.REAC...: 'reac_diff'> \n",
+ " \n",
+ " \n",
+ " \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ "RandomizedSearchCV(cv=3,\n",
+ " estimator=Pipeline(steps=[('featurizer',\n",
+ " ChempropMulticomponentTransformer(component_types=['reaction',\n",
+ " 'molecule'])),\n",
+ " ('regressor',\n",
+ " ChempropRegressor(epochs=5))]),\n",
+ " n_iter=3,\n",
+ " param_distributions={'regressor__depth': [[3], [6]],\n",
+ " 'regressor__dropout': [0, 0.2],\n",
+ " 'regressor__ffn_hidden_dim': [300, 1000,\n",
+ " 1700,\n",
+ " 2400],\n",
+ " 'regressor__ffn_num_layers': [1, 2]},\n",
+ " scoring='neg_mean_squared_error')"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.model_selection import GridSearchCV, RandomizedSearchCV\n",
+ "param_grid = {\n",
+ " 'regressor__dropout': [0,0.2],\n",
+ " 'regressor__depth': [[3], [6]],\n",
+ " 'regressor__ffn_hidden_dim': [300, 1000, 1700, 2400],\n",
+ " 'regressor__ffn_num_layers': [1,2]\n",
+ "}\n",
+ "\n",
+ "grid = GridSearchCV(multicomponent_pipeline, param_grid, cv=3, scoring='neg_mean_squared_error')\n",
+ "\n",
+ "# Alternatively use RandomizedSearchCV to test a number of randomly sampled parametered values from the grid to prevent exploding runtime.\n",
+ "grid = RandomizedSearchCV(multicomponent_pipeline, param_grid, n_iter=3, cv=3, scoring='neg_mean_squared_error')\n",
+ "grid.fit(X, y)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "e6b17970",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Best parameters: {'regressor__ffn_num_layers': 1, 'regressor__ffn_hidden_dim': 1000, 'regressor__dropout': 0, 'regressor__depth': [3]}\n",
+ "Best score (MSE): 8.599092815624193\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"Best parameters:\", grid.best_params_)\n",
+ "print(\"Best score (MSE):\", -grid.best_score_)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "83ac5479",
+ "metadata": {},
+ "source": [
+ "## Saving model(s) & Reloading from checkpoint\n",
+ "Save a model as best.pt with the _save_model method of the regressor object."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "72ebb358",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "best_regressor = grid.best_estimator_[\"regressor\"]\n",
+ "best_regressor.save_model(\"checkpoints\") # make sure to point to an existing directory"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8d348681",
+ "metadata": {},
+ "source": [
+ "Load a model by specifying the checkpoint argument of the regressor with a list of paths to .pt/.ckpt files."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "28144fa1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "model_path = Path(\"checkpoints/best.pt\")\n",
+ "loaded_regressor = ChempropRegressor(checkpoint = [model_path])\n",
+ "\n",
+ "#load multiple models with the ensemble regressor\n",
+ "loaded_ensemble_regressor = ChempropRegressor(checkpoint = [model_path, model_path])"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "chemprop_contrib",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.14"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/chemprop_contrib/sklearn_integration/rxn+mol.csv b/chemprop_contrib/sklearn_integration/rxn+mol.csv
new file mode 100644
index 0000000..a61f37c
--- /dev/null
+++ b/chemprop_contrib/sklearn_integration/rxn+mol.csv
@@ -0,0 +1,401 @@
+rxn_smiles,solvent_smiles,target
+[C:4](=[C:5]=[O:6])([H:12])[H:13].[O:1]([C:2]([C:3](=[C:7]([H:14])[H:15])[H:11])([H:9])[H:10])[H:8]>>[O:1]([C:2]([C:3]1([H:11])[C:4]([H:12])([H:13])[C:5](=[O:6])[C:7]1([H:14])[H:15])([H:9])[H:10])[H:8],O,-3.76
+[O:1]([C:2]1=[N:3][C:4](=[O:5])[C:6]([H:9])([H:10])[N:7]1[H:11])[H:8]>>[O:1]([c:2]1=[n:3][c:4]([O:5][H:9])[c:6]([H:10])[n:7]1[H:11])[H:8],O,3.46
+[C:1]1([H:7])([H:8])[C:2]([H:9])([H:10])[O:3][C:4]([H:11])=[N+:5]=[C-:6]1.[H:12][H:13]>>[C:1]1([H:7])([H:8])[C:2]([H:9])([H:10])[O:3][C:4]([H:11])=[N:5][C:6]1([H:12])[H:13],O,1.54
+[O:1]=[C:2]([C:3]([C:5](=[C:4])[H:9])([H:7])[H:8])[H:6]>>[O:1]=[C:2]([C:3]([C:4]#[C:5][H:9])([H:7])[H:8])[H:6],CCCCCCCCO,-0.54
+[N:1](=[C:2]1\[O:3][C@:4]1([C:6]([C:5]([H:7])([H:10])[H:11])([H:12])[H:13])[H:9])\[H:8]>>[N:1]([C:2](=[O:3])[C:4]1([H:9])[C:5]([H:10])([H:11])[C:6]1([H:12])[H:13])([H:7])[H:8],CCCCCCCCO,-7.56
+[N:1]([c:2]1[c:3]([O:4][H:10])[c:5]([H:11])[c:6]([H:12])[n:7]1[H:13])([H:8])[H:9]>>[N:1]([C@:2]1([H:13])[C:3]([O:4][H:10])=[C:5]([H:11])[C:6]([H:12])=[N:7]1)([H:8])[H:9],CCCCCCCCO,-1.14
+[O:1]=[C:2]1[C:3]([H:8])([H:9])[C:4]([H:10])([H:11])[C@@:5]2([H:12])[C:6]([H:13])([H:14])[C@@:7]12[H:15]>>[O:1]=[C:2]([C@@:7]1([H:15])[C@:5]([C:4](=[C:3]([H:8])[H:9])[H:11])([H:12])[C:6]1([H:13])[H:14])[H:10],CCc1ccccc1,-2.2
+[O:1]([N:2]1[C:3]([H:9])([H:10])[C:4]([H:11])=[C:5][C:6]([H:12])([H:13])[C:7]1([H:14])[H:15])[H:8]>>[O:1]([N:2]1[C:3]([H:10])[C:4]([H:11])=[C:5]([H:9])[C:6]([H:12])([H:13])[C:7]1([H:14])[H:15])[H:8],CCc1ccccc1,-2.19
+[H:7][H:9].[O:1]=[N:2][C:3]1=[C:4]([H:8])[C:5]([H:10])([H:11])[C:6]1([H:12])[H:13]>>[O:1]([N:2]=[C:3]1[C:4]([H:8])([H:9])[C:5]([H:10])([H:11])[C:6]1([H:12])[H:13])[H:7],CCc1ccccc1,-2.32
+[N:1]([C@:2]12[C:3]([H:10])([H:11])[C@@:4]1([H:12])[O:5][C:6]2=[O:7])([H:8])[H:9]>>[N:1]([C:2]([C@@:4]1([H:12])[C:3]([H:10])([H:11])[O:5]1)=[C:6]=[O:7])([H:8])[H:9],C=Cc1ccccc1,-0.11
+[O:1]=[C:2]([c:3]1[c:4]([H:9])[n:5][c:6]([H:10])[n:7]1[H:11])[H:8]>>[O:1]=[C:2]=[C:3]1[C:4]([H:8])([H:9])[N:5]=[C:6]([H:10])[N:7]1[H:11],C=Cc1ccccc1,-0.32
+[C:1]([C:2]([N:3]([C:4]([H:12])([H:13])[H:14])[C:5](=[O:6])[H:15])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1](/[C:2](=[N:3]/[C:5](=[O:6])[H:15])[H:11])([H:7])([H:8])[H:9].[C:4]([H:10])([H:12])([H:13])[H:14],C=Cc1ccccc1,0.82
+[C:1]([C@@:2]1([H:10])[C:3]([H:12])([H:13])[C:4]([H:14])([H:15])/[C:5]1=[N:6]/[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2]([C:3]([C:4]([C:5]#[N:6])([H:14])[H:15])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9],NCc1ccccc1,0.27
+[N:1]([c:2]1[n:3][n:4]([H:9])[n:5][c:6]1[H:10])([H:7])[H:8]>>[N-:4]([N+:5]#[C:6][H:10])[H:9].[N:1]([C:2]#[N:3])([H:7])[H:8],NCc1ccccc1,0.57
+[C:1]([H:8])([H:9])([H:10])[H:14].[C:2]1=[C:3]([H:11])[N:4]([H:12])[C:5](=[O:6])[C:7]=1[H:13]>>[C:1]([C:2]1=[C:3]([H:11])[N:4]([H:12])[C:5](=[O:6])[C:7]1([H:13])[H:14])([H:8])([H:9])[H:10],NCc1ccccc1,-2.84
+[C+:1]([C:2]1=[C:3]([H:10])[N:4]([H:11])[C-:5]([H:12])[C:6]1([H:7])[H:13])([H:8])[H:9]>>[C:1]([c:2]1[c:3]([H:10])[n:4]([H:11])[c:5]([H:12])[c:6]1[H:13])([H:7])([H:8])[H:9],N#Cc1ccccc1,-0.32
+[C:1]([C:2]([C:3]#[C:4][C:5]([O:6][H:14])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2]([C:3](=[C:4]=[C:5]([H:12])[H:13])[O:6][H:14])([H:10])[H:11])([H:7])([H:8])[H:9],N#Cc1ccccc1,-3.65
+[C:1]([C:2]([C:3]([H:12])([H:13])[H:14])([C:4]([C:5]1([H:17])[C:6]([H:18])([H:19])[C:7]1([H:20])[H:21])([H:15])[H:16])[H:11])([H:8])([H:9])[H:10]>>[C:1](=[C:2]([C:3]([H:12])([H:13])[H:14])[H:11])([H:9])[H:10].[C:4](=[C:5]1[C:6]([H:18])([H:19])[C:7]1([H:20])[H:21])([H:15])[H:16].[H:8][H:17],N#Cc1ccccc1,-0.46
+[C:1]1([H:6])([H:7])[C:2]([H:8])([H:9])[C:3]([H:10])=[C:4]([H:11])[C:5]1([H:12])[H:13]>>[C:1]([C:5]([C:4](=[C:3]=[C:2]([H:8])[H:9])[H:11])([H:12])[H:13])([H:6])([H:7])[H:10],OCc1ccccc1,-8.41
+[C:1](=[C:2]([H:10])[H:11])([H:8])[H:9].[C:3]1[C:4]([H:12])([H:13])[C@@:5]2([H:14])[O:6][C@@:7]12[H:15]>>[C:1]1([H:8])([H:9])[C:2]([H:10])([H:11])[C:3]12[C:4]([H:12])([H:13])[C@@:5]1([H:14])[O:6][C@@:7]21[H:15],OCc1ccccc1,-3.6
+[N:1](=[C:2]1[C:3]([O:4][H:10])=[C:5]([H:11])[C-:6]([H:12])[N+:7]1([H:8])[H:13])[H:9]>>[N:1]([c:2]1[c:3]([O:4][H:10])[c:5]([H:11])[c:6]([H:12])[n:7]1[H:13])([H:8])[H:9],OCc1ccccc1,7.53
+[C:1]([C@@:2]1([H:10])[O:3][C@@:4]2([H:11])[C:5]([H:12])([H:13])[C@@:6]12[H:14])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[O+:3]=[C-:4][C:5]([H:12])([H:13])[C:6]1([H:11])[H:14])([H:7])([H:8])[H:9],COc1ccccc1,-1.84
+[C:1]([O:2][C:3](=[O:4])[C:5](=[C:6]([H:13])[H:14])[H:11])([H:8])([H:9])[H:10].[O:7]([H:12])[H:15]>>[C:1]([O:2][C:3](=[O:4])[C:5]([C:6]([O:7][H:15])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],COc1ccccc1,1.07
+[N:1]([C@@:2]([C:3]([C:4]([O:5][H:15])([H:13])[H:14])([H:11])[H:12])([C:6]#[N:7])[H:10])([H:8])[H:9]>>[C:3](=[C:4]([H:13])[H:14])([H:11])[H:12].[N:1](=[C:2](\[C:6]#[N:7])[H:10])\[H:8].[O:5]([H:9])[H:15],COc1ccccc1,0.48
+[C:1]([N:2]([C:3](=[O:4])[C:5]([O:6][H:13])([H:11])[H:12])[H:10])([H:7])([H:8])[H:9]>>[C:1]([N:2]([C-:3]=[O+:4][C:5]([O:6][H:13])([H:11])[H:12])[H:10])([H:7])([H:8])[H:9],c1ccc(Oc2ccccc2)cc1,1.67
+[C:1]([O:2]/[C:3](=[C:4](\[C:5]([O:6][H:16])([H:14])[H:15])[H:12])[H:11])([H:7])([H:8])[H:9].[H:10][H:13]>>[C:1]([O:2][C:3]([C:4]([C:5]([O:6][H:16])([H:14])[H:15])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9],c1ccc(Oc2ccccc2)cc1,-2.7
+[N:1]([C:2](=[O:3])[C:4]([C:5](=[O:6])[H:11])([H:9])[H:10])([H:7])[H:8]>>[N:1]([C:2](=[O:3])[C:5]([C:4]([H:9])([H:10])[H:11])=[O:6])([H:7])[H:8],c1ccc(Oc2ccccc2)cc1,0.86
+[N:1]([C:2](=[O:3])[C:4]([C:5]([O:6][H:13])([H:11])[H:12])([H:9])[H:10])([H:7])[H:8]>>[C:4](=[C:5]([O:6][H:13])[H:11])([H:9])[H:10].[N:1]([C:2](=[O:3])[H:12])([H:7])[H:8],CCCCN(CCCC)CCCC,-2.4
+[C:1]([C-:2]1[N+:3]([H:11])([H:12])[C@:4]1([C:5]([H:13])([H:14])[H:15])[C:6]#[N:7])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C@:4]1([C:5]([H:13])([H:14])[H:15])[C:6]#[N:7])([H:8])([H:9])[H:10],CCCCN(CCCC)CCCC,3.06
+[O+:1](=[C-:2][H:8])[c:3]1[n:4][c:5]([H:9])[n:6][o:7]1>>[O:1]=[C:2]([c:3]1[n:4][c:5]([H:9])[n:6][o:7]1)[H:8],CCCCN(CCCC)CCCC,-0.01
+[O:1]=[C:2]1[C:3]([H:7])([H:8])[N+:4]([H:9])=[C-:5][N:6]1[H:10]>>[O:1]=[C:2]1[C:3]([H:7])([H:8])[N:4]=[C:5]([H:9])[N:6]1[H:10],CCOc1ccccc1,1.66
+[C:1]([C:2]1([H:10])[O:3][C:4]([H:11])([H:12])[C:5]([H:13])([H:14])[O:6]1)([H:7])([H:8])[H:9]>>[C:1]([C:2]1=[O+:3][C-:4]([H:12])[C:5]([H:13])([H:14])[O:6]1)([H:7])([H:8])[H:9].[H:10][H:11],CCOc1ccccc1,-0.41
+[C:1]([C@@:2]1([H:10])[O:3][C@:4]1([C:5]#[C:6][H:12])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[O:3][C:6]([H:12])=[C:5]=[C:4]1[H:11])([H:7])([H:8])[H:9],CCOc1ccccc1,-1.16
+[C:1]([C:2]([C:5]([C:3]#[N:4])=[O:6])([C:7]([H:12])([H:13])[H:14])[H:11])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]([C:3]#[N:4])([C:5](=[O:6])[C:7]([H:12])([H:13])[H:14])[H:11])([H:8])([H:9])[H:10],CCCCC(CO)CC,-6.68
+[C:1]1([H:7])([H:8])[C:2]([H:9])([H:10])[C:3]([H:11])=[C:4]([H:12])[C:5]([H:13])([H:14])[O:6]1>>[C:1]1([H:8])=[O+:6][C:5]([H:13])([H:14])[C:4]([H:12])=[C-:3][C:2]1([H:9])[H:10].[H:7][H:11],CCCCC(CO)CC,-1.4
+[N:1](/[C:2](=[C:3]([C:4](=[C:5](/[C:6]=[N:7][H:14])[H:13])\[H:12])/[H:11])[H:10])([H:8])[H:9]>>[N:1]([C:2]([c:3]1[c:4]([H:12])[c:5]([H:13])[c:6][n:7]1[H:14])([H:10])[H:11])([H:8])[H:9],CCCCC(CO)CC,-2.89
+[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C@:3]1([H:10])[C@@:4]1([H:11])[C:5]([H:12])([H:13])[C@@:6]21[H:14]>>[C:1]1([H:8])=[C:2]([H:9])[C:3]1([C:4]1([H:11])[C:5]([H:12])=[C:6]1[H:14])[H:10].[H:7][H:13],CCOC(CCC)=O,-0.68
+[C:1]([C-:2](/[C:3](=[N:4]/[H:11])[H:10])[N+:6]#[N:5])([H:7])([H:8])[H:9]>>[C:1]([c:2]1[c:3]([H:10])[n:4]([H:11])[n:5][n:6]1)([H:7])([H:8])[H:9],CCOC(CCC)=O,-0.35
+[C:1]([C@:2]1(/[C:3](=[N:4]/[H:12])[H:11])[C:5]([N:6]([H:13])[H:14])=[C:7]1[H:15])([H:8])([H:9])[H:10]>>[C:1]([c:2]1[c:3]([H:11])[n:4]([H:12])[c:5]([N:6]([H:13])[H:14])[c:7]1[H:15])([H:8])([H:9])[H:10],CCOC(CCC)=O,-0.6
+[C:1](=[C:2]([H:9])[H:10])([H:6])[H:8].[C:3](=[C:4]([O:5][H:7])[H:13])([H:11])[H:12]>>[C:1]([C:2]([C:3]([C:4](=[O:5])[H:13])([H:11])[H:12])([H:9])[H:10])([H:6])([H:7])[H:8],Cc1ccc(C)cc1,-0.61
+[C:1]([C:2]([C@:3]([N:4][H:14])([C:5](=[O:6])[O:7][H:15])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([H:8])([H:9])[H:10].[C:2](/[C:3](=[N:4]/[H:14])[H:13])([C:5](=[O:6])[O:7][H:15])([H:11])[H:12],Cc1ccc(C)cc1,0.38
+[C:1]([C:2][C:6]([C:5]([C:3]([O:4][H:12])([H:10])[H:11])([H:13])[H:14])([H:15])[H:16])([H:7])([H:8])[H:9]>>[C:1]([C:2]1([C:3]([O:4][H:12])([H:10])[H:11])[C:5]([H:13])([H:14])[C:6]1([H:15])[H:16])([H:7])([H:8])[H:9],Cc1ccc(C)cc1,0.49
+[C:1]([H:7])([H:8])([H:9])[H:14].[O:2]=[C:3]([C:4]([C:5](=[O:6])[H:13])([H:11])[H:12])[H:10]>>[C:1]([O:2][C@@:3]1([H:10])[C:4]([H:11])([H:12])[C@:5]1([O:6][H:14])[H:13])([H:7])([H:8])[H:9],BrCCBr,0.95
+[C:1]([C@@:2]([C:3]#[N:4])([C:5](=[O:6])[C:7]([H:12])([H:13])[H:14])[H:11])([H:8])([H:9])[H:10]>>[C:1](/[C:2]([C:3]#[N:4])=[C:5](\[O:6][H:11])[C:7]([H:12])([H:13])[H:14])([H:8])([H:9])[H:10],BrCCBr,-1.14
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C:4]([H:14])([H:15])[O:5][C@:6]1([C:7]([H:17])([H:18])[H:19])[H:16])([H:8])([H:9])[H:10]>>[C:1]([C:2]1=[C:6]([H:16])[O:5][C:4]([H:14])([H:15])[C@@:3]1([C:7]([H:17])([H:18])[H:19])[H:12])([H:8])([H:9])[H:10].[H:11][H:13],BrCCBr,-2.11
+[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C@:4]1([C:5](=[O:6])[H:14])[H:13])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C@@:4]2([H:13])[C@:5]1([H:14])[O:6]2)([H:7])([H:8])[H:9],CCCBr,-1.41
+[O:1]([C@:2]12[C:3]([H:8])([H:9])[C@@:4]1([H:10])[C:5]([H:11])([H:12])[C:6]2([H:13])[H:14])[H:7]>>[C:2]12=[C:4]([C:3]1([H:8])[H:9])[C:5]([H:11])([H:12])[C:6]2([H:13])[H:14].[O:1]([H:7])[H:10],CCCBr,-3.59
+[C:1]([N:2]1[C:3]([H:11])([H:12])[C@:4]1([C:5](=[O:6])[C:7]([H:14])([H:15])[H:16])[H:13])([H:8])([H:9])[H:10]>>[C:1]([N+:2]1=[C:3]([H:12])[C@:4]1([C-:5]([O:6][H:11])[C:7]([H:14])([H:15])[H:16])[H:13])([H:8])([H:9])[H:10],CCCBr,0.41
+[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C:3]([H:10])([H:11])[C:4]([H:12])([H:14])[C:5]([H:13])=[C:6]12>>[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C:3]([H:10])([H:11])[C:4]([H:12])=[C:5]([H:13])[C@@:6]12[H:14],CCCC,0.03
+[O:1]=[C:2]([N-:3][N+:4]#[C:5][H:7])[H:6]>>[o:1]1[c:2]([H:6])[n:3][n:4][c:5]1[H:7],CCCC,0.23
+[O:1]=[C:2]([C@@:3]1([H:9])[C:4]([H:10])([H:11])[N:5]1[C:6](=[O:7])[H:12])[H:8]>>[O:1]=[C:2]([C@@:3]1([H:9])[C-:4]([H:10])[N+:5]1=[C:6]([O:7][H:11])[H:12])[H:8],CCCC,-0.07
+[O:1]=[C:2]1[C:3]([H:7])([H:8])[C:4]([H:9])=[C:5]([H:10])[N:6]1[H:11]>>[O-:1][C:2]1=[C:3]([H:7])[C:4]([H:8])([H:9])[C:5]([H:10])=[N+:6]1[H:11],ClCCCl,-3.65
+[N:1]([C:3]1=[C:4]([H:10])[C@:2]1([C:5]#[N:6])[H:9])([H:7])[H:8]>>[N:1]([C@@:2]([C:3]#[C:4][H:10])([C:5]#[N:6])[H:9])([H:7])[H:8],ClCCCl,-2.21
+[C:1]([C@@:2]12[C@:3]3([H:11])[C@@:4]([H:12])([C@:5]3([H:13])[C:6]1)[C:7]2([H:14])[H:15])([H:8])([H:9])[H:10]>>[C:1]([C@:2]12[C@@:3]3([H:11])[C@:4]4([H:12])[C@@:5]3([H:13])[C@@:6]1([H:14])[C@:7]24[H:15])([H:8])([H:9])[H:10],ClCCCl,1.4
+[O:1]([C:2]([C@@:3]1([H:11])[C:4]([H:12])([H:13])[C:5]([H:14])([H:15])[O:6][C:7]1([H:16])[H:17])([H:9])[H:10])[H:8]>>[H:14][H:15].[O:1]([C:2]([C@@:3]1([H:11])[C:4]([H:12])([H:13])[C-:5]=[O+:6][C:7]1([H:16])[H:17])([H:9])[H:10])[H:8],CCCN,-4.98
+[C:1]([C@@:2]([C:3]([O:4][H:13])([H:11])[H:12])([C:5](=[O:6])[H:14])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[C@:5]([C:3]([O:4][H:13])([H:11])[H:12])([H:14])[O:6]1)([H:7])([H:8])[H:9],CCCN,-6.62
+[C:1]([C:2]([O:3][H:11])[C@:4]([N:5]([H:13])[H:14])([C:6]([O:7][H:17])([H:15])[H:16])[H:12])([H:8])([H:9])[H:10]>>[C:1](/[C:2]([O:3][H:11])=[C:4](/[C:6]([O:7][H:17])([H:15])[H:16])[H:12])([H:8])([H:9])[H:10].[N:5]([H:13])[H:14],CCCN,-3.66
+[C:1]([C:2]([C:3]([C:4]([C:5]([H:13])([H:14])[H:15])=[C:6]([H:16])[H:17])([H:11])[H:12])=[O:7])([H:8])([H:9])[H:10]>>[C:1]([C:2]12[C:3]([H:11])([H:12])[C:4]([C:5]([H:13])([H:14])[H:15])([C:6]1([H:16])[H:17])[O:7]2)([H:8])([H:9])[H:10],CCC#N,-2.71
+[C:1]1([H:8])([H:9])[C:2]([H:10])([H:11])[C:3]12[C:4]([H:12])([H:13])[C:5]([H:14])=[C:6]([H:15])[C:7]2([H:16])[H:17]>>[C:1]1([H:8])([H:9])[C:2]([H:10])([H:11])[C:3]12[C:4]([H:13])=[C:5]([H:14])[C:6]([H:15])=[C:7]2[H:17].[H:12][H:16],CCC#N,-1.13
+[O:1]=[C:2]1[C:3]([H:7])([H:8])[C:4][C:5]([H:10])([H:11])[C:6]1([H:9])[H:12]>>[O:1]=[C:2]1[C:3]([H:7])([H:8])[C@@:4]2([H:9])[C:5]([H:10])([H:11])[C@@:6]12[H:12],CCC#N,1.31
+[n:1]1([H:6])[c-:2][n+:3]([H:7])[c:4]([H:8])[n:5]1>>[n:1]1([H:6])[c:2]([H:7])[n:3][c:4]([H:8])[n:5]1,OCCO,6.19
+[C:1]([C:2]([C:3]([H:11])([H:12])[H:13])([O:4][C:5](=[O:6])[H:14])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C:2](=[C:3]([H:11])[H:13])[O:4][C:5](=[O:6])[H:14])([H:7])([H:8])[H:9].[H:10][H:12],OCCO,-0.74
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C@:4]1([C:5]([C:6](=[O:7])[H:17])([H:15])[H:16])[H:14])([H:8])([H:9])[H:10]>>[C:1]1([H:8])([H:10])[C@:2]2([H:11])[C:3]([H:12])([H:13])[C@:4]2([H:14])[C:5]([H:15])([H:16])[C@@:6]1([O:7][H:9])[H:17],OCCO,-4.23
+[C:1]([O:2][C:3]([C:4]([H:11])([H:12])[H:13])=[C:5]=[N:6][H:10])([H:7])([H:8])[H:9]>>[C:1]([O:2][C@@:3]([C:4]([H:11])([H:12])[H:13])([C:5]#[N:6])[H:10])([H:7])([H:8])[H:9],CCCC(C)C,0.34
+[C:1]([C@:2]1([H:10])[N:3]([H:11])[C@@:5]([O:6])([H:14])[C:4]1([H:12])[H:13])([H:7])([H:8])[H:9]>>[C:1]([C@:2]([N:3][H:11])([C:4]([C:5](=[O:6])[H:14])([H:12])[H:13])[H:10])([H:7])([H:8])[H:9],CCCC(C)C,0.03
+[C:1]([C:2]([C:3]([C:4]([C:5]([H:16])([H:17])[H:18])([H:14])[H:15])([N+:7]#[C-:6])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C:3]([C:4]([C:5]([H:16])([H:17])[H:18])([H:14])[H:15])([C:6]#[N:7])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10],CCCC(C)C,0.42
+[C:1](=[C:2]([H:9])[H:10])([H:6])[H:8].[C:3](=[C:4]([O:5][H:7])[H:13])([H:11])[H:12]>>[C:1]([C:2]([C:3]([C:4](=[O:5])[H:13])([H:11])[H:12])([H:9])[H:10])([H:6])([H:7])[H:8],CCCC(C)=O,1.75
+[C:1]([O:2][C:3]([C:4](/[N:5]=[C:6](/[O:7][H:15])[H:16])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([O:2][C:3]([C:4]([N:5]([C:6](=[O:7])[H:16])[H:15])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],CCCC(C)=O,1.69
+[C:1]([C:2](=[O:3])[C:4]([H:10])([H:11])[H:13])([H:7])([H:8])[H:9].[C:5]([O:6][H:14])[H:12]>>[C:1]([C:2](=[O:3])[C:4]([C:5]([O:6][H:14])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9],CCCC(C)=O,6.74
+[C:1]1([H:7])([H:9])[N:2]2[C@:3]1([H:10])[C:4]([H:11])=[C:5]([H:12])[C:6]2([H:8])[H:13]>>[C:1]([n:2]1[c:3]([H:10])[c:4]([H:11])[c:5]([H:12])[c:6]1[H:13])([H:7])([H:8])[H:9],CCCN(=O)=O,-0.71
+[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[N:4]([H:14])[C@:5]1([C:6]#[N:7])[H:15])([H:8])([H:9])[H:10]>>[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[N:4]([H:14])[C:5]([H:15])=[C:6]=[N:7]1)([H:8])([H:9])[H:10],CCCN(=O)=O,-0.44
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])=[C:4]([H:13])[N:5]([H:14])[C:6]1=[O:7])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C:3]([H:12])=[C-:4][N:5]([H:14])[C+:6]1[O:7][H:13])([H:8])([H:9])[H:10],CCCN(=O)=O,2.45
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[O:4][C@:5]([C:6]([H:15])([H:16])[H:17])([H:14])[O:7]1)([H:8])([H:9])[H:10]>>[C:1]([C:2]([O:7][C:5](=[O+:4][C-:3]([H:12])[H:13])[C:6]([H:15])([H:16])[H:17])([H:11])[H:14])([H:8])([H:9])[H:10],CC(=O)CC(C)C,0.58
+[N:1]1=[C-:2][C@@:3]2([H:8])[O+:4]=[C:5]([H:9])[C@@:7]2([H:12])[C:6]1([H:10])[H:11]>>[N:1]#[C:2][C@@:3]1([H:8])[O:4][C@@:5]2([H:9])[C:6]([H:10])([H:11])[C@@:7]12[H:12],CC(=O)CC(C)C,0.95
+[C:1]([O:2][C:3]([C:4]([O:5][C:6]([H:14])([H:15])[H:16])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C-:1]([O+:2]=[C:3]([H:10])[H:11])([H:7])[H:9].[C:4]([O:5][C:6]([H:14])([H:15])[H:16])([H:8])([H:12])[H:13],CC(=O)CC(C)C,0.71
+[C:1](/[C:2](=[C:3](\[C:4]([C:5](=[C:6]=[C:7]([H:16])[H:17])[H:15])([H:13])[H:14])[H:12])[H:11])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C@@:3]2([H:12])[C:4]([H:13])([H:14])[C:5]([H:15])=[C:6]([H:16])[C@@:7]12[H:17])([H:8])([H:9])[H:10],CC(C)OC(C)C,-0.5
+[C:1]1([H:8])([H:9])[C:2]([H:10])([H:11])[C:3]1([C:4]([C@@:5]1([H:14])[C:6]([H:15])([H:16])[C:7]1)([H:12])[H:13])[H:17]>>[C:1]1([H:8])([H:9])[C:2]([H:10])([H:11])[C:3]12[C:4]([H:12])([H:13])[C@@:5]1([H:14])[C:6]([H:15])([H:16])[C@@:7]21[H:17],CC(C)OC(C)C,0.08
+[C:1]([n:2]1[c:3]([H:11])[c:4]([H:12])[c:5]([C:6]([H:13])([H:14])[H:15])[n:7]1)([H:8])([H:9])[H:10]>>[C:1]([N:2]1[C:3]([H:11])=[C+:4][C@@:5]([C:6]([H:13])([H:14])[H:15])([H:12])[N-:7]1)([H:8])([H:9])[H:10],CC(C)OC(C)C,-1.99
+[C:1]([C@@:2]1([O:3][H:11])[C:4]([H:12])([H:13])[C@@:5]2([H:14])[O:6][C@@:7]12[H:15])([H:8])([H:9])[H:10]>>[C:1]([C:2]([O:3][H:11])=[C:4]([H:12])[H:13])([H:8])([H:9])[H:10].[C:5]([O-:6])(=[C+:7][H:15])[H:14],CC(C)OC(C)=O,-3.03
+[C:1]([O:2][C:3]([C:4]([C:5]([H:13])([H:14])[H:15])([C:6]([H:16])([H:17])[H:18])[C:7]([H:19])([H:20])[H:21])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([O+:2]=[C-:3][H:12])([H:8])([H:9])[H:10].[C:4]([C:5]([H:13])([H:14])[H:15])([C:6]([H:16])([H:17])[H:18])([C:7]([H:19])([H:20])[H:21])[H:11],CC(C)OC(C)=O,-0.77
+[C:1](=[C:2]1[C:3]([H:11])=[C:4]([N:5]([H:12])[H:13])[C:6]([H:10])([H:14])[N:7]1[H:15])([H:8])[H:9]>>[C:1]([c:2]1[c:3]([H:11])[c:4]([N:5]([H:12])[H:13])[c:6]([H:14])[n:7]1[H:15])([H:8])([H:9])[H:10],CC(C)OC(C)=O,0.61
+[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C-:4]([H:15])[O+:5]=[C:6]([H:16])[N:7]1[H:14])([H:8])([H:9])[H:10]>>[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C:4]([H:14])([H:15])[O:5][C:6]([H:16])=[N:7]1)([H:8])([H:9])[H:10],Cc1cccc(C)c1,2.48
+[C:1]([C@@:2]1([H:9])[N:3]([H:10])[N:4]1[C:5]([C:6]([H:13])([H:14])[H:15])([H:11])[H:12])([H:7])[H:8]>>[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[N:3]([H:10])[N@@:4]12.[C:5]([C:6]([H:13])([H:14])[H:15])([H:11])[H:12],Cc1cccc(C)c1,0.17
+[N:1](=[C:2]=[C:3]([N:4]=[C:5]([C:6](=[O:7])[H:11])[H:10])[H:9])[H:8]>>[N:1](=[c:2]1/[c:3]([H:9])[n:4][c:5]([H:10])[c:6]([H:11])[o:7]1)\[H:8],Cc1cccc(C)c1,0.52
+[C:1]([O:6]/[C:5](=[N:2]/[C:3](=[O:4])[H:11])[C:7]([H:12])([H:13])[H:14])([H:8])([H:9])[H:10]>>[C:1]([N:2]([C:3](=[O:4])[H:11])[C:5](=[O:6])[C:7]([H:12])([H:13])[H:14])([H:8])([H:9])[H:10],Cc1cccc(O)c1,-1.69
+[C:1]([N:2]1[C:3]([H:11])([H:12])[C@:4]1([C:5](=[O:6])[C:7]([H:14])([H:15])[H:16])[H:13])([H:8])([H:9])[H:10]>>[C:1]([C@@:4]([N:2]=[C:3]([H:11])[H:12])([C:5](=[O:6])[C:7]([H:14])([H:15])[H:16])[H:13])([H:8])([H:9])[H:10],Cc1cccc(O)c1,0.38
+[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C@:4]1([C:5]([N:7]=[C:6]([H:15])[H:16])([H:14])[H:17])[H:13])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C@:4]1([C@@:5]1([H:14])[C:6]([H:15])([H:16])[N:7]1[H:17])[H:13])([H:8])([H:9])[H:10],Cc1cccc(O)c1,-0.97
+[O:1]([C@@:2]1([H:8])[C:3]([H:9])([H:10])[C@:4]1([C:5]#[C:6][H:12])[H:11])[H:7]>>[O:1]([C:2]([C:3]([C-:4]=[C:5]=[C+:6][H:12])([H:9])[H:10])([H:8])[H:11])[H:7],Brc1ccccc1,-0.45
+[C:1]([O:2][C@@:3]1([H:10])[C-:4]=[O+:5][C:6]1([H:13])[H:14])([H:7])([H:8])[H:9].[H:11][H:12]>>[C:1]([O:2][C:3]1([H:10])[C:4]([H:11])([H:12])[O:5][C:6]1([H:13])[H:14])([H:7])([H:8])[H:9],Brc1ccccc1,-0.49
+[N:1](=[C:2]1/[C:3]([H:8])=[C:4]([H:9])[C:5]([H:10])([H:11])[O:6]1)\[H:7]>>[N:1]1([H:7])[C-:2]=[O+:6][C:5]([H:10])([H:11])[C:4]([H:9])=[C:3]1[H:8],Brc1ccccc1,-0.31
+[C:1]([C:2](=[O:3])[C:4]([C:5]([C:6](=[C:7]([H:18])[H:19])[H:16])([H:14])[H:15])([H:12])[H:13])([H:8])([H:9])[H:10].[H:11][H:17]>>[C:1]([C:2]1([O:3][H:11])[C:4]([H:12])([H:13])[C:5]([H:14])([H:15])[C:6]([H:16])([H:17])[C:7]1([H:18])[H:19])([H:8])([H:9])[H:10],CC1CCCCC1,-1.62
+[C:1]([C:2]([C:3]([C:4]([C:5]([O:6][C:7]([H:19])([H:20])[H:21])([H:17])[H:18])([H:15])[H:16])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([H:8])([H:9])([H:10])[H:14].[C:2](=[C:3]([C:4]([C:5]([O:6][C:7]([H:19])([H:20])[H:21])([H:17])[H:18])([H:15])[H:16])[H:13])([H:11])[H:12],CC1CCCCC1,0.02
+[C:1]([C:2]([N:3]([C:4]([O:5][H:13])[H:12])[H:11])([H:9])[H:10])([H:6])([H:7])[H:8]>>[C:1]([C:2]([N:3]([C:4]([O:5][H:13])([H:6])[H:12])[H:11])([H:9])[H:10])([H:7])[H:8],CC1CCCCC1,-0.23
+[O:1]([C@@:2]1([H:9])[C@@:3]2([H:10])[C@@:4]3([H:11])[C:5]([H:12])([H:13])[C@:6]1([H:14])[N:7]23)[H:8]>>[O:1]([C@@:2]1([H:9])[C@@:3]2([H:10])[C:4][C:5]([H:12])([H:13])[C@:6]1([H:14])[N:7]2[H:11])[H:8],Cc1ccccc1,-0.06
+[C:1](=[C:2]=[C:3]1[C:4]([H:9])([H:10])[O:5][C:6]1([H:11])[H:12])([H:7])[H:8]>>[C:1](#[C:2][C:3]1([H:8])[C:4]([H:9])([H:10])[O:5][C:6]1([H:11])[H:12])[H:7],Cc1ccccc1,-1.99
+[C:1]([C:2](/[C:3](=[N:4]/[H:11])[H:10])=[N+:6]=[C-:5][H:12])([H:7])([H:8])[H:9]>>[C:1]([c:2]1[c:3]([H:10])[n:4]([H:11])[c:5]([H:12])[n:6]1)([H:7])([H:8])[H:9],Cc1ccccc1,0.44
+[C:1]([O:2][C:3]([C:4]([C:5](=[O:6])[H:14])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]1([H:7])([H:8])[O:2][C:3]([H:10])([H:11])[C:4]([H:12])([H:13])[C@:5]1([O:6][H:9])[H:14],Clc1ccccc1,-1.27
+[C:1]1([H:7])([H:8])[C@:2]2([H:9])[C@:3]3([H:10])[C:4]([H:11])([H:12])[C@@:5]1([H:13])[C@:6]23[H:14]>>[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C@:3]([C:4]([H:11])([H:12])[H:13])([H:10])[C@@:6]2([H:14])[C:5]1,Clc1ccccc1,-1.49
+[C:1]([C-:2]/[N+:6](=[C:5](\[C:4]#[N:3])[H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([c:2]1[n:3][c:4][c:5]([H:10])[n:6]1[H:11])([H:7])([H:8])[H:9],Clc1ccccc1,0.23
+[C:1]([n:2]1[c:3]([H:10])[c:4]([H:11])[n:5][n:6]1)([H:7])([H:8])[H:9]>>[C:1]([C@:3]1([H:10])[N:2]=[N:6][N:5]=[C:4]1[H:11])([H:7])([H:8])[H:9],OC1CCCCC1,-0.98
+[C:1]([C@@:3]1([H:11])[N:2]=[C:6]([O:7][H:14])[C:5]([H:13])=[C:4]1[H:12])([H:8])([H:9])[H:10]>>[C:1]([n:2]1[c:3]([H:11])[c:4]([H:12])[c:5]([H:13])[c:6]1[O:7][H:14])([H:8])([H:9])[H:10],OC1CCCCC1,2.87
+[C:1]([C:2]([C:3]([C@:4]([N:5]([H:15])[H:16])([C:6]#[N:7])[H:14])([H:12])[H:13])[H:11])([H:8])([H:9])[H:10]>>[C:1]([C@:2]1([H:11])[C:3]([H:12])([H:13])[C@@:4]1([C:6]#[N:7])[H:14])([H:8])([H:9])[H:10].[N:5]([H:15])[H:16],OC1CCCCC1,-0.76
+[C:1]([N:2]1[C@@:3]2([H:11])[C@@:4]([C:7][H:16])([H:12])[C:5]([H:13])([H:14])[C@@:6]12[H:15])([H:8])([H:9])[H:10]>>[C:1]([N:2]1[C@@:3]2([H:11])[C@@:4]3([H:12])[C:5]([H:13])([H:14])[C@:6]1([H:15])[C@@:7]23[H:16])([H:8])([H:9])[H:10],O=C1CCCCC1,0.38
+[C:1]([C@@:2]1([H:10])[O:3][C@:4]1([C:5](=[O:6])[H:12])[H:11])([H:7])([H:8])[H:9]>>[C:1]([O:3][C@:4]([C:2][H:10])([C:5](=[O:6])[H:12])[H:11])([H:7])([H:8])[H:9],O=C1CCCCC1,0.66
+[O:1]=[C:2]([C:3]([O:4][C:5](=[O:6])[H:10])([H:7])[H:8])[H:9]>>[O:1]=[C:2]1[C:3]([H:7])([H:8])[O:4][C:5]([H:9])([H:10])[O:6]1,O=C1CCCCC1,-0.27
+[C:1]1([H:7])([H:8])[N:2]([H:9])[O:6][C:5]([H:12])([H:13])[C:4]([H:11])=[C:3]1[H:10]>>[C:1]1([H:7])([H:8])[N:2]([H:9])[C@:3]1([C@@:4]1([H:11])[C:5]([H:12])([H:13])[O:6]1)[H:10],Cc1ccccn1,-0.55
+[C:1]([C:2]([N:3]1[C:4]([H:12])([H:13])[C@:5]1([C:6]([H:15])([H:16])[H:17])[H:14])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2]([N:3]1[C:4]([H:12])=[C:5]1[H:14])([H:10])[H:11])([H:7])([H:8])[H:9].[C:6]([H:13])([H:15])([H:16])[H:17],Cc1ccccn1,-1.47
+[O:1]([C:2]([C:3]([C:4]#[C:5][H:12])([C:6]#[C:7][H:13])[H:11])([H:9])[H:10])[H:8]>>[O:1]([C:2]([C:3](=[C:4]=[C:5]([H:11])[H:12])[C:6]#[C:7][H:13])([H:9])[H:10])[H:8],Cc1ccccn1,-2.31
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[O:6][C:5]([H:15])([H:16])[C:4]([H:14])[C:7]1([H:17])[H:18])([H:8])([H:9])[H:10]>>[C:1]([C:2]1([H:11])[C:3]([H:12])([H:13])[C:4]([C:5]([O:6])([H:15])[H:16])([H:14])[C:7]1([H:17])[H:18])([H:8])([H:9])[H:10],CCCOC(C)=O,-0.32
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C@:4]([C:5]([H:15])([H:16])[H:17])([H:14])[C@:6]1([C:7]([H:19])([H:20])[H:21])[H:18])([H:8])([H:9])[H:10]>>[C:1]([H:8])([H:9])([H:10])[H:11].[C:2]1[C:3]([H:12])([H:13])[C@:4]([C:5]([H:15])([H:16])[H:17])([H:14])[C@:6]1([C:7]([H:19])([H:20])[H:21])[H:18],CCCOC(C)=O,-1.5
+[C:1]([N:2]([C:3]([C:4]#[N:5])([C:6]#[N:7])[H:12])[H:11])([H:8])([H:9])[H:10]>>[C:1]([N+:2]([C-:3]([C:4]#[N:5])[C:6]#[N:7])([H:11])[H:12])([H:8])([H:9])[H:10],CCCOC(C)=O,-4.3
+[N:1]([C:2](=[O:3])/[N:4]=[C:5](/[O:6][H:9])[H:10])([H:7])[H:8]>>[N:1]([C:2](=[O:3])[N:4]([C:5](=[O:6])[H:10])[H:9])([H:7])[H:8],CCCCC,0
+[C:1]([C:2]1=[N:5][C@@:6]1(/[N:3]=[N:4]/[H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([c:2]1[n:3][n:4]([H:10])[n:5][c:6]1[H:11])([H:7])([H:8])[H:9],CCCCC,-0.46
+[C:1]([C@@:2]1([C+:5]=[N:6][H:10])[C-:3]([H:11])[C:4]1([H:12])[H:13])([H:7])([H:8])[H:9]>>[C:1]([C:2]1([C:5]#[N:6])[C:3]([H:10])([H:11])[C:4]1([H:12])[H:13])([H:7])([H:8])[H:9],CCCCC,0.25
+[C:1]([N:2]([C:3]([C:4]([C:5](=[C:6]([N:7][H:17])[H:16])[H:15])([H:14])[H:18])([H:12])[H:13])[H:11])([H:8])([H:9])[H:10]>>[C:1]([N:2]([C:3](/[C:4](=[C:5](/[C:6]([N:7]([H:17])[H:18])[H:16])[H:15])[H:14])([H:12])[H:13])[H:11])([H:8])([H:9])[H:10],CCCCCl,0.14
+[C:1](/[C:2](=[C:3](/[C:4]([C:5]([H:14])([H:15])[H:17])([H:12])[H:13])[H:11])[C:6](=[O:7])[H:16])([H:8])([H:9])[H:10]>>[C:1]([C:2]1=[C:3]([H:11])[C:4]([H:12])([H:13])[C:5]([H:14])([H:15])[C@:6]1([O:7][H:17])[H:16])([H:8])([H:9])[H:10],CCCCCl,-1.29
+[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[N:4]([H:12])[C@:5]1([C:6](=[O:7])[H:14])[H:13])[H:8]>>[O:1]([C:3]([C@@:2]1([H:9])[N:4]([H:12])[C@:5]1([C:6](=[O:7])[H:14])[H:13])([H:10])[H:11])[H:8],CCCCCl,-0.66
+[C:1]([C:2]([C:3]#[C:4][C:5](=[O:6])[H:12])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]1([H:7])([H:9])[C:2]([H:10])([H:11])[C:3]1=[C:4]([C:5](=[O:6])[H:12])[H:8],CCCCN,-0.98
+[N:1](=[C:2]1/[C:3]([H:8])=[C:4]([H:9])[C:5]([H:10])([H:11])[O:6]1)\[H:7]>>[N:1]([c:2]1[c:3]([H:8])[c:4]([H:9])[c:5]([H:11])[o:6]1)([H:7])[H:10],CCCCN,0.71
+[O:1]([C:2]1=[C:3]([H:6])[O:4][C:5]1([H:8])[H:9])[H:7]>>[O:1]=[C:2]1[C:3]([H:6])([H:7])[O:4][C:5]1([H:8])[H:9],CCCCN,0.73
+[C:1]([C:2](=[C:3]([H:11])[H:13])[H:10])([H:7])([H:8])[H:9].[C:4](=[C:5]=[C:6]([H:12])[H:16])([H:14])[H:15]>>[C:1]([C:2]([C:3]([H:11])([H:12])[H:13])([C:4]([C:5]#[C:6][H:16])([H:14])[H:15])[H:10])([H:7])([H:8])[H:9],CCCC#N,-0.69
+[O:1]([C:2]([O+:4]=[C-:3][C:5]#[C:6][H:10])([H:8])[H:9])[H:7]>>[O:1]([C:2]([C:3](=[O:4])[C:5]#[C:6][H:10])([H:8])[H:9])[H:7],CCCC#N,-1.54
+[C:1]([C:2](=[C:3]=[C:4]([H:10])[H:11])[H:9])(/[C:6](=[N:5]\[H:12])[H:13])([H:7])[H:8]>>[C:1]1([H:7])([H:8])[C:2]([H:9])=[C:3]([H:10])[C@@:4]2([H:11])[N:5]([H:12])[C@@:6]12[H:13],CCCC#N,-1.42
+[C:1]([C:5]([C:4](=[C:3]=[C:2]([H:8])[H:9])[H:11])([H:12])[H:13])([H:6])([H:7])[H:10]>>[C:1]1([H:6])([H:7])[C:2]([H:8])([H:9])[C:3]([H:10])=[C:4]([H:11])[C:5]1([H:12])[H:13],COCCO,-8.49
+[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C@:4]1([C:5]#[N:6])[H:13])([H:7])([H:8])[H:9]>>[C:1]([C:2][C:3]([C:4]([C:5]#[N:6])([H:10])[H:13])([H:11])[H:12])([H:7])([H:8])[H:9],COCCO,-3.15
+[O:1]([C:2]([C:3]1([H:10])[C:4]([H:11])([H:12])[C:5]([H:13])([H:14])[C:6]1([H:15])[H:16])([H:8])[H:9])[H:7]>>[C:5](=[C:6]([H:15])[H:16])([H:13])[H:14].[O:1](/[C:2](=[C:3](/[C:4]([H:8])([H:11])[H:12])[H:10])[H:9])[H:7],COCCO,-2.21
+[O:1]([C@@:2]([C:3]([C:4]#[C:5][H:12])([H:10])[H:11])([C:6]#[C:7][H:13])[H:9])[H:8]>>[O:1]1[C@@:2]([C:6]#[C:7][H:13])([H:9])[C:3]([H:10])([H:11])[C:4]1=[C:5]([H:8])[H:12],C1CCOC1,-0.7
+[C:1]([C:2]1[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[N:5]=[C:6]([H:15])[O:7]1)([H:8])([H:9])[H:10]>>[C:1]([C@:2]12[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[N:5]1[C:6]([H:15])[O:7]2)([H:8])([H:9])[H:10],C1CCOC1,0.45
+[N:1](=[C:2]1/[O:3][C:4]([H:9])([H:10])[C-:5]=[N+:6]1[H:8])\[H:7]>>[N:1](=[C:2](/[O:3][C:4]([C:5]#[N:6])([H:9])[H:10])[H:8])\[H:7],C1CCOC1,2.89
+[C:1]1([H:7])([H:8])[C:2]([H:9])=[C:3]([H:10])[C@@:6]1([C:5](=[O:4])[H:11])[H:12]>>[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C@:3]3([H:10])[O:4][C@@:5]2([H:11])[C@:6]13[H:12],c1ccsc1,-0.95
+[C:1]([C@@:2]1([H:10])[N:3]([H:11])[C@:4]1([C:5]([O:6][H:15])([H:13])[H:14])[H:12])([H:7])([H:8])[H:9]>>[C:1]([C:2](/[N:3]=[C:4](/[C:5]([O:6][H:15])([H:13])[H:14])[H:12])([H:10])[H:11])([H:7])([H:8])[H:9],c1ccsc1,-0.81
+[C:1]([O:2][C:3](=[O:4])[C:5]#[C:6][H:10])([H:7])([H:8])[H:9]>>[C:1](=[O:2])([H:7])[H:9].[c:3]1(=[O:4])[c:5]([H:8])[c:6]1[H:10],c1ccsc1,0.29
+[N:1]1([H:7])/[C:2](=[N:6]\[H:11])[C:3]1([H:8])[H:9].[N:4]#[C:5][H:10]>>[N:1](=[C:2]1\[C:3]([H:8])([H:9])[N:4]=[C:5]([H:10])[N:6]1[H:11])\[H:7],CCCCCC,-0.1
+[C:1]([C@@:2]1([C:5](=[O:6])[N:7]([H:14])[H:15])[C:3]([H:11])([H:12])[N:4]1[H:13])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]([N+:4](=[C-:3][H:11])[H:13])([C:5](=[O:6])[N:7]([H:14])[H:15])[H:12])([H:8])([H:9])[H:10],CCCCCC,0.15
+[C:1]([C@@:2]12[O:3][C@@:4]3([H:11])[C:5]([H:12])([H:13])[C@:6]1([H:14])[C@@:7]23[H:15])([H:8])([H:9])[H:10]>>[C:1]([C@:2]1([H:14])[O:3][C@@:4]2([H:11])[C:5]([H:12])([H:13])[C:6][C@@:7]12[H:15])([H:8])([H:9])[H:10],CCCCCC,-0.66
+[C-:1]1([H:8])[N+:2]([H:7])([H:9])[C:3]12[C:4]([H:10])([H:11])[O:5][C:6]2([H:12])[H:13]>>[C:1]1([H:7])([H:8])[N:2]([H:9])[C:3]12[C:4]([H:10])([H:11])[O:5][C:6]2([H:12])[H:13],CCOCCO,9.67
+[O:1]([C@@:2]1([H:7])[C:3]([H:8])([H:9])[C@:4]1([O:5][H:11])[H:10])[H:6]>>[C:4]([O:5][H:11])[H:10].[O:1]([C:2](=[C:3]([H:8])[H:9])[H:7])[H:6],CCOCCO,-5.74
+[C:1]([C@@:2]12[C:3]([H:11])([H:12])[C@@:4]3([H:13])[O:5][C@:6]1([H:14])[C@@:7]23[H:15])([H:8])([H:9])[H:10]>>[C:1]([C@@:7]1([H:15])[C@@:4]2([H:13])[C:3]([H:11])([H:12])[C:2][C@:6]1([H:14])[O:5]2)([H:8])([H:9])[H:10],CCOCCO,-1.56
+[C:1]([O:2][C:3]([C:6]([C:4]([C:5]([H:14])([H:15])[H:16])([H:13])[H:17])=[O:7])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([O:2][C:3]([C@@:4]([C:5]([H:14])([H:15])[H:16])([C:6](=[O:7])[H:17])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10],C1CCCCC1,-0.89
+[C:1]([C@@:2]([C:3]([O:4][H:12])([H:10])[H:11])([C:5][H:14])[O:6][H:13])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([C:3]([O:4][H:12])([H:10])[H:11])[C:5]([H:13])([H:14])[O:6]1)([H:7])([H:8])[H:9],C1CCCCC1,0.88
+[C:1]([H:7])([H:8])([H:9])[H:10].[N:2]=[C:3]([C:4]([N:5]([C:6]([H:15])([H:16])[H:17])[H:14])([H:12])[H:13])[H:11]>>[C:1]([N:2][C:3]([C:4]([N:5]([C:6]([H:15])([H:16])[H:17])[H:14])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9],C1CCCCC1,-0.89
+[C:1]([O:2][C:3]([N:4][C:5]#[C:6][H:11])=[C:7]([H:12])[H:13])([H:8])([H:9])[H:10]>>[C:1]([O:2][C:3]1=[N:4][C:5]=[C:6]([H:11])[C:7]1([H:12])[H:13])([H:8])([H:9])[H:10],C1=CCCCC1,-0.3
+[C:1]([C@:2]1([H:9])/[C:3](=[N:5]/[H:11])[O:4]1)([H:6])([H:7])[H:8].[H:10][H:12]>>[C:1]([C:2]([C:3](=[O:4])[N:5]([H:11])[H:12])([H:9])[H:10])([H:6])([H:7])[H:8],C1=CCCCC1,-2.48
+[C:1](=[C:2]([c:3]1[c:4]([H:10])[c:5]([H:11])[c:6]([H:12])[n:7]1[H:13])[H:9])[H:8]>>[C-:1](=[C:2]([C:3]1=[C:4]([H:10])[C:5]([H:11])([H:12])[C+:6][N:7]1[H:13])[H:9])[H:8],C1=CCCCC1,-0.44
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C:4]([H:14])=[C:5]([H:15])[C@:6]1([O:7][H:17])[H:16])([H:8])([H:9])[H:10]>>[C:1](=[C:2](/[C:3](=[C:4]([C:5](=[C:6](/[O:7][H:17])[H:16])\[H:15])/[H:14])[H:12])[H:11])([H:8])[H:10].[H:9][H:13],c1ccncc1,-0.73
+[N:1]([C:2]1=[N:7][N+:6](=[N-:5])[C:4]([H:10])=[N:3]1)([H:8])[H:9]>>[N:1]([c:2]1[n:3][c:4]([H:10])[n:5][n:6][n:7]1)([H:8])[H:9],c1ccncc1,3.58
+[N:1]#[C:2][C@@:3]1([H:8])[C:4]([H:9])([H:10])[N:5]=[C:6]([H:11])[N:7]1[H:12]>>[N:1]#[C:2][C@@:3]1([H:8])[C:4]([H:9])=[N:5][C-:6]([H:11])[N+:7]1([H:10])[H:12],c1ccncc1,-3.2
+[C:1]([C@@:2]1([C:5](=[O:6])[N:7]([H:13])[H:14])[C:3]([H:11])([H:12])[O:4]1)([H:8])([H:9])[H:10]>>[C:1]([O:6]/[C:5](=[C:2]1\[C:3]([H:11])([H:12])[O:4]1)[N:7]([H:13])[H:14])([H:8])([H:9])[H:10],C1CCNCC1,-0.6
+[C:1]([C:2]([C:3]([C:4]([N+:6]#[C-:5])([H:14])[H:15])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2]([C:3]([C:4]([C:5]#[N:6])([H:14])[H:15])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9],C1CCNCC1,0.96
+[N:1]([c:2]1[n:3][o:4][c:5]([H:9])[c:6]1[H:10])([H:7])[H:8]>>[C:5](#[C:6][H:10])[H:9].[N:1]([C:2]#[N+:3][O-:4])([H:7])[H:8],C1CCNCC1,-1.74
+[C:1]([C:2]([C:3]([H:11])([H:12])[H:13])([C:4](=[O:5])[N:6]([H:14])[H:15])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C@@:4]([N:6]([H:14])[H:15])([H:10])[O:5]1)([H:7])([H:8])[H:9],CCCCCCO,-5.32
+[C-:6]#[O+:7].[C:1]([C:2]([C:3]([O:4][H:14])=[C:5]([H:15])[H:16])([H:11])[H:12])([H:8])([H:9])[H:10].[H:13][H:17]>>[C:1]([C:2]([C@@:3]([O:4][H:14])([C:5]([C:6](=[O:7])[H:17])([H:15])[H:16])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10],CCCCCCO,-3.93
+[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[C@@:4]2([O:5][H:12])[C:6]([H:13])([H:14])[C@@:7]12[H:15])[H:8]>>[O:1]([C:6]([C@:4]1([O:5][H:12])[C:3]([H:10])([H:11])[C:2]([H:9])=[C:7]1[H:15])([H:13])[H:14])[H:8],CCCCCCO,-0.62
+[C:1]([C:2]([C:3]([H:12])([H:13])[H:14])([N:4]([C:5]([H:15])([H:16])[H:17])[C:6](=[O:7])[H:18])[H:11])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C:3]([H:12])([H:13])[H:14])([H:11])[H:18])([H:8])([H:9])[H:10].[N:4]([C:5]([H:15])([H:16])[H:17])=[C:6]=[O:7],CCCOCCC,-0.66
+[C:1]([C@:5]1([H:10])[C-:4]=[N+:3]=[C:2][N:6]1[H:11])([H:7])([H:8])[H:9]>>[C:1]([c:2]1[n:3][c:4][c:5]([H:10])[n:6]1[H:11])([H:7])([H:8])[H:9],CCCOCCC,2.53
+[H:7][H:8].[O:1]=[C:2]([C:3](=[O:4])[H:9])[C:5]#[N:6]>>[O:1]([C@@:2]([C:3](=[O:4])[H:9])([C:5]#[N:6])[H:8])[H:7],CCCOCCC,-3.42
+[C:1]([C:2]([N:3]([C:4](=[N:5][H:14])[N+:7]#[C-:6])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([N:3](/[C:4](=[N:5]/[H:14])[C:6]#[N:7])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10],OCCOCCO,0.84
+[O:1]=[c:2]1[n:3]([H:7])[c:4]([H:8])[c:5]([H:9])[o:6]1>>[O:1]=[C:2]1[N:3]([H:7])[C:4]([H:8])([H:9])[C-:5]=[O+:6]1,OCCOCCO,-4.7
+[C:6](=[N:7][H:13])([H:11])[H:12].[N:1]([C:2](=[O:3])[C:4](=[O:5])[H:10])([H:8])[H:9]>>[N:1]([C:2](=[O:3])[C:4]([O:5]/[C:6](=[N:7]/[H:13])[H:12])([H:10])[H:11])([H:8])[H:9],OCCOCCO,-2.41
+[O:1]=[C:2]1[C:3]([H:7])([H:8])[C:4]([H:9])=[C:5]([H:10])[C:6]1([H:11])[H:12]>>[O:1]([C:2]1=[C:6]([H:11])[C:5]([H:10])=[C:4]([H:9])[C:3]1([H:7])[H:8])[H:12],CCCCCCCC,0.15
+[O:1](/[C:2](=[C:3](/[C:4]#[N:5])[H:7])[H:6])[H:8]>>[O:1]=[C:2]([C:3]([C:4]#[N:5])([H:7])[H:8])[H:6],CCCCCCCC,0.39
+[C:1]([C:2]([C:3]([H:11])([H:12])[H:13])=[C:4]1[C:5]([H:14])([H:15])[C:6]([H:16])[C:7]1([H:17])[H:18])([H:8])([H:9])[H:10]>>[C:1](=[C:2]([C:3]([H:11])([H:12])[H:13])[C:4]1[C:5]([H:14])([H:15])[C:6]([H:10])([H:16])[C:7]1([H:17])[H:18])([H:8])[H:9],CCCCCCCC,-0.08
+[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C@:4]1([C:5]([O:6][H:16])([H:14])[H:15])[H:13])([H:7])([H:8])[H:9]>>[C:1]([C:2]([C:3]([C@@:4]1([H:13])[C:5]([H:14])([H:15])[O:6]1)([H:11])[H:12])([H:10])[H:16])([H:7])([H:8])[H:9],N#CCCCCC#N,-6.8
+[C:1]([c:2]1[c:3]([H:10])[n:4]([H:11])[c:5]([H:12])[n:6]1)([H:7])([H:8])[H:9]>>[C:1]([N+:6]#[C:2][C-:3]([N+:4](=[C-:5][H:12])[H:11])[H:10])([H:7])([H:8])[H:9],N#CCCCCC#N,-2.96
+[C:1]([c:2]1[c:3]([H:11])[n:4]([H:12])[c:5]([O:6][H:13])[n:7]1)([H:8])([H:9])[H:10]>>[C:1](=[C:2]1[C:3]([H:11])=[N:4][C:5]([O:6][H:13])=[N:7]1)([H:8])[H:9].[H:10][H:12],N#CCCCCC#N,0.39
+[C:1]1([H:6])([H:7])[O:2][C:3]([H:8])([H:9])[C:4]([H:10])=[C:5]1[H:11]>>[C:1]([C:5]#[C:4][H:10])([H:6])([H:7])[H:11].[O:2]=[C:3]([H:8])[H:9],CCCCCCCO,-5.43
+[C:1]([C:2](=[O:3])[C:4]1([H:10])[C:5]([H:11])([H:12])[C:6]1([H:13])[H:14])([H:7])([H:8])[H:9]>>[C:1]1([H:7])([H:9])[C@:2]([C:4]2([H:10])[C:5]([H:11])([H:12])[C:6]2([H:13])[H:14])([H:8])[O:3]1,CCCCCCCO,-1.89
+[C:2](=[C:3]([O:4][C:5]1([H:12])[C:6]([H:13])([H:14])[C:7]1([H:15])[H:16])[H:10])[H:9].[O:1]([H:8])[H:11]>>[O:1]([C:2]([C:3]([O:4][C:5]1([H:12])[C:6]([H:13])([H:14])[C:7]1([H:15])[H:16])([H:10])[H:11])[H:9])[H:8],CCCCCCCO,-0.4
+[C:1]([C@:2]12[C:3]([H:10])([H:11])[C@@:4]1([H:12])[C:5]([H:13])([H:14])[O:6]2)([H:7])([H:8])[H:9]>>[C:1]([C@:2]1([O:6][H:14])[C:3]([H:10])([H:11])[C@:4]1([C:5][H:13])[H:12])([H:7])([H:8])[H:9],OCCOCCCC,-1.22
+[N:1](=[C:2]=[C:3]1[C:4]([H:8])([H:9])[C:5]([H:10])([H:11])[N:6]1[H:12])[H:7]>>[N:1]#[C:2][C@@:3]1([H:7])[C:4]([H:8])([H:9])[C:5]([H:10])([H:11])[N:6]1[H:12],OCCOCCCC,-1.49
+[C:1]([N:2]([C:3](=[O:4])[C:5]([C:6]([H:13])([H:14])[H:15])([C:7]([H:16])([H:17])[H:18])[H:12])[H:11])([H:8])([H:9])[H:10]>>[C:1](=[N:2][H:11])([H:9])[H:10].[C:3](=[O:4])([C:5]([C:6]([H:13])([H:14])[H:15])([C:7]([H:16])([H:17])[H:18])[H:12])[H:8],OCCOCCCC,-0.72
+[N+:1](#[C-:2])[C@@:3]1([H:8])[O:4][C@@:5]2([H:9])[C:6]([H:10])([H:11])[C@@:7]12[H:12]>>[N:1]#[C:2][C@@:3]1([H:8])[O:4][C@@:5]2([H:9])[C:6]([H:10])([H:11])[C@@:7]12[H:12],CCCCCCCCC,0.25
+[C:1]([C:2]([C:3]([C:4]1=[N:6][O:5]1)([H:11])[H:12])([H:10])[H:13])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C:4](=[O:5])[N:6]1[H:13])([H:7])([H:8])[H:9],CCCCCCCCC,-0.13
+[C-:2]1=[O+:7][C:6]([H:15])[N:5]=[C:4]([H:14])[C:3]1([H:11])[H:12].[C:1]([H:8])([H:9])([H:10])[H:13]>>[C:1]([C:2]1[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[N:5]=[C:6]([H:15])[O:7]1)([H:8])([H:9])[H:10],CCCCCCCCC,-1.21
+[C:1]1([H:7])([H:8])[O:2][C@:3]([C:4]([H:11])([H:12])[H:13])([H:10])[C:5]1([H:14])[H:15].[O:6]([H:9])[H:16]>>[C:1]([O:2][C@@:3]([C:4]([H:11])([H:12])[H:13])([C:5]([O:6][H:16])([H:14])[H:15])[H:10])([H:7])([H:8])[H:9],CCCCNCCCC,-0.91
+[C:1]([C@@:2]([O:3][C:4](=[C:5]([H:13])[H:14])[H:11])([O:6][H:12])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C:2]1([H:10])[O:3][C:4]([H:11])([H:12])[C:5]([H:13])([H:14])[O:6]1)([H:7])([H:8])[H:9],CCCCNCCCC,2.11
+[C:1]([C@@:2]1([O:3][H:10])[C:4]([H:11])([H:12])[C@:5]1([O:6][H:14])[H:13])([H:7])([H:8])[H:9]>>[C:1]([C:2]([O:3][H:10])([C:4]([H:11])([H:12])[H:14])[C:5](=[O:6])[H:13])([H:7])([H:8])[H:9],CCCCNCCCC,5.49
+[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[C@:4]2([H:12])[C:5]([H:13])([H:14])[C@@:6]1([H:15])[O:7]2)[H:8]>>[O:1]=[C:2]([C@@:6]([C:5]([C:4](=[C:3]([H:10])[H:11])[H:12])([H:13])[H:14])([O:7][H:8])[H:15])[H:9],CCCCCCCCCCCC,-0.68
+[N:1](=[C:2]1/[C:3]([H:9])([H:10])[C:4]([H:11])([H:12])[C:5]([H:13])([H:14])[C:6]([H:15])([H:16])[O:7]1)\[H:8]>>[N:1](=[C:2](/[C:3]([C:4]([C:5]([C:6](=[O:7])[H:15])([H:13])[H:14])([H:11])[H:12])([H:9])[H:10])[H:16])\[H:8],CCCCCCCCCCCC,0.02
+[O:1]([C:2][C:3]([C:4]([C:5](=[O:6])[H:8])([H:11])[H:12])([H:9])[H:10])[H:7]>>[O:1]([C@@:2]1([H:8])[C:3]([H:9])([H:10])[C:4]([H:11])([H:12])[C:5]1=[O:6])[H:7],CCCCCCCCCCCC,-0.84
+[C:1]([C@@:2]1([H:11])[N:3]=[C:4]1[H:13])([H:8])([H:9])[H:10].[C:5]1([H:14])=[N:7][C:6]1([H:15])[H:16].[H:12][H:17]>>[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C@:4]1([C@@:5]1([H:14])[C:6]([H:15])([H:16])[N:7]1[H:17])[H:13])([H:8])([H:9])[H:10],O=C1CCCC1,-1.7
+[N:1]#[C:2][C:3]1([H:8])[C:4]([H:9])([H:10])[C:5]([H:11])=[C:6]([H:12])[C:7]1([H:13])[H:14]>>[N:1](=[C:2]=[C:3]1[C:4]([H:9])([H:10])[C:5]([H:11])=[C:6]([H:12])[C:7]1([H:13])[H:14])[H:8],O=C1CCCC1,-0.14
+[C:1]1([H:6])([H:7])[C:2]([H:8])([H:9])[C:3]([H:10])([H:11])[O:4][C:5]1([H:12])[H:13]>>[C:1](=[C:5]([H:12])[H:13])([H:6])[H:7].[C:2]1([H:8])([H:9])[C:3]([H:10])([H:11])[O:4]1,O=C1CCCC1,-0.08
+[O:1]([C:2]([C@:3]1([H:11])[C:4]([H:12])=[C:5]([O:6][H:13])[C:7]1([H:14])[H:15])([H:9])[H:10])[H:8]>>[O:1]([C:2]([C:3]1([H:11])[C:4]([H:12])([H:13])[C:5](=[O:6])[C:7]1([H:14])[H:15])([H:9])[H:10])[H:8],CCN(CC)CC,2.16
+[C:1](/[C:2](=[C:4](/[C:5]([H:15])([H:16])[H:17])[H:14])[H:10])([H:7])([H:8])[H:9].[C:3]([O:6][H:18])([H:11])([H:12])[H:13]>>[C:1]([C:2]([C:3]([H:11])([H:12])[H:13])([C@@:4]([C:5]([H:15])([H:16])[H:17])([O:6][H:18])[H:14])[H:10])([H:7])([H:8])[H:9],CCN(CC)CC,1.48
+[C:1]([O:2][C:3]1=[C:7]=[C:6]([H:12])[N:5]([H:11])[N:4]1[H:13])([H:8])([H:9])[H:10]>>[C:1]([O:2][c:3]1[n:4][n:5]([H:11])[c:6]([H:12])[c:7]1[H:13])([H:8])([H:9])[H:10],CCN(CC)CC,1.22
+[N:1]1=[C:2]2[C@@:3]3([H:8])[C:4]([H:9])([H:10])[C@@:6]([H:12])([C@@:5]12[H:11])[C:7]3([H:13])[H:14]>>[N:1]#[C:2][C:3]1([H:8])[C:4]([H:9])([H:10])[C:5]([H:11])=[C:6]([H:12])[C:7]1([H:13])[H:14],CC(C)CCO,-16.73
+[N:1]([c:2]1[c:3]([H:9])[o:4][c:5]([H:10])[n:6]1)([H:7])[H:8]>>[N:1]([c:2]1[c:3]([H:9])[o+:4][c-:5][n:6]1[H:10])([H:7])[H:8],CC(C)CCO,-2.04
+[C:1]([C@:2]12[C:3]([H:10])([H:11])[C@@:4]1([H:12])[C:5]([H:13])([H:14])[C:6]2([H:15])[H:16])([H:7])([H:8])[H:9]>>[C:1]([C@:2]1([H:11])[C@:4]([C:3][H:10])([H:12])[C:5]([H:13])([H:14])[C:6]1([H:15])[H:16])([H:7])([H:8])[H:9],CC(C)CCO,-6.59
+[C:1]([H:7])([H:8])([H:9])[H:11].[C:2](=[O:3])=[C:4]([C:5]([O:6][H:14])([H:12])[H:13])[H:10]>>[C:1]([C:2](=[O:3])[C:4]([C:5]([O:6][H:14])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9],CC(CC(C)=O)=O,-1.89
+[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C:4]([H:14])([H:15])[O:5]/[C:6]1=[N:7]\[H:16])([H:8])([H:9])[H:10]>>[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C-:4]([H:15])[O+:5]=[C:6]1[N:7]([H:14])[H:16])([H:8])([H:9])[H:10],CC(CC(C)=O)=O,0.86
+[N+:1]([C:2]1=[C:6]=[C:5]([H:10])[O:4][C-:3]1[H:9])([H:7])([H:8])[H:11]>>[N:1]([c:2]1[c:3]([H:9])[o:4][c:5]([H:10])[c:6]1[H:11])([H:7])[H:8],CC(CC(C)=O)=O,10.97
+[O:1]=[C:2]1[N:3]([H:8])[C:4]([H:9])([H:10])[C@@:5]2([H:11])[O:6][C@@:7]12[H:12]>>[O:1]=[C:2]([N+:3](=[C:4]([H:9])[H:10])[H:8])[C:7](=[C:5]([O-:6])[H:11])[H:12],C1CCNC1,-2.2
+[C:1]([C:3]1([O:2][H:8])[C:4]([H:9])([H:10])[C:5]([H:11])([H:12])[C:6]1([H:13])[H:14])[H:7]>>[C:1]1([H:7])([H:8])[O:2][C:3]12[C:4]([H:9])([H:10])[C:5]([H:11])([H:12])[C:6]2([H:13])[H:14],C1CCNC1,8.8
+[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[N:4]([H:14])[C:5]([H:15])([H:16])[C:6]1=[O:7])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C:3]([H:11])([H:12])[H:13])=[N:4][H:14])([H:8])([H:9])[H:10].[C:5](=[C:6]=[O:7])([H:15])[H:16],C1CCNC1,-1.63
+[C:5](#[N:6])[H:12].[O:1]([C@@:2]1([C:7]([H:9])([H:13])[H:14])[C:3]([H:10])([H:11])[O:4]1)[H:8]>>[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[O:4][C:5]([H:12])=[N:6][C:7]1([H:13])[H:14])[H:8],CCCCOC(C)=O,-2.68
+[C:1]([C:2]([C@@:3]([C:4]([H:13])([H:14])[H:15])([C:5]([C:6][O:7][H:19])([H:16])[H:17])[H:18])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C@@:3]1([C:4]([H:13])([H:14])[H:15])[C:5]([H:16])([H:17])[C@:6]1([O:7][H:19])[H:18])([H:11])[H:12])([H:8])([H:9])[H:10],CCCCOC(C)=O,1.68
+[N:1](=[C:2](/[O:3][C:4](=[C:5]=[N:6][H:10])[H:9])[H:8])\[H:7]>>[N:1](=[C:2](/[O:3][C:4]([C:5]#[N:6])([H:9])[H:10])[H:8])\[H:7],CCCCOC(C)=O,-0.22
+[N:1](=[C:2]1\[O:3][C:4]([H:9])([H:10])[C@@:5]2([H:11])[C:6]([H:12])([H:13])[C@@:7]12[H:14])\[H:8]>>[H:10][H:14].[N-:1]([C:2]1=[C:7]2[C@@:5]([H:11])([C:4]([H:9])=[O+:3]1)[C:6]2([H:12])[H:13])[H:8],C1COCCO1,-0.77
+[C:1]1([H:7])([H:8])[O:2][C:3]12[C:4]([H:9])([H:10])[O:5][C:6]2([H:11])[H:12]>>[C:1]1([H:7])([H:8])[O+:2]=[C-:3][C:4]1([H:9])[H:10].[O:5]=[C:6]([H:11])[H:12],C1COCCO1,-4.77
+[C:1]([N:2]1[C:3]([H:10])=[C+:4][N:5]([H:11])[N-:6]1)([H:7])([H:8])[H:9]>>[C:1]([n:2]1[c:3]([H:10])[c:4]([H:11])[n:5][n:6]1)([H:7])([H:8])[H:9],C1COCCO1,1.74
+[C:1]([C:2](=[C:3]([H:11])[H:12])[H:10])(/[C:7](=[N:6]\[C:5](=[O:4])[H:13])[H:14])([H:8])[H:9]>>[C:1]1([H:8])([H:9])[C@@:2]2([H:10])[C:3]([H:11])([H:12])[O:4][C:5]([H:13])=[N:6][C@@:7]12[H:14],CCCCCCCCCC,-0.16
+[O:1]([C@@:2]1([H:7])[C:3]([H:8])([H:9])[C@:4]1([O:5][H:11])[H:10])[H:6]>>[C:4]([O:5][H:11])[H:10].[O:1]([C:2](=[C:3]([H:8])[H:9])[H:7])[H:6],CCCCCCCCCC,0.29
+[N:1]([c:2]1[n:3][n:4]([H:10])[c:5]([O:6][H:11])[n:7]1)([H:8])[H:9]>>[N:1]([C@@:5]([N:4]([N-:3])[H:10])([O:6][H:11])[N+:7]#[C:2])([H:8])[H:9],CCCCCCCCCC,-0.73
+[C:1](/[C:2](=[N:3]\[H:11])[H:9])([H:6])([H:7])[H:8].[C:4]=[N:5][H:10]>>[C:1]([C@@:2]([N:3]([H:10])[H:11])([C:4]#[N:5])[H:9])([H:6])([H:7])[H:8],ClC(Cl)=C(Cl)Cl,-6.67
+[O:1]([C:2]([C@@:3]([C:4]#[C:5][H:12])([C:6]#[N:7])[H:11])([H:9])[H:10])[H:8]>>[O:1]([C:2]([C@@:3]([C:5](=[C:4])[H:12])([C:6]#[N:7])[H:11])([H:9])[H:10])[H:8],ClC(Cl)=C(Cl)Cl,-0.59
+[O:1]=[C:2]([C:3]#[N+:4][N-:5][H:7])[H:6]>>[O-:1][C:2](=[C:3]([N+:4]#[N:5])[H:7])[H:6],ClC(Cl)=C(Cl)Cl,1.58
+[C:1]([C:2]([C:3]([C:4]([C:5]#[C:6][H:16])([H:14])[H:15])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2](=[C:3]([H:12])[H:13])[H:10])([H:7])([H:8])[H:9].[C:4](=[C:5]=[C:6]([H:11])[H:16])([H:14])[H:15],CC(=O)N(C)C,0
+[O:1]=[C:2]([C@@:3]1([H:8])[C:4]([H:9])([H:10])[C:5]([H:11])([H:12])[O:6]1)[H:7]>>[O:1]=[C:2]([C:4]1([H:9])[C:3]([H:8])([H:10])[O:6][C:5]1([H:11])[H:12])[H:7],CC(=O)N(C)C,-5.48
+[O+:1](=[C-:2][H:7])[C:3]([O:4][C:5](=[O:6])[H:10])([H:8])[H:9]>>[O:1]=[C:2]([C:3]([O:4][C:5](=[O:6])[H:10])([H:8])[H:9])[H:7],CC(=O)N(C)C,-5.11
+[N+:1]([C:2]1=[C:6]=[N:5][N:4]([H:9])[N-:3]1)([H:7])([H:8])[H:10]>>[N:1]([c:2]1[n:3][n:4]([H:9])[n:5][c:6]1[H:10])([H:7])[H:8],CCC(C)CO,17.95
+[C-:1]1([H:9])[C@@:2]2([H:10])[C@@:3]3([H:11])[C:4]([H:12])([H:13])[C@:5]([H:14])([C:6]3([H:15])[H:16])[N+:7]12[H:8]>>[C:1]1([H:8])([H:9])[C@@:2]2([H:10])[C@@:3]3([H:11])[C:4]([H:12])([H:13])[C@:5]([H:14])([C:6]3([H:15])[H:16])[N:7]12,CCC(C)CO,7.75
+[N:1]([C+:2]1[C@@:3]([O:6][H:12])([H:10])[N:4]([H:11])[C-:5]=[C:7]1[H:13])([H:8])[H:9]>>[N:1]([c:2]1[c:3]([H:10])[n:4]([H:11])[c:5]([O:6][H:12])[c:7]1[H:13])([H:8])[H:9],CCC(C)CO,0.53
+[C:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[C@:4]1([O:5][H:13])[H:12])([H:6])([H:7])[H:8]>>[C:1]([C:2]([C:3]([C:4][O:5][H:13])([H:10])[H:11])([H:9])[H:12])([H:6])([H:7])[H:8],NCCO,-2.95
+[O:1]([C-:2](/[C:3](=[N:4]/[H:9])[H:8])[N+:6]#[N:5])[H:7]>>[O:1]([c:2]1[c:3]([H:8])[n:4]([H:9])[n:5][n:6]1)[H:7],NCCO,-0.23
+[O:1]([C@@:2]1([H:9])[C@@:3]2([H:10])[C@:4]3([H:11])[C:5]([H:12])([H:13])[N:6]2[C@:7]13[H:14])[H:8]>>[H:8][H:9].[O:1]=[C:2]1[C@@:3]2([H:10])[C@:4]3([H:11])[C:5]([H:12])([H:13])[N:6]2[C@:7]13[H:14],NCCO,-4.06
+[C:1]1([H:7])=[C:6]([H:10])[C:5]([H:9])=[N+:4]2[C@:2]1([H:8])[N-:3]2>>[c:1]1([H:7])[c:2]([H:8])[n:3][n:4][c:5]([H:9])[c:6]1[H:10],CCOC(C)=O,0.22
+[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C:4]([H:14])([H:15])[N:5]([H:16])[C:6]1=[O:7])([H:8])([H:9])[H:10]>>[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C:6]([N:5]([C-:4]([H:14])[H:15])[H:16])=[O+:7]1)([H:8])([H:9])[H:10],CCOC(C)=O,0.18
+[C:1]1([H:8])([H:9])[C:2]([H:10])=[C:7]([H:13])[O:6][C@@:5]2([H:12])[O:3][C@@:4]12[H:11]>>[C:1]1([H:8])([H:9])[C@:2]2([H:10])[O:3][C@@:4]1([H:11])[C@:5]1([H:12])[O:6][C@:7]21[H:13],CCOC(C)=O,-3.06
+[C:1](#[C:2][C:3]([C:4]1([H:10])[C:5]([H:11])([H:12])[C:6]1([H:13])[H:14])([H:8])[H:9])[H:7]>>[C:1](=[C:2]=[C:3]([H:8])[H:9])([C:6]([C:4](=[C:5]([H:11])[H:12])[H:10])([H:13])[H:14])[H:7],CCCCCCC,0.17
+[O+:1]1=[C:2][N:7]([H:10])[C:5](=[O:6])[N:4]([H:9])[C-:3]1[H:8]>>[O:1]=[C:2]1[C:3]([H:8])[N:4]([H:9])[C:5](=[O:6])[N:7]1[H:10],CCCCCCC,0.99
+[C:1]([C:2]([O:3]/[C:4](=[N:5]/[H:13])[C:6]#[N:7])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([O+:3]=[C-:4][N:5]([N+:7]#[C-:6])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10],CCCCCCC,-2.14
+[C:1]([C:2]([C:3]1([C:4]([H:12])([H:13])[H:14])[C:5]([H:15])([H:16])[C:6]1([H:17])[H:18])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1](=[C:2]([H:10])[H:11])([H:7])[H:8].[C:3]1([C:4]([H:12])([H:13])[H:14])=[C:6]([H:17])[C:5]1([H:15])[H:16].[H:9][H:18],CCCCOCCCC,-0.85
+[O:1]([C:2]([C+:3]([N:5]([C-:4]([H:10])[H:11])[H:12])[H:9])([H:7])[H:8])[H:6]>>[O:1]([C:2]([C@@:3]1([H:9])[C:4]([H:10])([H:11])[N:5]1[H:12])([H:7])[H:8])[H:6],CCCCOCCCC,0.91
+[C:1]1([H:8])([H:9])[C:2]([H:10])([H:16])[C:3]([H:11])([H:12])[C@:4]2([H:13])[C:5]([H:14])([H:15])[C:6][C@:7]12[H:17]>>[C:1]1([H:8])([H:9])[C@@:2]2([H:10])[C:3]([H:11])([H:12])[C@:4]3([H:13])[C:5]([H:14])([H:15])[C@@:6]2([H:16])[C@:7]13[H:17],CCCCOCCCC,0.56
+[C:1]([C@@:2]1([H:10])[C@:3]([C:4]([H:12])([H:13])[H:14])([H:11])[C@:5]1([O:6][H:16])[H:15])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]([C:3]([C:4]([H:12])([H:13])[H:14])([H:11])[H:15])([C:5][O:6][H:16])[H:10])([H:7])([H:8])[H:9],OCCCCCCCCC,-3.34
+[N:1](=[C:2]1[C+:3]([H:9])[N:4]([H:10])[N-:5][C:6]1([H:7])[H:11])[H:8]>>[N:1]([c:2]1[c:3]([H:9])[n:4]([H:10])[n:5][c:6]1[H:11])([H:7])[H:8],OCCCCCCCCC,-1.63
+[O:1]([C:2][C:3]([C:4]1([O:5][H:12])[C:6]([H:13])([H:14])[C:7]1([H:9])[H:15])([H:10])[H:11])[H:8]>>[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[C@@:4]2([O:5][H:12])[C:6]([H:13])([H:14])[C@@:7]12[H:15])[H:8],OCCCCCCCCC,3.18
+[O:1]([C@@:2]1([H:8])[C:3]([H:9])([H:10])[N:4]([H:11])[C:5]1=[O:6])[H:7]>>[O:1]([C@@:2]1([H:8])[C:5]([N:4]([C-:3]([H:9])[H:10])[H:11])=[O+:6]1)[H:7],ClC=CCl,0.39
+[O:1]([C@@:2]1([H:8])[C:3]([H:9])([H:10])[C:4]([H:11])([H:12])[C:5]([H:13])=[C:6]1[H:14])[H:7]>>[H:7][H:8].[O:1]=[C:2]1[C:3]([H:9])([H:10])[C:4]([H:11])([H:12])[C:5]([H:13])=[C:6]1[H:14],ClC=CCl,-2.09
+[C-:2]([O+:3]=[C:4]([C:5]([O:6][C:7]([H:17])([H:18])[H:19])([H:15])[H:16])[H:13])([H:11])[H:12].[C:1]([H:8])([H:9])([H:10])[H:14]>>[C:1]([C:2]([O:3][C:4]([C:5]([O:6][C:7]([H:17])([H:18])[H:19])([H:15])[H:16])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],ClC=CCl,-0.53
+[C:1]([N+:2]([C:3](=[C:4]=[N:5][H:11])[H:10])=[N-:6])([H:7])([H:8])[H:9]>>[C:1]([n:2]1[c:3]([H:10])[c:4]([H:11])[n:5][n:6]1)([H:7])([H:8])[H:9],C1CCCC1,-0.76
+[C:1]([N:2]([C:3](=[O:4])[C:5]([H:10])([H:11])[H:12])[H:9])([H:6])([H:7])[H:8]>>[C:1]([N:2]=[C:3]=[O:4])([H:6])([H:7])[H:8].[C:5]([H:9])([H:10])([H:11])[H:12],C1CCCC1,0.85
+[O:1]=[C:2]([C:3]([H:7])([H:8])[H:9])[O:6][C:5](=[C:4]([H:10])[H:11])[H:12]>>[O:1]=[C:2]([C:3]([C:4]([C:5](=[O:6])[H:12])([H:10])[H:11])([H:8])[H:9])[H:7],C1CCCC1,-0.95
+[C:1]([C@:2]1([H:14])[N:3]([H:11])[C@:4]1([C:5](=[C:6]=[O:7])[H:13])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C@:2]12[N:3]([H:11])[C@@:4]1([H:12])[C:5]([H:13])([H:14])[C:6]2=[O:7])([H:8])([H:9])[H:10],Fc1c(F)c(F)c(F)c(F)c1F,-2.49
+[C:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[C-:4]=[C:5]([H:13])[C+:6]1[H:14])([H:7])([H:8])[H:12]>>[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C:3]([H:10])([H:11])[C:4]([H:12])=[C:5]([H:13])[C@@:6]12[H:14],Fc1c(F)c(F)c(F)c(F)c1F,1.84
+[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C:4](=[O:5])[N:6]1[H:13])([H:7])([H:8])[H:9]>>[C:1]([C-:2]([N:6]([C:4]1=[O+:5][C:3]1([H:11])[H:12])[H:13])[H:10])([H:7])([H:8])[H:9],Fc1c(F)c(F)c(F)c(F)c1F,1.63
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C@:4]2([C:5]([H:14])([H:15])[O:6]2)[C:7]1([H:16])[H:17])([H:8])([H:9])[H:10]>>[C:1]([C:2](=[C:3]([H:12])[H:13])[H:11])([H:8])([H:9])[H:10].[C:4]1(=[C:7]([H:16])[H:17])[C:5]([H:14])([H:15])[O:6]1,Fc1ccccc1,0.11
+[C:1]1([H:7])([H:8])[N:2]([H:9])[C:3]12[C:4]([H:10])([H:11])[O:5][C:6]2([H:12])[H:13]>>[C:1](=[N:2][H:9])([H:7])[H:8].[C:3]1([H:11])=[C:4]([H:10])[O:5][C:6]1([H:12])[H:13],Fc1ccccc1,-2.95
+[C:1]([C@@:2]([O:3][H:11])([C:4]([C:5](=[O:6])[H:14])([H:12])[H:13])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C:2](=[O:3])[H:10])([H:7])([H:8])[H:9].[C:4](=[C:5]([O:6][H:11])[H:14])([H:12])[H:13],Fc1ccccc1,0.71
+[N:1]([C:2](=[O:3])[C:4]([N:5]1[C:6]([H:12])([H:13])[C:7]1([H:14])[H:15])([H:10])[H:11])([H:8])[H:9]>>[N:1](=[C:2](/[O:3][H:9])[C:4]([N:5]1[C:6]([H:12])([H:13])[C:7]1([H:14])[H:15])([H:10])[H:11])\[H:8],CCCCl,1.31
+[C:1]([C@:2]1([N:3]([H:11])[H:12])[C:4]([H:13])([H:14])[C:5]([H:8])([H:15])[C:6]([H:16])([H:17])[O:7]1)([H:9])[H:10]>>[C:1]([C@:2]1([N:3]([H:11])[H:12])[C:4]([H:13])([H:14])[C:5]([H:15])[C:6]([H:16])([H:17])[O:7]1)([H:8])([H:9])[H:10],CCCCl,0.41
+[C:1]([O:2][C@@:3]([C:4]([H:11])([H:12])[H:13])([C:5]([O:6][H:16])([H:14])[H:15])[H:10])([H:7])([H:8])[H:9]>>[C:1]([O:6][C:5]([C@@:3]([O:2][H:16])([C:4]([H:11])([H:12])[H:13])[H:10])([H:14])[H:15])([H:7])([H:8])[H:9],CCCCl,-0.54
+[C:1](=[C:2]([C@@:3]1([H:12])[C:4]([H:13])([H:14])[C:5]([H:15])=[C:6]=[C:7]1[H:17])[H:11])([H:8])[H:10].[H:9][H:16]>>[C:1]([C@@:2]1([H:11])[C@@:3]2([H:12])[C:4]([H:13])([H:14])[C:5]([H:15])=[C:6]([H:16])[C@@:7]12[H:17])([H:8])([H:9])[H:10],CCCCCCCl,-1.87
+[C:1]([C@@:2]([O+:3]=[C-:4][H:12])([C:5]([C:6]([H:14])([H:15])[H:16])([C:7]([H:17])([H:18])[H:19])[H:13])[H:11])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[O:3][C:4]([H:12])([H:13])[C:5]1([C:6]([H:14])([H:15])[H:16])[C:7]([H:17])([H:18])[H:19])([H:8])([H:9])[H:10],CCCCCCCl,0.16
+[O:1]=[c:2]1[c:3]([H:8])[c:4]([H:9])[n:5]([H:10])[c:6]([H:11])[n:7]1>>[O+:1]1=[C:2]([H:8])[N:7]=[C:6]([H:11])[N:5]([H:10])[C:4]([H:9])=[C-:3]1,CCCCCCCl,1.66
+[C:1]([H:7])([H:8])([H:9])[H:12].[C:2]1([H:10])=[C:3]([H:11])[C:4]([H:13])([H:14])[C@:5]1([O:6][H:16])[H:15]>>[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[C@:5]1([O:6][H:16])[H:15])([H:7])([H:8])[H:9],CCCCCCCCCCCCCCCC,-1.28
+[C:1]([C:2]([C@:3]([N:4][H:14])([C:5](=[O:6])[O:7][H:15])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2](/[N+:4](=[C:3](\[C:5]([O-:6])[O:7][H:15])[H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],CCCCCCCCCCCCCCCC,0.54
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])[C:4]([H:14])=[C:5]([H:15])[C:6]([H:13])([H:16])[O:7]1)([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C:4]([H:14])=[C:5]([H:15])[C:6]([H:16])[O:7]1)([H:8])([H:9])[H:10],CCCCCCCCCCCCCCCC,0.28
+[C:1](/[C:2](=[C:6](/[C:5]1([H:15])[C:3]([H:11])([H:12])[C:4]1([H:13])[H:14])[H:16])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[C:5]([H:15])=[C:6]1[H:16])([H:7])([H:8])[H:9],ClC(Cl)(Cl)Cl,0.11
+[O:1]([C@@:2]1([H:9])[C:3]([H:10])[N:4]([H:11])[C:5]([H:12])([H:13])[C@@:6]1([O:7][H:15])[H:14])[H:8]>>[O:1]([C@@:2](/[C:3](=[N+:4](\[C-:5][H:13])[H:11])[H:10])([C:6]([O:7][H:15])([H:12])[H:14])[H:9])[H:8],ClC(Cl)(Cl)Cl,-0.84
+[C:1]([N:2]([C:3](=[O:4])[C:5]([H:10])([H:11])[H:12])[H:9])([H:6])([H:7])[H:8]>>[C:1]([O:4]/[C:3](=[N:2]/[H:9])[C:5]([H:10])([H:11])[H:12])([H:6])([H:7])[H:8],ClC(Cl)(Cl)Cl,1.28
+[N:1]1([H:7])[C@@:2]2([H:8])[C@:3]1([H:9])[C@@:4]1([H:10])[N:5]([H:11])[C@@:6]21[H:12]>>[N:1]1([H:7])[C@@:2]([C@@:6]2([H:12])[C:4][N:5]2[H:11])([H:8])[C:3]1([H:9])[H:10],OCC(O)CO,0.42
+[C:2]1([H:9])([H:10])[C:3]([H:11])([H:12])[C@@:4]2([H:13])[C@:5]1([H:15])[O:6][C:7]2([H:16])[H:17].[O:1]([H:8])[H:14]>>[O:1]([C:2]([C:3]([C:4]1([H:13])[C:5]([H:14])([H:15])[O:6][C:7]1([H:16])[H:17])([H:11])[H:12])([H:9])[H:10])[H:8],OCC(O)CO,2.25
+[O:1]([C:2]([C:3]1([H:10])[C:4]([H:11])([H:12])[C:5]([H:13])([H:14])[C:6]1([H:15])[H:16])([H:8])[H:9])[H:7]>>[O:1]([C:2]([C@@:3]([C:4]([H:11])([H:12])[H:13])([C:6]([C:5][H:14])([H:15])[H:16])[H:10])([H:8])[H:9])[H:7],OCC(O)CO,-5.82
+[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[O:4][C:5]([H:12])=[N:6][C:7]1([H:13])[H:14])[H:8]>>[O:1]([C:2](=[C:3]([H:10])[H:11])[H:9])[H:8].[O:4]=[C:5]([N:6]=[C:7]([H:13])[H:14])[H:12],Cc1cccnc1C,2.19
+[C:1]([C:2]([C:3]1=[C:5]([C:6]([H:16])([H:17])[H:18])[C:4]1([H:14])[H:15])([H:11])[H:12])([H:8])([H:9])[H:10].[O:7]([H:13])[H:19]>>[C:1]([C:2]([C@@:3]1([H:13])[C:4]([H:14])([H:15])[C@:5]1([C:6]([H:16])([H:17])[H:18])[O:7][H:19])([H:11])[H:12])([H:8])([H:9])[H:10],Cc1cccnc1C,0.21
+[C:1]([O:2][C@@:3]1([H:11])[C:4]([H:12])([H:13])[C@:5]1([C:6]([O:7][H:17])([H:15])[H:16])[H:14])([H:8])([H:9])[H:10]>>[C:1]([O:2][C@@:3]1([H:11])[C:4]([H:12])([H:13])[C:5]1=[C:6]([H:15])[H:16])([H:8])([H:9])[H:10].[O:7]([H:14])[H:17],Cc1cccnc1C,-3.52
+[C:1](=[C:2]([H:11])[H:12])([H:9])[H:10].[C:3](=[C:4]([O:5][H:8])[C:6](=[O:7])[H:15])([H:13])[H:14]>>[C:1]([C:2]([C:3]([C:4](=[O:5])[C:6](=[O:7])[H:15])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],CCC(O)CC,3.87
+[C:1]([C:2]([N:3][N:4]([C:5]([H:13])([H:14])[H:15])[C:6]([C:7]([H:18])([H:19])[H:20])([H:16])[H:17])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([N:3]([N:4]([C:5]([H:13])([H:14])[H:15])[C:6]([C:7]([H:18])([H:19])[H:20])([H:16])[H:17])[H:12])[H:11])([H:8])([H:9])[H:10],CCC(O)CC,0.24
+[C:1]([C@@:2]1([O:3][H:11])[C:4]([H:12])([H:13])[N:5]2[C:6]([H:14])([H:15])[C@@:7]12[H:16])([H:8])([H:9])[H:10]>>[C:1]([C:2]1=[C:7]2[N:5]([C:4]1([H:12])[H:13])[C:6]2([H:14])[H:15])([H:8])([H:9])[H:10].[O:3]([H:11])[H:16],CCC(O)CC,-8.86
+[O:1]([C:3](=[C:2]=[N:6][C:5](=[N:4][H:9])[H:10])[H:8])[H:7]>>[O:1]([c:2]1[c:3]([H:8])[n:4]([H:9])[c:5]([H:10])[n:6]1)[H:7],Ic1ccccc1,-0.1
+[N:1]#[C:2][C:3]([C@@:4]1([H:9])[C:5]([H:10])([H:11])[O:6]1)([H:7])[H:8]>>[N:1]#[C:2][C:3]([C-:4]=[O+:6][C:5]([H:9])([H:10])[H:11])([H:7])[H:8],Ic1ccccc1,-0.96
+[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C@:4]1([C@@:5]1([H:14])[C:6]([H:15])([H:16])[O:7]1)[H:13])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[N:3]([H:12])[O:7][C:6]([H:15])([H:16])[C:5]([H:14])=[C:4]1[H:13])([H:8])([H:9])[H:10],Ic1ccccc1,-1.04
+[C:1]1([H:7])([H:8])[O:2][C@@:3]2([H:9])[C:4]([H:10])([H:11])[O:5][C@@:6]12[H:12]>>[C:1]1([H:7])([H:8])[O:2][C:3]([H:9])=[C:6]([H:12])[O:5][C:4]1([H:10])[H:11],CCCCC(C)=O,1.4
+[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[C@:4]2([H:12])[C:5]([H:13])([H:14])[C@@:6]1([H:15])[O:7]2)[H:8]>>[C:3]1([H:10])([H:11])[C@@:4]2([H:12])[C:5]([H:13])([H:14])[C@:6]1([H:15])[O:7]2.[O:1]([C:2][H:9])[H:8],CCCCC(C)=O,-2.14
+[C:1]([C:2]([N:3]([H:11])[H:13])=[O:4])([H:8])([H:9])[H:10].[C:5]1([H:12])=[C:6]([H:14])[C:7]1([H:15])[H:16]>>[C:1](/[C:2](=[N:3]/[H:11])[O:4][C:5]1([H:12])[C:6]([H:13])([H:14])[C:7]1([H:15])[H:16])([H:8])([H:9])[H:10],CCCCC(C)=O,2.67
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C:4][C:6]([H:15])([H:16])[C@@:7]1([O:5][H:14])[H:17])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C@@:4]2([O:5][H:14])[C:6]([H:15])([H:16])[C@@:7]12[H:17])([H:8])([H:9])[H:10],C=CCCCC,1.07
+[C:1]([C@@:2]1([H:11])[C@@:3]2([H:12])[C:4]([H:13])([H:14])[C:5]([H:15])=[C:6]([H:16])[C@@:7]12[H:17])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C@:3]2([H:12])[C:4]([H:13])([H:14])[C@@:5]1([H:15])[C:6]([H:16])=[C:7]2[H:17])([H:8])([H:9])[H:10],C=CCCCC,-0.08
+[C:1]([C@@:2]1([H:11])[C:3](=[C:4]([H:12])[H:13])[N:5]([H:14])[C:6]1=[O:7])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C:3]([H:12])=[C:4]([H:13])[N:5]([H:14])[C:6]1=[O:7])([H:8])([H:9])[H:10],C=CCCCC,-4.27
+[O:1]([C:2][C:3]([O:4]/[C:5](=[N:6]\[C:7]([H:9])([H:13])[H:14])[H:12])([H:10])[H:11])[H:8]>>[O:1]([C@@:2]1([H:9])[C:3]([H:10])([H:11])[O:4][C:5]([H:12])=[N:6][C:7]1([H:13])[H:14])[H:8],CCOCC,0.31
+[N+:1](#[C-:2])[C@:3]1([H:6])[C:4]([H:7])[C:5]1([H:8])[H:9]>>[N:1]#[C:2][C@:3]1([H:6])[C:4]([H:7])[C:5]1([H:8])[H:9],CCOCC,0.73
+[C:1](=[C:2]([H:11])[H:12])([H:8])[H:9].[C:3]1(=[C:6]=[C:7]([H:10])[H:15])[C:4]([H:13])([H:14])[O:5]1>>[C:1]([C:2]([C@@:3]1([C:6]#[C:7][H:15])[C:4]([H:13])([H:14])[O:5]1)([H:11])[H:12])([H:8])([H:9])[H:10],CCOCC,-0.55
+[O:1]([c:2]1[n:3][n:4]([H:8])[c:5]([H:9])[c:6]1[H:10])[H:7]>>[O:1]([C:2]1=[C:6]([H:10])[C@@:5]2([H:9])[N:3]1[N:4]2[H:8])[H:7],Nc1ccccc1,2.87
+[N:1]1([H:8])[C-:2]=[O+:7][N:6]=[C:5]([H:11])[C:4]([H:10])=[C:3]1[H:9]>>[N:1](=[c:2]1/[c:3]([H:9])[c:4]([H:10])[c:5]([H:11])[n:6][o:7]1)\[H:8],Nc1ccccc1,2.84
+[O:1]=[C:2]([c:3]1[n:4][c:5]([H:9])[c:6]([H:10])[o:7]1)[H:8]>>[O:1]=[C:2]([C:3]([N:4]=[C:5]=[C:6]([H:9])[H:10])=[O:7])[H:8],Nc1ccccc1,-1.75
+[C:1]([C@@:2]1([H:10])[O:3][C@:4]1([C:5]([O:6][H:14])([H:12])[H:13])[H:11])([H:7])([H:8])[H:9]>>[C:1]([H:7])([H:8])([H:9])[H:12].[C@@:2]12([H:10])[O:3][C@:4]1([H:11])[C@:5]2([O:6][H:14])[H:13],CCCC(=O)OC,-2.26
+[O:1]=[C:2]([C@@:3]1([H:9])[C@@:4]2([H:10])[C:5]([H:11])([H:12])[C:6]([H:13])([H:14])[N:7]12)[H:8]>>[O:1]=[C:2](/[C:3](=[N:7]/[C:4]1([H:10])[C:5]([H:11])([H:12])[C:6]1([H:13])[H:14])[H:9])[H:8],CCCC(=O)OC,-1.47
+[N:1]([c:2]1[n:3][n:4]([H:10])[c:5]([O:6][H:11])[n:7]1)([H:8])[H:9]>>[N:1]([c:2]1[n:3]([H:10])[n:4][c:5]([O:6][H:11])[n:7]1)([H:8])[H:9],CCCC(=O)OC,0.67
+[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C:4]([O:5][C:7]([H:14])([H:15])[H:16])=[C:6]1[H:13])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C:4](=[O:5])[C@:6]1([C:7]([H:14])([H:15])[H:16])[H:13])([H:8])([H:9])[H:10],CCCCCOC(C)=O,-0.52
+[C:1]([C@@:2]1([H:10])[O:3][C:4]1=[C:5]([H:12])[H:13])([H:7])([H:8])[H:9].[O:6]([H:11])[H:14]>>[C:1]([C@@:2]1([H:10])[O:3][C@:4]1([C:5]([O:6][H:14])([H:12])[H:13])[H:11])([H:7])([H:8])[H:9],CCCCCOC(C)=O,-1
+[C:1]([O:2][H:12])([H:8])([H:9])[H:10].[C:3](=[O:4])=[C:5]([C:6]([O:7][H:15])([H:13])[H:14])[H:11]>>[C:1]([O:2][C:3](=[O:4])[C:5]([C:6]([O:7][H:15])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],CCCCCOC(C)=O,2.3
+[O:1]([C:2]1([H:9])[C:3]([H:10])([H:11])[N:4]([C:6](=[O:7])[H:14])[C:5]1([H:12])[H:13])[H:8]>>[C:2]1([H:9])=[C:3]([H:10])[N:4]([C:6](=[O:7])[H:14])[C:5]1([H:12])[H:13].[O:1]([H:8])[H:11],CCCCCC#N,0.16
+[C:1]1([H:4])([H:5])[C:2]([H:6])([H:7])[O:3]1>>[C:1]1([H:4])([H:5])[C-:2]=[O+:3]1.[H:6][H:7],CCCCCC#N,-0.34
+[C:1]([C@@:2]1([H:11])[N:3]([H:12])[N:6]([O:7][H:15])[C:5]1=[C:4]([H:13])[H:14])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[N:3]([H:12])[C:4]([H:13])([H:14])/[C:5]1=[N:6]\[O:7][H:15])([H:8])([H:9])[H:10],CCCCCC#N,-1.61
+[N:1](=[C:2]1/[C:3]([H:8])=[C:4]([C:5]([H:9])([H:10])[H:11])[O:6]1)\[H:7]>>[N:1](=[C:2]1/[C:3]([H:8])=[C:4]([H:9])[C:5]([H:10])([H:11])[O:6]1)\[H:7],CCO,-13.72
+[O:1]=[C:2]([C@:6]1([H:14])[C:5]([H:12])([H:13])[C@:4]2([H:11])[C:3]([H:8])([H:10])[N:7]21)[H:9]>>[O:1]([C@@:2]1([H:9])[C@@:3]2([H:10])[C@@:4]3([H:11])[C:5]([H:12])([H:13])[C@:6]1([H:14])[N:7]23)[H:8],CCO,-1.76
+[O:1]([C:2]([c:3]1[n:4][o:5][c:6]([H:11])[c:7]1[H:12])([H:9])[H:10])[H:8]>>[O:1]([C:2]([C:3]1=[C:7]=[C:6]([H:11])[O:5][N:4]1[H:12])([H:9])[H:10])[H:8],CCO,-6.14
+[C:1](/[C:4]([C:3]([C:2]([H:9])[H:10])([H:11])[H:12])=[N:5]\[H:13])([H:6])([H:7])[H:8]>>[C:1]([C:2]([C:3]([C:4]=[N:5][H:13])([H:11])[H:12])([H:9])[H:10])([H:6])([H:7])[H:8],CC(=O)O,1.77
+[N:1]([C:2]1=[N:7][N:6]2[C@@:3]1([H:10])[N:4]=[C:5]2[H:11])([H:8])[H:9]>>[N:1]([c:2]1[c:3]([H:10])[n:4][c:5]([H:11])[n:6][n:7]1)([H:8])[H:9],CC(=O)O,-0.89
+[c:1]1([H:7])[c:2]([H:8])[n:3][n:4][c:5]([H:9])[c:6]1[H:10]>>[C:1]1([H:7])=[C:6]=[C:5]([H:9])[N-:4][N:3]([H:10])[C+:2]1[H:8],CC(=O)O,4.45
+[C:1]([C@:2]1([H:11])[C@:5]([O+:4]=[C-:3][H:12])([H:13])[C@:6]1([O:7][H:15])[H:14])([H:8])([H:9])[H:10]>>[C:1]([C@:2]12[C:3]([H:11])([H:12])[O:4][C@@:5]1([H:13])[C@:6]2([O:7][H:15])[H:14])([H:8])([H:9])[H:10],CO,2.54
+[C:1]([C@@:2]([O:3][H:12])([C@@:4]([C:5]([H:14])([H:15])[H:16])([C:6]#[N:7])[H:13])[H:11])([H:8])([H:9])[H:10]>>[C:1](/[C:2]([O:3][H:12])=[C:4](/[C:5]([H:14])([H:15])[H:16])[C:6]#[N:7])([H:8])([H:9])[H:10].[H:11][H:13],CO,-4.7
+[C:1]([C@@:2]([C@@:3]([C:4]([H:12])([H:13])[H:14])([O:6][H:16])[H:11])([C:5][H:15])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[C@:3]([C:4]([H:12])([H:13])[H:14])([H:11])[C@:5]1([O:6][H:16])[H:15])([H:7])([H:8])[H:9],CO,2.07
+[C:1]([C@@:2]12[C:3]([H:11])([H:12])[C@:4]1([O:5][H:13])[C:6]([H:14])([H:15])[O:7]2)([H:8])([H:9])[H:10]>>[C:1]([C:2]1=[O+:7][C-:6]([H:15])[C@:4]1([C:3]([H:11])([H:12])[H:14])[O:5][H:13])([H:8])([H:9])[H:10],CC(C)O,1.08
+[C:1]([C:2]1=[C:3]([H:11])[C:4]([H:12])([H:13])[C@@:5]2([H:14])[O:6][C@@:7]12[H:15])([H:8])([H:9])[H:10]>>[C:1]([C:2]1=[C:7]2[C@@:5]([H:14])([C:4]([H:12])([H:13])[C:3]1([H:11])[H:15])[O:6]2)([H:8])([H:9])[H:10],CC(C)O,0.33
+[O:1]([C:4](=[C:3]=[C:2]([H:8])[H:9])[C:5]([O:6][H:12])([H:10])[H:11])[H:7]>>[O:1]([C:2]([C:3]#[C:4][C:5]([O:6][H:12])([H:10])[H:11])([H:8])[H:9])[H:7],CC(C)O,-9.44
+[C:1]([N:2]([C:3](=[O:4])[N:5]([C-:6]=[N+:7]([H:13])[H:14])[H:12])[H:11])([H:8])([H:9])[H:10]>>[C:1]([N:2]([C:3](=[O:4])[N:5](/[C:6](=[N:7]/[H:14])[H:13])[H:12])[H:11])([H:8])([H:9])[H:10],CC(C)=O,3.89
+[O:1]([C:2]1([C:5](=[O:6])[H:12])[C:3]([H:8])([H:9])[C:4]1([H:10])[H:11])[H:7]>>[O:1]([C:2]([C:5]1([H:12])[C:3]([H:8])([H:9])[C:4]1([H:10])[H:11])=[O:6])[H:7],CC(C)=O,-5.58
+[N:1](=[C:2]=[C:3]([C@@:4]1([H:9])[C:5]([H:10])([H:11])[O:6]1)[H:8])[H:7]>>[N:1]#[C:2][C:3]([C@@:4]1([H:9])[C:5]([H:10])([H:11])[O:6]1)([H:7])[H:8],CC(C)=O,-2.45
+[C:1]([C:2]([C:4](=[O:5])[C:6](=[O:7])[H:15])([H:11])[H:13])([H:8])([H:9])[H:10].[O:3]([H:12])[H:14]>>[C:1]([C@@:2]([O:3][H:12])([C@@:4]([O:5][H:14])([C:6](=[O:7])[H:15])[H:13])[H:11])([H:8])([H:9])[H:10],ClC(Cl)Cl,-5.36
+[C:1]([C:2]([N:3]1[C:4]([H:11])([H:12])[C:5]1([H:13])[H:14])([H:9])[H:10])([H:6])([H:7])[H:8]>>[C:1]([C-:2]([N+:3]1=[C:5]([H:14])[C:4]1([H:11])[H:12])[H:10])([H:6])([H:7])[H:8].[H:9][H:13],ClC(Cl)Cl,-0.44
+[C:1]([C@@:2]12[C:3]([H:11])([H:12])[C@:4]1([O:5][H:13])[C:6]([H:14])([H:15])[O:7]2)([H:8])([H:9])[H:10]>>[C:1]([C:2]1=[C:4]([O:5][H:13])[C:6]([H:14])([H:15])[O:7][C:3]1([H:11])[H:12])([H:8])([H:9])[H:10],ClC(Cl)Cl,-4.34
+[O:1]=[C:2]([C:3]#[C:4][C:5](=[O:6])[H:8])[H:7]>>[C-:3]#[C:4][C+:5]([O:6][H:7])[H:8].[O+:1]#[C-:2],CS(C)=O,0.36
+[C:1](=[C:2](/[C:3](=[N:4]\[C:5]([N:6]([H:12])[H:13])=[O:7])[H:11])[H:9])([H:8])[H:10]>>[C:1]([c:2]1[c:3]([H:11])[n:4][c:5]([N:6]([H:12])[H:13])[o:7]1)([H:8])([H:9])[H:10],CS(C)=O,-1.45
+[O:1]([N:2]=[C:3]=[C:4]([C:5]([C:6]([O:7][H:14])([H:9])[H:13])([H:11])[H:12])[H:10])[H:8]>>[O:1](/[N:2]=[C:3]1/[C:4]([H:9])([H:10])[C:5]([H:11])([H:12])[C@:6]1([O:7][H:14])[H:13])[H:8],CS(C)=O,1.13
+[C:1]([C@@:2]1([C:5](=[O:6])[H:13])[C:3]([H:10])([H:11])[N:4]1[H:12])([H:7])([H:8])[H:9]>>[C:1]([O:6]/[C:5](=[C:2]1/[C:3]([H:10])([H:11])[N:4]1[H:12])[H:13])([H:7])([H:8])[H:9],CN(C)C=O,-0.6
+[C:1]([C:2](=[O:3])[C:4]([C:5]([N:7]([H:18])[H:19])[H:14])([H:12])[H:13])([H:8])([H:9])[H:10].[C:6]([H:11])([H:15])([H:16])[H:17]>>[C:1]([C:2]([O:3][H:11])[C:4]([C@:5]([C:6]([H:15])([H:16])[H:17])([N:7]([H:18])[H:19])[H:14])([H:12])[H:13])([H:8])([H:9])[H:10],CN(C)C=O,-2.55
+[N-:1]=[C:2]=[C+:3][C:4]([C:5]([C:6]([H:7])([H:12])[H:13])([H:10])[H:11])([H:8])[H:9]>>[N:1]#[C:2][C:3]1([H:7])[C:4]([H:8])([H:9])[C:5]([H:10])([H:11])[C:6]1([H:12])[H:13],CN(C)C=O,-1.05
+[C:1]([C:2][C:3]([H:10])([H:11])[H:12])([H:7])([H:8])[H:9].[O:4]([C:5]([O:6][H:16])([H:14])[H:15])[H:13]>>[C:1]([C:2]([C:3]([H:10])([H:11])[H:12])([O:4][H:13])[C:5]([O:6][H:16])([H:14])[H:15])([H:7])([H:8])[H:9],CCCO,4.57
+[C:1]([C:2]1[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[N:5]=[C:6]([H:15])[O:7]1)([H:8])([H:9])[H:10]>>[C:1]([C:2]([C:3]([C:4]([H:13])[H:14])([H:11])[H:12])=[O:7])([H:8])([H:9])[H:10].[N:5]#[C:6][H:15],CCCO,-0.02
+[C:1]([N:2]1[C:3]([H:10])([H:11])[C:4]1([C:5]([H:12])([H:13])[H:14])[C:6]([H:15])([H:16])[H:17])([H:7])([H:8])[H:9]>>[C:1]([N+:2]1([H:10])[C-:3]([H:11])[C:4]1([C:5]([H:12])([H:13])[H:14])[C:6]([H:15])([H:16])[H:17])([H:7])([H:8])[H:9],CCCO,-3.9
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C@@:4]2([O:5][H:14])[C:6]([H:15])([H:16])[C@@:7]12[H:17])([H:8])([H:9])[H:10]>>[C:1]1([H:8])([H:9])[C@@:2]2([H:11])[C:3]([H:12])([H:13])[C@@:4]([O:5][H:14])([C:6]([H:10])([H:15])[H:16])[C@@:7]12[H:17],CCCCO,-0.3
+[C:1]1([H:7])=[C:2]=[C:3]([H:8])[O:4][C@@:5]1([C:6]([H:10])[H:11])[H:9]>>[C:1](=[C:2]=[C:3]([O:4][C:5](=[C:6]([H:10])[H:11])[H:9])[H:8])[H:7],CCCCO,5.96
+[C:1]([C@@:2]1([H:8])[C:3]([H:9])([H:10])[O:4]1)([H:5])([H:6])[H:7]>>[C:1](=[C:2]([H:6])[H:8])([H:5])[H:7].[C:3](=[O:4])([H:9])[H:10],CCCCO,-9.37
+[C:1]([C:2]([C:3]#[C:4][C:5]([O:6][H:14])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2](=[C:3]=[C:4]([C:5]([O:6][H:14])([H:12])[H:13])[H:10])[H:11])([H:7])([H:8])[H:9],CCCCCO,-4.31
+[C:1]([C:2][C:3]([C:4]([C@@:5]1([H:15])[C:6]([H:16])([H:17])[O:7]1)([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C@:2]12[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[C@@:5]1([H:15])[C:6]([H:16])([H:17])[O:7]2)([H:8])([H:9])[H:10],CCCCCO,1.86
+[C:1]([C:2]([C:3]([H:11])([H:12])[H:13])([C:4](=[O:5])[N:6]([H:14])[H:15])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C:2]1([C:3]([H:11])([H:12])[H:13])[C@@:4]([N:6]([H:14])[H:15])([H:10])[O:5]1)([H:7])([H:8])[H:9],CCCCCO,-5.39
+[C:1]([C:2]([C@@:3]([O:4][H:14])([C@@:5]([C:6]([H:16])([H:17])[H:18])([O:7][H:19])[H:15])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2](/[C:3](=[C:5](\[C:6]([H:16])([H:17])[H:18])[O:7][H:19])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10].[O:4]([H:14])[H:15],c1ccccc1,-0.28
+[C:1]([N:2][C:3]([C:4]([N:5]([C:6]([H:15])([H:16])[H:17])[H:14])([H:12])[H:13])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([N-:2][C:3]([C+:4][N:5]([C:6]([H:15])([H:16])[H:17])[H:14])([H:10])[H:11])([H:7])([H:8])[H:9].[H:12][H:13],c1ccccc1,-0.57
+[C:1]([O:6]/[C:5](=[C:2](\[C:3](=[O:4])[H:11])[H:10])[H:12])([H:7])([H:8])[H:9]>>[C:1]([C:2]([C:3](=[O:4])[H:11])([C:5](=[O:6])[H:12])[H:10])([H:7])([H:8])[H:9],c1ccccc1,0.8
+[N:1]#[C:2][C@:3]1([H:6])[C:4]([H:7])[C:5]1([H:8])[H:9]>>[N:1]=[C:2]=[C:3]([C:4](=[C:5]([H:8])[H:9])[H:7])[H:6],CC(Cl)(Cl)Cl,-0.24
+[C:1]([O:2][C:3]([C@@:4]1([H:13])[C:5]([H:14])([H:15])[C@:6]1([O:7][H:17])[H:16])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([O:2][C:3]([C:4][C:5]([C:6]([O:7][H:17])([H:13])[H:16])([H:14])[H:15])([H:11])[H:12])([H:8])([H:9])[H:10],CC(Cl)(Cl)Cl,-0.72
+[C:1]1([H:6])=[C:2]=[C:3]([H:7])[C:4]([H:8])([H:9])[O:5]1>>[C:1](#[C:2][C@@:3]1([H:7])[C:4]([H:8])([H:9])[O:5]1)[H:6],CC(Cl)(Cl)Cl,3.17
+[C:1]([C@:2]([N:3]([H:11])[H:12])([C:4](=[C:5]([O:6])[H:14])[H:13])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C@:2]([N:3][H:11])([C:4]([C:5](=[O:6])[H:14])([H:12])[H:13])[H:10])([H:7])([H:8])[H:9],CI,0.54
+[C:1]1([H:7])([H:8])[C:2]([H:9])([H:12])[C:6]1([C:5](=[C:4]=[C:3]([H:10])[H:11])[H:13])[H:14]>>[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C:3]([H:10])([H:11])[C:4]([H:12])=[C:5]([H:13])[C@@:6]12[H:14],CI,-4.55
+[O:1]([C@@:2]1([H:8])[N:3]([H:9])[C:4]([H:10])([H:11])[C:5]([H:12])=[C:6]=[C:7]1[H:14])[H:13]>>[O:1]=[C:2]([N:3]([C:4]([C:5]([C:6]#[C:7][H:14])([H:12])[H:13])([H:10])[H:11])[H:9])[H:8],CI,-0.46
+[C:1]([N:2]1[C:3]([H:10])([H:11])[C@:4]1([C:5](=[O:6])[H:13])[H:12])([H:7])([H:8])[H:9]>>[C:1](=[N+:2]1[C:3]([H:10])([H:11])[C:4]1=[C:5]([O-:6])[H:13])([H:7])[H:8].[H:9][H:12],CCBr,-0.57
+[C:1](/[C:2](=[N:3]/[H:11])[O:4][C:5]1([H:12])[C:6]([H:13])([H:14])[C:7]1([H:15])[H:16])([H:8])([H:9])[H:10]>>[C:1](/[C:2](=[N:3]/[H:11])[O:4][C@:5]([C:6][H:13])([C:7]([H:14])([H:15])[H:16])[H:12])([H:8])([H:9])[H:10],CCBr,-1.56
+[O:1]=[C:2]([c:3]1[c:4]([H:9])[n:5][c:6]([H:10])[n:7]1[H:11])[H:8]>>[O:1]=[C:2]([c:3]1[c-:4][n:5]([H:9])[c+:6]([H:10])[n:7]1[H:11])[H:8],CCBr,-1.03
+[C:1]1([H:8])([H:9])[C:2]([H:10])([H:11])[C:3]12[C:4]([H:12])([H:13])[C@@:5]1([H:14])[O:6][C@@:7]21[H:15]>>[C:1]1([H:8])([H:9])[C:2]([H:10])([H:11])[C:3]1([C@@:7]1([H:15])[C@:5]([C:4][H:12])([H:14])[O:6]1)[H:13],CCC,-0.64
+[N:1]([C:2](=[O:3])[C:4]([O:5]/[C:6](=[N:7]/[H:13])[H:12])([H:10])[H:11])([H:8])[H:9]>>[N:1]([C:2](=[O:3])[C:4]([N:7]([C:6](=[O:5])[H:12])[H:13])([H:10])[H:11])([H:8])[H:9],CCC,0.18
+[O:1]([C+:2]([N:3]([C:4](=[C:5]=[N-:6])[H:10])[H:8])[H:7])[H:9]>>[O:1]=[C:2]([N:3]([C:4]([C:5]#[N:6])([H:9])[H:10])[H:8])[H:7],CCC,-0.57
+[C:1](/[C:2]([C:3](=[C:4]([H:12])[H:13])[H:11])=[C:7](/[C:5](=[O:6])[H:14])[H:15])([H:8])([H:9])[H:10]>>[C:1]([C:2]1=[C:3]([H:11])[C:4]([H:12])([H:13])[C@@:5]2([H:14])[O:6][C@@:7]12[H:15])([H:8])([H:9])[H:10],CCI,-2.29
+[C:1]([C:2]([C@@:3]1([H:12])[C:4]([H:13])([H:14])[C:5]([H:15])([H:16])[O:6]1)([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2](/[C:3](=[C:4](/[C:5]([O:6][H:13])([H:15])[H:16])[H:14])[H:12])([H:10])[H:11])([H:7])([H:8])[H:9],CCI,-0.43
+[C:1]([C@@:2]([O:3][H:11])([C@@:4]1([H:12])[C:5]([H:13])([H:14])[N:6]1[H:15])[H:10])([H:7])([H:8])[H:9]>>[C:1](/[C:2](=[C:4]1\[C:5]([H:13])([H:14])[N:6]1[H:15])[H:10])([H:7])([H:8])[H:9].[O:3]([H:11])[H:12],CCI,-0.85
+[C:1]([N:2]([C:3]([H:10])([H:11])[H:12])[C:4]([C:5]#[N:6])([H:13])[H:14])([H:7])([H:8])[H:9]>>[C:1]([N+:2]([C:3]([H:10])([H:11])[H:12])([C-:4]([C:5]#[N:6])[H:13])[H:14])([H:7])([H:8])[H:9],CCN,-2.78
+[C:1]([C@@:2]1([H:10])[O:3][C@:4]1([C:5]#[N:6])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]([O:3][C:5]#[N:6])([C:4][H:11])[H:10])([H:7])([H:8])[H:9],CCN,-2.71
+[C:1]([c:2]1[c:3]([H:10])[o:4][n:5][n:6]1)([H:7])([H:8])[H:9]>>[C:1]([C:2]1([C:3](=[O:4])[H:10])[N:5]=[N:6]1)([H:7])([H:8])[H:9],CCN,0.2
+[C:1]([c:2]1[n:3][c:4][c:5]([H:10])[n:6]1[H:11])([H:7])([H:8])[H:9]>>[C:1](/[C:2]([C:4]#[N:3])=[N+:6](/[C-:5][H:10])[H:11])([H:7])([H:8])[H:9],CC#N,0.07
+[C:1]([C:2]([N:3]([C:4](=[O:5])[H:12])[H:11])([H:9])[H:10])([H:6])([H:7])[H:8]>>[C:1]1([H:6])([H:7])[C:2]([H:9])([H:10])[N:3]([H:11])[C@@:4]1([O:5][H:8])[H:12],CC#N,-0.01
+[C:1]([C@:2]([O:3][H:11])([N:4]1[C:5]([H:12])[C:6]1([H:13])[H:14])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C:2]([O:3][H:11])[N:4]1[C:5]([H:10])([H:12])[C:6]1([H:13])[H:14])([H:7])([H:8])[H:9],CC#N,-1.94
+[C+:1](=[C:2]=[C-:3][H:9])[H:7].[C:4]1([H:8])([H:10])[C:5]([H:11])([H:12])[C:6]1([H:13])[H:14]>>[C:1](#[C:2][C:3]([C:4]1([H:10])[C:5]([H:11])([H:12])[C:6]1([H:13])[H:14])([H:8])[H:9])[H:7],CC=O,-0.75
+[C:1]([C@@:2]1([C:5]#[O+:6])[C:3]([H:10])([H:11])[C-:4]1[H:13])([H:7])([H:8])[H:9].[H:12][H:14]>>[C:1]([C:2]1([C:5](=[O:6])[H:14])[C:3]([H:10])([H:11])[C:4]1([H:12])[H:13])([H:7])([H:8])[H:9],CC=O,-1.16
+[C:1]([C:2](/[C:3](=[N:4]\[H:14])[C@@:5]([O:6])([O:7][H:15])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C@:3]([N:4][H:14])([C:5](=[O:6])[O:7][H:15])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10],CC=O,0.26
+[C:1](/[N:2]=[C:3](/[N:4]([C:5](=[O:6])[H:12])[H:11])[H:10])([H:7])([H:8])[H:9]>>[C-:5]#[O+:6].[C:1]([N:2](/[C:3](=[N:4]/[H:11])[H:10])[H:12])([H:7])([H:8])[H:9],ClCCl,-0.73
+[C:1]([C:2](=[O:3])[C:4](=[O:5])[N:6]([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2](=[O:3])[H:10])([H:7])([H:8])[H:9].[C:4](=[O:5])=[N:6][H:11],ClCCl,0.94
+[C:1]([C:2]1([C:6]#[N:7])[C:4]([H:13])([H:14])[C:5]1([H:15])[H:16])([H:8])([H:9])[H:10].[C:3]([H:11])[H:12]>>[C:1]([C:2]1([C:6]#[N:7])[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[C:5]1([H:15])[H:16])([H:8])([H:9])[H:10],ClCCl,-0.68
+[O:1]=[C:2]1[C:3]([H:6])([H:7])[C:4]([H:8])([H:9])[C:5]1([H:10])[H:11]>>[O:1]([C:2]1=[C:5]([H:10])[C:4]([H:8])([H:9])[C:3]1([H:6])[H:7])[H:11],S=C=S,0.31
+[C:1]([C:2]([C@@:3]1([H:13])[C:4]([H:14])([H:15])[C@@:5]2([H:16])[C:6]([H:17])([H:18])[C@@:7]12[H:19])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C@:2]1([H:11])[C@@:3]2([H:13])[C:4]([H:14])([H:15])[C@@:5]3([H:16])[C@:6]1([H:18])[C@@:7]23[H:19])([H:8])([H:9])[H:10].[H:12][H:17],S=C=S,-0.71
+[N:1]#[C:2]/[C:3](=[C:7](\[C:6]([C:5](=[O:4])[H:9])([H:10])[H:11])[H:12])[H:8]>>[N:1]#[C:2][C@@:3]1([H:8])[O:4][C@@:5]2([H:9])[C:6]([H:10])([H:11])[C@@:7]12[H:12],S=C=S,0.25
+[C:1](=[C:2]([C:3]([O:4][H:11])[C@:5]1([H:12])[C:6]([H:13])([H:14])[O:7]1)[H:10])([H:8])[H:9]>>[C:1](=[C:2](/[C:3]([O:4][H:11])=[C:5]1\[C:6]([H:13])([H:14])[O:7]1)[H:10])[H:8].[H:9][H:12],CSC,-0.7
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])=[C:4]([H:13])[N:5]([H:14])[C:6]1=[O:7])([H:8])([H:9])[H:10]>>[C:1](/[C:2](=[C:3]([C:4](=[N:5]/[H:14])/[H:13])\[H:12])[C:6](=[O:7])[H:11])([H:8])([H:9])[H:10],CSC,-3.01
+[C:1]([C@@:2]12[O:3][C@@:4]3([H:11])[C:5]([H:12])([H:13])[C@:6]1([H:14])[C@@:7]23[H:15])([H:8])([H:9])[H:10]>>[C:1]([C:2](=[O:3])[C@:6]1([H:14])[C:5]([H:12])([H:13])[C:4]([H:11])=[C:7]1[H:15])([H:8])([H:9])[H:10],CSC,-0.84
+[C:1]1([H:7])([H:8])[C@:2]2([H:9])[C@:3]3([H:10])[C:4]([H:11])([H:12])[C@@:5]1([H:13])[C@:6]23[H:14]>>[C:1]1([H:7])([H:8])[C@@:2]2([H:9])[C@:3]([C:4]([H:11])([H:12])[H:13])([H:10])[C@@:6]2([H:14])[C:5]1,BrC(Br)Br,-5.44
+[C:1](=[C:2]([C:3]([O:4][H:11])[C@:5]1([H:12])[C:6]([H:13])([H:14])[O:7]1)[H:10])([H:8])[H:9]>>[C:1](=[C:2]([C:3]([O:4][H:11])[C:5](=[C:6]([O:7][H:13])[H:14])[H:12])[H:10])([H:8])[H:9],BrC(Br)Br,-0.04
+[C:1]([C:2]([C:3]([C:4]([C:5]([H:16])([H:17])[H:18])([H:14])[H:15])([C:6](=[O:7])[H:19])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1](/[C:2](=[C:3](/[C:6](=[O:7])[H:19])[H:13])[H:12])([H:8])([H:9])[H:10].[C:4](=[C:5]([H:16])[H:18])([H:14])[H:15].[H:11][H:17],BrC(Br)Br,-1.92
+[C:1]([C:2]1([H:10])[C:3]([H:11])=[C:6]1[H:14])([H:7])([H:8])[H:9].[C:4](=[O:5])([H:12])[H:13]>>[C:1]([C@@:2]1([H:10])[C@@:3]2([H:11])[C:4]([H:12])([H:13])[O:5][C@@:6]12[H:14])([H:7])([H:8])[H:9],NC(C)C,-1.08
+[O:1]=[C:2]([C:3]1([H:8])[C:4]([H:9])([H:10])[C:5]([H:11])([H:12])[C:6]1([H:13])[H:14])[H:7]>>[O:1](/[C:2](=[C:3](\[C:6]1([H:14])[C:4]([H:9])([H:10])[C:5]1([H:11])[H:12])[H:8])[H:7])[H:13],NC(C)C,0.03
+[C:1](=[C:2]([C:6]([C:5]([C:4]([C:3]([H:7])([H:11])[H:12])([H:13])[H:14])([H:15])[H:16])([H:17])[H:18])[H:10])([H:8])[H:9]>>[C:1]([C:2]1([H:10])[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[C:5]([H:15])([H:16])[C:6]1([H:17])[H:18])([H:7])([H:8])[H:9],NC(C)C,-0.53
+[C:2]1([H:8])([H:9])[C:3]([H:10])([H:11])[O:4]/[C:5]1=[N:6]/[H:13].[O:1]([H:7])[H:12]>>[O:1]([C:2]([C:3]([O:4]/[C:5](=[N:6]/[H:13])[H:12])([H:10])[H:11])([H:8])[H:9])[H:7],CC(Cl)Cl,0.25
+[C:1]1([H:6])([H:7])[C:2]([H:8])([H:9])[C:3]([H:10])=[C:4]([H:11])[C:5]1([H:12])[H:13]>>[C:1]([C:2]([C:3](=[C:4])[H:10])([H:8])[H:9])([C:5]([H:11])([H:12])[H:13])([H:6])[H:7],CC(Cl)Cl,-1.76
+[C:1]([C:2]([C:3]([C:4]([N:5]([H:15])[H:16])=[C:6]=[N:7])([H:12])[H:13])([H:11])[H:14])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C:3]([C@:4]([N:5]([H:15])[H:16])([C:6]#[N:7])[H:14])([H:12])[H:13])[H:11])([H:8])([H:9])[H:10],CC(Cl)Cl,1.09
+[N:1]([C:2](=[C:3]([N+:4]#[N:5])[H:9])[N-:6][H:10])([H:7])[H:8]>>[N:1]([c:2]1[c:3]([H:9])[n:4][n:5][n:6]1[H:10])([H:7])[H:8],C[N+](=O)[O-],0.08
+[C:1]([N:2]([c:3]1[n:4]([H:12])[n:5][c:6]([H:13])[c:7]1[H:14])[H:11])([H:8])([H:9])[H:10]>>[C:1]([N:2]([c:3]1[n:4][n:5]([H:12])[c:6]([H:13])[c:7]1[H:14])[H:11])([H:8])([H:9])[H:10],C[N+](=O)[O-],2.07
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[O:4][C:5]1=[C:6]=[C:7]([H:14])[H:15])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[O:4][C@:5]1([C:6]#[C:7][H:15])[H:14])([H:8])([H:9])[H:10],C[N+](=O)[O-],-5.36
+[O:1]([C:2]([C@@:3]1([H:10])[C:4]([H:11])([H:12])[C:5]([H:13])([H:14])[O:6]1)([H:8])[H:9])[H:7]>>[O:1]([C:2](/[C:3](=[C:4](/[C:5]([O:6][H:12])([H:13])[H:14])[H:11])[H:10])([H:8])[H:9])[H:7],CC(C)(C)O,-0.13
+[C:1]([C:2]([N:3]([C:4](=[O:5])[C:6]([H:13])([H:14])[H:15])[H:12])([H:10])[H:11])([H:7])([H:8])[H:9]>>[C:1]([C:2]([N:3]([C-:4]=[O+:5][C:6]([H:13])([H:14])[H:15])[H:12])([H:10])[H:11])([H:7])([H:8])[H:9],CC(C)(C)O,1.45
+[C:1]1([H:7])([H:8])[O+:2]=[C-:3][C@@:4]2([H:11])[N:5]([H:12])[C@@:6]12[H:13].[H:9][H:10]>>[C:1]1([H:7])([H:8])[O:2][C:3]([H:9])([H:10])[C@@:4]2([H:11])[N:5]([H:12])[C@@:6]12[H:13],CC(C)(C)O,2.15
+[O:1]=[N:2][C:3]1=[C:6]([H:13])[C:5]([H:11])([H:12])[C:4]1([H:9])[H:10].[O:7]([H:8])[H:14]>>[O:1](/[N:2]=[C:3]1/[C:4]([H:9])([H:10])[C:5]([H:11])([H:12])[C@:6]1([O:7][H:14])[H:13])[H:8],CCC(C)C,-1.46
+[N+:1](=[C-:2][C:3]([N:4]=[C:5]([H:9])[H:10])([H:7])[H:8])=[C:6]([H:11])[H:12]>>[N:1]#[C:2][C:3]([N:4]1[C:5]([H:9])([H:10])[C:6]1([H:11])[H:12])([H:7])[H:8],CCC(C)C,-2.11
+[C:1](/[C:2]([C-:3]([N+:4]#[N:5])[H:10])=[N:6]\[H:11])([H:7])([H:8])[H:9]>>[C:1]([c:2]1[c:3]([H:10])[n:4][n:5][n:6]1[H:11])([H:7])([H:8])[H:9],CCC(C)C,-0.08
+[C:1]([C@@:2]1([H:10])[O+:3]=[C-:4][C@:5]1([O:6][H:14])[H:13])([H:7])([H:8])[H:9].[H:11][H:12]>>[C:1]([C@@:2]1([H:10])[O:3][C:4]([H:11])([H:12])[C@:5]1([O:6][H:14])[H:13])([H:7])([H:8])[H:9],CCC(O)C,2.84
+[C:1]1([H:7])([H:8])[C:2]([H:9])([H:10])[C:3]([H:11])([H:12])[C:4]([H:13])=[C:5]([H:14])[C:6]1([H:15])[H:16]>>[C:1]1([H:7])([H:8])[C:2]([H:9])([H:10])[C:3]([H:11])([H:12])[C:4]1([C:5](=[C:6]([H:15])[H:16])[H:14])[H:13],CCC(O)C,0.34
+[C:1]([C@@:2]([O:3][H:11])([C+:4]=[C:5]([O-:6])[H:12])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[O:3][C@:4]1([C:5](=[O:6])[H:12])[H:11])([H:7])([H:8])[H:9],CCC(O)C,10.23
+[O:1]([C@@:2]12[C:3]([H:9])([H:10])[C@@:4]3([H:11])[C:5]([H:12])([H:13])[C@:6]1([H:14])[C@@:7]23[H:15])[H:8]>>[O:1](/[C:2](=[C:3](/[C@@:4]1([H:11])[C:5]([H:12])([H:13])[C:6]([H:14])=[C:7]1[H:15])[H:9])[H:10])[H:8],CCC(C)=O,-1.85
+[C:1]([C:2]([C:3]1=[C:6]=[C:7]([H:15])[C:4]([H:13])([H:14])[O:5]1)([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C@@:3]1([C:6]#[C:7][H:15])[C:4]([H:13])([H:14])[O:5]1)([H:11])[H:12])([H:8])([H:9])[H:10],CCC(C)=O,1.01
+[N:1]#[C:2][C:3]([C@@:4]1([H:9])[C:5]([H:10])([H:11])[N:6]1[H:12])([H:7])[H:8]>>[N:1]#[C:2][C:3]([C:4][N:6]([C:5]([H:9])([H:10])[H:11])[H:12])([H:7])[H:8],CCC(C)=O,-1.07
+[C:1]([N-:2][N+:7]#[C:6][H:15])([H:8])([H:9])[H:10].[C:3](#[C:4][C:5]([H:12])([H:13])[H:14])[H:11]>>[C:1]([n:2]1[c:3]([H:11])[c:4]([C:5]([H:12])([H:13])[H:14])[c:6]([H:15])[n:7]1)([H:8])([H:9])[H:10],COC(C)=O,0.2
+[O:1]=[C:2]1[C:3]([H:7])([H:8])[C@@:4]2([H:9])[N:5]([H:10])[C@@:6]12[H:11]>>[O:1]([C:2]1=[C:3]([H:8])[C@@:4]2([H:9])[N:5]([H:10])[C@@:6]12[H:11])[H:7],COC(C)=O,1.21
+[O-:1][C:2](=[C:3]=[O+:6][C:5]([C:4]([H:8])([H:9])[H:10])([H:11])[H:12])[H:7]>>[O:1]=[C:2]([C@@:3]1([H:8])[C:4]([H:9])([H:10])[C:5]([H:11])([H:12])[O:6]1)[H:7],COC(C)=O,-1.06
+[C:1]([C@:2]([N:3][H:11])([C:4]([C:5](=[O:6])[H:14])([H:12])[H:13])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C@:2]([N-:3][H:11])([C:4]([C+:5][O:6][H:14])([H:12])[H:13])[H:10])([H:7])([H:8])[H:9],CC[N+](=O)[O-],1.24
+[C:1]([C:2]([O:3][C@@:4]([C:5]([H:14])([H:15])[H:16])([C:6](=[O:7])[H:17])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([H:8])([H:9])([H:10])[H:13].[C:2](=[O+:3][C:4]([C:5]([H:14])([H:15])[H:16])=[C:6]([O-:7])[H:17])([H:11])[H:12],CC[N+](=O)[O-],-1.25
+[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C:4]([H:14])=[C:5]([H:15])[C:6]([H:16])[O:7]1)([H:8])([H:9])[H:10]>>[C:1]([C@@:2]1([H:11])[C:3]([H:12])([H:13])[C:4]([H:14])=[C:5]([H:15])[C:6]([H:9])([H:16])[O:7]1)([H:8])[H:10],CC[N+](=O)[O-],-0.46
+[C:1]([C:2]1([C:3]([O:4][H:12])([H:10])[H:11])[C:5]([H:13])([H:14])[C:6]1([H:15])[H:16])([H:7])([H:8])[H:9]>>[C:1]([C:2]1([O:4][H:12])[C:5]([H:13])([H:14])[C:6]1([H:15])[H:16])([H:7])([H:8])[H:9].[C:3]([H:10])[H:11],ClC(Cl)C(Cl)Cl,-0.46
+[C:1]([C:2]([N:3][N:4]([C:5]([H:13])([H:14])[H:15])[C:6]([C:7]([H:18])([H:19])[H:20])([H:16])[H:17])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([N:3]([C:2]([H:11])[H:12])[N:4]([C:5]([H:13])([H:14])[H:15])[C:6]([C:7]([H:18])([H:19])[H:20])([H:16])[H:17])([H:8])([H:9])[H:10],ClC(Cl)C(Cl)Cl,1.06
+[C:1]([C:2]([C:3](=[C:4]=[O:5])[H:13])([H:11])[H:12])([H:8])([H:9])[H:10].[C:6](=[O:7])([H:14])[H:15]>>[C:1]([C:2]([C:3]([C:4](=[O:5])[C:6](=[O:7])[H:15])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],ClC(Cl)C(Cl)Cl,-4.59
+[C:1]([N:2]([C:3]([C:4]#[N:5])([H:10])[H:11])[H:9])([H:6])([H:7])[H:8]>>[C:1]([N:2]([C:3]([N+:5]#[C-:4])([H:10])[H:11])[H:9])([H:6])([H:7])[H:8],CC(C)[N+](=O)[O-],-3.83
+[C:1]([C+:2]1[N:3]([H:11])[C@:4]1([C-:5]=[N:6][H:10])[H:12])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]1([H:10])[N:3]([H:11])[C@:4]1([C:5]#[N:6])[H:12])([H:7])([H:8])[H:9],CC(C)[N+](=O)[O-],0.54
+[O:1]([C:2]([C:3]([C:4]([C:5]#[C:6][H:14])([H:12])[H:13])([H:10])[H:11])([H:8])[H:9])[H:7]>>[O:1]([C@:2]1([H:9])[C:3]([H:10])([H:11])[C:4]([H:12])([H:13])[C:5][C:6]1([H:8])[H:14])[H:7],CC(C)[N+](=O)[O-],-4.74
+[C:1]([C:2]([O:3][H:11])=[C:4]([H:12])[H:13])([H:8])([H:9])[H:10].[C:5](=[C:6]=[O:7])([H:14])[H:15]>>[C:1]([C@@:2]1([O:3][H:11])[C:4]([H:12])([H:13])[C:5]([H:14])([H:15])[C:6]1=[O:7])([H:8])([H:9])[H:10],c1ccc2ncccc2c1,1.23
+[C:1]([C:2]([C:3]([C@:4]([O:5][H:15])([C:6]([N:7]([H:18])[H:19])([H:16])[H:17])[H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10]>>[C:1]([C:2]([C:3]([C:4]([O:5][H:15])[C:6]([N:7]([H:18])[H:19])([H:16])[H:17])([H:13])[H:14])([H:11])[H:12])([H:8])([H:9])[H:10],c1ccc2ncccc2c1,0.79
+[C-:1]([O+:2]=[C:3]([C:4]([C:5](=[O:6])[H:13])([H:11])[H:12])[H:10])([H:7])[H:9].[H:8][H:14]>>[C:1]([O:2][C@@:3]1([H:10])[C:4]([H:11])([H:12])[C@:5]1([O:6][H:14])[H:13])([H:7])([H:8])[H:9],c1ccc2ncccc2c1,-4.68
+[C:1]([C@@:2]([O:3][C:4](=[O:5])[H:12])([C:7](=[C:6])[H:13])[H:11])([H:8])([H:9])[H:10]>>[C:1]([C@@:2]([O:3][C:4](=[O:5])[H:12])([C:6]#[C:7][H:13])[H:11])([H:8])([H:9])[H:10],Cc1ccccc1C,0.41
+[C:1]([C@@:2]([C:3](=[O:4])[H:11])([C:5]#[N:6])[H:10])([H:7])([H:8])[H:9]>>[C:1]([C@@:2]([C:3](=[O:4])[H:11])([N+:6]#[C-:5])[H:10])([H:7])([H:8])[H:9],Cc1ccccc1C,1.35
+[C:1]([C@@:2]1([C:3]([C:4]#[N:5])([H:11])[H:12])[C:6]([H:13])([H:14])[N:7]1[H:15])([H:8])([H:9])[H:10]>>[C:1](/[C:2]([C:3]([C:4]1=[N:5][C:6]1([H:13])[H:14])([H:11])[H:12])=[N:7]\[H:15])([H:8])([H:9])[H:10],Cc1ccccc1C,0.29
+[O:1]([N:2]1[C:3]([H:9])([H:10])[C:4]([H:11])=[C:5][C:6]([H:12])([H:13])[C:7]1([H:14])[H:15])[H:8]>>[H:13].[O:1]([N:2]1[C:3]([H:9])([H:10])[C:4]([H:11])=[C:5]=[C:6]([H:12])[C:7]1([H:14])[H:15])[H:8],Clc1ccccc1Cl,0.13
+[C:1]([C@@:2]1([H:11])[O:3][C:4]([H:12])([H:13])[C@@:5]2([H:14])[C:6]([H:15])([H:16])[C@@:7]12[H:17])([H:8])([H:9])[H:10]>>[C:1]1([H:9])([H:10])[C@@:2]2([H:11])[O:3][C:4]([H:12])([H:13])[C@:5]([C:6]([H:8])([H:15])[H:16])([H:14])[C@@:7]12[H:17],Clc1ccccc1Cl,-1.16
+[N:1]([C:2](=[O:3])[C:4]([O:5]/[C:6](=[N:7]/[H:13])[H:12])([H:10])[H:11])([H:8])[H:9]>>[N:1]([C:2]([O:3][C@@:6]1([H:12])[O:5][N:7]1[H:13])=[C:4]([H:10])[H:11])([H:8])[H:9],Clc1ccccc1Cl,-1.5
+[C:1]([C:2]([C@@:3]1([H:10])[C:4]([H:11])=[N:5]1)=[O:6])([H:7])([H:8])[H:9]>>[C:1]([c:2]1[c:3]([H:10])[c:4]([H:11])[n:5][o:6]1)([H:7])([H:8])[H:9],Cc1ccc(C)c(C)c1,-0.54
diff --git a/chemprop_contrib/sklearn_integration/test_sklearn_integration.py b/chemprop_contrib/sklearn_integration/test_sklearn_integration.py
new file mode 100644
index 0000000..5c8a12d
--- /dev/null
+++ b/chemprop_contrib/sklearn_integration/test_sklearn_integration.py
@@ -0,0 +1,38 @@
+from pathlib import Path
+
+import pandas as pd
+import pytest
+from chemprop_contrib.sklearn_integration import (
+ ChempropMulticomponentTransformer,
+ ChempropRegressor,
+)
+from sklearn.pipeline import Pipeline
+
+
+@pytest.fixture
+def rxn_mol_regression_data():
+ df = pd.read_csv(Path(__file__).parent / "rxn+mol.csv")
+ rxns = df["rxn_smiles"].to_list()
+ smis = df["solvent_smiles"].to_list()
+ Y = df["target"].to_numpy().reshape(-1, 1)
+
+ return rxns, smis, Y
+
+
+def test_sklearn_pipeline(rxn_mol_regression_data, tmp_path):
+ sklearnPipeline = Pipeline(
+ [
+ (
+ "featurizer",
+ ChempropMulticomponentTransformer(
+ component_types=["molecule", "reaction"]
+ ),
+ ),
+ ("regressor", ChempropRegressor(epochs=100)),
+ ]
+ )
+ rxns, smis, Y = rxn_mol_regression_data
+ sklearnPipeline.fit(X=[smis, rxns], y=Y)
+ score = sklearnPipeline.score(X=[smis, rxns], y=Y)
+ assert score[0] < 1
+ sklearnPipeline["regressor"].save_model(tmp_path)