neurosnap.chemistry.landscape module#

Topology-aware chemical-library characterization.

Reimplementation of the ChemManifold chemical-landscape algorithm by Danial Gharaie Amirabadi. A molecular library is represented as a multi-resolution traversable chemical graph:

  • nodes: compounds, Bemis-Murcko scaffolds, fragments

  • edges: compound -> scaffold, compound -> fragment, compound <-> compound Tanimoto similarity, scaffold hierarchy (general -> specific), fragment sharing through a common ring system

from neurosnap.chemistry import ChemicalLandscape

landscape = ChemicalLandscape(“library.csv”, smiles_column=”smiles”) landscape.build_all() report = landscape.characterize() print(report.summary()) landscape.path_between(“aspirin”, “naproxen”)

class neurosnap.chemistry.landscape.CharacterizationReport(diversity, network, islands, frontier=<factory>, counts=<factory>, metadata=<factory>)[source]#

Bases: object

Everything the engine can say about a library.

counts: dict#
diversity: DiversityMetrics#
frontier: list#
islands: IslandResult#
metadata: dict#
network: NetworkMetrics#
summary()[source]#

Human-readable answer to ‘does this library contain real diversity?’

Return type:

str

to_dict()[source]#
Return type:

dict

class neurosnap.chemistry.landscape.ChemicalGraph(node_type, smiles, compound_id, level, frequency, n_atoms, n_rings, mw, method, murcko, src, dst, edge_type, weight)[source]#

Bases: object

Column-store heterogeneous chemical graph.

Nodes: compounds, scaffolds, fragments. Edges: compound-scaffold, compound-fragment, similarity, scaffold hierarchy, fragment sharing. Flat NumPy arrays plus a cached SciPy CSR adjacency for graph algorithms.

adjacency(edge_types=None)[source]#

Unweighted undirected CSR adjacency, optionally restricted to types.

Return type:

csr_matrix

average_path_length(sources)[source]#

Average shortest-path length estimated from BFS trees of sources.

connected_components(edge_types=None)[source]#
Return type:

ndarray

count_edges(edge_type)[source]#
Return type:

int

count_nodes(node_type)[source]#
Return type:

int

degrees(edge_types=None)[source]#
Return type:

ndarray

edges_of_type(edge_type)[source]#
Return type:

ndarray

classmethod from_dict(data)[source]#
Return type:

ChemicalGraph

label(node)[source]#
Return type:

str

property n_edges: int#
property n_nodes: int#
neighborhood(node, radius=1, edge_types=None)[source]#
Return type:

ndarray

neighbors(node, edge_types=None)[source]#
Return type:

ndarray

node_id_of_compound(compound_id)[source]#
Return type:

int

node_id_of_smiles(smiles, node_type)[source]#
Return type:

int

nodes_of_type(node_type)[source]#
Return type:

ndarray

pagerank(damping=0.85, n_iter=100, tol=1e-08, edge_types=None)[source]#
Return type:

ndarray

shortest_path(source, target, edge_types=None)[source]#

One shortest hop path source -> target (empty if none).

Return type:

ndarray

to_dict()[source]#
Return type:

dict

weighted_adjacency(edge_types=None)[source]#

Undirected CSR with edge weights (used by community detection).

Return type:

csr_matrix

class neurosnap.chemistry.landscape.ChemicalLandscape(source=None, smiles_column='smiles', id_column=None, config=None, *, compound_ids=None, **overrides)[source]#

Bases: object

A molecular library and the chemical landscape built from it.

The source may be a path or an in-memory SMILES sequence:

landscape = ChemicalLandscape(“library.csv”, smiles_column=”smiles”) landscape.build_all() report = landscape.characterize() print(report.summary()) landscape.save(“out/”) reloaded = ChemicalLandscape.from_store(“out/”)

Parameters:
  • source (Union[str, Path, Sequence[str], None]) – Input path or in-memory SMILES sequence.

  • smiles_column (str) – SMILES column for delimited input files.

  • id_column (Optional[str]) – Optional compound identifier column.

  • config (Optional[LandscapeConfig]) – Optional complete landscape configuration.

  • compound_ids (Optional[Sequence[str]]) – IDs corresponding to an in-memory SMILES sequence.

  • **overrides (Any) – Configuration field overrides.

