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
47 #include <gromacs/trajectoryanalysis.h>
48 #include <gromacs/pbcutil/pbc.h>
49 #include <gromacs/utility/smalloc.h>
50 #include <gromacs/math/do_fit.h>
52 #include "fittingn.cpp"
54 #define MAX_NTRICVEC 12
66 void make_graph(int mgwi_natoms, rvec *mgwi_x, std::vector< std::vector< node > > &mgwi_graph)
68 mgwi_graph.resize(mgwi_natoms);
69 for (int i = 0; i < mgwi_natoms; i++) {
70 mgwi_graph[i].resize(mgwi_natoms);
72 for (int i = 0; i < mgwi_natoms; i++) {
73 for (int j = 0; j < mgwi_natoms; j++) {
74 rvec_sub(mgwi_x[i], mgwi_x[j], mgwi_graph[i][j].r);
75 mgwi_graph[i][j].n = 0;
80 void update_graph(std::vector< std::vector< node > > &ugwi_graph, rvec *ugwi_x, long double ugwi_epsi) {
82 int ugwi_for = ugwi_graph.size();
83 for (int i = 0; i < ugwi_for; i++) {
84 for (int j = i; j < ugwi_for; j++) {
85 rvec_sub(ugwi_x[i], ugwi_x[j], ugwi_temp);
86 rvec_dec(ugwi_temp, ugwi_graph[i][j].r.as_vec());
87 if (norm(ugwi_temp) <= ugwi_epsi) {
100 void update_graph_v2(std::vector< std::vector< node > > &ugwi_graph, std::vector < RVec > ugwi_x, long double ugwi_epsi) {
102 int ugwi_for = ugwi_graph.size();
103 for (int i = 0; i < ugwi_for; i++) {
104 for (int j = i; j < ugwi_for; j++) {
105 rvec_sub(ugwi_x[i].as_vec(), ugwi_x[j].as_vec(), ugwi_temp);
106 rvec_dec(ugwi_temp, ugwi_graph[i][j].r.as_vec());
107 if (norm(ugwi_temp) <= ugwi_epsi) {
109 ugwi_graph[i][j].n++;
112 ugwi_graph[i][j].n++;
113 ugwi_graph[j][i].n++;
120 void check_domains(long double cd_delta, int cd_frames, std::vector< std::vector< std::vector< node > > > &cd_graph) {
121 int cd_for1 = cd_graph.size(), cd_for2 = cd_graph[1].size();
122 for (int k = 0; k < cd_for1; k++) {
123 for (int i = 0; i < cd_for2; i++) {
124 for (int j = 0; j < cd_for2; j++) {
125 if (cd_graph[k][i][j].n >= cd_frames * cd_delta) {
126 cd_graph[k][i][j].yep = true;
129 cd_graph[k][i][j].yep = false;
136 void find_domain_sizes(std::vector< std::vector< std::vector< node > > > fds_graph, std::vector< std::vector< int > > &fds_domsizes) {
137 fds_domsizes.resize(fds_graph.size());
138 int fds_for1 = fds_graph.size(), fds_for2 = fds_graph[1].size();
139 for (int i = 0; i < fds_for1; i++) {
140 fds_domsizes[i].resize(fds_for2, 0);
141 for (int j = 0; j < fds_for2; j++) {
142 for (int k = 0; k < fds_for2; k++) {
143 if (fds_graph[i][j][k].yep) {
144 fds_domsizes[i][j]++;
151 void get_maxsized_domain(std::vector< int > &gmd_max_d, std::vector< std::vector< std::vector< node > > > gmd_graph, std::vector< std::vector< int > > gmd_domsizes) {
152 int gmd_number1 = 0, gmd_number2 = 0;
153 int gmd_for1 = gmd_domsizes.size(), gmd_for2 = gmd_domsizes[0].size();
154 for (int i = 0; i < gmd_for1; i++) {
155 for (int j = 0; j < gmd_for2; j++) {
156 if (gmd_domsizes[i][j] >= gmd_domsizes[gmd_number1][gmd_number2]) {
163 int gmd_for3 = gmd_graph[gmd_number1][gmd_number2].size();
164 for (int i = 0; i < gmd_for3; i++) {
165 if (gmd_graph[gmd_number1][gmd_number2][i].yep) {
166 gmd_max_d.push_back(i);
171 void get_min_domain(std::vector< int > &gmd_min_d, std::vector< std::vector< std::vector< node > > > gmd_graph, std::vector< std::vector< int > > gmd_domsizes, int gmd_min_dom_size) {
172 int gmd_number1 = 0, gmd_number2 = 0;
173 int gmd_for1 = gmd_domsizes.size(), gmd_for2 = gmd_domsizes[0].size();
174 for (int i = 0; i < gmd_for1; i++) {
175 for (int j = 0; j < gmd_for2; j++) {
176 if (gmd_domsizes[gmd_number1][gmd_number2] < gmd_min_dom_size && gmd_domsizes[i][j] >= gmd_min_dom_size) {
180 if (gmd_domsizes[i][j] <= gmd_domsizes[gmd_number1][gmd_number2] && gmd_domsizes[i][j] >= gmd_min_dom_size) {
187 int gmd_for3 = gmd_graph[gmd_number1][gmd_number2].size();
188 for (int i = 0; i < gmd_for3; i++) {
189 if (gmd_graph[gmd_number1][gmd_number2][i].yep) {
190 gmd_min_d.push_back(i);
195 void delete_domain_from_graph(std::vector< std::vector< std::vector< node > > > &ddf_graph, std::vector< int > ddf_domain) {
196 int ddfg_for1 = ddf_domain.size(), ddfg_for2 = ddf_graph.size(), ddfg_for3 = ddf_graph[1].size();
197 for (int i = 0; i < ddfg_for1; i++) {
198 for (int k = 0; k < ddfg_for2; k++) {
199 for (int j = 0; j < ddfg_for3; j++) {
200 if (ddf_graph[k][ddf_domain[i]][j].yep) {
201 ddf_graph[k][ddf_domain[i]][j].yep = false;
203 if (ddf_graph[k][j][ddf_domain[i]].yep) {
204 ddf_graph[k][j][ddf_domain[i]].yep = false;
211 bool check_domsizes(std::vector< std::vector< int > > cd_domsizes, int cd_domain_min_size) {
212 int cd_for1 = cd_domsizes.size(), cd_for2 = cd_domsizes[0].size();
213 for (int i = 0; i < cd_for1; i++) {
214 for (int j = 0; j < cd_for2; j++) {
215 if (cd_domsizes[i][j] >= cd_domain_min_size) {
223 void print_domains(std::vector< std::vector< int > > pd_domains, std::vector< int > index, std::string fnNdx_, int dms, double epsi, double delta) {
225 fpNdx_ = std::fopen(fnNdx_.c_str(), "w+");
227 for (int i = 0; i < pd_domains.size(); i++) {
228 std::fprintf(fpNdx_, "[domain_â„–_%3d_%3d_%4.3f_%4.3f]\n", i + 1, dms, epsi, delta);
230 for (int j = 0; j < pd_domains[i].size(); j++) {
232 if (write_count > 20) {
234 std::fprintf(fpNdx_, "\n");
236 std::fprintf(fpNdx_, "%5d ", index[pd_domains[i][j]] + 1);
237 std::printf("%5d ", index[pd_domains[i][j]] + 1);
240 std::fprintf(fpNdx_,"\n\n");
242 std::fprintf(fpNdx_,"\n");
247 * \ingroup module_trajectoryanalysis
249 class Domains : public TrajectoryAnalysisModule
256 //! Set the options and setting
257 virtual void initOptions(IOptionsContainer *options,
258 TrajectoryAnalysisSettings *settings);
260 //! First routine called by the analysis framework
261 // virtual void initAnalysis(const t_trxframe &fr, t_pbc *pbc);
262 virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
263 const TopologyInformation &top);
265 virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
266 const t_trxframe &fr);
268 //! Call for each frame of the trajectory
269 // virtual void analyzeFrame(const t_trxframe &fr, t_pbc *pbc);
270 virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
271 TrajectoryAnalysisModuleData *pdata);
273 //! Last routine called by the analysis framework
274 // virtual void finishAnalysis(t_pbc *pbc);
275 virtual void finishAnalysis(int nframes);
277 //! Routine to write output, that is additional over the built-in
278 virtual void writeOutput();
284 std::vector< std::vector< std::vector< node > > > graph;
286 std::vector< std::vector< int > > domains;
287 std::vector< std::vector< int > > domsizes;
289 std::vector< int > index;
290 std::vector< int > numbers;
291 std::vector< std::vector < RVec > > trajectory;
294 int domain_min_size = 5; // selectable
297 std::vector< std::vector< std::pair< int, int > > > w_rls2;
299 double delta = 0.90; // selectable
300 double epsi = 0.15; // selectable
303 int DomainSearchingAlgorythm = 0; // selectable
304 // Copy and assign disallowed by base.
307 Domains::Domains(): TrajectoryAnalysisModule()
316 Domains::initOptions(IOptionsContainer *options,
317 TrajectoryAnalysisSettings *settings)
319 static const char *const desc[] = {
320 "[THISMODULE] to be done"
322 // Add the descriptive text (program help text) to the options
323 settings->setHelpText(desc);
324 // Add option for selecting a subset of atoms
325 options->addOption(SelectionOption("select")
326 .store(&selec).required()
327 .description("Atoms that are considered as part of the excluded volume"));
328 // Add option for output file name
329 options->addOption(FileNameOption("on").filetype(eftIndex).outputFile()
330 .store(&fnNdx_).defaultBasename("domains")
331 .description("Index file from the domains"));
332 // Add option for domain min size constant
333 options->addOption(gmx::IntegerOption("dms")
334 .store(&domain_min_size)
335 .description("minimum domain size"));
336 // Add option for Domain's Searching Algorythm
337 options->addOption(gmx::IntegerOption("DSA")
338 .store(&DomainSearchingAlgorythm)
339 .description("Domain's Searching Algorythm: 0 == default (from bigger to smaller) | 1 == (from smaller to bigger)"));
340 // Add option for epsi constant
341 options->addOption(DoubleOption("epsilon")
343 .description("thermal vibrations' constant"));
344 // Add option for delta constant
345 options->addOption(DoubleOption("delta")
347 .description("domain membership probability"));
348 // Control input settings
349 settings->setFlags(TrajectoryAnalysisSettings::efNoUserPBC);
350 settings->setPBC(true);
354 Domains::initAnalysis(const TrajectoryAnalysisSettings &settings,
355 const TopologyInformation &top)
360 Domains::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings,
361 const t_trxframe &fr)
364 for (ArrayRef< const int >::iterator ai = selec.atomIndices().begin(); (ai < selec.atomIndices().end()); ai++) {
365 index.push_back(*ai);
367 trajectory.resize(2);
368 trajectory[0].resize(selec.atomCount());
370 for (int i = 0; i < selec.atomCount(); i++) {
371 trajectory[0][i] = fr.x[index[i]];
377 bone = index.size() - domain_min_size + 1;
381 for (int i = 0; i < bone; i++) {
382 snew(w_rls[i], index.size());
383 for (int j = 0; j < index.size(); j++) {
384 if (j >= i && j <= i + domain_min_size - 1) {
391 for (int j = 0; j < domain_min_size; j++) {
392 w_rls2[i].push_back(std::make_pair(j + i, j + i));
395 snew(etalon, index.size());
396 for (int j = 0; j < index.size(); j++) {
397 copy_rvec(trajectory[0][j].as_vec(), etalon[j]);
399 reset_x(index.size(), NULL, index.size(), NULL, etalon, w_rls[i]);
400 make_graph(index.size(), etalon, graph[i]);
403 trajectory[1].resize(index.size());
407 Domains::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
408 TrajectoryAnalysisModuleData *pdata)
410 for (int i = 0; i < index.size(); i++) {
411 trajectory[1][i] = fr.x[index[i]];
413 std::vector < RVec > temp;
418 #pragma omp for schedule(dynamic)
419 for (int j = 0; j < bone; j++) {
420 /*rvec *etalon, *traj;
421 snew(etalon, index.size());
422 for (int k = 0; k < index.size(); k++) {
423 copy_rvec(trajectory[0][k].as_vec(), etalon[k]);
425 snew(traj, index.size());
426 for (int k = 0; k < index.size(); k++) {
427 copy_rvec(trajectory[1][k].as_vec(), traj[k]);
429 reset_x(index.size(), NULL, index.size(), NULL, etalon, w_rls[j]);
430 reset_x(index.size(), NULL, index.size(), NULL, traj, w_rls[j]);
431 do_fit(index.size(), w_rls[j], etalon, traj);
432 update_graph(graph[j], traj, epsi);
436 std::vector < RVec > temp = trajectory[1];
437 MyFitNew(trajectory[0], temp, w_rls2[j]);
438 update_graph_v2(graph[j], temp, epsi);
441 std::cout << "frame: " << frames << " analyzed\n";
445 Domains::finishAnalysis(int nframes)
449 std::cout << "final cheking\n";
450 check_domains(delta, frames, graph);
452 std::cout << "finding domains' sizes\n";
453 find_domain_sizes(graph, domsizes);
455 std::cout << "finding domains\n";
456 std::vector< int > a;
458 while (check_domsizes(domsizes, domain_min_size)) {
459 domains.push_back(a);
460 if (DomainSearchingAlgorythm == 0) {
461 get_maxsized_domain(domains.back(), graph, domsizes);
462 } else if (DomainSearchingAlgorythm == 1) {
463 get_min_domain(domains.back(), graph, domsizes, domain_min_size);
465 std::cout << "new domain: " << domains.back().size() << " atoms\n";
466 delete_domain_from_graph(graph, domains.back());
468 find_domain_sizes(graph, domsizes);
470 for (int i = 0; i < bone; i++) {
477 Domains::writeOutput()
479 std::cout << "making output file\n";
480 print_domains(domains, index, fnNdx_, domain_min_size, epsi, delta); // see function for details | numbers from index
481 std::cout << "\n END \n";
485 * The main function for the analysis template.
488 main(int argc, char *argv[])
490 return gmx::TrajectoryAnalysisCommandLineRunner::runAsMain<Domains>(argc, argv);