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

Added exclusions andnd angles to segmentmodel

parent d3361ce8
No related branches found
No related tags found
No related merge requests found
......@@ -67,7 +67,7 @@ class HarmonicPotential():
self.prefix = prefix
self.periodic = False
self.type_ = "None"
self.kscale_ = None
self.kscale_ = None # only used for
def filename(self):
# raise NotImplementedError("Not implemented")
......@@ -90,8 +90,9 @@ class HarmonicPotential():
u = 0.5*self.k*dr**2
if self.maxForce is not None:
assert(self.maxForce > 0)
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
......@@ -121,15 +122,15 @@ class HarmonicBond(HarmonicPotential):
self.kscale_ = 1.0
class HarmonicAngle(HarmonicPotential):
def __init__(self, k, r0, rRange=(0,50), resolution=0.1, maxForce=None, prefix="potentials/"):
def __init__(self, k, r0, rRange=(0,181), resolution=0.1, maxForce=None, prefix="potentials/"):
HarmonicPotential.__init__(self, k, r0, rRange, resolution, maxForce, prefix)
self.type_ = "angle"
self.kscale_ = (180.0/pi)**2
self.kscale_ = (180.0/np.pi)**2
class HarmonicDihedral(HarmonicPotential):
def __init__(self, k, r0, rRange=(0,50), resolution=0.1, maxForce=None, prefix="potentials/"):
def __init__(self, k, r0, rRange=(-180,180), resolution=0.1, maxForce=None, prefix="potentials/"):
HarmonicPotential.__init__(self, k, r0, rRange, resolution, maxForce, prefix)
self.periodic = True
self.type_ = "dihedral"
self.kscale_ = (180.0/pi)**2
self.kscale_ = (180.0/np.pi)**2
......@@ -94,7 +94,7 @@ class Segment(ConnectableElement, Group):
ret.append( tmp )
return ret
def get_beads_before_bead(self, bead, number, inclusive=True):
def get_beads_before_bead(self, bead, number, inclusive=False):
## Assume that consecutive beads in self.children are bonded
i = self.children.index(bead)
l = len(self.children)
......@@ -105,7 +105,7 @@ class Segment(ConnectableElement, Group):
if inclusive: start = 0
return [self.children[i-j] for j in range(start,number)]
def get_beads_after_bead(self, bead, number, inclusive=True):
def get_beads_after_bead(self, bead, number, inclusive=False):
## Assume that consecutive beads in self.children are bonded
i = self.children.index(bead)
l = len(self.children)
......@@ -116,6 +116,10 @@ class Segment(ConnectableElement, Group):
if inclusive: start = 0
return [self.children[i+i] for j in range(start,number)]
# def get_bead_pairs_within(self, cutoff):
# for b1,b2 in self.get_all_consecutive_beads(self, number)
def _generate_beads(self, bead_model, max_nts_per_bead=4):
""" Generate beads (positions, types, etcl) and bonds, angles, dihedrals, exclusions """
......@@ -334,39 +338,68 @@ class SegmentModel(ArbdModel):
if c.type_ == "intrahelical":
b1,b2 = [loc.particle for loc in (c.A,c.B)]
for b in (b1,b2): assert( b is not None )
## TODO: make this code more robust
## TODO: find bug that makes things be out of order
try:
b0 = s1.get_beads_before_bead(b1,1)[0]
b0 = s1.get_beads_before_bead(b1,1)
assert(len(b0) == 1)
b0 = b0[0]
assert( b0 is not None )
ret.append( [b0,b1,b2] )
except:
...
try:
b0 = s1.get_beads_after_bead(b1,1)[0]
b0 = s1.get_beads_after_bead(b1,1)
assert(len(b0) == 1)
b0 = b0[0]
assert( b0 is not None )
ret.append( [b2,b1,b0] )
except:
...
try:
b3 = s2.get_beads_before_bead(b2,1)[0]
b3 = s2.get_beads_before_bead(b2,1)
assert(len(b3) == 1)
b3 = b3[0]
assert( b3 is not None )
ret.append( [b3,b2,b1] )
except:
...
try:
b3 = s2.get_beads_after_bead(b2,1)[0]
b3 = s2.get_beads_after_bead(b2,1)
assert(len(b3) == 1)
b3 = b3[0]
assert( b3 is not None )
ret.append( [b1,b2,b3] )
except:
...
return ret
# def _get_intrahelical_bead_pairs_within(self, cutoff):
# dist = dict()
# for b1,b2 in self._get_intrahelical_beads:
# dist(b1,b2)
# ret = []
# for s in self.segments:
# ret.extend( s.get_bead_pairs_within(cutoff) )
# for s1 in self.segments:
# for c in s1.connections:
# if c.A.container != s1: continue
# s2 = c.B.container
# if c.type_ == "intrahelical":
# ret
def _get_potential(self, type_, kSpring, d):
key = (type_,kSpring,d)
if key not in self._bonded_potential:
if type_ == "bond":
self._bonded_potential[key] = HarmonicBond(kSpring,d)
elif type_ == "angle":
self._bonded_potential[key] = HarmonicAngle(kSpring,d)
self._bonded_potential[key] = HarmonicAngle(kSpring,d) # , resolution = 1, maxForce=0.1)
elif type_ == "dihedral":
self._bonded_potential[key] = HarmonicDihedral(kSpring,d)
else:
......@@ -415,8 +448,8 @@ class SegmentModel(ArbdModel):
beadtype_s[key] = b.type_ = t
""" Add intrahelical potentials """
## First replace intrahelical bonds
""" Add intrahelical bond potentials """
dists = dict() # built for later use
for b1,b2 in self._get_intrahelical_beads():
if b1.parent == b2.parent:
sep = 0.5*(b1.num_nts+b2.num_nts)
......@@ -424,19 +457,83 @@ class SegmentModel(ArbdModel):
else:
sep = 1
parent = self
conversion = 0.014393265 # units "pN/AA" kcal_mol/AA^2
if b1.type_.name[0] == "D" and b1.type_.name[0] == "D":
k = 10.0/np.sqrt(sep) # TODO: determine from simulations
elastic_modulus = 1000 # pN http://markolab.bmbcb.northwestern.edu/marko/Cocco.CRP.02.pdf
d = 3.4*sep
k = conversion*elastic_modulus/d
else:
## TODO: get correct numbers from ssDNA model
k = 1.0/np.sqrt(sep)
## TODO: get better numbers our ssDNA model
elastic_modulus = 800 # pN http://markolab.bmbcb.northwestern.edu/marko/Cocco.CRP.02.pdf
d = 5*sep
k = conversion*elastic_modulus/d
if b1 not in dists:
dists[b1] = []
if b2 not in dists:
dists[b2] = []
dists[b1].append([b2,sep])
dists[b2].append([b1,sep])
# dists[[b1,b2]] = dists[[b2,b1]] = sep
bond = self.get_bond_potential(k,d)
parent.add_bond( b1, b2, bond, exclude=True )
""" Add intrahelical angle potentials """
for b1,b2,b3 in self._get_intrahelical_angle_beads():
sep = 0
if b1.parent == b2.parent:
sep += 0.5*(b1.num_nts+b2.num_nts)
else:
sep += 1
if b2.parent == b3.parent:
sep += 0.5*(b2.num_nts+b3.num_nts)
else:
sep += 1
if b1.parent == b2.parent and b2.parent == b3.parent:
parent = b1.parent
else:
parent = self
kT = 0.58622522 # kcal/mol
if b1.type_.name[0] == "D" and b2.type_.name[0] == "D" and b3.type_.name[0] == "D":
## <cos(q)> = exp(-s/Lp) = integrate( x^4 exp(-A x^2) / 2, {x, 0, pi} ) / integrate( x^2 exp(-A x^2), {x, 0, pi} )
## <cos(q)> ~ 1 - 3/4A
## where A = k_spring / (2 kT)
k = 1.5 * kT * (1.0 / (1-np.exp(-float(sep)/147))) * 0.00030461742; # kcal_mol/degree^2
else:
## TODO: get correct number from ssDNA model
k = 1.5 * kT * (1.0 / (1-np.exp(-float(sep)/3))) * 0.00030461742; # kcal_mol/degree^2
# k *= 1e-6
angle = self.get_angle_potential(k,180)
parent.add_angle( b1, b2, b3, angle )
""" Add intrahelical exclusions """
beads = dists.keys()
def _recursively_get_beads_within(b1,d,done=[]):
ret = []
for b2,sep in dists[b1]:
if b2 in done: continue
if sep < d:
ret.append( b2 )
done.append( b2 )
tmp = _recursively_get_beads_within(b2, d-sep, done)
if len(tmp) > 0: ret.extend(tmp)
return ret
exclusions = set()
for b1 in beads:
exclusions.update( [(b1,b) for b in _recursively_get_beads_within(b1, 20, done=[b1])] )
for b1,b2 in exclusions:
if b1.parent == b2.parent:
parent = b1.parent
else:
parent = self
parent.add_exclusion( b1, b2 )
""" Add connection potentials """
## TODO
......@@ -449,39 +546,3 @@ class SegmentModel(ArbdModel):
# r
# ...
if __name__ == "__main__":
seg1 = DoubleStrandedSegment("strand", num_nts = 46)
seg2 = SingleStrandedSegment("strand",
start_position = seg1.end_position + np.array((1,0,1)),
num_nts = 12)
seg3 = SingleStrandedSegment("strand",
start_position = seg1.start_position + np.array((-1,0,-1)),
end_position = seg1.end_position + np.array((-1,0,1)),
num_nts = 128)
seg1.start3
seg1.start5
seg1.end3
seg1.end5
seg1.connect_end3(seg2)
seg1.connect_end5(seg3)
seg1.connect_start3(seg3)
model = SegmentModel( [seg1, seg2, seg3],
dimensions=(5000,5000,5000),
)
model.useNonbondedScheme( nbDnaScheme )
model.simulate( outputPrefix = 'strand-test', outputPeriod=1e4, numSteps=1e6, gpu=1 )
# seg = SingleStrandedSegment("strand", num_nts = 21)
# generate_bead_model( [seg] )
# for b in seg:
# print(b.num_nts, b.position)
......@@ -17,12 +17,12 @@ if __name__ == "__main__":
seg1 = DoubleStrandedSegment("strand", num_nts = 46)
seg2 = SingleStrandedSegment("strand",
start_position = seg1.end_position + np.array((1,0,1)),
start_position = seg1.end_position + np.array((5,0,5)),
num_nts = 12)
seg3 = SingleStrandedSegment("strand",
start_position = seg1.start_position + np.array((-1,0,-1)),
end_position = seg1.end_position + np.array((-1,0,1)),
start_position = seg1.start_position + np.array((-5,0,-5)),
end_position = seg1.end_position + np.array((-5,0,5)),
num_nts = 128)
seg1.start3
......@@ -37,5 +37,6 @@ if __name__ == "__main__":
model = SegmentModel( [seg1, seg2, seg3],
dimensions=(5000,5000,5000),
)
model.useNonbondedScheme( nbDnaScheme )
model.simulate( outputPrefix = 'strand-test', outputPeriod=1e4, numSteps=1e6, gpu=1 )
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