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
49 #include <gromacs/trajectoryanalysis.h>
50 #include <gromacs/pbcutil/pbc.h>
51 #include <gromacs/pbcutil/rmpbc.h>
52 #include <gromacs/utility/smalloc.h>
53 #include <gromacs/math/vectypes.h>
54 #include <gromacs/math/vec.h>
55 #include <gromacs/math/do_fit.h>
57 #include "gromacs/analysisdata/analysisdata.h"
58 #include "gromacs/analysisdata/modules/average.h"
59 #include "gromacs/analysisdata/modules/histogram.h"
60 #include "gromacs/analysisdata/modules/plot.h"
61 #include "gromacs/math/vec.h"
62 #include "gromacs/options/basicoptions.h"
63 #include "gromacs/options/filenameoption.h"
64 #include "gromacs/options/ioptionscontainer.h"
65 #include "gromacs/pbcutil/pbc.h"
66 #include "gromacs/selection/selection.h"
67 #include "gromacs/selection/selectionoption.h"
68 #include "gromacs/trajectory/trajectoryframe.h"
69 #include "gromacs/trajectoryanalysis/analysissettings.h"
70 #include "gromacs/utility/arrayref.h"
71 #include "gromacs/utility/exceptions.h"
72 #include "gromacs/utility/stringutil.h"
78 void make_pdb_trajectory(std::vector< std::vector< RVec > > trajectory, const char* file_name)
81 file = std::fopen(file_name, "w+");
82 for (int i = 1; i < trajectory.size(); i++) {
83 std::fprintf(file, "MODEL%9d\n", i);
84 for (int j = 0; j < trajectory[i].size(); j++) {
85 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);
87 std::fprintf(file, "ENDMDL\n");
91 1 - 6 Record name "ATOM "
92 7 - 11 Integer Atom serial number.
93 13 - 16 Atom Atom name.
94 17 Character Alternate location indicator.
95 18 - 20 Residue name Residue name.
96 22 Character Chain identifier.
97 23 - 26 Integer Residue sequence number.
98 27 AChar Code for insertion of residues.
99 31 - 38 Real(8.3) Orthogonal coordinates for X in Angstroms.
100 39 - 46 Real(8.3) Orthogonal coordinates for Y in Angstroms.
101 47 - 54 Real(8.3) Orthogonal coordinates for Z in Angstroms.
102 55 - 60 Real(6.2) Occupancy.
103 61 - 66 Real(6.2) Temperature factor (Default = 0.0).
104 73 - 76 LString(4) Segment identifier, left-justified.
105 77 - 78 LString(2) Element symbol, right-justified.
106 79 - 80 LString(2) Charge on the atom.
109 void make_correlation_file(std::vector< std::vector< std::vector< double > > > correlations, const char* file_name, int start)
112 file = std::fopen(file_name, "w+");
113 std::cout << "start printing\n";
114 for (int i = start; i < correlations.size(); i++) {
115 std::fprintf(file, "correlation between 'n' and 'n + %d' frames\n", i);
117 std::cout << "correlation between 'n' and 'n + " << i << "' frames\n";
119 for (int j = 0; j < correlations[i].size(); j++) {
120 for (int k = 0; k < correlations[i][j].size(); k++) {
121 //if (std::abs(correlations[i][j][k]) > 0.5) {
122 std::fprintf(file, "%3.2f ", correlations[i][j][k]);
125 std::fprintf(file, "\n");
130 void make_rout_file(std::vector< int > dist, std::vector< std::vector< int > > rout, const char* file_name)
133 file = std::fopen(file_name, "w+");
134 std::cout << "start printing\n";
135 for (int i = 0; i < rout.size(); i++) {
137 std::fprintf(file, "sum dist %d\n", dist[i]);
138 for (int j = 0; j < rout[i].size(); j++) {
139 std::fprintf(file, "%3d ", rout[i][j]);
141 std::fprintf(file, "\n");
147 int dive_in(std::vector< std::vector< std::pair< int, int > > > &graph, int a, int b, int frames, int depth)
150 if (depth > frames) {
153 for (int i = 0; i < graph[a].size(); i++) {
154 c1 = dive_in(graph, graph[a][i].first, b++, frames, depth + graph[a][i].second);
159 return (std::max(c2, b));
164 * Class used to compute free volume in a simulations box.
166 * Inherits TrajectoryAnalysisModule and all functions from there.
167 * Does not implement any new functionality.
169 * \ingroup module_trajectoryanalysis
173 class Domains : public TrajectoryAnalysisModule
180 //! Set the options and setting
181 virtual void initOptions(IOptionsContainer *options,
182 TrajectoryAnalysisSettings *settings);
184 //! First routine called by the analysis framework
185 // virtual void initAnalysis(const t_trxframe &fr, t_pbc *pbc);
186 virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
187 const TopologyInformation &top);
189 virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
190 const t_trxframe &fr);
192 //! Call for each frame of the trajectory
193 // virtual void analyzeFrame(const t_trxframe &fr, t_pbc *pbc);
194 virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
195 TrajectoryAnalysisModuleData *pdata);
197 //! Last routine called by the analysis framework
198 // virtual void finishAnalysis(t_pbc *pbc);
199 virtual void finishAnalysis(int nframes);
201 //! Routine to write output, that is additional over the built-in
202 virtual void writeOutput();
209 std::vector< std::vector< int > > domains;
210 std::vector< std::vector< int > > domains_local;
211 std::vector< std::vector< RVec > > trajectory;
212 std::vector< std::vector< RVec > > frankenstein_trajectory;
215 std::vector< int > index;
216 std::vector< int > numbers;
222 // Copy and assign disallowed by base.
225 Domains::Domains(): TrajectoryAnalysisModule()
234 Domains::initOptions(IOptionsContainer *options,
235 TrajectoryAnalysisSettings *settings)
237 static const char *const desc[] = {
238 "[THISMODULE] to be done"
240 // Add the descriptive text (program help text) to the options
241 settings->setHelpText(desc);
242 // Add option for output file name
243 options->addOption(FileNameOption("on").filetype(eftIndex).outputFile()
244 .store(&fnNdx_).defaultBasename("domains")
245 .description("Index file from the domains"));
246 // Add option for selection list
247 options->addOption(SelectionOption("select_domains_and_residue").storeVector(&sel_)
248 .required().dynamicMask().multiValue()
249 .description("Domains to form rigid skeleton"));
250 // Control input settings
251 settings->setFlags(TrajectoryAnalysisSettings::efNoUserPBC);
252 settings->setPBC(true);
256 Domains::initAnalysis(const TrajectoryAnalysisSettings &settings,
257 const TopologyInformation &top)
259 domains_ePBC = top.ePBC();
263 Domains::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
264 const t_trxframe &fr)
266 ConstArrayRef< int > atomind = sel_[0].atomIndices();
268 for (ConstArrayRef<int>::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
269 index.push_back(*ai);
272 trajectory.resize(1);
273 trajectory.back().resize(index.size());
275 for (int i = 0; i < index.size(); i++) {
276 trajectory.back()[i] = fr.x[index[i]];
279 domains.resize(sel_.size());
280 for (int i = 1; i < sel_.size(); i++) {
281 atomind = sel_[i].atomIndices();
282 for (ConstArrayRef<int>::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
283 domains[i].push_back(*ai);
287 for (int i = 0; i < domains.size(); i++) {
288 for (int j = 0; j < domains[i].size(); j++) {
290 while (index[k] != domains[i][j]) {
297 for (int i = 0; i < domains.size(); i++) {
298 if (domains[i].size() >= 2) {
299 domains_local.push_back(domains[i]);
300 for (int k = 0; k < domains[i].size(); k++) {
301 for (int j = i + 1; j < domains.size(); j++) {
302 for (int x = 0; x < domains[j].size(); x++) {
303 if (domains[j][x] == domains[i][k]) {
304 domains[j].erase(domains[j].begin() + x);
313 domains = domains_local;
315 std::vector< bool > flags;
316 flags.resize(index.size(), true);
318 for (int i = 0; i < domains.size(); i++) {
319 for (int j = 0; j < domains[i].size(); j++) {
320 flags[domains[i][j]] = false;
324 for (int i = 0; i < index.size(); i++) {
326 int a, b, dist = 90000001;
328 //if (domains.size() != 2) { спорно как ту поступить
329 for (int j = 0; j < domains.size(); j++) {
330 for (int k = 0; k < domains[j].size(); k++) {
331 rvec_sub(trajectory.back()[i], trajectory.back()[domains[j][k]], temp);
332 if (norm(temp) <= dist) {
340 domains_local[a].push_back(i);
345 frankenstein_trajectory.resize(trajectory.size());
346 frankenstein_trajectory.back() = trajectory.back();
352 Domains::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
353 TrajectoryAnalysisModuleData *pdata)
355 trajectory.resize(trajectory.size() + 1);
356 trajectory.back().resize(index.size());
358 for (int i = 0; i < index.size(); i++) {
359 trajectory.back()[i] = fr.x[index[i]];
362 snew(w_rls, domains_local.size() + 1);
363 for (int i = 0; i < domains_local.size(); i++) {
364 snew(w_rls[i], index.size());
365 for (int j = 0; j < index.size(); j++) {
368 for (int j = 0; j < domains_local[i].size(); j++) {
369 w_rls[i][domains_local[i][j]] = 1;
372 snew(w_rls[domains_local.size()], index.size());
373 for (int i = 0; i < index.size(); i++) {
374 w_rls[domains_local.size()][i] = 1;
377 frankenstein_trajectory.resize(trajectory.size());
378 frankenstein_trajectory.back().resize(index.size());
380 for (int i = 0; i < domains_local.size(); i++) {
382 snew(basic, index.size());
383 for (int k = 0; k < index.size(); k++) {
384 copy_rvec(trajectory[basic_frame][k].as_vec(), basic[k]);
386 snew(traj, index.size());
387 for (int k = 0; k < index.size(); k++) {
388 copy_rvec(trajectory.back()[k].as_vec(), traj[k]);
390 reset_x(index.size(), NULL, index.size(), NULL, basic, w_rls[i]);
391 reset_x(index.size(), NULL, index.size(), NULL, traj, w_rls[i]);
392 do_fit(index.size(), w_rls[i], basic, traj);
394 for (int j = 0; j < index.size(); j++) {
395 if (w_rls[i][j] == 0) {
396 copy_rvec(basic[j], traj[j]);
399 reset_x(index.size(), NULL, index.size(), NULL, traj, w_rls[domains_local.size()]);
401 for (int j = 0; j < domains_local[i].size(); j++) {
402 frankenstein_trajectory.back()[domains_local[i][j]] = traj[domains_local[i][j]];
412 //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'
415 Domains::finishAnalysis(int nframes)
417 //make_pdb_trajectory(frankenstein_trajectory, "/home/toluk/Develop/samples/reca_rd/frank_with_duo_test.pdb");
418 std::vector< std::vector< std::vector< double > > > crltns;
419 int k = 950, m = 949;
420 crltns.resize(k + 1);
421 for (int i = 0; i < crltns.size(); i++) {
422 crltns[i].resize(index.size());
423 for (int j = 0; j < crltns[i].size(); j++) {
424 crltns[i][j].resize(index.size(), 0);
428 //#pragma omp parallel
430 //#pragma omp for schedule(dynamic)
431 for (int i = m; i <= k; i += 1) {
432 std::cout << " \n " << " k = " << i << " \n";
433 //std::vector< float > medx, medy;
434 //medx.resize(index.size(), 0);
435 //medy.resize(index.size(), 0);
436 rvec *medx, *medy, temp_zero;
437 snew(medx, index.size());
438 snew(medy, index.size());
442 for (int i = 0; i < index.size(); i++) {
443 copy_rvec(temp_zero, medx[i]);
444 copy_rvec(temp_zero, medy[i]);
446 for (int j = 0; j < frankenstein_trajectory.size() - k; j++) {
447 for (int f = 0; f < index.size(); f++) {
449 //rvec_sub(frankenstein_trajectory[j][f], frankenstein_trajectory[j + 1][f], temp);
450 rvec_sub(frankenstein_trajectory[basic_frame][f], frankenstein_trajectory[j][f], temp);
451 rvec_inc(medx[f], temp);
452 //medx[f] += norm(temp);
453 //rvec_sub(frankenstein_trajectory[j + k - 1][f], frankenstein_trajectory[j + k][f], temp);
454 rvec_sub(frankenstein_trajectory[basic_frame][f], frankenstein_trajectory[j + k][f], temp);
455 rvec_inc(medy[f], temp);
456 //medy[f] += norm(temp);
460 for (int j = 0; j < index.size(); j++) {
461 //medx[j] /= frankenstein_trajectory.size();
463 real temp2 = frankenstein_trajectory.size() - k;
465 copy_rvec(medx[j], temp);
466 svmul(temp2, temp, medx[j]);
467 //medy[j] /= frankenstein_trajectory.size();
468 copy_rvec(medy[j], temp);
469 svmul(temp2, temp, medy[j]);
472 /*for (int j = 0; j < index.size(); j++) {
473 std::cout << medx[j][0] << " " << medx[j][1] << " " << medx[j][2] << " " << medy[j][0] << " " << medy[j][1] << " " << medy[j][2] << "\n";
476 std::vector< std::vector< double > > a, b, c;
477 a.resize(index.size());
478 b.resize(index.size());
479 c.resize(index.size());
480 for (int j = 0; j < index.size(); j++) {
481 a[j].resize(index.size(), 0);
482 b[j].resize(index.size(), 0);
483 c[j].resize(index.size(), 0);
485 for (int j = 0; j < frankenstein_trajectory.size() - k; j++) {
486 for (int f1 = 0; f1 < index.size(); f1++) {
487 for (int f2 = 0; f2 < index.size(); f2++) {
489 //rvec_sub(frankenstein_trajectory[j][f1], frankenstein_trajectory[j + 1][f1], temp1);
490 rvec_sub(frankenstein_trajectory[basic_frame][f1], frankenstein_trajectory[j][f1], temp1);
491 rvec_dec(temp1, medx[f1]);
492 //rvec_sub(frankenstein_trajectory[j + k - 1][f2], frankenstein_trajectory[j + k][f2], temp2);
493 rvec_sub(frankenstein_trajectory[basic_frame][f2], frankenstein_trajectory[j + k][f2], temp2);
494 rvec_dec(temp2, medy[f2]);
495 //a[f1][f2] += (norm(temp1) - medx[f1]) * (norm(temp2) - medy[f2]);
496 //b[f1][f2] += (norm(temp1) - medx[f1]) * (norm(temp1) - medx[f1]);
497 //c[f1][f2] += (norm(temp2) - medy[f2]) * (norm(temp2) - medy[f2]);
498 a[f1][f2] += (temp1[0] * temp2[0] + temp1[1] * temp2[1] + temp1[2] * temp2[2]);
499 b[f1][f2] += (temp1[0] * temp1[0] + temp1[1] * temp1[1] + temp1[2] * temp1[2]);
500 c[f1][f2] += (temp2[0] * temp2[0] + temp2[1] * temp2[1] + temp2[2] * temp2[2]);
501 //std::cout << a[f1][f2] << " " << b[f1][f2] << " " << c[f1][f2] << "\n";
506 for (int j = 0; j < index.size(); j++) {
507 for (int f = 0; f < index.size(); f++) {
508 crltns[i][j][f] = a[j][f] / (std::sqrt(b[j][f] * c[j][f]));
515 // std::cout << "\noutput file\n";
516 make_correlation_file(crltns, "/home/toluk/Develop/samples/reca_rd/corrs2.txt", m);
517 // std::cout << "\n\n file done \n\n";
530 /*std::cout << "\n\n\n\n";
531 for (int i2 = 0; i2 < 75; i2++) {
532 long int count_here = 0;
533 for (int i = 0; i < k; i++) {
534 for (int j = 0; j < index.size(); j++) {
535 for (int f = 0; f < index.size(); f++) {
536 if (std::abs(crltns[i][j][f]) >= (float)i2 / 100) {
542 std::cout << i2 << " " << count_here << "\n";
544 std::cout << "\n\n\n\n";*/
549 std::vector< std::vector< std::pair< int, int > > > graph;
550 graph.resize(index.size());
551 for (int i = 0; i < k; i++) {
552 for (int j = 0; j < index.size(); j++) {
553 for (int f = 0; f < index.size(); f++) {
554 if (std::abs(crltns[i][j][f]) >= 0.65) {
555 graph[j].push_back(std::make_pair(f, i));
561 /*for (int i = 0; i < index.size(); i++) {
562 std::cout << graph[i].size() << " ";
566 std::vector< std::vector < int > > rout_old, rout_new;
567 std::vector< int > length_old, length_new;
570 length_new.resize(0);
571 length_old.resize(index.size(), 0);
572 rout_old.resize(index.size());
573 for (int i = 0; i < index.size(); i++) {
574 rout_old[i].resize(1, i);
577 std::cout << "building routs\n" ;
581 for (int i = 0; i < index.size(); i++) {
582 std::cout << i << " " << dive_in(graph, i, 0, frames, 0) << " ";
587 for (long int i = 0; i < rout_old.size(); i++) {
588 if (graph[rout_old[i].back()].size() == 0 && rout_old[i].size() > 2) {
589 rout_new.push_back(rout_old[i]);
590 length_new.push_back(length_old[i]);
592 for (long int j = 0; j < graph[rout_old[i].back()].size(); j++) {
593 if (length_old[i] + graph[rout_old[i].back()][j].second <= frames) {
594 rout_new.push_back(rout_old[i]);
595 rout_new.back().push_back(graph[rout_old[i].back()][j].first);
596 length_new.push_back(length_old[i] + graph[rout_old[i].back()][j].second);
604 length_old = length_new;
605 std::cout << length_old.size() << "\n";
606 length_new.resize(0);
610 std::cout << "finished routs\n" ;
611 make_rout_file(length_old, rout_old, "/home/toluk/Develop/samples/reca_rd/routs.txt");
612 std::cout << "\n\n\n job done \n\n\n";
617 Domains::writeOutput()
624 * The main function for the analysis template.
627 main(int argc, char *argv[])
629 return gmx::TrajectoryAnalysisCommandLineRunner::runAsMain<Domains>(argc, argv);