build_all()[source]#

Run every stage.

Return type:

ChemicalLandscape

build_fragments()[source]#

Fragment every compound (BRICS, rotatable bonds, linkers).

When FragmentConfig.reversible is enabled, each compound also keeps a ReverseFragmentRecord (attachment points + cut orders) so it can be rebuilt with reassemble().

Return type:

ChemicalLandscape

build_scaffolds()[source]#

Annotate Bemis-Murcko scaffolds and build the scaffold network.

Return type:

ChemicalLandscape

build_similarity_graph()[source]#

Build the sparse compound-compound similarity graph.

Return type:

ChemicalLandscape

characterize(n_samples=512, seed=0, resolution=1.0)[source]#

Run the full characterization and cache the report.

Return type:

CharacterizationReport

common_cores(n=10)[source]#

Return the most frequently shared scaffold SMILES.

Parameters:

n (int) – Maximum number of scaffold SMILES.

Return type:

list[str]

Returns:

Scaffold SMILES ordered by support.

property compound_ids: list[str]#

Canonical compound identifiers in library order.

decompose(core_smiles=None, *, params=None)[source]#

Decompose the library into a core + per-position R-groups.

If core_smiles is omitted, the most frequent scaffold is used.

Parameters:
  • core_smiles (Optional[str]) – Optional labeled or unlabeled core SMILES.

  • params (Any) – Optional RDKit R-group decomposition parameters.

Return type:

RGroupDecompositionResult

Returns:

Per-molecule R-group decomposition.

enumerate(core_smiles, rgroups_by_label, *, max_products=100000)[source]#

Enumerate all products of a labeled core with R-groups per position.

rgroups_by_label maps an attachment label to a list of R-group SMILES (each carrying a matching labeled dummy, e.g. CO[*:1]).

Parameters:
  • core_smiles (str) – Labeled core SMILES.

  • rgroups_by_label (Mapping[int, Sequence[str]]) – R-group choices keyed by attachment label.

  • max_products (int) – Maximum products to return.

Return type:

list[str]

Returns:

Enumerated product SMILES.

export_graphml(path, **kwargs)[source]#

Export the assembled graph as GraphML.

Return type:

Path

export_json(path, **kwargs)[source]#

Export the assembled graph as node-link JSON.

Return type:

Path

property failures: list[tuple[str, str]]#

(compound_id, smiles) pairs RDKit could not parse.

property fingerprints: FingerprintBlock | None#

Packed Morgan fingerprints, if the library has been loaded.

classmethod from_store(path)[source]#

Load a previously persisted landscape.

Parameters:

path (Union[str, Path]) – Landscape directory created by save().

Return type:

ChemicalLandscape

Returns:

Restored ChemicalLandscape instance.

property graph: ChemicalGraph#

The heterogeneous chemical graph (assembled on first access).

island_of(compound_id)[source]#

Island id of a compound (-1 if it was not part of the analysis).

Return type:

int

load()[source]#

Parse the input, canonicalize SMILES and build fingerprints.

Return type:

ChemicalLandscape

neighbors(compound_id, edge_types=None)[source]#

Return labels of the direct neighbours of a compound.

Parameters:
Return type:

list[str]

Returns:

Labels of directly connected nodes.

node_of(compound_id)[source]#

Return the graph node ID for a compound identifier.

Return type:

int

path_between(compound_a, compound_b)[source]#

Return a traversal path between two compounds.

Parameters:
  • compound_a (str) – First compound identifier.

  • compound_b (str) – Second compound identifier.

Return type:

list[str]

Returns:

Labels along the shortest graph path.

plot(outdir)[source]#

Write the scaffold map, island plot, and diversity report.

Parameters:

outdir (Union[str, Path]) – Destination directory for the three image files.

Return type:

list[Path]

Returns:

Paths to the generated image files.

