Library#

Block 1 — describe the combinatorial library. See the guide.

Pipeline#

class TACTICS.library_enumeration.synthesis_pipeline.SynthesisPipeline(config)[source]#

Synthesis pipeline for single-step, multi-step, and alternative-SMARTS reactions.

This is the main entry point for: - ThompsonSampler compound generation - Full library enumeration - Reagent validation and compatibility detection

Variables:
  • config – ReactionConfig defining the synthesis

  • reagent_file_list – List of reagent file paths

Example

>>> from TACTICS.library_enumeration import SynthesisPipeline
>>> from TACTICS.library_enumeration.smarts_toolkit import ReactionDef, ReactionConfig
>>>
>>> config = ReactionConfig(
...     reactions=[ReactionDef(reaction_smarts="...", step_index=0)],
...     reagent_file_list=["acids.smi", "amines.smi"]
... )
>>> pipeline = SynthesisPipeline(config)
>>> result = pipeline.enumerate_single(reagent_mols, reagent_keys)
__init__(config)[source]#

Initialize pipeline from ReactionConfig.

Parameters:

config (ReactionConfig) – ReactionConfig with reactions and reagent files

property reagent_file_list: List[str]#

Reagent file paths from config.

property num_steps: int#

Number of reaction steps.

property num_components: int#

Number of reagent components (files).

property has_alternatives: bool#

True if any step has alternative SMARTS patterns.

property is_multi_step: bool#

True if this is a multi-step synthesis.

property pattern_ids: Dict[int, List[str]]#

Available pattern IDs at each step.

property reactions: List[ReactionDef]#

Get all ReactionDef objects.

enumerate_single(reagent_mols, reagent_keys=None, store_intermediates=False)[source]#

Enumerate a single product from reagent molecules.

Used by ThompsonSampler for individual compound generation.

Parameters:
  • reagent_mols (List[Mol]) – List of RDKit Mol objects (one per reagent position)

  • reagent_keys (List[str] | None) – Optional reagent identifiers for routing

  • store_intermediates (bool) – If True, store intermediate products

Returns:

EnumerationResult with product or error details

Return type:

EnumerationResult

enumerate_single_from_smiles(smiles_list, reagent_keys=None, store_intermediates=False)[source]#

Enumerate a single product from SMILES strings.

Parameters:
  • smiles_list (List[str]) – List of SMILES strings

  • reagent_keys (List[str] | None) – Optional reagent identifiers

  • store_intermediates (bool) – If True, store intermediate products

Returns:

EnumerationResult

Return type:

EnumerationResult

enumerate(reagent_mols, reagent_keys=None, store_intermediates=False)[source]#

Alias for enumerate_single (backward compatibility).

Return type:

EnumerationResult

enumerate_from_smiles(smiles_list, reagent_keys=None, store_intermediates=False)[source]#

Alias for enumerate_single_from_smiles (backward compatibility).

Return type:

EnumerationResult

enumerate_batch(combinations, n_jobs=1, show_progress=False)[source]#

Enumerate multiple products.

Parameters:
  • combinations (List[Tuple[List[Mol], List[str] | None]]) – List of (reagent_mols, reagent_keys) tuples

  • n_jobs (int) – Parallel workers (1 = sequential)

  • show_progress (bool) – Show progress bar

Returns:

List of EnumerationResult

Return type:

List[EnumerationResult]

enumerate_library(n_jobs=1, show_progress=True)[source]#

Enumerate entire combinatorial library.

Generates all possible products from reagent files.

Parameters:
  • n_jobs (int) – Number of parallel workers

  • show_progress (bool) – Show progress bar

Returns:

List of EnumerationResult for all products

Return type:

List[EnumerationResult]

auto_detect_compatibility(reagent_lists=None, deprotect=False, desalt=False)[source]#

Automatically detect which reagents work with which patterns.

This runs validation for each pattern and builds a compatibility map used during enumeration for routing.

Parameters:
  • reagent_lists (List[List[Any]] | None) – Optional list of Reagent lists from Thompson Sampling

  • deprotect (bool) – Apply deprotection during detection

  • desalt (bool) – Apply desalting during detection

