Skip to content

Commit

Permalink
new features
Browse files Browse the repository at this point in the history
- concentrations can now be relative
- database file can be located anywhere in file system. Added search
path priority (first in database file folder, then in cwd, then in
assemble home)
- improved randomization of in polymers in system (repeat 100 times,
select distribution best matching what user wants)
  • Loading branch information
degiacom committed Aug 12, 2016
1 parent 8194177 commit a0ca023
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 67 deletions.
10 changes: 7 additions & 3 deletions Assemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import sys, os

import logging
from astropy.io.ascii.tests.common import CWD


def make_chain(length, percentage):
Expand Down Expand Up @@ -184,7 +185,10 @@ def run(infile):
logger.removeHandler(ch)

if __name__=="__main__":
#get database filename
#infile="infile"

cwd=os.getcwd()
assembled=os.path.abspath(os.path.dirname(str(sys.argv[0])))
os.environ["ASSEMBLEPATH"]="%s;%s"%(cwd,assembled)

infile=str(sys.argv[1])
run(infile)
run(infile)
17 changes: 11 additions & 6 deletions Assemble_GUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@


import os
import sys
import wx
from Database import Database
from ForceField import ForceField
Expand All @@ -32,7 +33,11 @@ def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(700,600))
self.CreateStatusBar() # A Status bar in the bottom of the window
self.SetBackgroundColour("white")


cwd=os.getcwd()
assembled=os.path.abspath(os.path.dirname(str(sys.argv[0])))
os.environ["ASSEMBLEPATH"]="%s;%s"%(cwd,assembled)

#initialize datastructures
self.db=Database()
self.ff=ForceField()
Expand Down Expand Up @@ -229,10 +234,10 @@ def OnMake(self,event):
self.errorPopup("concentration of polymer %s must be\na number between 0 and 100!"%self.P.lc.GetItem(itemId=i,col=0).GetText(), "ERROR!")
return

if conc!=100:
#if conc!=100:
#self.errorPopup("sum of polymer concentrations is equal to %s (expected 100)\nTreating concentrations as ratios!"%conc, "WARNING!")
self.errorPopup("sum of polymer concentrations\n should be equal to 100 percent!", "ERROR!")
return
##self.errorPopup("sum of polymer concentrations\n should be equal to 100 percent!", "ERROR!")
##return

#check box size information consistency
try:
Expand Down Expand Up @@ -666,7 +671,7 @@ def __init__(self, parent):
self.lc.InsertColumn(1, 'chain')
self.lc.InsertColumn(2, 'length')
self.lc.InsertColumn(3, 'components (%)')
self.lc.InsertColumn(4, 'concent. (%)')
self.lc.InsertColumn(4, 'concentr.')
self.lc.SetColumnWidth(0, 65)
self.lc.SetColumnWidth(1, 230)
self.lc.SetColumnWidth(2, 60)
Expand Down Expand Up @@ -876,7 +881,7 @@ def __init__(self, parent,params=-1):
self.lblchain = wx.StaticText(self, label="chain:")
self.editchain = wx.TextCtrl(self, value="")

self.lblconc = wx.StaticText(self, label="concentr.(%):")
self.lblconc = wx.StaticText(self, label="concentr.:")
self.editconc = wx.TextCtrl(self, value="", size=(40,-1))


Expand Down
61 changes: 50 additions & 11 deletions Database.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,50 @@ def __init__(self):
self.molecules={}
self.logger=logging.getLogger('assemble')

def load(self,infile,mode):


def findfile(self, infile):

#search path for relative paths:
#1. working directory of database file
#2. current working directory
#3. assemble home directory
mypath=os.environ["ASSEMBLEPATH"].split(";")

#print mypath

#find pdbfile
fname=""
if os.path.isabs(infile): #absolute path, just check existence
if os.path.isfile(infile):
fname=infile
else: #relative path, look for first hit in different folders
for p in mypath:
test="%s\\%s"%(p,infile)
if os.path.isfile(test):
fname=test
break

return fname


def load(self, infile, mode):

files=[]

self.logger.info("\n> Preparing molecules database...")
f = open(infile, 'r+')
try:
f = open(infile, 'r+')
except:
raise IOError("database file %s not found!"%infile)

#append folder of database file at the beginning of search path
thisdir=os.path.dirname(os.path.abspath(infile))
os.environ["ASSEMBLEPATH"]="%s;%s"%(thisdir, os.environ["ASSEMBLEPATH"])

for line in f:

w=line.split()

if len(w)==0: #to new line if line is empty
continue

Expand All @@ -40,23 +73,29 @@ def load(self,infile,mode):

if len(w[0])>1:
raise IOError("found %s identifier in database file %s.\nOne letter code expected!"%(w[0],infile))

if not os.path.isfile(w[1]):

fname=self.findfile(w[1])
if fname=="":
raise IOError("PDB file %s not found for molecule %s"%(w[1],w[0]))

try:
self.logger.info(">> loading PDB %s"%w[1])
self.logger.info(">> loading PDB %s"%fname)
m=Molecule()
m.import_pdb(w[1], mode)
m.import_pdb(fname, mode)