reassemble(compound_id)[source]#

Rebuild a compound’s canonical SMILES from its fragments.

Uses the reversible fragment record (attachment points + cut orders) captured during build_fragments(). Returns "" if the compound was not fragmented reversibly.

Return type:

str

property report: CharacterizationReport#

Return the cached characterization report, building it if needed.

rgroups_at(compound_id, core_smiles=None)[source]#

Return one compound’s R-groups for a core.

Parameters:
  • compound_id (str) – Compound identifier to decompose.

  • core_smiles (Optional[str]) – Optional labeled or unlabeled core SMILES.

Return type:

dict[str, str]

Returns:

Mapping of R-group labels to SMILES.

save(path)[source]#

Persist the landscape as JSON plus an optional NPZ fingerprint store.

Return type:

Path

property smiles: list[str]#

Canonical SMILES in library order.

swap_rgroup(compound_id, position, new_rgroup, core_smiles=None)[source]#

Replace an R-group at position and return the new molecule.

new_rgroup should carry a dummy labeled for position (e.g. CO[*:1] for position 1). The compound is decomposed against a core, the labelled position is substituted, and the product is reassembled with the other R-groups left in place.

Return type:

str

class neurosnap.chemistry.landscape.DiversityMetrics(n_compounds=0, n_scaffold_nodes=0, n_populated_scaffolds=0, n_murcko_scaffolds=0, n_fragments=0, scaffold_entropy=0.0, scaffold_entropy_normalized=0.0, scaffold_gini=0.0, fragment_entropy=0.0, fragment_entropy_normalized=0.0, chemical_coverage=0.0, scaffold_redundancy=0.0, fragment_coverage=0.0, singleton_scaffold_fraction=0.0, compounds_per_scaffold=0.0, scaffold_levels=<factory>, top_scaffolds=<factory>, top_fragments=<factory>)[source]#

Bases: object

Diversity summary of a library.

chemical_coverage: float = 0.0#
compounds_per_scaffold: float = 0.0#
fragment_coverage: float = 0.0#
fragment_entropy: float = 0.0#
fragment_entropy_normalized: float = 0.0#
n_compounds: int = 0#
n_fragments: int = 0#
n_murcko_scaffolds: int = 0#
n_populated_scaffolds: int = 0#
n_scaffold_nodes: int = 0#
scaffold_entropy: float = 0.0#
scaffold_entropy_normalized: float = 0.0#
scaffold_gini: float = 0.0#
scaffold_levels: dict#
scaffold_redundancy: float = 0.0#
singleton_scaffold_fraction: float = 0.0#
to_dict()[source]#
Return type:

dict

top_fragments: list#
top_scaffolds: list#
class neurosnap.chemistry.landscape.EdgeType(*values)[source]#

Bases: IntEnum

Edge types of the heterogeneous chemical graph.

COMPOUND_FRAGMENT = 2#
COMPOUND_SCAFFOLD = 1#
COMPOUND_SIMILARITY = 3#
FRAGMENT_SHARED = 5#
SCAFFOLD_HIERARCHY = 4#
class neurosnap.chemistry.landscape.FingerprintBlock(packed, popcounts, n_bits)[source]#

Bases: object

Packed Morgan fingerprints for the whole library.

dense(start=0, stop=None)[source]#
Return type:

ndarray

property n_mols: int#
property n_words: int#
onbits_csr()[source]#

CSR of set bit positions: (offsets, indices).

Return type:

tuple

class neurosnap.chemistry.landscape.FingerprintConfig(radii=(2, 3), n_bits=2048, use_chirality=False, use_features=False)[source]#

Bases: object

Morgan fingerprint settings.

radii may hold several radii; bits of all radii are OR-ed into one packed vector, which keeps one fingerprint per compound while still covering multiple resolutions (radius 2 and 3 by default).

n_bits: int = 2048#
property n_words: int#
radii: tuple = (2, 3)#
use_chirality: bool = False#
use_features: bool = False#
class neurosnap.chemistry.landscape.FragmentConfig(use_brics=True, use_rotatable_bonds=True, use_linkers=True, min_fragment_atoms=3, max_fragments_per_molecule=32, max_rotatable_cuts=8, shared_links_per_fragment=4, reversible=True)[source]#