Returns:

AutoDetectionResult with full compatibility information

Return type:

AutoDetectionResult

register_compatibility(position, reagent_key, compatible_patterns, step_index=0)[source]#

Manually register reagent-pattern compatibility.

Parameters:
  • position (int) – Reagent position

  • reagent_key (str) – Unique reagent identifier

  • compatible_patterns (Set[str]) – Set of compatible pattern IDs

  • step_index (int) – Which step this applies to

get_compatible_patterns(reagent_keys, step_index=0)[source]#

Find a pattern compatible with all given reagents.

Parameters:
  • reagent_keys (List[str]) – Reagent identifiers for each position

  • step_index (int) – Which step

Returns:

First compatible pattern_id, or None if no pattern works

Return type:

str | None

get_compatibility_map()[source]#

Get the full compatibility cache.

Return type:

Dict[Tuple[int, int, str], Set[str]]

validate_all(deprotect=False, desalt=False)[source]#

Validate all reactions against reagent files.

Parameters:
  • deprotect (bool) – Apply deprotection during validation

  • desalt (bool) – Apply desalting during validation

Returns:

{step_index: {pattern_id: ValidationResult}}

Return type:

Nested dict

get_validator(step_index, pattern_id='primary')[source]#

Get validator for a specific step/pattern.

Parameters:
  • step_index (int) – Step index

  • pattern_id (str) – Pattern identifier

Returns:

_SMARTSValidator or None if not validated

Return type:

_SMARTSValidator | None

prepare_worker_data()[source]#

Prepare serializable data for multiprocessing workers.

Returns:

Dict that workers can use to reconstruct the pipeline

Return type:

Dict

classmethod from_worker_data(data)[source]#

Reconstruct pipeline in a worker process.

Parameters:

data (Dict) – Dict from prepare_worker_data()

Returns:

Reconstructed SynthesisPipeline

Return type:

SynthesisPipeline

Reaction definition#

Configuration classes for the SMARTS toolkit.

This module provides validated Pydantic configuration for: - Single reaction definitions (ReactionDef) - Multi-step synthesis pipelines (ReactionConfig) - Deprotection specifications (DeprotectionSpec) - Step input mappings (StepInput)

The configuration system supports three modes: 1. Single SMARTS: One ReactionDef with step_index=0 2. Alternative SMARTS: Multiple ReactionDef with same step_index, marked with step_modes 3. Multi-step: Multiple ReactionDef with different step_index values

class TACTICS.library_enumeration.smarts_toolkit.config.InputSource(value)[source]#

Source of input for a reaction step.

class TACTICS.library_enumeration.smarts_toolkit.config.ProtectingGroupInfo(name, smarts, deprotection_smarts=None)[source]#

Definition of a protecting group for detection and optional removal.

Variables:
  • name (str) – Human-readable name (e.g., “Boc”, “Fmoc”)

  • smarts (str) – SMARTS pattern to detect the group

  • deprotection_smarts (str | None) – Optional reaction SMARTS for removal

Example

>>> boc = ProtectingGroupInfo(
...     name="Boc",
...     smarts="[NX3][C](=O)OC(C)(C)C",
...     deprotection_smarts="[N:1][C](=O)OC(C)(C)C>>[N:1]"
... )
class TACTICS.library_enumeration.smarts_toolkit.config.StepInput(*, source, file_index=None, step_index=None)[source]#

Configuration for one input to a reaction step.

Specifies where the input comes from: - REAGENT_FILE: From one of the original reagent files - PREVIOUS_STEP: From the output of a previous reaction step

Example

>>> # Input from first reagent file
>>> input1 = StepInput(source=InputSource.REAGENT_FILE, file_index=0)
>>> # Input from step 0's output
>>> input2 = StepInput(source=InputSource.PREVIOUS_STEP, step_index=0)

Fields

Parameters:
  • source (InputSource) – Default: required.

  • file_index (int | None) – Index into reagent_file_list (for REAGENT_FILE source). Default: None.

  • step_index (int | None) – Index of previous step to use output from (for PREVIOUS_STEP source). Default: None.

