Coder Social home page Coder Social logo

marcello-sega / pytim Goto Github PK

View Code? Open in Web Editor NEW
78.0 8.0 34.0 210.72 MB

a python package for the interfacial analysis of molecular simulations

Home Page: https://marcello-sega.github.io/pytim/

License: GNU General Public License v3.0

Python 100.00%
simulations molecular-dynamics data-analysis mdanalysis gromacs namd charmm lammps interfaces scientific-computing

pytim's Introduction

What is Pytim | Examples | More info | How to Install | References

Build Status GitHub tags GitHub issues codecov Code Climate License: GPL v3

If you try this software out and have some suggestions, remarks, or bugfixes, feel free to comment here on GitHub and/or make a pull request.

Jupyter Notebooks with more examples are available at Marcello-Sega/pytim-notebooks

The paper about pytim has been published on J. Comput. Chem. It is open access and you can download the pdf from Wiley (see also the references)

What is Pytim

Pytim is a cross-platform python implementation of several methods for the detection of fluid interfaces in molecular simulations. It is based on MDAnalysis, but it integrates also seamlessly with MDTraj, and can be even used for online analysis during an OpenMM simulation (see further down for examples with MDTraj and with OpenMM).

So far the following interface/phase identification methods have been implemented:

  • ITIM
  • GITIM
  • SASA
  • Willard Chandler
  • DBSCAN filtering

Supported formats

Pytim relies on the MDAnalysis package for reading/writing trajectories, and work therefore seamlessly for a number of popular trajectory formats, including:

  • GROMACS
  • CHARMM/NAMD
  • LAMMPS
  • AMBER
  • DL_Poly

as well as common structure file formats such as XYZ or PDB (have a look at the complete list)

Install from PyPi or Anaconda - PyPI version Anaconda-Server Badge

PyPi: pip install --user --upgrade pytim

Anaconda: conda install -c conda-forge pytim

NOTE: on Mac OS you might want to use CFLAGS='-stdlib=libc++' pip install --user --upgrade pytim

Show me an example usage, now!

Ok, ok ... have a look below: this example is about computing molecular layers of a flat interface:

Step 1: interface identification

import MDAnalysis as mda
import pytim
from pytim.datafiles import WATER_GRO

# load the configuration in MDAnalysis
u = mda.Universe(WATER_GRO)

# compute the interface using ITIM. Identify 4 layers.
inter = pytim.ITIM(u,max_layers=4)

That's it. There's no step 2!

Now interfacial atoms are accessible in different ways, pick the one you like:

  1. Through the atoms group accessible as
inter.atoms.positions # this is a numpy array holding the position of atoms in the layers
array([[ 22.10000038,  16.05999947,  94.19633484],
       [ 22.43999863,  16.97999954,  93.96632385],
       ...,
       [ 33.70999908,  49.02999878,  62.52632904],
       [ 34.06999969,  48.18000031,  61.16632843]], dtype=float32)
  1. Using the label that each atom in the MDAnalysis universe now has, which specifies in which layer it is found:
u.atoms.layers  # -1 if not in any layer, 1 if in the first layer, ...
  1. Using the layers groups, stored as a list (of lists, in case of upper/lower layers in flat interfaces) of groups:
inter.layers

array([[<AtomGroup with 780 atoms>, <AtomGroup with 690 atoms>,
        <AtomGroup with 693 atoms>, <AtomGroup with 660 atoms>],
       [<AtomGroup with 777 atoms>, <AtomGroup with 687 atoms>,
        <AtomGroup with 663 atoms>, <AtomGroup with 654 atoms>]], dtype=object)

Visualisation

Pytim can export in different file formats: the PDB format with the beta field used to tag the layers, VTK, cube for both continuous surfaces and particles, and, of course, all formats supported by MDAnalysis.

In VMD, for example, using beta == 1 allows you to select all atoms in the first interfacial layer. Just save your PDB file with layers information using

inter.writepdb('myfile.pdb')

In a jupyter notebook, you can use nglview like this:

import nglview
v = nglview.show_mdanalysis(u)
v.camera='orthographic'
v.center()
system = v.component_0
colors = ['','red','orange','yellow','white']

for n in [1,2,3,4]:
    system.add_spacefill(selection = inter.atoms[inter.atoms.layers==n].indices, color=colors[n] )

system.add_spacefill(selection = (u.atoms - inter.atoms).indices, color='gray' )
# this must go in a separate cell
v.display()

Analysing trajectories (MDAnalysis and mdtraj)

Once one of the pytim classes (ITIM,GITIM,WillardChandler,...) has been initialised, whenever a new frame is loaded, the interfacial properties will be calculated automatically without need of doing anything else

MDAnalysis example

import MDAnalysis as mda
import pytim 
from pytim.datafiles import WATER_GRO, WATER_XTC 

u = mda.Universe(WATER_GRO,WATER_XTC)
inter = pytim.ITIM(u)
for step in u.trajectory[:]:
    print "surface atoms:", repr(inter.atoms)

mdtraj example

Under the hood, pytim uses MDAnalysis, but this is made (almost completely) transparent to the user, so that interoperability with other software is easy to implement. For example, to analyse a trajectory loaded with MDTraj, it is enough to do the following:

import mdtraj
import pytim                     
from pytim.datafiles import WATER_GRO, WATER_XTC 

t = mdtraj.load_xtc(WATER_XTC,top=WATER_GRO) 
inter = pytim.ITIM(t) 
for step in t[:]:
        print "surface atoms:" , repr(inter.atoms.indices)

openmm example

Another example is using pytim to perform online interfacial analysis during an OpenMM simulation:

# openmm imports
from simtk.openmm.app import *
from simtk.openmm import *
from simtk.unit import *
# pytim
import pytim
from pytim.datafiles import WATER_PDB

# usual openmm setup, we load one of pytim's example files
pdb = PDBFile(WATER_PDB)
forcefield = ForceField('amber99sb.xml', 'spce.xml')
system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME,
        nonbondedCutoff=1*nanometer)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(pdb.topology, system, integrator)
simulation.context.setPositions(pdb.positions)

# just pass the openmm Simulation object to pytim
inter = pytim.ITIM(simulation)
print repr(inter.atoms)