Bases: object

Fragmentation settings, in priority order.

max_fragments_per_molecule: int = 32#
max_rotatable_cuts: int = 8#
min_fragment_atoms: int = 3#
reversible: bool = True#
use_brics: bool = True#
use_linkers: bool = True#
use_rotatable_bonds: bool = True#
class neurosnap.chemistry.landscape.FragmentMethod(*values)[source]#

Bases: IntEnum

Provenance of a fragment node.

BRICS = 1#
LINKER = 3#
ROTATABLE_BOND = 2#
UNKNOWN = 0#
class neurosnap.chemistry.landscape.FragmentResult(fragments=None, methods=None, frequencies=None, ring_systems=None, compound_fragment_src=None, compound_fragment_dst=None, compound_fragment_method=None, n_compounds=0)[source]#

Bases: object

Fragment nodes plus compound->fragment edges for a chunk.

classmethod merge(results)[source]#
property n_fragments: int#
class neurosnap.chemistry.landscape.GraphBuilder[source]#

Bases: object

Incremental builder that deduplicates scaffold and fragment nodes.

add_compound(smiles, compound_id, n_atoms=0, n_rings=0, mw=0.0, murcko='')[source]#
add_edge(src, dst, edge_type, weight=1.0)[source]#

Add a single edge (convenience wrapper around add_edges()).

add_edges(src, dst, edge_type, weight=1.0)[source]#
add_fragment(smiles, method=0, n_atoms=0, n_rings=0, mw=0.0)[source]#
add_scaffold(smiles, level=1, n_atoms=0, mw=0.0, frequency=1)[source]#
build()[source]#
Return type:

ChemicalGraph

set_frequency(node_id, frequency)[source]#
Return type:

None

class neurosnap.chemistry.landscape.IslandResult(labels, compound_nodes, islands=<factory>, bridges=<factory>, method='louvain_local_moving', modularity=0.0, resolution=1.0)[source]#

Bases: object

Community structure of the compound similarity graph.

bridges: list#
compound_nodes: ndarray#
islands: list#
labels: ndarray#
method: str = 'louvain_local_moving'#
modularity: float = 0.0#
property n_bridges: int#
property n_islands: int#
resolution: float = 1.0#
to_dict()[source]#
Return type:

dict

class neurosnap.chemistry.landscape.LandscapeConfig(smiles_column='smiles', id_column=None, delimiter=None, chunk_size=20000, workers=1, limit=None, fingerprints=<factory>, scaffolds=<factory>, fragments=<factory>, similarity=<factory>)[source]#

Bases: object

Top-level build settings.

chunk_size: int = 20000#
delimiter: Optional[str] = None#
fingerprints: FingerprintConfig#
fragments: FragmentConfig#
classmethod from_dict(data)[source]#
Return type:

LandscapeConfig

id_column: Optional[str] = None#
limit: Optional[int] = None#
scaffolds: ScaffoldConfig#
similarity: SimilarityConfig#
smiles_column: str = 'smiles'#
to_dict()[source]#
Return type:

dict

workers: int = 1#
class neurosnap.chemistry.landscape.NetworkMetrics(n_nodes=0, n_edges=0, density=0.0, mean_degree=0.0, median_degree=0.0, max_degree=0, degree_histogram=<factory>, n_components=0, largest_component_size=0, largest_component_fraction=0.0, n_singletons=0, component_size_distribution=<factory>, average_path_length=0.0, path_sample_pairs=0, path_length_exact=False, edge_type_counts=<factory>, node_type_counts=<factory>, central_nodes=<factory>)[source]#

Bases: object

Topology summary of the chemical graph.

