2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
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.
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.
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.
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.
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.
45 #include "gromacs/commandline/pargs.h"
46 #include "gromacs/commandline/viewit.h"
47 #include "gromacs/fileio/confio.h"
48 #include "gromacs/fileio/matio.h"
49 #include "gromacs/fileio/pdbio.h"
50 #include "gromacs/fileio/tpxio.h"
51 #include "gromacs/fileio/trxio.h"
52 #include "gromacs/fileio/xvgr.h"
53 #include "gromacs/gmxana/gmx_ana.h"
54 #include "gromacs/gmxana/gstat.h"
55 #include "gromacs/listed_forces/disre.h"
56 #include "gromacs/math/do_fit.h"
57 #include "gromacs/math/functions.h"
58 #include "gromacs/math/vec.h"
59 #include "gromacs/mdlib/force.h"
60 #include "gromacs/mdlib/mdatoms.h"
61 #include "gromacs/mdtypes/fcdata.h"
62 #include "gromacs/mdtypes/inputrec.h"
63 #include "gromacs/mdtypes/md_enums.h"
64 #include "gromacs/pbcutil/ishift.h"
65 #include "gromacs/pbcutil/mshift.h"
66 #include "gromacs/pbcutil/pbc.h"
67 #include "gromacs/pbcutil/rmpbc.h"
68 #include "gromacs/topology/index.h"
69 #include "gromacs/topology/mtop_util.h"
70 #include "gromacs/topology/topology.h"
71 #include "gromacs/trajectoryanalysis/topologyinformation.h"
72 #include "gromacs/utility/arraysize.h"
73 #include "gromacs/utility/fatalerror.h"
74 #include "gromacs/utility/futil.h"
75 #include "gromacs/utility/smalloc.h"
82 static t_toppop
*top
= nullptr;
87 real sumv
, averv
, maxv
;
88 real
*aver1
, *aver2
, *aver_3
, *aver_6
;
91 static void init5(int n
)
101 for (i
= 0; (i
< ntop
); i
++)
108 static void add5(int ndr
, real viol
)
113 for (i
= 1; (i
< ntop
); i
++)
115 if (top
[i
].v
< top
[mini
].v
)
120 if (viol
> top
[mini
].v
)
127 static void print5(FILE *fp
)
131 std::sort(top
, top
+ntop
, [](const t_toppop
&a
, const t_toppop
&b
) {return a
.v
> b
.v
; }); //reverse sort
132 fprintf(fp
, "Index:");
133 for (i
= 0; (i
< ntop
); i
++)
135 fprintf(fp
, " %6d", top
[i
].n
);
137 fprintf(fp
, "\nViol: ");
138 for (i
= 0; (i
< ntop
); i
++)
140 fprintf(fp
, " %6.3f", top
[i
].v
);
145 static void check_viol(FILE *log
,
146 t_ilist
*disres
, t_iparams forceparams
[],
148 t_pbc
*pbc
, t_graph
*g
, t_dr_result dr
[],
149 int clust_id
, int isize
, const int index
[], real vvindex
[],
153 int i
, j
, nat
, n
, type
, nviol
, ndr
, label
;
154 real rt
, mviol
, tviol
, viol
, lam
, dvdl
, drt
;
156 static gmx_bool bFirst
= TRUE
;
168 forceatoms
= disres
->iatoms
;
169 for (j
= 0; (j
< isize
); j
++)
173 nat
= interaction_function
[F_DISRES
].nratoms
+1;
174 for (i
= 0; (i
< disres
->nr
); )
176 type
= forceatoms
[i
];
178 label
= forceparams
[type
].disres
.label
;
181 fprintf(debug
, "DISRE: ndr = %d, label = %d i=%d, n =%d\n",
186 gmx_fatal(FARGS
, "tpr inconsistency. ndr = %d, label = %d\n", ndr
, label
);
192 while (((i
+n
) < disres
->nr
) &&
193 (forceparams
[forceatoms
[i
+n
]].disres
.label
== label
));
195 calc_disres_R_6(nullptr, nullptr, n
, &forceatoms
[i
],
196 x
, pbc
, fcd
, nullptr);
198 if (fcd
->disres
.Rt_6
[label
] <= 0)
200 gmx_fatal(FARGS
, "ndr = %d, rt_6 = %f", ndr
, fcd
->disres
.Rt_6
[label
]);
203 rt
= gmx::invsixthroot(fcd
->disres
.Rt_6
[label
]);
204 dr
[clust_id
].aver1
[ndr
] += rt
;
205 dr
[clust_id
].aver2
[ndr
] += gmx::square(rt
);
206 drt
= 1.0/gmx::power3(rt
);
207 dr
[clust_id
].aver_3
[ndr
] += drt
;
208 dr
[clust_id
].aver_6
[ndr
] += fcd
->disres
.Rt_6
[label
];
210 snew(fshift
, SHIFTS
);
211 ta_disres(n
, &forceatoms
[i
], forceparams
,
213 pbc
, g
, lam
, &dvdl
, nullptr, fcd
, nullptr);
215 viol
= fcd
->disres
.sumviol
;
222 add5(forceparams
[type
].disres
.label
, viol
);
229 for (j
= 0; (j
< isize
); j
++)
231 if (index
[j
] == forceparams
[type
].disres
.label
)
233 vvindex
[j
] = gmx::invsixthroot(fcd
->disres
.Rt_6
[label
]);
240 dr
[clust_id
].nv
= nviol
;
241 dr
[clust_id
].maxv
= mviol
;
242 dr
[clust_id
].sumv
= tviol
;
243 dr
[clust_id
].averv
= tviol
/ndr
;
244 dr
[clust_id
].nframes
++;
248 fprintf(stderr
, "\nThere are %d restraints and %d pairs\n",
249 ndr
, disres
->nr
/nat
);
261 real up1
, r
, rT3
, rT6
, viol
, violT3
, violT6
;
264 static void dump_dump(FILE *log
, int ndr
, t_dr_stats drs
[])
266 static const char *core
[] = { "All restraints", "Core restraints" };
267 static const char *tp
[] = { "linear", "third power", "sixth power" };
268 real viol_tot
, viol_max
, viol
= 0;
273 for (int iCore
= 0; iCore
< 2; iCore
++)
275 bCore
= (iCore
== 1);
276 for (kkk
= 0; (kkk
< 3); kkk
++)
282 for (i
= 0; (i
< ndr
); i
++)
284 if (!bCore
|| drs
[i
].bCore
)
292 viol
= drs
[i
].violT3
;
295 viol
= drs
[i
].violT6
;
298 gmx_incons("Dumping violations");
300 viol_max
= std::max(viol_max
, viol
);
309 if ((nrestr
> 0) || (bCore
&& (nrestr
< ndr
)))
312 fprintf(log
, "+++++++ %s ++++++++\n", core
[bCore
]);
313 fprintf(log
, "+++++++ Using %s averaging: ++++++++\n", tp
[kkk
]);
314 fprintf(log
, "Sum of violations: %8.3f nm\n", viol_tot
);
317 fprintf(log
, "Average violation: %8.3f nm\n", viol_tot
/nrestr
);
319 fprintf(log
, "Largest violation: %8.3f nm\n", viol_max
);
320 fprintf(log
, "Number of violated restraints: %d/%d\n", nviol
, nrestr
);
326 static void dump_viol(FILE *log
, int ndr
, t_dr_stats
*drs
, gmx_bool bLinear
)
330 fprintf(log
, "Restr. Core Up1 <r> <rT3> <rT6> <viol><violT3><violT6>\n");
331 for (i
= 0; (i
< ndr
); i
++)
333 if (bLinear
&& (drs
[i
].viol
== 0))
337 fprintf(log
, "%6d%5s%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f\n",
338 drs
[i
].index
, yesno_names
[drs
[i
].bCore
],
339 drs
[i
].up1
, drs
[i
].r
, drs
[i
].rT3
, drs
[i
].rT6
,
340 drs
[i
].viol
, drs
[i
].violT3
, drs
[i
].violT6
);
344 static gmx_bool
is_core(int i
, int isize
, const int index
[])
347 gmx_bool bIC
= FALSE
;
349 for (kk
= 0; !bIC
&& (kk
< isize
); kk
++)
351 bIC
= (index
[kk
] == i
);
357 static void dump_stats(FILE *log
, int nsteps
, int ndr
, t_ilist
*disres
,
358 t_iparams ip
[], t_dr_result
*dr
,
359 int isize
, int index
[], t_atoms
*atoms
)
365 fprintf(log
, "++++++++++++++ STATISTICS ++++++++++++++++++++++++\n");
368 nra
= interaction_function
[F_DISRES
].nratoms
+1;
369 for (i
= 0; (i
< ndr
); i
++)
371 /* Search for the appropriate restraint */
372 for (; (j
< disres
->nr
); j
+= nra
)
374 if (ip
[disres
->iatoms
[j
]].disres
.label
== i
)
380 drs
[i
].bCore
= is_core(i
, isize
, index
);
381 drs
[i
].up1
= ip
[disres
->iatoms
[j
]].disres
.up1
;
382 drs
[i
].r
= dr
->aver1
[i
]/nsteps
;
383 drs
[i
].rT3
= gmx::invcbrt(dr
->aver_3
[i
]/nsteps
);
384 drs
[i
].rT6
= gmx::invsixthroot(dr
->aver_6
[i
]/nsteps
);
385 drs
[i
].viol
= std::max(0.0, static_cast<double>(drs
[i
].r
-drs
[i
].up1
));
386 drs
[i
].violT3
= std::max(0.0, static_cast<double>(drs
[i
].rT3
-drs
[i
].up1
));
387 drs
[i
].violT6
= std::max(0.0, static_cast<double>(drs
[i
].rT6
-drs
[i
].up1
));
390 int j1
= disres
->iatoms
[j
+1];
391 int j2
= disres
->iatoms
[j
+2];
392 atoms
->pdbinfo
[j1
].bfac
+= drs
[i
].violT3
*5;
393 atoms
->pdbinfo
[j2
].bfac
+= drs
[i
].violT3
*5;
396 dump_viol(log
, ndr
, drs
, FALSE
);
398 fprintf(log
, "+++ Sorted by linear averaged violations: +++\n");
399 std::sort(drs
, drs
+ndr
, [](const t_dr_stats
&a
, const t_dr_stats
&b
)
400 {return a
.viol
> b
.viol
; }); //Reverse sort
401 dump_viol(log
, ndr
, drs
, TRUE
);
403 dump_dump(log
, ndr
, drs
);
408 static void dump_clust_stats(FILE *fp
, int ndr
, t_ilist
*disres
,
409 t_iparams ip
[], t_blocka
*clust
, t_dr_result dr
[],
410 char *clust_name
[], int isize
, int index
[])
412 int i
, j
, k
, nra
, mmm
= 0;
413 double sumV
, maxV
, sumVT3
, sumVT6
, maxVT3
, maxVT6
;
417 fprintf(fp
, "++++++++++++++ STATISTICS ++++++++++++++++++++++\n");
418 fprintf(fp
, "Cluster NFrames SumV MaxV SumVT MaxVT SumVS MaxVS\n");
422 for (k
= 0; (k
< clust
->nr
); k
++)
424 if (dr
[k
].nframes
== 0)
428 if (dr
[k
].nframes
!= (clust
->index
[k
+1]-clust
->index
[k
]))
430 gmx_fatal(FARGS
, "Inconsistency in cluster %s.\n"
431 "Found %d frames in trajectory rather than the expected %d\n",
432 clust_name
[k
], dr
[k
].nframes
,
433 clust
->index
[k
+1]-clust
->index
[k
]);
437 gmx_fatal(FARGS
, "Inconsistency with cluster %d. Invalid name", k
);
440 nra
= interaction_function
[F_DISRES
].nratoms
+1;
441 sumV
= sumVT3
= sumVT6
= maxV
= maxVT3
= maxVT6
= 0;
442 for (i
= 0; (i
< ndr
); i
++)
444 /* Search for the appropriate restraint */
445 for (; (j
< disres
->nr
); j
+= nra
)
447 if (ip
[disres
->iatoms
[j
]].disres
.label
== i
)
453 drs
[i
].bCore
= is_core(i
, isize
, index
);
454 drs
[i
].up1
= ip
[disres
->iatoms
[j
]].disres
.up1
;
455 drs
[i
].r
= dr
[k
].aver1
[i
]/dr
[k
].nframes
;
456 if ((dr
[k
].aver_3
[i
] <= 0) || !std::isfinite(dr
[k
].aver_3
[i
]))
458 gmx_fatal(FARGS
, "dr[%d].aver_3[%d] = %f", k
, i
, dr
[k
].aver_3
[i
]);
460 drs
[i
].rT3
= gmx::invcbrt(dr
[k
].aver_3
[i
]/dr
[k
].nframes
);
461 drs
[i
].rT6
= gmx::invsixthroot(dr
[k
].aver_6
[i
]/dr
[k
].nframes
);
462 drs
[i
].viol
= std::max(0.0, static_cast<double>(drs
[i
].r
-drs
[i
].up1
));
463 drs
[i
].violT3
= std::max(0.0, static_cast<double>(drs
[i
].rT3
-drs
[i
].up1
));
464 drs
[i
].violT6
= std::max(0.0, static_cast<double>(drs
[i
].rT6
-drs
[i
].up1
));
466 sumVT3
+= drs
[i
].violT3
;
467 sumVT6
+= drs
[i
].violT6
;
468 maxV
= std::max(maxV
, static_cast<double>(drs
[i
].viol
));
469 maxVT3
= std::max(maxVT3
, static_cast<double>(drs
[i
].violT3
));
470 maxVT6
= std::max(maxVT6
, static_cast<double>(drs
[i
].violT6
));
472 if (std::strcmp(clust_name
[k
], "1000") == 0)
476 fprintf(fp
, "%-10s%6d%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
478 dr
[k
].nframes
, sumV
, maxV
, sumVT3
, maxVT3
, sumVT6
, maxVT6
);
485 static void init_dr_res(t_dr_result
*dr
, int ndr
)
487 snew(dr
->aver1
, ndr
+1);
488 snew(dr
->aver2
, ndr
+1);
489 snew(dr
->aver_3
, ndr
+1);
490 snew(dr
->aver_6
, ndr
+1);
498 static void dump_disre_matrix(const char *fn
, t_dr_result
*dr
, int ndr
,
499 int nsteps
, t_idef
*idef
, const gmx_mtop_t
*mtop
,
500 real max_dr
, int nlevels
, gmx_bool bThird
)
504 int n_res
, a_offset
, mol
, a
;
505 int i
, j
, nra
, nratoms
, tp
, ri
, rj
, index
, nlabel
, label
;
507 real
**matrix
, *t_res
, hi
, *w_dr
, rav
, rviol
;
508 t_rgb rlo
= { 1, 1, 1 };
509 t_rgb rhi
= { 0, 0, 0 };
515 snew(resnr
, mtop
->natoms
);
518 for (const gmx_molblock_t
&molb
: mtop
->molblock
)
520 const t_atoms
&atoms
= mtop
->moltype
[molb
.type
].atoms
;
521 for (mol
= 0; mol
< molb
.nmol
; mol
++)
523 for (a
= 0; a
< atoms
.nr
; a
++)
525 resnr
[a_offset
+ a
] = n_res
+ atoms
.atom
[a
].resind
;
528 a_offset
+= atoms
.nr
;
533 for (i
= 0; (i
< n_res
); i
++)
538 for (i
= 0; (i
< n_res
); i
++)
540 snew(matrix
[i
], n_res
);
542 nratoms
= interaction_function
[F_DISRES
].nratoms
;
543 nra
= (idef
->il
[F_DISRES
].nr
/(nratoms
+1));
549 for (i
= 0; (i
< idef
->il
[F_DISRES
].nr
); i
+= nratoms
+1)
551 tp
= idef
->il
[F_DISRES
].iatoms
[i
];
552 label
= idef
->iparams
[tp
].disres
.label
;
556 /* Set index pointer */
560 gmx_fatal(FARGS
, "nlabel is %d, label = %d", nlabel
, label
);
564 gmx_fatal(FARGS
, "ndr = %d, index = %d", ndr
, index
);
566 /* Update the weight */
567 w_dr
[index
] = 1.0/nlabel
;
576 printf("nlabel = %d, index = %d, ndr = %d\n", nlabel
, index
, ndr
);
578 for (i
= 0; (i
< ndr
); i
++)
580 for (j
= ptr
[i
]; (j
< ptr
[i
+1]); j
+= nratoms
+1)
582 tp
= idef
->il
[F_DISRES
].iatoms
[j
];
583 ai
= idef
->il
[F_DISRES
].iatoms
[j
+1];
584 aj
= idef
->il
[F_DISRES
].iatoms
[j
+2];
590 rav
= gmx::invcbrt(dr
->aver_3
[i
]/nsteps
);
594 rav
= dr
->aver1
[i
]/nsteps
;
598 fprintf(debug
, "DR %d, atoms %d, %d, distance %g\n", i
, ai
, aj
, rav
);
600 rviol
= std::max(0.0_real
, rav
-idef
->iparams
[tp
].disres
.up1
);
601 matrix
[ri
][rj
] += w_dr
[i
]*rviol
;
602 matrix
[rj
][ri
] += w_dr
[i
]*rviol
;
603 hi
= std::max(hi
, matrix
[ri
][rj
]);
604 hi
= std::max(hi
, matrix
[rj
][ri
]);
614 printf("Warning: the maxdr that you have specified (%g) is smaller than\nthe largest value in your simulation (%g)\n", max_dr
, hi
);
618 printf("Highest level in the matrix will be %g\n", hi
);
619 fp
= gmx_ffopen(fn
, "w");
620 write_xpm(fp
, 0, "Distance Violations", "<V> (nm)", "Residue", "Residue",
621 n_res
, n_res
, t_res
, t_res
, matrix
, 0, hi
, rlo
, rhi
, &nlevels
);
625 int gmx_disre(int argc
, char *argv
[])
627 const char *desc
[] = {
628 "[THISMODULE] computes violations of distance restraints.",
629 "The program always",
630 "computes the instantaneous violations rather than time-averaged,",
631 "because this analysis is done from a trajectory file afterwards",
632 "it does not make sense to use time averaging. However,",
633 "the time averaged values per restraint are given in the log file.[PAR]",
634 "An index file may be used to select specific restraints for",
636 "When the optional [TT]-q[tt] flag is given a [REF].pdb[ref] file coloured by the",
637 "amount of average violations.[PAR]",
638 "When the [TT]-c[tt] option is given, an index file will be read",
639 "containing the frames in your trajectory corresponding to the clusters",
640 "(defined in another manner) that you want to analyze. For these clusters",
641 "the program will compute average violations using the third power",
642 "averaging algorithm and print them in the log file."
645 static int nlevels
= 20;
646 static real max_dr
= 0;
647 static gmx_bool bThird
= TRUE
;
649 { "-ntop", FALSE
, etINT
, {&ntop
},
650 "Number of large violations that are stored in the log file every step" },
651 { "-maxdr", FALSE
, etREAL
, {&max_dr
},
652 "Maximum distance violation in matrix output. If less than or equal to 0 the maximum will be determined by the data." },
653 { "-nlevels", FALSE
, etINT
, {&nlevels
},
654 "Number of levels in the matrix output" },
655 { "-third", FALSE
, etBOOL
, {&bThird
},
656 "Use inverse third power averaging or linear for matrix output" }
659 FILE *out
= nullptr, *aver
= nullptr, *numv
= nullptr, *maxxv
= nullptr, *xvg
= nullptr;
666 rvec
*x
, *xav
= nullptr;
671 int *index
= nullptr, *ind_fit
= nullptr;
673 t_cluster_ndx
*clust
= nullptr;
674 t_dr_result dr
, *dr_clust
= nullptr;
676 real
*vvindex
= nullptr, *w_rls
= nullptr;
677 t_pbc pbc
, *pbc_null
;
680 gmx_output_env_t
*oenv
;
681 gmx_rmpbc_t gpbc
= nullptr;
684 { efTPR
, nullptr, nullptr, ffREAD
},
685 { efTRX
, "-f", nullptr, ffREAD
},
686 { efXVG
, "-ds", "drsum", ffWRITE
},
687 { efXVG
, "-da", "draver", ffWRITE
},
688 { efXVG
, "-dn", "drnum", ffWRITE
},
689 { efXVG
, "-dm", "drmax", ffWRITE
},
690 { efXVG
, "-dr", "restr", ffWRITE
},
691 { efLOG
, "-l", "disres", ffWRITE
},
692 { efNDX
, nullptr, "viol", ffOPTRD
},
693 { efPDB
, "-q", "viol", ffOPTWR
},
694 { efNDX
, "-c", "clust", ffOPTRD
},
695 { efXPM
, "-x", "matrix", ffOPTWR
}
697 #define NFILE asize(fnm)
699 if (!parse_common_args(&argc
, argv
, PCA_CAN_TIME
| PCA_CAN_VIEW
,
700 NFILE
, fnm
, asize(pa
), pa
, asize(desc
), desc
, 0, nullptr, &oenv
))
705 fplog
= ftp2FILE(efLOG
, NFILE
, fnm
, "w");
712 t_inputrec irInstance
;
713 t_inputrec
*ir
= &irInstance
;
715 gmx::TopologyInformation topInfo
;
716 topInfo
.fillFromInputFile(ftp2fn(efTPR
, NFILE
, fnm
));
717 int ntopatoms
= topInfo
.mtop()->natoms
;
719 bPDB
= opt2bSet("-q", NFILE
, fnm
);
722 snew(xav
, ntopatoms
);
723 snew(ind_fit
, ntopatoms
);
724 snew(w_rls
, ntopatoms
);
725 for (kkk
= 0; (kkk
< ntopatoms
); kkk
++)
731 atoms
= topInfo
.copyAtoms();
733 if (atoms
->pdbinfo
== nullptr)
735 snew(atoms
->pdbinfo
, atoms
->nr
);
737 atoms
->havePdbInfo
= TRUE
;
740 gmx_mtop_generate_local_top(*topInfo
.mtop(), &top
, ir
->efep
!= efepNO
);
744 if (ir
->ePBC
!= epbcNONE
)
746 if (ir
->bPeriodicMols
)
752 g
= mk_graph(fplog
, &top
.idef
, 0, ntopatoms
, FALSE
, FALSE
);
756 if (ftp2bSet(efNDX
, NFILE
, fnm
))
758 /* TODO: Nothing is written to this file if -c is provided, but it is
760 rd_index(ftp2fn(efNDX
, NFILE
, fnm
), 1, &isize
, &index
, &grpname
);
761 xvg
= xvgropen(opt2fn("-dr", NFILE
, fnm
), "Individual Restraints", "Time (ps)",
763 snew(vvindex
, isize
);
765 for (i
= 0; (i
< isize
); i
++)
769 sprintf(leg
[i
], "index %d", index
[i
]);
771 xvgr_legend(xvg
, isize
, leg
, oenv
);
779 init_disres(fplog
, topInfo
.mtop(), ir
, nullptr, nullptr, &fcd
, nullptr, FALSE
);
781 int natoms
= read_first_x(oenv
, &status
, ftp2fn(efTRX
, NFILE
, fnm
), &t
, &x
, box
);
784 init_dr_res(&dr
, fcd
.disres
.nres
);
785 if (opt2bSet("-c", NFILE
, fnm
))
787 clust
= cluster_index(fplog
, opt2fn("-c", NFILE
, fnm
));
788 snew(dr_clust
, clust
->clust
->nr
+1);
789 for (i
= 0; (i
<= clust
->clust
->nr
); i
++)
791 init_dr_res(&dr_clust
[i
], fcd
.disres
.nres
);
796 out
= xvgropen(opt2fn("-ds", NFILE
, fnm
),
797 "Sum of Violations", "Time (ps)", "nm", oenv
);
798 aver
= xvgropen(opt2fn("-da", NFILE
, fnm
),
799 "Average Violation", "Time (ps)", "nm", oenv
);
800 numv
= xvgropen(opt2fn("-dn", NFILE
, fnm
),
801 "# Violations", "Time (ps)", "#", oenv
);
802 maxxv
= xvgropen(opt2fn("-dm", NFILE
, fnm
),
803 "Largest Violation", "Time (ps)", "nm", oenv
);
806 auto mdAtoms
= gmx::makeMDAtoms(fplog
, *topInfo
.mtop(), *ir
, false);
807 atoms2md(topInfo
.mtop(), ir
, -1, nullptr, ntopatoms
, mdAtoms
.get());
808 update_mdatoms(mdAtoms
->mdatoms(), ir
->fepvals
->init_lambda
);
809 if (ir
->ePBC
!= epbcNONE
)
811 gpbc
= gmx_rmpbc_init(&top
.idef
, ir
->ePBC
, natoms
);
817 if (ir
->ePBC
!= epbcNONE
)
819 if (ir
->bPeriodicMols
)
821 set_pbc(&pbc
, ir
->ePBC
, box
);
825 gmx_rmpbc(gpbc
, natoms
, box
, x
);
831 if (j
> clust
->maxframe
)
833 gmx_fatal(FARGS
, "There are more frames in the trajectory than in the cluster index file. t = %8f\n", t
);
835 my_clust
= clust
->inv_clust
[j
];
836 range_check(my_clust
, 0, clust
->clust
->nr
);
837 check_viol(fplog
, &(top
.idef
.il
[F_DISRES
]),
839 x
, f
, pbc_null
, g
, dr_clust
, my_clust
, isize
, index
, vvindex
, &fcd
);
843 check_viol(fplog
, &(top
.idef
.il
[F_DISRES
]),
845 x
, f
, pbc_null
, g
, &dr
, 0, isize
, index
, vvindex
, &fcd
);
849 reset_x(atoms
->nr
, ind_fit
, atoms
->nr
, nullptr, x
, w_rls
);
850 do_fit(atoms
->nr
, w_rls
, x
, x
);
853 /* Store the first frame of the trajectory as 'characteristic'
854 * for colouring with violations.
856 for (kkk
= 0; (kkk
< atoms
->nr
); kkk
++)
858 copy_rvec(x
[kkk
], xav
[kkk
]);
866 fprintf(xvg
, "%10g", t
);
867 for (i
= 0; (i
< isize
); i
++)
869 fprintf(xvg
, " %10g", vvindex
[i
]);
873 fprintf(out
, "%10g %10g\n", t
, dr
.sumv
);
874 fprintf(aver
, "%10g %10g\n", t
, dr
.averv
);
875 fprintf(maxxv
, "%10g %10g\n", t
, dr
.maxv
);
876 fprintf(numv
, "%10g %10d\n", t
, dr
.nv
);
880 while (read_next_x(oenv
, status
, &t
, x
, box
));
882 if (ir
->ePBC
!= epbcNONE
)
884 gmx_rmpbc_done(gpbc
);
889 dump_clust_stats(fplog
, fcd
.disres
.nres
, &(top
.idef
.il
[F_DISRES
]),
890 top
.idef
.iparams
, clust
->clust
, dr_clust
,
891 clust
->grpname
, isize
, index
);
895 dump_stats(fplog
, j
, fcd
.disres
.nres
, &(top
.idef
.il
[F_DISRES
]),
896 top
.idef
.iparams
, &dr
, isize
, index
,
897 bPDB
? atoms
.get() : nullptr);
900 write_sto_conf(opt2fn("-q", NFILE
, fnm
),
901 "Coloured by average violation in Angstrom",
902 atoms
.get(), xav
, nullptr, ir
->ePBC
, box
);
904 dump_disre_matrix(opt2fn_null("-x", NFILE
, fnm
), &dr
, fcd
.disres
.nres
,
905 j
, &top
.idef
, topInfo
.mtop(), max_dr
, nlevels
, bThird
);
910 do_view(oenv
, opt2fn("-dn", NFILE
, fnm
), "-nxy");
911 do_view(oenv
, opt2fn("-da", NFILE
, fnm
), "-nxy");
912 do_view(oenv
, opt2fn("-ds", NFILE
, fnm
), "-nxy");
913 do_view(oenv
, opt2fn("-dm", NFILE
, fnm
), "-nxy");
920 do_view(oenv
, opt2fn("-dr", NFILE
, fnm
), "-nxy");