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 : $$ 39 : E=\frac{1}{1+(R/R_0)^6} 40 : $$ 41 : 42 : where $R$ is the distance and $R_0$ 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 : ## 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 : 54 : ```plumed 55 : fe1: FRET ATOMS=3,5 R0=5.5 56 : fe2: FRET ATOMS=2,4 R0=5.5 57 : PRINT ARG=fe1,fe2 58 : ``` 59 : 60 : The following input computes the FRET efficiency calculated on the 61 : terminal atoms of a polymer 62 : of 100 atoms and keeps it at a value around 0.5. 63 : 64 : ```plumed 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 : ``` 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 [WHOLEMOLECULES](WHOLEMOLECULES.md) 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 : 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 : void calculate() override; 93 : }; 94 : 95 : PLUMED_REGISTER_ACTION(FretEfficiency,"FRET") 96 : 97 16 : void FretEfficiency::registerKeywords( Keywords& keys ) { 98 16 : Colvar::registerKeywords( keys ); 99 16 : keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between"); 100 16 : keys.add("compulsory","R0","The value of the Forster radius."); 101 32 : keys.setValueDescription("scalar","the fret efficiency between the input pair of atoms"); 102 16 : } 103 : 104 14 : FretEfficiency::FretEfficiency(const ActionOptions&ao): 105 : PLUMED_COLVAR_INIT(ao), 106 14 : pbc(true) { 107 : std::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 : } 112 14 : parse("R0",R0_); 113 14 : bool nopbc=!pbc; 114 14 : parseFlag("NOPBC",nopbc); 115 14 : pbc=!nopbc; 116 14 : checkRead(); 117 : 118 14 : log.printf(" between atoms %d %d\n",atoms[0].serial(),atoms[1].serial()); 119 14 : log.printf(" with Forster radius set to %lf\n",R0_); 120 : 121 14 : if(pbc) { 122 14 : log.printf(" using periodic boundary conditions\n"); 123 : } else { 124 0 : log.printf(" without periodic boundary conditions\n"); 125 : } 126 : 127 28 : log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n"; 128 : 129 14 : addValueWithDerivatives(); 130 14 : setNotPeriodic(); 131 : 132 14 : requestAtoms(atoms); 133 14 : } 134 : 135 : 136 : // calculator 137 238 : void FretEfficiency::calculate() { 138 : 139 238 : if(pbc) { 140 238 : makeWhole(); 141 : } 142 : 143 : Vector distance=delta(getPosition(0),getPosition(1)); 144 238 : const double dist_mod=distance.modulo(); 145 238 : const double inv_dist_mod=1.0/dist_mod; 146 : 147 238 : const double ratiosix=std::pow(dist_mod/R0_,6); 148 238 : const double fret_eff = 1.0/(1.0+ratiosix); 149 : 150 238 : const double der = -6.0*fret_eff*fret_eff*ratiosix*inv_dist_mod; 151 : 152 238 : setAtomsDerivatives(0,-inv_dist_mod*der*distance); 153 238 : setAtomsDerivatives(1, inv_dist_mod*der*distance); 154 : setBoxDerivativesNoPbc(); 155 238 : setValue(fret_eff); 156 : 157 238 : } 158 : 159 : } 160 : } 161 : 162 : 163 :