validate_source_fields()[source]#

Ensure correct fields are provided based on source type.

class TACTICS.library_enumeration.smarts_toolkit.config.DeprotectionSpec(*, group, target)[source]#

Deprotection to apply to a reactant or product.

Specifies which protecting group to remove and the target molecule. The target can be: - An integer (0, 1, 2, …): Index of the reactant to deprotect BEFORE the reaction - The string “product”: Apply deprotection to the product AFTER the reaction

Multiple DeprotectionSpec can be applied to a single reaction.

Examples

>>> # Remove Boc from the first reactant (before reaction)
>>> deprot = DeprotectionSpec(group="Boc", target=0)
>>>
>>> # Remove Fmoc from the product (after reaction)
>>> deprot = DeprotectionSpec(group="Fmoc", target="product")

Fields

Parameters:
  • group (str) – Name of protecting group (e.g., ‘Boc’, ‘Fmoc’). Default: required.

  • target (int | Literal['product']) – Reactant index (int >= 0) for pre-reaction deprotection, or ‘product’ for post-reaction deprotection. Default: required.

property is_product_deprotection: bool#

Return True if this deprotection targets the product.

property reactant_index: int | None#

Return reactant index if targeting a reactant, else None.

class TACTICS.library_enumeration.smarts_toolkit.config.ReactionDef(*, reaction_smarts, step_index=0, pattern_id=None, description=None, deprotections=<factory>)[source]#

Definition of a single chemical reaction with built-in validation.

This is the fundamental building block for all synthesis configurations. Every reaction must specify a step_index (0 for single-step reactions, 0/1/2… for sequences).

Validation is built-in: call validate() to check reagent compatibility.

Example

>>> rxn = ReactionDef(
...     reaction_smarts="[C:1](=O)O.[N:2]H2>>[C:1](=O)[N:2]",
...     step_index=0,
...     description="Amide coupling"
... )
>>> result = rxn.validate(reagent_files=["acids.smi", "amines.smi"])
>>> print(rxn.coverage_stats)

Fields

Parameters:
  • reaction_smarts (str) – Reaction SMARTS string. Default: required.

  • step_index (int) – Step index (0 = first step). Default: 0.

  • pattern_id (str | None) – Identifier for this pattern (for alternatives). Default: None.

  • description (str | None) – Human-readable description. Default: None.

  • deprotections (List[DeprotectionSpec]) – Deprotections to apply before this reaction executes. Default: computed.

validate_reaction(reagent_files=None, reagent_smiles=None, protecting_groups=None, deprotect=False, desalt=False, test_reactions=False)[source]#

Validate this reaction against reagent files or SMILES lists.

Parameters:
  • reagent_files (List[str] | None) – Paths to reagent .smi files

  • reagent_smiles (List[List[Tuple[str, str]]] | None) – Direct SMILES lists as [(smiles, name), …] per position (useful for validating against intermediates)

  • protecting_groups (List[ProtectingGroupInfo] | None) – Custom protecting group definitions

  • deprotect (bool) – Remove protecting groups before checking compatibility

  • desalt (bool) – Remove salt fragments before checking compatibility

  • test_reactions (bool) – Actually run reaction on sample combinations

Returns:

ValidationResult with comprehensive compatibility information

Return type:

ValidationResult

Example

>>> rxn = ReactionDef(reaction_smarts="[C:1](=O)O.[N:2]>>[C:1](=O)[N:2]")
>>> result = rxn.validate_reaction(reagent_files=["acids.smi", "amines.smi"])
>>> print(f"Coverage: {result.coverage_stats}")
get_compatible_reagents(position)[source]#

Get reagents compatible with template at position.

Parameters:

position (int) – Reagent position (0-indexed)

Returns:

List of (smiles, name) tuples

Raises:

ValueError – If validate_reaction() hasn’t been called

Return type:

List[Tuple[str, str]]

get_incompatible_reagents(position)[source]#

Get reagents that don’t match template at position.

Parameters:

position (int) – Reagent position (0-indexed)

Returns:

List of (smiles, name) tuples

