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