Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-2020 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed 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 : plumed 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 plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "ReadAnalysisFrames.h" 23 : #include "core/PlumedMain.h" 24 : #include "core/ActionSet.h" 25 : #include "core/ActionRegister.h" 26 : 27 : //+PLUMEDOC ANALYSIS COLLECT_FRAMES 28 : /* 29 : This allows you to convert a trajectory and a dissimilarity matrix into a dissimilarity object 30 : 31 : \par Examples 32 : 33 : */ 34 : //+ENDPLUMEDOC 35 : 36 : namespace PLMD { 37 : namespace analysis { 38 : 39 7416 : PLUMED_REGISTER_ACTION(ReadAnalysisFrames,"COLLECT_FRAMES") 40 : 41 31 : void ReadAnalysisFrames::registerKeywords( Keywords& keys ) { 42 31 : AnalysisBase::registerKeywords( keys ); 43 124 : keys.remove("SERIAL"); keys.remove("USE_OUTPUT_DATA_FROM"); keys.use("ARG"); 44 124 : keys.add("atoms-1","ATOMS","the atoms whose positions we are tracking for the purpose of analyzing the data"); 45 124 : keys.add("atoms-1","STRIDE","the frequency with which data should be stored for analysis. By default data is collected on every step"); 46 155 : keys.add("compulsory","CLEAR","0","the frequency with which data should all be deleted and restarted"); 47 124 : keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages"); 48 31 : } 49 : 50 30 : ReadAnalysisFrames::ReadAnalysisFrames( const ActionOptions& ao ): 51 : Action(ao), 52 : AnalysisBase(ao), 53 : clearonnextstep(false), 54 : wham_pointer(NULL), 55 150 : weights_calculated(false) 56 : { 57 60 : parse("CLEAR",clearstride); 58 30 : if( clearstride!=0 ) log.printf(" clearing stored data every %u steps\n",clearstride); 59 : // Get the names of the argumes 60 30 : argument_names.resize( getNumberOfArguments() ); 61 98 : for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i]=getPntrToArgument(i)->getName(); 62 : // Find the atom numbers to read in 63 60 : parseAtomList("ATOMS",atom_numbers); 64 30 : if( atom_numbers.size()>0 ) { 65 5 : log.printf(" monitoring positions of atoms "); 66 232 : for(unsigned i=0; i<atom_numbers.size(); ++i) log.printf("%d ",atom_numbers[i].serial() ); 67 5 : log.printf("\n"); requestAtoms(atom_numbers); 68 : } 69 : 70 : // Get stuff for any reweighting that should go on 71 90 : std::vector<std::string> wwstr; parseVector("LOGWEIGHTS",wwstr); 72 30 : if( wwstr.size()>0 ) log.printf(" reweighting using weights from "); 73 30 : std::vector<Value*> arg( ActionWithArguments::getArguments() ); 74 96 : for(unsigned i=0; i<wwstr.size(); ++i) { 75 24 : ActionWithValue* val = plumed.getActionSet().selectWithLabel<ActionWithValue*>(wwstr[i]); 76 12 : if( !val ) error("could not find value named"); 77 36 : weight_vals.push_back( val->copyOutput(val->getLabel()) ); 78 36 : arg.push_back( val->copyOutput(val->getLabel()) ); 79 24 : log.printf("%s ",wwstr[i].c_str() ); 80 : } 81 30 : if( wwstr.size()>0 ) { 82 12 : log.printf("\n"); 83 12 : wham_pointer = dynamic_cast<bias::ReweightBase*>( weight_vals[0]->getPntrToAction() ); 84 12 : if( !wham_pointer ) wham_pointer = NULL; 85 12 : else if( !wham_pointer->buildsWeightStore() ) wham_pointer = NULL; 86 24 : if( wham_pointer && weight_vals.size()!=1 ) error("can only extract weights from one wham object"); 87 18 : } else log.printf(" weights are all equal to one\n"); 88 30 : requestArguments( arg ); 89 : 90 : // Now add fake components to the underlying ActionWithValue for the arguments 91 196 : for(unsigned i=0; i<argument_names.size(); ++i) { addComponent( argument_names[i] ); componentIsNotPeriodic( argument_names[i] ); } 92 30 : } 93 : 94 62 : std::vector<Value*> ReadAnalysisFrames::getArgumentList() { 95 62 : std::vector<Value*> arg_vals( ActionWithArguments::getArguments() ); 96 142 : for(unsigned i=0; i<weight_vals.size(); ++i) arg_vals.erase(arg_vals.end()-1); 97 62 : return arg_vals; 98 : } 99 : 100 5 : std::string ReadAnalysisFrames::getDissimilarityInstruction() const { 101 5 : return "TYPE=UNKNOWN"; 102 : } 103 : 104 12 : const std::vector<AtomNumber>& ReadAnalysisFrames::getAtomIndexes() const { 105 12 : return getAbsoluteIndexes(); 106 : } 107 : 108 26 : void ReadAnalysisFrames::calculateWeights() { 109 26 : weights_calculated=true; 110 52 : weights.resize( logweights.size() ); 111 26 : if( weight_vals.empty() ) { 112 9764 : for(unsigned i=0; i<logweights.size(); ++i) weights[i]=1.0; 113 : } else { 114 7 : if( wham_pointer ) { 115 14 : wham_pointer->calculateWeights( logweights.size() ); 116 4928 : for(unsigned i=0; i<logweights.size(); ++i) weights[i]=wham_pointer->getWeight(i); 117 : } else { 118 : // Find the maximum weight 119 0 : double maxweight=logweights[0]; 120 0 : for(unsigned i=1; i<getNumberOfDataPoints(); ++i) { 121 0 : if(logweights[i]>maxweight) maxweight=logweights[i]; 122 : } 123 : // Calculate weights (no memory) -- business here with maxweight is to prevent overflows 124 0 : for(unsigned i=0; i<logweights.size(); ++i) weights[i]=exp( logweights[i]-maxweight ); 125 : } 126 : } 127 26 : } 128 : 129 7500 : void ReadAnalysisFrames::update() { 130 7528 : if( getStep()==0 ) return; 131 : // Delete everything we stored now that it has been analyzed 132 7472 : if( clearonnextstep ) { 133 10 : my_data_stash.clear(); my_data_stash.resize(0); 134 10 : logweights.clear(); logweights.resize(0); 135 5 : if( wham_pointer ) wham_pointer->clearData(); 136 5 : clearonnextstep=false; 137 : } 138 : 139 : // Get the weight and store it in the weights array 140 27580 : double ww=0; for(unsigned i=0; i<weight_vals.size(); ++i) ww+=weight_vals[i]->get(); 141 7472 : weights_calculated=false; logweights.push_back(ww); 142 : 143 : // Now create the data collection object and push it back to be stored 144 14944 : unsigned index = my_data_stash.size(); my_data_stash.push_back( DataCollectionObject() ); 145 22416 : my_data_stash[index].setAtomNumbersAndArgumentNames( getLabel(), atom_numbers, argument_names ); 146 7472 : my_data_stash[index].setAtomPositions( getPositions() ); 147 49372 : for(unsigned i=0; i<argument_names.size(); ++i) my_data_stash[index].setArgument( argument_names[i], getArgument(i) ); 148 : 149 7472 : if( clearstride>0 ) { 150 475 : if( getStep()%clearstride==0 ) clearonnextstep=true; 151 : } 152 : } 153 : 154 : } 155 5517 : }