File: | gromacs/gmxana/gmx_rdf.c |
Location: | line 915, column 16 |
Description: | Array access results in a null pointer dereference |
1 | /* | |||
2 | * This file is part of the GROMACS molecular simulation package. | |||
3 | * | |||
4 | * Copyright (c) 1991-2000, University of Groningen, The Netherlands. | |||
5 | * Copyright (c) 2001-2004, The GROMACS development team. | |||
6 | * Copyright (c) 2013,2014, by the GROMACS development team, led by | |||
7 | * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, | |||
8 | * and including many others, as listed in the AUTHORS file in the | |||
9 | * top-level source directory and at http://www.gromacs.org. | |||
10 | * | |||
11 | * GROMACS is free software; you can redistribute it and/or | |||
12 | * modify it under the terms of the GNU Lesser General Public License | |||
13 | * as published by the Free Software Foundation; either version 2.1 | |||
14 | * of the License, or (at your option) any later version. | |||
15 | * | |||
16 | * GROMACS is distributed in the hope that it will be useful, | |||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
19 | * Lesser General Public License for more details. | |||
20 | * | |||
21 | * You should have received a copy of the GNU Lesser General Public | |||
22 | * License along with GROMACS; if not, see | |||
23 | * http://www.gnu.org/licenses, or write to the Free Software Foundation, | |||
24 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||
25 | * | |||
26 | * If you want to redistribute modifications to GROMACS, please | |||
27 | * consider that scientific software is very special. Version | |||
28 | * control is crucial - bugs must be traceable. We will be happy to | |||
29 | * consider code for inclusion in the official distribution, but | |||
30 | * derived work must not be called official GROMACS. Details are found | |||
31 | * in the README & COPYING files - if they are missing, get the | |||
32 | * official version at http://www.gromacs.org. | |||
33 | * | |||
34 | * To help us fund GROMACS development, we humbly ask that you cite | |||
35 | * the research papers on the package. Check out http://www.gromacs.org. | |||
36 | */ | |||
37 | ||||
38 | #ifdef HAVE_CONFIG_H1 | |||
39 | #include <config.h> | |||
40 | #endif | |||
41 | ||||
42 | #include <math.h> | |||
43 | ||||
44 | #include "typedefs.h" | |||
45 | #include "macros.h" | |||
46 | #include "gromacs/math/vec.h" | |||
47 | #include "pbc.h" | |||
48 | #include "gromacs/fileio/xvgr.h" | |||
49 | #include "viewit.h" | |||
50 | #include "gromacs/utility/futil.h" | |||
51 | #include "gromacs/commandline/pargs.h" | |||
52 | #include "gromacs/fileio/tpxio.h" | |||
53 | #include "gromacs/fileio/trxio.h" | |||
54 | #include "physics.h" | |||
55 | #include "index.h" | |||
56 | #include "gromacs/utility/smalloc.h" | |||
57 | #include "calcgrid.h" | |||
58 | #include "nrnb.h" | |||
59 | #include "coulomb.h" | |||
60 | #include "gstat.h" | |||
61 | #include "gromacs/fileio/matio.h" | |||
62 | #include "gmx_ana.h" | |||
63 | #include "names.h" | |||
64 | ||||
65 | #include "gromacs/utility/fatalerror.h" | |||
66 | ||||
67 | static void check_box_c(matrix box) | |||
68 | { | |||
69 | if (fabs(box[ZZ2][XX0]) > GMX_REAL_EPS5.96046448E-08*box[ZZ2][ZZ2] || | |||
70 | fabs(box[ZZ2][YY1]) > GMX_REAL_EPS5.96046448E-08*box[ZZ2][ZZ2]) | |||
71 | { | |||
72 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 72, | |||
73 | "The last box vector is not parallel to the z-axis: %f %f %f", | |||
74 | box[ZZ2][XX0], box[ZZ2][YY1], box[ZZ2][ZZ2]); | |||
75 | } | |||
76 | } | |||
77 | ||||
78 | static void calc_comg(int is, int *coi, int *index, gmx_bool bMass, t_atom *atom, | |||
79 | rvec *x, rvec *x_comg) | |||
80 | { | |||
81 | int c, i, d; | |||
82 | rvec xc; | |||
83 | real mtot, m; | |||
84 | ||||
85 | if (bMass && atom == NULL((void*)0)) | |||
86 | { | |||
87 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 87, "No masses available while mass weighting was requested"); | |||
88 | } | |||
89 | ||||
90 | for (c = 0; c < is; c++) | |||
91 | { | |||
92 | clear_rvec(xc); | |||
93 | mtot = 0; | |||
94 | for (i = coi[c]; i < coi[c+1]; i++) | |||
95 | { | |||
96 | if (bMass) | |||
97 | { | |||
98 | m = atom[index[i]].m; | |||
99 | for (d = 0; d < DIM3; d++) | |||
100 | { | |||
101 | xc[d] += m*x[index[i]][d]; | |||
102 | } | |||
103 | mtot += m; | |||
104 | } | |||
105 | else | |||
106 | { | |||
107 | rvec_inc(xc, x[index[i]]); | |||
108 | mtot += 1.0; | |||
109 | } | |||
110 | } | |||
111 | svmul(1/mtot, xc, x_comg[c]); | |||
112 | } | |||
113 | } | |||
114 | ||||
115 | static void split_group(int isize, int *index, char *grpname, | |||
116 | t_topology *top, char type, | |||
117 | int *is_out, int **coi_out) | |||
118 | { | |||
119 | t_block *mols = NULL((void*)0); | |||
120 | t_atom *atom = NULL((void*)0); | |||
121 | int is, *coi; | |||
122 | int cur, mol, res, i, a, i1; | |||
123 | ||||
124 | /* Split up the group in molecules or residues */ | |||
125 | switch (type) | |||
126 | { | |||
127 | case 'm': | |||
128 | mols = &top->mols; | |||
129 | break; | |||
130 | case 'r': | |||
131 | atom = top->atoms.atom; | |||
132 | break; | |||
133 | default: | |||
134 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 134, "Unknown rdf option '%s'", type); | |||
135 | } | |||
136 | snew(coi, isize+1)(coi) = save_calloc("coi", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 136, (isize+1), sizeof(*(coi))); | |||
137 | is = 0; | |||
138 | cur = -1; | |||
139 | mol = 0; | |||
140 | for (i = 0; i < isize; i++) | |||
141 | { | |||
142 | a = index[i]; | |||
143 | if (type == 'm') | |||
144 | { | |||
145 | /* Check if the molecule number has changed */ | |||
146 | i1 = mols->index[mol+1]; | |||
147 | while (a >= i1) | |||
148 | { | |||
149 | mol++; | |||
150 | i1 = mols->index[mol+1]; | |||
151 | } | |||
152 | if (mol != cur) | |||
153 | { | |||
154 | coi[is++] = i; | |||
155 | cur = mol; | |||
156 | } | |||
157 | } | |||
158 | else if (type == 'r') | |||
159 | { | |||
160 | /* Check if the residue index has changed */ | |||
161 | res = atom[a].resind; | |||
162 | if (res != cur) | |||
163 | { | |||
164 | coi[is++] = i; | |||
165 | cur = res; | |||
166 | } | |||
167 | } | |||
168 | } | |||
169 | coi[is] = i; | |||
170 | srenew(coi, is+1)(coi) = save_realloc("coi", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 170, (coi), (is+1), sizeof(*(coi))); | |||
171 | printf("Group '%s' of %d atoms consists of %d %s\n", | |||
172 | grpname, isize, is, | |||
173 | (type == 'm' ? "molecules" : "residues")); | |||
174 | ||||
175 | *is_out = is; | |||
176 | *coi_out = coi; | |||
177 | } | |||
178 | ||||
179 | static void do_rdf(const char *fnNDX, const char *fnTPS, const char *fnTRX, | |||
180 | const char *fnRDF, const char *fnCNRDF, const char *fnHQ, | |||
181 | gmx_bool bCM, const char *close, | |||
182 | const char **rdft, gmx_bool bXY, gmx_bool bPBC, gmx_bool bNormalize, | |||
183 | real cutoff, real binwidth, real fade, int ng, | |||
184 | const output_env_t oenv) | |||
185 | { | |||
186 | FILE *fp; | |||
187 | t_trxstatus *status; | |||
188 | char outf1[STRLEN4096], outf2[STRLEN4096]; | |||
189 | char title[STRLEN4096], gtitle[STRLEN4096], refgt[30]; | |||
190 | int g, natoms, i, ii, j, k, nbin, j0, j1, n, nframes; | |||
191 | int **count; | |||
192 | char **grpname; | |||
193 | int *isize, isize_cm = 0, nrdf = 0, max_i, isize0, isize_g; | |||
194 | atom_id **index, *index_cm = NULL((void*)0); | |||
195 | gmx_int64_t *sum; | |||
196 | real t, rmax2, cut2, r, r2, r2ii, invhbinw, normfac; | |||
197 | real segvol, spherevol, prev_spherevol, **rdf; | |||
198 | rvec *x, dx, *x0 = NULL((void*)0), *x_i1, xi; | |||
199 | real *inv_segvol, invvol, invvol_sum, rho; | |||
200 | gmx_bool bClose, *bExcl, bTop, bNonSelfExcl; | |||
201 | matrix box, box_pbc; | |||
202 | int **npairs; | |||
203 | atom_id ix, jx, ***pairs; | |||
204 | t_topology *top = NULL((void*)0); | |||
205 | int ePBC = -1, ePBCrdf = -1; | |||
206 | t_block *mols = NULL((void*)0); | |||
207 | t_blocka *excl; | |||
208 | t_atom *atom = NULL((void*)0); | |||
209 | t_pbc pbc; | |||
210 | gmx_rmpbc_t gpbc = NULL((void*)0); | |||
211 | int *is = NULL((void*)0), **coi = NULL((void*)0), cur, mol, i1, res, a; | |||
212 | ||||
213 | excl = NULL((void*)0); | |||
214 | ||||
215 | bClose = (close[0] != 'n'); | |||
216 | ||||
217 | if (fnTPS) | |||
218 | { | |||
219 | snew(top, 1)(top) = save_calloc("top", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 219, (1), sizeof(*(top))); | |||
220 | bTop = read_tps_conf(fnTPS, title, top, &ePBC, &x, NULL((void*)0), box, TRUE1); | |||
221 | if (bTop && !(bCM || bClose)) | |||
222 | { | |||
223 | /* get exclusions from topology */ | |||
224 | excl = &(top->excls); | |||
225 | } | |||
226 | } | |||
227 | snew(grpname, ng+1)(grpname) = save_calloc("grpname", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 227, (ng+1), sizeof(*(grpname))); | |||
228 | snew(isize, ng+1)(isize) = save_calloc("isize", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 228, (ng+1), sizeof(*(isize))); | |||
229 | snew(index, ng+1)(index) = save_calloc("index", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 229, (ng+1), sizeof(*(index))); | |||
230 | fprintf(stderrstderr, "\nSelect a reference group and %d group%s\n", | |||
231 | ng, ng == 1 ? "" : "s"); | |||
232 | if (fnTPS) | |||
233 | { | |||
234 | get_index(&(top->atoms), fnNDX, ng+1, isize, index, grpname); | |||
235 | atom = top->atoms.atom; | |||
236 | } | |||
237 | else | |||
238 | { | |||
239 | rd_index(fnNDX, ng+1, isize, index, grpname); | |||
240 | } | |||
241 | ||||
242 | if (bCM || bClose) | |||
243 | { | |||
244 | snew(is, 1)(is) = save_calloc("is", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 244, (1), sizeof(*(is))); | |||
245 | snew(coi, 1)(coi) = save_calloc("coi", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 245, (1), sizeof(*(coi))); | |||
246 | if (bClose) | |||
247 | { | |||
248 | split_group(isize[0], index[0], grpname[0], top, close[0], &is[0], &coi[0]); | |||
249 | } | |||
250 | } | |||
251 | if (rdft[0][0] != 'a') | |||
252 | { | |||
253 | /* Split up all the groups in molecules or residues */ | |||
254 | srenew(is, ng+1)(is) = save_realloc("is", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 254, (is), (ng+1), sizeof(*(is))); | |||
255 | srenew(coi, ng+1)(coi) = save_realloc("coi", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 255, (coi), (ng+1), sizeof(*(coi))); | |||
256 | for (g = ((bCM || bClose) ? 1 : 0); g < ng+1; g++) | |||
257 | { | |||
258 | split_group(isize[g], index[g], grpname[g], top, rdft[0][0], &is[g], &coi[g]); | |||
259 | } | |||
260 | } | |||
261 | ||||
262 | if (bCM) | |||
263 | { | |||
264 | is[0] = 1; | |||
265 | snew(coi[0], is[0]+1)(coi[0]) = save_calloc("coi[0]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 265, (is[0]+1), sizeof(*(coi[0]))); | |||
266 | coi[0][0] = 0; | |||
267 | coi[0][1] = isize[0]; | |||
268 | isize0 = is[0]; | |||
269 | snew(x0, isize0)(x0) = save_calloc("x0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 269, (isize0), sizeof(*(x0))); | |||
270 | } | |||
271 | else if (bClose || rdft[0][0] != 'a') | |||
272 | { | |||
273 | isize0 = is[0]; | |||
274 | snew(x0, isize0)(x0) = save_calloc("x0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 274, (isize0), sizeof(*(x0))); | |||
275 | } | |||
276 | else | |||
277 | { | |||
278 | isize0 = isize[0]; | |||
279 | } | |||
280 | ||||
281 | natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box); | |||
282 | if (!natoms) | |||
283 | { | |||
284 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 284, "Could not read coordinates from statusfile\n"); | |||
285 | } | |||
286 | if (fnTPS) | |||
287 | { | |||
288 | /* check with topology */ | |||
289 | if (natoms > top->atoms.nr) | |||
290 | { | |||
291 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 291, "Trajectory (%d atoms) does not match topology (%d atoms)", | |||
292 | natoms, top->atoms.nr); | |||
293 | } | |||
294 | } | |||
295 | /* check with index groups */ | |||
296 | for (i = 0; i < ng+1; i++) | |||
297 | { | |||
298 | for (j = 0; j < isize[i]; j++) | |||
299 | { | |||
300 | if (index[i][j] >= natoms) | |||
301 | { | |||
302 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 302, "Atom index (%d) in index group %s (%d atoms) larger " | |||
303 | "than number of atoms in trajectory (%d atoms)", | |||
304 | index[i][j], grpname[i], isize[i], natoms); | |||
305 | } | |||
306 | } | |||
307 | } | |||
308 | ||||
309 | /* initialize some handy things */ | |||
310 | if (ePBC == -1) | |||
311 | { | |||
312 | ePBC = guess_ePBC(box); | |||
313 | } | |||
314 | copy_mat(box, box_pbc); | |||
315 | if (bXY) | |||
316 | { | |||
317 | check_box_c(box); | |||
318 | switch (ePBC) | |||
319 | { | |||
320 | case epbcXYZ: | |||
321 | case epbcXY: ePBCrdf = epbcXY; break; | |||
322 | case epbcNONE: ePBCrdf = epbcNONE; break; | |||
323 | default: | |||
324 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 324, "xy-rdf's are not supported for pbc type'%s'", | |||
325 | EPBC(ePBC)((((ePBC) < 0) || ((ePBC) >= (epbcNR))) ? "UNDEFINED" : (epbc_names)[ePBC])); | |||
326 | break; | |||
327 | } | |||
328 | /* Make sure the z-height does not influence the cut-off */ | |||
329 | box_pbc[ZZ2][ZZ2] = 2*max(box[XX][XX], box[YY][YY])(((box[0][0]) > (box[1][1])) ? (box[0][0]) : (box[1][1]) ); | |||
330 | } | |||
331 | else | |||
332 | { | |||
333 | ePBCrdf = ePBC; | |||
334 | } | |||
335 | if (bPBC) | |||
336 | { | |||
337 | rmax2 = 0.99*0.99*max_cutoff2(bXY ? epbcXY : epbcXYZ, box_pbc); | |||
338 | } | |||
339 | else | |||
340 | { | |||
341 | rmax2 = sqr(3*max(box[XX][XX], max(box[YY][YY], box[ZZ][ZZ]))(((box[0][0]) > ((((box[1][1]) > (box[2][2])) ? (box[1] [1]) : (box[2][2]) ))) ? (box[0][0]) : ((((box[1][1]) > (box [2][2])) ? (box[1][1]) : (box[2][2]) )) )); | |||
342 | } | |||
343 | if (debug) | |||
344 | { | |||
345 | fprintf(debug, "rmax2 = %g\n", rmax2); | |||
346 | } | |||
347 | ||||
348 | /* We use the double amount of bins, so we can correctly | |||
349 | * write the rdf and rdf_cn output at i*binwidth values. | |||
350 | */ | |||
351 | nbin = (int)(sqrt(rmax2) * 2 / binwidth); | |||
352 | invhbinw = 2.0 / binwidth; | |||
353 | cut2 = sqr(cutoff); | |||
354 | ||||
355 | snew(count, ng)(count) = save_calloc("count", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 355, (ng), sizeof(*(count))); | |||
356 | snew(pairs, ng)(pairs) = save_calloc("pairs", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 356, (ng), sizeof(*(pairs))); | |||
357 | snew(npairs, ng)(npairs) = save_calloc("npairs", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 357, (ng), sizeof(*(npairs))); | |||
358 | ||||
359 | snew(bExcl, natoms)(bExcl) = save_calloc("bExcl", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 359, (natoms), sizeof(*(bExcl))); | |||
360 | max_i = 0; | |||
361 | for (g = 0; g < ng; g++) | |||
362 | { | |||
363 | if (isize[g+1] > max_i) | |||
364 | { | |||
365 | max_i = isize[g+1]; | |||
366 | } | |||
367 | ||||
368 | /* this is THE array */ | |||
369 | snew(count[g], nbin+1)(count[g]) = save_calloc("count[g]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 369, (nbin+1), sizeof(*(count[g]))); | |||
370 | ||||
371 | /* make pairlist array for groups and exclusions */ | |||
372 | snew(pairs[g], isize[0])(pairs[g]) = save_calloc("pairs[g]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 372, (isize[0]), sizeof(*(pairs[g]))); | |||
373 | snew(npairs[g], isize[0])(npairs[g]) = save_calloc("npairs[g]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 373, (isize[0]), sizeof(*(npairs[g]))); | |||
374 | for (i = 0; i < isize[0]; i++) | |||
375 | { | |||
376 | /* We can only have exclusions with atomic rdfs */ | |||
377 | if (!(bCM || bClose || rdft[0][0] != 'a')) | |||
378 | { | |||
379 | ix = index[0][i]; | |||
380 | for (j = 0; j < natoms; j++) | |||
381 | { | |||
382 | bExcl[j] = FALSE0; | |||
383 | } | |||
384 | /* exclusions? */ | |||
385 | if (excl) | |||
386 | { | |||
387 | for (j = excl->index[ix]; j < excl->index[ix+1]; j++) | |||
388 | { | |||
389 | bExcl[excl->a[j]] = TRUE1; | |||
390 | } | |||
391 | } | |||
392 | k = 0; | |||
393 | snew(pairs[g][i], isize[g+1])(pairs[g][i]) = save_calloc("pairs[g][i]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 393, (isize[g+1]), sizeof(*(pairs[g][i]))); | |||
394 | bNonSelfExcl = FALSE0; | |||
395 | for (j = 0; j < isize[g+1]; j++) | |||
396 | { | |||
397 | jx = index[g+1][j]; | |||
398 | if (!bExcl[jx]) | |||
399 | { | |||
400 | pairs[g][i][k++] = jx; | |||
401 | } | |||
402 | else if (ix != jx) | |||
403 | { | |||
404 | /* Check if we have exclusions other than self exclusions */ | |||
405 | bNonSelfExcl = TRUE1; | |||
406 | } | |||
407 | } | |||
408 | if (bNonSelfExcl) | |||
409 | { | |||
410 | npairs[g][i] = k; | |||
411 | srenew(pairs[g][i], npairs[g][i])(pairs[g][i]) = save_realloc("pairs[g][i]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 411, (pairs[g][i]), (npairs[g][i]), sizeof(*(pairs[g][i]))); | |||
412 | } | |||
413 | else | |||
414 | { | |||
415 | /* Save a LOT of memory and some cpu cycles */ | |||
416 | npairs[g][i] = -1; | |||
417 | sfree(pairs[g][i])save_free("pairs[g][i]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 417, (pairs[g][i])); | |||
418 | } | |||
419 | } | |||
420 | else | |||
421 | { | |||
422 | npairs[g][i] = -1; | |||
423 | } | |||
424 | } | |||
425 | } | |||
426 | sfree(bExcl)save_free("bExcl", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 426, (bExcl)); | |||
427 | ||||
428 | snew(x_i1, max_i)(x_i1) = save_calloc("x_i1", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 428, (max_i), sizeof(*(x_i1))); | |||
429 | nframes = 0; | |||
430 | invvol_sum = 0; | |||
431 | if (bPBC && (NULL((void*)0) != top)) | |||
432 | { | |||
433 | gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms); | |||
434 | } | |||
435 | ||||
436 | do | |||
437 | { | |||
438 | /* Must init pbc every step because of pressure coupling */ | |||
439 | copy_mat(box, box_pbc); | |||
440 | if (bPBC) | |||
441 | { | |||
442 | if (top != NULL((void*)0)) | |||
443 | { | |||
444 | gmx_rmpbc(gpbc, natoms, box, x); | |||
445 | } | |||
446 | if (bXY) | |||
447 | { | |||
448 | check_box_c(box); | |||
449 | clear_rvec(box_pbc[ZZ2]); | |||
450 | } | |||
451 | set_pbc(&pbc, ePBCrdf, box_pbc); | |||
452 | ||||
453 | if (bXY) | |||
454 | { | |||
455 | /* Set z-size to 1 so we get the surface iso the volume */ | |||
456 | box_pbc[ZZ2][ZZ2] = 1; | |||
457 | } | |||
458 | } | |||
459 | invvol = 1/det(box_pbc); | |||
460 | invvol_sum += invvol; | |||
461 | ||||
462 | if (bCM) | |||
463 | { | |||
464 | /* Calculate center of mass of the whole group */ | |||
465 | calc_comg(is[0], coi[0], index[0], TRUE1, atom, x, x0); | |||
466 | } | |||
467 | else if (!bClose && rdft[0][0] != 'a') | |||
468 | { | |||
469 | calc_comg(is[0], coi[0], index[0], rdft[0][6] == 'm', atom, x, x0); | |||
470 | } | |||
471 | ||||
472 | for (g = 0; g < ng; g++) | |||
473 | { | |||
474 | if (rdft[0][0] == 'a') | |||
475 | { | |||
476 | /* Copy the indexed coordinates to a continuous array */ | |||
477 | for (i = 0; i < isize[g+1]; i++) | |||
478 | { | |||
479 | copy_rvec(x[index[g+1][i]], x_i1[i]); | |||
480 | } | |||
481 | } | |||
482 | else | |||
483 | { | |||
484 | /* Calculate the COMs/COGs and store in x_i1 */ | |||
485 | calc_comg(is[g+1], coi[g+1], index[g+1], rdft[0][6] == 'm', atom, x, x_i1); | |||
486 | } | |||
487 | ||||
488 | for (i = 0; i < isize0; i++) | |||
489 | { | |||
490 | if (bClose) | |||
491 | { | |||
492 | /* Special loop, since we need to determine the minimum distance | |||
493 | * over all selected atoms in the reference molecule/residue. | |||
494 | */ | |||
495 | if (rdft[0][0] == 'a') | |||
496 | { | |||
497 | isize_g = isize[g+1]; | |||
498 | } | |||
499 | else | |||
500 | { | |||
501 | isize_g = is[g+1]; | |||
502 | } | |||
503 | for (j = 0; j < isize_g; j++) | |||
504 | { | |||
505 | r2 = 1e30; | |||
506 | /* Loop over the selected atoms in the reference molecule */ | |||
507 | for (ii = coi[0][i]; ii < coi[0][i+1]; ii++) | |||
508 | { | |||
509 | if (bPBC) | |||
510 | { | |||
511 | pbc_dx(&pbc, x[index[0][ii]], x_i1[j], dx); | |||
512 | } | |||
513 | else | |||
514 | { | |||
515 | rvec_sub(x[index[0][ii]], x_i1[j], dx); | |||
516 | } | |||
517 | if (bXY) | |||
518 | { | |||
519 | r2ii = dx[XX0]*dx[XX0] + dx[YY1]*dx[YY1]; | |||
520 | } | |||
521 | else | |||
522 | { | |||
523 | r2ii = iprod(dx, dx); | |||
524 | } | |||
525 | if (r2ii < r2) | |||
526 | { | |||
527 | r2 = r2ii; | |||
528 | } | |||
529 | } | |||
530 | if (r2 > cut2 && r2 <= rmax2) | |||
531 | { | |||
532 | count[g][(int)(sqrt(r2)*invhbinw)]++; | |||
533 | } | |||
534 | } | |||
535 | } | |||
536 | else | |||
537 | { | |||
538 | /* Real rdf between points in space */ | |||
539 | if (bCM || rdft[0][0] != 'a') | |||
540 | { | |||
541 | copy_rvec(x0[i], xi); | |||
542 | } | |||
543 | else | |||
544 | { | |||
545 | copy_rvec(x[index[0][i]], xi); | |||
546 | } | |||
547 | if (rdft[0][0] == 'a' && npairs[g][i] >= 0) | |||
548 | { | |||
549 | /* Expensive loop, because of indexing */ | |||
550 | for (j = 0; j < npairs[g][i]; j++) | |||
551 | { | |||
552 | jx = pairs[g][i][j]; | |||
553 | if (bPBC) | |||
554 | { | |||
555 | pbc_dx(&pbc, xi, x[jx], dx); | |||
556 | } | |||
557 | else | |||
558 | { | |||
559 | rvec_sub(xi, x[jx], dx); | |||
560 | } | |||
561 | ||||
562 | if (bXY) | |||
563 | { | |||
564 | r2 = dx[XX0]*dx[XX0] + dx[YY1]*dx[YY1]; | |||
565 | } | |||
566 | else | |||
567 | { | |||
568 | r2 = iprod(dx, dx); | |||
569 | } | |||
570 | if (r2 > cut2 && r2 <= rmax2) | |||
571 | { | |||
572 | count[g][(int)(sqrt(r2)*invhbinw)]++; | |||
573 | } | |||
574 | } | |||
575 | } | |||
576 | else | |||
577 | { | |||
578 | /* Cheaper loop, no exclusions */ | |||
579 | if (rdft[0][0] == 'a') | |||
580 | { | |||
581 | isize_g = isize[g+1]; | |||
582 | } | |||
583 | else | |||
584 | { | |||
585 | isize_g = is[g+1]; | |||
586 | } | |||
587 | for (j = 0; j < isize_g; j++) | |||
588 | { | |||
589 | if (bPBC) | |||
590 | { | |||
591 | pbc_dx(&pbc, xi, x_i1[j], dx); | |||
592 | } | |||
593 | else | |||
594 | { | |||
595 | rvec_sub(xi, x_i1[j], dx); | |||
596 | } | |||
597 | if (bXY) | |||
598 | { | |||
599 | r2 = dx[XX0]*dx[XX0] + dx[YY1]*dx[YY1]; | |||
600 | } | |||
601 | else | |||
602 | { | |||
603 | r2 = iprod(dx, dx); | |||
604 | } | |||
605 | if (r2 > cut2 && r2 <= rmax2) | |||
606 | { | |||
607 | count[g][(int)(sqrt(r2)*invhbinw)]++; | |||
608 | } | |||
609 | } | |||
610 | } | |||
611 | } | |||
612 | } | |||
613 | } | |||
614 | nframes++; | |||
615 | } | |||
616 | while (read_next_x(oenv, status, &t, x, box)); | |||
617 | fprintf(stderrstderr, "\n"); | |||
618 | ||||
619 | if (bPBC && (NULL((void*)0) != top)) | |||
620 | { | |||
621 | gmx_rmpbc_done(gpbc); | |||
622 | } | |||
623 | ||||
624 | close_trj(status); | |||
625 | ||||
626 | sfree(x)save_free("x", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 626, (x)); | |||
627 | ||||
628 | /* Average volume */ | |||
629 | invvol = invvol_sum/nframes; | |||
630 | ||||
631 | /* Calculate volume of sphere segments or length of circle segments */ | |||
632 | snew(inv_segvol, (nbin+1)/2)(inv_segvol) = save_calloc("inv_segvol", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 632, ((nbin+1)/2), sizeof(*(inv_segvol))); | |||
633 | prev_spherevol = 0; | |||
634 | for (i = 0; (i < (nbin+1)/2); i++) | |||
635 | { | |||
636 | r = (i + 0.5)*binwidth; | |||
637 | if (bXY) | |||
638 | { | |||
639 | spherevol = M_PI3.14159265358979323846*r*r; | |||
640 | } | |||
641 | else | |||
642 | { | |||
643 | spherevol = (4.0/3.0)*M_PI3.14159265358979323846*r*r*r; | |||
644 | } | |||
645 | segvol = spherevol-prev_spherevol; | |||
646 | inv_segvol[i] = 1.0/segvol; | |||
647 | prev_spherevol = spherevol; | |||
648 | } | |||
649 | ||||
650 | snew(rdf, ng)(rdf) = save_calloc("rdf", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 650, (ng), sizeof(*(rdf))); | |||
651 | for (g = 0; g < ng; g++) | |||
652 | { | |||
653 | /* We have to normalize by dividing by the number of frames */ | |||
654 | if (rdft[0][0] == 'a') | |||
655 | { | |||
656 | normfac = 1.0/(nframes*invvol*isize0*isize[g+1]); | |||
657 | } | |||
658 | else | |||
659 | { | |||
660 | normfac = 1.0/(nframes*invvol*isize0*is[g+1]); | |||
661 | } | |||
662 | ||||
663 | /* Do the normalization */ | |||
664 | nrdf = max((nbin+1)/2, 1+2*fade/binwidth)((((nbin+1)/2) > (1+2*fade/binwidth)) ? ((nbin+1)/2) : (1+ 2*fade/binwidth) ); | |||
665 | snew(rdf[g], nrdf)(rdf[g]) = save_calloc("rdf[g]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 665, (nrdf), sizeof(*(rdf[g]))); | |||
666 | for (i = 0; i < (nbin+1)/2; i++) | |||
667 | { | |||
668 | r = i*binwidth; | |||
669 | if (i == 0) | |||
670 | { | |||
671 | j = count[g][0]; | |||
672 | } | |||
673 | else | |||
674 | { | |||
675 | j = count[g][i*2-1] + count[g][i*2]; | |||
676 | } | |||
677 | if ((fade > 0) && (r >= fade)) | |||
678 | { | |||
679 | rdf[g][i] = 1 + (j*inv_segvol[i]*normfac-1)*exp(-16*sqr(r/fade-1)); | |||
680 | } | |||
681 | else | |||
682 | { | |||
683 | if (bNormalize) | |||
684 | { | |||
685 | rdf[g][i] = j*inv_segvol[i]*normfac; | |||
686 | } | |||
687 | else | |||
688 | { | |||
689 | rdf[g][i] = j/(binwidth*isize0*nframes); | |||
690 | } | |||
691 | } | |||
692 | } | |||
693 | for (; (i < nrdf); i++) | |||
694 | { | |||
695 | rdf[g][i] = 1.0; | |||
696 | } | |||
697 | } | |||
698 | ||||
699 | if (rdft[0][0] == 'a') | |||
700 | { | |||
701 | sprintf(gtitle, "Radial distribution"); | |||
702 | } | |||
703 | else | |||
704 | { | |||
705 | sprintf(gtitle, "Radial distribution of %s %s", | |||
706 | rdft[0][0] == 'm' ? "molecule" : "residue", | |||
707 | rdft[0][6] == 'm' ? "COM" : "COG"); | |||
708 | } | |||
709 | fp = xvgropen(fnRDF, gtitle, "r", "", oenv); | |||
710 | if (bCM) | |||
711 | { | |||
712 | sprintf(refgt, " %s", "COM"); | |||
713 | } | |||
714 | else if (bClose) | |||
715 | { | |||
716 | sprintf(refgt, " closest atom in %s.", close); | |||
717 | } | |||
718 | else | |||
719 | { | |||
720 | sprintf(refgt, "%s", ""); | |||
721 | } | |||
722 | if (ng == 1) | |||
723 | { | |||
724 | if (output_env_get_print_xvgr_codes(oenv)) | |||
725 | { | |||
726 | fprintf(fp, "@ subtitle \"%s%s - %s\"\n", grpname[0], refgt, grpname[1]); | |||
727 | } | |||
728 | } | |||
729 | else | |||
730 | { | |||
731 | if (output_env_get_print_xvgr_codes(oenv)) | |||
732 | { | |||
733 | fprintf(fp, "@ subtitle \"reference %s%s\"\n", grpname[0], refgt); | |||
734 | } | |||
735 | xvgr_legend(fp, ng, (const char**)(grpname+1), oenv); | |||
736 | } | |||
737 | for (i = 0; (i < nrdf); i++) | |||
738 | { | |||
739 | fprintf(fp, "%10g", i*binwidth); | |||
740 | for (g = 0; g < ng; g++) | |||
741 | { | |||
742 | fprintf(fp, " %10g", rdf[g][i]); | |||
743 | } | |||
744 | fprintf(fp, "\n"); | |||
745 | } | |||
746 | gmx_ffclose(fp); | |||
747 | ||||
748 | do_view(oenv, fnRDF, NULL((void*)0)); | |||
749 | ||||
750 | /* h(Q) function: fourier transform of rdf */ | |||
751 | if (fnHQ) | |||
752 | { | |||
753 | int nhq = 401; | |||
754 | real *hq, *integrand, Q; | |||
755 | ||||
756 | /* Get a better number density later! */ | |||
757 | rho = isize[1]*invvol; | |||
758 | snew(hq, nhq)(hq) = save_calloc("hq", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 758, (nhq), sizeof(*(hq))); | |||
759 | snew(integrand, nrdf)(integrand) = save_calloc("integrand", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 759, (nrdf), sizeof(*(integrand))); | |||
760 | for (i = 0; (i < nhq); i++) | |||
761 | { | |||
762 | Q = i*0.5; | |||
763 | integrand[0] = 0; | |||
764 | for (j = 1; (j < nrdf); j++) | |||
765 | { | |||
766 | r = j*binwidth; | |||
767 | integrand[j] = (Q == 0) ? 1.0 : sin(Q*r)/(Q*r); | |||
768 | integrand[j] *= 4.0*M_PI3.14159265358979323846*rho*r*r*(rdf[0][j]-1.0); | |||
769 | } | |||
770 | hq[i] = print_and_integrate(debug, nrdf, binwidth, integrand, NULL((void*)0), 0); | |||
771 | } | |||
772 | fp = xvgropen(fnHQ, "h(Q)", "Q(/nm)", "h(Q)", oenv); | |||
773 | for (i = 0; (i < nhq); i++) | |||
774 | { | |||
775 | fprintf(fp, "%10g %10g\n", i*0.5, hq[i]); | |||
776 | } | |||
777 | gmx_ffclose(fp); | |||
778 | do_view(oenv, fnHQ, NULL((void*)0)); | |||
779 | sfree(hq)save_free("hq", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 779, (hq)); | |||
780 | sfree(integrand)save_free("integrand", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 780, (integrand)); | |||
781 | } | |||
782 | ||||
783 | if (fnCNRDF) | |||
784 | { | |||
785 | normfac = 1.0/(isize0*nframes); | |||
786 | fp = xvgropen(fnCNRDF, "Cumulative Number RDF", "r", "number", oenv); | |||
787 | if (ng == 1) | |||
788 | { | |||
789 | if (output_env_get_print_xvgr_codes(oenv)) | |||
790 | { | |||
791 | fprintf(fp, "@ subtitle \"%s-%s\"\n", grpname[0], grpname[1]); | |||
792 | } | |||
793 | } | |||
794 | else | |||
795 | { | |||
796 | if (output_env_get_print_xvgr_codes(oenv)) | |||
797 | { | |||
798 | fprintf(fp, "@ subtitle \"reference %s\"\n", grpname[0]); | |||
799 | } | |||
800 | xvgr_legend(fp, ng, (const char**)(grpname+1), oenv); | |||
801 | } | |||
802 | snew(sum, ng)(sum) = save_calloc("sum", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 802, (ng), sizeof(*(sum))); | |||
803 | for (i = 0; (i <= nbin/2); i++) | |||
804 | { | |||
805 | fprintf(fp, "%10g", i*binwidth); | |||
806 | for (g = 0; g < ng; g++) | |||
807 | { | |||
808 | fprintf(fp, " %10g", (real)((double)sum[g]*normfac)); | |||
809 | if (i*2+1 < nbin) | |||
810 | { | |||
811 | sum[g] += count[g][i*2] + count[g][i*2+1]; | |||
812 | } | |||
813 | } | |||
814 | fprintf(fp, "\n"); | |||
815 | } | |||
816 | gmx_ffclose(fp); | |||
817 | sfree(sum)save_free("sum", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 817, (sum)); | |||
818 | ||||
819 | do_view(oenv, fnCNRDF, NULL((void*)0)); | |||
820 | } | |||
821 | ||||
822 | for (g = 0; g < ng; g++) | |||
823 | { | |||
824 | sfree(rdf[g])save_free("rdf[g]", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 824, (rdf[g])); | |||
825 | } | |||
826 | sfree(rdf)save_free("rdf", "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 826, (rdf)); | |||
827 | } | |||
828 | ||||
829 | ||||
830 | int gmx_rdf(int argc, char *argv[]) | |||
831 | { | |||
832 | const char *desc[] = { | |||
833 | "The structure of liquids can be studied by either neutron or X-ray", | |||
834 | "scattering. The most common way to describe liquid structure is by a", | |||
835 | "radial distribution function. However, this is not easy to obtain from", | |||
836 | "a scattering experiment.[PAR]", | |||
837 | "[THISMODULE] calculates radial distribution functions in different ways.", | |||
838 | "The normal method is around a (set of) particle(s), the other methods", | |||
839 | "are around the center of mass of a set of particles ([TT]-com[tt])", | |||
840 | "or to the closest particle in a set ([TT]-surf[tt]).", | |||
841 | "With all methods, the RDF can also be calculated around axes parallel", | |||
842 | "to the [IT]z[it]-axis with option [TT]-xy[tt].", | |||
843 | "With option [TT]-surf[tt] normalization can not be used.[PAR]", | |||
844 | "The option [TT]-rdf[tt] sets the type of RDF to be computed.", | |||
845 | "Default is for atoms or particles, but one can also select center", | |||
846 | "of mass or geometry of molecules or residues. In all cases, only", | |||
847 | "the atoms in the index groups are taken into account.", | |||
848 | "For molecules and/or the center of mass option, a run input file", | |||
849 | "is required.", | |||
850 | "Weighting other than COM or COG can currently only be achieved", | |||
851 | "by providing a run input file with different masses.", | |||
852 | "Options [TT]-com[tt] and [TT]-surf[tt] also work in conjunction", | |||
853 | "with [TT]-rdf[tt].[PAR]", | |||
854 | "If a run input file is supplied ([TT]-s[tt]) and [TT]-rdf[tt] is set", | |||
855 | "to [TT]atom[tt], exclusions defined", | |||
856 | "in that file are taken into account when calculating the RDF.", | |||
857 | "The option [TT]-cut[tt] is meant as an alternative way to avoid", | |||
858 | "intramolecular peaks in the RDF plot.", | |||
859 | "It is however better to supply a run input file with a higher number of", | |||
860 | "exclusions. For e.g. benzene a topology, setting nrexcl to 5", | |||
861 | "would eliminate all intramolecular contributions to the RDF.", | |||
862 | "Note that all atoms in the selected groups are used, also the ones", | |||
863 | "that don't have Lennard-Jones interactions.[PAR]", | |||
864 | "Option [TT]-cn[tt] produces the cumulative number RDF,", | |||
865 | "i.e. the average number of particles within a distance r.[PAR]" | |||
866 | }; | |||
867 | static gmx_bool bCM = FALSE0, bXY = FALSE0, bPBC = TRUE1, bNormalize = TRUE1; | |||
868 | static real cutoff = 0, binwidth = 0.002, fade = 0.0; | |||
869 | static int ngroups = 1; | |||
870 | ||||
871 | static const char *closet[] = { NULL((void*)0), "no", "mol", "res", NULL((void*)0) }; | |||
872 | static const char *rdft[] = { NULL((void*)0), "atom", "mol_com", "mol_cog", "res_com", "res_cog", NULL((void*)0) }; | |||
873 | ||||
874 | t_pargs pa[] = { | |||
875 | { "-bin", FALSE0, etREAL, {&binwidth}, | |||
876 | "Binwidth (nm)" }, | |||
877 | { "-com", FALSE0, etBOOL, {&bCM}, | |||
878 | "RDF with respect to the center of mass of first group" }, | |||
879 | { "-surf", FALSE0, etENUM, {closet}, | |||
880 | "RDF with respect to the surface of the first group" }, | |||
881 | { "-rdf", FALSE0, etENUM, {rdft}, | |||
882 | "RDF type" }, | |||
883 | { "-pbc", FALSE0, etBOOL, {&bPBC}, | |||
884 | "Use periodic boundary conditions for computing distances. Without PBC the maximum range will be three times the largest box edge." }, | |||
885 | { "-norm", FALSE0, etBOOL, {&bNormalize}, | |||
886 | "Normalize for volume and density" }, | |||
887 | { "-xy", FALSE0, etBOOL, {&bXY}, | |||
888 | "Use only the x and y components of the distance" }, | |||
889 | { "-cut", FALSE0, etREAL, {&cutoff}, | |||
890 | "Shortest distance (nm) to be considered"}, | |||
891 | { "-ng", FALSE0, etINT, {&ngroups}, | |||
892 | "Number of secondary groups to compute RDFs around a central group" }, | |||
893 | { "-fade", FALSE0, etREAL, {&fade}, | |||
894 | "From this distance onwards the RDF is tranformed by g'(r) = 1 + [g(r)-1] exp(-(r/fade-1)^2 to make it go to 1 smoothly. If fade is 0.0 nothing is done." } | |||
895 | }; | |||
896 | #define NPA((int)(sizeof(pa)/sizeof((pa)[0]))) asize(pa)((int)(sizeof(pa)/sizeof((pa)[0]))) | |||
897 | const char *fnTPS, *fnNDX; | |||
898 | output_env_t oenv; | |||
899 | ||||
900 | t_filenm fnm[] = { | |||
901 | { efTRX, "-f", NULL((void*)0), ffREAD1<<1 }, | |||
902 | { efTPS, NULL((void*)0), NULL((void*)0), ffOPTRD(1<<1 | 1<<3) }, | |||
903 | { efNDX, NULL((void*)0), NULL((void*)0), ffOPTRD(1<<1 | 1<<3) }, | |||
904 | { efXVG, "-o", "rdf", ffWRITE1<<2 }, | |||
905 | { efXVG, "-cn", "rdf_cn", ffOPTWR(1<<2| 1<<3) }, | |||
906 | { efXVG, "-hq", "hq", ffOPTWR(1<<2| 1<<3) }, | |||
907 | }; | |||
908 | #define NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))) asize(fnm)((int)(sizeof(fnm)/sizeof((fnm)[0]))) | |||
909 | if (!parse_common_args(&argc, argv, PCA_CAN_VIEW(1<<5) | PCA_CAN_TIME((1<<6) | (1<<7) | (1<<14)) | PCA_BE_NICE(1<<13), | |||
| ||||
910 | NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm, NPA((int)(sizeof(pa)/sizeof((pa)[0]))), pa, asize(desc)((int)(sizeof(desc)/sizeof((desc)[0]))), desc, 0, NULL((void*)0), &oenv)) | |||
911 | { | |||
912 | return 0; | |||
913 | } | |||
914 | ||||
915 | if (bCM || closet[0][0] != 'n' || rdft[0][0] == 'm' || rdft[0][6] == 'm') | |||
| ||||
916 | { | |||
917 | fnTPS = ftp2fn(efTPS, NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm); | |||
918 | } | |||
919 | else | |||
920 | { | |||
921 | fnTPS = ftp2fn_null(efTPS, NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm); | |||
922 | } | |||
923 | fnNDX = ftp2fn_null(efNDX, NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm); | |||
924 | ||||
925 | if (!fnTPS && !fnNDX) | |||
926 | { | |||
927 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 927, "Neither index file nor topology file specified\n" | |||
928 | "Nothing to do!"); | |||
929 | } | |||
930 | ||||
931 | if (closet[0][0] != 'n') | |||
932 | { | |||
933 | if (bCM) | |||
934 | { | |||
935 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxana/gmx_rdf.c" , 935, "Can not have both -com and -surf"); | |||
936 | } | |||
937 | if (bNormalize) | |||
938 | { | |||
939 | fprintf(stderrstderr, "Turning of normalization because of option -surf\n"); | |||
940 | bNormalize = FALSE0; | |||
941 | } | |||
942 | } | |||
943 | ||||
944 | do_rdf(fnNDX, fnTPS, ftp2fn(efTRX, NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm), | |||
945 | opt2fn("-o", NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm), opt2fn_null("-cn", NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm), | |||
946 | opt2fn_null("-hq", NFILE((int)(sizeof(fnm)/sizeof((fnm)[0]))), fnm), | |||
947 | bCM, closet[0], rdft, bXY, bPBC, bNormalize, cutoff, binwidth, fade, ngroups, | |||
948 | oenv); | |||
949 | ||||
950 | return 0; | |||
951 | } |