426d306ffdd7956499b09bca8b08d2e81c6444aa
[alexxy/gromacs-spacetimecorr.git] / src / corrtype.cpp
1 #include "corrtype.h"
2
3 // деструктор класса
4 correlationType::~correlationType() {}
5
6 // конструктор класса для инициализации
7 correlationType::correlationType() {}
8
9 correlationType::correlationType(const std::vector< RVec > &ref, int wnd, int taau, int tau_st, float crlUp, float effRad, int mod,
10                                  const std::string &out, const std::vector< int > &indx,
11                                  const std::vector< std::vector < std::vector < size_t > > > &sels,
12                                  const std::vector< std::string > &rsNames) {
13     setDefaults(ref, wnd, taau, tau_st, crlUp, effRad, mod, out, indx, sels, rsNames);
14 }
15
16 void correlationType::setDefaults(const std::vector< RVec > &ref, int wnd, int taau, int tau_st, float crlUp, float effRad, int mod,
17                                   const std::string &out, const std::vector< int > &indx,
18                                   const std::vector< std::vector < std::vector < size_t > > > &sels,
19                                   const std::vector< std::string > &rsNames) {
20     // очень странная штука в индуском стиле... зачем столько ифов?!!!
21     if (ref.size() != 0) {reference = ref;}
22     if (wnd != -1) {window = wnd;}
23     if (taau != -1) {tau = taau;}
24     if (tau_st != -1) {tauStep = tau_st;}
25     if (crlUp != -1) {crlUpBorder = crlUp;}
26     if (effRad != -1) {effRadius = effRad;}
27     if (mod != -1) {mode = mod;}
28     if (out != "") {outputName = out;}
29     if (sels.size() != 0) {selections = sels;}
30     if (rsNames.size() > 0) {resNames = rsNames;}
31     if (indx.size() > 0) {index = indx;}
32     subGraphRouts.resize(0);
33     trajectoryPartition();
34 }
35
36 void correlationType::update(const int frameNum, const std::vector< RVec > &curFrame) {
37     trajectory.push_back(curFrame);
38     size_t temp = window + tau;
39     if (trajectory.size() == temp + 1) {
40         trajectory.erase(trajectory.begin());
41     }
42     if (mode == 1) {
43         if ( ((frameNum - temp + 1) >= 0) && ((frameNum - temp + 1) % tauStep == 0)) {
44             correlationEval();
45             selections.erase(selections.begin());
46             std::cout << "\n\t\tcorrEval successful\n" << std::endl;
47         }
48     }
49 }
50
51 void correlationType::readEval() {
52     if (mode == 0) {
53         readWriteCorrelations(0);
54         subGraphRouts.resize(subGraphRouts.size() + 1);
55         graphCalculations(1, static_cast< size_t >(tau));
56         graphBackBoneEvaluation();
57     }
58 }
59
60 void correlationType::printData() {
61     printOutputData();
62 }
63
64 void correlationType::trajectoryPartition() {
65     std::vector< bool > temp1;
66     std::pair< size_t, size_t > temp2;
67     float temp3;
68     std::vector< std::vector < std::vector < size_t > > > selectionsTemp;
69     selectionsTemp.resize(selections.size());
70     for (size_t i1 {0}; i1 < selections.size(); i1++) {
71         selectionsTemp[i1].resize(selections[i1].size());
72         for (size_t i2 {0}; i2 < selections[i1].size(); i2++) {
73             selectionsTemp[i1][i2].resize(0);
74             for (size_t i3 {0}; i3 < selections[i1][i2].size(); i3++) {
75                 for (size_t i4 {0}; i4 < index.size(); i4++) {
76                     if (selections[i1][i2][i3] == index[i4]) {
77                         selectionsTemp[i1][i2].push_back(i4);
78                         break;
79                     }
80                 }
81             }
82         }
83     }
84     selections = selectionsTemp;
85     for (auto &k : selections) {
86         temp1.resize(0);
87         temp1.resize(index.size(), true);
88         for (auto &i : k) {
89             for (auto &j : i) {
90                 temp1[j] = false;
91             }
92         }
93         for (size_t i {0}; i < temp1.size(); i++) {
94             if (temp1[i]) {
95                 temp3 = std::numeric_limits<float>::max();
96                 for (size_t f {0}; f < k.size(); f++) {
97                     for (size_t j {0}; j < k[f].size(); j++) {
98                         if (float temp4 {(reference[k[f][j]] - reference[i]).norm()}; temp3 > temp4) {
99                             temp3 = temp4;
100                             temp2 = std::make_pair(f, j);
101                         }
102                     }
103                 }
104                 k[temp2.first].push_back(i);
105             }
106         }
107     }
108 }
109
110 void correlationType::readWriteCorrelations(int rwMode) {
111     FILE *file;
112     if (rwMode == 1) {
113         file = std::fopen((outputName + "-matrixData").c_str(), "a");
114         for (size_t i {0}; i < matrixes.size(); i++) {
115             std::fprintf(file, "%d %lud\n", count, i);
116             for (size_t j {0}; j < matrixes[i].size(); j++) {
117                 for (size_t f {0}; f < matrixes[i][j].size(); f++) {
118                     std::fprintf(file, "%.4f ", matrixes[i][j][f]); //~16
119                 }
120                 std::fprintf(file, "\n");
121             }
122         }
123         std::fclose(file);
124       }
125     if (rwMode == 0) {
126         file = std::fopen((outputName + "-matrixData").c_str(), "r+");
127         matrixes.resize(0);
128         matrixes.resize(static_cast< unsigned int >(tau + 1));
129         for (size_t i {0}; i < static_cast< size_t >(tau + 1); i++) {
130             int t0, t1, t2 = std::fscanf(file, "%d %d\n", &t0, &t1);
131             matrixes[i].resize(0);
132             matrixes[i].resize(index.size());
133             for (size_t j {0}; j < index.size(); j++) {
134                 matrixes[i][j].resize(index.size());
135                 for (size_t k {0}; k < index.size(); k++) {
136                     t2 = std::fscanf(file, "%lf ", &matrixes[i][j][k]);
137                 }
138             }
139         }
140     }
141 }
142
143 inline void correlationType::trajectoryFitting() {
144     std::vector< std::vector< std::pair< size_t, size_t > > > pairs;
145     pairs.resize(0);
146     pairs.resize(selections.front().size());
147     for (size_t i {0}; i < selections.front().size(); i++) {
148         pairs[i].resize(0);
149         for (size_t j {0}; j < selections.front()[i].size(); j++) {
150             pairs[i].push_back(std::make_pair(selections.front()[i][j], selections.front()[i][j]));
151         }
152     }
153     fitTrajectory.resize(0);
154     fitTrajectory.resize(selections.front().size(), trajectory);
155     #pragma omp parallel for schedule(dynamic) firstprivate(reference)
156     for (size_t i = 0; i < selections.front().size(); i++) {
157         for (size_t j {0}; j < fitTrajectory[i].size(); j++) {
158             MyFitNew(reference, fitTrajectory[i][j], pairs[i], 0);
159         }
160     }
161     #pragma omp barrier
162     for (size_t i {0}; i < selections.front().size(); i++) {
163         for (size_t j {0}; j < selections.front()[i].size(); j++) {
164             for (size_t k {0}; k < fitTrajectory[i].size(); k++) {
165                 trajectory[k][selections.front()[i][j]] = fitTrajectory[i][k][selections.front()[i][j]];
166             }
167         }
168     }
169 }
170
171 inline void correlationType::matrixNullFitting() {
172     matrixes.resize(0);
173     matrixes.resize(static_cast< size_t >(tau + 1));
174     for (auto &i : matrixes) {
175         i.resize(0);
176         i.resize(index.size());
177         for (auto &j : i) {
178             j.resize(0);
179             j.resize(index.size());
180             for (auto &k : j) {
181                 k = 0.;
182             }
183         }
184     }
185 }
186
187 void correlationType::correlationEval() {
188     trajectoryFitting();
189     matrixNullFitting();
190     std::vector< std::vector< double > > a, b, c;
191     std::vector< double > d;
192     d.resize(index.size(), 0.);
193     #pragma omp parallel for ordered schedule(dynamic) shared(matrixes) firstprivate(trajectory, reference)
194     for (size_t i = 0; i <= static_cast< size_t >(tau); i++) {
195         a.resize(0); b.resize(0); c.resize(0);
196         a.resize(index.size(), d); b.resize(index.size(), d); c.resize(index.size(), d);
197         for (size_t j {0}; j < static_cast< size_t >(window); j++) {
198             for (size_t k1 {0}; k1 < index.size(); k1++) {
199                 for (size_t k2 {0}; k2 < index.size(); k2++) {
200                     RVec temp1, temp2;
201                     temp1 = trajectory[j][k1]     - reference[k1];
202                     temp2 = trajectory[j + i][k2] - reference[k2];
203                     a[k1][k2] +=   (static_cast<double>(temp1[0]) * static_cast<double>(temp2[0]) +
204                                     static_cast<double>(temp1[1]) * static_cast<double>(temp2[1]) +
205                                     static_cast<double>(temp1[2]) * static_cast<double>(temp2[2]));
206                     b[k1][k2] +=   (static_cast<double>(temp1[0]) * static_cast<double>(temp1[0]) +
207                                     static_cast<double>(temp1[1]) * static_cast<double>(temp1[1]) +
208                                     static_cast<double>(temp1[2]) * static_cast<double>(temp1[2]));
209                     c[k1][k2] +=   (static_cast<double>(temp2[0]) * static_cast<double>(temp2[0]) +
210                                     static_cast<double>(temp2[1]) * static_cast<double>(temp2[1]) +
211                                     static_cast<double>(temp2[2]) * static_cast<double>(temp2[2]));
212                 }
213             }
214         }
215         for (size_t j {0}; j < index.size(); j++) {
216             for (size_t k {0}; k < index.size(); k++) {
217                 matrixes[i][j][k] = a[j][k] / (std::sqrt(b[j][k] * c[j][k]));
218             }
219         }
220     }
221     #pragma omp barrier
222     for (size_t i {0}; i < matrixes.size(); i++) {
223         for (size_t j {0}; j < matrixes[i].size(); j++) {
224             for (size_t k {0}; k < matrixes[i][j].size(); k++) {
225                 matrixes[i][j][k] = std::round(matrixes[i][j][k] * 10000) / 10000;
226             }
227         }
228     }
229     readWriteCorrelations(1);
230     count++;
231 }
232
233 void correlationType::graphCalculations(size_t tauStart, size_t tauEnd) {
234     graph.resize(0);
235     graph.resize(index.size());
236     subGraphPoints.resize(0);
237     subGraphRbr.resize(0);
238     for (size_t i {0}; i < index.size(); i++) {
239         graph[i].resize(index.size(), std::make_pair(0, -1));
240     }
241     RVec temp;
242     for (size_t i {tauStart}; i <= tauEnd; i++) {
243         for (size_t j {0}; j < index.size(); j++) {
244             for (size_t k {j}; k < index.size(); k++) {
245                 temp = reference[j] - reference[k];
246                 if (double tempIf {std::max(std::abs(matrixes[i][j][k]), std::abs(matrixes[i][k][j]))}; (tempIf >= static_cast< double >(crlUpBorder)) &&
247                     (static_cast< float >(norm(temp)) <= effRadius) && (std::abs(graph[j][k].first) < tempIf)) {
248                     graph[j][k].first = tempIf;
249                     graph[j][k].second = static_cast< int >(i);
250                 }
251             }
252         }
253     }
254     std::vector< bool > graph_flags;
255     graph_flags.resize(0);
256     graph_flags.resize(index.size(), true);
257     std::vector< size_t > a;
258     std::vector< std::pair< size_t, size_t > > b;
259     a.resize(0);
260     b.resize(0);
261     std::vector< size_t > width1, width2, tempSubGraph;
262     for (size_t i {0}; i < index.size(); i++) {
263         if (graph_flags[i]) {
264             subGraphPoints.push_back(a);
265             subGraphRbr.push_back(b);
266             width1.resize(0);
267             width2.resize(0);
268             tempSubGraph.resize(0);
269             width1.push_back(i);
270             tempSubGraph.push_back(i);
271             graph_flags[i] = false;
272             while(width1.size() > 0) {
273                 width2.resize(0);
274                 for (size_t j {0}; j < width1.size(); j++) {
275                     for (size_t k {0}; k < index.size(); k++) {
276                         if ((graph[width1[j]][k].second > -1) && graph_flags[k]) {
277                             width2.push_back(k);
278                             graph_flags[k] = false;
279                         }
280                     }
281                 }
282                 width1 = width2;
283                 for (size_t j {0}; j < width2.size(); j++) {
284                     tempSubGraph.push_back(width2[j]);
285                 }
286             }
287             subGraphPoints.back() = tempSubGraph;
288             for (size_t j {0}; j < tempSubGraph.size(); j++) {
289                 for (size_t k {0}; k < index.size(); k++) {
290                     if (graph[tempSubGraph[j]][k].second > -1) {
291                         subGraphRbr.back().push_back(std::make_pair(tempSubGraph[j], k));
292                     }
293                 }
294             }
295         }
296     }
297 }
298
299 bool correlationType::myComparisonFunction (const std::pair< int, double > i, const std::pair< int, double > j) {
300     return i.second < j.second;
301 }
302
303 void correlationType::graphBackBoneEvaluation() {
304     std::vector< double >                       key;
305     std::vector< long >                         path;
306     std::vector< std::pair< size_t, double > >  que;
307     std::vector< std::pair< size_t, size_t > >  a;
308     size_t                                      v;
309     a.resize(0);
310     subGraphRouts.back().resize(0);
311     for (size_t i {0}; i < subGraphPoints.size(); i++) {
312         key.resize(0);
313         path.resize(0);
314         que.resize(0);
315         v = 0;
316         if (subGraphPoints[i].size() > 2) {
317             key.resize(index.size(), 2);
318             path.resize(index.size(), -1);
319             key[subGraphPoints[i][0]] = 0;
320             for (size_t j {0}; j < subGraphPoints[i].size(); j++) {
321                 que.push_back(std::make_pair(subGraphPoints[i][j], key[subGraphPoints[i][j]]));
322             }
323             std::sort(que.begin(), que.end(), myComparisonFunction);
324             while (!que.empty()) {
325                 v = que.front().first;
326                 que.erase(que.begin());
327                 for (size_t j {0}; j < subGraphRbr[i].size(); j++) {
328                     long u {-1};
329                     if (subGraphRbr[i][j].first == v) {
330                         u = subGraphRbr[i][j].second;
331                     } else if (subGraphRbr[i][j].second == v) {
332                         u = subGraphRbr[i][j].first;
333                     }
334                     bool flag {false};
335                     size_t pos {0};
336                     for (size_t k {0}; k < que.size(); k++) {
337                         if (que[k].first == u) {
338                             flag = true;
339                             pos = k;
340                             k = que.size() + 1;
341                         }
342                     }
343                     if (double tempIf {1. - std::abs(graph[v][static_cast< size_t >(u)].first)};
344                             flag && (key[static_cast< size_t >(u)] > tempIf)) {
345                         path[static_cast< size_t >(u)] = v;
346                         key[static_cast< size_t >(u)] = tempIf;
347                         que[pos].second = key[static_cast< size_t >(u)];
348                         sort(que.begin(), que.end(), myComparisonFunction);
349                     }
350                 }
351             }
352             subGraphRouts.back().push_back(a);
353             for (size_t j {0}; j < index.size(); j++) {
354                 if (path[j] != -1) {
355                     subGraphRouts.back().back().push_back(std::make_pair(path[j], j));
356                 }
357             }
358         }
359     }
360 }
361
362 void correlationType::printOutputData() {
363     FILE *file {std::fopen((outputName + "-arrowsData.txt").c_str(), "w+")};
364     size_t same, pre {0};
365     std::vector< std::tuple< int, int, std::vector< int > > > table;
366     table.resize(0);
367     std::vector< int > a;
368     for (size_t i {0}; i < subGraphRouts.size(); i++) {
369         same = i;
370         for (size_t j {i + 1}; j < subGraphRouts.size(); j++) {
371             if (subGraphRouts[j] == subGraphRouts[i]) {
372                 same = j;
373             } else {
374                 break;
375             }
376         }
377         if (i == same) {
378             std::fprintf(file, "\n Starting time point = %d | correlations >= %0.2f | tau = %d | window = %d\n\n", static_cast< int >(i) * tauStep, static_cast< double >(crlUpBorder), tau, window);
379         } else {
380             std::fprintf(file, "\n Starting time point = [%d ; %d] | correlations >= %0.2f | tau = %d | window = %d\n\n", static_cast< int >(i) * tauStep, static_cast< int >(same) * tauStep, static_cast< double >(crlUpBorder), tau, window);
381         }
382         for (size_t j {0}; j < subGraphRouts[i].size(); j++) {
383             for (size_t k {0}; k < subGraphRouts[i][j].size(); k++) {
384                 std::fprintf(file, "cgo_arrow (id %3d), (id %3d), radius=0.05\n", index[subGraphRouts[i][j][k].first] + 1, index[subGraphRouts[i][j][k].second] + 1);
385             }
386             std::fprintf(file, "\n");
387         }
388         table.resize(0);
389         for (auto &j : subGraphRouts[i]) {
390             for (auto &k : j) {
391                 bool flag1 {true}, flag2 {true};
392                 for (size_t m {0}; m < table.size(); m++) {
393                     if (std::get<0>(table[m]) == index[k.first]) {
394                         std::get<1>(table[m])++;
395                         std::get<2>(table[m]).push_back(index[k.second]);
396                         flag1 = false;
397                     }
398                     if (std::get<0>(table[m]) == index[k.second]) {
399                         std::get<1>(table[m])++;
400                         std::get<2>(table[m]).push_back(index[k.first]);
401                         flag2 = false;
402                     }
403                 }
404                 if (flag1) {
405                     a.resize(0);
406                     a.push_back(index[k.second]);
407                     table.push_back(std::make_tuple(index[k.first], 1, a));
408                 }
409                 if (flag2) {
410                     a.resize(0);
411                     a.push_back(index[k.first]);
412                     table.push_back(std::make_tuple(index[k.second], 1, a));
413                 }
414             }
415         }
416         for (size_t j {0}; j < table.size(); j++) {
417             std::fprintf(file, "residue %s connections %d | ", (resNames[static_cast< size_t >(std::find(index.begin(), index.end(), std::get<0>(table[j])) - index.begin())]).c_str(), std::get<1>(table[j]));
418             for (size_t k {0}; k < std::get<2>(table[j]).size(); k++) {
419                 std::fprintf(file, "%s ", (resNames[static_cast< size_t >(std::find(index.begin(), index.end(), std::get<2>(table[j])[k]) - index.begin())]).c_str());
420             }
421             std::fprintf(file, "\n");
422         }
423         if (pre != 0) {
424             std::vector< std::vector< std::pair< size_t, size_t > > > temp01, temp02;
425             std::vector< std::pair< size_t, size_t > > temp03, temp04, temp05;
426             temp01 = subGraphRouts[pre];
427             temp02 = subGraphRouts[same];
428             temp03.resize(0);
429             temp04.resize(0);
430             temp05.resize(0);
431             for (auto &j : temp01) {
432                 for (auto &k : j) {
433                     temp03.push_back(k);
434                 }
435             }
436             for (auto &j : temp02) {
437                 for (auto &k : j) {
438                     temp04.push_back(k);
439                 }
440             }
441             std::sort(temp03.begin(), temp03.end());
442             std::sort(temp04.begin(), temp04.end());
443             std::set_difference(temp03.begin(), temp03.end(), temp04.begin(), temp04.end(), std::inserter(temp05, temp05.begin()));
444             std::fprintf(file, "minus:\n");
445             for (auto &j : temp05) {
446                 std::fprintf(file, "cgo_arrow (id %3d), (id %3d), radius=0.05\n", index[j.first] + 1, index[j.second] + 1);
447             }
448             temp05.resize(0);
449             std::set_difference(temp04.begin(), temp04.end(), temp03.begin(), temp03.end(), std::inserter(temp05, temp05.begin()));
450             std::fprintf(file, "plus:\n");
451             for (auto &j : temp05) {
452                 std::fprintf(file, "cgo_arrow (id %3d), (id %3d), radius=0.05\n", index[j.first] + 1, index[j.second] + 1);
453             }
454         }
455         pre = same;
456         i = same;
457     }
458     std::fclose(file);
459 }