# the new interfacial atoms will be computed at the end
# of the integration cycle
simulation.step(10)
print repr(inter.atoms)

What if the interface is not flat?

You could use GITIM, or the Willard-Chandler method. Let's have a look first at GITIM:

import MDAnalysis as mda
import pytim
from   pytim.datafiles import *

u       = mda.Universe(MICELLE_PDB)
g       = u.select_atoms('resname DPC')

interface = pytim.GITIM(u,group=g,molecular=False,
                        symmetry='spherical',alpha=2.5)
layer = interface.layers[0]
interface.writepdb('gitim.pdb',centered=False)
print repr(layer)
<AtomGroup with 872 atoms>

nglview can be used to show a section cut of the micelle in a jupyter notebook:

import nglview
import numpy as np

v = nglview.show_mdanalysis(u)
v.camera='orthographic'
v.center()
v.add_unitcell()
system = v.component_0
system.clear()

selection = g.atoms.positions[:,2]>30.
system.add_spacefill(selection =g.atoms.indices[selection])

selection = np.logical_and(inter.atoms.layers==1,inter.atoms.positions[:,2]>30.)
system.add_spacefill(selection =inter.atoms.indices[selection], color='yellow' )
v.display()

The Willard-Chandler method can be used, instead to find out isodensity surfaces:

import MDAnalysis as mda
import pytim
from pytim.datafiles import MICELLE_PDB
import nglview

u = mda.Universe(MICELLE_PDB)
g = u.select_atoms('resname DPC')
interface = pytim.WillardChandler(u, group=g, mesh=1.5, alpha=3.0)
interface.writecube('data.cube')

Done, the density file is written in .cube format, we can now open it with programs such as Paraview, or visualize it in a jupyter notebook with nglview

view = nglview.show_mdanalysis(u.atoms) # the atoms, this will be component_0 in nglview
view.add_component('data.cube') # the density data, this will be component_1 in nglview

view.clear() # looks like this is needed in order for view._display_image() to work correctly 
# let's center the view on our atoms, and draw them as spheres  
view.component_0.center()
view.component_0.add_spacefill(selection='DPC')

# let's add a transparent, red representation for the isodensity surface at 50% density
view.component_1.add_surface(color='red',isolevelType="value",isolevel=0.5,opacity=0.6) 

# add a nice simulation box
view.add_unitcell()
view.display()

Calculate multiple layers with GITIM: solvation shells of glucose

import MDAnalysis as mda
import pytim
from   pytim.datafiles import GLUCOSE_PDB

u       = mda.Universe(GLUCOSE_PDB)
solvent = u.select_atoms('name OW')
glc     = u.atoms - solvent.residues.atoms

inter = pytim.GITIM(u, group=solvent, molecular=True,
                    max_layers=3, alpha=2)

for i in [0,1,2]:
    print "Layer "+str(i),repr(inter.layers[i])
Layer 0 <AtomGroup with 81 atoms>
Layer 1 <AtomGroup with 186 atoms>
Layer 2 <AtomGroup with 240 atoms>
import nglview
import numpy as np

v = nglview.show_mdanalysis(u)
v.camera='orthographic'
v.center()
v.add_unitcell()

v.clear()

# glucose
v.add_licorice(selection =glc.atoms.indices,radius=.35)

colors = ['yellow','blue','purple']
# hydration layers
for layer in [0,1,2]:
    selection = np.logical_and(inter.atoms.layers==layer+1 ,inter.atoms.positions[:,2]>9)
    v.add_spacefill(selection =inter.atoms.indices[selection], color=colors[layer] )
v.display()

When calculating surfaces with GITIM, it can happen that several disconnected, closed surfaces are found in a simulation box. To restrict the analysis to the largest, clustered interfacial atoms (also when calculating multiple layers), one can pass the biggest_cluster_only option, as in:

inter = pytim.GITIM(u, group=solvent, molecular=True, max_layers=3, alpha=2, 
                    biggest_cluster_only=True, cluster_cut = 3.5)

In order for this option to have any effect, a cluster_cut value should also be passed.

More info

  1. Have a look at the jupyter notebooks: https://github.com/Marcello-Sega/pytim-notebooks

  2. Browse the examples in the Pytim Online Manual

  3. Check out the Pytim Poster from the 10th Liquid Matter Conference Available on ResearchGate DOI:10.13140/RG.2.2.18613.17126

How to install the package and the documentation?

From the PyPI

this will install the latest release present in the Python Package Index:

pip install --user --upgrade pytim

From Github

  1. Make sure you have an up-to-date version of cython, numpy, scipy and MDAnalysis:
pip install --user --upgrade cython numpy scipy MDAnalysis
  1. Download and install pytim
git clone https://github.com/Marcello-Sega/pytim.git
cd pytim
python setup.py install --user

Setting the PYTHONPATH variable