Raises:

ValueError – If validate_reaction() hasn’t been called

Return type:

List[Tuple[str, str]]

visualize_template_match(smiles, position, highlight_color=(0.0, 0.8, 0.0), size=(400, 300))[source]#

Visualize which atoms in a molecule match the reaction template.

This is the primary troubleshooting tool for understanding why a reagent or intermediate doesn’t work with the reaction.

Parameters:
  • smiles (str) – SMILES of molecule to visualize

  • position (int) – Which reactant position to check against

  • highlight_color (Tuple[float, float, float]) – RGB tuple for highlight color (default: green)

  • size (Tuple[int, int]) – Image dimensions (width, height)

Returns:

IPython Image for Jupyter display, or PIL Image

Return type:

Any

visualize_reaction(size=(800, 200))[source]#

Visualize the reaction scheme.

Parameters:

size (Tuple[int, int]) – Image dimensions

Returns:

IPython Image or PIL Image

Return type:

Any

get_reactant_template(position)[source]#

Get the RDKit mol template for a reactant position.

Parameters:

position (int) – Reactant position (0-indexed)

Returns:

RDKit Mol object representing the reactant pattern

Return type:

Mol | None

property num_reactants: int#

Number of reactants in this reaction.

property is_validated: bool#

True if validate() has been called.

property coverage_stats: Dict[int, float]#

Coverage percentage per position.

Returns:

Dict mapping position to coverage percentage (0-100)

Raises:

ValueError – If validate_reaction() hasn’t been called

property validation_result: ValidationResult | None#

Get the cached validation result.

summary()[source]#

Human-readable validation summary.

Returns:

Multi-line string with validation summary

Return type:

str

class TACTICS.library_enumeration.smarts_toolkit.config.ReactionConfig(*, reactions, reagent_file_list=<factory>, step_inputs=None, step_modes=None, protecting_groups=None)[source]#

Container for synthesis configuration.

Rules: - Every ReactionDef must have a step_index - step_inputs is REQUIRED when len(reactions) > 1 - step_modes is only used to mark steps with alternative SMARTS patterns - pattern_ids are auto-generated for alternatives if not provided

Examples

# Single reaction (simplest case) >>> config = ReactionConfig( … reactions=[ReactionDef(reaction_smarts=”…”, step_index=0)], … reagent_file_list=[“acids.smi”, “amines.smi”] … )

# Alternatives at step 0 >>> config = ReactionConfig( … reactions=[ … ReactionDef(reaction_smarts=”…”, step_index=0, pattern_id=”primary”), … ReactionDef(reaction_smarts=”…”, step_index=0, pattern_id=”secondary”), … ], … reagent_file_list=[“amines.smi”, “acids.smi”], … step_inputs={0: [StepInput(…), StepInput(…)]}, … step_modes={0: “alternative”} … )

# Multi-step sequence >>> config = ReactionConfig( … reactions=[ … ReactionDef(reaction_smarts=”…”, step_index=0), … ReactionDef(reaction_smarts=”…”, step_index=1), … ], … reagent_file_list=[“bb1.smi”, “bb2.smi”, “bb3.smi”], … step_inputs={ … 0: [StepInput(source=InputSource.REAGENT_FILE, file_index=0), …], … 1: [StepInput(source=InputSource.PREVIOUS_STEP, step_index=0), …], … } … )

Fields

Parameters:
  • reactions (List[ReactionDef]) – Default: required.

  • reagent_file_list (List[str]) – Default: computed.

  • step_inputs (Dict[int, List[StepInput]] | None) – Mapping of step_index to input sources (required if multiple reactions). Default: None.

  • step_modes (Dict[int, Literal['alternative']] | None) – Mark steps with alternative SMARTS patterns. Default: None.

  • protecting_groups (List[ProtectingGroupInfo] | None) – Custom protecting group definitions. Default: None.

validate_config()[source]#

Validate the configuration: 1. Require step_inputs when multiple reactions 2. Auto-generate pattern_ids for alternatives 3. Validate step_modes references valid step indices 4. Validate step_inputs references valid file/step indices

