[e1a46d] | 1 | #!@PYTHON@
|
---|
| 2 | #
|
---|
| 3 | # determines all distance between each atomic pair and prints minimum and respective ids
|
---|
| 4 |
|
---|
| 5 | import sys, string, re, math
|
---|
| 6 | wrerr = sys.stderr.write
|
---|
| 7 | wrout = sys.stdout.write
|
---|
| 8 | THRESHOLD=0.4
|
---|
| 9 |
|
---|
| 10 | # check for parameters
|
---|
| 11 | if len(sys.argv) < 6:
|
---|
| 12 | wrerr("Usage: "+sys.argv[0]+" <datafile> <bondfile> <offsetID> <offsetElement> <offsetXYZ> <output>\n")
|
---|
| 13 | sys.exit(1)
|
---|
| 14 |
|
---|
| 15 | #Get box boundaries (open parameter file)
|
---|
| 16 | input = open(sys.argv[1], "r")
|
---|
| 17 | inputbonds = open(sys.argv[2], "r")
|
---|
| 18 | offsetID=int(sys.argv[3])
|
---|
| 19 | offsetElement=int(sys.argv[4])
|
---|
| 20 | offsetXYZ=int(sys.argv[5])
|
---|
| 21 |
|
---|
| 22 | # read in bond criteria
|
---|
| 23 | CELLLENGTH=0.
|
---|
| 24 | bonds=[]
|
---|
| 25 | for line in inputbonds:
|
---|
| 26 | entries=line.split()
|
---|
| 27 | if float(entries[2]) > CELLLENGTH:
|
---|
| 28 | CELLLENGTH=float(entries[2])
|
---|
| 29 | bonds.append([ entries[0], entries[1], float(entries[2])])
|
---|
| 30 | # bonds.append([ entries[1], entries[0], float(entries[2])])
|
---|
| 31 | CELLLENGTH+=THRESHOLD
|
---|
| 32 |
|
---|
| 33 | print str(CELLLENGTH)+" length of cell."
|
---|
| 34 |
|
---|
| 35 | filetype=sys.argv[1].split(".")
|
---|
| 36 | if (filetype[-1]=="data"):
|
---|
| 37 | while 1:
|
---|
| 38 | line=input.readline() # skip header (starting with #)
|
---|
| 39 | if not re.compile("^#").match(line):
|
---|
| 40 | break
|
---|
| 41 | elif (filetype[-1]=="xyz"):
|
---|
| 42 | line=input.readline()
|
---|
| 43 | line=input.readline()
|
---|
| 44 |
|
---|
| 45 | line=input.readline()
|
---|
| 46 | atoms=line.split()
|
---|
| 47 | max=[float(atoms[offsetXYZ]), float(atoms[offsetXYZ+1]), float(atoms[offsetXYZ+2])]
|
---|
| 48 | min=[float(atoms[offsetXYZ]), float(atoms[offsetXYZ+1]), float(atoms[offsetXYZ+2])]
|
---|
| 49 | for line in input:
|
---|
| 50 | if "#" in line:
|
---|
| 51 | continue
|
---|
| 52 | if "END" in line:
|
---|
| 53 | break
|
---|
| 54 | atom=line.split()
|
---|
| 55 | for i in range(3):
|
---|
| 56 | if float(atom[offsetXYZ+i]) < min[i]:
|
---|
| 57 | min[i] = float(atom[offsetXYZ+i])
|
---|
| 58 | if float(atom[offsetXYZ+i]) > max[i]:
|
---|
| 59 | max[i] = float(atom[offsetXYZ+i])
|
---|
| 60 | print "Found Box bounds [%f,%f]x[%f,%f]x[%f,%f]." % (min[0],max[0],min[1],max[1],min[2],max[2])
|
---|
| 61 | for i in range(3): # shift by minimum if below zero
|
---|
| 62 | if min[i] < 0:
|
---|
| 63 | max[i]-=min[i]
|
---|
| 64 | else:
|
---|
| 65 | min[i]=0
|
---|
| 66 | cells_x=int(math.ceil(float(max[0])/CELLLENGTH))+1
|
---|
| 67 | cells_y=int(math.ceil(float(max[1])/CELLLENGTH))+1
|
---|
| 68 | cells_z=int(math.ceil(float(max[2])/CELLLENGTH))+1
|
---|
| 69 | print "Number of cells in each axis direction (%f,%f,%f)." % (cells_x, cells_y, cells_z)
|
---|
| 70 | input.close()
|
---|
| 71 |
|
---|
| 72 | #create 3 dim array to fit in box, each cell has size 5 Ang
|
---|
| 73 | cell=[]
|
---|
| 74 |
|
---|
| 75 | for i in range(cells_x):
|
---|
| 76 | cell.append([])
|
---|
| 77 | for j in range(cells_y):
|
---|
| 78 | cell[i].append([])
|
---|
| 79 | for k in range(cells_z):
|
---|
| 80 | cell[i][j].append([0])
|
---|
| 81 |
|
---|
| 82 |
|
---|
| 83 | # open files
|
---|
| 84 | input = open(sys.argv[1], "r")
|
---|
| 85 |
|
---|
| 86 | # parse every atom into appropriate cell
|
---|
| 87 | n=0
|
---|
| 88 | filetype=sys.argv[1].split(".")
|
---|
| 89 | if (filetype[-1]=="data"):
|
---|
| 90 | while 1:
|
---|
| 91 | line=input.readline() # skip header (starting with #)
|
---|
| 92 | if not re.compile("^#").match(line):
|
---|
| 93 | break
|
---|
| 94 | elif (filetype[-1]=="xyz"):
|
---|
| 95 | line=input.readline()
|
---|
| 96 | line=input.readline()
|
---|
| 97 | for line in input:
|
---|
| 98 | if "#" in line:
|
---|
| 99 | continue
|
---|
| 100 | if "END" in line:
|
---|
| 101 | break
|
---|
| 102 | # atom=[]
|
---|
| 103 | fields=line.split()
|
---|
| 104 | x=int(math.floor((float(fields[offsetXYZ+0])-min[0])/CELLLENGTH)) # shift coordinates by box minimum
|
---|
| 105 | y=int(math.floor((float(fields[offsetXYZ+1])-min[1])/CELLLENGTH))
|
---|
| 106 | z=int(math.floor((float(fields[offsetXYZ+2])-min[2])/CELLLENGTH))
|
---|
| 107 | atom=[int(fields[offsetID]), float(fields[offsetXYZ+0]), float(fields[offsetXYZ+1]), float(fields[offsetXYZ+2]), fields[offsetElement]]
|
---|
| 108 | if int(fields[offsetID]) == 0:
|
---|
| 109 | print "error"
|
---|
| 110 | #wrout("Appending atom nr.%d (%f,%f,%f)in (%d,%d,%d)\n" % (n, float(fields[offsetXYZ+1]), float(fields[offsetXYZ+2]), float(fields[offsetXYZ+3]), x,y,z))
|
---|
| 111 | cell[x][y][z][0] +=1
|
---|
| 112 | cell[x][y][z].append(atom)
|
---|
| 113 | n=n+1
|
---|
| 114 | print "I parsed "+str(n)+" atoms."
|
---|
| 115 |
|
---|
| 116 | # go through every cell
|
---|
| 117 | min = 100000.
|
---|
| 118 | minid=-1
|
---|
| 119 | minid2=-1
|
---|
| 120 | atom1=[0,0.,0.,0.]
|
---|
| 121 | atom2=[0,0.,0.,0.]
|
---|
| 122 | v=0
|
---|
| 123 | nr=0
|
---|
| 124 |
|
---|
| 125 | output = open(sys.argv[6], "w")
|
---|
| 126 | for i in range(cells_x):
|
---|
| 127 | for j in range(cells_y):
|
---|
| 128 | for k in range(cells_z):
|
---|
| 129 | v+=cell[i][j][k][0]
|
---|
| 130 |
|
---|
| 131 | #go through every atom in cell
|
---|
| 132 | for l in range(1, cell[i][j][k][0]+1):
|
---|
| 133 | atom1=cell[i][j][k][l]
|
---|
| 134 |
|
---|
| 135 | # go through cell and all lower neighbours
|
---|
| 136 | for e in range(i-1,i+2):
|
---|
| 137 | #if on border continue periodic
|
---|
| 138 | if e<0 or e>cells_x-1:
|
---|
| 139 | break
|
---|
| 140 | for r in range(j-1,j+2):
|
---|
| 141 | #if on border continue periodic
|
---|
| 142 | if r<0 or r>cells_y-1:
|
---|
| 143 | break
|
---|
| 144 | for t in range(k-1,k+2):
|
---|
| 145 | #if on boarder continue periodic
|
---|
| 146 | if t<0 or t>cells_z-1:
|
---|
| 147 | break
|
---|
| 148 | w=cell[e][r][t][0]
|
---|
| 149 | #go through all atoms in cell
|
---|
| 150 | for m in range(1, w+1):
|
---|
| 151 | atom2=cell[e][r][t][m]
|
---|
| 152 | dist=0
|
---|
| 153 | #when in same cell: ommit identical particles
|
---|
| 154 | if (atom1[0]==atom2[0]):
|
---|
| 155 | continue
|
---|
| 156 | for h in range(1,4):
|
---|
| 157 | dist += (atom1[h] - atom2[h])*(atom1[h] - atom2[h])
|
---|
| 158 | for type in range(len(bonds)):
|
---|
| 159 | if (atom1[4] == bonds[type][0]) and (atom2[4] == bonds[type][1]):
|
---|
| 160 | if ((dist < (bonds[type][2]+THRESHOLD)*(bonds[type][2]+THRESHOLD)) and (dist > ((bonds[type][2]-THRESHOLD))*((bonds[type][2]-THRESHOLD)))):
|
---|
| 161 | output.write("%d\t%d\n" % (atom1[0], atom2[0]))
|
---|
| 162 | nr+=1
|
---|
| 163 |
|
---|
| 164 | output.close()
|
---|
| 165 | #print v
|
---|
| 166 | print str(nr)+" bonds were found."
|
---|