Skip to content
Snippets Groups Projects
Commit 5ed0da54 authored by cmaffeo2's avatar cmaffeo2
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Pipeline #113755 failed
__pycache__
.backup
/build
*.egg-info
/mrdna/RELEASE-VERSION
LICENSE 0 → 100644
University of Illinois Open Source License
Copyright 2010-2016 Aksimentiev Group,
All rights reserved.
Developed by: Aksimentiev Group
University of Illinois at Urbana-Champaign
http://bionano.phsyics.illinois.edu
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the Software), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to
do so, subject to the following conditions:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the documentation
and/or other materials provided with the distribution.
- Neither the names of the Aksimentiev Group, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to endorse or
promote products derived from this Software without specific prior written
permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS WITH THE SOFTWARE.
include arbdmodel/RELEASE-VERSION
include arbdmodel/README.md
include arbdmodel/LICENSE
README.md 0 → 100644
# ARBD modeling
Provides a Python interface to the ARBD simulation engine.
The interface currently supports the construction of simulation
systems out of point-like particles interacting through bonded and
non-bonded potentials. Rigid body particles are not yet supported.
The interface presently communicates with ARBD through files.
## Example: Consstructing a coarse-grained ssDNA model
```python
import numpy as np
import sys
from arbdmodel import ArbdModel, ParticleType, PointParticle, Group
from arbdmodel.nonbonded import TabulatedPotential, HarmonicBond, HarmonicAngle, HarmonicDihedral
"""Define particle types"""
P = ParticleType("P",
diffusivity = 43.5,
mass = 150,
radius = 3,
nts = 0.5 # made compatible with nbPot
)
B = ParticleType("B",
diffusivity = 43.5,
mass = 150,
radius = 3,
nts = 0.5 # made compatible with nbPot
)
"""Function that creates a strand of DNA of a given length"""
def createDnaStrand(numNts):
p = PointParticle(P, (0,0,0), "P")
b = PointParticle(B, (3,0,1), "B")
nt = Group( name = "nt", children = [p,b])
nt.add_bond( i=p, j=b, bond = 'tabPot/BPB.dat' )
nts = [nt.duplicate() for i in range( numNts )]
strand = Group(name="strand", children=nts)
for i in range(len(nts)):
# nts[i].position[2] = i*4.5
nts[i].children[0].position[2] = i*4.5
nts[i].children[1].position[2] = i*4.5+1
## Two consecutive nts
for i in range(len(nts)-1):
p1,b1 = nts[i].children
p2,b2 = nts[i+1].children
strand.add_bond( i=b1, j=p2, bond = 'tabPot/BBP.dat', exclude=True )
strand.add_bond( i=p1, j=p2, bond = 'tabPot/BPP.dat', exclude=True )
strand.add_angle( i=p1, j=p2, k=b2, angle = 'tabPot/p1p2b2.dat')
strand.add_angle( i=b1, j=p2, k=b2, angle = 'tabPot/b1p2b2.dat')
strand.add_dihedral( i=b1, j=p1, k=p2, l=b2, dihedral = 'tabPot/b1p1p2b2.dat')
strand.add_exclusion( i=b1, j=b2 )
strand.add_exclusion( i=p1, j=b2 )
## Three consecutive nts
for i in range(len(nts)-2):
p1,b1 = nts[i].children
p2,b2 = nts[i+1].children
p3,b3 = nts[i+2].children
strand.add_angle( i=p1, j=p2, k=p3, angle = 'tabPot/p1p2p3.dat')
strand.add_angle( i=b1, j=p2, k=p3, angle = 'tabPot/b1p2p3.dat')
strand.add_dihedral( i=b1, j=p2, k=p3, l=b3, dihedral = 'tabPot/b1p2p3b3.dat')
strand.add_exclusion( i=p1, j=p3 )
strand.add_exclusion( i=b1, j=p3 )
## Four consecutive nts
for i in range(len(nts)-4):
p1,b1 = nts[i].children
p2,b2 = nts[i+1].children
p3,b3 = nts[i+2].children
p4,b4 = nts[i+3].children
strand.add_dihedral( i=p1, j=p2, k=p3, l=p4, dihedral = 'tabPot/p0p1p2p3.dat')
return strand
if __name__ == "__main__":
strands = []
for i in range(5,60,5):
strand = createDnaStrand(i)
strands.extend( [strand.duplicate() for j in range(int(round(600/i**1.2)))] )
## Randomly place strands through system
model = ArbdModel( strands, dimensions=(200, 200, 200) )
old_schemes = model.nbSchemes
model.nbSchemes = []
model.useNonbondedScheme( TabulatedPotential('tabPot/NBBB.dat'), typeA=B, typeB=B )
model.useNonbondedScheme( TabulatedPotential('tabPot/NBPB.dat'), typeA=P, typeB=B )
model.useNonbondedScheme( TabulatedPotential('tabPot/NBPP.dat'), typeA=P, typeB=P )
model.nbSchemes.extend(old_schemes)
for s in strands:
s.position = np.array( [(a-0.5)*b for a,b in
zip( np.random.uniform(size=3), model.dimensions )] )
model.simulate( output_name = 'many-strands', output_period=1e4, num_steps=1e6 )
```
../LICENSE
\ No newline at end of file
../README.md
\ No newline at end of file
This diff is collapsed.
from shutil import copyfile
import os, sys
import numpy as np
class NonbondedScheme():
""" Abstract class for writing nonbonded interactions """
def __init__(self, typesA=None, typesB=None, resolution=0.1, rMin=0):
"""If typesA is None, and typesB is None, then """
self.resolution = resolution
self.rMin = rMin
def add_sim_system(self, simSystem):
self.rMax = simSystem.cutoff
self.r = np.arange(rMin,rMax,resolution)
def potential(self, r, typeA, typeB):
raise NotImplementedError
def write_file(self, filename, typeA, typeB, rMax):
r = np.arange(self.rMin, rMax+self.resolution, self.resolution)
u = self.potential(r, typeA, typeB)
np.savetxt(filename, np.array([r,u]).T)
class LennardJones(NonbondedScheme):
def potential(self, r, typeA, typeB):
epsilon = sqrt( typeA.epsilon**2 + typeB.epsilon**2 )
r0 = 0.5 * (typeA.radius + typeB.radius)
r6 = (r0/r)**6
r12 = r6**2
u = epsilon * (r12-2*r6)
u[0] = u[1] # Remove NaN
return u
LennardJones = LennardJones()
class HalfHarmonic(NonbondedScheme):
def potential(self, r, typeA, typeB):
k = 10 # kcal/mol AA**2
r0 = (typeA.radius + typeB.radius)
u = 0.5 * k * (r-r0)**2
u[r > r0] = np.zeros( np.shape(u[r > r0]) )
return u
HalfHarmonic = HalfHarmonic()
class TabulatedPotential(NonbondedScheme):
def __init__(self, tableFile, typesA=None, typesB=None, resolution=0.1, rMin=0):
"""If typesA is None, and typesB is None, then """
self.tableFile = tableFile
# self.resolution = resolution
# self.rMin = rMin
## TODO: check that tableFile exists and is regular file
def write_file(self, filename, typeA, typeB, rMax):
if filename != self.tableFile:
copyfile(self.tableFile, filename)
## Bonded potentials
class HarmonicPotential():
def __init__(self, k, r0, rRange=(0,50), resolution=0.1, maxForce=None, max_potential=None, prefix="potentials/"):
self.k = k
self.r0 = r0
self.rRange = rRange
self.resolution = 0.1
self.maxForce = maxForce
self.prefix = prefix
self.periodic = False
self.type_ = "None"
self.max_potential = max_potential
self.kscale_ = None # only used for
def filename(self):
# raise NotImplementedError("Not implemented")
return "%s%s-%.3f-%.3f.dat" % (self.prefix, self.type_,
self.k*self.kscale_, self.r0)
def __str__(self):
return self.filename()
def write_file(self):
r = np.arange( self.rRange[0],
self.rRange[1]+self.resolution,
self.resolution )
dr = r-self.r0
if self.periodic == True:
rSpan = self.rRange[1]-self.rRange[0]
assert(rSpan > 0)
dr = np.mod( dr+0.5*rSpan, rSpan) - 0.5*rSpan
u = 0.5*self.k*dr**2
maxForce = self.maxForce
if maxForce is not None:
assert(maxForce > 0)
f = np.diff(u)/np.diff(r)
f[f>maxForce] = maxForce
f[f<-maxForce] = -maxForce
u[0] = 0
u[1:] = np.cumsum(f*np.diff(r))
if self.max_potential is not None:
f = np.diff(u)/np.diff(r)
ids = np.where( 0.5*(u[1:]+u[:-1]) > self.max_potential )[0]
w = np.sqrt(2*self.max_potential/self.k)
drAvg = 0.5*(np.abs(dr[ids]) + np.abs(dr[ids+1]))
f[ids] = f[ids] * np.exp(-(drAvg-w)/(w))
u[0] = 0
u[1:] = np.cumsum(f*np.diff(r))
u = u - np.min(u)
np.savetxt( self.filename(), np.array([r, u]).T, fmt="%f" )
def __hash__(self):
assert(self.type_ != "None")
return hash((self.type_, self.k, self.r0, self.rRange, self.resolution, self.maxForce, self.max_potential, self.prefix, self.periodic))
def __eq__(self, other):
for a in ("type_", "k", "r0", "rRange", "resolution", "maxForce", "max_potential", "prefix", "periodic"):
if self.__dict__[a] != other.__dict__[a]:
return False
return True
# class NonBonded(HarmonicPotential):
# def _init_hook(self):
# self.type = "nonbonded"
# self.kscale_ = 1.0
class HarmonicBond(HarmonicPotential):
def __init__(self, k, r0, rRange=(0,50), resolution=0.1, maxForce=None, max_potential=None, prefix="potentials/"):
HarmonicPotential.__init__(self, k, r0, rRange, resolution, maxForce, max_potential, prefix)
self.type_ = "bond"
self.kscale_ = 1.0
class HarmonicAngle(HarmonicPotential):
def __init__(self, k, r0, rRange=(0,181), resolution=0.1, maxForce=None, max_potential=None, prefix="potentials/"):
HarmonicPotential.__init__(self, k, r0, rRange, resolution, maxForce, max_potential, prefix)
self.type_ = "angle"
self.kscale_ = (180.0/np.pi)**2
class HarmonicDihedral(HarmonicPotential):
def __init__(self, k, r0, rRange=(-180,180), resolution=0.1, maxForce=None, max_potential=None, prefix="potentials/"):
HarmonicPotential.__init__(self, k, r0, rRange, resolution, maxForce, max_potential, prefix)
self.periodic = True
self.type_ = "dihedral"
self.kscale_ = (180.0/np.pi)**2
This diff is collapsed.
# -*- coding: utf-8 -*-
# Author: Douglas Creager <dcreager@dcreager.net>
# This file is placed into the public domain.
# Calculates the current version number. If possible, this is the
# output of “git describe”, modified to conform to the versioning
# scheme that setuptools uses. If “git describe” returns an error
# (most likely because we're in an unpacked copy of a release tarball,
# rather than in a git working copy), then we fall back on reading the
# contents of the RELEASE-VERSION file.
#
# To use this script, simply import it your setup.py file, and use the
# results of get_git_version() as your package version:
#
# from version import *
#
# setup(
# version=get_git_version(),
# .
# .
# .
# )
#
#
# This will automatically update the RELEASE-VERSION file, if
# necessary. Note that the RELEASE-VERSION file should *not* be
# checked into git; please add it to your top-level .gitignore file.
#
# You'll probably want to distribute the RELEASE-VERSION file in your
# sdist tarballs; to do this, just create a MANIFEST.in file that
# contains the following line:
#
# include RELEASE-VERSION
__all__ = ("get_version")
from pathlib import Path
import subprocess
from subprocess import Popen, PIPE
_version_file = Path(__file__).parent / "RELEASE-VERSION"
def check_git_repository():
try:
remotes = subprocess.check_output(['git', 'remote', '-v'], stderr=subprocess.STDOUT)
return b'arbdmodel.git' in remotes
except:
return False
def call_git_describe(abbrev):
try:
p = Popen(['git', 'describe', '--tags', '--abbrev=%d' % abbrev],
stdout=PIPE, stderr=PIPE)
p.stderr.close()
line = p.stdout.readlines()[0]
return line.strip().decode('utf-8')
except:
return None
def is_dirty():
try:
p = Popen(["git", "diff-index", "--name-only", "HEAD"],
stdout=PIPE, stderr=PIPE)
p.stderr.close()
lines = p.stdout.readlines()
return len(lines) > 0
except:
return False
def read_release_version():
try:
f = open(_version_file, "r")
try:
version = f.readlines()[0]
return version.strip()
finally:
f.close()
except:
return None
def write_release_version(version):
f = open(_version_file, "w")
f.write("%s\n" % version)
f.close()
def get_version(abbrev=7):
# Read in the version that's currently in RELEASE-VERSION.
release_version = read_release_version()
if not check_git_repository():
return release_version
# raise Exception(__function__ +" called from outside a version controlled source repository")
# First try to get the current version using “git describe”.
split_version = call_git_describe(abbrev).split("-")
version = split_version[0]
if len(split_version) > 1 and int(split_version[-2]) > 0:
version += ".dev{}".format(int(split_version[-2]))
# If that doesn't work, fall back on the value that's in
# RELEASE-VERSION.
if version is None:
version = release_version
# If we still don't have anything, that's an error.
if version is None:
raise ValueError("Cannot find the version number!")
# If the current version is different from what's in the
# RELEASE-VERSION file, update the file to be current.
if version != release_version:
write_release_version(version)
# Finally, return the current version.
return version
if __name__ == "__main__":
print( get_version() )
def read_version_file(filename):
with open(filename) as fh:
version = fh.readlines()[0].strip()
return version
try:
version = read_version_file(_version_file)
except:
try:
version = read_version_file(_version_file)
except:
version = "Unknown"
setup.py 0 → 100644
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
with open("LICENSE", "r") as fh:
license = fh.read()
from arbdmodel.version import get_version
setuptools.setup(
name="arbdmodel",
version=get_version(),
author="Christopher Maffeo",
author_email="cmaffeo2@illinois.edu",
description="Python interface to ARBD simulation engine",
license=license,
long_description=long_description,
long_description_content_type="text/markdown",
url="https://gitlab.engr.illinois.edu/tbgl/tools/arbdmodel",
packages=setuptools.find_packages(),
include_package_data=True,
install_requires=(
'numpy>=1.14',
'appdirs>=1.4'
),
classifiers=(
"Programming Language :: Python :: 3",
"License :: UIUC Open source License",
"Operating System :: OS Independent",
),
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment