Skip to content

Instantly share code, notes, and snippets.

@schneiderfelipe
Last active August 29, 2018 12:04
Show Gist options
  • Save schneiderfelipe/46ce40815c64c673d7cdc9ed185a2739 to your computer and use it in GitHub Desktop.
Save schneiderfelipe/46ce40815c64c673d7cdc9ed185a2739 to your computer and use it in GitHub Desktop.
API proposal for pyrrole
class pyrrole.ChemicalEquation:
"""
Examples
--------
pyrrole.atoms.create_data is useful for producing data objects (receives iterables or mappings of pyrrole.atoms.Atoms):
>>> r = pyr.ChemicalEquation("A <=> B + C", pyr.atoms.create_data([pyr.atoms.read_cclib("path/to/A.out", "A"),
... pyr.atoms.read_cclib("path/to/B.out", "B"),
... pyr.atoms.read_cclib("path/to/C.out", "C")]))
You can get general information:
>>> r.reactants
["A"]
>>> r.products
["B", "C"]
>>> r.species
["A", "B", "C"]
Printing a canonical version:
>>> print(r)
A <=> B + C
Balancing equations:
>>> r.balance()
Equilibrium constant and pKa calculations:
>>> K = np.exp(- r.attribute['freeenergy'] / (R * r.attribute['temperature']))
>>> pKa = -np.log10(K)
Produce data useful for supporting information (calls ChemicalEquation.to_series and uses mhchem if requested) with energies
differences, etc.:
>>> r.to_latex(use_mhchem=True)
Final equilibrium proportions for single equation should be treated as a ChemicalSystem with a single equation (below).
Single reaction propagation in time should be done as a ChemicalSystem with a single reaction.
Plotting and manipulation of spectra for a single equilibrium or reaction should be done as a ChemicalSystem with a single
equation.
Data objects
------------
Conceptually, reference data are objects that store data retrieved from sources. This data can be used by internal
algorithms. The data is never modified, only referenced, and is always of pandas.DataFrame type.
The create_data function that eases the creation of such a pandas.DataFrame based on iterables of types:
- Series are appended
- Atoms have their to_series function called and are appended as Series
- DataFrames are concatenated as sets of Series
You can also produce data objects with cclib.io.ccframe or its script couterpart.
To do
-----
Implement or indicate a way to check for reactions and equilibria (right now reactions have '->' arrow,
equilibria '<=>' arrow).
Implement mapping behavior (to get properties or stoichiometric coefficients by string or object).
Implement a method for solving one or a set of chemical equations as a function of other chemical equations.
Implement simplification ("2 A -> 2 B" becomes "A -> B").
Implement special functions for generating common reaction schemes such as equilibria of many conformations.
Implement detection of the following types of reactions:
- from ground state to transition state.
- from ground state to ground state.
- from transition state to ground state.
- others.
"""
pass
class pyrrole.ChemicalSystem:
"""
Examples
--------
>>> rs = pyr.ChemicalSystem("D <- A <=> B + C", pyr.atoms.create_data([pyr.atoms.read_cclib("path/to/A.out", "A"),
... pyr.atoms.read_cclib("path/to/B.out", "B"),
... pyr.atoms.read_cclib("path/to/C.out", "C"),
... pyr.atoms.read_cclib("path/to/D.out", "D")]))
You can get general information:
>>> rs.reactants
["A"]
>>> rs.products
["B", "C", "D"]
>>> rs.species
["A", "B", "C", "D"]
Printing a canonical version:
>>> print(rs)
A -> D
A <=> B + C
Produce complete data table for supporting information (calls ChemicalSystem.to_series and uses mhchem if requested) with
energies differences, etc.:
>>> rs.to_latex(use_mhchem=True)
Balancing multiple equations:
>>> for r in rs.equations:
... r.balance()
Final equilibrium proportions for a set of equations (equilibria only):
>>> rs.equilibrate()
Plotting and manipulation of spectra for a set of equilibria or reactions, which calls Atoms.spectrum for each species and
combines results:
>>> rs.spectrum('ir')
Set initial state of system as a set of concentrations:
>>> rs.concentration = {'D': 1.}
Propagation in time of multiple equations (always keeps equilibrium):
>>> rs.propagate(1.) # seconds
>>> rs.time # time passed in seconds
To do
-----
Implement mapping behavior (to get properties or ChemicalEquation by string or object) or sequence behavior (to get
ChemicalEquation by index).
Implement a method for eliminating a chemical species from a system of chemical equations (if possible), useful for removing
certain species that are difficult to handle: ChemicalSystem.eliminate("H+"), ChemicalSystem.eliminate("e-").
Implement methodologies for obtaining new reactions out of existing ones (implicit reactions, etc.).
Implement tunneling corrections for reaction rates.
Implement methodologies for calculating kinetic isotope effects.
Implement a method of accessing reactions in an indirect manner:
>>> system = pyr.ChemicalSystem("A <=> B <=> C", data)
>>> system["A <=> C"].to_series()
"""
pass
class pyrrole.atoms.Atoms:
"""
1. bag of properties
- Atoms.__init__ receive anything that can turn into a pandas.Series or another Atoms object. This is a record of a data
object (see below).
- Atoms.__init__ is not intended to be used directly.
Factory functions are there to make objects from (already implemented are not shown):
- a pybel.Molecule object (read_pybel).
- atomic positions and numbers.
- a SMILES string (read_smiles).
- a chemical formula (read_formula).
- a string of coordinates (read_string).
- online databases (like molget):
- molecule name (read_name).
- CCSD id (read_ccsd).
- chemspider, etc.
Reference property data is set accordingly in all cases.
2. ordered set of vectors
- This class also attends the demand for manipulating, modifying, measuring and comparing
geometries (np.arrays of size (n, 3) plus atomic numbers). This is simply a set of algorithms to manipulate properties
already stored in the bag (if they do exist).
Examples
--------
Correction for electronic energies:
>>> low_level_freq = pyr.atoms.read_cclib("path/to/low_level_freq.out")
>>> high_level_single_point = pyr.atoms.read_cclib("path/to/high_level_single_point.out")
>>> low_level_freq.attribute['corrected freeenergy'] = low_level_freq.attribute['freeenergy'] \
... - low_level_freq.attribute['scfenergy'] + high_level_single_point.attribute['scfenergy']
Produce a simple representation as xyz geometry:
>>> print(s)
Produce data useful for supporting information (calls Atoms.to_series and prints coordinates):
>>> s.to_latex(use_mhchem=True)
Plotting and manipulation of spectra for individual data sources:
>>> s.spectrum('ir') # or 'nmr' or 'raman', etc.
Molecular orbital diagrams:
>>> s.modiagram()
One of the stored properties are atom coordinates, which live as a
sequence of vectors in `Atoms.attribute['atomcoords']`, allowing for
easy manipulation (see below).
Geometry analysis and manipulation:
>>> carbon_dioxide = pyr.atoms.read_string('''O 0. 0. -1.128
... C 0. 0. 0.
... O 0. 0. 1.128''')
Atom and fragment position arrays:
>>> carbon_dioxide[0]
np.array([0., 0., -1.128])
>>> carbon_dioxide['O']
np.array([[0., 0., -1.128], [0., 0., 1.128]])
Geometry manipulation: bond lengths, distance measurements and angles (radians):
>>> carbon_dioxide[0, 2]
2.256
>>> carbon_dioxide[0, 1, 2]
np.pi
Whole molecule manipulation:
>>> carbon_dioxide -= carbon_dioxide.center_of_mass + np.array([1., 0., 0.])
To do
-----
Implement peak broadening and escalonation for spectra.
Implement bridges for psi4numpy, PyQuante, etc..
Implement detection of fundamental and transition states (Atoms.isgroundstate, Atoms.istransitionstate).
"""
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment