3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Green Red Orange Magenta Azure Cyan Skyblue
53 #include "sortwater.h"
56 static void rand_rot(int natoms
,rvec x
[],rvec v
[],vec4 xrot
[],vec4 vrot
[],
57 int *seed
,rvec max_rot
)
59 mat4 mt1
,mt2
,mr
[DIM
],mtemp1
,mtemp2
,mtemp3
,mxtot
,mvtot
;
65 for(i
=0; (i
<natoms
); i
++)
66 for(m
=0; (m
<DIM
); m
++) {
67 xcm
[m
]+=x
[i
][m
]/natoms
; /* get center of mass of one molecule */
69 fprintf(stderr
,"center of geometry: %f, %f, %f\n",xcm
[0],xcm
[1],xcm
[2]);
71 translate(-xcm
[XX
],-xcm
[YY
],-xcm
[ZZ
],mt1
); /* move c.o.ma to origin */
72 for(m
=0; (m
<DIM
); m
++) {
73 phi
=M_PI
*max_rot
[m
]*(2*rando(seed
) - 1)/180;
76 translate(xcm
[XX
],xcm
[YY
],xcm
[ZZ
],mt2
);
78 /* For mult_matrix we need to multiply in the opposite order
79 * compared to normal mathematical notation.
81 mult_matrix(mtemp1
,mt1
,mr
[XX
]);
82 mult_matrix(mtemp2
,mr
[YY
],mr
[ZZ
]);
83 mult_matrix(mtemp3
,mtemp1
,mtemp2
);
84 mult_matrix(mxtot
,mtemp3
,mt2
);
85 mult_matrix(mvtot
,mr
[XX
],mtemp2
);
87 for(i
=0; (i
<natoms
); i
++) {
88 m4_op(mxtot
,x
[i
],xrot
[i
]);
89 m4_op(mvtot
,v
[i
],vrot
[i
]);
93 static void move_x(int natoms
,rvec x
[],matrix box
)
99 for(i
=0; (i
<natoms
); i
++)
100 for(m
=0; (m
<DIM
); m
++)
102 for(m
=0; (m
<DIM
); m
++)
103 xcm
[m
] = 0.5*box
[m
][m
]-xcm
[m
]/natoms
;
104 for(i
=0; (i
<natoms
); i
++)
105 for(m
=0; (m
<DIM
); m
++)
109 int gmx_genconf(int argc
, char *argv
[])
111 const char *desc
[] = {
112 "genconf multiplies a given coordinate file by simply stacking them",
113 "on top of each other, like a small child playing with wooden blocks.",
114 "The program makes a grid of [IT]user defined[it]",
115 "proportions ([TT]-nbox[tt]), ",
116 "and interspaces the grid point with an extra space [TT]-dist[tt].[PAR]",
117 "When option [TT]-rot[tt] is used the program does not check for overlap",
118 "between molecules on grid points. It is recommended to make the box in",
119 "the input file at least as big as the coordinates + ",
120 "Van der Waals radius.[PAR]",
121 "If the optional trajectory file is given, conformations are not",
122 "generated, but read from this file and translated appropriately to",
126 const char *bugs
[] = {
127 "The program should allow for random displacement off lattice points." };
130 t_atoms
*atoms
; /* list with all atoms */
132 rvec
*x
,*xx
,*v
; /* coordinates? */
136 matrix box
,boxx
; /* box length matrix */
138 int natoms
; /* number of atoms in one molecule */
139 int nres
; /* number of molecules? */
140 int i
,j
,k
,l
,m
,ndx
,nrdx
,nx
,ny
,nz
,status
=-1;
145 { efSTX
, "-f", "conf", ffREAD
},
146 { efSTO
, "-o", "out", ffWRITE
},
147 { efTRX
, "-trj",NULL
, ffOPTRD
}
149 #define NFILE asize(fnm)
150 static rvec nrbox
= {1,1,1};
151 static int seed
= 0; /* seed for random number generator */
152 static int nmolat
= 3;
153 static int nblock
= 1;
154 static bool bShuffle
= FALSE
;
155 static bool bSort
= FALSE
;
156 static bool bRandom
= FALSE
; /* False: no random rotations */
157 static bool bRenum
= TRUE
; /* renumber residues */
158 static rvec dist
= {0,0,0}; /* space added between molecules ? */
159 static rvec max_rot
= {180,180,180}; /* maximum rotation */
161 { "-nbox", FALSE
, etRVEC
, {nrbox
}, "Number of boxes" },
162 { "-dist", FALSE
, etRVEC
, {dist
}, "Distance between boxes" },
163 { "-seed", FALSE
, etINT
, {&seed
},
164 "Random generator seed, if 0 generated from the time" },
165 { "-rot", FALSE
, etBOOL
, {&bRandom
}, "Randomly rotate conformations" },
166 { "-shuffle",FALSE
, etBOOL
, {&bShuffle
},"Random shuffling of molecules" },
167 { "-sort", FALSE
, etBOOL
, {&bSort
}, "Sort molecules on X coord" },
168 { "-block", FALSE
, etINT
, {&nblock
},
169 "Divide the box in blocks on this number of cpus" },
170 { "-nmolat", FALSE
, etINT
, {&nmolat
},
171 "Number of atoms per molecule, assumed to start from 0. "
172 "If you set this wrong, it will screw up your system!" },
173 { "-maxrot", FALSE
, etRVEC
, {max_rot
}, "Maximum random rotation" },
174 { "-renumber",FALSE
,etBOOL
, {&bRenum
}, "Renumber residues" }
177 CopyRight(stderr
,argv
[0]);
178 parse_common_args(&argc
,argv
,0,NFILE
,fnm
,asize(pa
),pa
,
179 asize(desc
),desc
,asize(bugs
),bugs
,&oenv
);
181 if (bRandom
&& (seed
== 0))
184 bTRX
= ftp2bSet(efTRX
,NFILE
,fnm
);
185 nx
= (int)(nrbox
[XX
]+0.5);
186 ny
= (int)(nrbox
[YY
]+0.5);
187 nz
= (int)(nrbox
[ZZ
]+0.5);
189 if ((nx
<= 0) || (ny
<= 0) || (nz
<= 0))
190 gmx_fatal(FARGS
,"Number of boxes (-nbox) should be larger than zero");
191 if ((nmolat
<= 0) && bShuffle
)
192 gmx_fatal(FARGS
,"Can not shuffle if the molecules only have %d atoms",
195 vol
=nx
*ny
*nz
; /* calculate volume in grid points (= nr. molecules) */
197 get_stx_coordnum(opt2fn("-f",NFILE
,fnm
),&natoms
);
199 /* make space for all the atoms */
200 init_t_atoms(atoms
,natoms
*vol
,FALSE
);
201 snew(x
,natoms
*vol
); /* get space for coordinates of all atoms */
202 snew(xrot
,natoms
); /* get space for rotation matrix? */
203 snew(v
,natoms
*vol
); /* velocities. not really needed? */
205 /* set atoms->nr to the number in one box *
206 * to avoid complaints in read_stx_conf *
209 read_stx_conf(opt2fn("-f",NFILE
,fnm
),title
,atoms
,x
,v
,&ePBC
,box
);
211 nres
=atoms
->nres
; /* nr of residues in one element? */
214 if (!read_first_x(oenv
,&status
,ftp2fn(efTRX
,NFILE
,fnm
),&t
,&xx
,boxx
))
215 gmx_fatal(FARGS
,"No atoms in trajectory %s",ftp2fn(efTRX
,NFILE
,fnm
));
218 for(i
=0; i
<natoms
; i
++) {
219 copy_rvec(x
[i
],xx
[i
]);
224 for(k
=0; (k
<nz
); k
++) { /* loop over all gridpositions */
225 shift
[ZZ
]=k
*(dist
[ZZ
]+box
[ZZ
][ZZ
]);
227 for(j
=0; (j
<ny
); j
++) {
228 shift
[YY
]=j
*(dist
[YY
]+box
[YY
][YY
])+k
*box
[ZZ
][YY
];
230 for(i
=0; (i
<nx
); i
++) {
231 shift
[XX
]=i
*(dist
[XX
]+box
[XX
][XX
])+j
*box
[YY
][XX
]+k
*box
[ZZ
][XX
];
233 ndx
=(i
*ny
*nz
+j
*nz
+k
)*natoms
;
234 nrdx
=(i
*ny
*nz
+j
*nz
+k
)*nres
;
236 /* Random rotation on input coords */
238 rand_rot(natoms
,xx
,v
,xrot
,vrot
,&seed
,max_rot
);
240 for(l
=0; (l
<natoms
); l
++) {
241 for(m
=0; (m
<DIM
); m
++) {
243 x
[ndx
+l
][m
] = xrot
[l
][m
];
244 v
[ndx
+l
][m
] = vrot
[l
][m
];
247 x
[ndx
+l
][m
] = xx
[l
][m
];
248 v
[ndx
+l
][m
] = v
[l
][m
];
251 if (ePBC
== epbcSCREW
&& i
% 2 == 1) {
252 /* Rotate around x axis */
253 for(m
=YY
; m
<=ZZ
; m
++) {
254 x
[ndx
+l
][m
] = box
[YY
][m
] + box
[ZZ
][m
] - x
[ndx
+l
][m
];
255 v
[ndx
+l
][m
] = -v
[ndx
+l
][m
];
258 for(m
=0; (m
<DIM
); m
++) {
259 x
[ndx
+l
][m
] += shift
[m
];
261 atoms
->atom
[ndx
+l
].resind
= nrdx
+ atoms
->atom
[l
].resind
;
262 atoms
->atomname
[ndx
+l
]=atoms
->atomname
[l
];
265 for(l
=0; (l
<nres
); l
++) {
266 atoms
->resinfo
[nrdx
+l
] = atoms
->resinfo
[l
];
268 atoms
->resinfo
[nrdx
+l
].nr
+= nrdx
;
271 if (!read_next_x(oenv
,status
,&t
,natoms
,xx
,boxx
) &&
272 ((i
+1)*(j
+1)*(k
+1) < vol
))
273 gmx_fatal(FARGS
,"Not enough frames in trajectory");
280 /* make box bigger */
281 for(m
=0; (m
<DIM
); m
++)
282 box
[m
][m
] += dist
[m
];
283 svmul(nx
,box
[XX
],box
[XX
]);
284 svmul(ny
,box
[YY
],box
[YY
]);
285 svmul(nz
,box
[ZZ
],box
[ZZ
]);
286 if (ePBC
== epbcSCREW
&& nx
% 2 == 0) {
287 /* With an even number of boxes in x we can forgot about the screw */
291 /* move_x(natoms*vol,x,box); */ /* put atoms in box? */
296 /*depending on how you look at it, this is either a nasty hack or the way it should work*/
298 for (i
=0;i
<atoms
->nres
;i
++)
299 atoms
->resinfo
[i
].nr
=i
+1;
303 randwater(0,atoms
->nr
/nmolat
,nmolat
,x
,v
,&seed
);
305 sortwater(0,atoms
->nr
/nmolat
,nmolat
,x
,v
);
306 else if (opt2parg_bSet("-block",asize(pa
),pa
))
307 mkcompact(0,atoms
->nr
/nmolat
,nmolat
,x
,v
,nblock
,box
);
309 write_sto_conf(opt2fn("-o",NFILE
,fnm
),title
,atoms
,x
,v
,ePBC
,box
);