2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 * Implements gmx::analysismodules::Freevolume.
39 * \author Titov Anatoly <Wapuk-cobaka@yandex.ru>
40 * \ingroup module_trajectoryanalysis
50 #include <gromacs/trajectoryanalysis.h>
51 #include <gromacs/pbcutil/pbc.h>
52 #include <gromacs/pbcutil/rmpbc.h>
53 #include <gromacs/utility/smalloc.h>
54 #include <gromacs/math/vectypes.h>
55 #include <gromacs/math/vec.h>
56 #include <gromacs/math/do_fit.h>
58 #include "gromacs/analysisdata/analysisdata.h"
59 #include "gromacs/analysisdata/modules/average.h"
60 #include "gromacs/analysisdata/modules/histogram.h"
61 #include "gromacs/analysisdata/modules/plot.h"
62 #include "gromacs/math/vec.h"
63 #include "gromacs/options/basicoptions.h"
64 #include "gromacs/options/filenameoption.h"
65 #include "gromacs/options/ioptionscontainer.h"
66 #include "gromacs/pbcutil/pbc.h"
67 #include "gromacs/selection/selection.h"
68 #include "gromacs/selection/selectionoption.h"
69 #include "gromacs/trajectory/trajectoryframe.h"
70 #include "gromacs/trajectoryanalysis/analysissettings.h"
71 #include "gromacs/utility/arrayref.h"
72 #include "gromacs/utility/exceptions.h"
73 #include "gromacs/utility/stringutil.h"
79 void make_pdb_trajectory(std::vector< std::vector< RVec > > trajectory, const char* file_name)
82 file = std::fopen(file_name, "w+");
83 for (int i = 1; i < trajectory.size(); i++) {
84 std::fprintf(file, "MODEL%9d\n", i);
85 for (int j = 0; j < trajectory[i].size(); j++) {
86 std::fprintf(file, "ATOM %5d CA LYS 1 %8.3f%8.3f%8.3f 1.00 0.00\n", j, trajectory[i][j][0] * 10, trajectory[i][j][1] * 10, trajectory[i][j][2] * 10);
88 std::fprintf(file, "ENDMDL\n");
92 1 - 6 Record name "ATOM "
93 7 - 11 Integer Atom serial number.
94 13 - 16 Atom Atom name.
95 17 Character Alternate location indicator.
96 18 - 20 Residue name Residue name.
97 22 Character Chain identifier.
98 23 - 26 Integer Residue sequence number.
99 27 AChar Code for insertion of residues.
100 31 - 38 Real(8.3) Orthogonal coordinates for X in Angstroms.
101 39 - 46 Real(8.3) Orthogonal coordinates for Y in Angstroms.
102 47 - 54 Real(8.3) Orthogonal coordinates for Z in Angstroms.
103 55 - 60 Real(6.2) Occupancy.
104 61 - 66 Real(6.2) Temperature factor (Default = 0.0).
105 73 - 76 LString(4) Segment identifier, left-justified.
106 77 - 78 LString(2) Element symbol, right-justified.
107 79 - 80 LString(2) Charge on the atom.
110 void make_correlation_file(std::vector< std::vector< std::vector< double > > > correlations, const char* file_name, int start)
113 file = std::fopen(file_name, "w+");
114 for (int i = start; i < correlations.size(); i++) {
115 if (correlations.size() - start > 1) {
116 std::fprintf(file, "correlation between 'n' and 'n + %d' frames\n", i);
119 std::cout << "correlation between 'n' and 'n + " << i << "' frames\n";
121 for (int j = 0; j < correlations[i].size(); j++) {
122 for (int f = 0; f < correlations[i][j].size(); f++) {
123 std::fprintf(file, "%3.2f ", correlations[i][j][f]);
125 std::fprintf(file, "\n");
131 void make_rout_file(double crl_border, std::vector< int > indx, std::vector< std::vector< int > > rout, const char* file_name)
134 file = std::fopen(file_name, "w+");
135 std::fprintf(file, "correlations >= %0.2f\n", crl_border);
136 for (int i = 0; i < rout.size(); i++) {
137 for (int j = 0; j < rout[i].size(); j++) {
138 std::fprintf(file, "%3d ", indx[rout[i][j]] + 1);
140 std::fprintf(file, "\n");
145 int dive_in(std::vector< std::vector< std::pair< int, int > > > graph, int start, int steps, int frames, int depth, int depth_go, std::vector< std::pair< int, int > > path)
147 int steps_old = 0, steps_new = 0;
148 if (depth > frames) {
152 for (int i = 0; i < path.size(); i++) {
153 if (path[i].first == start) {
158 path.push_back(std::make_pair(start, depth_go));
160 for (int i = 0; i < graph[start].size(); i++) {
162 for (int j = 0; j < path.size(); j++) {
163 if (path[j].first == graph[start][i].first) {
168 steps_new = dive_in(graph, graph[start][i].first, steps + 1, frames, depth + graph[start][i].second, graph[start][i].second, path);
169 if (steps_old < steps_new) {
170 steps_old = steps_new;
174 return (std::max(steps_old, steps));
177 bool mysortfunc (std::vector<int> a, std::vector<int> b) { return (a.size() > b.size()); }
180 * Class used to compute free volume in a simulations box.
182 * Inherits TrajectoryAnalysisModule and all functions from there.
183 * Does not implement any new functionality.
185 * \ingroup module_trajectoryanalysis
189 class Domains : public TrajectoryAnalysisModule
196 //! Set the options and setting
197 virtual void initOptions(IOptionsContainer *options,
198 TrajectoryAnalysisSettings *settings);
200 //! First routine called by the analysis framework
201 // virtual void initAnalysis(const t_trxframe &fr, t_pbc *pbc);
202 virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
203 const TopologyInformation &top);
205 virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
206 const t_trxframe &fr);
208 //! Call for each frame of the trajectory
209 // virtual void analyzeFrame(const t_trxframe &fr, t_pbc *pbc);
210 virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
211 TrajectoryAnalysisModuleData *pdata);
213 //! Last routine called by the analysis framework
214 // virtual void finishAnalysis(t_pbc *pbc);
215 virtual void finishAnalysis(int nframes);
217 //! Routine to write output, that is additional over the built-in
218 virtual void writeOutput();
225 std::vector< std::vector< int > > domains;
226 std::vector< std::vector< int > > domains_local;
227 std::vector< std::vector< RVec > > trajectory;
228 std::vector< std::vector< RVec > > frankenstein_trajectory;
231 std::vector< int > index;
232 std::vector< int > numbers;
236 double crl_border = 0;
240 // Copy and assign disallowed by base.
243 Domains::Domains(): TrajectoryAnalysisModule()
252 Domains::initOptions(IOptionsContainer *options,
253 TrajectoryAnalysisSettings *settings)
255 static const char *const desc[] = {
256 "[THISMODULE] to be done"
258 // Add the descriptive text (program help text) to the options
259 settings->setHelpText(desc);
260 // Add option for output file name
261 options->addOption(FileNameOption("on").filetype(eftIndex).outputFile()
262 .store(&fnNdx_).defaultBasename("domains")
263 .description("Index file from the domains"));
264 // Add option for tau constant
265 options->addOption(gmx::IntegerOption("tau")
267 .description("number of frames for time travel"));
268 // Add option for crl_border constant
269 options->addOption(DoubleOption("crl")
271 .description("make graph based on corrs > constant"));
272 // Add option for selection list
273 options->addOption(SelectionOption("select_domains_and_residue").storeVector(&sel_)
274 .required().dynamicMask().multiValue()
275 .description("Domains to form rigid skeleton"));
276 // Control input settings
277 settings->setFlags(TrajectoryAnalysisSettings::efNoUserPBC);
278 settings->setPBC(true);
282 Domains::initAnalysis(const TrajectoryAnalysisSettings &settings,
283 const TopologyInformation &top)
285 domains_ePBC = top.ePBC();
289 Domains::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
290 const t_trxframe &fr)
292 ConstArrayRef< int > atomind = sel_[0].atomIndices();
294 for (ConstArrayRef<int>::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
295 index.push_back(*ai);
298 trajectory.resize(1);
299 trajectory.back().resize(index.size());
301 for (int i = 0; i < index.size(); i++) {
302 trajectory.back()[i] = fr.x[index[i]];
305 domains.resize(sel_.size());
306 for (int i = 1; i < sel_.size(); i++) {
307 atomind = sel_[i].atomIndices();
308 for (ConstArrayRef<int>::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
309 domains[i].push_back(*ai);
313 for (int i = 0; i < domains.size(); i++) {
314 for (int j = 0; j < domains[i].size(); j++) {
316 while (index[k] != domains[i][j]) {
323 for (int i = 0; i < domains.size(); i++) {
324 if (domains[i].size() >= 2) {
325 domains_local.push_back(domains[i]);
326 for (int k = 0; k < domains[i].size(); k++) {
327 for (int j = i + 1; j < domains.size(); j++) {
328 for (int x = 0; x < domains[j].size(); x++) {
329 if (domains[j][x] == domains[i][k]) {
330 domains[j].erase(domains[j].begin() + x);
339 domains = domains_local;
341 std::vector< bool > flags;
342 flags.resize(index.size(), true);
344 for (int i = 0; i < domains.size(); i++) {
345 for (int j = 0; j < domains[i].size(); j++) {
346 flags[domains[i][j]] = false;
350 for (int i = 0; i < index.size(); i++) {
352 int a, b, dist = 90000001;
354 for (int j = 0; j < domains.size(); j++) {
355 for (int k = 0; k < domains[j].size(); k++) {
356 rvec_sub(trajectory.back()[i], trajectory.back()[domains[j][k]], temp);
357 if (norm(temp) <= dist) {
364 domains_local[a].push_back(i);
369 frankenstein_trajectory.resize(trajectory.size());
370 frankenstein_trajectory.back() = trajectory.back();
376 Domains::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
377 TrajectoryAnalysisModuleData *pdata)
379 trajectory.resize(trajectory.size() + 1);
380 trajectory.back().resize(index.size());
382 for (int i = 0; i < index.size(); i++) {
383 trajectory.back()[i] = fr.x[index[i]];
386 snew(w_rls, domains_local.size() + 1);
387 for (int i = 0; i < domains_local.size(); i++) {
388 snew(w_rls[i], index.size());
389 for (int j = 0; j < index.size(); j++) {
392 for (int j = 0; j < domains_local[i].size(); j++) {
393 w_rls[i][domains_local[i][j]] = 1;
396 snew(w_rls[domains_local.size()], index.size());
397 for (int i = 0; i < index.size(); i++) {
398 w_rls[domains_local.size()][i] = 1;
401 frankenstein_trajectory.resize(trajectory.size());
402 frankenstein_trajectory.back().resize(index.size());
404 for (int i = 0; i < domains_local.size(); i++) {
406 snew(basic, index.size());
407 for (int k = 0; k < index.size(); k++) {
408 copy_rvec(trajectory[basic_frame][k].as_vec(), basic[k]);
410 snew(traj, index.size());
411 for (int k = 0; k < index.size(); k++) {
412 copy_rvec(trajectory.back()[k].as_vec(), traj[k]);
414 reset_x(index.size(), NULL, index.size(), NULL, basic, w_rls[i]);
415 reset_x(index.size(), NULL, index.size(), NULL, traj, w_rls[i]);
416 do_fit(index.size(), w_rls[i], basic, traj);
418 for (int j = 0; j < index.size(); j++) {
419 if (w_rls[i][j] == 0) {
420 copy_rvec(basic[j], traj[j]);
423 reset_x(index.size(), NULL, index.size(), NULL, traj, w_rls[domains_local.size()]);
425 for (int j = 0; j < domains_local[i].size(); j++) {
426 frankenstein_trajectory.back()[domains_local[i][j]] = traj[domains_local[i][j]];
436 //spacetimecorr -s '/home/toluk/Develop/samples/reca_rd/reca_rd.mono.tpr' -f '/home/toluk/Develop/samples/reca_rd/reca_rd.mono.xtc' -n '/home/toluk/Develop/samples/reca_rd/test.ndx'
439 Domains::finishAnalysis(int nframes)
441 //make_pdb_trajectory(frankenstein_trajectory, "/home/toluk/Develop/samples/reca_rd/10k_frames.pdb");
443 //frankenstein_trajectory = trajectory;
445 std::vector< std::vector< std::vector< double > > > crltns;
450 crltns.resize(k + 1);
451 for (int i = 0; i < crltns.size(); i++) {
452 crltns[i].resize(index.size());
453 for (int j = 0; j < crltns[i].size(); j++) {
454 crltns[i][j].resize(index.size(), 0);
461 #pragma omp for schedule(dynamic)
462 for (int i = m; i <= k; i += 1) {
463 std::cout << " k = " << i << " ";
465 rvec *medx, *medy, temp_zero;
466 snew(medx, index.size());
467 snew(medy, index.size());
471 for (int i = 0; i < index.size(); i++) {
472 copy_rvec(temp_zero, medx[i]);
473 copy_rvec(temp_zero, medy[i]);
476 for (int j = 0; j < frankenstein_trajectory.size() - i; j++) {
477 for (int f = 0; f < index.size(); f++) {
480 rvec_sub(frankenstein_trajectory[basic_frame][f], frankenstein_trajectory[j][f], temp);
481 rvec_inc(medx[f], temp);
482 rvec_sub(frankenstein_trajectory[basic_frame][f], frankenstein_trajectory[j + i][f], temp);
483 rvec_inc(medy[f], temp);
487 for (int j = 0; j < index.size(); j++) {
489 real temp2 = frankenstein_trajectory.size();
492 copy_rvec(medx[j], temp);
493 svmul(temp2, temp, medx[j]);
494 copy_rvec(medy[j], temp);
495 svmul(temp2, temp, medy[j]);
498 std::vector< std::vector< double > > a, b, c;
499 a.resize(index.size());
500 b.resize(index.size());
501 c.resize(index.size());
502 for (int j = 0; j < index.size(); j++) {
503 a[j].resize(index.size(), 0);
504 b[j].resize(index.size(), 0);
505 c[j].resize(index.size(), 0);
507 for (int j = 0; j < frankenstein_trajectory.size() - i; j++) {
508 for (int f1 = 0; f1 < index.size(); f1++) {
509 for (int f2 = 0; f2 < index.size(); f2++) {
511 rvec_sub(frankenstein_trajectory[basic_frame][f1], frankenstein_trajectory[j][f1], temp1);
512 rvec_dec(temp1, medx[f1]);
513 rvec_sub(frankenstein_trajectory[basic_frame][f2], frankenstein_trajectory[j + i][f2], temp2);
514 rvec_dec(temp2, medy[f2]);
515 a[f1][f2] += (temp1[0] * temp2[0] + temp1[1] * temp2[1] + temp1[2] * temp2[2]);
516 b[f1][f2] += (temp1[0] * temp1[0] + temp1[1] * temp1[1] + temp1[2] * temp1[2]);
517 c[f1][f2] += (temp2[0] * temp2[0] + temp2[1] * temp2[1] + temp2[2] * temp2[2]);
521 for (int j = 0; j < index.size(); j++) {
522 for (int f = 0; f < index.size(); f++) {
523 crltns[i][j][f] = a[j][f] / (std::sqrt(b[j][f] * c[j][f]));
532 std::cout << "printing correlation's file\n" ;
533 make_correlation_file(crltns, "corrs.txt", m);
534 std::cout << "done\n" ;
536 for (int i1 = 0; i1 < 100; i1++) {
538 for (int i2 = 1; i2 < crltns.size(); i2++) {
539 for (int i3 = 0; i3 < crltns[i2].size(); i3++) {
540 for (int i4 = 0; i4 < crltns[i2][i3].size(); i4++) {
541 if (crltns[i2][i3][i4] >= (double)i1 / 100) {
547 std::cout << i1 << " - " << i5 << " ";
555 std::vector< std::vector< int > > graph;
556 graph.resize(index.size());
557 for (int i = 1; i <= k; i++) {
558 for (int j = 0; j < index.size(); j++) {
559 for (int f = 0; f < index.size(); f++) {
560 if (std::abs(crltns[i][j][f]) >= crl_border) {
561 bool local_flag = true;
562 for (int f2 = 0; f2 < graph[j].size(); f2++) {
563 if (graph[j][f2] == f) {
568 graph[j].push_back(f);
575 /*for (int i = 0; i < index.size(); i++) {
576 if (graph[i].size() > 0) {
577 std::cout << i << " - " << graph[i].size() << "\n";
582 std::vector< std::vector < int > > rout_old, rout_new;
585 rout_old.resize(index.size());
586 for (int i = 0; i < index.size(); i++) {
587 rout_old[i].resize(1, i);
590 std::cout << "building routs\n\n" ;
594 std::vector < int > flag3;
595 for (long int i = 0; i < rout_old.size(); i++) {
596 if (graph[rout_old[i].back()].size() == 0 && rout_old[i].size() > 2) {
597 rout_new.push_back(rout_old[i]);
600 for (long int j = 0; j < graph[rout_old[i].back()].size(); j++) {
601 bool flag2 = true, flag22 = true;
603 for (int f = 0; f < flag3.size(); f++) {
604 if (flag3[f] == graph[rout_old[i].back()][j]) {
609 flag3.push_back(graph[rout_old[i].back()][j]);
610 for (int f = 0; f < rout_new.size(); f++) {
611 if (rout_new[f] == flag3) {
616 rout_new.push_back(flag3);
623 if (flag222 && rout_old[i].size() > 2) {
624 rout_new.push_back(rout_old[i]);
628 if (rout_new.size() != 0) {
629 std::cout << rout_old.size() << " -> " << rout_new.size() << "\n";
635 std::sort(rout_old.begin(), rout_old.end(), mysortfunc);
637 std::cout << "\nfinished routs\n\n" ;
640 graph.resize(index.size());
643 for (int i = 0; i < rout_old.size(); i++) {
645 for (int j = 0; j < rout_old[i].size() - 1; j++) {
647 for (int f = 0; f < graph[rout_old[i][j]].size(); f++) {
648 if (graph[rout_old[i][j]][f] == rout_old[i][j + 1]) {
653 graph[rout_old[i][j]].push_back(rout_old[i][j + 1]);
658 rout_new.push_back(rout_old[i]);
663 /*std::cout << "\n test old \n";
664 for (int i = 0; i < rout_old.size(); i++) {
665 for (int j = 0; j < rout_old[i].size(); j++) {
666 std::cout << index[rout_old[i][j]] << " ";
671 std::cout << "\n test new \n";*/
674 for (int i = rout_old.size() - 1; i >= 0; i--) {
676 for (int j = 0; j < i; j++) {
677 if (rout_old[i].size() < rout_old[j].size()) {
679 for (int f = 0; f < rout_old[j].size(); f++) {
680 if (rout_old[j][f] == rout_old[i][la]) {
684 if (la == rout_old[i].size()) {
690 rout_new.push_back(rout_old[i]);
694 make_rout_file(crl_border, index, rout_new, "routs.txt");
696 /*for (int i = 0; i < rout_new.size(); i++) {
697 for (int j = 0; j < rout_new[i].size(); j++) {
698 std::cout << index[rout_new[i][j]] << " ";
703 std::cout << "\n\n\n job done \n\n\n";
707 Domains::writeOutput()
714 * The main function for the analysis template.
717 main(int argc, char *argv[])
719 return gmx::TrajectoryAnalysisCommandLineRunner::runAsMain<Domains>(argc, argv);