348f7d72dfc419800c5d908cf45a74d88d42d1c7
[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 <vector>
47 #include <math.h>
48 #include <omp.h>
49 #include <string>
50
51 #include <gromacs/trajectoryanalysis.h>
52 #include <gromacs/utility/smalloc.h>
53 #include <gromacs/math/do_fit.h>
54 #include <gromacs/trajectoryanalysis/topologyinformation.h>
55
56 using namespace gmx;
57
58 using gmx::RVec;
59
60 void make_correlation_matrix_file(std::vector< std::vector< std::vector< float > > > correlations, const char* file_name, int start)
61 {
62     FILE *file;
63     file = std::fopen(file_name, "w+");
64     for (int i = start; i < correlations.size(); i++) {
65         if (correlations.size() - start > 1) {
66             std::fprintf(file, "correlation between 'n' and 'n + %d' frames\n", i);
67         }
68         if (i % 50 == 0) {
69             std::cout << "correlation between 'n' and 'n + " << i << "' frames\n";
70         }
71         for (int j = 0; j < correlations[i].size(); j++) {
72             for (int f = 0; f < correlations[i][j].size(); f++) {
73                 std::fprintf(file, "%3.4f ", correlations[i][j][f]);
74             }
75             std::fprintf(file, "\n");
76         }
77     }
78     std::fclose(file);
79 }
80
81 void make_correlation_pairs_file(std::vector< std::vector< std::vector< float > > > correlations, const char* file_name, int start)
82 {
83     FILE *file;
84     file = std::fopen(file_name, "w+");
85     for (int i = 0; i < correlations.front().size(); i++) {
86         for (int j = 0; j < correlations.front().front().size(); j++) {
87             //std::fprintf(file, "correlation between point '%d' and point '%d'\n", i, j);
88             std::fprintf(file, "%d %d\n", i, j);
89             for (int k = 0; k < correlations.size(); k++) {
90                 std::fprintf(file, "%3.4f ", correlations[k][i][j]);
91             }
92             std::fprintf(file, "\n");
93         }
94         if (i % 10 == 0) {
95             std::cout << "correlations in row " << i << " out of " << correlations.front().size() << " completed\n";
96         }
97     }
98     std::fclose(file);
99 }
100
101 void make_rout_file(float crl_border, std::vector< int > indx, std::vector< std::vector< std::pair< int, int > > > rout, const char* file_name)
102 {
103     FILE *file;
104     file = std::fopen(file_name, "w+");
105     std::fprintf(file, "correlations >= %0.2f\n\n", crl_border);
106     for (int i = 0; i < rout.size(); i++) {
107         for (int j = 0; j < rout[i].size(); j++) {
108             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*/);
109         }
110         std::fprintf(file, "\n\n");
111     }
112     std::fclose(file);
113 }
114
115 void make_best_corrs_graphics(std::vector< std::vector< std::vector< float > > > correlations,
116                               std::vector< std::vector< std::pair< int, int > > > rout_pairs,
117                               std::vector< int > indx,
118                               const char* file_name)
119 {
120     FILE *file;
121     file = std::fopen(file_name, "w+");
122     for (int i = 0; i < rout_pairs.size(); i++) {
123         for (int j = 0; j < rout_pairs[i].size(); j++) {
124             std::fprintf(file, "%3d %3d\n", indx[rout_pairs[i][j].first]/* + 1*/, indx[rout_pairs[i][j].second]/* + 1*/);
125             for (int k = 0; k < correlations.size(); k++) {
126                 std::fprintf(file, "%3.5f ", correlations[k][rout_pairs[i][j].first][rout_pairs[i][j].second]);
127             }
128             std::fprintf(file, "\n");
129         }
130     }
131     std::fclose(file);
132 }
133
134 void make_diffusion_file(const char* file_name, std::vector< float > D)
135 {
136     FILE *file;
137     file = std::fopen(file_name, "w+");
138     for (int i = 0; i < D.size(); i++) {
139         std::fprintf(file, "%f ", D[i]);
140     }
141     std::fclose(file);
142 }
143
144 bool mysortfunc (std::vector< int > a, std::vector< int > b) {
145     return (a.size() > b.size());
146 }
147
148 bool isitsubset (std::vector< int > a, std::vector< int > b) {
149     if (b.size() == 0) {
150         return true;
151     }
152     std::sort(a.begin(), a.end());
153     std::sort(b.begin(), b.end());
154     int k = 0;
155     for (int i = 0; i < a.size(); i++) {
156         if (b[k] == a[i]) {
157             k++;
158         }
159     }
160     if (k == b.size()) {
161         return true;
162     } else {
163         return false;
164     }
165 }
166
167 void correlation_evaluation(std::vector< RVec > ref, std::vector< std::vector< RVec > > traj, int b_frame, std::vector< std::vector< std::vector< float > > > &crl, int tauS, int tauE) {
168     crl.resize(tauE + 1);
169     for (int i = 0; i < crl.size(); i++) {
170         crl[i].resize(traj.front().size());
171         for (int j = 0; j < crl[i].size(); j++) {
172             crl[i][j].resize(traj.front().size(), 0);
173         }
174     }
175     RVec temp_zero;
176     temp_zero[0] = 0;
177     temp_zero[1] = 0;
178     temp_zero[2] = 0;
179
180     std::vector< float > d;
181     d.resize(traj.front().size(), 0);
182
183     #pragma omp parallel for schedule(dynamic)
184     for (int i = tauS; i <= tauE; i += 1) {
185         RVec temp1, temp2;
186         std::vector< std::vector< float > > a, b, c;
187         a.resize(traj.front().size(), d);
188         b.resize(traj.front().size(), d);
189         c.resize(traj.front().size(), d);
190         for (int j = 0; j < traj.size() - i - 1; j++) {
191             for (int f1 = 0; f1 < traj.front().size(); f1++) {
192                 for (int f2 = 0; f2 < traj.front().size(); f2++) {
193                     temp1 = traj[j][f1] - ref[f1];
194                     temp2 = traj[j + i][f2] - ref[f2];
195                     a[f1][f2] += (temp1[0] * temp2[0] + temp1[1] * temp2[1] + temp1[2] * temp2[2]);
196                     b[f1][f2] += (temp1[0] * temp1[0] + temp1[1] * temp1[1] + temp1[2] * temp1[2]);
197                     c[f1][f2] += (temp2[0] * temp2[0] + temp2[1] * temp2[1] + temp2[2] * temp2[2]);
198                 }
199             }
200         }
201         for (int j = 0; j < traj.front().size(); j++) {
202             for (int f = 0; f < traj.front().size(); f++) {
203                 crl[i][j][f] = a[j][f] / (std::sqrt(b[j][f] * c[j][f]));
204             }
205         }
206         std::cout << i << " corr done\n";
207     }
208     #pragma omp barrier
209 }
210
211 void graph_calculation(std::vector< std::vector< std::pair< float, int > > > &graph, std::vector< std::vector< int > > &s_graph, std::vector< std::vector< std::pair< int, int > > > &s_graph_rbr,
212                       std::vector< std::vector< RVec > > traj, int b_frame,
213                       std::vector< std::vector< std::vector< float > > > crl, float crl_b, float e_rad, int tauE) {
214     graph.resize(traj.front().size());
215     for (int i = 0; i < traj.front().size(); i++) {
216         graph[i].resize(traj.front().size(), std::make_pair(0, -1));
217     }
218     RVec temp;
219     for (int i = 1; i <= tauE; i++) {
220         for (int j = 0; j < traj.front().size(); j++) {
221             for (int f = j; f < traj.front().size(); f++) {
222                 temp = traj[b_frame][j] - traj[b_frame][f];
223                 if (std::max(std::abs(crl[i][j][f]), std::abs(crl[i][f][j])) >= crl_b && norm(temp) <= e_rad && std::abs(graph[j][f].first) < std::max(std::abs(crl[i][j][f]), std::abs(crl[i][f][j]))) {
224                     if (std::abs(crl[i][j][f]) > std::abs(crl[i][f][j])) {
225                         graph[j][f].first = crl[i][j][f];
226                     } else {
227                         graph[j][f].first = crl[i][f][j];
228                     }
229                     graph[j][f].second = i;
230                 }
231             }
232         }
233     }
234     std::cout << "crl analysed\n";
235     std::vector< bool > graph_flags;
236     graph_flags.resize(traj.front().size(), true);
237     std::vector< int > a;
238     a.resize(0);
239     std::vector< std::pair< int, int > > b;
240     b.resize(0);
241     std::vector< int > que1, que2, que3;
242     for (int i = 0; i < traj.front().size(); i++) {
243         if (graph_flags[i]) {
244             s_graph.push_back(a);
245             s_graph_rbr.push_back(b);
246             que1.resize(0);
247             que2.resize(0);
248             que3.resize(0);
249             que1.push_back(i);
250             que3.push_back(i);
251             graph_flags[i] = false;
252             while(que1.size() > 0) {
253                 que2.clear();
254                 for (int k = 0; k < que1.size(); k++) {
255                     for (int j = 0; j < traj.front().size(); j++) {
256                         if (graph[que1[k]][j].second > -1 && graph_flags[j]) {
257                             que2.push_back(j);
258                             graph_flags[j] = false;
259                         }
260                     }
261                 }
262                 que1 = que2;
263                 for (int j = 0; j < que2.size(); j++) {
264                     que3.push_back(que2[j]);
265                 }
266             }
267             s_graph.back() = que3;
268             for (int j = 0; j < que3.size(); j++) {
269                 for (int k = 0; k < traj.front().size(); k++) {
270                     if (graph[que3[j]][k].second > -1) {
271                         s_graph_rbr.back().push_back(std::make_pair(que3[j], k));
272                     }
273                 }
274             }
275             //std::cout << s_graph.back().size() << "   ";
276         }
277     }
278 }
279
280 bool myfunction (const std::pair< int, float > i, const std::pair< int, float > j) {
281     return i.second < j.second;
282 }
283
284 void graph_back_bone_evaluation(std::vector< std::vector < std::pair< int, int > > > &rout_n, int indxSize,
285                                 std::vector< std::vector< std::pair< float, int > > > graph, std::vector< std::vector< int > > s_graph, std::vector< std::vector< std::pair< int, int > > > s_graph_rbr) {
286     std::vector< float > key;
287     std::vector< int > path;
288     std::vector< std::pair< int, float > > que;
289     std::vector< std::pair< int, int > > a;
290     int v;
291     for (int i = 0; i < s_graph.size(); i++) {
292         key.resize(0);
293         path.resize(0);
294         que.resize(0);
295         v = 0;
296         if (s_graph[i].size() > 2) {
297             key.resize(indxSize, 2);
298             path.resize(indxSize, -1);
299             key[s_graph[i][0]] = 0;
300             for (int j = 0; j < s_graph[i].size(); j++) {
301                 que.push_back(std::make_pair(s_graph[i][j], key[s_graph[i][j]]));
302             }
303             std::sort(que.begin(), que.end(), myfunction);
304             while (!que.empty()) {
305                 v = que[0].first;
306                 que.erase(que.begin());
307                 for (int j = 0; j < s_graph_rbr[i].size(); j++) {
308                     int u = -1;
309                     if (s_graph_rbr[i][j].first == v) {
310                         u = s_graph_rbr[i][j].second;
311                     } else if (s_graph_rbr[i][j].second == v) {
312                         u = s_graph_rbr[i][j].first;
313                     }
314                     bool flag = false;
315                     int pos = -1;
316                     for (int k = 0; k < que.size(); k++) {
317                         if (que[k].first == u) {
318                             flag = true;
319                             pos = k;
320                             k = que.size() + 1;
321                         }
322                     }
323                     if (flag && key[u] > 1 - std::abs(graph[v][u].first)) {
324                         path[u] = v;
325                         key[u] = 1 - std::abs(graph[v][u].first);
326                         que[pos].second = key[u];
327                         sort(que.begin(), que.end(), myfunction);
328                     }
329                 }
330             }
331             a.resize(0);
332             rout_n.push_back(a);
333             for (int j = 0; j < indxSize; j++) {
334                 if (path[j] != -1) {
335                     rout_n.back().push_back(std::make_pair(j, path[j]));
336                 }
337             }
338         }
339     }
340 }
341
342 gmx::RVec evaluate_com(std::vector< RVec > frame) {
343     RVec temp;
344     temp[0] = 0;
345     temp[1] = 0;
346     temp[2] = 0;
347     for (int i = 0; i < frame.size(); i++) {
348         temp += frame[i];
349     }
350     temp[0] /= frame.size();
351     temp[1] /= frame.size();
352     temp[2] /= frame.size();
353     return temp;
354 }
355
356 void evaluate_diffusion(std::vector< std::vector< RVec > > trj, std::vector< float > &D/*, int max_frame_depth*/) {
357     D.resize(trj.size() * 0.9 - 1/*max_frame_depth*/);
358     float temp;
359     for (int i = 1; i < trj.size() * 0.9 /*max_frame_depth*/; i++) {
360         temp = 0;
361         for (int j = 0; j < trj.size() - 1 - i /*trj.size() - 1 - max_frame_depth*/; j++) {
362             temp += (evaluate_com(trj[j]) - evaluate_com(trj[j + i])).norm2();
363             //D[i][j] = (evaluate_com(trj[j]) - evaluate_com(trj[j + i])).norm2() / (2 * i);
364         }
365         D[i - 1] = temp / (trj.size() - 1 - i) / (2 * i * 0.000001);
366     }
367 }
368
369 /*! \brief
370  * \ingroup module_trajectoryanalysis
371  */
372
373 class SpaceTimeCorr : public TrajectoryAnalysisModule
374 {
375     public:
376
377         SpaceTimeCorr();
378         virtual ~SpaceTimeCorr();
379
380         //! Set the options and setting
381         virtual void initOptions(IOptionsContainer          *options,
382                                  TrajectoryAnalysisSettings *settings);
383
384         //! First routine called by the analysis framework
385         // virtual void initAnalysis(const t_trxframe &fr, t_pbc *pbc);
386         virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
387                                   const TopologyInformation        &top);
388
389         virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings   &settings,
390                                          const t_trxframe                   &fr);
391
392         //! Call for each frame of the trajectory
393         // virtual void analyzeFrame(const t_trxframe &fr, t_pbc *pbc);
394         virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
395                                   TrajectoryAnalysisModuleData *pdata);
396
397         //! Last routine called by the analysis framework
398         // virtual void finishAnalysis(t_pbc *pbc);
399         virtual void finishAnalysis(int nframes);
400
401         //! Routine to write output, that is additional over the built-in
402         virtual void writeOutput();
403
404     private:
405
406         SelectionList                                               sel_;
407
408         std::vector< std::vector< RVec > >                          trajectory;
409         std::vector< RVec >                                         reference;
410
411         std::vector< int >                                          index;
412         int                                                         frames              = 0;
413         int                                                         basic_frame         = 0;
414         int                                                         tau                 = 0; // selectable
415         float                                                       crl_border          = 0; // selectable
416         float                                                       eff_rad             = 1.5; // selectable
417         std::string                                                 OutPutName; // selectable
418         // Copy and assign disallowed by base.
419 };
420
421 SpaceTimeCorr::SpaceTimeCorr(): TrajectoryAnalysisModule()
422 {
423 }
424
425 SpaceTimeCorr::~SpaceTimeCorr()
426 {
427 }
428
429 void
430 SpaceTimeCorr::initOptions(IOptionsContainer          *options,
431                      TrajectoryAnalysisSettings *settings)
432 {
433     static const char *const desc[] = {
434         "[THISMODULE] to be done"
435     };
436     // Add the descriptive text (program help text) to the options
437     settings->setHelpText(desc);
438     // Add option for output file name
439     //options->addOption(FileNameOption("on").filetype(eftIndex).outputFile()
440     //                        .store(&fnNdx_).defaultBasename("domains")
441     //                        .description("Index file from the domains"));
442     // Add option for tau constant
443     options->addOption(gmx::IntegerOption("tau")
444                             .store(&tau)
445                             .description("number of frames for time travel"));
446     // Add option for crl_border constant
447     options->addOption(FloatOption("crl")
448                             .store(&crl_border)
449                             .description("make graph based on corrs > constant"));
450     // Add option for eff_rad constant
451     options->addOption(FloatOption("ef_rad")
452                             .store(&eff_rad)
453                             .description("effective radius for atoms to evaluate corrs"));
454     // Add option for selection list
455     options->addOption(SelectionOption("select_domains_and_residue").storeVector(&sel_)
456                            .required().dynamicMask().multiValue()
457                            .description("Domains to form rigid skeleton"));
458     options->addOption(StringOption("out_put")
459                             .store(&OutPutName)
460                             .description("<your name here> + <local file tag>.txt"));
461     // Control input settings
462     settings->setFlags(TrajectoryAnalysisSettings::efNoUserPBC);
463     settings->setFlag(TrajectoryAnalysisSettings::efUseTopX);
464     settings->setPBC(true);
465 }
466
467 void
468 SpaceTimeCorr::initAnalysis(const TrajectoryAnalysisSettings &settings,
469                       const TopologyInformation        &top)
470 {
471     ArrayRef< const int > atomind = sel_[0].atomIndices();
472     index.resize(0);
473     for (ArrayRef< const int >::iterator ai = atomind.begin(); (ai < atomind.end()); ai++) {
474         index.push_back(*ai);
475     }
476     trajectory.resize(0);
477
478     reference.resize(0);
479     if (top.hasFullTopology()) {
480         for (int i = 0; i < index.size(); i++) {
481             reference.push_back(top.x().at(index[i]));
482         }
483     }
484 }
485
486 void
487 SpaceTimeCorr::initAfterFirstFrame(const TrajectoryAnalysisSettings       &settings,
488                              const t_trxframe                       &fr)
489 {
490 }
491
492 // -s '/home/toluk/Develop/samples/reca_rd/reca_rd.mono.xtc' -f '/home/toluk/Develop/samples/reca_rd/reca_rd.mono.xtc' -n '/home/toluk/Develop/samples/reca_rd/test6.ndx' -sf '/home/toluk/Develop/samples/reca_rd/SelectionList5'  -tau 5 -crl 0.10
493 // -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/CorrsTestDomainsNfit.ndx' -sf '/home/toluk/Develop/samples/reca_rd/SelectionListDomainsNFit' -tau 5000 -crl 0.75 -ef_rad 1
494 // -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/TestCa.ndx' -sf '/home/toluk/Develop/samples/reca_rd/SelListCa' -tau 100 -crl 0.75 -ef_rad 1
495 // -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/testCa.ndx' -sf '/home/toluk/Develop/samples/reca_rd/SelListCa' -tau 9000 -crl 0.60 -ef_rad 1
496
497 // -s '/home/toluk/Develop/samples/CubeTermal/CUBETermalTest1.pdb' -f '/home/toluk/Develop/samples/CubeTermal/CUBETermalTest.pdb' -n '/home/toluk/Develop/samples/CubeTermal/testCa.ndx' -sf '/home/toluk/Develop/samples/CubeTermal/SelListCa' -tau 900 -crl 0.20 -ef_rad 1
498 // cube.000.000.10k.10.3.1stfrm
499 // -s '/home/toluk/Develop/samples/JustCube/cube.000.000.10k.10.3.1stfrm.pdb' -f '/home/toluk/Develop/samples/JustCube/cube.000.000.10k.10.3.pdb' -n '/home/toluk/Develop/samples/JustCube/system.ndx' -sf '/home/toluk/Develop/samples/JustCube/SLsystem' -tau 1000 -crl 0.20 -ef_rad 9000 -out_put OLA
500
501 // -s '*.pdb' -f '*.pdb' -n '*.ndx' -sf 'name' -tau 1000 -crl 0.20 -ef_rad 9000 -out_put OLA
502 // -s '*.tpr' -f '*.xtc' -n '*.ndx' -sf 'name' -tau 1000 -crl 0.30 -ef_rad 20 -out_put 'test_run'
503
504 void
505 SpaceTimeCorr::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
506                       TrajectoryAnalysisModuleData *pdata)
507 {
508     trajectory.resize(trajectory.size() + 1);
509     trajectory.back().resize(index.size());
510     for (int i = 0; i < index.size(); i++) {
511         trajectory.back()[i] = fr.x[index[i]];
512     }
513     frames++;
514 }
515
516 void
517 SpaceTimeCorr::finishAnalysis(int nframes)
518 {
519     std::vector< std::vector< std::vector< float > > > crltns;
520     std::vector< std::vector< std::pair< float, int > > > graph;
521     std::vector< std::vector< int > > sub_graph;
522     std::vector< std::vector< std::pair< int, int > > > sub_graph_rbr, rout_new;
523     int k = 1000, m = 0;
524     if (tau > 0) {
525         k = tau;
526     }
527
528     std::cout << "\nCorrelation's evaluation - start\n";
529
530     correlation_evaluation(reference, trajectory, basic_frame, crltns, m, k);
531
532     make_correlation_matrix_file(crltns, (OutPutName + "_matrix.txt").c_str(), 0);
533     std::cout << "corelation matrix printed\n";
534
535     make_correlation_pairs_file(crltns, (OutPutName + "_pairs.txt").c_str(), 0);
536     std::cout << "corelation pairs printed\n";
537
538     std::cout << "Correlation's evaluation - end\n" << "graph evaluation: start\n";
539
540     graph_calculation(graph, sub_graph, sub_graph_rbr, trajectory, basic_frame, crltns, crl_border, eff_rad, k);
541     std::cout << "graph evaluation: end\n" << "routs evaluation: start\n";
542
543     graph_back_bone_evaluation(rout_new, index.size(), graph, sub_graph, sub_graph_rbr);
544
545     std::cout << "routs evaluation: end\n";
546
547     make_rout_file(crl_border, index, rout_new, (OutPutName + "_routs.txt").c_str());
548     std::cout << "corelation routs printed\n";
549
550     make_best_corrs_graphics(crltns, rout_new, index, (OutPutName + "_routs_graphics.txt").c_str());
551     std::cout << "corelation routs' pairs' graphics printed\n";
552
553
554     /*std::cout << "extra params\n";
555     std::vector< float > diffusion;
556     evaluate_diffusion(trajectory, diffusion);
557     make_diffusion_file((OutPutName + "_diffusion.txt").c_str(), diffusion);*/
558
559     std::cout << "Finish Analysis - end\n\n";
560 }
561
562 void
563 SpaceTimeCorr::writeOutput()
564 {
565
566 }
567
568 /*! \brief
569  * The main function for the analysis template.
570  */
571 int
572 main(int argc, char *argv[])
573 {
574     return gmx::TrajectoryAnalysisCommandLineRunner::runAsMain<SpaceTimeCorr>(argc, argv);
575 }