IMP logo
IMP Reference Guide  develop.eb1b99edaa,2026/06/25
The Integrative Modeling Platform
ProjectionMask.h
Go to the documentation of this file.
1 /**
2  * \file IMP/em2d/ProjectionMask.h
3  * \brief projection masks
4  * Copyright 2007-2023 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/atom/Mass.h"
13 #include "IMP/em/exp.h"
14 #include "IMP/algebra/Vector3D.h"
15 #include "IMP/algebra/Vector2D.h"
16 #include "IMP/algebra/Rotation3D.h"
19 #include "IMP/core/XYZR.h"
20 #include "IMP/Particle.h"
21 #include "IMP/exception.h"
22 #include <complex>
23 #include <memory>
24 #include <cereal/access.hpp>
25 
26 IMPEM2D_BEGIN_NAMESPACE
27 
28 class ProjectionMask;
29 class MasksManager;
30 
31 typedef std::shared_ptr<ProjectionMask> ProjectionMaskPtr;
32 typedef std::shared_ptr<MasksManager> MasksManagerPtr;
33 
34 //! Mask that contains the projection of a given particles. This matrices
35 //! speed up projecting because the only have to be computed once for a model
36 class IMPEM2DEXPORT ProjectionMask {
37  public:
38  ProjectionMask() {}
39 #if !defined(DOXYGEN) && !defined(SWIG)
40  ProjectionMask(const em::KernelParameters& kparams,
41  double voxelsize, double mass = 1.0);
42 
43  //! Generates the mask
44  /*!
45  \param[in] kparams Kernel parameters to employ. See the EM module
46  \param[in] mass Mass to give to the mask
47  */
48  void create(const em::KernelParameters& kparams,
49  double mass = 1.0);
50 #endif
51 
52  //! Adds the values of the mask to a matrix at the given pixel
53  /*!
54  \param[out] m matrix where the values of the mask are added.
55  \param[in] v pixel where to apply the values. Currently used as integer.
56  */
57  void apply(cv::Mat &m, const algebra::Vector2D &v);
58 
59  void show(std::ostream &out = std::cout) const;
60 
61  ~ProjectionMask();
62 
63  protected:
64  int dim_; // dimension of the mask
65  double sq_pixelsize_; // Used to save multiplications
66  cv::Mat data_; // actual matrix with the mask
67 private:
68  friend class cereal::access;
69 
70  template<class Archive> void serialize(Archive &ar) {
71  ar(dim_, sq_pixelsize_, data_);
72  }
73 };
74 
76 
77 IMPEM2D_END_NAMESPACE
78 
79 namespace cereal {
80  template<class Archive> inline void save(
81  Archive &ar, const std::map<double,
82  IMP::em2d::ProjectionMaskPtr> &m) {
83  size_t sz = m.size();
84  ar(sz);
85  for (const auto &p : m) {
86  ar(p.first);
87  ar(*(p.second));
88  }
89  }
90 
91  template<class Archive> inline void load(
92  Archive &ar, std::map<double, IMP::em2d::ProjectionMaskPtr> &m) {
93  m.clear();
94  size_t sz;
95  ar(sz);
96  for (size_t i = 0; i < sz; ++i) {
97  double mass;
98  IMP::em2d::ProjectionMaskPtr ptr(new IMP::em2d::ProjectionMask());
99  ar(mass);
100  ar(*ptr);
101  m[mass] = ptr;
102  }
103  }
104 }
105 
106 IMPEM2D_BEGIN_NAMESPACE
107 
108 // Place a matrix in another
109 // Very ugly but very fast projecting function
110 
111 /*!
112  \param[in] mask matrix to place in m
113  \param[in] m matrix
114  \param[in] v Pixel of the matrix dest where the center of m is put.
115 */
116 inline void do_place(cv::Mat &mask, cv::Mat &m, const algebra::Vector2D &v) {
117 
118  // v is the vector of coordinates respect to the center of the matrix m
119  int vi = algebra::get_rounded(v[0]);
120  int vj = algebra::get_rounded(v[1]);
121 
122  // Centers for the matrix
123  int center[2];
124  center[0] = static_cast<int>(0.5 * m.rows);
125  center[1] = static_cast<int>(0.5 * m.cols);
126 
127  int start[2], end[2];
128  start[0] = -center[0];
129  start[1] = -center[1];
130  end[0] = m.rows - 1 - center[0];
131  end[1] = m.cols - 1 - center[1];
132 
133  // Check range: If the vector is outside the matrix, don't do anything.
134  if (vi < start[0] || vi > end[0]) return;
135  if (vj < start[1] || vj > end[1]) return;
136 
137  // Centers for the mask
138  int mcenter[2];
139  mcenter[0] = static_cast<int>(0.5 * mask.rows);
140  mcenter[1] = static_cast<int>(0.5 * mask.cols);
141 
142  int mstart[2], mend[2];
143  mstart[0] = -mcenter[0];
144  mstart[1] = -mcenter[1];
145  mend[0] = mask.rows - 1 - mcenter[0];
146  mend[1] = mask.cols - 1 - mcenter[1];
147 
148  // Get the admissible range for the mask
149  int start_i = std::max(start[0] - vi, mstart[0]);
150  int start_j = std::max(start[1] - vj, mstart[1]);
151  int end_i = std::min(end[0] - vi, mend[0]);
152  int end_j = std::min(end[1] - vj, mend[1]);
153 
154  int row = vi + center[0];
155  int col = vj + center[1];
156 
157  for (int i = start_i; i <= end_i; ++i) {
158  int p = i + row;
159  for (int j = start_j; j <= end_j; ++j) {
160  m.at<double>(p, j + col) +=
161  mask.at<double>(i + mcenter[0], j + mcenter[1]);
162  }
163  }
164 }
165 
166 //! Management of projection masks
167 class IMPEM2DEXPORT MasksManager {
168  public:
169  MasksManager() {
170  is_setup_ = false;
171  };
172 
173  MasksManager(double resolution, double pixelsize) {
174  setup_kernel(resolution, pixelsize);
175  }
176 
177  //! Initializes the kernel
178  inline void setup_kernel(double resolution, double pixelsize) {
179  kernel_params_ = em::KernelParameters((float)resolution);
180  pixelsize_ = pixelsize;
181  is_setup_ = true;
182  }
183 
184  //! Generates all the masks for a set of particles. This is the function
185  //! you typically want to use
186  void create_masks(const ParticlesTemp &ps);
187 
188  //! Creates the adequate mask for a particle of given mass
189  /*!
190  \param[in] mass of the particle
191  */
192  void create_mask(double mass);
193 
194  //! Returns the adequate mask for a particle of given mass
195  ProjectionMaskPtr find_mask(double mass);
196 
197  void show(std::ostream &out = std::cout) const;
198 
199  unsigned int get_number_of_masks() const { return mass2mask_.size(); }
200 
201  ~MasksManager();
202 
203  protected:
204  // A map to store the masks
205  std::map<double, ProjectionMaskPtr> mass2mask_;
206  // Kernel Params for the particles
207  em::KernelParameters kernel_params_;
208  // Pixel size for the masks
209  double pixelsize_;
210  bool is_setup_;
211 
212 private:
213  friend class cereal::access;
214 
215  template<class Archive> void serialize(Archive &ar) {
216  ar(mass2mask_, kernel_params_, pixelsize_, is_setup_);
217  }
218 
219 };
220 
222 
223 IMPEM2D_END_NAMESPACE
224 
225 #endif /* IMPEM2D_PROJECTION_MASK_H */
A decorator for particles with mass.
VectorD< 2 > Vector2D
Definition: VectorD.h:403
Calculates and stores Gaussian kernel parameters.
void setup_kernel(double resolution, double pixelsize)
Initializes the kernel.
Simple 2D vector class.
Calculates and stores Gaussian kernel parameters.
Interface with OpenCV Copyright 2007-2026 IMP Inventors. All rights reserved.
Exception definitions and assertions.
An approximation of the exponential function.
A more IMP-like version of the std::vector.
Definition: Vector.h:50
#define IMP_VALUES(Name, PluralName)
Define the type for storing sets of values.
Definition: value_macros.h:23
int get_rounded(const T &x)
Rounds a number to next integer.
Stores and converts spherical coordinates.
Simple 3D vector class.
Simple 3D rotation class.
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)
Print the hierarchy using a given decorator to display each node.
void do_place(cv::Mat &mask, cv::Mat &m, const algebra::Vector2D &v)
Decorator for a sphere-like particle.
Management of projection masks.