If you install with the option --user (which you have to do if you don't have administrator rights) you shouldn't forget to tell python where to look for the module by setting the PYTHONPATH environment variable.

Under Linux, you could do, for example:

export PYTHONPATH=$HOME/.local/lib/python2.7/site-packages

Under OS-X, instead, use something like:

export PYTHONPATH=$HOME/Library/Python/2.7/lib/python/site-packages

You can search for the exact path by issuing the following command:

python -c "import site; print(site.USER_SITE)"

If this for some reason doesn't work, get some hint using:

find $HOME -name site-packages

Trouble installing?

Some of the most common issues are the following:

Problem: The system does not let me write (even using sudo) some files

Solution: You're most likely running under a recent version of OS-X. Always install packages as user (pip install <package> --user

Problem: cKDTree complains about the boxsize parameter

Solution: the version of scipy must be >= 0.18

Problem: Even though I've upgraded scipy, I keep getting problems about boxsize

Solution: You should tell python where to find packages by setting the variable $PYTHONPATH

Problem: some error message mentioning ... file was built for x86_64 which is not the architecture being linked (i386)

Solution: use export ARCHFLAGS='-arch x86_64' before installing

Problem: I'm getting an annoying message like "UserWarning: Module pytim_dbscan was already imported from [...]"

Solution: You've installed pytim, and are launching python within the pytim package directory. Move away from there :)


References

The pytim paper is avaliable (under the terms of the Creative Commons BY-NC 4.0 licence) from Wiley. Please cite it if you use pytim for your research:

M. Sega, S. G. Hantal, B. Fabian and P. Jedlovszky, J. Comp. Chem. 39, 2118-2125 (2018) Pytim: A python package for the interfacial analysis of molecular simulations

@article{sega2018pytim,
  title={Pytim: A python package for the interfacial analysis of molecular simulations},
  author={Sega, M. and Hantal, G. and F{\'a}bi{\'a}n, B. and Jedlovszky, P.},
  journal={J. Comput. Chem.},
  pages={2118--2125},
  volume={39},
  year={2018},
  publisher={Wiley Online Library}
}

Depending on which algorithm you are using, you might also want to cite the following:

M. Sega, S. S. Kantorovich, P. Jedlovszky and M. Jorge, J. Chem. Phys. 138, 044110 (2013) The generalized identification of truly interfacial molecules (ITIM) algorithm for nonplanar interfaces.

L. B. Pรกrtay, G. Hantal, P. Jedlovszky, ร. Vincze and G. Horvai, J. Comp. Chem. 29, 945 (2008) A new method for determining the interfacial molecules and characterizing the surface roughness in computer simulations. Application to the liquidโ€“vapor interface of water

M. Sega and G. Hantal.Phys. Chem. Chem. Phys. 29, 18968-18974 (2017) Phase and interface determination in computer simulations of liquid mixtures with high partial miscibility.

A. P. Willard, D. Chandler, J. Phys. Chem. B 114,1954 (2010) Instantaneous Liquid Interfaces

pytim's People

Contributors

balazsfabian avatar bnovak1 avatar elija-feigl avatar gyorgy-hantal avatar iuvenis avatar jakobmichl avatar marcello-sega avatar pyup-bot avatar quantifiedcode-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pytim's Issues

cluster search fails for too small search radii

when an unreasonably small value of cluster_cut parameter is passed, the algorithm fails, e.g:

import pytim
from pytim.datafiles import *
import MDAnalysis as mda 
u=mda.Universe(WATER_GRO)
inter=pytim.ITIM(u,alpha=1.25,cluster_cut=0.1)
inter.assign_layers()

produces

  File "test.py", line 12, in <module>
  inter.assign_layers()
  File "build/bdist.macosx-10.12-intel/egg/pytim/itim.py", line 231, in assign_layers
  File "build/bdist.macosx-10.12-intel/egg/pytim/utilities.py", line 174, in     do_cluster_analysis_DBSCAN
  File "pytim/_dbscan_inner.pyx", line 24, in dbscan.dbscan_inner (pytim/_dbscan_inner.cpp:1734)
  ValueError: Buffer has wrong number of dimensions (expected 1, got 2)

AttributeError: module 'numpy' has no attribute 'int'

Discussed in #405

Originally posted by lubilok May 9, 2024
Hi,
I was trying to find out the true interface of the liquid/vapor interface in my system using Pytim modules, but I am getting an error like below

import MDAnalysis as mda
import pytim
u = mda.Universe("md_0_1.gro")
interface = pytim.ITIM(u)
interface.writepdb('layers.pdb',centered='middle')
upper_layer = interface.layers[0,0]

AttributeError Traceback (most recent call last)
/tmp/ipykernel_80284/2357494757.py in
4 # initialize the interface, this has to be called only once
5 # before iterating over the trajectory!
----> 6 interface = pytim.ITIM(u)
7
8 # write a pdb with the information on the surface layers

~/anaconda3/lib/python3.9/site-packages/pytim/itim.py in init(self, universe, group, alpha, normal, molecular, max_layers, radii_dict, cluster_cut, cluster_threshold_density, extra_cluster_groups, info, centered, warnings, mesh, autoassign, **kargs)
217 cluster_threshold_density, extra_cluster_groups)
218 sanity.assign_normal(normal)
--> 219 sanity.assign_radii(radii_dict=radii_dict)
220
221 self.grid = None

~/anaconda3/lib/python3.9/site-packages/pytim/sanity_check.py in assign_radii(self, radii_dict)
146 self.patch_radii_dict()
147
--> 148 _missing_attributes(self.interface, self.interface.universe)
149
150 try:

~/anaconda3/lib/python3.9/site-packages/pytim/properties.py in _missing_attributes(interface, universe)
72 _check_missing_attribute(interface, 'elements', 'Elements', universe.atoms,
73 1)
---> 74 _extra_attributes(interface, universe)
75
76

~/anaconda3/lib/python3.9/site-packages/pytim/properties.py in _extra_attributes(interface, universe)
81 for key in attr.keys():
82 if key not in dir(universe.atoms):
---> 83 vals = np.zeros(len(universe.atoms), dtype=np.int) - 1
84 universe.add_TopologyAttr(attrkey)
85

~/anaconda3/lib/python3.9/site-packages/numpy/init.py in getattr(attr)
282 return Tester
283
--> 284 raise AttributeError("module {!r} has no attribute "
285 "{!r}".format(name, attr))
286

AttributeError: module 'numpy' has no attribute 'int'

Please tell me how I can fix it.
Thank you.

unreasonable results of intrinsic profiles at distances far from the first layer

I have successfully (no errors) calculated the intrinsic profile with respective to the first layer for the freestanding film. I find it is reasonable at distances close to the first layer. However, great fluctuations occur at distances far from the first layer. This furthest distance should correspond to the center of the film, so that great fluctuations in the density profile are not expected. How to cope with it? The python scipt and resulting data are copied below.

python scipt:
import MDAnalysis as mda
import numpy as np
import pytim
from pytim.observables import Profile
u = mda.Universe('LJ.gro', 'LJ.short.xtc')
g = u.select_atoms('all')
inter = pytim.ITIM(u, alpha=2.5, cluster_cut=4.5)
profile = Profile(interface=inter)

for ts in u.trajectory[:]:
profile.sample(g)

lower, upper, avg = profile.get_values(binwidth=0.5)
bins = (lower + upper) / 2.
np.savetxt('profile.dat', list(zip(bins, avg)))
//end of file

resulting data:
-5.035062712938795926e+01 0.000000000000000000e+00
-4.985210606870095518e+01 0.000000000000000000e+00
-4.935358500801394399e+01 0.000000000000000000e+00
-4.885506394732693281e+01 0.000000000000000000e+00
-4.835654288663992872e+01 0.000000000000000000e+00
-4.785802182595291754e+01 0.000000000000000000e+00
-4.735950076526590635e+01 0.000000000000000000e+00
-4.686097970457889517e+01 0.000000000000000000e+00
-4.636245864389188398e+01 0.000000000000000000e+00
-4.586393758320487279e+01 0.000000000000000000e+00
-4.536541652251786871e+01 0.000000000000000000e+00
-4.486689546183085753e+01 0.000000000000000000e+00
-4.436837440114385345e+01 0.000000000000000000e+00
-4.386985334045684226e+01 0.000000000000000000e+00
-4.337133227976983108e+01 0.000000000000000000e+00
-4.287281121908281989e+01 0.000000000000000000e+00
-4.237429015839580870e+01 0.000000000000000000e+00
-4.187576909770879752e+01 1.449272759536325908e-02
-4.137724803702178633e+01 3.225800658322789533e-02
-4.087872697633478225e+01 1.041664795916734214e-02
-4.038020591564777106e+01 1.936795706169340547e-02
-3.988168485496076698e+01 1.859054162362421686e-02
-3.938316379427375580e+01 1.806448368660762069e-02
-3.888464273358674461e+01 2.016033034571494340e-02
-3.838612167289973343e+01 2.176759793827573453e-02
-3.788760061221272224e+01 1.870930490520346032e-02
-3.738907955152571105e+01 1.917743203569530902e-02
-3.689055849083869987e+01 1.952938891259046669e-02
-3.639203743015169579e+01 1.936810541405449212e-02
-3.589351636946469171e+01 1.861534984911493093e-02
-3.539499530877768052e+01 1.937610907085984824e-02
-3.489647424809066933e+01 1.946026327913569567e-02
-3.439795318740365815e+01 1.935515105749004844e-02
-3.389943212671664696e+01 1.892188139810614331e-02
-3.340091106602963578e+01 1.986514233089321790e-02
-3.290239000534262459e+01 1.963342509190037916e-02
-3.240386894465562051e+01 1.939103058098697735e-02
-3.190534788396860932e+01 1.929858295589167300e-02
-3.140682682328159814e+01 1.880571100679631277e-02
-3.090830576259459050e+01 1.942059936917492000e-02
-3.040978470190758287e+01 1.918294684444531509e-02
-2.991126364122057169e+01 1.946983376040790220e-02
-2.941274258053356050e+01 1.919970599363195196e-02
-2.891422151984655287e+01 1.969604878871897627e-02
-2.841570045915954523e+01 1.915730998680769195e-02
-2.791717939847253405e+01 1.937657295848854017e-02
-2.741865833778552286e+01 1.940839313389452342e-02
-2.692013727709851523e+01 1.967623847211384322e-02
-2.642161621641150759e+01 1.914304017663918597e-02
-2.592309515572449641e+01 1.937525276552039960e-02
-2.542457409503748522e+01 1.934865600370361607e-02
-2.492605303435047759e+01 1.921509472467793425e-02
-2.442753197366346996e+01 1.924592952218833267e-02
-2.392901091297645877e+01 1.929158722244531804e-02
-2.343048985228944758e+01 1.902266794084753188e-02
-2.293196879160243640e+01 1.927876866212916915e-02
-2.243344773091542876e+01 1.972800673543309569e-02
-2.193492667022842113e+01 1.930172763408526809e-02
-2.143640560954140994e+01 1.940943129822006105e-02
-2.093788454885439876e+01 1.929648463317657978e-02
-2.043936348816739113e+01 1.955189631696432895e-02
-1.994084242748038349e+01 1.935724353915499463e-02
-1.944232136679337231e+01 1.903861278863661424e-02
-1.894380030610636112e+01 1.915113963524758128e-02
-1.844527924541935349e+01 1.937632504353440505e-02
-1.794675818473234585e+01 1.935590046403035808e-02
-1.744823712404533467e+01 1.939097747162774749e-02
-1.694971606335832348e+01 1.938592350831594077e-02
-1.645119500267131585e+01 1.936542673516332067e-02
-1.595267394198430821e+01 1.906375560572837538e-02
-1.545415288129729703e+01 1.880710621721897596e-02
-1.495563182061028584e+01 1.928766309518091179e-02
-1.445711075992327466e+01 1.951113085439000472e-02
-1.395858969923626702e+01 1.950576627544101452e-02
-1.346006863854925939e+01 1.944158747724345632e-02
-1.296154757786224820e+01 1.897716759763632549e-02
-1.246302651717523702e+01 1.932484503461963030e-02
-1.196450545648822938e+01 1.926312419055146302e-02
-1.146598439580122175e+01 1.931455499936012010e-02
-1.096746333511421057e+01 1.959914325902381224e-02
-1.046894227442719938e+01 1.956927351721393302e-02
-9.970421213740191746e+00 1.964436773014710536e-02
-9.471900153053184113e+00 1.864408577939197578e-02
-8.973379092366172927e+00 1.793961849657403629e-02
-8.474858031679161741e+00 1.870319415697850596e-02
-7.976336970992150555e+00 1.959919453559987035e-02
-7.477815910305142921e+00 2.089975591733926261e-02
-6.979294849618135288e+00 2.065644281206698712e-02
-6.480773788931124102e+00 1.924593753273420860e-02
-5.982252728244112916e+00 1.737777286076639185e-02
-5.483731667557105283e+00 1.624369351447351242e-02
-4.985210606870097649e+00 1.683840784922158856e-02
-4.486689546183086463e+00 1.945033837965195328e-02
-3.988168485496075277e+00 2.363828094721494646e-02
-3.489647424809067644e+00 2.459804801244238476e-02
-2.991126364122060011e+00 1.809994380282325607e-02
-2.492605303435048825e+00 1.161535820148200740e-02
-1.994084242748037639e+00 7.115508993645667038e-03
-1.495563182061030005e+00 4.313275185250832131e-03
-9.970421213740223720e-01 2.272874564688437751e-03
-4.985210606870111860e-01 8.157364297837847982e-04
0.000000000000000000e+00 1.141878033889469762e-01
4.985210606870111860e-01 inf
9.970421213740188193e-01 6.660660099777298399e-05
1.495563182061026453e+00 2.541205390956845626e-05
1.994084242748037639e+00 2.781736763999990617e-05
2.492605303435048825e+00 2.226429894506140258e-05
2.991126364122056458e+00 6.634532499017687583e-05
3.489647424809064091e+00 1.581564409536120657e-04
3.988168485496075277e+00 2.735507339821699729e-04
4.486689546183086463e+00 3.331689266377581759e-04
4.985210606870094097e+00 3.876949202223419627e-04
5.483731667557101730e+00 3.890697563618831438e-04
5.982252728244112916e+00 3.199210863682981219e-04
6.480773788931124102e+00 3.351051919067460122e-04
6.979294849618131735e+00 2.959607143066183632e-04
7.477815910305139369e+00 2.652493143339502610e-04
7.976336970992150555e+00 2.555529669901805646e-04
8.474858031679161741e+00 3.352333372579785367e-04
8.973379092366172927e+00 2.886045755682656051e-04
9.471900153053184113e+00 2.329659928466151059e-04
9.970421213740195299e+00 2.417367392016161684e-04
1.046894227442719938e+01 2.992563080590063870e-04
1.096746333511420346e+01 2.668574355835189168e-04

python3.8 dependencies

There is a cascade of dependencies MDAnalysis < gsd < Cython "numpy>=2.0.0rc1", the last of which cannot be satisfied under python3.8

python3.8  -m pip install  gsd>=3.0.0

Collecting gsd>=3.0.0
  Using cached gsd-3.3.0.tar.gz (182 kB)
  Installing build dependencies ... error
  ERROR: Command errored out with exit status 1:
   command: /apps/local/software/Anaconda3/2021.05/bin/python3.8 /tmp/pip-standalone-pip-qplmzu33/__env_pip__.zip/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-pueturds/overlay --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'setuptools>=64.0.0' wheel Cython 'numpy>=2.0.0rc1'
       cwd: None
  Complete output (8 lines):
  Collecting setuptools>=64.0.0
    Using cached setuptools-70.0.0-py3-none-any.whl (863 kB)
  Collecting wheel
    Using cached wheel-0.43.0-py3-none-any.whl (65 kB)
  Collecting Cython
    Using cached Cython-3.0.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.6 MB)
  ERROR: Could not find a version that satisfies the requirement numpy>=2.0.0rc1 (from versions: 1.3.0, 1.4.1, 1.5.0, 1.5.1, 1.6.0, 1.6.1, 1.6.2, 1.7.0, 1.7.1, 1.7.2, 1.8.0, 1.8.1, 1.8.2, 1.9.0, 1.9.1, 1.9.2, 1.9.3, 1.10.0.post2, 1.10.1, 1.10.2, 1.10.4, 1.11.0, 1.11.1, 1.11.2, 1.11.3, 1.12.0, 1.12.1, 1.13.0, 1.13.1, 1.13.3, 1.14.0, 1.14.1, 1.14.2, 1.14.3, 1.14.4, 1.14.5, 1.14.6, 1.15.0, 1.15.1, 1.15.2, 1.15.3, 1.15.4, 1.16.0, 1.16.1, 1.16.2, 1.16.3, 1.16.4, 1.16.5, 1.16.6, 1.17.0, 1.17.1, 1.17.2, 1.17.3, 1.17.4, 1.17.5, 1.18.0, 1.18.1, 1.18.2, 1.18.3, 1.18.4, 1.18.5, 1.19.0, 1.19.1, 1.19.2, 1.19.3, 1.19.4, 1.19.5, 1.20.0, 1.20.1, 1.20.2, 1.20.3, 1.21.0, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.22.0, 1.22.1, 1.22.2, 1.22.3, 1.22.4, 1.23.0rc1, 1.23.0rc2, 1.23.0rc3, 1.23.0, 1.23.1, 1.23.2, 1.23.3, 1.23.4, 1.23.5, 1.24.0rc1, 1.24.0rc2, 1.24.0, 1.24.1, 1.24.2, 1.24.3, 1.24.4)
  ERROR: No matching distribution found for numpy>=2.0.0rc1

Couldn't find a setup script in /tmp/easy_install-4f0kz3s0/scikit_image-0.21.0.tar.gz

The following error occurred when I ran the command "python3.6 setup.py install --user"
Installed /home/chenza/.local/lib/python3.6/site-packages/sphinx-7.0.1-py3.6.egg
Searching for scikit-image>=0.14.2
Reading https://pypi.org/simple/scikit-image/
Downloading https://files.pythonhosted.org/packages/1d/c2/a54d5e6e2d6708e0722a1aaccef4b7cc1e6df6f76c8b4ce98cd6d0c332c3/scikit_image-0.21.0.tar.gz#sha256=b33e823c54e6f11873ea390ee49ef832b82b9f70752c8759efd09d5a4e3d87f0
Best match: scikit-image 0.21.0
Processing scikit_image-0.21.0.tar.gz
error: Couldn't find a setup script in /tmp/easy_install-4f0kz3s0/scikit_image-0.21.0.tar.gz

Profile issues with interpolator

The distance interpolator can in some cases return NaN (e.g.,the projected position of one atom does not fit within any element of the triangolated surface). In this case, the triangulation returns NaN as a distance, and scipy.stats.binned_statistic() complains because one of the positions is NaN.

add examples / testcases

Feel free to add to this list:

  • document group.clusters and group.sides (Marcello)
  • add scaling of other algorithms (Marcello)
  • make a more visible example (manual, notebooks, examples) on how to use a trajectory (Gyorgy)
  • add example on how to use DBSCAN (examples) (Gyorgy)
  • test that all examples work (Gyorgy)
  • add example on how to use the extra groups for mixed interfaces (manual, examples, notebooks)
  • add LAMMPS example/testcase (dcd trajectory ?; Marcello, Gyorgy)
  • add NAMD example (Marcello)
  • add an example (with capital letters warning) in the manual on how to load beta factors in multiple frames pdb file (Marcello)
  • document and describe the MonteCarlo normalization (Marcello)
  • Tutorial on Multiple interfaces (layers of CCL4 as seen from interface of water) (Gyorgy)
  • Check that all observables are documented/described
  • Correlation function (variable groups) expand documentation and add Tutorial (Balazs)
  • Add trajectory handling (+discussion of the mechanism) in quicktour (Gyorgy)
  • Add Tutorial about trajectory handling (in detail, including manual procedure) (Gyorgy )
  • Check numbers in micelle tutorial (Marcello)
  • Check centering (Marcello, Gyorgy)
  • mdtraj integration: add an example to the manual
  • related to mdtraj: add an example about how to interact with openMM
  • replace the image in README.md with markdown

Error with pytim.ITIM

Dear Marcello,

I try to run the following example code with pytim 0.8,4

import MDAnalysis as mda
import pytim
from pytim.datafiles import WATER_GRO

# load the configuration in MDAnalysis
u = mda.Universe(WATER_GRO)

# compute the interface using ITIM. Identify 4 layers.
inter = pytim.GITIM(u,max_layers=4)
#################

The code can run well, and produce result
But when I change to use:

pytim.ITIM(u,max_layers=4)

It throw the following Error:

###############
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-16-81c4521ead9c> in <module>()
      1 # initialize the interface, this has to be called only once
      2 # before iterating over the trajectory!
----> 3 interface = pytim.ITIM(mdaTraj)
      4 
      5 # write a pdb with the information on the surface layers

C:\DevProgram\miniconda3\envs\py37\lib\site-packages\pytim\itim.py in __init__(self, universe, group, alpha, normal,     molecular, max_layers, radii_dict, cluster_cut, cluster_threshold_density, extra_cluster_groups, info, centered, warnings, mesh,     autoassign, **kargs)
    224         patchTrajectory(self.universe.trajectory, self)
    225 
--> 226         self._assign_layers()
    227 
    228     def _create_mesh(self):

C:\DevProgram\miniconda3\envs\py37\lib\site-packages\pytim\itim.py in _assign_layers(self)
    386 
    387         for p in proc:
--> 388             p.start()
    389         for uplow in [up, low]:
    390             for index, group in enumerate(queue[uplow].get()):

C:\DevProgram\miniconda3\envs\py37\lib\multiprocessing\process.py in start(self)
    110                'daemonic processes are not allowed to have children'
    111         _cleanup()
--> 112         self._popen = self._Popen(self)
    113         self._sentinel = self._popen.sentinel
    114         # Avoid a refcycle if the target function holds an indirect

C:\DevProgram\miniconda3\envs\py37\lib\multiprocessing\context.py in _Popen(process_obj)
    221     @staticmethod
    222     def _Popen(process_obj):
--> 223         return _default_context.get_context().Process._Popen(process_obj)
    224 
    225 class DefaultContext(BaseContext):

C:\DevProgram\miniconda3\envs\py37\lib\multiprocessing\context.py in _Popen(process_obj)
    320         def _Popen(process_obj):
    321             from .popen_spawn_win32 import Popen
--> 322             return Popen(process_obj)
    323 
    324     class SpawnContext(BaseContext):

C:\DevProgram\miniconda3\envs\py37\lib\multiprocessing\popen_spawn_win32.py in __init__(self, process_obj)
     87             try:
     88                 reduction.dump(prep_data, to_child)
---> 89                 reduction.dump(process_obj, to_child)
     90             finally:
     91                 set_spawning_popen(None)
    
C:\DevProgram\miniconda3\envs\py37\lib\multiprocessing\reduction.py in dump(obj, file, protocol)
     58 def dump(obj, file, protocol=None):
     59     '''Replacement for pickle.dump() using ForkingPickler.'''
---> 60     ForkingPickler(file, protocol).dump(obj)
     61 
     62 #

C:\DevProgram\miniconda3\envs\py37\lib\site-packages\MDAnalysis\core\universe.py in __getstate__(self)
    743 
    744     def __getstate__(self):
--> 745         raise NotImplementedError
    746 
    747     def __setstate__(self, state):
    

NotImplementedError: 
##############

Can you give me some hint to overcome this
Thank you so much

ITIM gives different number of surface molecules with mdtraj and default radii_dict for water

With the default radii_dict, ITIM on the water example with mdtraj gives a different number of atoms at the surface compared to ITIM with mdanalysis. When giving the radii explictly, the number of surface atoms is the same when using mdtraj or mdanalysis.

import MDAnalysis as mda
import mdtraj
import pytim
from pytim.datafiles import WATER_GRO, WATER_XTC

# mdanalysis with default radii
u = mda.Universe(WATER_GRO,WATER_XTC)
inter_mdanalysis = pytim.ITIM(u)
for stepu in u.trajectory[:1]:
    print(repr(inter_mdanalysis.atoms))

<AtomGroup with 1572 atoms>

# mdtraj with default radii
t = mdtraj.load_xtc(WATER_XTC, top=WATER_GRO, frame=0)
inter_mdtraj = pytim.ITIM(t)
for step in t[0]:
    print(repr(inter_mdtraj.atoms))

<AtomGroup with 1761 atoms>

# mdanalysis with radii_dict specified
u = mda.Universe(WATER_GRO,WATER_XTC)
inter_mdanalysis = pytim.ITIM(u, radii_dict={'OW': 1.5828241418604836, 'HW': 0.0})
for stepu in u.trajectory[:1]:
    print(repr(inter_mdanalysis.atoms))

<AtomGroup with 1572 atoms>

# mdtraj with radii_dict specified
t = mdtraj.load_xtc(WATER_XTC, top=WATER_GRO, frame=0)
inter_mdtraj = pytim.ITIM(t, radii_dict={'OW': 1.5828241418604836, 'HW': 0.0})
for step in t[0]:
    print(repr(inter_mdtraj.atoms))

<AtomGroup with 1572 atoms>

MDAnalysis version

Tried to run pytim with MDA version 0.15.0, which is mentioned in the requirements.txt and setup.py.
However, on creating an ITIM object, the code tells me that I should use 0.16.x or newer. Can't we just require MDA 0.16.x or newer in the setup.py?

problem detecting surface atoms

From #345 @thangckt

Dear Marcello,

It runs now. Thank you for your update.

I have a problem with pytim.ITIM when I try to detect to the free surface of the simple model as figure (free surface on 'z' and periodicity on 'x' and 'y')
image

I use the following code:
##########
import MDAnalysis, pytim
mdaTraj = MDAnalysis.Universe('Model_Al_z001.cfg', format='lammpsdump')
inter = pytim.ITIM(mdaTraj, molecular=False, normal='z')
inter.atoms
#######
and the result return: <AtomGroup with 0 atoms>

Can you give me some hints on what I get wrong?
I attracted the model file here: https://ufile.io/cmi0nxjs

Thank you so much

Originally posted by @thangckt in #345 (comment)

undefined radii lead to unexpected behaviour

Problem: when an atomic radius is not found in the database, the default value of zero is used. This can lead to unexpected/unphysical behaviour (e.g., too thick surface layer).

Solution: when initialising the interface, a warning should be issued that lists the atoms, for which the default zero radius is going to be used.

MDAnalysis 2.0.0 issues

Hi there,

I'm finding that when I upgrade my MDAnalysis package to the latest version 2.0.0 pytim stops working for me. It imports fine but pytim.ITIM hangs when called on a Universe.

Creating a conda environment with the previous MDAnalysis version 1.1.1 seemingly solves the issue: conda create -n new_env -c conda-forge mdanalysis=1.1 pytim

I would like to be able to use the latest version of MDAnalysis as Universes can now be pickled paving the way to easier parallel analyses. Do you know if this would be true of a Universe that has first been analysed with pytim.ITIM?

Cheers,
Rowan

Incompatibility with numpy 1.16.0

Python 2.7.14 (default, Oct 12 2017, 15:33:51) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pytim
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build/bdist.macosx-10.10-x86_64/egg/pytim/__init__.py", line 8, in <module>
  File "build/bdist.macosx-10.10-x86_64/egg/pytim/willard_chandler.py", line 9, in <module>
  File "/Users/bfabian/.pyenv/versions/2.7.14/lib/python2.7/site-packages/skimage/__init__.py", line 167, in <module>
    from .util.dtype import (img_as_float32,
  File "/Users/bfabian/.pyenv/versions/2.7.14/lib/python2.7/site-packages/skimage/util/__init__.py", line 6, in <module>
    from .apply_parallel import apply_parallel
  File "/Users/bfabian/.pyenv/versions/2.7.14/lib/python2.7/site-packages/skimage/util/apply_parallel.py", line 8, in <module>
    import dask.array as da
  File "/Users/bfabian/.pyenv/versions/2.7.14/lib/python2.7/site-packages/dask/array/__init__.py", line 9, in <module>
    from .routines import (take, choose, argwhere, where, coarsen, insert,
  File "/Users/bfabian/.pyenv/versions/2.7.14/lib/python2.7/site-packages/dask/array/routines.py", line 256, in <module>
    @wraps(np.matmul)
  File "/Users/bfabian/.pyenv/versions/2.7.14/lib/python2.7/functools.py", line 33, in update_wrapper
    setattr(wrapper, attr, getattr(wrapped, attr))
AttributeError: 'numpy.ufunc' object has no attribute '__module__'
>>> import numpy
>>> numpy.__version__
'1.16.0'

Initial Update

Hi ๐Ÿ‘Š

This is my first visit to this fine repo, but it seems you have been working hard to keep all dependencies updated so far.

Once you have closed this issue, I'll create separate pull requests for every update as soon as I find one.

That's it for now!

Happy merging! ๐Ÿค–

Mismatch in number of surface atoms

Hi Marcello,

We were trying to find the surface atoms of a water slab of size 555 nm^3 inside a vacuum box of dimension 5560 nm^3. Using different configuration files for the same simulation time step (i.e using gro, xtc, trr) we are getting different number of interfacial (i.e water-vapour interface) atoms.

Using .gro and .xtc configuration file we are getting this output :
[array([[<AtomGroup with 1032 atoms>],
[<AtomGroup with 1068 atoms>]], dtype=object)]

while for .trr configuration file we are getting this output:
[array([[<AtomGroup with 1036 atoms>],
[<AtomGroup with 1068 atoms>]], dtype=object)]


Code Used:

import MDAnalysis as mda
import pytim
u = mda.Universe("t100000.tpr","11.trr")
inter = pytim.ITIM(u,max_layers=1, cluster_cut=3.5)
print (inter.layers)


similar for rest of the configuration files.

Files: https://github.com/ParthGoyal1508/Files

retrieving coordinates of Willard-Chandler interface

I want to use this package to determine the Willard-Chandler interface for a surface that is not flat. I was running the MICELLE_PDB example provided in the README. I could run it successfully and visualize the WC interface in the NGL viewer. However, I am unclear on how to retrieve the coordinates of the isodensity surface. I want to utilize the isodensity surface for further analysis.

import MDAnalysis as mda
import pytim
from pytim.datafiles import MICELLE_PDB
import nglview

u = mda.Universe(MICELLE_PDB)
g = u.select_atoms('resname DPC')

interface = pytim.WillardChandler(u, group=g, mesh=1.5, alpha=3.0)
interface.writecube('data.cube')
`interface.writepdb('surface.pdb')`

Unlike the ITIM example, I could not retrieve the surface coordinates from interface.atoms.positions, or interface.layers [0]. The former resulted in the error *** AttributeError: AtomGroup has no attribute sum., while the latter resulted in the error *** AttributeError: can't set attribute. I understand that the WC interface might have a different implementation, and these options may not work here. I hence wrote the interface to the pdb file using interface.writepdb('surface.pdb'), I could only see DPC and SOL residues and could not find the surface coordinates.

I don't understand the cube file format to be able to infer an isodensity surface at half the bulk density (typical WC definition) from data.cube file. Can anyone explain on how can I retrieve the coordinates of the isodensity surface that is being visualized with the following command:

# let's add a transparent, red representation for the isodensity surface at 50% density
view.component_1.add_surface(color='red',isolevelType="value",isolevel=0.5,opacity=0.6) 

Numpy raises TypeError when using python3

Having installed from pip and running the script

import MDAnalysis as mda
import pytim
from   pytim.datafiles import *

u = mda.Universe(WATER_GRO, format='gro')

interface = pytim.ITIM(u)

I get the error message

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/numpy/core/function_base.py", line 117, in linspace
    num = operator.index(num)
TypeError: 'numpy.float64' object cannot be interpreted as an integer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tutorial.txt", line 7, in <module>
    interface = pytim.ITIM(u)
  File "/home/iuvenis/.local/lib/python3.8/site-packages/pytim/itim.py", line 218, in __init__
    self._assign_layers()
  File "/home/iuvenis/.local/lib/python3.8/site-packages/pytim/itim.py", line 358, in _assign_layers
    self._prepare_layers_assignment()
  File "/home/iuvenis/.local/lib/python3.8/site-packages/pytim/itim.py", line 317, in _prepare_layers_assignment
    self._assign_mesh()
  File "/home/iuvenis/.local/lib/python3.8/site-packages/pytim/itim.py", line 235, in _assign_mesh
    _x = np.linspace(0, box[0], num=self.mesh_nx, endpoint=False)
  File "<__array_function__ internals>", line 5, in linspace
  File "/usr/lib/python3.8/site-packages/numpy/core/function_base.py", line 119, in linspace
    raise TypeError(
TypeError: object of type <class 'numpy.float64'> cannot be safely interpreted as an integer.

on python3.8.
The script works fine on 2.7.18 on the other hand.

mdtraj example failing

The mdtraj example is not working (pytim 0.8.1, mdtraj 1.9.2, mdanalysis 0.19.2).

CODE:

import mdtraj
import pytim
from pytim.datafiles import WATER_GRO, WATER_XTC
t = mdtraj.load_xtc(WATER_XTC,top=WATER_GRO)
inter = pytim.ITIM(t)

OUTPUT:

NameError Traceback (most recent call last)
/home/bnovak1/Sync_NAS/CIMM/melting_point/TiNi_Ko_Grabowski_Neugebauer_2015/NiTi/modified_delr_0.4/semigrand/1152_atoms/output/1809.0K/test2.py in ()
4
5 t = mdtraj.load_xtc(WATER_XTC,top=WATER_GRO)
----> 6 inter = pytim.ITIM(t)
7 for step in t[:]:
8 print('surface atoms: ', repr(inter.atoms.indices))

/home/bnovak1/miniconda3/envs/CIMM2/lib/python2.7/site-packages/pytim/itim.pyc in init(self, universe, group, alpha, normal, molecular, max_layers, radii_dict, clu$
ter_cut, cluster_threshold_density, extra_cluster_groups, info, centered, warnings, mesh, autoassign, **kargs)
193 sanity = SanityCheck(self)
194 sanity.assign_universe(
--> 195 universe, radii_dict=radii_dict, warnings=warnings)
196 sanity.assign_alpha(alpha)
197 sanity.assign_mesh(mesh)

/home/bnovak1/miniconda3/envs/CIMM2/lib/python2.7/site-packages/pytim/sanity_check.pyc in assign_universe(self, input_obj, radii_dict, warnings)
154 def assign_universe(self, input_obj, radii_dict=None, warnings=False):
155
--> 156 self.interface._mode = self._apply_patches(input_obj)
157 if self.interface._mode is None:
158 raise Exception(messages.WRONG_UNIVERSE)

/home/bnovak1/miniconda3/envs/CIMM2/lib/python2.7/site-packages/pytim/sanity_check.pyc in _apply_patches(self, input_obj)
123 input_obj[0].save_pdb(_file.name)
124 self.interface.universe = MDAnalysis.Universe(_file.name)
--> 125 PatchMDTRAJ(input_obj, self.interface.universe)
126 os.remove(_file.name)
127 return 'mdtraj'

NameError: global name 'PatchMDTRAJ' is not defined

Can volume be compute?

Hi Marcello,

Is there possible to compute the volume enveloped in GITIM, or volume of space formed by ITIM and periodic bounds of simulation box?

Conda Pytim for OSX

Hi @Marcello-Sega ๐Ÿ‘‹๐Ÿผ

I just came across this work, looks great! It looks like the conda installation for Mac OS might be restricted to py2.7 from what I can see in list of versions. If this is the case, could you confirm if you plan to update this?

Cheers!

Update for Mac OSX users installing via pip:

You might need to add CFLAGS='-stdlib=libc++' prior to pip install --user --upgrade pytim

Undocumented feature in GITIM

The parameter buffer_factor is undocumented in GITIM, but it has a significant effect on the interfacial determination. What is the purpose of this variable? How does one choose the optimum value?

This issue was introduced in 80d3c32 : gitim cleanup & fixes (#274)

Issue with zero-radius atoms

In case one or more atoms are buried within the excluded volume of another one the GITIM algorithm does not behave as one would expect. The typical case is hydrogen atoms in water models like SPCx, TIPxP. This happens because:

  1. the resulting triangulation includes simplexes with acute angles
  2. the kissing spheres algorithm might provide spurios soulutions.

Usually can be dealt with by excluding hydrogen atoms from the analysis group. As this can be not immediately obvious to new users, one possibility is to introduce the default behaviour of not including hydrogens or atoms with zero radius. As the atom types are not always reliable, probably the best option is to exclude atoms with zero radius.

pytim not closing files

When I run pytim.ITIM sufficient times in a python script, I get a "too many open files" error. I think that some files are not being closed when ITIM runs. They are only closed when the script calling ITIM terminates.

Bug when re-instantiating an interface

When an interface is being re-instantiated, the trajectory is not correctly indexed.
This can be easily triggered with this minimal example:

import pytim 
import MDAnalysis as mda
u = mda.Universe(pytim.datafiles.WATER_GRO,pytim.datafiles.WATER_XTC)

inter = pytim.ITIM(u)
print(inter.universe.trajectory.frame,inter.atoms.n_atoms)
u.trajectory[1]
print(inter.universe.trajectory.frame,inter.atoms.n_atoms) 
#
inter = pytim.ITIM(u) 
u.trajectory[0]
print(inter.universe.trajectory.frame,inter.atoms.n_atoms)

0 1572
1 1506
0 1506

handling args in Position()

If a universe is passed, as in other observables, crashes instead of bypassing it.

Same for Velocity() & Force()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.