IMP  2.0.1
The Integrative Modeling Platform
ProjectionMask.h
Go to the documentation of this file.
1 /**
2  * \file ProjectionMask.h
3  * \brief projection masks
4  * Copyright 2007-2013 IMP Inventors. All rights reserved.
5 */
6 
7 #ifndef IMPEM2D_PROJECTION_MASK_H
8 #define IMPEM2D_PROJECTION_MASK_H
9 
10 #include "IMP/em2d/em2d_config.h"
12 #include "IMP/em2d/CenteredMat.h"
13 #include "IMP/atom/Mass.h"
14 #include "IMP/em/exp.h"
15 #include "IMP/algebra/Vector3D.h"
16 #include "IMP/algebra/Vector2D.h"
17 #include "IMP/algebra/Rotation3D.h"
20 #include "IMP/core/XYZR.h"
21 #include "IMP/Particle.h"
22 #include "IMP/exception.h"
23 #include <complex>
24 #include <boost/shared_ptr.hpp>
25 
26 IMPEM2D_BEGIN_NAMESPACE
27 
28 class ProjectionMask;
29 class MasksManager;
30 
31 typedef boost::shared_ptr<ProjectionMask> ProjectionMaskPtr;
32 typedef boost::shared_ptr<MasksManager> MasksManagerPtr;
33 
34 
35 //! Mask that contains the projection of a given particles. This matrices
36 //! speed up projecting because the only have to be computed once for a model
37 class IMPEM2DEXPORT ProjectionMask {
38 #ifdef SWIG
39  ProjectionMask(){}
40 #endif
41 public:
42 #if !defined(DOXYGEN) && !defined(SWIG)
45  double voxelsize,
46  double mass =1.0);
47 
48  //! Generates the mask
49  /*!
50  \param[in] KP Kernel parameteres to employ. See the EM module
51  \param[in] params Kernel parameteres associated with radius to employ
52  \param[in] mass Mass to give to the mask
53  */
54  void create(const em::KernelParameters &KP,
56  double mass = 1.0);
57 #endif
58 
59  //! Adds the values of the mask to a matrix at the given pixel
60  /*!
61  \param[out] m matrix where the values of the mask are added.
62  \param[in] v pixel where to apply the values. Currently used as integer.
63  \param[in] weight Weight given to the values of the mask.
64  */
65  void apply(cv::Mat &m,
66  const algebra::Vector2D &v);
67 
68  void show(std::ostream &out = std::cout) const;
69 
70  ~ProjectionMask();
71 
72 protected:
73  int dim_; // dimension of the mask
74  double sq_pixelsize_; // Used to save multiplications
75  cv::Mat data_; // actual matrix with the mask
76 };
77 
79 
80 
81 
82 
83 // Place a matrix in another
84 // Very ugly but very fast projecting function
85 
86 /*!
87  \param[in] mask matrix to place in m
88  \param[in] m matrix
89  \param[in] v Pixel of the matrix dest where the center of m is put.
90 */
91 inline
92 void do_place(cv::Mat &mask, cv::Mat &m,
93  const algebra::Vector2D &v) {
94 
95  // v is the vector of coordinates respect to the center of the matrix m
96  int vi= algebra::get_rounded(v[0]);
97  int vj= algebra::get_rounded(v[1]);
98 
99  // Centers for the matrix
100  int center[2];
101  center[0] = static_cast<int>(0.5*m.rows);
102  center[1] = static_cast<int>(0.5*m.cols);
103 
104  int start[2], end[2];
105  start[0] = -center[0];
106  start[1] = -center[1];
107  end[0]=m.rows - 1 - center[0];
108  end[1]=m.cols - 1 - center[1];
109 
110  // Check range: If the vector is outside the matrix, don't do anything.
111  if(vi < start[0] || vi > end[0]) return;
112  if(vj < start[1] || vj > end[1]) return;
113 
114 
115  // Centers for the mask
116  int mcenter[2];
117  mcenter[0] = static_cast<int>(0.5*mask.rows);
118  mcenter[1] = static_cast<int>(0.5*mask.cols);
119 
120  int mstart[2], mend[2];
121  mstart[0] = -mcenter[0];
122  mstart[1] = -mcenter[1];
123  mend[0] = mask.rows - 1 - mcenter[0];
124  mend[1] = mask.cols - 1 - mcenter[1];
125 
126  // Get the admisible range for the mask
127  int start_i = std::max(start[0] - vi, mstart[0]);
128  int start_j = std::max(start[1] - vj, mstart[1]);
129  int end_i = std::min(end[0] - vi, mend[0]);
130  int end_j = std::min(end[1] - vj, mend[1]);
131 
132 
133  int row = vi+center[0];
134  int col = vj+center[1];
135 
136  for(int i = start_i; i <= end_i; ++i) {
137  int p = i+row;
138  for(int j = start_j; j <= end_j; ++j) {
139  m.at<double>(p, j+col) += mask.at<double>(i+mcenter[0], j+mcenter[1]);
140  }
141  }
142 }
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 //! Manage of projection masks
158 class IMPEM2DEXPORT MasksManager {
159 public:
160  MasksManager() {
161  is_setup_ = false;
162  };
163 
164  MasksManager(double resolution,double pixelsize) {
165  setup_kernel(resolution,pixelsize);
166  }
167 
168  //! Initializes the kernel
169  inline void setup_kernel(double resolution,double pixelsize) {
170  kernel_params_= em::KernelParameters((float)resolution);
171  pixelsize_=pixelsize;
172  is_setup_ = true;
173  }
174 
175  //! Generates all the masks for a set of particles. This is the function
176  //! you typically want to use
177  void create_masks(const ParticlesTemp &ps);
178 
179  //! Creates the adequate mask for a particle of given radius
180  /*!
181  \param[in] params Kernel parameters for the particle
182  \param[in] radius of the particle
183  \param[in] mass of the particle
184  */
185  void create_mask(double radius, double mass);
186 
187  //! Returns the adequate mask for a particle of given radius
188  ProjectionMaskPtr find_mask(double radius);
189 
190  void show(std::ostream &out = std::cout) const;
191 
192  unsigned int get_number_of_masks() const {
193  return radii2mask_.size();
194  }
195 
196  ~MasksManager();
197 
198 
199 protected:
200  // A map to store the masks
201  std::map <double,ProjectionMaskPtr > radii2mask_;
202  // Kernel Params for the particles
203  em::KernelParameters kernel_params_;
204  // Pixel size for the masks
205  double pixelsize_;
206  bool is_setup_;
207 };
208 
209 
211 
212 
213 IMPEM2D_END_NAMESPACE
214 
215 #endif /* IMPEM2D_PROJECTION_MASK_H */