property num_steps: int#

Number of unique steps.

property is_multi_step: bool#

True if more than one step.

property steps_with_alternatives: List[int]#

List of step indices that have alternative SMARTS.

property step_indices: List[int]#

Sorted list of all step indices.

get_reactions_for_step(step_index)[source]#

Get all ReactionDef objects for a step (including alternatives).

Parameters:

step_index (int) – The step index

Returns:

List of ReactionDef objects for that step

Return type:

List[ReactionDef]

get_primary_reaction(step_index)[source]#

Get the primary reaction for a step.

Returns the reaction with pattern_id=’primary’, or the first one if not found.

Parameters:

step_index (int) – The step index

Returns:

The primary ReactionDef or None if step doesn’t exist

Return type:

ReactionDef | None

get_inputs_for_step(step_index)[source]#

Get the input configuration for a step.

For single-reaction configs without step_inputs, auto-generates inputs from reagent_file_list.

Parameters:

step_index (int) – The step index

Returns:

List of StepInput objects for that step

Return type:

List[StepInput]

has_alternatives_at_step(step_index)[source]#

Check if a step has alternative SMARTS patterns.

Parameters:

step_index (int) – The step index

Returns:

True if step has alternatives marked in step_modes

Return type:

bool

validate_all(deprotect=False, desalt=False)[source]#

Validate all reactions in the config.

Parameters:
  • deprotect (bool) – Apply deprotection during validation

  • desalt (bool) – Apply desalting during validation

Returns:

{step_index: {pattern_id: ValidationResult}}

Return type:

Nested dict

Validation result#

class TACTICS.library_enumeration.smarts_toolkit._validator.ValidationResult(compatible_reagents=<factory>, incompatible_reagents=<factory>, invalid_smiles=<factory>, duplicate_smiles=<factory>, protected_reagents=<factory>, multi_fragment_reagents=<factory>, coverage_stats=<factory>, reaction_success_rate=0.0, error_messages=<factory>, warnings=<factory>)[source]#

Comprehensive results from SMARTS validation.

Variables:
  • compatible_reagents (Dict[int, List[Tuple[str, str]]]) – {position: [(smiles, name), …]} - Reagents that match template

  • incompatible_reagents (Dict[int, List[Tuple[str, str]]]) – {position: [(smiles, name), …]} - Reagents that don’t match

  • invalid_smiles (Dict[int, List[Tuple[str, str]]]) – {position: [(smiles, name), …]} - Unparseable SMILES

  • duplicate_smiles (Dict[int, List[Tuple[str, str]]]) – {position: [(smiles, name), …]} - Duplicate entries

  • protected_reagents (Dict[int, List[Tuple[str, str, List[str]]]]) – {position: [(smiles, name, [groups]), …]} - With protecting groups

  • multi_fragment_reagents (Dict[int, List[Tuple[str, str, List[str]]]]) – {position: [(smiles, name, [fragments]), …]} - With salts

  • coverage_stats (Dict[int, float]) – {position: float} - Percent compatible per position (0-100)

  • reaction_success_rate (float) – float - Percent of test reactions that succeeded

  • error_messages (List[str]) – List[str] - Critical errors

  • warnings (List[str]) – List[str] - Non-critical warnings

is_valid()[source]#

True if all positions have >0% coverage and no critical errors.

Return type:

bool

property total_compatible: int#

Total number of compatible reagents across all positions.

property total_incompatible: int#

Total number of incompatible reagents across all positions.

Enumeration results and helpers#

Enumeration utilities and result dataclasses.

This module provides: - EnumerationResult: Result from product enumeration - EnumerationError: Details about failed enumeration - AutoDetectionResult: Results from SMARTS compatibility detection - Utility functions for reagent processing

class TACTICS.library_enumeration.enumeration_utils.EnumerationError(step_index, pattern_id, error_type, message, reagent_smiles=<factory>, reagent_names=<factory>, reaction_smarts=None)[source]#

Details about a failed enumeration.

