a0ad64f94a8d0fbb739a28dd897815b8fccf082d
[alexxy/gromacs-spacetimecorr.git] / src / spacetimecorr.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \internal \file
36  * \brief
37  * Implements gmx::analysismodules::Freevolume.
38  *
39  * \author Titov Anatoly <Wapuk-cobaka@yandex.ru>
40  * \ingroup module_trajectoryanalysis
41  */
42
43
44 #include <iostream>
45 #include <algorithm>
46 #include <iterator>
47 #include <vector>
48 #include <math.h>
49 #include <cmath>
50 #include <string>
51 #include <sstream>
52
53 #include <gromacs/trajectoryanalysis.h>
54 #include <gromacs/utility/smalloc.h>
55 #include <gromacs/math/do_fit.h>
56 #include <gromacs/trajectoryanalysis/topologyinformation.h>
57 #include "gromacs/topology/topology.h"
58 #include "gromacs/topology/index.h"
59
60 using namespace gmx;
61
62 using gmx::RVec;
63
64 const std::vector< std::vector< std::vector< double > > > read_correlation_matrix_file(const char* file_name, unsigned long size, unsigned int length)
65 {
66     FILE *file;
67     std::vector< std::vector< std::vector< double > > > crrlts;
68     file = std::fopen(file_name, "r+");
69     std::vector< double > c;
70     c.resize(size, 0);
71     std::vector< std::vector< double > > b;
72     b.resize(size, c);
73     crrlts.resize(length + 1, b);
74     char a[100];
75     std::cout << "reading correlations from a file:\n";
76     for (unsigned int i = 0; i < length + 1; i++) {
77         int t0 = 0, t1 = std::fscanf(file, "%d\n", &t0);
78         std::cout << t0 << " | ";
79         if (i % 100 == 0) {
80             std::cout << "\n";
81         }
82         for (unsigned int j = 0; j < size; j++) {
83             for (unsigned int f = 0; f < size; f++) {
84                 int t2 = std::fscanf(file, "%lf ", &crrlts[i][j][f]);
85             }
86         }
87     }
88     std::fclose(file);
89     std::cout << "\n";
90     return crrlts;
91 }
92
93 template< typename T >
94 unsigned int posSrch(std::vector< T > a, T b) {
95     for (unsigned i01 = 0; i01 < a.size(); i01++) {
96         if (a[i01] == b) {
97             return i01;
98             break;
99         }
100     }
101     return a.size() + 1;
102 }
103
104 void make_rout_file(double crl_border, std::vector< int > indx, std::vector< std::string > resNames,
105                     std::vector< std::vector< std::vector< std::pair< unsigned int, unsigned int > > > > rout,
106                     const char* file_name01, const unsigned int tauD, const unsigned int window_size)
107 {
108     FILE *file01;
109     file01 = std::fopen(file_name01, "w+");
110
111     unsigned int f, pre = 0;
112     std::vector< std::tuple< int, int, std::vector< int > > > table;
113
114     for (unsigned int i01 = 0; i01 < rout.size(); i01++) {
115         f = i01;
116         for (unsigned int i02 = i01 + 1; i02 <rout.size(); i02++) {
117             if (rout[i02] == rout[i01]) {
118                 f = i02;
119             } else {
120                 break;
121             }
122         }
123         if (i01 == f) {
124             std::fprintf(file01, "\n Starting time point = %d | correlations >= %0.2f | tau = %d | window = %d\n\n", i01, crl_border, tauD, window_size);
125         } else {
126             std::fprintf(file01, "\n Starting time point = [%d ; %d] | correlations >= %0.2f | tau = %d | window = %d\n\n", i01, f, crl_border, tauD, window_size);
127         }
128         for (unsigned int i02 = 0; i02 < rout[i01].size(); i02++) {
129             for (unsigned int i03 = 0; i03 < rout[i01][i02].size(); i03++) {
130                 std::fprintf(file01, "cgo_arrow (id %3d), (id %3d), radius=0.075\n", indx[rout[i01][i02][i03].first] + 1, indx[rout[i01][i02][i03].second] + 1);
131             }
132             std::fprintf(file01, "\n");
133         }
134         table.resize(0);
135         for (unsigned int i02 = 0; i02 < rout[i01].size(); i02++) {
136             for (unsigned int i03 = 0; i03 < rout[i01][i02].size(); i03++) {
137                 bool flag = true;
138                 for (unsigned int i04 = 0; i04 < table.size(); i04++) {
139                     if (std::get<0>(table[i04]) == indx[rout[i01][i02][i03].first]) {
140                         std::get<1>(table[i04])++;
141                         std::get<2>(table[i04]).push_back(indx[rout[i01][i02][i03].second]);
142                         flag = false;
143                     } else if (std::get<0>(table[i04]) == indx[rout[i01][i02][i03].second]) {
144                         std::get<1>(table[i04])++;
145                         std::get<2>(table[i04]).push_back(indx[rout[i01][i02][i03].first]);
146                         flag = false;
147                     }
148                 }
149                 if (flag) {
150                     std::vector< int > a;
151                     a.resize(0);
152                     a.push_back(indx[rout[i01][i02][i03].second]);
153                     table.push_back(std::make_tuple(indx[rout[i01][i02][i03].first], 1, a));
154                     a.resize(0);
155                     a.push_back(indx[rout[i01][i02][i03].first]);
156                     table.push_back(std::make_tuple(indx[rout[i01][i02][i03].second], 1, a));
157                 }
158             }
159         }
160
161         for (unsigned int i02 = 0; i02 < table.size(); i02++) {
162             std::fprintf(file01, "residue %s connections %d | ", (resNames[posSrch(indx, std::get<0>(table[i02]))]).c_str(), std::get<1>(table[i02]));
163             for (unsigned int i03 = 0; i03 < std::get<2>(table[i02]).size(); i03++) {
164                 std::fprintf(file01, "%s ", (resNames[posSrch(indx, std::get<2>(table[i02])[i03])]).c_str());
165             }
166             std::fprintf(file01, "\n");
167         }
168         if (pre != 0) {
169             std::vector< std::vector< std::pair< unsigned int, unsigned int > > > temp01, temp02;
170             std::vector< std::pair< unsigned int, unsigned int > > temp03, temp04, temp05;
171             temp01 = rout[pre];
172             temp02 = rout[f];
173             temp03.resize(0);
174             temp04.resize(0);
175             for (unsigned int i02 = 0; i02 < temp01.size(); i02++) {
176                 for (unsigned int i03 = 0; i03 < temp01[i02].size(); i03++) {
177                     temp03.push_back(temp01[i02][i03]);
178                 }
179             }
180             for (unsigned int i02 = 0; i02 < temp02.size(); i02++) {
181                 for (unsigned int i03 = 0; i03 < temp02[i02].size(); i03++) {
182                     temp04.push_back(temp02[i02][i03]);
183                 }
184             }
185             std::sort(temp03.begin(), temp03.end());
186             std::sort(temp04.begin(), temp04.end());
187             temp05.resize(0);
188             std::set_difference(temp03.begin(), temp03.end(), temp04.begin(), temp04.end(), std::inserter(temp05, temp05.begin()));
189             std::fprintf(file01, "minus:\n");
190             for (unsigned int i02 = 0; i02 < temp05.size(); i02++) {
191                 std::fprintf(file01, "cgo_arrow (id %3d), (id %3d), radius=0.075\n", indx[temp05[i02].first] + 1, indx[temp05[i02].second] + 1);
192             }
193             temp05.resize(0);
194             std::set_difference(temp04.begin(), temp04.end(), temp03.begin(), temp03.end(), std::inserter(temp05, temp05.begin()));
195             std::fprintf(file01, "plus:\n");
196             for (unsigned int i02 = 0; i02 < temp05.size(); i02++) {
197                 std::fprintf(file01, "cgo_arrow (id %3d), (id %3d), radius=0.075\n", indx[temp05[i02].first] + 1, indx[temp05[i02].second] + 1);
198             }
199         }
200         pre = f;
201         i01 = f;
202     }
203     std::fclose(file01);
204 }
205
206 bool isitsubset (std::vector< int > a, std::vector< int > b) {
207     if (b.size() == 0) {
208         return true;
209     }
210     std::sort(a.begin(), a.end());
211     std::sort(b.begin(), b.end());
212     unsigned int k = 0;
213     for (unsigned int i = 0; i < a.size(); i++) {
214         if (b[k] == a[i]) {
215             k++;
216         }
217     }
218     if (k == b.size()) {
219         return true;
220     } else {
221         return false;
222     }
223 }
224
225 void correlation_evaluation(const std::vector< RVec > ref, const std::vector< std::vector< RVec > > trajectory, const unsigned int tauE, const unsigned int window_size, const char* file_name) {
226     std::vector< std::vector< std::vector< double > > > crl;
227     std::vector< std::vector< RVec > > trj;
228
229     for (unsigned int istart = 0; istart < trajectory.size() - window_size - tauE; istart++) {
230         trj.clear();
231         trj.resize(window_size + tauE);
232         for (unsigned int i = 0; i < window_size + tauE; i++) {
233             for (unsigned int j = 0; j < trajectory[i].size(); j++) {
234                 trj[i].push_back(trajectory[i + istart][j]);
235             }
236         }
237         crl.resize(tauE + 1);
238         for (unsigned int i = 0; i < crl.size(); i++) {
239             crl[i].resize(trajectory.front().size());
240             for (unsigned int j = 0; j < trajectory.front().size(); j++) {
241                 crl[i][j].resize(trajectory.front().size());
242                 for (unsigned int k = 0; k < trajectory.front().size(); k++) {
243                     crl[i][j][k] = 0.;
244                 }
245             }
246         }
247         #pragma omp parallel for ordered schedule(dynamic) shared(crl) firstprivate(trj, ref)
248         for (unsigned int i = 0; i <= tauE; i++) {
249             std::vector< std::vector< double > > a, b, c;
250             std::vector< double > d;
251             d.resize(0);
252             for (unsigned int j = 0; j < trajectory.front().size(); j++) {
253                 a.push_back(d);
254                 b.push_back(d);
255                 c.push_back(d);
256                 for (unsigned int k = 0; k < trajectory.front().size(); k++) {
257                     a[j].push_back(0.);
258                     b[j].push_back(0.);
259                     c[j].push_back(0.);
260                 }
261             }
262             for (unsigned int j = 0; j < trj.size() - tauE; j++) {
263                 for (unsigned int f1 = 0; f1 < trj.front().size(); f1++) {
264                     for (unsigned int f2 = 0; f2 < trj.front().size(); f2++) {
265                         RVec temp1, temp2;
266                         temp1 = trj[j][f1] - ref[f1];
267                         temp2 = trj[j + i][f2] - ref[f2];
268                         a[f1][f2] +=    (static_cast<double>(temp1[0]) * static_cast<double>(temp2[0]) +
269                                         static_cast<double>(temp1[1]) * static_cast<double>(temp2[1]) +
270                                         static_cast<double>(temp1[2]) * static_cast<double>(temp2[2]));
271                         b[f1][f2] +=    (static_cast<double>(temp1[0]) * static_cast<double>(temp1[0]) +
272                                         static_cast<double>(temp1[1]) * static_cast<double>(temp1[1]) +
273                                         static_cast<double>(temp1[2]) * static_cast<double>(temp1[2]));
274                         c[f1][f2] +=    (static_cast<double>(temp2[0]) * static_cast<double>(temp2[0]) +
275                                         static_cast<double>(temp2[1]) * static_cast<double>(temp2[1]) +
276                                         static_cast<double>(temp2[2]) * static_cast<double>(temp2[2]));
277                     }
278                 }
279             }
280             for (unsigned int j = 0; j < trj.front().size(); j++) {
281                 for (unsigned int f = 0; f < trj.front().size(); f++) {
282                     crl[i][j][f] = a[j][f] / (std::sqrt(b[j][f] * c[j][f]));
283                 }
284             }
285         }
286         #pragma omp barrier
287
288         for (unsigned int i1 = 0; i1 < crl.size(); i1++) {
289             for (unsigned int i2 = 0; i2 < crl[i1].size(); i2++) {
290                 for (unsigned int i3 = 0; i3 < crl[i1][i2].size(); i3++) {
291                     crl[i1][i2][i3] = std::round(crl[i1][i2][i3] * 10000) / 10000;
292                 }
293             }
294         }
295
296         FILE *file;
297         file = std::fopen(file_name, "a");
298         for (unsigned int i = 0; i < crl.size(); i++) {
299             std::fprintf(file, "%d %d\n", istart, i);
300             for (unsigned int j = 0; j < crl[i].size(); j++) {
301                 for (unsigned int f = 0; f < crl[i][j].size(); f++) {
302                     std::fprintf(file, "%.6f ", crl[i][j][f]); //~16
303                 }
304                 std::fprintf(file, "\n");
305             }
306         }
307         std::fclose(file);
308         if (istart % 10 == 0 && istart > 0) {
309             std::cout << "\n";
310         }
311         std::cout << " | done " << istart << " | ";
312     }
313     std::cout << "\n";
314 }
315
316 void graph_calculation( std::vector< std::vector< std::pair< double, long int > > > &graph, std::vector< std::vector< unsigned int > > &s_graph,
317                         std::vector< std::vector< std::pair< unsigned int, unsigned int > > > &s_graph_rbr,
318                         const std::vector< RVec > ref,
319                         const std::vector< std::vector< std::vector<double > > > crl,
320                         const double crl_b, const double e_rad, const unsigned int tauB, const unsigned int tauE) {
321     graph.resize(ref.size());
322     for (unsigned int i = 0; i < ref.size(); i++) {
323         graph[i].resize(ref.size(), std::make_pair(0, -1));
324     }
325     RVec temp;
326     for (unsigned int i = tauB; i <= tauE; i++) {
327         for (unsigned int j = 0; j < ref.size(); j++) {
328             for (unsigned int f = j; f < ref.size(); f++) {
329                 temp = ref[i] - ref[f];
330                 if (std::max(std::abs(crl[i][j][f]), std::abs(crl[i][f][j])) >= crl_b &&
331                     static_cast<double>(norm(temp)) <= e_rad && std::abs(graph[j][f].first) < std::max(std::abs(crl[i][j][f]), std::abs(crl[i][f][j]))) {
332                     if (std::abs(crl[i][j][f]) > std::abs(crl[i][f][j])) {
333                         graph[j][f].first = crl[i][j][f];
334                     } else {
335                         graph[j][f].first = crl[i][f][j];
336                     }
337                     graph[j][f].second = i;
338                 }
339             }
340         }
341     }
342     std::vector< bool > graph_flags;
343     graph_flags.resize(ref.size(), true);
344     std::vector< unsigned int > a;
345     a.resize(0);
346     std::vector< std::pair< unsigned int, unsigned int > > b;
347     b.resize(0);
348     std::vector< unsigned int > que1, que2, que3;
349     for (unsigned int i = 0; i < ref.size(); i++) {
350         if (graph_flags[i]) {
351             s_graph.push_back(a);
352             s_graph_rbr.push_back(b);
353             que1.resize(0);
354             que2.resize(0);
355             que3.resize(0);
356             que1.push_back(i);
357             que3.push_back(i);
358             graph_flags[i] = false;
359             while(que1.size() > 0) {
360                 que2.clear();
361                 for (unsigned int k = 0; k < que1.size(); k++) {
362                     for (unsigned int j = 0; j < ref.size(); j++) {
363                         if (graph[que1[k]][j].second > -1 && graph_flags[j]) {
364                             que2.push_back(j);
365                             graph_flags[j] = false;
366                         }
367                     }
368                 }
369                 que1 = que2;
370                 for (unsigned int j = 0; j < que2.size(); j++) {
371                     que3.push_back(que2[j]);
372                 }
373             }
374             s_graph.back() = que3;
375             for (unsigned int j = 0; j < que3.size(); j++) {
376                 for (unsigned int k = 0; k < ref.size(); k++) {
377                     if (graph[que3[j]][k].second > -1) {
378                         s_graph_rbr.back().push_back(std::make_pair(que3[j], k));
379                     }
380                 }
381             }
382         }
383     }
384 }
385
386 bool myfunction (const std::pair< int, double > i, const std::pair< int, double > j) {
387     return i.second < j.second;
388 }
389
390 void graph_back_bone_evaluation(std::vector< std::vector < std::pair< unsigned int, unsigned int > > > &rout_n, const unsigned long indxSize,
391                                 const std::vector< std::vector< std::pair< double, long > > > graph, const std::vector< std::vector< unsigned int > > s_graph,
392                                 const std::vector< std::vector< std::pair< unsigned int, unsigned int > > > s_graph_rbr) {
393     std::vector< double > key;
394     std::vector< long > path;
395     std::vector< std::pair< unsigned int, double > > que;
396     std::vector< std::pair< unsigned int, unsigned int > > a;
397     unsigned int v;
398     for (unsigned int i = 0; i < s_graph.size(); i++) {
399         key.resize(0);
400         path.resize(0);
401         que.resize(0);
402         v = 0;
403         if (s_graph[i].size() > 2) {
404             key.resize(indxSize, 2);
405             path.resize(indxSize, -1);
406             key[s_graph[i][0]] = 0;
407             for (unsigned int j = 0; j < s_graph[i].size(); j++) {
408                 que.push_back(std::make_pair(s_graph[i][j], key[s_graph[i][j]]));
409             }
410             std::sort(que.begin(), que.end(), myfunction);
411             while (!que.empty()) {
412                 v = que[0].first;
413                 que.erase(que.begin());
414                 for (unsigned int j = 0; j < s_graph_rbr[i].size(); j++) {
415                     long u = -1;
416                     if (s_graph_rbr[i][j].first == v) {
417                         u = s_graph_rbr[i][j].second;
418                     } else if (s_graph_rbr[i][j].second == v) {
419                         u = s_graph_rbr[i][j].first;
420                     }
421                     bool flag = false;
422                     unsigned long pos = 0;
423                     for (unsigned long k = 0; k < que.size(); k++) {
424                         if (que[k].first == u) {
425                             flag = true;
426                             pos = k;
427                             k = que.size() + 1;
428                         }
429                     }
430                     if (flag && key[static_cast< unsigned long >(u)] > 1 - std::abs(graph[v][static_cast< unsigned long >(u)].first)) {
431                         path[static_cast< unsigned long >(u)] = v;
432                         key[static_cast< unsigned long >(u)] = 1 - std::abs(graph[v][static_cast< unsigned long >(u)].first);
433                         que[pos].second = key[static_cast< unsigned long >(u)];
434                         sort(que.begin(), que.end(), myfunction);
435                     }
436                 }
437             }
438             a.resize(0);
439             rout_n.push_back(a);
440             for (unsigned int j = 0; j < indxSize; j++) {
441                 if (path[j] != -1) {
442                     rout_n.back().push_back(std::make_pair(j, path[j]));
443                 }
444             }
445         }
446     }
447 }
448
449 gmx::RVec evaluate_com(std::vector< RVec > frame) {
450     RVec temp;
451     temp[0] = 0;
452     temp[1] = 0;
453     temp[2] = 0;
454     for (unsigned int i = 0; i < frame.size(); i++) {
455         temp += frame[i];
456     }
457     temp[0] /= frame.size();
458     temp[1] /= frame.size();
459     temp[2] /= frame.size();
460     return temp;
461 }
462
463 /*! \brief
464  * \ingroup module_trajectoryanalysis
465  */
466
467 class SpaceTimeCorr : public TrajectoryAnalysisModule
468 {
469     public:
470
471         SpaceTimeCorr();
472         virtual ~SpaceTimeCorr();
473
474         //! Set the options and setting
475         virtual void initOptions(IOptionsContainer          *options,
476                                  TrajectoryAnalysisSettings *settings);
477
478         //! First routine called by the analysis framework
479         // virtual void initAnalysis(const t_trxframe &fr, t_pbc *pbc);
480         virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
481                                   const TopologyInformation        &top);
482
483         virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings   &settings,
484                                          const t_trxframe                   &fr);
485
486         //! Call for each frame of the trajectory
487         // virtual void analyzeFrame(const t_trxframe &fr, t_pbc *pbc);
488         virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
489                                   TrajectoryAnalysisModuleData *pdata);
490
491         //! Last routine called by the analysis framework
492         // virtual void finishAnalysis(t_pbc *pbc);
493         virtual void finishAnalysis(int nframes);
494
495         //! Routine to write output, that is additional over the built-in
496         virtual void writeOutput();
497
498     private:
499
500         SelectionList                                               sel_;
501
502         std::vector< std::vector< RVec > >                          trajectory;
503         std::vector< RVec >                                         reference;
504
505         std::vector< int >                                          index;
506         std::vector< std::string >                                  resNms;
507
508         int                                                         frames              = 0;
509         int                                                         tau                 = 0;    // selectable
510         int                                                         window              = 0;
511         float                                                       crl_border          = 0;    // selectable
512         float                                                       eff_rad             = 1.5;  // selectable
513         std::string                                                 OutPutName;                 // selectable
514         int                                                         mode                = 0;    // selectable
515         // Copy and assign disallowed by base.
516 };
517
518 SpaceTimeCorr::SpaceTimeCorr(): TrajectoryAnalysisModule()
519 {
520 }
521
522 SpaceTimeCorr::~SpaceTimeCorr()
523 {
524 }
525
526 void
527 SpaceTimeCorr::initOptions(IOptionsContainer          *options,
528                      TrajectoryAnalysisSettings *settings)
529 {
530     static const char *const desc[] = {
531         "[THISMODULE] to be done"
532     };
533     // Add the descriptive text (program help text) to the options
534     settings->setHelpText(desc);
535     // Add option for output file name
536     //options->addOption(FileNameOption("on").filetype(eftIndex).outputFile()
537     //                        .store(&fnNdx_).defaultBasename("domains")
538     //                        .description("Index file from the domains"));
539     // Add option for working mode
540     options->addOption(gmx::IntegerOption("mode")
541                             .store(&mode)
542                             .description("default 0 - creation of sigle matrixes' file | 1 - reading prepared correlation file to make graphs and etc."));
543     // Add option for tau constant
544     options->addOption(gmx::IntegerOption("tau")
545                             .store(&tau)
546                             .description("max number of frames to shift to evaluate correlations | all starts from array [0 ; tau]"));
547     // Add option for window constant
548     options->addOption(gmx::IntegerOption("window")
549                             .store(&window)
550                             .description("size of window in frames that correlation evaluation based on"));
551     // Add option for crl_border constant
552     options->addOption(FloatOption("crl")
553                             .store(&crl_border)
554                             .description("make graphs based on corrs > crl const"));
555     // Add option for eff_rad constant
556     options->addOption(FloatOption("ef_rad")
557                             .store(&eff_rad)
558                             .description("effective radius for atoms to see each other to evaluate corrs"));
559     // Add option for selection list
560     options->addOption(SelectionOption("select_domains_and_residue").storeVector(&sel_)
561                            .required().dynamicMask().multiValue()
562                            .description("Domains to form rigid skeleton"));
563     // Add option for output file names
564     options->addOption(StringOption("out_put")
565                             .store(&OutPutName)
566                             .description("<your name here> + <local file tag>.txt"));
567     // Control input settings
568     settings->setFlags(TrajectoryAnalysisSettings::efNoUserPBC);
569     settings->setFlag(TrajectoryAnalysisSettings::efUseTopX);
570     settings->setPBC(true);
571 }
572
573 void
574 SpaceTimeCorr::initAnalysis(const TrajectoryAnalysisSettings &settings, const TopologyInformation &top)
575 {
576     ArrayRef< const int > atomind = sel_[0].atomIndices();
577     index.resize(0);
578     for (ArrayRef< const int >::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
579         index.push_back(*ai);
580         resNms.push_back(*(top.atoms()->resinfo[top.atoms()->atom[*ai].resind].name) + std::to_string((top.atoms()->atom[*ai].resind + 1)));
581     }
582     trajectory.resize(0);
583
584     reference.resize(0);
585     if (top.hasFullTopology()) {
586         for (unsigned int i = 0; i < index.size(); i++) {
587             reference.push_back(top.x().at(index[i]));
588         }
589     }
590 }
591
592 void
593 SpaceTimeCorr::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, const t_trxframe &fr)
594 {
595 }
596
597 // -s *.tpr -f *.xtc -n *.ndx -sf 'name' -mode <> -tau <> -window <> -crl <> -ef_rad <> -out_put <>
598
599 void
600 SpaceTimeCorr::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, TrajectoryAnalysisModuleData *pdata)
601 {
602     trajectory.resize(trajectory.size() + 1);
603     trajectory.back().resize(index.size());
604     for (unsigned int i = 0; i < index.size(); i++) {
605         trajectory.back()[i] = fr.x[index[i]];
606     }
607     frames++;
608 }
609
610 void
611 SpaceTimeCorr::finishAnalysis(int nframes)
612 {
613     std::vector< std::vector< std::vector< std::pair< unsigned int, unsigned int > > > > rout_new;
614     unsigned int k = 1000, m = 0;
615     if (tau > 0) {
616         k = static_cast< unsigned int>(tau);
617     }
618     if (window == 0) {
619         window = k * 2;
620     }
621
622     if (mode == 0) {
623         std::cout << "\nCorrelation's evaluation - start\n";
624
625         correlation_evaluation(reference, trajectory, k, static_cast< unsigned int >(window), (OutPutName + "-DumpData.txt").c_str());
626
627         std::cout << "Correlation's evaluation - end\n";
628     } else if (mode == 1) {
629         rout_new.resize(trajectory.size() - static_cast< unsigned long>(window) - k);
630         FILE *file;
631         file = std::fopen((OutPutName + "-DumpData.txt").c_str(), "r+");
632         #pragma omp parallel for ordered schedule(dynamic) shared(rout_new) firstprivate(reference, crl_border, eff_rad, m, k)
633         for(unsigned long i = 0; i < trajectory.size() - static_cast< unsigned int>(window) - k; i++) {
634             std::vector< std::vector< std::vector< double > > > crltns;
635             std::vector< std::vector< std::pair< double, long int > > > graph;
636             std::vector< std::vector< unsigned int > > sub_graph;
637             std::vector< std::vector< std::pair< unsigned int, unsigned int > > > sub_graph_rbr;
638
639             #pragma omp ordered
640             {
641                 crltns.resize(k + 1);
642                 for (unsigned int i1 = 0; i1 < crltns.size(); i1++) {
643                     crltns[i1].resize(trajectory.front().size());
644                     for (unsigned int i2 = 0; i2 < trajectory.front().size(); i2++) {
645                         crltns[i1][i2].resize(trajectory.front().size());
646                         for (unsigned int i3 = 0; i3 < trajectory.front().size(); i3++) {
647                             crltns[i1][i2][i3] = 0.;
648                         }
649                     }
650                 }
651                 for (unsigned int i1 = 0; i1 < k + 1; i1++) {
652                     int t0, t1, t2 = std::fscanf(file, "%d %d\n", &t0, &t1);
653                     for (unsigned int i2 = 0; i2 < trajectory.front().size(); i2++) {
654                         for (unsigned int i3 = 0; i3 < trajectory.front().size(); i3++) {
655                             t2 = std::fscanf(file, "%lf ", &crltns[i1][i2][i3]);
656                         }
657                     }
658                 }
659                 if (i % 10 == 0 && i > 0) {
660                     std::cout << "\n";
661                 }
662                 std::cout << " | mtrxs " << i << " red | ";
663             }
664
665             graph_calculation(graph, sub_graph, sub_graph_rbr, reference, crltns, static_cast< double >(crl_border), static_cast< double >(eff_rad), m, k);
666             graph_back_bone_evaluation(rout_new[i], reference.size()/*index.size()*/, graph, sub_graph, sub_graph_rbr);
667
668         }
669         #pragma omp barrier
670         std::cout << "\n Almost - end\n";
671         make_rout_file(static_cast< double >(crl_border), index, resNms, rout_new, (OutPutName + "-routs.txt").c_str(), static_cast< unsigned int >(tau), static_cast< unsigned int >(window));
672     }
673     std::cout << "Finish Analysis - end\n\n";
674 }
675
676 void
677 SpaceTimeCorr::writeOutput()
678 {
679
680 }
681
682 /*! \brief
683  * The main function for the analysis template.
684  */
685 int
686 main(int argc, char *argv[])
687 {
688     return gmx::TrajectoryAnalysisCommandLineRunner::runAsMain<SpaceTimeCorr>(argc, argv);
689 }