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
48 #include <gromacs/trajectoryanalysis.h>
49 #include <gromacs/utility/smalloc.h>
50 #include <gromacs/math/do_fit.h>
56 void make_pdb_trajectory(std::vector< std::vector< RVec > > trajectory, const char* file_name)
59 file = std::fopen(file_name, "w+");
60 for (int i = 1; i < trajectory.size(); i++) {
61 std::fprintf(file, "MODEL%9d\n", i);
62 for (int j = 0; j < trajectory[i].size(); j++) {
63 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);
65 std::fprintf(file, "ENDMDL\n");
69 void make_correlation_file(std::vector< std::vector< std::vector< double > > > correlations, const char* file_name, int start)
72 file = std::fopen(file_name, "w+");
73 for (int i = start; i < correlations.size(); i++) {
74 if (correlations.size() - start > 1) {
75 std::fprintf(file, "correlation between 'n' and 'n + %d' frames\n", i);
78 std::cout << "correlation between 'n' and 'n + " << i << "' frames\n";
80 for (int j = 0; j < correlations[i].size(); j++) {
81 for (int f = 0; f < correlations[i][j].size(); f++) {
82 std::fprintf(file, "%3.2f ", correlations[i][j][f]);
84 std::fprintf(file, "\n");
90 void make_rout_file2(double crl_border, std::vector< int > indx, std::vector< std::vector< std::pair< int, int > > > rout, const char* file_name)
93 file = std::fopen(file_name, "w+");
94 std::fprintf(file, "correlations >= %0.2f\n\n", crl_border);
95 for (int i = 0; i < rout.size(); i++) {
96 for (int j = 0; j < rout[i].size(); j++) {
97 std::fprintf(file, "cgo_arrow (id %3d), (id %3d), radius=0.15\n", indx[rout[i][j].first] + 1, indx[rout[i][j].second] + 1);
99 std::fprintf(file, "\n\n");
104 void make_best_corrs_graphics(std::vector< std::vector< std::vector< double > > > correlations,
105 std::vector< std::vector< std::pair< int, int > > > rout_pairs,
106 std::vector< int > indx,
107 const char* file_name)
110 file = std::fopen(file_name, "w+");
111 for (int i = 0; i < rout_pairs.size(); i++) {
112 for (int j = 0; j < rout_pairs[i].size(); j++) {
113 std::fprintf(file, "%3d %3d\n", indx[rout_pairs[i][j].first] + 1, indx[rout_pairs[i][j].second] + 1);
114 for (int k = 0; k < correlations.size(); k++) {
115 std::fprintf(file, "%3.5f ", correlations[k][rout_pairs[i][j].first][rout_pairs[i][j].second]);
117 std::fprintf(file, "\n");
123 bool mysortfunc (std::vector< int > a, std::vector< int > b) { return (a.size() > b.size()); }
125 bool isitsubset (std::vector< int > a, std::vector< int > b) {
129 std::sort(a.begin(), a.end());
130 std::sort(b.begin(), b.end());
132 for (int i = 0; i < a.size(); i++) {
144 bool myfunction (const std::pair< int, double > i, const std::pair< int, double > j) {
145 return i.second < j.second;
149 * \ingroup module_trajectoryanalysis
152 class Domains : public TrajectoryAnalysisModule
159 //! Set the options and setting
160 virtual void initOptions(IOptionsContainer *options,
161 TrajectoryAnalysisSettings *settings);
163 //! First routine called by the analysis framework
164 // virtual void initAnalysis(const t_trxframe &fr, t_pbc *pbc);
165 virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
166 const TopologyInformation &top);
168 virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
169 const t_trxframe &fr);
171 //! Call for each frame of the trajectory
172 // virtual void analyzeFrame(const t_trxframe &fr, t_pbc *pbc);
173 virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
174 TrajectoryAnalysisModuleData *pdata);
176 //! Last routine called by the analysis framework
177 // virtual void finishAnalysis(t_pbc *pbc);
178 virtual void finishAnalysis(int nframes);
180 //! Routine to write output, that is additional over the built-in
181 virtual void writeOutput();
188 std::vector< std::vector< int > > domains;
189 std::vector< std::vector< int > > domains_local;
190 std::vector< std::vector< RVec > > trajectory;
191 std::vector< std::vector< RVec > > frankenstein_trajectory;
193 std::vector< int > index;
194 std::vector< int > numbers;
198 double crl_border = 0;
199 double eff_rad = 1.5;
203 // Copy and assign disallowed by base.
206 Domains::Domains(): TrajectoryAnalysisModule()
215 Domains::initOptions(IOptionsContainer *options,
216 TrajectoryAnalysisSettings *settings)
218 static const char *const desc[] = {
219 "[THISMODULE] to be done"
221 // Add the descriptive text (program help text) to the options
222 settings->setHelpText(desc);
223 // Add option for output file name
224 options->addOption(FileNameOption("on").filetype(eftIndex).outputFile()
225 .store(&fnNdx_).defaultBasename("domains")
226 .description("Index file from the domains"));
227 // Add option for tau constant
228 options->addOption(gmx::IntegerOption("tau")
230 .description("number of frames for time travel"));
231 // Add option for crl_border constant
232 options->addOption(DoubleOption("crl")
234 .description("make graph based on corrs > constant"));
235 // Add option for eff_rad constant
236 options->addOption(DoubleOption("ef_rad")
238 .description("effective radius for atoms to evaluate corrs"));
239 // Add option for selection list
240 options->addOption(SelectionOption("select_domains_and_residue").storeVector(&sel_)
241 .required().dynamicMask().multiValue()
242 .description("Domains to form rigid skeleton"));
243 // Control input settings
244 settings->setFlags(TrajectoryAnalysisSettings::efNoUserPBC);
245 settings->setPBC(true);
249 Domains::initAnalysis(const TrajectoryAnalysisSettings &settings,
250 const TopologyInformation &top)
252 domains_ePBC = top.ePBC();
256 Domains::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
257 const t_trxframe &fr)
259 ConstArrayRef< int > atomind = sel_[0].atomIndices();
261 for (ConstArrayRef<int>::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
262 index.push_back(*ai);
264 trajectory.resize(1);
265 trajectory.back().resize(index.size());
267 for (int i = 0; i < index.size(); i++) {
268 trajectory.back()[i] = fr.x[index[i]];
270 domains.resize(sel_.size());
271 for (int i = 0; i < sel_.size(); i++) {
272 if (sel_.size() != 1) {
275 atomind = sel_[i].atomIndices();
276 for (ConstArrayRef<int>::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
277 domains[i].push_back(*ai);
280 for (int i = 0; i < domains.size(); i++) {
281 for (int j = 0; j < domains[i].size(); j++) {
283 while (index[k] != domains[i][j]) {
289 for (int i = 0; i < domains.size(); i++) {
290 if (domains[i].size() >= 2) {
291 domains_local.push_back(domains[i]);
292 for (int k = 0; k < domains[i].size(); k++) {
293 for (int j = i + 1; j < domains.size(); j++) {
294 for (int x = 0; x < domains[j].size(); x++) {
295 if (domains[j][x] == domains[i][k]) {
296 domains[j].erase(domains[j].begin() + x);
304 domains = domains_local;
305 std::vector< bool > flags;
306 flags.resize(index.size(), true);
307 for (int i = 0; i < domains.size(); i++) {
308 for (int j = 0; j < domains[i].size(); j++) {
309 flags[domains[i][j]] = false;
312 for (int i = 0; i < index.size(); i++) {
314 int a, b, dist = 90000001;
316 for (int j = 0; j < domains.size(); j++) {
317 for (int k = 0; k < domains[j].size(); k++) {
318 rvec_sub(trajectory.back()[i], trajectory.back()[domains[j][k]], temp);
319 if (norm(temp) <= dist) {
326 domains_local[a].push_back(i);
330 frankenstein_trajectory.resize(trajectory.size());
331 frankenstein_trajectory.back() = trajectory.back();
336 Domains::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
337 TrajectoryAnalysisModuleData *pdata)
339 trajectory.resize(trajectory.size() + 1);
340 trajectory.back().resize(index.size());
341 for (int i = 0; i < index.size(); i++) {
342 trajectory.back()[i] = fr.x[index[i]];
344 snew(w_rls, domains_local.size() + 1);
345 for (int i = 0; i < domains_local.size(); i++) {
346 snew(w_rls[i], index.size());
347 for (int j = 0; j < index.size(); j++) {
350 for (int j = 0; j < domains_local[i].size(); j++) {
351 w_rls[i][domains_local[i][j]] = 1;
354 snew(w_rls[domains_local.size()], index.size());
355 for (int i = 0; i < index.size(); i++) {
356 w_rls[domains_local.size()][i] = 1;
358 frankenstein_trajectory.resize(trajectory.size());
359 frankenstein_trajectory.back().resize(index.size());
360 for (int i = 0; i < domains_local.size(); i++) {
362 snew(basic, index.size());
363 for (int k = 0; k < index.size(); k++) {
364 copy_rvec(trajectory[basic_frame][k].as_vec(), basic[k]);
366 snew(traj, index.size());
367 for (int k = 0; k < index.size(); k++) {
368 copy_rvec(trajectory.back()[k].as_vec(), traj[k]);
370 reset_x(index.size(), NULL, index.size(), NULL, basic, w_rls[i]);
371 reset_x(index.size(), NULL, index.size(), NULL, traj, w_rls[i]);
372 do_fit(index.size(), w_rls[i], basic, traj);
373 for (int j = 0; j < index.size(); j++) {
374 if (w_rls[i][j] == 0) {
375 copy_rvec(basic[j], traj[j]);
378 reset_x(index.size(), NULL, index.size(), NULL, traj, w_rls[domains_local.size()]);
380 for (int j = 0; j < domains_local[i].size(); j++) {
381 frankenstein_trajectory.back()[domains_local[i][j]] = traj[domains_local[i][j]];
390 Domains::finishAnalysis(int nframes)
392 std::vector< std::vector< std::vector< double > > > crltns;
397 crltns.resize(k + 1);
398 for (int i = 0; i < crltns.size(); i++) {
399 crltns[i].resize(index.size());
400 for (int j = 0; j < crltns[i].size(); j++) {
401 crltns[i][j].resize(index.size(), 0);
404 std::cout << "Correlation's evaluation - start\n\n";
405 #pragma omp parallel shared(crltns)
407 #pragma omp for schedule(dynamic)
408 for (int i = m; i <= k; i += 1) {
409 rvec *medx, *medy, temp_zero;
410 snew(medx, index.size());
411 snew(medy, index.size());
415 for (int i = 0; i < index.size(); i++) {
416 copy_rvec(temp_zero, medx[i]);
417 copy_rvec(temp_zero, medy[i]);
419 for (int j = 0; j < frankenstein_trajectory.size() - i - 1; j++) {
420 for (int f = 0; f < index.size(); f++) {
423 rvec_sub(frankenstein_trajectory[basic_frame][f], frankenstein_trajectory[j][f], temp);
424 rvec_inc(medx[f], temp);
426 rvec_sub(frankenstein_trajectory[basic_frame][f], frankenstein_trajectory[j + i][f], temp);
427 rvec_inc(medy[f], temp);
430 for (int j = 0; j < index.size(); j++) {
432 real temp2 = frankenstein_trajectory.size() - 1;
436 copy_rvec(medx[j], temp);
437 svmul(temp2, temp, medx[j]);
438 copy_rvec(medy[j], temp);
439 svmul(temp2, temp, medy[j]);
441 std::vector< std::vector< double > > a, b, c;
442 a.resize(index.size());
443 b.resize(index.size());
444 c.resize(index.size());
445 for (int j = 0; j < index.size(); j++) {
446 a[j].resize(index.size(), 0);
447 b[j].resize(index.size(), 0);
448 c[j].resize(index.size(), 0);
450 for (int j = 0; j < frankenstein_trajectory.size() - i - 1; j++) {
451 for (int f1 = 0; f1 < index.size(); f1++) {
452 for (int f2 = 0; f2 < index.size(); f2++) {
454 rvec_sub(frankenstein_trajectory[basic_frame][f1], frankenstein_trajectory[j][f1], temp1);
455 rvec_dec(temp1, medx[f1]);
457 rvec_sub(frankenstein_trajectory[basic_frame][f2], frankenstein_trajectory[j + i][f2], temp2);
458 rvec_dec(temp2, medy[f2]);
460 a[f1][f2] += (temp1[0] * temp2[0] + temp1[1] * temp2[1] + temp1[2] * temp2[2]);
461 b[f1][f2] += (temp1[0] * temp1[0] + temp1[1] * temp1[1] + temp1[2] * temp1[2]);
462 c[f1][f2] += (temp2[0] * temp2[0] + temp2[1] * temp2[1] + temp2[2] * temp2[2]);
466 for (int j = 0; j < index.size(); j++) {
467 for (int f = 0; f < index.size(); f++) {
468 crltns[i][j][f] = a[j][f] / (std::sqrt(b[j][f] * c[j][f]));
476 std::cout << "Correlation's evaluation - end\n\n";
477 for (int i1 = 0; i1 < 100; i1++) {
479 for (int i2 = 1; i2 < crltns.size(); i2++) {
480 for (int i3 = 0; i3 < crltns[i2].size(); i3++) {
481 for (int i4 = 0; i4 < crltns[i2][i3].size(); i4++) {
482 if (std::abs(crltns[i2][i3][i4]) >= (double)i1 / 100 && i3 != i4) {
488 std::cout << i1 << " - " << i5 << " | ";
493 std::vector< std::vector< std::pair< double, int > > > graph;
494 graph.resize(index.size());
495 for (int i = 0; i < index.size(); i++) {
496 graph[i].resize(index.size(), std::make_pair(0, -1));
499 for (int i = 1; i <= k; i++) {
500 for (int j = 0; j < index.size(); j++) {
501 for (int f = j; f < index.size(); f++) {
502 copy_rvec(frankenstein_trajectory[basic_frame][j], temp);
503 rvec_dec(temp, frankenstein_trajectory[basic_frame][f]);
504 if (std::max(std::abs(crltns[i][j][f]), std::abs(crltns[i][f][j])) >= crl_border && norm(temp) <= eff_rad && std::abs(graph[j][f].first) < std::max(std::abs(crltns[i][j][f]), std::abs(crltns[i][f][j]))) {
505 if (std::abs(crltns[i][j][f]) > std::abs(crltns[i][f][j])) {
506 graph[j][f].first = crltns[i][j][f];
508 graph[j][f].first = crltns[i][f][j];
510 graph[j][f].second = i;
515 std::vector< bool > graph_flags;
516 graph_flags.resize(index.size(), true);
517 std::vector< std::vector< int > > sub_graph;
518 std::vector< std::vector< std::pair< int, int > > > sub_graph_rbr;
519 std::vector< int > a;
520 std::vector< std::pair< int, int > > b;
523 for (int i = 0; i < index.size(); i++) {
524 if (graph_flags[i]) {
525 sub_graph.push_back(a);
526 sub_graph_rbr.push_back(b);
527 std::vector< int > que1, que2, que3;
533 graph_flags[i] = false;
534 while(que1.size() > 0) {
536 for (int k = 0; k < que1.size(); k++) {
537 for (int j = 0; j < index.size(); j++) {
538 if (graph[que1[k]][j].second > -1 && graph_flags[j]) {
540 graph_flags[j] = false;
545 for (int j = 0; j < que2.size(); j++) {
546 que3.push_back(que2[j]);
549 sub_graph.back() = que3;
550 for (int j = 0; j < que3.size(); j++) {
551 for (int k = 0; k < index.size(); k++) {
552 if (graph[que3[j]][k].second > -1) {
553 sub_graph_rbr.back().push_back(std::make_pair(que3[j], k));
557 std::cout << sub_graph.back().size() << " ";
560 std::vector< std::vector < std::pair< int, int > > > rout_new;
561 for (int i = 0; i < sub_graph.size(); i++) {
562 if (sub_graph[i].size() > 2) {
563 std::vector< double > key;
564 std::vector< int > path;
565 std::vector< std::pair< int, double > > que;
567 key.resize(index.size(), 2);
568 path.resize(index.size(), -1);
569 key[sub_graph[i][0]] = 0;
571 for (int j = 0; j < sub_graph[i].size(); j++) {
572 que.push_back(std::make_pair(sub_graph[i][j], key[sub_graph[i][j]]));
574 std::sort(que.begin(), que.end(), myfunction);
575 while (!que.empty()) {
577 que.erase(que.begin());
578 for (int j = 0; j < sub_graph_rbr[i].size(); j++) {
580 if (sub_graph_rbr[i][j].first == v) {
581 u = sub_graph_rbr[i][j].second;
582 } else if (sub_graph_rbr[i][j].second == v) {
583 u = sub_graph_rbr[i][j].first;
587 for (int k = 0; k < que.size(); k++) {
588 if (que[k].first == u) {
594 if (flag && key[u] > 1 - std::abs(graph[v][u].first)) {
596 key[u] = 1 - std::abs(graph[v][u].first);
597 que[pos].second = key[u];
598 sort(que.begin(), que.end(), myfunction);
602 std::vector < std::pair< int, int > > a;
604 rout_new.push_back(a);
605 for (int j = 0; j < index.size(); j++) {
607 rout_new.back().push_back(std::make_pair(j, path[j]));
612 make_rout_file2(crl_border, index, rout_new, "routs_new.txt");
613 make_best_corrs_graphics(crltns, rout_new, index, "best_graphics.txt");
614 std::cout << "Finish Analysis - end\n\n";
618 Domains::writeOutput()
624 * The main function for the analysis template.
627 main(int argc, char *argv[])
629 return gmx::TrajectoryAnalysisCommandLineRunner::runAsMain<Domains>(argc, argv);