LCOV - code coverage report
Current view: top level - dimred - SketchMapRead.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 94 107 87.9 %
Date: 2026-03-30 13:16:06 Functions: 11 14 78.6 %

          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 "core/ActionRegister.h"
      23             : #include "SketchMapBase.h"
      24             : #include "reference/ReferenceConfiguration.h"
      25             : #include "reference/MetricRegister.h"
      26             : #include "core/PlumedMain.h"
      27             : #include "core/Atoms.h"
      28             : #include "tools/PDB.h"
      29             : 
      30             : //+PLUMEDOC DIMRED SKETCHMAP_READ
      31             : /*
      32             : Read in a sketch-map projection from an input file
      33             : 
      34             : \par Examples
      35             : 
      36             : */
      37             : //+ENDPLUMEDOC
      38             : 
      39             : namespace PLMD {
      40             : namespace dimred {
      41             : 
      42             : class SketchMapRead : public SketchMapBase {
      43             : private:
      44             :   std::string mtype;
      45             :   PDB mypdb;
      46             :   std::vector<Value*> all_values;
      47             :   std::vector<double> weights;
      48             : /// The list of properties in the property map
      49             :   std::map<std::string,std::vector<double> > property;
      50             : /// The data collection objects we have
      51             :   std::vector<analysis::DataCollectionObject> data;
      52             : /// The frames that we are using to calculate distances
      53             :   std::vector<std::unique_ptr<ReferenceConfiguration> > myframes;
      54             : public:
      55             :   static void registerKeywords( Keywords& keys );
      56             :   explicit SketchMapRead( const ActionOptions& ao );
      57             :   void minimise( Matrix<double>& ) override;
      58             :   analysis::DataCollectionObject& getStoredData( const unsigned& idata, const bool& calcdist ) override;
      59             :   unsigned getNumberOfDataPoints() const override;
      60             :   std::vector<Value*> getArgumentList() override;
      61             :   unsigned getDataPointIndexInBase( const unsigned& idata ) const override;
      62             :   double getDissimilarity( const unsigned& i, const unsigned& j ) override;
      63             :   double getWeight( const unsigned& idata ) override;
      64             : };
      65             : 
      66       13787 : PLUMED_REGISTER_ACTION(SketchMapRead,"SKETCHMAP_READ")
      67             : 
      68           5 : void SketchMapRead::registerKeywords( Keywords& keys ) {
      69           5 :   SketchMapBase::registerKeywords( keys );
      70           5 :   keys.remove("USE_OUTPUT_DATA_FROM");
      71          10 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
      72             :            "metrics that are available in PLUMED can be found in the section of the manual on "
      73             :            "\\ref dists");
      74          10 :   keys.add("compulsory","REFERENCE","the file containing the sketch-map projection");
      75          10 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
      76          10 :   keys.addFlag("DISABLE_CHECKS",false,"disable checks on reference input structures.");
      77           5 :   useCustomisableComponents(keys);
      78           5 : }
      79             : 
      80           1 : SketchMapRead::SketchMapRead( const ActionOptions& ao ):
      81             :   Action(ao),
      82           1 :   SketchMapBase(ao) {
      83             :   std::vector<std::string> propnames;
      84           2 :   parseVector("PROPERTY",propnames);
      85           1 :   if(propnames.size()==0) {
      86           0 :     error("no properties were specified");
      87             :   }
      88           1 :   nlow=propnames.size();
      89           3 :   for(unsigned i=0; i<nlow; ++i) {
      90           4 :     std::size_t dot=propnames[i].find_first_of( getLabel() + "." );
      91           2 :     std::string substr=propnames[i].c_str();
      92           2 :     if( dot!=std::string::npos ) {
      93           2 :       substr.erase(dot,getLabel().length()+1);
      94             :     }
      95           2 :     log.printf(",%s", propnames[i].c_str() );
      96           2 :     addComponent( substr );
      97           2 :     componentIsNotPeriodic( substr );
      98           4 :     property.insert( std::pair<std::string,std::vector<double> >( propnames[i], std::vector<double>() ) );
      99             :   }
     100           1 :   log.printf("  mapped properties are %s ",propnames[0].c_str() );
     101           2 :   for(unsigned i=1; i<nlow; ++i) {
     102           1 :     log.printf(",%s", propnames[i].c_str() );
     103             :   }
     104           1 :   log.printf("\n");
     105             : 
     106           1 :   parse("TYPE",mtype);
     107             :   bool skipchecks;
     108           2 :   parseFlag("DISABLE_CHECKS",skipchecks);
     109             :   std::string ifilename;
     110           2 :   parse("REFERENCE",ifilename);
     111           1 :   FILE* fp=this->fopen(ifilename.c_str(),"r");
     112           1 :   if(!fp) {
     113           0 :     error("could not open reference file " + ifilename );
     114             :   }
     115             : // call fclose when fp goes out of scope
     116           1 :   auto deleter=[this](FILE* f) {
     117           1 :     this->fclose(f);
     118           1 :   };
     119             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
     120             : 
     121             : 
     122             :   // Read in the embedding
     123             :   bool do_read=true;
     124             :   double val, ww, wnorm=0, prop;
     125             :   unsigned nfram=0;
     126          85 :   while (do_read) {
     127          85 :     PDB inpdb;
     128             :     // Read the pdb file
     129         170 :     do_read=inpdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
     130             :     // Break if we are done
     131          85 :     if( !do_read ) {
     132             :       break ;
     133             :     }
     134             :     // Check for required properties
     135         252 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
     136         168 :       if( !inpdb.getArgumentValue( it->first, prop ) ) {
     137           0 :         error("pdb input does not have contain property named " + it->first );
     138             :       }
     139         168 :       it->second.push_back(prop);
     140             :     }
     141             :     // And read the frame ( create a measure )
     142          84 :     myframes.emplace_back( metricRegister().create<ReferenceConfiguration>( mtype, inpdb ) );
     143         168 :     if( !inpdb.getArgumentValue( "WEIGHT", ww ) ) {
     144           0 :       error("could not find weights in input pdb");
     145             :     }
     146          84 :     weights.push_back( ww );
     147          84 :     wnorm += ww;
     148          84 :     nfram++;
     149             :     // And create a data collection object
     150             :     analysis::DataCollectionObject new_data;
     151          84 :     new_data.setAtomNumbersAndArgumentNames( getLabel(), inpdb.getAtomNumbers(), inpdb.getArgumentNames() );
     152          84 :     new_data.setAtomPositions( inpdb.getPositions() );
     153         504 :     for(unsigned i=0; i<inpdb.getArgumentNames().size(); ++i) {
     154         420 :       std::string aname = inpdb.getArgumentNames()[i];
     155         420 :       if( !inpdb.getArgumentValue( aname, val ) ) {
     156           0 :         error("failed to find argument named " + aname);
     157             :       }
     158         420 :       new_data.setArgument( aname, val );
     159             :     }
     160          84 :     data.push_back( new_data );
     161          85 :   }
     162             :   // Finish the setup of the object by getting the arguments and atoms that are required
     163             :   std::vector<AtomNumber> atoms;
     164             :   std::vector<std::string> args;
     165          85 :   for(unsigned i=0; i<myframes.size(); ++i) {
     166          84 :     weights[i] /= wnorm;
     167          84 :     myframes[i]->getAtomRequests( atoms, skipchecks );
     168          84 :     myframes[i]->getArgumentRequests( args, skipchecks );
     169             :   }
     170           1 :   requestAtoms( atoms );
     171             :   std::vector<Value*> req_args;
     172             :   std::vector<std::string> fargs;
     173           6 :   for(unsigned i=0; i<args.size(); ++i) {
     174             :     bool found=false;
     175          12 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
     176           9 :       if( args[i]==it->first ) {
     177             :         found=true;
     178             :         break;
     179             :       }
     180             :     }
     181           5 :     if( !found ) {
     182           3 :       fargs.push_back( args[i] );
     183             :     }
     184             :   }
     185           1 :   interpretArgumentList( fargs, req_args );
     186           1 :   mypdb.setArgumentNames( fargs );
     187           1 :   requestArguments( req_args );
     188             : 
     189           1 :   if(nfram==0 ) {
     190           0 :     error("no reference configurations were specified");
     191             :   }
     192           1 :   log.printf(" found %u configurations in file %s\n",nfram,ifilename.c_str() );
     193           4 : }
     194             : 
     195           1 : void SketchMapRead::minimise( Matrix<double>& projections ) {
     196             :   unsigned j=0;
     197           3 :   for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
     198         170 :     for(unsigned i=0; i<myframes.size(); ++i) {
     199         168 :       projections(i,j) = it->second[i];
     200             :     }
     201           2 :     j++;
     202             :   }
     203           1 : }
     204             : 
     205        7056 : analysis::DataCollectionObject & SketchMapRead::getStoredData( const unsigned& idata, const bool& calcdist ) {
     206        7056 :   return data[idata];
     207             : }
     208             : 
     209         173 : unsigned SketchMapRead::getNumberOfDataPoints() const {
     210         173 :   return myframes.size();
     211             : }
     212             : 
     213           0 : unsigned SketchMapRead::getDataPointIndexInBase( const unsigned& idata ) const {
     214           0 :   error("cannot use read in sketch-map to out of sample project data");
     215             :   return idata;
     216             : }
     217             : 
     218           0 : std::vector<Value*> SketchMapRead::getArgumentList() {
     219           0 :   std::vector<Value*> arglist( ActionWithArguments::getArguments() );
     220           0 :   for(unsigned i=0; i<nlow; ++i) {
     221           0 :     arglist.push_back( getPntrToComponent(i) );
     222             :   }
     223           0 :   return arglist;
     224             : }
     225             : 
     226             : // Highly unsatisfactory solution to problem GAT
     227        3486 : double SketchMapRead::getDissimilarity( const unsigned& i, const unsigned& j ) {
     228        3486 :   plumed_assert( i<myframes.size() && j<myframes.size() );
     229        3486 :   if( i!=j ) {
     230             :     double dd;
     231        3486 :     getStoredData( i, true ).transferDataToPDB( mypdb );
     232        3486 :     auto myref1=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
     233        3486 :     getStoredData( j, true ).transferDataToPDB( mypdb );
     234        3486 :     auto myref2=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
     235        3486 :     dd=distance( getPbc(), ActionWithArguments::getArguments(), myref1.get(), myref2.get(), true );
     236             :     return dd;
     237        3486 :   }
     238             :   return 0.0;
     239             : }
     240             : 
     241         168 : double SketchMapRead::getWeight( const unsigned& idata ) {
     242         168 :   plumed_assert( idata<weights.size() );
     243         168 :   return weights[idata];
     244             : }
     245             : 
     246             : }
     247             : }

Generated by: LCOV version 1.16