LCOV - code coverage report
Current view: top level - colvar - MultiRMSD.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 51 56 91.1 %
Date: 2024-10-18 13:59:31 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-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/ActionShortcut.h"
      23             : #include "core/ActionRegister.h"
      24             : #include "core/ActionWithArguments.h"
      25             : #include "tools/PDB.h"
      26             : #include "core/PlumedMain.h"
      27             : 
      28             : //+PLUMEDOC DCOLVAR MULTI_RMSD
      29             : /*
      30             : Calculate RMSD distances for different domains and combine them.
      31             : 
      32             : This action is largely depracated.  In previous versions of PLUMED a more complex version of this method was implemented.
      33             : We felt, however, that the input syntax for the method was not very transparant.  We have thus provided this minimal action
      34             : that creates the input for calculating the MultiDomain RMSD for simple cases.  This action is a shortcut.  If you look at the log you can see how we
      35             : use the various actions that are in PLUMED to calculate the final quantity.  If you would like to implement some of the more
      36             : complicated CVs things that this could do with MULTI_RMSD looking at how this shortcut works will help you start.
      37             : 
      38             : 
      39             : \par Examples
      40             : 
      41             : */
      42             : //+ENDPLUMEDOC
      43             : 
      44             : namespace PLMD {
      45             : namespace colvar {
      46             : 
      47             : class MultiRMSD : public ActionShortcut {
      48             : public:
      49             :   static void registerKeywords(Keywords& keys);
      50             :   explicit MultiRMSD(const ActionOptions&);
      51             : };
      52             : 
      53             : PLUMED_REGISTER_ACTION(MultiRMSD,"MULTI_RMSD")
      54             : 
      55           3 : void MultiRMSD::registerKeywords(Keywords& keys) {
      56           3 :   ActionShortcut::registerKeywords( keys );
      57           6 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
      58           6 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be MULTI-OPTIMAL, MULTI-OPTIMAL-FAST,  MULTI-SIMPLE or MULTI-DRMSD.");
      59           6 :   keys.addFlag("SQUARED",false," This should be set if you want the mean squared displacement instead of the root mean squared displacement");
      60           6 :   keys.addFlag("NOPBC",false,"don't use periodic boundary conditions");
      61           6 :   keys.setValueDescription("scalar","the sum of the multiple RMSD distances");
      62           9 :   keys.needsAction("CONSTANT"); keys.needsAction("WHOLEMOLECULES"); keys.needsAction("POSITION");
      63          12 :   keys.needsAction("CONCATENATE"); keys.needsAction("RMSD_VECTOR"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM");
      64           3 : }
      65             : 
      66           1 : MultiRMSD::MultiRMSD(const ActionOptions& ao):
      67             :   Action(ao),
      68           1 :   ActionShortcut(ao)
      69             : {
      70           2 :   warning("this action is depracated.  look at the log to see how it is implemented using the new syntax");
      71           2 :   std::string type; parse("TYPE",type); bool nopbc; parseFlag("NOPBC",nopbc);
      72           1 :   std::size_t dash=type.find_first_of("-");
      73           1 :   if( dash!=std::string::npos ) {
      74           2 :     if( type.substr(0,dash)=="MULTI" ) warning("MULTI is deprecated.  You can just use OPTIMAL/SIMPLE");
      75           0 :     else error("cannot understand type " + type );
      76           2 :     type = type.substr(dash+1);
      77             :   }
      78           2 :   std::string reference; parse("REFERENCE",reference); PDB pdb;
      79           1 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) ) error("missing input file " + reference );
      80             : 
      81           1 :   unsigned nblocks =  pdb.getNumberOfAtomBlocks();
      82           1 :   if( nblocks<2 ) error("multidomain RMSD only has one block of atoms");
      83           1 :   std::string num; std::vector<unsigned> blocks( nblocks+1 ); blocks[0]=0;
      84           3 :   for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
      85             : 
      86           3 :   for(unsigned i=1; i<=nblocks; ++i) {
      87             :     // Setup a constant
      88           2 :     double asum=0; std::string bnum; Tools::convert( i, bnum );
      89          17 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) asum += pdb.getOccupancy()[j];
      90           2 :     Vector center; center.zero();
      91          17 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) center += ( pdb.getOccupancy()[j] / asum )*pdb.getPositions()[j];
      92             :     std::vector<double> vals;
      93           8 :     for(unsigned k=0; k<3; ++k) {
      94          51 :       for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) vals.push_back( pdb.getPositions()[j][k] - center[k] );
      95             :     }
      96           2 :     std::string valstr; Tools::convert( vals[0], valstr );
      97          45 :     for(unsigned i=1; i<vals.size(); ++i) { std::string rnum; Tools::convert( vals[i], rnum ); valstr += "," + rnum; }
      98             :     // Create the reference value
      99           4 :     readInputLine( getShortcutLabel() + "_ref" + bnum + ": CONSTANT VALUES=" + valstr );
     100             :     // Do whole molecules
     101           2 :     if( !nopbc ) {
     102           0 :       std::string num; Tools::convert( pdb.getAtomNumbers()[blocks[i-1]].serial(), num ); std::string wm_line = "WHOLEMOLECULES ENTITY0=" + num;
     103           0 :       for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getAtomNumbers()[j].serial(), num ); wm_line += "," + num; }
     104           0 :       readInputLine( wm_line );
     105             :     }
     106             :     // Get the positions of the atoms in this block
     107           4 :     std::string num; Tools::convert( pdb.getAtomNumbers()[blocks[i-1]].serial(), num ); std::string pos_line = getShortcutLabel() + "_cpos" + bnum + ": POSITION NOPBC ATOMS=" + num;
     108          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getAtomNumbers()[j].serial(), num ); pos_line += "," + num; }
     109           2 :     readInputLine( pos_line );
     110             :     // Concatenate the positiosn together
     111           4 :     readInputLine( getShortcutLabel() + "_pos" + bnum + ": CONCATENATE ARG=" + getShortcutLabel() + "_cpos" + bnum + ".x," + getShortcutLabel() + "_cpos" + bnum + ".y," + getShortcutLabel() + "_cpos" + bnum + ".z");
     112             :     // Computer the RMSD for this block
     113           4 :     std::string rmsd_line = getShortcutLabel() + "_rmsd" + bnum + ": RMSD_VECTOR SQUARED ARG=" + getShortcutLabel() + "_pos" + bnum + "," + getShortcutLabel() + "_ref" + bnum;
     114             :     // Now align
     115           4 :     Tools::convert( pdb.getOccupancy()[blocks[i-1]], num ); rmsd_line += " ALIGN=" + num;
     116          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getOccupancy()[j], num ); rmsd_line += "," + num; }
     117             :     // And displace
     118           4 :     Tools::convert( pdb.getBeta()[blocks[i-1]], num ); rmsd_line += " DISPLACE=" + num;
     119          15 :     for(unsigned j=blocks[i-1]+1; j<blocks[i]; ++j) { Tools::convert( pdb.getBeta()[j], num ); rmsd_line += "," + num; }
     120           4 :     readInputLine( rmsd_line + " TYPE=" + type );
     121             :   }
     122           3 :   std::string argstr = getShortcutLabel() + "_rmsd1"; for(unsigned i=1; i<nblocks; ++i) { std::string bnum; Tools::convert( i+1, bnum); argstr += "," + getShortcutLabel() + "_rmsd" + bnum; }
     123           1 :   bool squared; parseFlag("SQUARED",squared);
     124           1 :   if( !squared ) {
     125           2 :     readInputLine( getShortcutLabel() + "_2: COMBINE ARG=" + argstr + " PERIODIC=NO");
     126           2 :     readInputLine( getShortcutLabel() + ": CUSTOM ARG=" + getShortcutLabel() + "_2 FUNC=sqrt(x) PERIODIC=NO");
     127           0 :   } else readInputLine( getShortcutLabel() + ": COMBINE ARG=" + argstr + " PERIODIC=NO");
     128           2 : }
     129             : 
     130             : }
     131             : }

Generated by: LCOV version 1.16