mooonpy package
- class mooonpy.Molspace(filename='', **kwargs)[source]
Bases:
objectInitializes a Molspace instance
- This class can be called via:
Full namespace syntax :
mooonpy.molspace.molspace.Molspace()Aliased namespace syntax :
mooonpy.Molspace()
Initialization Parameters
- filenamestr, optional
An optional filename to read and initialize a Molspace() instance with molecular system information (e.g. atoms, bonds, force field parameters …). Supported file extensions:
LAMMPS datafile
.dataTripos mol2 file
.mol2SYBL mol file
.mol
If no filename is provided the Molspace instance will be generated with no molecular system information.
Attributes
- Nint
The order of the filter. For ‘bandpass’ and ‘bandstop’ filters, the resulting order of the final second-order sections (‘sos’) matrix is
2*N, with N the number of biquad sections of the desired system.- Wnarray_like
The critical frequency or frequencies. For lowpass and highpass filters, Wn is a scalar; for bandpass and bandstop filters, Wn is a length-2 sequence.
Methods
- Nint
The order of the filter. For ‘bandpass’ and ‘bandstop’ filters, the resulting order of the final second-order sections (‘sos’) matrix is
2*N, with N the number of biquad sections of the desired system.
- add_type_labels(labels, per_atom_comment=False)[source]
Adds type labels for atom types and use 1st instance for each BADI type label
could refactor the composition to a function somewhere
- bonds_from_distances(periodicity: str = 'ppp')[source]
Resets the bonds in a molecular system, based in interatomic distances and valences of atoms. The cutoff distances are set based on the summation of vdw radii per element involved in the bond. Each atom’s valence is respected (e.g. the maximum number of allowable bonded atoms to a carbon atom is 4).
- Example:
>>> import mooonpy >>> my_molecule = mooonpy.molspace('detda.data') >>> my_molecule.bonds_from_distances(periodicity='fff')
Note
Before using this command the element per-atom info and element per-mass info need to be updated by running “my_molecule.update_elements()”.
- Parameters:
periodicity (str) – Optional for setting the periodicity of the model, where f=fixed and p=periodic. Each position is a face (e.g. periodicity=’fpp’ is fixed on X-faces and periodic in Y- and Z-faces)
- Returns:
None
- Return type:
None
- build_old2new(mode='contiguous', offset=0, start=1, keep=None)[source]
Build an
(old2new, new2old)mapping for use withremap_ids().See
mooonpy.molspace.remap.build_old2new()for parameter details.
- combine(other, vect=None, move_mode='offset', offset_types=False, assign_clusters=True)[source]
Append
otherintoselfin place.other’s atom ids are shifted byself’s currentmax(atoms)so they don’t collide. Coordinates of the shifted copy are translated viaAtoms.move()before merging.- Parameters:
other (Molspace) – Molspace to append. Not mutated.
vect (tuple[float, float, float] or None) – Displacement applied to
otherbefore merging.Noneskips translation.move_mode (str) – Mode passed to
Atoms.move(). Defaults to'offset'.offset_types (bool) – If True,
other’s atom-type integers are shifted bymax(self.ff.masses)and the corresponding mass entries are merged intoself.ff.masseswith the shifted keys. This is needed when the two systems use unrelated type tables (e.g. combining raw monomers from independent atom_typing runs). For systems that already share the same FF (e.g. post-BRM data files), leave it False so types stay aligned.assign_clusters (bool) – Re-run cluster identification after merge.
- Returns:
The id offset applied to
other’s atom ids.- Return type:
int
- compute_BADI_by_type(periodicity='ppp', comp_bond=True, comp_angle=True, comp_dihedral=True, comp_improper=True)[source]
Apply this command mol.ff.has_type_labels = True or mol.add_type_labels(labels) To make dict keys type labels
- compute_pairs(cutoff, whitelist=None, blacklist=None, algorithm='DD_13', periodicity='ppp')[source]
Compute pairwise distances within cutoff between atoms
- contiguous(start=1)[source]
Renumber atoms
start..start+N-1in current insertion order, in place. Returns theold2newdict.
- copy(deepcopy=False)[source]
Return a fully independent copy of this Molspace (independence verified in
tests/test_molspace_copy.py).Factory classes and defaults are frozen at construction, so the copy references the SAME factory/lookup instances by design; all mutable state is rebuilt fresh.
- Parameters:
deepcopy (bool) – if True, use the
copy.deepcopyfallback (same result, ~6-8x slower; for cross-checking only).
- find_rings(ring_sizes: tuple[int] = (3, 4, 5, 6, 7))[source]
Finds all rings in the current Molspace instance. The size of rings searched for is set in the ring_sizes parameter.
- Example:
>>> import mooonpy >>> my_molecule = mooonpy.molspace('detda.mol2') >>> rings = my_molecule.find_rings(ring_sizes=(3,4,5,6,7)) >>> print(rings) [(1, 2, 3, 4, 5, 6)]
Note
Each ring will be sorted in the order it was traversed in the graph and will be in the canonical form (e.g., canonical=(1,2,3) vs non_canonical=(2,3,1)).
- Parameters:
ring_sizes (tuple[int]) – Tuple containing ring sizes to search for in graph
- Returns:
rings
- Return type:
list[tuple[int]]
- min_image_unwrap(changeimg=True)[source]
Make every molecule whole under the minimum-image convention, in place.
Walks each bonded cluster outward from the atom nearest the box center and shifts every neighbor to its minimum-image position relative to the atom it was reached from, so no bond spans more than half the box. Restricted- triclinic safe: the minimum image is taken in fractional space (consistent with
Atoms.wrap()), then converted back through the box h-matrix.- Parameters:
mol – Molspace modified in place (needs .atoms, .atoms.box, bonds).
changeimg – If True, update each shifted atom’s image flags so the canonical wrapped position is preserved (unwrapped = stored + h.image stays invariant;
Atoms.wrap()will still recover the cell).
- reachable(start_id, depth)[source]
Flat-set bond-graph reachability from
start_idup todepthbonds (inclusive ofstart_id). Thin wrapper aroundmooonpy.molspace.graph_theory.interface.find_reachable_neighbors().
- read_files(filename, dsect=['all'], steps=Ellipsis)[source]
Read files into Molspace Currently supports .data and .dump files.
- Parameters:
filename (str or Path) – path to file to read
dsect (list) – Sections of data file to read, see mooonpy.molspace._files_io.read_lmp_data for more details
steps (list or int) – Steps in dump file to read see mooonpy.molspace._files_io.read_lmp_dump for more details
- Returns:
Modifies self in-place if data or single step, returns dict if multiple steps
- Return type:
None or dict
- Example:
>>> from mooonpy import Molspace >>> MyPath = Path('Project/Monomers/DETDA.data') >>> mol = Molspace(MyPath, dsect=['all']) >>> MyPath2 = Path('Project/Monomers/DETDA.dump') >>> series = Molspace(MyPath2, steps=None)
- remap_ids(old2new)[source]
Renumber and/or slice atom ids in place using
old2new.Any current atom whose id is not a key in
old2newis dropped, along with any bond/angle/dihedral/improper entry that references it. Container Python identities and surviving per-atom/per-bond object identities are preserved. Seemooonpy.molspace.remap.
- slice(keep_ids, renumber=True)[source]
Drop every atom whose id is not in
keep_ids, in place. By default the surviving atoms are renumbered contiguously from 1. Returns theold2newdict.
- update_atoms(atoms, whitelist=None, blacklist=None, box=True)[source]
Map per atom information from other atoms instance to this molspace
- update_elements(type2mass=None, type2element=None)[source]
Updates every per-atom .element attribute with the element type for that atom.
- Example:
>>> import mooonpy >>> my_molecule = mooonpy.molspace('detda.data') >>> my_molecule.update_elements()
Note
This will also update the per-mass .element attribute in ff.masses dictionary as well.
- Parameters:
type2mass (dict[int, float]) – Optional for setting the atom type to mass map (e.g. type2mass={1: 12.01115, 2: 1.008}). If not provided this will be generated from the masses section.
type2element (dict[int, str]) – Optional for setting the atom type to mass map (e.g. type2element={1: ‘C’, 2: ‘H’}). If not provided this will be generated from the masses section and interally defined periodic table.
- Returns:
None
- Return type:
None
- class mooonpy.Path(string: str | Path)[source]
Bases:
strAs computational scientists, half our jobs is file management and manipulation, the Path class contains several aliases for the os.path and glob.glob modules to make processing data easier. All mooonpy functions internally use this class for inputs of files or folders. Relevant strings are converted to path on entering functions
Examples
A copy of the code used in these examples is avalible in rootmooonpyexamplestoolspath_utilsexample_Path.py
- Basic Path Operations
>>> project_path = Path('Project/Data/Analysis') >>> filename = Path('results.txt') >>> full_path = project_path / filename >>> print(full_path) Project\Data\Analysis\results.txt >>> print(abs(full_path)) root\mooonpy\examples\tools\path_utils\Project\Data\Analysis\results.txt
- Path Parsing
>>> sample_path = Path('experiments/run_001/data.csv.gz') >>> print(sample_path.dir()) experiments\run_001 >>> print(sample_path.basename()) data.csv.gz >>> print(sample_path.root()) data.csv >>> print(sample_path.ext()) .gz
- Extension Manipulation
>>> data_file = Path('analysis/results.txt') >>> print(data_file.new_ext('.json')) analysis\results.json >>> print(data_file.new_ext('.txt.gz')) analysis\results.txt.gz
- File Existence
>>> current_file = Path(__file__) >>> fake_file = Path('nonexistent.txt') >>> print(bool(current_file)) True >>> print(bool(fake_file)) False
- Wildcard Matching
>>> txt_pattern = Path('temp_dir/*.txt') >>> print(txt_pattern.matches()) ['test1.txt', 'test2.txt'] >>> for file in Path('temp_dir/*'): ... print(file.basename()) data.csv readme.md test1.txt test2.txt
- Recent File Finding
>>> pattern = Path('temp_dir/*.txt') >>> print(pattern.recent()) newest_file.txt >>> print(pattern.recent(oldest=True)) old_file.txt
- Smart File Opening
>>> mypath = Path('data.txt') >>> with mypath.open('w') as f: ... f.write('Hello World') # Creates regular file >>> compressed_path = Path('data.txt.gz') >>> # compressed_path.open() would use gzip automatically # Would automatically handle gzip compression ** Absolute Path Conversion ** >>> rel_path = Path('data/file.txt') >>> print(abs(rel_path)) root\mooonpy\examples\tools\path_utils\data\file.txt
Todo
__truediv__ __bool__ __abs__ and __iter__ docstrings in config?
- basename() Path[source]
Split Path to filename and extention.
Alias for os.path.basename
- Returns:
Path of file
- Return type:
- Example:
>>> from mooonpy import Path >>> MyPath = Path('Project/Monomers/DETDA.mol') >>> print(MyPath.basename()) 'DETDA.mol'
- dir() Path[source]
Split Path to directory.
Alias for os.path.dirname.
- Returns:
Path to directory
- Return type:
- Example:
>>> from mooonpy import Path >>> MyPath = Path('Project/Monomers/DETDA.mol') >>> print(MyPath.dir()) 'Project\Monomers'
- ext() Path[source]
Split Path to just extention.
Alias for os.path.basename and splitext.
- Returns:
extention as Path
- Return type:
- Example:
>>> from mooonpy import Path >>> MyPath = Path('Project/Monomers/DETDA.mol') >>> print(MyPath.ext()) '.mol'
- classmethod find_prefix(common=None, path=None, add=True) Path | None[source]
Extract the prefix of path up to and including common, and optionally append it to
search_prefixes.When path is omitted the caller’s
__file__is used automatically, so a script located inside the common directory tree only needs to supply the common directory name. When common is omitted the already-storedsearch_commonis reused, allowing multiple calls for different drives without repeating the directory name.- Parameters:
common (str or None) – Shared directory name, e.g.
'research'. Omit to reusesearch_common(must have been set earlier).path (str, Path, or None) – Path containing common as a component. Omit to use the calling script’s
__file__automatically.add (bool) – Append the extracted prefix to
search_prefixes(defaultTrue). Duplicates are skipped.
- Returns:
Extracted prefix
Path, orNoneif common was not found in path.- Return type:
Path or None
- Example:
>>> # In a script at C:/research/sims/run_001/analysis.py: >>> Path.find_prefix('research') # auto-detects C:\research Path('C:\\research') >>> Path.find_prefix(path='D:/backups/research/sims/run_001/analysis.py') Path('D:\\backups\\research') # reuses search_common='research'
- format(*args, **kwargs) str[source]
Return a formatted version of S, using substitutions from args and kwargs. The substitutions are identified by braces (‘{’ and ‘}’).
- ignore_nonnumeric_priority_wild = False
- locate(recent=None) Path | None[source]
Locate this path across
search_prefixes.Behaviour depends on recent and whether the path contains a
*wildcard:recent=None(default) — prefix-order priorityNo wildcard: return the first prefix for which the exact file exists.
Wildcard: return the glob pattern (
*kept in place) for the first prefix that has any matches. Pass that result tomatches()or iterate over it to expand the files.
recent=True— return the most recently modified file across all prefixes (wildcards expanded vialocate_all()).recent=False— return the oldest file across all prefixes.
Naming note:
locateavoids shadowing the built-instr.find()method.- Parameters:
recent –
Nonefor prefix-order (default),Truefor newest,Falsefor oldest.- Returns:
Matched
Path, orNone.- Return type:
Path or None
- Example:
>>> Path.search_prefixes = [Path('C:/research'), Path('D:/backups/research')] >>> Path.search_common = 'research' >>> Path('sims/run_001/output.log').locate() Path('C:\\research\\sims\\run_001\\output.log') >>> Path('sims/*/output.log').locate() # returns the pattern Path('C:\\research\\sims\\*\\output.log') >>> Path('sims/*/output.log').locate(recent=True) Path('D:\\backups\\research\\sims\\run_002\\output.log') >>> Path('sims/*/output.log').locate(recent=False) Path('C:\\research\\sims\\run_001\\output.log')
- locate_all(whitelist_ext=None, blacklist_ext=None) List[Path][source]
Return all glob matches of this path across every prefix in
search_prefixes.Wildcards are expanded on each prefix independently, so
Path('sims/*/output.log').locate_all()collects every matching file across all configured drives.- Parameters:
whitelist_ext – If given, only include paths with these extensions.
blacklist_ext – If given, exclude paths with these extensions.
- Returns:
All matching
Pathobjects across all prefixes.- Return type:
List[Path]
- Example:
>>> Path.search_prefixes = [Path('C:/research'), Path('D:/backups/research')] >>> Path.search_common = 'research' >>> Path('sims/*/output.log').locate_all() [Path('C:\\research\\sims\\run_001\\output.log'), Path('D:\\backups\\research\\sims\\run_001\\output.log'), Path('D:\\backups\\research\\sims\\run_002\\output.log')]
- matches(whitelist_ext=None, blacklist_ext=None) List[Path][source]
Finds matching paths with a * (asterisk) wildcard character.
- Returns:
List of matching Paths
- Return type:
List[Path]
- Example:
>>> from mooonpy import Path >>> MyWildcard = Path('*.mol') >>> print(Path.matches(MyWildcard)) [Path('DETDA.mol'), Path('DEGBF.mol')]
- natsort_right_to_left = True
- open(mode='r', encoding='utf-8')[source]
Open path with smart_open
- Parameters:
mode (str) – Open mode, usually ‘r’ or ‘a’
encoding (str) – File encoding
- Returns:
opened file as object
- Return type:
File Object
- Example:
>>> from mooonpy import Path >>> MyPath = Path('Project/Monomers/DETDA.mol') >>> MyFileObj = MyPath.open(mode='r')
- recent(oldest: bool = False) Path | None[source]
Find wildcard matches and return the Path of the most recently modified file.
- Parameters:
oldest (bool) – Reverses direction and finds least recently modified file.
- Returns:
Path of most recently modified file
- Return type:
- Example:
>>> from mooonpy import Path >>> MyWildcard = Path('Template_*.lmpmol') >>> print(Path.recent()) 'Template_1_v10_final_realthistime.lmpmol' >>> print(Path.recent(oldest=True)) 'Template_1.lmpmol'
- root() Path[source]
Split Path to filename with no extention.
Alias for os.path.basename and splitext.
- Returns:
Path of filename
- Return type:
- Example:
>>> from mooonpy import Path >>> MyPath = Path('Project/Monomers/DETDA.mol') >>> print(MyPath.root()) 'DETDA'
- search_common = None
- search_prefixes = None
- swap_prefix(target) Path | None[source]
Return a new path with this path’s prefix replaced by target.
Strips everything up to and including
search_commonfrom self (via_relpath_from_common()), then prepends the chosen prefix.- Parameters:
target (int, str, or Path) – Replacement prefix — either an
intindex intosearch_prefixes, or astr/Pathvalue.- Returns:
Rewritten
Path, orNoneif target is an out-of-range integer index.- Return type:
Path or None
- Example:
>>> Path.search_prefixes = [Path('C:/research'), Path('D:/backups/research')] >>> Path.search_common = 'research' >>> p = Path('D:/backups/research/sims/run_001/output.log') >>> p.swap_prefix(0) Path('C:\\research\\sims\\run_001\\output.log') >>> p.swap_prefix('D:/backups/research') Path('D:\\backups\\research\\sims\\run_001\\output.log')
- class mooonpy.ReactionTemplate(A, B, *, A_name='A', B_name='B', breaks=(), makes=(), changed_typ=(), vect=(0.0, 0.0, 0.0), delete_byproduct=True)[source]
Bases:
objectBuild a
fix bond/reacttemplate pair from twoFragmentreactants.- Parameters:
A (Fragment) – First reactant fragment.
B (Fragment) – Second reactant fragment.
A_name (str) – Short string used as the dictionary key for
Aatoms inbreaks,makes,changed_typ, andid_map.B_name (str) – Same as
A_nameforB.breaks (list[tuple[str, int, int]]) – List of
(name, orig_id1, orig_id2)triples — bonds to remove from the post state. Both ids must reference the same reactant.makes (list[tuple[str, int, str, int]]) – List of
(name1, orig_id1, name2, orig_id2)quads — bonds to create in the post state.changed_typ (list[tuple[str, int, str]]) – List of
(name, orig_id, new_nta)triples — writenew_ntaintopost.atoms[new_id].comment. The integeratom.typeis left untouched (downstream atom_typing re-assigns it from the.ntafile).vect (tuple[float, float, float]) – Relative displacement between the two fragment initiators in the combined pre state.
B’s initiator is placed atA_initiator + vect.(0, 0, 0)makes them coincident.delete_byproduct (bool) – After applying bond changes, run cluster ID on the post state; everything not in the largest cluster is added to
DeleteIDs.
Computed attributes:
pre(Molspace): merged pre-reaction state with 1..N ids.post(Molspace): same ids; bonds and NTAs updated.rxn_map(dict): editable intermediate; written bywrite_map().id_map(dict):{(name, original_id): preserved_id}.
- write_data(pre_path, post_path)[source]
Write pre and post
.datafiles plus their companion.ntafiles.Data files are FF-stripped: no angles / dihedrals / impropers, no FF coefficient sections, no Velocities section, and a single dummy bond type. The Masses section is kept so downstream tools can sanity-check atom types. Atom comments are reduced to just the NTA token.
The
.ntafiles are derived from the data file paths by replacing the extension. They feedatom_typing/all2lmpdownstream.
- write_map(path)[source]
Write
self.rxn_maptopathin mooonpy map-file format.- Parameters:
path (str or
mooonpy.tools.file_utils.Path) – Output path. Wrapped inPathif it isn’t one.
- class mooonpy.Thermospace(filename=None, **kwargs)[source]
Bases:
ColTableClass to hold data found in LAMMPS logs. Data is organized into columns
- join_restart(restart, step_col='Step', restart_step_ind=0, this_step_ind=None)[source]
Appends data from a restarted thermospace to the current one. Uses (step_col, restart_step_ind) as the start of the appended section, and finds the last matching (step_col, this_step_ind) and overwrites after that
step_col is the column used for indexing, defaults to ‘Step’ but ‘v_Time’ may also be used
restart_step_ind = 0 uses 0th index step, and so on this_step_ind = None uses last matching value
- sect(sect_string: str | range | list | int | ndarray | None = None, priority='off') ColTable[source]
Extract a subset of data by section ID(s).
- Parameters:
sect_string – Section selector. int for single section, list/array of ints for multiple, range for a range of IDs, None for all sections. str supports comma-separated values and colon ranges with stride (inclusive, 1-indexed, negative indexing):
"1:3""6:""-3:""::-1""1:5:2""1,3,-1"priority – ‘first’ drops the first row of non-first sections, ‘last’ drops the last row of non-first sections, ‘off’ keeps all rows.
Subpackages
- mooonpy.fitting package
- mooonpy.guis package
- mooonpy.molspace package
- Subpackages
- Submodules
- mooonpy.molspace.atom_styles module
- mooonpy.molspace.atoms module
- mooonpy.molspace.bonds_from_distances module
- mooonpy.molspace.box module
- mooonpy.molspace.clusters module
- mooonpy.molspace.distance module
- mooonpy.molspace.doc_examples module
- mooonpy.molspace.force_field module
- mooonpy.molspace.molspace module
MolspaceMolspace.KE()Molspace.add_type_labels()Molspace.bonds_from_distances()Molspace.build_old2new()Molspace.combine()Molspace.compute_ADI()Molspace.compute_BADI_by_type()Molspace.compute_bond_length()Molspace.compute_pairs()Molspace.contiguous()Molspace.copy()Molspace.find_rings()Molspace.generate_graph()Molspace.min_image_unwrap()Molspace.reachable()Molspace.read_files()Molspace.remap_ids()Molspace.remove_atoms()Molspace.slice()Molspace.temp()Molspace.update_atoms()Molspace.update_elements()Molspace.write_files()
- mooonpy.molspace.periodic_table module
- mooonpy.molspace.reaxff module
- mooonpy.molspace.remap module
- mooonpy.molspace.rings module
- mooonpy.molspace.topology module
- mooonpy.programs package
- mooonpy.template package
- mooonpy.thermospace package
- mooonpy.tools package
- Submodules
- mooonpy.tools.file_utils module
- mooonpy.tools.loop_utils module
- mooonpy.tools.math_utils module
- mooonpy.tools.misc_utils module
- mooonpy.tools.signals module
- mooonpy.tools.string_utils module
- mooonpy.tools.tables module
- Submodules
- mooonpy.xrdspace package