Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-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 "colvar/Colvar.h" 23 : #include "colvar/ActionRegister.h" 24 : #include "core/PlumedMain.h" 25 : #include "tools/Pbc.h" 26 : 27 : #include <string> 28 : #include <cmath> 29 : 30 : using namespace std; 31 : 32 : namespace PLMD { 33 : namespace isdb { 34 : 35 : //+PLUMEDOC ISDB_COLVAR FRET 36 : /* 37 : Calculates the FRET efficiency between a pair of atoms. 38 : The efficiency is calculated using the Forster relation: 39 : 40 : \f[ 41 : E=\frac{1}{1+(R/R_0)^6} 42 : \f] 43 : 44 : where \f$R\f$ is the distance and \f$R_0\f$ is the Forster radius. 45 : 46 : By default the distance is computed taking into account periodic 47 : boundary conditions. This behavior can be changed with the NOPBC flag. 48 : 49 : 50 : \par Examples 51 : 52 : The following input tells plumed to print the FRET efficiencies 53 : calculated as a function of the distance between atoms 3 and 5 and 54 : the distance between atoms 2 and 4. 55 : \plumedfile 56 : fe1: FRET ATOMS=3,5 R0=5.5 57 : fe2: FRET ATOMS=2,4 R0=5.5 58 : PRINT ARG=fe1,fe2 59 : \endplumedfile 60 : 61 : The following input computes the FRET efficiency calculated on the 62 : terminal atoms of a polymer 63 : of 100 atoms and keeps it at a value around 0.5. 64 : \plumedfile 65 : WHOLEMOLECULES ENTITY0=1-100 66 : fe: FRET ATOMS=1,100 R0=5.5 NOPBC 67 : RESTRAINT ARG=fe KAPPA=100 AT=0.5 68 : \endplumedfile 69 : 70 : Notice that NOPBC is used 71 : to be sure that if the distance is larger than half the simulation 72 : box the distance is compute properly. Also notice that, since many MD 73 : codes break molecules across cell boundary, it might be necessary to 74 : use the \ref WHOLEMOLECULES keyword (also notice that it should be 75 : _before_ FRET). 76 : Just be sure that the ordered list provide to WHOLEMOLECULES has the following 77 : properties: 78 : - Consecutive atoms should be closer than half-cell throughout the entire simulation. 79 : - Atoms required later for the distance (e.g. 1 and 100) should be included in the list 80 : 81 : */ 82 : //+ENDPLUMEDOC 83 : 84 28 : class FretEfficiency : public Colvar { 85 : bool pbc; 86 : double R0_; 87 : 88 : public: 89 : static void registerKeywords( Keywords& keys ); 90 : explicit FretEfficiency(const ActionOptions&); 91 : // active methods: 92 : virtual void calculate(); 93 : }; 94 : 95 7384 : PLUMED_REGISTER_ACTION(FretEfficiency,"FRET") 96 : 97 15 : void FretEfficiency::registerKeywords( Keywords& keys ) { 98 15 : Colvar::registerKeywords( keys ); 99 60 : keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between"); 100 60 : keys.add("compulsory","R0","The value of the Forster radius."); 101 15 : } 102 : 103 14 : FretEfficiency::FretEfficiency(const ActionOptions&ao): 104 : PLUMED_COLVAR_INIT(ao), 105 14 : pbc(true) 106 : { 107 : vector<AtomNumber> atoms; 108 28 : parseAtomList("ATOMS",atoms); 109 14 : if(atoms.size()!=2) 110 0 : error("Number of specified atoms should be 2"); 111 28 : parse("R0",R0_); 112 14 : bool nopbc=!pbc; 113 28 : parseFlag("NOPBC",nopbc); 114 14 : pbc=!nopbc; 115 14 : checkRead(); 116 : 117 28 : log.printf(" between atoms %d %d\n",atoms[0].serial(),atoms[1].serial()); 118 14 : log.printf(" with Forster radius set to %lf\n",R0_); 119 : 120 14 : if(pbc) log.printf(" using periodic boundary conditions\n"); 121 0 : else log.printf(" without periodic boundary conditions\n"); 122 : 123 42 : log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n"; 124 : 125 14 : addValueWithDerivatives(); 126 14 : setNotPeriodic(); 127 : 128 14 : requestAtoms(atoms); 129 14 : } 130 : 131 : 132 : // calculator 133 238 : void FretEfficiency::calculate() { 134 : 135 238 : if(pbc) makeWhole(); 136 : 137 238 : Vector distance=delta(getPosition(0),getPosition(1)); 138 238 : const double dist_mod=distance.modulo(); 139 238 : const double inv_dist_mod=1.0/dist_mod; 140 : 141 238 : const double ratiosix=pow(dist_mod/R0_,6); 142 238 : const double fret_eff = 1.0/(1.0+ratiosix); 143 : 144 238 : const double der = -6.0*fret_eff*fret_eff*ratiosix*inv_dist_mod; 145 : 146 476 : setAtomsDerivatives(0,-inv_dist_mod*der*distance); 147 476 : setAtomsDerivatives(1, inv_dist_mod*der*distance); 148 : setBoxDerivativesNoPbc(); 149 238 : setValue(fret_eff); 150 : 151 238 : } 152 : 153 : } 154 5517 : } 155 : 156 : 157 :