Variables:
  • step_index (int) – Which step failed

  • pattern_id (str | None) – Which pattern was attempted

  • error_type (Literal['no_compatible_pattern', 'reaction_failed', 'invalid_input', 'deprotection_failed']) – Type of error

  • message (str) – Human-readable description

  • reagent_smiles (List[str]) – Input SMILES that failed

  • reagent_names (List[str]) – Input reagent names for traceability

  • reaction_smarts (str | None) – The SMARTS pattern that was attempted (if available)

detailed_message()[source]#

Generate a detailed error message for debugging.

Returns:

Multi-line string with full error details

Return type:

str

to_dict()[source]#

Convert error to dictionary for DataFrame export.

Returns:

Dictionary with all error fields

Return type:

Dict[str, Any]

class TACTICS.library_enumeration.enumeration_utils.EnumerationResult(product=None, product_smiles=None, product_name=None, patterns_used=<factory>, intermediates=None, error=None)[source]#

Complete result from pipeline enumeration.

Variables:
  • product (rdkit.Chem.rdchem.Mol | None) – Final product molecule (None if failed)

  • product_smiles (str | None) – SMILES of final product

  • product_name (str | None) – Name of product (from reagent keys)

  • patterns_used (Dict[int, str]) – {step_index: pattern_id} for each step

  • intermediates (Dict[int, rdkit.Chem.rdchem.Mol] | None) – {step_index: mol} if store_intermediates=True

  • error (TACTICS.library_enumeration.enumeration_utils.EnumerationError | None) – EnumerationError if failed

property success: bool#

True if enumeration succeeded.

class TACTICS.library_enumeration.enumeration_utils.AutoDetectionResult(pattern_results=<factory>, compatibility_map=<factory>, coverage_by_pattern=<factory>, unmatched_reagents=<factory>, warnings=<factory>)[source]#

Results from automatic SMARTS compatibility detection.

Variables:
  • pattern_results (Dict[int, Dict[str, Any]]) – {step_index: {pattern_id: ValidationResult}}

  • compatibility_map (Dict[Tuple[int, int, str], Set[str]]) – {(step_index, position, reagent_key): {pattern_ids}}

  • coverage_by_pattern (Dict[int, Dict[str, Dict[int, float]]]) – {step_index: {pattern_id: {position: coverage%}}}

  • unmatched_reagents (Dict[int, List[str]]) – {position: [reagent_names]} - Reagents matching no patterns

  • warnings (List[str]) – List of warning messages

TACTICS.library_enumeration.enumeration_utils.read_reagent_file(file_path)[source]#

Read reagents from a SMILES file.

Parameters:

file_path (str) – Path to .smi file with “SMILES name” format

Returns:

List of (smiles, name) tuples

Return type:

List[Tuple[str, str]]

TACTICS.library_enumeration.enumeration_utils.results_to_dataframe(results, include_failures=False)[source]#

Convert enumeration results to Polars DataFrame.

Parameters:
Returns:

product_name, product_smiles, success

Return type:

DataFrame with columns

TACTICS.library_enumeration.enumeration_utils.failures_to_dataframe(results)[source]#

Convert failed enumeration results to a detailed Polars DataFrame for analysis.

Parameters:

results (List[EnumerationResult]) – List of EnumerationResult (will filter to failures only)

Returns:

  • product_name: Attempted product name

  • step_index: Which step failed

  • pattern_id: Which pattern was attempted

  • error_type: Type of error

  • message: Error message

  • reagent_names: Semicolon-separated reagent names

  • reagent_smiles: Semicolon-separated reagent SMILES

  • reaction_smarts: The SMARTS pattern attempted (if available)

Return type:

DataFrame with columns

Example

>>> results = pipeline.enumerate_library()
>>> failures_df = failures_to_dataframe(results)
>>> print(failures_df.group_by("error_type").count())
TACTICS.library_enumeration.enumeration_utils.summarize_failures(results)[source]#

Generate a summary of enumeration failures.

Parameters:

results (List[EnumerationResult]) – List of EnumerationResult

Returns:

  • total: Total number of results

  • successes: Number of successful enumerations

  • failures: Number of failed enumerations

  • by_error_type: Count per error type

  • by_step: Count per step index

  • failure_rate: Percentage of failures