average_path_length: float = 0.0#
central_nodes: list#
component_size_distribution: list#
degree_histogram: dict#
density: float = 0.0#
edge_type_counts: dict#
largest_component_fraction: float = 0.0#
largest_component_size: int = 0#
max_degree: int = 0#
mean_degree: float = 0.0#
median_degree: float = 0.0#
n_components: int = 0#
n_edges: int = 0#
n_nodes: int = 0#
n_singletons: int = 0#
node_type_counts: dict#
path_length_exact: bool = False#
path_sample_pairs: int = 0#
to_dict()[source]#
Return type:

dict

class neurosnap.chemistry.landscape.NodeType(*values)[source]#

Bases: IntEnum

Node types of the heterogeneous chemical graph.

COMPOUND = 0#
FRAGMENT = 2#
SCAFFOLD = 1#
class neurosnap.chemistry.landscape.RGroupDecompositionResult(core_smiles='', rows=<factory>, n_failed=0)[source]#

Bases: object

A library decomposed into a core plus per-position R-groups.

rows is a list of per-molecule dicts keyed by R-group label ('Core', 'R1', 'R2', …) mapping to the group SMILES.

core_smiles: str = ''#
n_failed: int = 0#
property positions#

Sorted integer attachment labels present (excluding the core).

rows: list#
to_dict()[source]#
Return type:

dict

class neurosnap.chemistry.landscape.ReverseFragmentRecord(pieces=None, cut_orders=None, methods=None)[source]#

Bases: object

A compound’s fragments kept with their attachment points so the molecule can be rebuilt.

Cutting a set of bonds produces pieces whose cut ends are capped with dummy atoms carrying a unique cut-id isotope. pieces stores those reactive SMILES; cut_orders[k] is the bond order of the cut that produced the k-th isotope pair. Reassembly matches the two dummies of each cut id and reconnects their neighbours with the recorded bond order.

classmethod from_dict(data)[source]#
Return type:

ReverseFragmentRecord

property n_cuts: int#
to_dict()[source]#
Return type:

dict

class neurosnap.chemistry.landscape.ScaffoldConfig(max_level=6, include_generic=False, flatten_chirality=True, keep_only_first_fragment=True, strip_attachments=True, max_nodes_per_molecule=64)[source]#

Bases: object

Scaffold network settings (Bemis-Murcko is only the entry point).

flatten_chirality: bool = True#
include_generic: bool = False#
keep_only_first_fragment: bool = True#
max_level: int = 6#
max_nodes_per_molecule: int = 64#
strip_attachments: bool = True#
class neurosnap.chemistry.landscape.ScaffoldNetworkResult(scaffolds=None, levels=None, compound_scaffold=None, hierarchy_parent=None, hierarchy_child=None, hierarchy_relation=None, murcko=None)[source]#

Bases: object

Scaffold nodes, per-compound Murcko links and hierarchy edges.

classmethod merge(results)[source]#

Merge chunk results, re-indexing scaffolds into one global list.

property n_hierarchy_edges: int#
property n_scaffolds: int#
class neurosnap.chemistry.landscape.SimilarityConfig(threshold=0.55, k=8, n_permutations=128, n_bands=32, bucket_cap=64, max_candidate_pairs=20000000, mutual_only=False, seed=12648430, metric='tanimoto', exact_below=2000)[source]#

Bases: object

Sparse similarity graph settings (never all-vs-all above a size cap).

bucket_cap: int = 64#
exact_below: int = 2000#
k: int = 8#
max_candidate_pairs: int = 20000000#
metric: str = 'tanimoto'#
mutual_only: bool = False#
n_bands: int = 32#
n_permutations: int = 128#
seed: int = 12648430#
threshold: float = 0.55#
neurosnap.chemistry.landscape.apply_reversible_cut(mol, bond_ids)[source]#

Cut bond_ids and cap both ends with cut-id dummy atoms.

Returns (pieces, cut_orders) where pieces are reactive SMILES in which cut k explains isotope k + 1 and cut_orders[k] holds the original bond order of that cut.

Return type:

tuple[list[str], list[int]]

neurosnap.chemistry.landscape.attach_rgroup(core_smiles, rgroup_smiles, label)[source]#

Connect an R-group onto a core at the labeled attachment point.

