schrodinger.application.matsci.martini3_ff module¶
Martini 3 force-field parameterization and coarse-grained mapping.
Combines nonbond parameter loading + shifted-potential fits with the Martini 3 mapping logic and lipid mapper. Bead-type taxonomy lives in the dependency-free martini3_types module.
Reference: Souza, P.C.T. et al. Martini 3: a general purpose force field for coarse-grained molecular dynamics. Nature Methods 18, 382-388 (2021).
Copyright Schrodinger, LLC. All rights reserved.
- schrodinger.application.matsci.martini3_ff.resolve_martini_ff_type(ff_type_str)¶
Resolve a force field type string to a canonical Martini version constant.
Handles legacy ‘martini’ alias, returning MARTINI for backward compatibility. Returns the input unchanged if it is not a Martini type.
- Parameters:
ff_type_str (str) – raw force_field_type value from JSON
- Return type:
str
- Returns:
canonical Martini version constant, or original string
- schrodinger.application.matsci.martini3_ff.loadMartini3NonbondParams()¶
Load and cache the Martini 3 pairwise nonbond parameters.
Reads the three shard files martini3_nonbond_params_1.json, martini3_nonbond_params_2.json, and martini3_nonbond_params_3.json and merges their pairs mappings into a single in-memory cache.
The cache maps ‘TYPE1,TYPE2’ (alphabetically sorted pair key) to a (sigma_angstrom, epsilon_kcal) tuple.
- Return type:
dict
- Returns:
mapping of pair key to (sigma, epsilon) tuple
- schrodinger.application.matsci.martini3_ff.get_martini3_sigmas()¶
Return the allowed Martini 3 sigma values.
- Return type:
list(float)
- Returns:
Sigma values in ascending order, in Angstrom
- schrodinger.application.matsci.martini3_ff.get_martini3_compatible_type(bead_type)¶
Return the Martini 3 type corresponding to a Martini 2 bead type.
- Parameters:
bead_type (str) – Martini bead type
- Return type:
str
- Returns:
Martini 3-compatible bead type, or the original type when it is not in the Martini 2 compatibility table
- schrodinger.application.matsci.martini3_ff.getMartini3Epsilon(type1, type2)¶
Return the Martini 3 epsilon for a bead-type pair.
- Parameters:
type1 – first Martini 3 bead type or supported legacy type
type2 – second Martini 3 bead type or supported legacy type
- Return type:
float
- Returns:
epsilon in kcal/mol
- Raises:
KeyError – if the pair is not in the parameter database
- schrodinger.application.matsci.martini3_ff.getMartini3Sigma(type1, type2)¶
Return the Martini 3 sigma for a bead-type pair.
- Parameters:
type1 – first Martini 3 bead type or supported legacy type
type2 – second Martini 3 bead type or supported legacy type
- Return type:
float
- Returns:
sigma in Angstrom
- Raises:
KeyError – if the pair is not in the parameter database
- schrodinger.application.matsci.martini3_ff.getMartini3NonbondPair(type1, type2)¶
Return both sigma and epsilon for a Martini 3 bead-type pair.
- Parameters:
type1 – first Martini 3 bead type or supported legacy type
type2 – second Martini 3 bead type or supported legacy type
- Return type:
tuple(float, float)
- Returns:
(sigma_angstrom, epsilon_kcal)
- Raises:
KeyError – if the pair is not in the parameter database
- schrodinger.application.matsci.martini3_ff.clearMartini3NonbondCache()¶
Clear the Martini 3 nonbond parameter cache.
Useful for testing or after modifying the underlying JSON file.
- schrodinger.application.matsci.martini3_ff.computeShiftedLJFitCoefficients(sigma, m_exp=12, n_exp=6, r_shift=9.0, r_cutoff=12.0)¶
Compute polynomial_cij fit coefficients for a shifted Lennard-Jones potential at the given sigma, using least-squares regression.
The fit is to the unitless potential (V/epsilon) so that the returned coefficients can be multiplied by epsilon at runtime (same convention as SHIFTED_LJ_FIT).
Results are cached by (sigma, m_exp, n_exp, r_shift, r_cutoff).
- Parameters:
sigma – sigma parameter in Angstrom
m_exp – repulsive exponent (default 12)
n_exp – attractive exponent (default 6)
r_shift – shift onset radius in Angstrom
r_cutoff – cutoff radius in Angstrom
- Return type:
list(tuple(int, int, float))
- Returns:
list of (one_based_index, exponent, coefficient) tuples compatible with the SHIFTED_LJ_FIT format
- schrodinger.application.matsci.martini3_ff.clearShiftedLJFitCache()¶
Clear the on-the-fly shifted LJ fit coefficient cache.
- schrodinger.application.matsci.martini3_ff.computeShiftedCoulombFitCoefficients(r_shift=0.0, r_cutoff=12.0)¶
Compute polynomial_cij fit coefficients for the shifted Coulomb potential, using least-squares regression.
The fit is to the unitless potential so that the returned coefficients can be multiplied by q_i * q_j / dielectric at runtime (same convention as SHIFTED_COULOMB_FIT).
Results are cached by (r_shift, r_cutoff).
- Parameters:
r_shift – shift onset radius in Angstrom
r_cutoff – cutoff radius in Angstrom
- Return type:
list(tuple(int, int, float))
- Returns:
list of (one_based_index, exponent, coefficient) tuples compatible with the SHIFTED_COULOMB_FIT format
- schrodinger.application.matsci.martini3_ff.clearShiftedCoulombFitCache()¶
Clear the on-the-fly shifted Coulomb fit coefficient cache.
- class schrodinger.application.matsci.martini3_ff.Martini3BeadTypeAssigner¶
Bases:
objectAssigns Martini 3 bead types to molecular fragments based on their chemical composition and environment.
Martini 3 bead type assignment follows a hierarchy:
Size from heavy atom count: 4+ atoms -> Regular (no prefix), 3 atoms -> Small (S), 2 atoms -> Tiny (T), aromatic rings always -> Tiny (T)
Chemical type from functional groups: pure hydrocarbon -> C, ether/ester -> N, alcohol/amide -> P, charged -> Q, halogenated -> X
Level from specific chemical environment (1-6 polarity scale)
Suffix from H-bond capability: donor -> d, acceptor -> a, both -> h
- classmethod assignBeadType(fragment_st, num_heavy_atoms, is_aromatic_ring, is_ring, martini_version=None, aromatic_ring_size=None, is_adjacent_to_aromatic=False, has_ring_ether_oxygen=False, ring_ether_o_total=0, ring_size=0, has_ring_thioether_sulfur=False, is_mixed_aromatic_alkyl=False, has_ring_nh=False, has_ring_n_no_h=False, has_adj_ring_ether=False)¶
Assign a Martini 3 bead type string to a molecular fragment.
- Parameters:
fragment_st (Structure) – extracted fragment structure
num_heavy_atoms (int) – number of heavy atoms in the fragment
is_aromatic_ring (bool) – whether the fragment is an aromatic ring
is_ring (bool) – whether the fragment is any ring
martini_version (str) – Martini version for version-specific chemistry rules
aromatic_ring_size (int) – size of the parent aromatic ring (5 or 6), used to distinguish imidazole-type (TN5a) from pyridine-type (TN6a) imine nitrogen beads
is_adjacent_to_aromatic (bool) – True when at least one bead node is directly bonded to an aromatic ring atom outside the bead. Used to assign level 4 (N4a) to aryl carbonyl beads (e.g. acetophenone ketone) vs level 6 (N6a) for aliphatic carbonyls (e.g. heptanal).
has_ring_ether_oxygen (bool) – True when an O atom in the bead is itself a ring member (THP/THF), not just an exocyclic alcohol
ring_ether_o_total (int) – total ether O atoms in the parent ring across all beads
ring_size (int) – total number of atoms in the parent ring
has_ring_thioether_sulfur (bool) – True when an S atom in the bead is itself a ring member (THT)
is_mixed_aromatic_alkyl (bool) – True when the bead contains both ring carbons and non-ring carbons with no heteroatom (e.g. toluene)
has_ring_nh (bool) – True when any ring N in the bead carries an H atom in the original molecule (pyrrole-type NH). Cannot be inferred from the heavy-atom-only extracted fragment.
- Return type:
str
- Returns:
Martini 3 bead type string (e.g. ‘SC4’, ‘TC5e’, ‘P1h’)
- schrodinger.application.matsci.martini3_ff.absorb_bridgehead_beads(fragment, mapping, fused_ring_bridgehead_nodes)¶
Redistribute bridgehead atoms into adjacent non-bridgehead beads.
For fused aromatic rings, the standard Martini 3 mapping places bridgehead atoms (shared between two rings) into their own 2-atom bead. This function moves each bridgehead atom into the smallest adjacent bead so that the molecule maps to the reference 4-bead topology.
Bridgehead nodes are added to fused_ring_bridgehead_nodes so that assign_martini3_bead_name can exclude them from the heavy-atom count.
- Parameters:
fragment (SymmRingFragmentData) – fragment describing the fused ring
mapping (Mapping) – current best mapping
fused_ring_bridgehead_nodes (set) – set to collect bridgehead node indices
- Return type:
- Returns:
updated mapping with bridgehead atoms absorbed into adjacent beads
- schrodinger.application.matsci.martini3_ff.try_heteroatom_singleton(fragment, best_mapping, best_score, validator)¶
For Martini 3 non-aromatic rings, try candidates where each heteroatom ring atom is placed in a 2-atom bead with exactly one adjacent ring carbon, and the remaining carbons form one or more 3-atom beads.
Recovers the reference SC3 + TN6d split for pyrrolidine and analogous 5-membered aliphatic rings.
- Parameters:
fragment (SymmRingFragmentData) – fragment data
best_mapping (Mapping) – current best mapping
best_score (float) – current best cost
validator (MappingValidator) – mapping validator
- Return type:
tuple(Mapping, float)
- Returns:
updated best mapping and score
- schrodinger.application.matsci.martini3_ff.try_exocyclic_split(fragment, best_mapping, best_score, validator)¶
For Martini 3 non-aromatic rings with exocyclic heavy-atom substituents, try placing each decorated ring carbon with its substituent(s) and one adjacent ring carbon into a 3-atom bead.
Recovers SN6{O, C1, C2} + SC3{C3, C4, C5} for cyclopentanol.
- Parameters:
fragment (SymmRingFragmentData) – ring fragment data
best_mapping (Mapping) – current best mapping
best_score (float) – current best cost
validator (MappingValidator) – mapping validator
- Return type:
tuple(Mapping, float)
- Returns:
updated best mapping and score
- schrodinger.application.matsci.martini3_ff.try_ring_halving(fragment, best_mapping, best_score, validator)¶
For Martini 3 even-sized non-aromatic rings with at least one ring heteroatom, try splitting the ring into two equal halves.
Recovers SC3+SN4a (3+3) for THP instead of 3x2 perfect-matching.
- Parameters:
fragment (SymmRingFragmentData) – fragment data
best_mapping (Mapping) – current best mapping
best_score (float) – current best cost
validator (MappingValidator) – mapping validator
- Return type:
tuple(Mapping, float)
- Returns:
updated best mapping and score
- schrodinger.application.matsci.martini3_ff.ring_atom_cost(mapping, ring_node_set, cg_scale)¶
Compute a cost based on ring-atom counts per bead only.
Non-ring nodes are excluded from the count so that decoration atoms do not inflate the size penalty. A bead with exactly 1 ring atom paired with decoration atoms is treated as effective size min(cg_scale, ring + decoration_count).
- Parameters:
mapping (Mapping) – the CG mapping
ring_node_set (set) – set of ring atom node indices
cg_scale (int) – target bead size (e.g. TINY_SCALE=2)
- Return type:
float
- Returns:
ring-atom size cost
- schrodinger.application.matsci.martini3_ff.try_ring_perfect_matchings(fragment, best_mapping, best_score, validator, martini_version=None)¶
Try perfect matchings of a simple ring cycle as candidate CG mappings.
For an even-length ring there are exactly two perfect matchings. Decoration nodes are attached to the bead containing their parent ring atom. Cost is computed using ring-atom counts only so decorations do not distort the comparison.
- Parameters:
fragment (SymmRingFragmentData) – fragment data
best_mapping (Mapping) – current best mapping
best_score (float) – current best cost
validator (MappingValidator) – mapping validator
martini_version (str) – Martini version string
- Return type:
tuple(Mapping, float)
- Returns:
updated best mapping and score
- schrodinger.application.matsci.martini3_ff.apply_ring_strategies(fragment, best_mapping, best_score, validator, fused_ring_bridgehead_nodes, martini_version, is_aromatic)¶
Facade that runs all Martini 3 ring mapping strategies in sequence.
For aromatic fragments: tries perfect matchings then absorbs bridgehead beads. For non-aromatic fragments: tries heteroatom singleton, exocyclic split, and ring halving strategies.
- Parameters:
fragment (SymmRingFragmentData) – fragment data
best_mapping (Mapping) – current best mapping
best_score (float) – current best cost
validator (MappingValidator) – mapping validator
fused_ring_bridgehead_nodes (set) – set collecting bridgehead nodes
martini_version (str) – Martini version string
is_aromatic (bool) – True if this is an aromatic ring fragment
- Return type:
tuple(Mapping, float)
- Returns:
updated (best_mapping, best_score)
- schrodinger.application.matsci.martini3_ff.is_bead_aromatic_m3(nodes, aromatic_bonds)¶
Determine if any node in the bead participates in an aromatic bond.
Martini 3 version: checks any node (even bonds outside the bead), because M3 beads pair a ring carbon with a substituent (e.g. {C_ring, O} for phenol) and no aromatic bond may exist within the bead itself.
- Parameters:
nodes (list) – bead node indices
aromatic_bonds (list) – list of (node_a, node_b) aromatic bond pairs
- Return type:
bool
- Returns:
True if any node participates in an aromatic bond
- schrodinger.application.matsci.martini3_ff.get_aromatic_ring_size(nodes, mol_rings_mapping, aromatic_bonds)¶
Determine the size of the smallest aromatic ring containing any of the given nodes.
- Parameters:
nodes (list) – bead node indices
mol_rings_mapping – mapping object with group_node attribute
aromatic_bonds (list) – list of (node_a, node_b) aromatic bond pairs
- Return type:
int or None
- Returns:
ring size (e.g. 5 or 6), or None if not determinable
- schrodinger.application.matsci.martini3_ff.assign_martini3_bead_name(nodes, bead_graph, molecule_st, node_to_atom_idx, mapping_solution, mol_rings_mapping, st_graph, aromatic_bonds, martini_version, fused_ring_bridgehead_nodes)¶
Assign a Martini 3 bead type name based on fragment chemistry.
- Parameters:
nodes (list) – nodes belonging to this bead
bead_graph (networkx.Graph) – subgraph for this bead
molecule_st (Structure) – parent molecule structure
node_to_atom_idx (dict) – mapping from node index to atom index
mapping_solution – current mapping solution with node_group
mol_rings_mapping – ring mapping with group_node attribute
st_graph (networkx.Graph) – full structure graph
aromatic_bonds (list) – list of (node_a, node_b) aromatic bond pairs
martini_version (str) – Martini version string
fused_ring_bridgehead_nodes (set) – bridgehead node indices to exclude
- Return type:
str
- Returns:
Martini 3 bead type string (e.g. ‘SC4’, ‘TC5e’)
- schrodinger.application.matsci.martini3_ff.compute_m3_bead_metrics(fragment, bead, bead_nodes, cg_scale)¶
Compute bead_size and bead_scale for a single bead under Martini 3 rules.
Returns raw node count as bead_size (not inflated by ring contribution), and a per-bead target scale based on heteroatom content and ring type.
- Parameters:
fragment – fragment data object (ResidueData or SymmRingFragmentData)
bead – bead identifier
bead_nodes (list) – nodes in this bead
cg_scale (int) – default CG scale
- Return type:
tuple(int, int)
- Returns:
(bead_size, bead_scale)
- schrodinger.application.matsci.martini3_ff.m3_is_score_improved(new_num_beads, best_num_beads, new_num_shared, best_num_shared)¶
Martini 3 tie-breaking rule: prefer finer resolution (more beads), then fewer shared atoms as secondary criterion.
- Parameters:
new_num_beads (int) – number of beads in new mapping
best_num_beads (int) – number of beads in best mapping
new_num_shared (int) – shared atom count in new mapping
best_num_shared (int) – shared atom count in best mapping
- Return type:
bool
- Returns:
True if new mapping is preferred
- schrodinger.application.matsci.martini3_ff.get_martini3_target_scale(is_ring_bead, is_aromatic_ring)¶
Get the target bead size for Martini 3 bead sizing.
Aromatic ring beads target TINY_SCALE (2), aliphatic ring beads target SMALL_SCALE (3), regular non-ring beads target MARTINI_SCALE (4).
- Parameters:
is_ring_bead (bool) – whether the bead contains ring nodes
is_aromatic_ring (bool) – whether the ring is aromatic
- Return type:
int
- Returns:
target scale for bead sizing
- schrodinger.application.matsci.martini3_ff.get_ring_graph_weights()¶
Return substituent edge weights for the Martini 3 weighted ring graph.
Martini 3 uses equal weights of 0.5 for short-end and long-end substituents so that ring decorations are treated as full-weight nodes during centrality scoring (distinct from the implicit ring edge weight of 1.0).
- Return type:
tuple(float, float)
- Returns:
(short_end_weight, long_end_weight)
- schrodinger.application.matsci.martini3_ff.is_ring_eligible_m3(ring, scale)¶
Martini 3 ring eligibility check.
Aromatic rings with 3+ atoms are eligible because T-beads map 2-3 heavy atoms. Non-aromatic rings use the standard criterion (size within (scale, 2*scale]).
- Parameters:
ring (structure.Ring) – the ring
scale (int) – current CG scale
- Return type:
bool
- Returns:
True if the ring is eligible for coarse-graining
- schrodinger.application.matsci.martini3_ff.get_residue_scale(sample_fragments_data, residue, default_scale)¶
Determine the CG scale for residue-level homogenization under Martini 3.
If all fragments of the residue are aromatic ring fragments, use TINY_SCALE so that 2-atom aromatic beads are preserved during homogenization.
- Parameters:
sample_fragments_data (list) – all fragment data objects for the molecule
residue – residue data object with res_name attribute
default_scale (int) – default CG scale
- Return type:
int
- Returns:
scale to use for this residue
- schrodinger.application.matsci.martini3_ff.get_mapping_from_order_m3(fragment, nodes, new_mapping, mapped_nodes)¶
Martini 3 aromatic ring node grouping strategy.
Pairs adjacent nodes within each connected component into 2-atom T-beads. Graph coloring (used in the Martini 2 path) is not applicable because it enforces non-adjacency between grouped nodes.
Mutates new_mapping and mapped_nodes in place.
- Parameters:
fragment – fragment data object
nodes (list) – unmapped nodes of the current node type
new_mapping – current Mapping being built (mutated)
mapped_nodes (list) – already-mapped node indices (mutated)
- Return type:
None
- Returns:
None
- schrodinger.application.matsci.martini3_ff.get_fused_aromatic_ring_bead_groups_from_molecule(molecule_data)¶
Identify groups of CG beads belonging to fused aromatic ring systems.
Delegates to the graph module for cycle detection and checks aromaticity via the molecule’s aromatic bond set. Only ring systems with 3 or more beads are included (eligible for virtual site placement).
- Parameters:
molecule_data – MoleculeData instance with mol_rings_mapping, st_graph, aromatic_bonds, bead_types, and mapping_solution attributes
- Return type:
list(list(tuple(str, int)))
- Returns:
list of ring bead groups; each group is a list of (bead_type_name, bead_idx) tuples
- exception schrodinger.application.matsci.martini3_ff.LipidMappingError¶
Bases:
ExceptionRaised when lipid mapping fails.
- class schrodinger.application.matsci.martini3_ff.Martini3LipidMapper(struct, martini_version)¶
Bases:
objectMaps all-atom lipid structures to Martini 3 coarse-grained beads.
Follows the same driver-consumption contract as AutomatedMartiniProteinMapping: after calling map, the particles_info property returns the standard automated-mapping particle records that the driver iterates to build the CG structure.
Supported lipid molecules are those whose residue name (or CG atom name) appears as a site key prefix in Martini3_cgff.json (e.g. DPPC, POPC, CHOL). The lipid-fragment SMARTS library is loaded from map_lipid_to_martini3.json.
Atom-to-bead assignment uses the CG atom name stored in each atom’s atom_type or pdbname field: the name is expected to match a key in the CGFF sites dict under the pattern <RESNAME>_<BEADNAME>.
- MAPPING_FILENAME = 'map_lipid_to_martini3.json'¶
- CGFF_FILENAME = 'Martini3_cgff.json'¶
- PHOSPHATE_COMPONENT = 'phosphate'¶
- __init__(struct, martini_version)¶
Load the lipid mapping JSON and CGFF JSON, and store the structure.
- Parameters:
struct (Structure) – all-atom structure to be mapped
martini_version (str) – Martini force field version string (e.g. ‘martini3’)
- map()¶
Detect lipid molecules, assign available CG beads, and tag atoms.
- Return type:
- Returns:
the input structure with CG mapping properties tagged on each relevant atom
- property particles_info¶
Return the standard automated-mapping particle records accumulated during mapping
- Return type:
list(AUTOMAPPED_PARTICLE_INFO)
- Returns:
particle records for driver consumption