BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
IDetector.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Device/Detector/IDetector.h
6 //! @brief Defines common detector interface.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #ifndef BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
16 #define BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
17 
18 #include "Base/Types/ICloneable.h"
20 #include "Device/Coord/Tags.h" // enum Coords
22 #include "Device/Pol/PolFilter.h"
23 #include <functional>
24 
25 class Beam;
26 class CoordSystem2D;
27 class DetectorContext;
28 class DetectorMask;
29 class DiffuseElement;
30 class Direction;
31 class IAxis;
32 class ICoordSystem;
34 class IPixel;
36 class IShape2D;
37 
38 class Datafield;
39 
40 //! Abstract detector interface.
41 //!
42 //! Handles also "region of interest" (ROI). In general, the ROI is the whole
43 //! detector, and all methods related to ROI work on the whole detector.
44 //! If a ROI different to the detector size is explicitly set, then ROI-related
45 //! methods work on this reduced ROI.
46 //! Therefore, when calling ROI related methods, the distinction between "explicit
47 //! ROI exists: yes/no" does not have to be made by the caller, but it is handled in here.
48 //! For access to the whole detector, even if a smaller ROI is explicitly defined, use the
49 //! non-ROI-related methods like totalSize() or axes().
50 //! Any method which is not speaking of "explicit ROI" handles the "implicit ROI", i.e. uses
51 //! an explicitly set ROI or the whole detector if no explicit ROI exists.
52 //! To access the explicitly set ROI, use the methods which have the explicit in its
53 //! name, like sizeOfExplicitRegionOfInterest().
54 //!
55 //! @ingroup detector
56 
57 class IDetector : public ICloneable, public INode {
58 public:
60  IDetector();
61 
62  IDetector* clone() const override = 0;
63 
64  ~IDetector() override;
65 
66  //! Inits detector with the beam settings
67  virtual void setDetectorNormal(const Direction&) {} // nontrivial only for RectangularDetector
68 
69  void addDetAxis(const IAxis& axis);
70 
71  //! Sets the polarization analyzer characteristics of the detector
72  void setAnalyzer(R3 direction, double efficiency, double total_transmission);
73  //! Sets the detector resolution
74  void setDetectorResolution(const IDetectorResolution& p_detector_resolution);
75  void setResolutionFunction(const IResolutionFunction2D& resFunc);
76 
77  //! Resets region of interest making whole detector plane available for the simulation.
78  void resetRegionOfInterest();
79 
80  std::vector<const INode*> nodeChildren() const override;
81 
82  //! Iterate over all points within "region of interest", no matter whether they are masked or
83  //! not. If no region of interest is explicitly defined, then the whole detector is taken as
84  //! "region of interest".
85  void iterateOverRegionOfInterest(std::function<void(const_iterator)> func) const;
86 
87  //! Iterate over all non-masked points within "region of interest".
88  //! If no region of interest is explicitly defined, then the whole detector is taken as
89  //! "region of interest".
90  void iterateOverNonMaskedPoints(std::function<void(const_iterator)> func) const;
91 
92  //! Sets equidistant axes
93  void setDetectorParameters(size_t n_x, double x_min, double x_max, size_t n_y, double y_min,
94  double y_max);
95 
96  const DetectorMask* detectorMask() const;
97 
98  //! Adds mask of given shape to the stack of detector masks. The mask value 'true' means
99  //! that the channel will be excluded from the simulation. The mask which is added last
100  //! has priority.
101  //! @param shape The shape of mask (Rectangle, Polygon, Line, Ellipse)
102  //! @param mask_value The value of mask
103  void addMask(const IShape2D& shape, bool mask_value = true);
104 
105  //! Put the mask for all detector channels (i.e. exclude whole detector from the analysis)
106  void maskAll();
107 
108  //! Sets rectangular region of interest with lower left and upper right corners defined.
109  void setRegionOfInterest(double xlow, double ylow, double xup, double yup);
110 
111  virtual ICoordSystem* offspecCoords(IAxis* beamAxis, const Direction& beamDirection) const = 0;
112  virtual CoordSystem2D* scatteringCoords(const Beam& beam) const = 0;
113 
114  //! Returns vector of unmasked detector indices.
115  std::vector<size_t> active_indices() const;
116 
117  //! Creates an IPixel for the given Datafield object and index
118  virtual IPixel* createPixel(size_t index) const = 0;
119 
120  //! Returns index of pixel that contains the specular wavevector.
121  //! If no pixel contains this specular wavevector, the number of pixels is
122  //! returned. This corresponds to an overflow index.
123  virtual size_t indexOfSpecular(const Beam& beam) const = 0;
124 
125  //! One axis of the complete detector.
126  //! Any region of interest is not taken into account.
127  const IAxis& axis(size_t index) const;
128 
129  //! Returns number of defined axes
130  size_t rank() const;
131 
132  //! Calculate axis index for given global index
133  size_t axisBinIndex(size_t index, size_t selected_axis) const;
134 
135  //! Returns total number of pixels.
136  //! Any region of interest is not taken into account.
137  size_t totalSize() const;
138 
139  //! The size of the "Region of Interest". Same as totalSize()
140  //! if no region of interest has been explicitly set.
141  size_t sizeOfRegionOfInterest() const;
142 
143  //! True if a region of interest is explicitly set.
144  bool hasExplicitRegionOfInterest() const;
145 
146  //! Returns the axes clipped to the region of interest. If no region of interest is explicitly
147  //! defined, then the whole detector is taken as "region of interest".
149 
150  //! Convert an index of the region of interest to an index of the detector.
151  //! If no region of interest is set, then the index stays unmodified (since ROI == detector
152  //! area).
153  size_t regionOfInterestIndexToDetectorIndex(size_t regionOfInterestIndex) const;
154  size_t detectorIndexToRegionOfInterestIndex(size_t detectorIndex) const;
155 
156  //! Applies the detector resolution to the given intensity maps
157  void applyDetectorResolution(Datafield* p_intensity_map) const;
158 
159  //! Returns a pointer to detector resolution object
161 
162  //! Returns new intensity map with resolution applied, and cropped to ROI if applicable.
163  Datafield*
164  createDetectorIntensity(const std::vector<std::unique_ptr<DiffuseElement>>& elements) const;
165 
166  //! Return default axes units
167  virtual Coords defaultCoords() const = 0;
168 
169  //! Returns number of simulation elements.
170  size_t numberOfElements() const;
171 
172  //! The lower and upper bound of the region of interest. If no region of interest is explicitly
173  //! defined, then the whole detector is taken as "region of interest".
174  std::pair<double, double> regionOfInterestBounds(size_t iAxis) const;
175 
176 #ifndef SWIG
177  std::unique_ptr<DetectorContext> createContext() const;
178 
179  //! Create begin-iterator to iterate over all points which are not masked and lay
180  //! within the "Region of Interest"
182 
183  //! Create end-iterator to iterate over all points which are not masked and lay
184  //! within the "Region of Interest"
186 
187  //! Create begin-iterator to iterate over all points which lay
188  //! within the "Region of Interest". If no region of interest is explicitly
189  //! defined, then the whole detector is taken as "region of interest".
190  //! No matter whether masked or not.
192 
193  //! Create end-iterator to iterate over all points which lay
194  //! within the "Region of Interest". If no region of interest is explicitly
195  //! defined, then the whole detector is taken as "region of interest".
196  //! No matter whether masked or not.
198 
199  //! Returns empty detector map in given axes units.
200  //! This map is a data array limited to the size of the "Region of interest"
201  std::unique_ptr<Datafield> createDetectorMap() const;
202 
203  //! Returns detection properties
204  const PolFilter& analyzer() const { return m_polAnalyzer; }
205 #endif // SWIG
206 
207 protected:
208  IDetector(const IDetector& other);
209 
210  void clear();
211 
212  //! Returns the name for the axis with given index
213  virtual std::string axisName(size_t index) const = 0;
214 
215  //! Return 0 if no ROI has been explicitly set.
216  //! Size means number of data points.
217  virtual size_t sizeOfExplicitRegionOfInterest() const;
218 
219  //! Lower and upper bound of one axis of an explicitly set ROI.
220  //! Return 0/0 if no ROI has been explicitly set.
221  virtual std::pair<double, double> boundsOfExplicitRegionOfInterest(size_t iAxis) const;
222 
223  //! Calculate global index from two axis indices
224  size_t getGlobalIndex(size_t x, size_t y) const;
225 
226 #ifndef SWIG
227  //! Keeps RegionOfInterest (ROI) data of one axis
228  struct RoiOfAxis {
229  double lower;
230  double upper;
231 
232  // The following values are all pre-computed values. Aim is to speed up repeated
233  // calculations.
234  size_t lowerIndex; //!< index corresponding to 'lower'
235  size_t upperIndex; //!< index corresponding to 'upper'
236  size_t roiSize; //!< number of bins on axis of ROI
237  size_t detectorSize; //!< number of bins on axis of detector
238 
239  RoiOfAxis(const IAxis& axis, double lower, double upper);
240  };
241 
242  std::vector<RoiOfAxis> m_explicitROI; //!< an explicitly defined region of interest.
243  //!< Empty if no ROI has been defined.
244  //!< Vector index corresponds to axis index in m_axes
245 
246 
247 private:
250  std::unique_ptr<IDetectorResolution> m_detector_resolution;
251  std::shared_ptr<DetectorMask> m_detector_mask;
252 #endif // SWIG
253 };
254 
255 #endif // BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
Defines and implements the standard mix-in ICloneable.
Defines and implements templated class OwningVector.
Defines class DetectionProperties.
Defines class SimulationAreaIterator.
Defines enum Axis::Units.
An incident neutron or x-ray beam.
Definition: Beam.h:28
Interface for objects that provide axis translations to different units for IDetector objects.
Definition: CoordSystem2D.h:32
Stores radiation power per bin.
Definition: Datafield.h:30
Holds precalculated information for faster DiffuseElement generation.
Collection of detector masks.
Definition: DetectorMask.h:42
Data stucture containing both input and output of a single detector cell.
A direction in three-dimensional space.
Definition: Direction.h:24
Abstract base class for one-dimensional axes.
Definition: IAxis.h:27
Interface for polymorphic classes that should not be copied, except by explicit cloning.
Definition: ICloneable.h:23
Interface to provide axis translations to different units for simulation output.
Definition: ICoordSystem.h:40
Interface for detector resolution algorithms.
Abstract detector interface.
Definition: IDetector.h:57
virtual std::pair< double, double > boundsOfExplicitRegionOfInterest(size_t iAxis) const
Lower and upper bound of one axis of an explicitly set ROI. Return 0/0 if no ROI has been explicitly ...
Definition: IDetector.cpp:106
size_t sizeOfRegionOfInterest() const
The size of the "Region of Interest". Same as totalSize() if no region of interest has been explicitl...
Definition: IDetector.cpp:125
void iterateOverRegionOfInterest(std::function< void(const_iterator)> func) const
Iterate over all points within "region of interest", no matter whether they are masked or not....
Definition: IDetector.cpp:243
OwningVector< IAxis > m_axes
Definition: IDetector.h:248
PolFilter m_polAnalyzer
Definition: IDetector.h:249
virtual size_t indexOfSpecular(const Beam &beam) const =0
Returns index of pixel that contains the specular wavevector. If no pixel contains this specular wave...
void addDetAxis(const IAxis &axis)
Definition: IDetector.cpp:57
virtual Coords defaultCoords() const =0
Return default axes units.
virtual size_t sizeOfExplicitRegionOfInterest() const
Return 0 if no ROI has been explicitly set. Size means number of data points.
Definition: IDetector.cpp:94
virtual std::string axisName(size_t index) const =0
Returns the name for the axis with given index.
size_t numberOfElements() const
Returns number of simulation elements.
Definition: IDetector.cpp:220
SimulationAreaIterator beginRegionOfInterestPoints() const
Create begin-iterator to iterate over all points which lay within the "Region of Interest"....
Definition: IDetector.cpp:271
void setRegionOfInterest(double xlow, double ylow, double xup, double yup)
Sets rectangular region of interest with lower left and upper right corners defined.
Definition: IDetector.cpp:337
const PolFilter & analyzer() const
Returns detection properties.
Definition: IDetector.h:204
const SimulationAreaIterator & const_iterator
Definition: IDetector.h:59
std::pair< double, double > regionOfInterestBounds(size_t iAxis) const
The lower and upper bound of the region of interest. If no region of interest is explicitly defined,...
Definition: IDetector.cpp:227
void maskAll()
Put the mask for all detector channels (i.e. exclude whole detector from the analysis)
Definition: IDetector.cpp:365
void iterateOverNonMaskedPoints(std::function< void(const_iterator)> func) const
Iterate over all non-masked points within "region of interest". If no region of interest is explicitl...
Definition: IDetector.cpp:252
void clear()
Definition: IDetector.cpp:69
std::vector< const INode * > nodeChildren() const override
Returns all children.
Definition: IDetector.cpp:238
SimulationAreaIterator beginNonMaskedPoints() const
Create begin-iterator to iterate over all points which are not masked and lay within the "Region of I...
Definition: IDetector.cpp:261
size_t axisBinIndex(size_t index, size_t selected_axis) const
Calculate axis index for given global index.
Definition: IDetector.cpp:80
size_t regionOfInterestIndexToDetectorIndex(size_t regionOfInterestIndex) const
Convert an index of the region of interest to an index of the detector. If no region of interest is s...
Definition: IDetector.cpp:281
virtual CoordSystem2D * scatteringCoords(const Beam &beam) const =0
size_t totalSize() const
Returns total number of pixels. Any region of interest is not taken into account.
Definition: IDetector.cpp:114
void setDetectorParameters(size_t n_x, double x_min, double x_max, size_t n_y, double y_min, double y_max)
Sets equidistant axes.
Definition: IDetector.cpp:329
std::unique_ptr< Datafield > createDetectorMap() const
Returns empty detector map in given axes units. This map is a data array limited to the size of the "...
Definition: IDetector.cpp:205
std::unique_ptr< IDetectorResolution > m_detector_resolution
Definition: IDetector.h:250
size_t detectorIndexToRegionOfInterestIndex(size_t detectorIndex) const
Definition: IDetector.cpp:294
const IAxis & axis(size_t index) const
One axis of the complete detector. Any region of interest is not taken into account.
Definition: IDetector.cpp:74
void addMask(const IShape2D &shape, bool mask_value=true)
Adds mask of given shape to the stack of detector masks. The mask value 'true' means that the channel...
Definition: IDetector.cpp:360
bool hasExplicitRegionOfInterest() const
True if a region of interest is explicitly set.
Definition: IDetector.cpp:131
void setResolutionFunction(const IResolutionFunction2D &resFunc)
Definition: IDetector.cpp:158
std::vector< size_t > active_indices() const
Returns vector of unmasked detector indices.
Definition: IDetector.cpp:346
OwningVector< IAxis > axesClippedToRegionOfInterest() const
Returns the axes clipped to the region of interest. If no region of interest is explicitly defined,...
Definition: IDetector.cpp:136
virtual void setDetectorNormal(const Direction &)
Inits detector with the beam settings.
Definition: IDetector.h:67
void setAnalyzer(R3 direction, double efficiency, double total_transmission)
Sets the polarization analyzer characteristics of the detector.
Definition: IDetector.cpp:147
SimulationAreaIterator endNonMaskedPoints() const
Create end-iterator to iterate over all points which are not masked and lay within the "Region of Int...
Definition: IDetector.cpp:266
std::unique_ptr< DetectorContext > createContext() const
Definition: IDetector.cpp:355
size_t getGlobalIndex(size_t x, size_t y) const
Calculate global index from two axis indices.
Definition: IDetector.cpp:377
void setDetectorResolution(const IDetectorResolution &p_detector_resolution)
Sets the detector resolution.
Definition: IDetector.cpp:152
virtual IPixel * createPixel(size_t index) const =0
Creates an IPixel for the given Datafield object and index.
std::vector< RoiOfAxis > m_explicitROI
an explicitly defined region of interest. Empty if no ROI has been defined. Vector index corresponds ...
Definition: IDetector.h:242
IDetector * clone() const override=0
~IDetector() override
const IDetectorResolution * detectorResolution() const
Returns a pointer to detector resolution object.
Definition: IDetector.cpp:186
SimulationAreaIterator endRegionOfInterestPoints() const
Create end-iterator to iterate over all points which lay within the "Region of Interest"....
Definition: IDetector.cpp:276
void resetRegionOfInterest()
Resets region of interest making whole detector plane available for the simulation.
Definition: IDetector.cpp:164
size_t rank() const
Returns number of defined axes.
Definition: IDetector.cpp:64
const DetectorMask * detectorMask() const
Definition: IDetector.cpp:372
Datafield * createDetectorIntensity(const std::vector< std::unique_ptr< DiffuseElement >> &elements) const
Returns new intensity map with resolution applied, and cropped to ROI if applicable.
Definition: IDetector.cpp:191
void applyDetectorResolution(Datafield *p_intensity_map) const
Applies the detector resolution to the given intensity maps.
Definition: IDetector.cpp:169
virtual ICoordSystem * offspecCoords(IAxis *beamAxis, const Direction &beamDirection) const =0
std::shared_ptr< DetectorMask > m_detector_mask
Definition: IDetector.h:251
Base class for tree-like structures containing parameterized objects.
Definition: INode.h:40
Interface for a function that maps [0,1]x[0,1] to the kvectors in a pixel. Abstract base class for Sp...
Definition: IPixel.h:29
Interface providing two-dimensional resolution function.
Basic class for all shapes in 2D.
Definition: IShape2D.h:26
Detector properties (efficiency, transmission).
Definition: PolFilter.h:27
An iterator for SimulationArea.
Coords
Definition: Tags.h:20
Keeps RegionOfInterest (ROI) data of one axis.
Definition: IDetector.h:228
size_t roiSize
number of bins on axis of ROI
Definition: IDetector.h:236
size_t upperIndex
index corresponding to 'upper'
Definition: IDetector.h:235
RoiOfAxis(const IAxis &axis, double lower, double upper)
Definition: IDetector.cpp:315
size_t detectorSize
number of bins on axis of detector
Definition: IDetector.h:237
size_t lowerIndex
index corresponding to 'lower'
Definition: IDetector.h:234