Return type:

Dictionary with failure statistics

Example

>>> results = pipeline.enumerate_library()
>>> summary = summarize_failures(results)
>>> print(f"Failure rate: {summary['failure_rate']:.1f}%")

File writing utilities for enumerated chemical libraries.

This module provides functions to write enumeration results to various formats: - CSV: Standard comma-separated values - SMI: SMILES format (SMILES name) - SDF: Structure-Data File format

TACTICS.library_enumeration.file_writer.write_enumerated_library(results, output_path, format='csv', include_failures=False)[source]#

Write enumerated library to file.

Parameters:
  • results (List[EnumerationResult]) – List of EnumerationResult from enumeration

  • output_path (str) – Output file path

  • format (Literal['csv', 'smi', 'sdf']) – Output format (csv, smi, sdf)

  • include_failures (bool) – Include failed enumerations in output

Returns:

Number of products written

Return type:

int

Example

>>> results = pipeline.enumerate_library()
>>> n_written = write_enumerated_library(results, "products.csv", format="csv")
>>> print(f"Wrote {n_written} products")
TACTICS.library_enumeration.file_writer.write_products_chunked(results, output_dir, products_per_file=5000, format='smi', file_prefix='products')[source]#

Write products to multiple files with a specified number per file.

Parameters:
  • results (List[EnumerationResult]) – List of EnumerationResult

  • output_dir (str) – Output directory path

  • products_per_file (int) – Maximum products per file

  • format (Literal['csv', 'smi']) – Output format (csv or smi)

  • file_prefix (str) – Prefix for output file names

Returns:

Total number of products written

Return type:

int

Product generation utilities for chemical library enumeration.

This module provides functions for: - Single product enumeration from reagents - Batch enumeration (sequential and parallel) - Reaction execution helpers - Deprotection application

These functions are used by SynthesisPipeline for library enumeration.

TACTICS.library_enumeration.generate_products.enumerate_products(pipeline, combinations, n_jobs=1, show_progress=False)[source]#

Enumerate products from reagent combinations.

Parameters:
  • pipeline (SynthesisPipeline) – SynthesisPipeline instance (for reaction config and state)

  • combinations (List[Tuple[List[Mol], List[str] | None]]) – List of (reagent_mols, reagent_keys) tuples

  • n_jobs (int) – Number of parallel workers (1 = sequential)

  • show_progress (bool) – Show progress bar

Returns:

List of EnumerationResult objects

Return type:

List[EnumerationResult]

TACTICS.library_enumeration.generate_products.generate_all_combinations(reagent_files, return_separate_names=False)[source]#

Generate all reagent combinations from files.

Parameters:
  • reagent_files (List[str]) – List of reagent file paths

  • return_separate_names (bool) – If True, also return separate reagent names per combination

Returns:

Tuple of (mol_combinations, name_combinations, reagent_name_lists) - mol_combinations: List of tuples of Mol objects - name_combinations: List of product names (reagent names joined by _) - reagent_name_lists: List of [reagent_name, …] lists (only if return_separate_names=True)

Return type:

Tuple[List[Tuple[Mol, …]], List[str], List[List[str]] | None]

Protecting groups and salts#

Default constants for SMARTS validation.

Provides commonly-used protecting groups and salt fragments for automatic detection during reagent validation.

The protecting groups include SMARTS patterns for detection and optional reaction SMARTS for deprotection. Salt fragments are provided as SMILES patterns for common counterions and salts.

These defaults can be extended by providing additional entries when creating a SMARTSValidator instance.

TACTICS.library_enumeration.smarts_toolkit.constants.get_protecting_group(name)[source]#

Get a protecting group by name.

Parameters:

name (str) – Name of the protecting group (e.g., “Boc”, “Fmoc”)

Returns:

ProtectingGroupInfo object

Raises:

KeyError – If protecting group not found

Return type:

ProtectingGroupInfo

TACTICS.library_enumeration.smarts_toolkit.constants.get_all_protecting_group_names()[source]#

Get list of all default protecting group names.

Return type:

List[str]