Both the core and the R-group carry a matching labeled dummy (isotope or map-number form). The two dummies are removed and a single bond joins their neighbours. Returns the product SMILES (still carrying any other labels).

Parameters:
  • core_smiles (str) – Core containing the labeled attachment point.

  • rgroup_smiles (str) – R-group containing the matching label.

  • label (int) – Attachment-point label.

Return type:

str

Returns:

Product SMILES, or "" if the attachment is invalid.

neurosnap.chemistry.landscape.build_similarity_edges(fps, cfg=None)[source]#

Build compound-compound similarity edges (src, dst, score).

Exact scan for small libraries, MinHash/LSH + exact rescoring above cfg.exact_below. Returned pairs satisfy src < dst and are unique.

Parameters:
Return type:

tuple[ndarray, ndarray, ndarray]

Returns:

Unique source indices, destination indices, and Tanimoto scores.

neurosnap.chemistry.landscape.characterize(graph, n_samples=512, seed=0, resolution=1.0, min_frontier_support=1, metadata=None)[source]#

Run every analysis block over a built chemical graph.

Parameters:
  • graph (ChemicalGraph) – Built chemical graph.

  • n_samples (int) – Maximum number of path-length source nodes.

  • seed (int) – Random generator seed.

  • resolution (float) – Island community resolution.

  • min_frontier_support (int) – Maximum direct support for frontier scaffolds.

  • metadata (Optional[Mapping[str, Any]]) – Optional metadata copied into the report.

Return type:

CharacterizationReport

Returns:

Complete characterization report.

neurosnap.chemistry.landscape.decompose_molecules(mol_smiles, core_smiles, *, params=None)[source]#

Decompose a set of molecules into a core + R-groups (R-group linkage).

core_smiles may be labeled ([*:1], [*:2], …) or unlabeled; an unlabeled core is matched and its attachment points detected automatically.

Parameters:
  • mol_smiles (Sequence[str]) – Molecules to decompose.

  • core_smiles (str) – Labeled or unlabeled core SMILES.

  • params (Any) – Optional RDKit R-group decomposition parameters.

Return type:

RGroupDecompositionResult

Returns:

Decomposition rows and the matched core SMILES.

neurosnap.chemistry.landscape.detect_islands(graph, resolution=1.0, top_scaffolds=3)[source]#

Detect chemical islands and describe their chemistry.

Parameters:
  • graph (ChemicalGraph) – Chemical graph to analyze.

  • resolution (float) – Local-moving community resolution.

  • top_scaffolds (int) – Number of representative scaffolds per island.

Return type:

IslandResult

Returns:

Island labels and per-island summaries.

neurosnap.chemistry.landscape.diversity_metrics(graph, top_n=10)[source]#

Compute the diversity block of a characterization report.

Parameters:
  • graph (ChemicalGraph) – Chemical graph to summarize.

  • top_n (int) – Number of top scaffolds and fragments to retain.

Return type:

DiversityMetrics

Returns:

Diversity metrics for the graph.

neurosnap.chemistry.landscape.enumerate_core(core_smiles, rgroups_by_label, *, max_products=100000, dedupe=True)[source]#

Enumerate all products of a labeled core with lists of R-groups per label.

rgroups_by_label maps an attachment label to a list of R-group SMILES (each carrying a matching dummy). Returns the cartesian product as SMILES.

Parameters:
  • core_smiles (str) – Core containing labeled attachment points.

  • rgroups_by_label (Mapping[int, Sequence[str]]) – R-group choices keyed by attachment label.

  • max_products (int) – Maximum number of products to return.

  • dedupe (bool) – Whether to remove duplicate canonical products.

Return type:

list[str]

Returns:

Enumerated product SMILES.

neurosnap.chemistry.landscape.export_graphml(graph, path, node_types=None, edge_types=None)[source]#

Streaming GraphML export (no NetworkX).

Return type:

Path

neurosnap.chemistry.landscape.export_json(graph, path, indent=None, **kwargs)[source]#

Write a node-link JSON representation of graph.

Return type:

Path

