Advertisement
Guest User

Untitled

a guest
Nov 29th, 2013
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.97 KB | None | 0 0
  1. #import
  2. import getopt, subprocess, math, sys
  3. import numpy as np
  4. import random as rand
  5. import time
  6. import matplotlib.pyplot as plt
  7.  
  8. #options
  9. helptext = '''
  10. Usage:
  11.  
  12. %s -i INPUT -o OUTPUT -n NUMBER OF MOLECULES -d BOX DIMENSIONS x,y,z -c MOLECULE COUNTER -r RUN IN VMD -f FILL IN MISSING DATA -p PLOT GENERATION PROGRESS
  13. ''' % sys.argv[0]
  14.  
  15. short_opt = "i:o:n:d:crfp"
  16. long_opt = [ "input=", "output=", "number=", "dimensions=", "counter", "run", "fillin", "plot" ]
  17.  
  18. opts, args = getopt.getopt(sys.argv[1:], short_opt, long_opt)
  19.  
  20. in_fnm = ''
  21. out_fnm = ''
  22. num_of_mol = ''
  23. dims = ''
  24. counter_check = False
  25. run_check = False
  26. fillin_check = False
  27. plot_check = False
  28.  
  29. for t in opts:
  30.     if t[0] == "-i" or t[0] == "--input": in_fnm = t[1]
  31.     if t[0] == "-o" or t[0] == "--output": out_fnm = t[1]
  32.     if t[0] == "-n" or t[0] == "--number": num_of_mol = int(t[1])
  33.     if t[0] == "-d" or t[0] == "--dimensions": dims = t[1].split(',')
  34.     if t[0] == "-c" or t[0] == "--counter": counter_check = True
  35.     if t[0] == "-r" or t[0] == "--run": run_check = True
  36.     if t[0] == "-f" or t[0] == "--fillin": fillin_check = True
  37.     if t[0] == "-p" or t[0] == "--plot": plot_check = True
  38.  
  39. if (not in_fnm or not out_fnm or not num_of_mol or not dims) and not fillin_check:
  40.     print helptext
  41.     exit(1)
  42.  
  43. if fillin_check:
  44.     if not in_fnm: in_fnm = "water.gro"
  45.     if not out_fnm: out_fnm = str(in_fnm.split('.')[0]) + "new." + str(in_fnm.split('.')[1])
  46.     if not num_of_mol: num_of_mol = 500
  47.     if not dims: dims = [10.,10.,10.]
  48.  
  49. #define distance function
  50. def atom_distance_sq(atom1,atom2):
  51.     if newmoleclist == []:
  52.         return threshold**2
  53.     else:
  54.         return ( (atom1[4]-atom2[4])**2 + (atom1[5]-atom2[5])**2 + (atom1[6]-atom2[6])**2 )
  55.  
  56. #open file
  57. file = open(in_fnm, "r")
  58.  
  59. #readlines
  60. lines = file.readlines()
  61.  
  62. #number of atoms in the molecule
  63. numb = len(lines[2:-1])
  64.  
  65. #target molecule number; user defines the target number of molecules to be created
  66. targetmolcount = num_of_mol
  67.  
  68. #target atom number
  69. targetatcount = numb*targetmolcount
  70.  
  71. #box dimensions
  72. dimx = float(dims[0])
  73. dimy = float(dims[1])
  74. dimz = float(dims[2])
  75.  
  76. #atom distance threshold; how far atoms have to be treated as being bonded to eachother
  77. threshold = 0.2
  78.  
  79. #residue id and atom id; residue name and atom name; coordinate list
  80. resid = []
  81. atomid = []
  82. resnm = []
  83. atomnm = []
  84. xl = []
  85. yl = []
  86. zl = []
  87. for i in lines[2:-1]:
  88.     resid.append(i[0:5].strip())
  89.     atomid.append(i[15:20].strip())
  90.     resnm.append(i[5:10].strip())
  91.     atomnm.append(i[10:15].strip())
  92.     xl.append(float(i[20:28]))
  93.     yl.append(float(i[28:36]))
  94.     zl.append(float(i[36:44]))
  95.  
  96. #normalization
  97. avgx = sum(xl) / float(len(xl))
  98. avgy = sum(yl) / float(len(yl))
  99. avgz = sum(zl) / float(len(zl))
  100.  
  101. #create a molecule; creates a list consisting of every atom of the source molecule
  102. sourcemolec = []
  103. for i in range(numb):
  104.     sourcemolec.append( [resid[i], resnm[i], atomnm[i], atomid[i], xl[i] - avgx, yl[i] - avgy, zl[i] - avgz, [0,0,0]] )
  105.  
  106. #create a list of molecules
  107. #list containing source material molecule(s)
  108. moleclist = [sourcemolec]
  109. #list containing molecules with randomized coordinates
  110. newmoleclist = []
  111. #adjusts the atom id number from molecule to molecule
  112. atomidstep = 0
  113. #counts the number of molecules, collisions, attempts
  114. molcount = 0
  115. molcountnot = 0
  116. molcountany = 0
  117. #time measurement
  118. times = []
  119. timesnot = []
  120. timesany = []
  121. time_start = time.time()
  122.  
  123. while molcount < targetmolcount:
  124.     #adjusts the atom id number from molecule to molecule
  125.     atomid = 1+numb*atomidstep
  126.     #adjusts the residue/molecule id number
  127.     resid = 1+math.floor(atomidstep)
  128.  
  129.     for molecule in moleclist:
  130.         atcount = 0
  131.         atomidstep = 0
  132.         #new molecule with randomized coordinates
  133.         tentative_molecule = []
  134.  
  135.         while atcount < numb:
  136.             sourcemolec_rot = sourcemolec
  137.  
  138.             alpha = rand.uniform(0,2*math.pi)
  139.             beta = rand.uniform(0,2*math.pi)
  140.             gamma = rand.uniform(0,2*math.pi)
  141.            
  142.             R_alpha = [[1,0,0],[0,math.cos(alpha),-math.sin(alpha)],[0,math.sin(alpha),math.cos(alpha)]]
  143.             R_beta = [[math.cos(beta),0,math.sin(beta)],[0,1,0],[-math.sin(beta),0,math.cos(beta)]]
  144.             R_gamma = [[math.cos(gamma),-math.sin(gamma),0],[math.sin(gamma),math.cos(gamma),0],[0,0,1]]
  145.            
  146.             for atom in sourcemolec_rot:
  147.                 point = [atom[4], atom[5], atom[6]]
  148.                 point2 = np.matrix(point) * np.matrix(R_alpha) * np.matrix(R_beta) * np.matrix(R_gamma)
  149.                 point3 = np.array(point2).reshape(-1,).tolist()
  150.                 atom[4], atom[5], atom[6] = point3[0], point3[1], point3[2]
  151.            
  152.             xrdm = rand.uniform(0,dimx)
  153.             yrdm = rand.uniform(0,dimy)
  154.             zrdm = rand.uniform(0,dimz)
  155.  
  156.             for atom in sourcemolec_rot:
  157.                 xl = atom[4] + xrdm
  158.                 yl = atom[5] + yrdm
  159.                 zl = atom[6] + zrdm
  160.                 resnm = atom[1]
  161.                 atomnm = atom[2]
  162.                 molec_center = [atom[7][0] + xrdm, atom[7][1] + yrdm, atom[7][2] + zrdm]
  163.                 tentative_molecule.append( (resid, resnm, atomnm, atomid, xl, yl, zl) )
  164.                 atcount += 1
  165.                 atomid += 1
  166.  
  167.         overlap = False
  168.  
  169.         for atom1 in tentative_molecule:
  170.             for existing_molecule in newmoleclist:
  171.                 if newmoleclist == []:
  172.                     overlap = False
  173.                 else:
  174.                     for atom2 in existing_molecule:
  175.                         distance_square = atom_distance_sq(atom1,atom2)
  176.                         if distance_square < threshold**2:
  177.                             overlap = True
  178.                             break
  179.                     if overlap: break
  180.         #counts the number of attempts
  181.         molcountany += 1
  182.         #measures time-dependence of molcountany
  183.         timesany.append([time.time() - time_start, molcountany])
  184.  
  185.         if overlap:
  186.             #counts the number of collisions
  187.             molcountnot += 1
  188.             #measures time-dependence of molcountnot
  189.             timesnot.append([time.time() - time_start, molcountnot])
  190.             continue
  191.         if not overlap:
  192.             #appends the newly created molecules to the fresh list of molecules
  193.             newmoleclist.append(tentative_molecule)
  194.             #adjusts the atom id number from molecule to molecule
  195.             atomidstep = len(newmoleclist)
  196.             #counts the number of molecules
  197.             molcount += 1
  198.             #measures time-dependence of molcount
  199.             times.append([time.time() - time_start, molcount])
  200.             #displays molecule counter
  201.             if counter_check:
  202.                 sys.stdout.write("\rNumber of molecules generated: %d in %.2f seconds" % (molcount, (time.time() - time_start)))
  203.                 sys.stdout.flush()
  204.  
  205. #new line
  206. sys.stdout.write("\n")
  207.  
  208. #open output file
  209. file2 = open(out_fnm, "w")
  210.  
  211. #write comment & number of atoms
  212. targetmolcount
  213. print >> file2, "COMMENT HERE"
  214. print >> file2, targetmolcount*numb
  215.  
  216. for molecule in newmoleclist:
  217.     for atom in molecule:
  218.         print >>file2, "%5d%-5s%5s%5d%8.3f%8.3f%8.3f" % atom
  219.  
  220. #write box dimensions in the output file
  221. box = "%10.5f%10.5f%10.5f" % (dimx, dimy, dimz)
  222. print >>file2, box
  223.  
  224. #close all files
  225. file.close()
  226. file2.close()
  227.  
  228. #print parameters
  229. print "Box dimensions (x, y, z) [nm]:", "%.1f, %.1f, %.1f" % (dimx, dimy, dimz)
  230. print "Input file name:", in_fnm
  231. print "Output file name:", out_fnm
  232. print "Runtime: %.2f seconds" % times[num_of_mol - 1][0]
  233. print "Number of molecules generated:", molcount
  234. print "Number of collisions:", molcountnot
  235. print "Number of attempts:", molcountany
  236.  
  237. #run VMD
  238. if run_check:
  239.     subprocess.Popen(["C:\\Program Files\\University of Illinois\\VMD\\vmd.exe", out_fnm], creationflags = subprocess.CREATE_NEW_CONSOLE)
  240.     #subprocess.call(["vmd", out_fnm])
  241.     #subprocess.Popen(["vmd", out_fnm], stdout=subprocess.PIPE)
  242.  
  243. #plot time-dependence of number of molecules generated
  244. if plot_check == True:
  245.     horaxis = []
  246.     vertaxis = []
  247.  
  248.     for i in range(len(times)):
  249.         horaxis.append(times[i][1])
  250.         vertaxis.append(times[i][0])
  251.  
  252.     horaxisnot = []
  253.     vertaxisnot = []
  254.  
  255.     for i in range(len(timesnot)):
  256.         horaxisnot.append(timesnot[i][1])
  257.         vertaxisnot.append(timesnot[i][0])
  258.  
  259.     horaxisany = []
  260.     vertaxisany = []
  261.  
  262.     for i in range(len(timesany)):
  263.         horaxisany.append(timesany[i][1])
  264.         vertaxisany.append(timesany[i][0])
  265.  
  266.     p = []
  267.     p += [plt.plot(horaxis,vertaxis, label = "Molecules")]
  268.     p += [plt.plot(horaxisnot,vertaxisnot, label = "Collisions")]
  269.     p += [plt.plot(horaxisany,vertaxisany, label = "Attempts")]
  270.     plt.xlabel("Number of molecules")
  271.     plt.ylabel("Time")
  272.     plt.legend(loc="center left")
  273.     plt.show(p)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement