Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2023 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 "analysis/AnalysisBase.h" 23 : #include "reference/ReferenceAtoms.h" 24 : #include "reference/ReferenceArguments.h" 25 : #include "core/ActionRegister.h" 26 : #include "core/PlumedMain.h" 27 : #include "core/ActionSet.h" 28 : #include "core/Atoms.h" 29 : #include "core/GenericMolInfo.h" 30 : #include "tools/PDB.h" 31 : #include "PCA.h" 32 : 33 : namespace PLMD { 34 : namespace dimred { 35 : 36 : //+PLUMEDOC DIMRED OUTPUT_PCA_PROJECTION 37 : /* 38 : This is used to output the projection calculated by principle component analysis 39 : 40 : \par Examples 41 : 42 : */ 43 : //+ENDPLUMEDOC 44 : 45 : class OutputPCAProjection : public analysis::AnalysisBase { 46 : private: 47 : PDB mypdb; 48 : PCA* mypca; 49 : std::string fmt; 50 : std::string filename; 51 : public: 52 : static void registerKeywords( Keywords& keys ); 53 : explicit OutputPCAProjection( const ActionOptions& ); 54 0 : void performTask( const unsigned&, const unsigned&, MultiValue& ) const { 55 0 : plumed_error(); 56 : } 57 : void performAnalysis(); 58 : }; 59 : 60 13789 : PLUMED_REGISTER_ACTION(OutputPCAProjection,"OUTPUT_PCA_PROJECTION") 61 : 62 6 : void OutputPCAProjection::registerKeywords( Keywords& keys ) { 63 6 : analysis::AnalysisBase::registerKeywords( keys ); 64 12 : keys.add("compulsory","FILE","the name of the file to output to"); 65 12 : keys.add("optional","FMT","the format to use in the output file"); 66 12 : keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data. The default value of 0 tells plumed to use all the data"); 67 6 : } 68 : 69 2 : OutputPCAProjection::OutputPCAProjection( const ActionOptions& ao ): 70 : Action(ao), 71 : analysis::AnalysisBase(ao), 72 2 : fmt("%f") { 73 : // Setup the PCA object 74 2 : mypca = dynamic_cast<PCA*>( my_input_data ); 75 2 : if( !mypca ) { 76 0 : error("input must be a PCA object"); 77 : } 78 : 79 : // Get setup the pdb 80 2 : mypdb.setAtomNumbers( my_input_data->getAtomIndexes() ); 81 2 : mypdb.setArgumentNames( (mypca->my_input_data)->getArgumentNames() ); 82 : 83 : // Find a moldata object 84 2 : auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this); 85 2 : if( moldat ) { 86 2 : warning("PDB output files do not have atom types unless you use MOLDATA"); 87 : } 88 : 89 2 : parse("FILE",filename); 90 4 : parse("FMT",fmt); 91 2 : if( !getRestart() ) { 92 2 : OFile ofile; 93 2 : ofile.link(*this); 94 2 : ofile.setBackupString("analysis"); 95 2 : ofile.backupAllFiles(filename); 96 2 : } 97 2 : log.printf(" printing data to file named %s \n",filename.c_str() ); 98 2 : } 99 : 100 2 : void OutputPCAProjection::performAnalysis() { 101 : // Find a moldata object 102 2 : auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this); 103 : // Output the embedding in plumed pdb format 104 2 : OFile afile; 105 2 : afile.link(*this); 106 2 : afile.setBackupString("analysis"); 107 2 : mypdb.setAtomPositions( (mypca->myref)->getReferencePositions() ); 108 4 : for(unsigned j=0; j<mypca->getArguments().size(); ++j) { 109 2 : mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), (mypca->myref)->getReferenceArgument(j) ); 110 : } 111 : // And output the first frame 112 2 : afile.open( filename ); 113 2 : afile.printf("REMARK TYPE=%s \n", mypca->mtype.c_str() ); 114 2 : if( plumed.getAtoms().usingNaturalUnits() ) { 115 0 : mypdb.print( 1.0, mymoldat, afile, fmt ); 116 : } else { 117 2 : mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, afile, fmt ); 118 : } 119 : // And now output the eigenvectors 120 6 : for(unsigned dim=0; dim<mypca->nlow; ++dim) { 121 4 : afile.printf("REMARK TYPE=DIRECTION \n"); 122 4 : mypdb.setAtomPositions( mypca->directions[dim].getReferencePositions() ); 123 8 : for(unsigned j=0; j<mypca->getArguments().size(); ++j) { 124 4 : mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), mypca->directions[dim].getReferenceArgument(j) ); 125 : } 126 4 : if( plumed.getAtoms().usingNaturalUnits() ) { 127 0 : mypdb.print( 1.0, mymoldat, afile, fmt ); 128 : } else { 129 4 : mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, afile, fmt ); 130 : } 131 : } 132 2 : afile.close(); 133 2 : } 134 : 135 : } 136 : }