neurosnap.chemistry.landscape.fragment_cut_bonds(mol, cfg=None)[source]#

Bond indices each enabled method would cut, with their FragmentMethod.

Returns [(bond_idx, method), ...] with duplicates removed and the per-molecule budget respected.

Parameters:
Return type:

list[tuple[int, FragmentMethod]]

Returns:

Unique bond indices paired with their cut method.

neurosnap.chemistry.landscape.fragment_library(smiles, cfg=None)[source]#

Fragment a chunk of compounds into deduplicated fragment nodes.

Parameters:
Return type:

FragmentResult

Returns:

Fragment nodes and compound-to-fragment edges for the input chunk.

neurosnap.chemistry.landscape.fragment_molecule(smiles, cfg=None)[source]#

Fragment one molecule into (fragment_smiles, method) pairs.

Parameters:
  • smiles (Union[str, Mol]) – SMILES string or RDKit molecule to fragment.

  • cfg (Optional[FragmentConfig]) – Optional fragmentation settings.

Return type:

list[tuple[str, int]]

Returns:

Fragment SMILES paired with their FragmentMethod value. Invalid molecules return an empty list.

neurosnap.chemistry.landscape.frontier_scaffolds(graph, min_support=1, limit=20)[source]#

Unexplored regions: general scaffolds whose descendants are populated.

A frontier scaffold has at most min_support compounds of its own while its children in the hierarchy carry many compounds. Ranked by descendant support.

Parameters:
  • graph (ChemicalGraph) – Chemical graph to inspect.

  • min_support (int) – Maximum direct support for a frontier scaffold.

  • limit (int) – Maximum number of frontier records.

Return type:

list[dict[str, Any]]

Returns:

Ranked frontier scaffold records.

neurosnap.chemistry.landscape.load_landscape(path)[source]#

Load a landscape written by save_landscape().

Parameters:

path (Union[str, Path]) – Landscape directory.

Return type:

tuple[ChemicalGraph, Optional[FingerprintBlock], LandscapeConfig, dict[str, Any]]

Returns:

Graph, optional fingerprints, configuration, and extra metadata.

neurosnap.chemistry.landscape.louvain_local_moving(A, resolution=1.0, n_iter=20)[source]#

Modularity local-moving (first Louvain phase) in pure NumPy.

Community-detection fallback used because igraph/leidenalg are not Neurosnap dependencies. Returns a community label per node.

Parameters:
  • A (csr_matrix) – Weighted sparse adjacency matrix.

  • resolution (float) – Modularity resolution parameter.

  • n_iter (int) – Maximum local-moving iterations.

Return type:

ndarray

Returns:

Dense community label for every node.

neurosnap.chemistry.landscape.minhash_signatures(offsets, indices, a, b)[source]#

Compute MinHash signatures over on-bit CSR data.

Parameters:
  • offsets (ndarray) – CSR row offsets.

  • indices (ndarray) – CSR set-bit indices.

  • a (ndarray) – MinHash multiplier coefficients.

  • b (ndarray) – MinHash offset coefficients.

Return type:

ndarray

Returns:

A uint32 signature matrix with one row per molecule.

neurosnap.chemistry.landscape.morgan_packed(smiles, cfg)[source]#

Generate packed Morgan fingerprints.

Parameters:
Return type:

FingerprintBlock

Returns:

A packed fingerprint block. Unparsable SMILES produce all-zero rows.

neurosnap.chemistry.landscape.murcko_smiles(smiles_or_mol)[source]#

Return the canonical Bemis-Murcko scaffold SMILES.

Parameters:

smiles_or_mol (Union[str, Mol]) – SMILES string or RDKit molecule.

Return type:

str

Returns:

The scaffold SMILES, or "" for acyclic or invalid input.

neurosnap.chemistry.landscape.network_metrics(graph, n_samples=512, seed=0, top_central=10)[source]#

Compute the network block of a characterization report.

Parameters:
  • graph (ChemicalGraph) – Chemical graph to summarize.

  • n_samples (int) – Maximum number of source nodes for path-length sampling.

  • seed (int) – Random generator seed.

  • top_central (int) – Number of PageRank-central nodes to retain.

