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 { plumed_error(); } 55 : void performAnalysis(); 56 : }; 57 : 58 10423 : PLUMED_REGISTER_ACTION(OutputPCAProjection,"OUTPUT_PCA_PROJECTION") 59 : 60 3 : void OutputPCAProjection::registerKeywords( Keywords& keys ) { 61 3 : analysis::AnalysisBase::registerKeywords( keys ); 62 6 : keys.add("compulsory","FILE","the name of the file to output to"); 63 6 : keys.add("optional","FMT","the format to use in the output file"); 64 6 : 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"); 65 3 : } 66 : 67 2 : OutputPCAProjection::OutputPCAProjection( const ActionOptions& ao ): 68 : Action(ao), 69 : analysis::AnalysisBase(ao), 70 2 : fmt("%f") 71 : { 72 : // Setup the PCA object 73 2 : mypca = dynamic_cast<PCA*>( my_input_data ); 74 2 : if( !mypca ) error("input must be a PCA object"); 75 : 76 : // Get setup the pdb 77 2 : mypdb.setAtomNumbers( my_input_data->getAtomIndexes() ); 78 2 : mypdb.setArgumentNames( (mypca->my_input_data)->getArgumentNames() ); 79 : 80 : // Find a moldata object 81 2 : auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this); 82 3 : if( moldat ) warning("PDB output files do not have atom types unless you use MOLDATA"); 83 : 84 6 : parse("FILE",filename); parse("FMT",fmt); 85 4 : if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(filename); } 86 2 : log.printf(" printing data to file named %s \n",filename.c_str() ); 87 2 : } 88 : 89 2 : void OutputPCAProjection::performAnalysis() { 90 : // Find a moldata object 91 2 : auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this); 92 : // Output the embedding in plumed pdb format 93 2 : OFile afile; afile.link(*this); afile.setBackupString("analysis"); 94 2 : mypdb.setAtomPositions( (mypca->myref)->getReferencePositions() ); 95 4 : for(unsigned j=0; j<mypca->getArguments().size(); ++j) mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), (mypca->myref)->getReferenceArgument(j) ); 96 : // And output the first frame 97 2 : afile.open( filename ); afile.printf("REMARK TYPE=%s \n", mypca->mtype.c_str() ); 98 2 : if( plumed.getAtoms().usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt ); 99 2 : else mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, afile, fmt ); 100 : // And now output the eigenvectors 101 6 : for(unsigned dim=0; dim<mypca->nlow; ++dim) { 102 4 : afile.printf("REMARK TYPE=DIRECTION \n"); 103 4 : mypdb.setAtomPositions( mypca->directions[dim].getReferencePositions() ); 104 8 : for(unsigned j=0; j<mypca->getArguments().size(); ++j) mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), mypca->directions[dim].getReferenceArgument(j) ); 105 4 : if( plumed.getAtoms().usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt ); 106 4 : else mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, afile, fmt ); 107 : } 108 2 : afile.close(); 109 2 : } 110 : 111 : } 112 : }