Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2019 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 6466 : 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 4839 : }
155 :
156 :
157 :
|