Return type:

NetworkMetrics

Returns:

Network metrics for the graph.

neurosnap.chemistry.landscape.popcount_rows(packed)[source]#

Count set bits row-wise in a packed fingerprint matrix.

Parameters:

packed (ndarray) – (n, n_words) uint64 fingerprint matrix.

Return type:

ndarray

Returns:

One population count per row.

neurosnap.chemistry.landscape.popcount_words(words)[source]#

Count set bits in uint64 values.

Parameters:

words (ndarray) – NumPy array of values to count.

Return type:

ndarray

Returns:

An array with the population count of each input value.

neurosnap.chemistry.landscape.reassemble_fragments(pieces, cut_orders)[source]#

Join reactive fragment pieces back into the original molecule.

Two dummies sharing a cut-id isotope are reconnected with the recorded bond order, then all dummies are removed and the result is sanitized.

Parameters:
  • pieces (Sequence[str]) – Reactive fragment SMILES.

  • cut_orders (Sequence[int]) – Original bond-order values, indexed by cut isotope.

Return type:

str

Returns:

The reassembled canonical SMILES, or "" if reassembly fails.

neurosnap.chemistry.landscape.reversible_fragment_record(smiles, cfg=None)[source]#

Fragment a molecule reversibly.

Parameters:
  • smiles (Union[str, Mol]) – SMILES string or RDKit molecule to fragment.

  • cfg (Optional[FragmentConfig]) – Optional fragmentation settings.

Return type:

Optional[ReverseFragmentRecord]

Returns:

A reversible fragment record, or None when no reversible cut applies.

neurosnap.chemistry.landscape.save_landscape(graph, fingerprints, config, path, extra=None)[source]#

Persist the landscape as JSON plus an optional NPZ fingerprint store.

Parameters:
Return type:

Path

Returns:

The destination directory.

neurosnap.chemistry.landscape.scaffold_network(smiles, cfg=None)[source]#

Build the scaffold network for a list of compounds.

Unique Murcko scaffolds are expanded once, so cost scales with the number of distinct scaffolds rather than the number of compounds.

Parameters:
Return type:

ScaffoldNetworkResult

Returns:

Scaffold nodes, compound links, and hierarchy edges.

neurosnap.chemistry.landscape.shannon_entropy(counts)[source]#

Compute Shannon entropy in bits.

Parameters:

counts (Union[Sequence[float], ndarray]) – Count vector; zero entries are ignored.

Return type:

float

Returns:

Shannon entropy in bits.

neurosnap.chemistry.landscape.shared_fragment_edges(ring_systems, frequencies, links_per_fragment=4)[source]#

Fragment-fragment edges for fragments sharing a ring system.

Each fragment links to the links_per_fragment most frequent other fragments carrying the same ring system, keeping the edge count linear.

Parameters:
  • ring_systems (Sequence[str]) – Ring-system SMILES parallel to the fragment list.

  • frequencies (Union[Sequence[int], ndarray]) – Fragment frequencies parallel to ring_systems.

  • links_per_fragment (int) – Maximum number of neighbours per fragment.

Return type:

tuple[ndarray, ndarray]

Returns:

Two arrays containing the source and destination fragment indices.

neurosnap.chemistry.landscape.stream_chunks(path, smiles_column='smiles', id_column=None, chunk_size=20000, limit=None, delimiter=None)[source]#

Stream a molecular library in bounded chunks.

Parameters:
  • path (Union[str, Path]) – CSV, TSV, SMI, or SDF input path, optionally compressed.

  • smiles_column (str) – Name of the SMILES column for delimited inputs.

  • id_column (Optional[str]) – Optional compound identifier column.

  • chunk_size (int) – Maximum number of records yielded per chunk.

  • limit (Optional[int]) – Optional maximum number of records to read.

  • delimiter (Optional[str]) – Optional delimiter override for delimited inputs.

Yields:

RecordChunk instances containing compound IDs and SMILES.

Raises:
Return type:

Iterator[RecordChunk]