LOOS 4.1.0
The Lightweight Object Oriented Structural analysis library/toolkit
Loading...
Searching...
No Matches
membrane_map.hpp
1/*
2 * Compute membrane property distribution about a protein
3 * Can compute chain molecular order parameter, tilt vector, or density
4 *
5 * Alan Grossfield
6 * (adapted from some code by Josh Horn, adapted from some stuff I wrote)
7 */
8
9#include <boost/lexical_cast.hpp>
10#include <sstream>
11
12//* Virtual base class for CalcProperty. Needed because CalcProperty is
13// a template, and you can't instantiate a template, only a particular version
14// of it.
16{
17public:
18 virtual void normalize(uint frames)
19 {
20 }
21
22 virtual void calc(const loos::AtomicGroup &group,
23 const uint xbin, const uint ybin)
24 {
25 }
26
27 virtual void set(const uint xbin, const uint ybin, const double val)
28 {
29 }
30
31 virtual void set(const uint xbin, const uint ybin, const loos::GCoord val)
32 {
33 }
34
35 virtual void incr(const uint xbin, const uint ybin, const double val)
36 {
37 }
38
39 virtual void incr(const uint xbin, const uint ybin, const loos::GCoord val)
40 {
41 }
42
43 //* Need to use a pointer to val instead of a return val so
44 // that the template below can overload it.
45 // NOTE: if you're going to create a new CalcProperty subclass
46 // that returns something other than a double or a GCoord, you'll
47 // need to add new virtual version of all of the methods here
48 virtual void get(const uint xbin, const uint ybin, double *val)
49 {
50 }
51
52 virtual void get(const uint xbin, const uint ybin, loos::GCoord *val)
53 {
54 }
55
56 virtual const uint get_norm(const uint xbin, const uint ybin)
57 {
58 uint i = 1;
59 return(i);
60 }
61
62 virtual const std::string print(const uint xbin, const uint ybin)
63 {
64 std::string s(" ");
65 return(s);
66 }
67
68};
69
70template <class T> class CalcProperty : public CalcPropertyBase
71{
72protected:
73 uint _xbins, _ybins;
74public:
75 CalcProperty( uint xbins, uint ybins ):
76 _xbins(xbins),
77 _ybins(ybins),
78 _storage(xbins*ybins),
79 _norm(xbins*ybins)
80 {
81 }
82
83 // This will usually be ok, but will occassionally
84 // get overridden by subclasses, eg ones that return
85 // a density
86 void normalize (uint frames)
87 {
88 T val;
89 for (uint i=0; i< _xbins; ++i)
90 {
91 for (uint j=0; j< _ybins; ++j)
92 {
93 get(i, j, &val);
94 uint norm = get_norm(i,j);
95 if (norm)
96 {
97 set(i,j, val /get_norm(i,j));
98 }
99 else
100 set(i,j, -999999999.);
101 }
102 }
103 }
104
105 // This will get overridden by subclasses
106 void calc(const loos::AtomicGroup &group, const uint xbin, const uint ybin)
107 {
108 incr(xbin, ybin, static_cast<T>(1.0));
109 }
110
111 void set(const uint xbin, const uint ybin, const T val)
112 {
113 uint index= xbin * _ybins + ybin;
114 _storage[index] = val;
115 }
116
117 void incr(const uint xbin, const uint ybin, const T val)
118 {
119 uint index= xbin * _ybins + ybin;
120 _storage[index] += val;
121 _norm[index]++;
122 }
123
124 void get(const uint xbin, const uint ybin, T *val)
125 {
126 uint index= xbin * _ybins + ybin;
127 *val = _storage[index];
128 }
129
130 const uint get_norm(const uint xbin, const uint ybin)
131 {
132 uint index= xbin * _ybins + ybin;
133 return(_norm[index]);
134 }
135
136 const std::string print(const uint xbin, const uint ybin)
137 {
138 T val;
139 get(xbin, ybin, &val);
140 return(boost::lexical_cast<std::string>(val));
141 }
142
143private:
144 std::vector<T> _storage;
145 std::vector<uint> _norm;
146
147};
148
149//* calculate the density distribution, in groups/Ang^2
150class CalcDensity : public CalcProperty<double>
151{
152public:
153 CalcDensity( uint xbins, uint ybins, double xwidth, double ywidth) :
154 CalcProperty<double>(xbins, ybins)
155 {
156 _bin_area = xwidth * ywidth;
157 }
158
159 void normalize (uint frames)
160 {
161 double norm = _bin_area * frames;
162 double val;
163 for (uint i=0; i< this->_xbins; ++i)
164 {
165 for (uint j=0; j< this->_ybins; ++j)
166 {
167 this->get(i,j, &val);
168 this->set(i, j, val / norm);
169 }
170 }
171 }
172
173private:
174 double _bin_area;
175};
176
177//* Calculate molecular order parameter
178class CalcMolOrder : public CalcProperty<double>
179{
180public:
181 CalcMolOrder (uint xbins, uint ybins) : CalcProperty<double>(xbins, ybins)
182 {
183 }
184
185 void calc(const loos::AtomicGroup &group, const uint xbin, const uint ybin)
186 {
187 std::vector<loos::GCoord> axes = group.principalAxes();
188 loos::GCoord ave = 0.5* (axes[1] + axes[2]);
189 double cosine = ave.z() / ave.length();
190 double val = fabs(1.5*cosine*cosine - 0.5);
191 incr(xbin, ybin, val);
192 }
193
194};
195
196//* Calculate height
197class CalcHeight : public CalcProperty<double>
198{
199public:
200 CalcHeight (uint xbins, uint ybins) : CalcProperty<double>(xbins, ybins)
201 {
202 }
203
204 // This implicitly assumes the membrane center is z=0
205 void calc(const loos::AtomicGroup &group, const uint xbin, const uint ybin)
206 {
207 loos::GCoord centroid = group.centroid();
208 incr(xbin, ybin, centroid.z());
209 }
210
211};
212//* Calculate the in-plane "orientation field" for the group
213class CalcOrientVector : public CalcProperty<loos::GCoord>
214{
215public:
216 CalcOrientVector(uint xbins, uint ybins) :
217 CalcProperty<loos::GCoord>(xbins, ybins)
218 {
219 }
220
221 void calc(const loos::AtomicGroup &group, const uint xbin, const uint ybin)
222 {
223 std::vector<loos::GCoord> axes = group.principalAxes();
224 // Force a consistent sign convention on the principal axis
225 // by insisting it point toward the center of the membrane.
226 // So, if the molecule is in the +z leaflet, the axis must point
227 // "downward"
228 loos::GCoord centroid = group.centroid();
229 if (axes[0].z()*centroid.z() > 0)
230 {
231 axes[0] *= -1;
232 }
233 axes[0].z() = 0.0;
234 incr(xbin, ybin, axes[0]);
235 }
236
237 const std::string print(const uint xbin, const uint ybin)
238 {
239 std::stringstream s;
240 loos::GCoord tmp;
241 get(xbin, ybin, &tmp);
242 s << tmp.x();
243 s << "\t";
244 s << tmp.y();
245 return(s.str());
246 }
247
248 void normalize (uint frames)
249 {
250 loos::GCoord val;
251 loos::GCoord zero(0., 0., 0.);
252 for (uint i=0; i< _xbins; ++i)
253 {
254 for (uint j=0; j< _ybins; ++j)
255 {
256 get(i, j, &val);
257 uint norm = get_norm(i,j);
258 if (norm)
259 {
260 set(i,j, val /get_norm(i,j));
261 }
262 else
263 set(i,j, zero);
264 }
265 }
266 }
267};
268
269//* Calculate the dipole moment of the group
270class CalcDipole : public CalcProperty<loos::GCoord>
271{
272public:
273 CalcDipole(uint xbins, uint ybins) :
274 CalcProperty<loos::GCoord>(xbins, ybins)
275 {
276 }
277
278 void calc(const loos::AtomicGroup &group, const uint xbin, const uint ybin)
279 {
280 // TODO: do I want to enforce a sign convention so that upper and lower
281 // leaflets don't cancel?
282 loos::GCoord dipole = group.dipoleMoment();
283 incr(xbin, ybin, dipole);
284 }
285
286 const std::string print(const uint xbin, const uint ybin)
287 {
288 std::stringstream s;
289 loos::GCoord tmp;
290 get(xbin, ybin, &tmp);
291 s << tmp.x() << "\t"
292 << tmp.y() << "\t"
293 << tmp.z();
294 return(s.str());
295 }
296
297 void normalize (uint frames)
298 {
299 loos::GCoord val;
300 loos::GCoord zero(0., 0., 0.);
301 for (uint i=0; i< _xbins; ++i)
302 {
303 for (uint j=0; j< _ybins; ++j)
304 {
305 get(i, j, &val);
306 uint norm = get_norm(i,j);
307 if (norm)
308 {
309 set(i,j, val /get_norm(i,j));
310 }
311 else
312 set(i,j, zero);
313 }
314 }
315 }
316};
Definition membrane_map.hpp:151
Definition membrane_map.hpp:271
Definition membrane_map.hpp:198
Definition membrane_map.hpp:179
Definition membrane_map.hpp:214
Definition membrane_map.hpp:16
Definition membrane_map.hpp:71
Class for handling groups of Atoms (pAtoms, actually)
Definition AtomicGroup.hpp:108