IMP logo
IMP Reference Guide  develop.d36d3deffb,2026/11/09
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-2026 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>
11 #include "IMP/em2d/Matrix.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(DoubleMatrix &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  DoubleMatrix 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(DoubleMatrix &mask, DoubleMatrix &m,
117  const algebra::Vector2D &v) {
118 
119  // v is the vector of coordinates respect to the center of the matrix m
120  int vi = algebra::get_rounded(v[0]);
121  int vj = algebra::get_rounded(v[1]);
122 
123  // Centers for the matrix
124  int center[2];
125  center[0] = static_cast<int>(0.5 * m.rows());
126  center[1] = static_cast<int>(0.5 * m.cols());
127 
128  int start[2], end[2];
129  start[0] = -center[0];
130  start[1] = -center[1];
131  end[0] = m.rows() - 1 - center[0];
132  end[1] = m.cols() - 1 - center[1];
133 
134  // Check range: If the vector is outside the matrix, don't do anything.
135  if (vi < start[0] || vi > end[0]) return;
136  if (vj < start[1] || vj > end[1]) return;
137 
138  // Centers for the mask
139  int mcenter[2];
140  mcenter[0] = static_cast<int>(0.5 * mask.rows());
141  mcenter[1] = static_cast<int>(0.5 * mask.cols());
142 
143  int mstart[2], mend[2];
144  mstart[0] = -mcenter[0];
145  mstart[1] = -mcenter[1];
146  mend[0] = mask.rows() - 1 - mcenter[0];
147  mend[1] = mask.cols() - 1 - mcenter[1];
148 
149  // Get the admissible range for the mask
150  int start_i = std::max(start[0] - vi, mstart[0]);
151  int start_j = std::max(start[1] - vj, mstart[1]);
152  int end_i = std::min(end[0] - vi, mend[0]);
153  int end_j = std::min(end[1] - vj, mend[1]);
154 
155  int row = vi + center[0];
156  int col = vj + center[1];
157 
158  if (end_i < start_i || end_j < start_j) return;
159  int n_rows = end_i - start_i + 1, n_cols = end_j - start_j + 1;
160  m.block(start_i + row, start_j + col, n_rows, n_cols) +=
161  mask.block(start_i + mcenter[0], start_j + mcenter[1], n_rows, n_cols);
162 }
163 
164 //! Management of projection masks
165 class IMPEM2DEXPORT MasksManager {
166  public:
167  MasksManager() {
168  is_setup_ = false;
169  };
170 
171  MasksManager(double resolution, double pixelsize) {
172  setup_kernel(resolution, pixelsize);
173  }
174 
175  //! Initializes the kernel
176  inline void setup_kernel(double resolution, double pixelsize) {
177  kernel_params_ = em::KernelParameters((float)resolution);
178  pixelsize_ = pixelsize;
179  is_setup_ = true;
180  }
181 
182  //! Generates all the masks for a set of particles. This is the function
183  //! you typically want to use
184  void create_masks(const ParticlesTemp &ps);
185 
186  //! Creates the adequate mask for a particle of given mass
187  /*!
188  \param[in] mass of the particle
189  */
190  void create_mask(double mass);
191 
192  //! Returns the adequate mask for a particle of given mass
193  ProjectionMaskPtr find_mask(double mass);
194 
195  void show(std::ostream &out = std::cout) const;
196 
197  unsigned int get_number_of_masks() const { return mass2mask_.size(); }
198 
199  ~MasksManager();
200 
201  protected:
202  // A map to store the masks
203  std::map<double, ProjectionMaskPtr> mass2mask_;
204  // Kernel Params for the particles
205  em::KernelParameters kernel_params_;
206  // Pixel size for the masks
207  double pixelsize_;
208  bool is_setup_;
209 
210 private:
211  friend class cereal::access;
212 
213  template<class Archive> void serialize(Archive &ar) {
214  ar(mass2mask_, kernel_params_, pixelsize_, is_setup_);
215  }
216 
217 };
218 
220 
221 IMPEM2D_END_NAMESPACE
222 
223 #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.
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
void do_place(DoubleMatrix &mask, DoubleMatrix &m, const algebra::Vector2D &v)
int get_rounded(const T &x)
Rounds a number to next integer.
Stores and converts spherical coordinates.
Matrices used to store image data Copyright 2007-2026 IMP Inventors. All rights reserved.
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.
Eigen::Array< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > DoubleMatrix
Matrix of doubles, used to store the data of an image.
Definition: Matrix.h:28
Decorator for a sphere-like particle.
Management of projection masks.