Xmipp  v3.23.11-Nereus
arotation_estimator.h
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: David Strelak (davidstrelak@gmail.com)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #ifndef LIBRARIES_RECONSTRUCTION_AROTATION_ESTIMATOR_H_
27 #define LIBRARIES_RECONSTRUCTION_AROTATION_ESTIMATOR_H_
28 
29 #include "data/hw.h"
30 #include "data/dimensions.h"
31 #include "core/xmipp_error.h"
32 #include "align_type.h"
33 #include <vector>
34 #include <assert.h>
35 #include <limits>
36 
40 namespace Alignment {
41 
43 public:
44  std::vector<HW*> hw;
48  size_t batch;
49  float maxRotDeg;
50  bool fullCircle;
51  unsigned firstRing;
52  unsigned lastRing;
54  bool allowDataOverwrite; // input data, such as reference or 'other' images can be overwrite by the algorithm. This can be, however, faster
55 
56  inline static float getMaxRotation() {
57  return 360.f - std::numeric_limits<float>::min();
58  }
59 
60  inline static unsigned getDefaultLastRing(const Dimensions &d) {
61  return (d.x() - 3) / 2; // so that we have some edge around the biggest ring
62  }
63 
64  inline static unsigned getDefaultFirstRing(const Dimensions &d) {
65  return std::max((size_t)2, d.x() / 20);
66  }
67 
68  inline unsigned getNoOfRings() const {
69  return 1 + lastRing - firstRing;
70  }
71 
72  void check() const {
73  if (0 == hw.size()) {
74  REPORT_ERROR(ERR_VALUE_INCORRECT, "HW contains zero (0) devices");
75  }
76  if ( ! refDims.isValid()) {
77  REPORT_ERROR(ERR_LOGIC_ERROR, "'Reference' dimensions are invalid (contain 0)");
78  }
79  if ( ! otherDims.isValid()) {
80  REPORT_ERROR(ERR_LOGIC_ERROR, "'Other' dimensions are invalid (contain 0)");
81  }
82  if ( ! refDims.equalExceptNPadded(otherDims)) {
83  REPORT_ERROR(ERR_LOGIC_ERROR, "Dimensions of the reference and other signals differ");
84  }
85  if (AlignType::None == type) {
86  REPORT_ERROR(ERR_LOGIC_ERROR, "'None' alignment type is set. This is invalid value");
87  }
88  if ((AlignType::OneToN == type)
89  && (1 != refDims.n())) {
90  REPORT_ERROR(ERR_LOGIC_ERROR, "More than one reference specified for alignment type 1:N");
91  }
92  if ((AlignType::MToN == type)
93  && (1 == refDims.n())) {
94  REPORT_ERROR(ERR_LOGIC_ERROR, "Single reference specified for alignment type M:N");
95  }
96  if (batch > otherDims.n()) {
97  REPORT_ERROR(ERR_LOGIC_ERROR, "Batch is bigger than number of signals");
98  }
99  if (0 == batch) {
100  REPORT_ERROR(ERR_LOGIC_ERROR, "Batch is zero (0)");
101  }
102  if (0 == maxRotDeg) {
103  REPORT_ERROR(ERR_VALUE_INCORRECT, "Max rotation is zero (0)");
104  }
105  if (0 == lastRing) {
106  REPORT_ERROR(ERR_VALUE_INCORRECT, "Last ring is zero (0)");
107  }
108  if (0 == firstRing) {
109  REPORT_ERROR(ERR_VALUE_INCORRECT, "First ring is zero (0)");
110  }
111  if (lastRing <= firstRing) {
112  REPORT_ERROR(ERR_VALUE_INCORRECT, "Last ring is bigger (or equal) than first ring");
113  }
114  if (lastRing >= refDims.x()) {
115  REPORT_ERROR(ERR_VALUE_INCORRECT, "Last ring is too big");
116  }
117  if (firstRing >= refDims.x()) {
118  REPORT_ERROR(ERR_VALUE_INCORRECT, "First ring is too big");
119  }
120  }
121 };
122 
123 template<typename T>
125 public:
127  m_isInit(false),
128  m_isRefLoaded(false) {};
129  // no reference on purpose, we store a copy anyway
130  void init(const RotationEstimationSetting settings, bool reuse);
131 
132  void loadReference(const T *ref);
133 
134  void compute(T *others);
135 
136  inline const std::vector<float> &getRotations2D() const {
137  return m_rotations2D;
138  }
139 
140  virtual ~ARotationEstimator() {};
141 
142  HW& getHW() const { // FIXME DS remove once we use the new data-centric approach
143  assert(m_isInit);
144  return *m_settings.hw.at(0);
145  }
146 
147  inline const RotationEstimationSetting &getSettings() const {
148  return m_settings;
149  }
150 
151 protected:
152  virtual void check() = 0;
153 
154  virtual void init2D() = 0;
155  virtual void load2DReferenceOneToN(const T *ref) = 0;
156  virtual void computeRotation2DOneToN(T *others) = 0;
157  virtual bool canBeReused2D(const RotationEstimationSetting &s) const = 0;
158 
159 
160  inline std::vector<float> &getRotations2D() {
161  return m_rotations2D;
162  }
163 
164  inline constexpr bool isInitialized() const {
165  return m_isInit;
166  }
167 
168  inline constexpr bool isRefLoaded() const {
169  return m_isRefLoaded;
170  }
171 
172 private:
173  RotationEstimationSetting m_settings;
174 
175  // computed shifts
176  std::vector<float> m_rotations2D;
177 
178  // flags
179  bool m_isInit;
180  bool m_isRefLoaded;
181 
182  bool canBeReused(const RotationEstimationSetting &s) const;
183 };
184 
185 } /* namespace Alignment */
187 #endif /* LIBRARIES_RECONSTRUCTION_AROTATION_ESTIMATOR_H_ */
void min(Image< double > &op1, const Image< double > &op2)
const RotationEstimationSetting & getSettings() const
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Definition: hw.h:35
constexpr bool isInitialized() const
const std::vector< float > & getRotations2D() const
doublereal * d
static unsigned getDefaultFirstRing(const Dimensions &d)
CUDA_HD constexpr size_t x() const
Definition: dimensions.h:51
constexpr bool equalExceptNPadded(const Dimensions &b) const
Definition: dimensions.h:124
static unsigned getDefaultLastRing(const Dimensions &d)
void max(Image< double > &op1, const Image< double > &op2)
CUDA_HD constexpr size_t n() const
Definition: dimensions.h:78
constexpr bool isRefLoaded() const
constexpr bool isValid() const
Definition: dimensions.h:138
std::vector< float > & getRotations2D()
Incorrect value received.
Definition: xmipp_error.h:195
Some logical error in the pipeline.
Definition: xmipp_error.h:147