Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2018 The VES code team
3 : (see the PEOPLE-VES file at the root of this folder for a list of names)
4 :
5 : See http://www.ves-code.org for more information.
6 :
7 : This file is part of VES code module.
8 :
9 : The VES code module is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : The VES code module 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
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with the VES code module. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 :
23 : #include "TargetDistribution.h"
24 :
25 : #include "GridIntegrationWeights.h"
26 : #include "VesTools.h"
27 :
28 : #include "core/ActionRegister.h"
29 : #include "core/PlumedMain.h"
30 : #include "tools/File.h"
31 : #include "tools/Grid.h"
32 :
33 :
34 : namespace PLMD {
35 : namespace ves {
36 :
37 : //+PLUMEDOC VES_UTILS VES_OUTPUT_TARGET_DISTRIBUTION
38 : /*
39 : Output target distribution to file.
40 :
41 : This action can be used to output target distributions to a grid file,
42 : for example to see how they look like before using them in a VES bias.
43 : This action only support static target distributions.
44 :
45 : This action is normally used through the \ref driver.
46 :
47 :
48 : \par Examples
49 :
50 : In the following input we define a target distribution that is uniform for
51 : argument 1 and a Gaussian for argument 2 and then output it to a file
52 : called targetdist-1.data.
53 : \plumedfile
54 : t1_1: TD_UNIFORM MINIMA=-4.0 MAXIMA=+4.0
55 : t1_2: TD_GAUSSIAN CENTER1=-2.0 SIGMA1=0.5
56 : t1: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=t1_1,t1_2
57 :
58 : VES_OUTPUT_TARGET_DISTRIBUTION ...
59 : GRID_MIN=-4.0,-4.0
60 : GRID_MAX=+4.0,+4.0
61 : GRID_BINS=100,100
62 : TARGET_DISTRIBUTION=t1
63 : TARGETDIST_FILE=targetdist-1.data
64 : LOG_TARGETDIST_FILE=targetdist-1.log.data
65 : FMT_GRIDS=%11.6f
66 : ... VES_OUTPUT_TARGET_DISTRIBUTION
67 : \endplumedfile
68 :
69 : This input should be run through the driver by using a command similar to the
70 : following one where the trajectory/configuration file conf.gro is needed to
71 : trick the code to exit correctly.
72 : \verbatim
73 : plumed driver --plumed plumed.dat --igro conf.gro
74 : \endverbatim
75 :
76 : */
77 : //+ENDPLUMEDOC
78 :
79 :
80 120 : class OutputTargetDistribution :
81 : public Action
82 : {
83 : public:
84 : explicit OutputTargetDistribution(const ActionOptions&);
85 0 : void calculate() {}
86 0 : void apply() {}
87 : static void registerKeywords(Keywords& keys);
88 : };
89 :
90 :
91 6572 : PLUMED_REGISTER_ACTION(OutputTargetDistribution,"VES_OUTPUT_TARGET_DISTRIBUTION")
92 :
93 121 : void OutputTargetDistribution::registerKeywords(Keywords& keys) {
94 121 : Action::registerKeywords(keys);
95 484 : keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
96 484 : keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
97 484 : keys.add("compulsory","GRID_BINS","the number of bins used for the grid.");
98 484 : keys.add("optional","GRID_PERIODICITY","specfiy if the individual arguments should be made periodic (YES) or not (NO). By default all arguments are taken as not periodic.");
99 484 : keys.add("compulsory","TARGETDIST_FILE","filename of the file for writing the target distribution");
100 484 : keys.add("optional","LOG_TARGETDIST_FILE","filename of the file for writing the log of the target distribution");
101 484 : keys.add("compulsory","TARGET_DISTRIBUTION","the target distribution to be used.");
102 484 : keys.add("optional","FMT_GRIDS","the numerical format of the target distribution grids written to file. By default it is %14.9f");
103 363 : keys.addFlag("DO_1D_PROJECTIONS",false,"Also output the one-dimensional marginal distributions for multi-dimensional target distribution.");
104 121 : }
105 :
106 120 : OutputTargetDistribution::OutputTargetDistribution(const ActionOptions&ao):
107 120 : Action(ao)
108 : {
109 :
110 : std::string targetdist_fname;
111 240 : parse("TARGETDIST_FILE",targetdist_fname);
112 : std::string log_targetdist_fname;
113 240 : parse("LOG_TARGETDIST_FILE",log_targetdist_fname);
114 120 : if(targetdist_fname==log_targetdist_fname) {
115 0 : plumed_merror("error in " + getName() + ":TARGETDIST_FILE and LOG_TARGETDIST_FILE cannot be the same");
116 : }
117 :
118 : std::vector<unsigned int> grid_bins;
119 240 : parseVector("GRID_BINS",grid_bins);
120 120 : unsigned int nargs = grid_bins.size();
121 :
122 240 : std::vector<std::string> grid_min(nargs);
123 240 : parseVector("GRID_MIN",grid_min);
124 240 : std::vector<std::string> grid_max(nargs);
125 240 : parseVector("GRID_MAX",grid_max);
126 :
127 240 : std::vector<std::string> grid_periodicity(nargs);
128 240 : parseVector("GRID_PERIODICITY",grid_periodicity);
129 232 : if(grid_periodicity.size()==0) {grid_periodicity.assign(nargs,"NO");}
130 :
131 120 : std::string fmt_grids="%14.9f";
132 240 : parse("FMT_GRIDS",fmt_grids);
133 :
134 120 : bool do_1d_proj = false;
135 240 : parseFlag("DO_1D_PROJECTIONS",do_1d_proj);
136 120 : if(do_1d_proj && nargs==1) {
137 0 : plumed_merror("doesn't make sense to use the DO_1D_PROJECTIONS keyword for a one-dimensional distribution");
138 : }
139 :
140 120 : plumed_massert(grid_min.size()==nargs,"mismatch between number of values given for grid parameters");
141 120 : plumed_massert(grid_max.size()==nargs,"mismatch between number of values given for grid parameters");
142 120 : plumed_massert(grid_periodicity.size()==nargs,"mismatch between number of values given for grid parameters");
143 :
144 : std::string targetdist_label;
145 240 : parse("TARGET_DISTRIBUTION",targetdist_label);
146 120 : checkRead();
147 : //
148 120 : std::vector<Value*> arguments(nargs);
149 454 : for(unsigned int i=0; i < nargs; i++) {
150 167 : std::string is; Tools::convert(i+1,is);
151 167 : if(nargs==1) {is="";}
152 501 : arguments[i]= new Value(NULL,"arg"+is,false);
153 167 : if(grid_periodicity[i]=="YES") {
154 22 : arguments[i]->setDomain(grid_min[i],grid_max[i]);
155 : }
156 156 : else if(grid_periodicity[i]=="NO") {
157 156 : arguments[i]->setNotPeriodic();
158 : }
159 : else {
160 0 : plumed_merror("wrong value given in GRID_PERIODICITY, either specfiy YES or NO");
161 : }
162 : }
163 :
164 120 : std::string error_msg = "";
165 240 : TargetDistribution* targetdist_pntr = VesTools::getPointerFromLabel<TargetDistribution*>(targetdist_label,plumed.getActionSet(),error_msg);
166 120 : if(error_msg.size()>0) {plumed_merror("Error in keyword TARGET_DISTRIBUTION of "+getName()+": "+error_msg);}
167 : //
168 120 : if(targetdist_pntr->isDynamic()) {
169 0 : plumed_merror(getName() + " only works for static target distributions");
170 : }
171 120 : targetdist_pntr->setupGrids(arguments,grid_min,grid_max,grid_bins);
172 120 : targetdist_pntr->updateTargetDist();
173 : Grid* targetdist_grid_pntr = targetdist_pntr->getTargetDistGridPntr();
174 : Grid* log_targetdist_grid_pntr = targetdist_pntr->getLogTargetDistGridPntr();
175 :
176 :
177 120 : double sum_grid = TargetDistribution::integrateGrid(targetdist_grid_pntr);
178 120 : log.printf(" target distribution integrated over the grid: %16.12f\n",sum_grid);
179 120 : log.printf(" (%30.16e)\n",sum_grid);
180 : //
181 240 : OFile ofile;
182 120 : ofile.link(*this);
183 120 : ofile.enforceBackup();
184 120 : ofile.open(targetdist_fname);
185 : targetdist_grid_pntr->setOutputFmt(fmt_grids);
186 120 : targetdist_grid_pntr->writeToFile(ofile);
187 120 : ofile.close();
188 120 : if(log_targetdist_fname.size()>0) {
189 46 : OFile ofile2;
190 23 : ofile2.link(*this);
191 23 : ofile2.enforceBackup();
192 23 : ofile2.open(log_targetdist_fname);
193 : log_targetdist_grid_pntr->setOutputFmt(fmt_grids);
194 23 : log_targetdist_grid_pntr->writeToFile(ofile2);
195 23 : ofile2.close();
196 : }
197 :
198 120 : if(do_1d_proj) {
199 20 : for(unsigned int i=0; i<nargs; i++) {
200 16 : std::vector<std::string> arg1d(1);
201 16 : arg1d[0] = arguments[i]->getName();
202 16 : Grid marginal_grid = targetdist_pntr->getMarginal(arg1d);
203 : //
204 : std::string suffix;
205 8 : Tools::convert(i+1,suffix);
206 16 : suffix = "proj-" + suffix;
207 16 : std::string marginal_fname = FileBase::appendSuffix(targetdist_fname,"."+suffix);
208 : //
209 16 : OFile ofile3;
210 8 : ofile3.link(*this);
211 8 : ofile3.enforceBackup();
212 8 : ofile3.open(marginal_fname);
213 : marginal_grid.setOutputFmt(fmt_grids);
214 8 : marginal_grid.writeToFile(ofile3);
215 : }
216 : }
217 :
218 : //
219 454 : for(unsigned int i=0; i < nargs; i++) {
220 334 : delete arguments[i];
221 : }
222 : arguments.clear();
223 :
224 :
225 120 : }
226 :
227 :
228 :
229 :
230 :
231 : }
232 4839 : }
|