except IOError:
raise IOError("loading of PDB file %s failed for molecule %s"%(w[1],w[0]))
raise IOError("loading of PDB file %s failed for molecule %s"%(fname,w[0]))

try:
if mode=="gromacs":
if len(w)==3:
self.logger.info(">> loading topology %s"%w[2])
m.import_topology(w[2])

fname=self.findfile(w[2])
if fname=="":
raise IOError("topology file %s not found for molecule %s"%(w[2],w[0]))

self.logger.info(">> loading topology %s"%fname)
m.import_topology(fname)
else:
raise IOError("in gromacs mode, a topology file is expected for molecule %s!"%w[0])

Expand Down
6 changes: 3 additions & 3 deletions Parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ def check_variables(self):
cnt+=val
p2.append([m,val])

if cnt!=100:
print "ERROR: sum of provided percentages equal to %s. Should be 100!"%cnt
return -1
#if cnt!=100:
# print "ERROR: sum of provided percentages equal to %s. Should be 100!"%cnt
# return -1

self.concentration=p2

Expand Down
79 changes: 44 additions & 35 deletions System.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,57 +25,66 @@ def __init__(self,polymers,ff,params):

#generate a random distribution of molecules in a box, given their percentages
def make_box(self, dim, percentage):


'''
print percentage
#normalize to 100

#normalize to 100 percent
test=0
for i in percentage.keys():
test+=float(percentage[i][0])
for l in percentage:
test+=float(l[1])

print test
for i in percentage.keys():
v=percentage[i][0]
percentage[i][0]=str((float(v)/test)*100.0)
print percentage
'''
for i in xrange(len(percentage)):
v=float(percentage[i][1])
percentage[i][1]=(v/test)*100.0

if len(dim)!=3:
raise IOError("ERROR: expected 3 values for dimensions")

length=dim[0]*dim[1]*dim[2]

c=[]
#make roulette array
roulette=[percentage[0][1]]
t=[percentage[0][1]]
for r in xrange(1,len(percentage),1):
t.append(percentage[r][1])
roulette.append(roulette[r-1]+percentage[r][1])

#pick a random monomer according to desired percentages
counter=np.zeros(len(roulette))
for x in xrange(0,length,1):
rnd=np.random.rand(1)[0]*100
index=0
while True:
if roulette[index]>rnd:
break
else:
index+=1
c.append(percentage[index][0])
counter[index]+=1
target=np.array(t)
error=100000.0
cbest=np.array([])
#attempt distributing molecules in box according to desired concentration
#keep best of 100 attemps
for i in xrange(1,100):

c=[]

#pick a random monomer according to desired percentages
counter=np.zeros(len(roulette))
for x in xrange(0,length,1):
rnd=np.random.rand(1)[0]*100
index=0
while True:
if roulette[index]>rnd:
break
else:
index+=1
c.append(percentage[index][0])
counter[index]+=1

#chain completed, report produced percentages:
counter/=float(length)
counter*=100.0
#chain completed, report produced percentages:
counter/=float(length)
counter*=100.0

tmp_err=np.sum((counter-target)**2)

if tmp_err<error:
error=tmp_err
cbest=np.array(c)
counterbest=counter.copy()

self.logger.info("> polymer concentrations in box:")
for x in xrange(0,len(counter),1):
self.logger.info(">> %s: %s percent"%(percentage[x][0],counter[x]))
for x in xrange(0,len(counterbest),1):
self.logger.info(">> %s: %s percent"%(percentage[x][0],counterbest[x]))

return np.reshape(np.array(c),dim)
return np.reshape(cbest,dim)


def create_system(self,mypath="."):
Expand Down
18 changes: 9 additions & 9 deletions database/database.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
c ./database/cis-PI-monomer.pdb ./database/cis-PI-monomer.txt
t ./database/trans-PI-monomer.pdb ./database/trans-PI-monomer.txt
c .\database\cis-PI-monomer.pdb .\database\cis-PI-monomer.txt
t .\database\trans-PI-monomer.pdb .\database\trans-PI-monomer.txt

C ./database/cis-PBD-monomer.pdb ./database/cis-PBD-monomer.txt
T ./database/trans-PBD-monomer.pdb ./database/trans-PBD-monomer.txt
C .\database\cis-PBD-monomer.pdb .\database\cis-PBD-monomer.txt
T .\database\trans-PBD-monomer.pdb .\database\trans-PBD-monomer.txt

V ./database/vinyl-PBD-monomer.pdb ./database/vinyl-PBD-monomer.txt
V .\database\vinyl-PBD-monomer.pdb .\database\vinyl-PBD-monomer.txt

S ./database/Styrene.pdb ./database/Styrene.txt
e ./database/diethylene.pdb ./database/diethylene.txt
S .\database\Styrene.pdb .\database\Styrene.txt
e .\database\diethylene.pdb .\database\diethylene.txt

H ./database/hPI-monomer.pdb ./database/hPI-monomer.txt
r ./database/rev-hPI-monomer.pdb ./database/rev-hPI-monomer.txt
H .\database\hPI-monomer.pdb .\database\hPI-monomer.txt
r .\database\rev-hPI-monomer.pdb .\database\rev-hPI-monomer.txt

0 comments on commit a0ca023

Please sign in to comment.