1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Device/Detector/IDetector.h
//! @brief Defines common detector interface.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#ifndef BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
#define BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
#include "Base/Axis/Frame.h"
#include "Base/Type/ICloneable.h"
#include "Device/Data/Datafield.h"
#include "Device/Pol/PolFilter.h"
class Beam;
class IDetectorResolution;
class IResolutionFunction2D;
class IShape2D;
class MaskStack;
class Pixel;
class Scale;
struct RoiOfAxis;
//! Abstract base for 2D detectors, realized by SphericalDetector.
//!
//! Handles also "region of interest" (ROI). In general, the ROI is the whole
//! detector, and all methods related to ROI work on the whole detector.
//! If a ROI different to the detector size is explicitly set, then ROI-related
//! methods work on this reduced ROI.
//! Therefore, when calling ROI related methods, the distinction between "explicit
//! ROI exists: yes/no" does not have to be made by the caller, but it is handled in here.
//! For access to the whole detector, even if a smaller ROI is explicitly defined, use the
//! non-ROI-related methods like totalSize() or axes().
//! Any method which is not speaking of "explicit ROI" handles the "implicit ROI", i.e. uses
//! an explicitly set ROI or the whole detector if no explicit ROI exists.
class IDetector : public ICloneable, public INode {
public:
//! Constructor that takes ownership of Frame.
IDetector(Frame* frame);
~IDetector() override;
//! Sets the polarization analyzer characteristics of the detector
void setAnalyzer(const R3& Bloch_vector = {}, double mean_transmission = 0.5);
void setResolutionFunction(const IResolutionFunction2D& resFunc);
const Frame& frame() const;
const MaskStack* detectorMask() const;
//! Adds mask of given shape to the stack of detector masks. The mask value 'true' means
//! that the channel will be excluded from the simulation. The mask which is added last
//! has priority.
//! @param shape The shape of mask (Rectangle, Polygon, Line, Ellipse)
//! @param mask_value The value of mask
void addMask(const IShape2D& shape, bool mask_value = true);
//! Put the mask for all detector channels (i.e. exclude whole detector from the analysis)
void maskAll();
//! One axis of the complete detector.
//! Any region of interest is not taken into account.
const Scale& axis(size_t i) const;
//! Sets rectangular region of interest with lower left and upper right corners defined.
void setRegionOfInterest(double xlow, double ylow, double xup, double yup);
//! Returns a Frame clipped to the region of interest. If no region of interest is explicitly
//! defined, then the whole detector is taken as "region of interest".
Frame clippedFrame() const;
#ifndef SWIG
IDetector* clone() const override = 0;
std::vector<const INode*> nodeChildren() const override;
//! Returns total number of pixels.
//! Any region of interest is not taken into account.
size_t totalSize() const;
//! Returns a pointer to detector resolution object
const IDetectorResolution* detectorResolution() const { return m_resolution.get(); }
//! Sets the detector resolution
void setDetectorResolution(const IDetectorResolution& detector_resolution);
//! Creates an Pixel for the given Datafield object and index
virtual const Pixel* createPixel(size_t i) const = 0;
//! Returns vector of unmasked detector indices.
std::vector<size_t> activeIndices() const;
//! Returns index of pixel that contains the specular wavevector.
//! If no pixel contains this specular wavevector, the number of pixels is
//! returned. This corresponds to an overflow index.
virtual size_t indexOfSpecular(const Beam& beam) const = 0;
//! Applies the detector resolution to the given intensity maps
void applyDetectorResolution(Datafield* df) const;
//! True if a region of interest is explicitly set.
bool hasExplicitRegionOfInterest() const;
//! The size of the "Region of Interest". Same as totalSize()
//! if no region of interest has been explicitly set.
size_t sizeOfRegionOfInterest() const;
//! Convert an index of the region of interest to an index of the detector.
//! If no region of interest is set, then the index stays unmodified (since ROI == detector
//! area).
size_t roiToFullIndex(size_t i) const;
//! The lower and upper bound of the region of interest. If no region of interest is explicitly
//! defined, then the whole detector is taken as "region of interest".
std::pair<double, double> regionOfInterestBounds(size_t iAxis) const;
//! Returns empty detector map in given axes units.
//! This map is a data array limited to the size of the "Region of interest"
Datafield createDetectorMap() const;
//! Returns detection properties
const PolFilter& analyzer() const { return m_pol_analyzer; }
protected:
IDetector(const IDetector& other);
//! Returns flattened index computed from two axis indices.
size_t getGlobalIndex(size_t x, size_t y) const;
//! Calculate axis index for given global index
size_t axisBinIndex(size_t i, size_t k_axis) const;
private:
std::vector<RoiOfAxis> m_explicitROI; //!< an explicitly defined region of interest.
//!< Empty if no ROI has been defined.
//!< Vector index corresponds to axis index in m_frame
std::unique_ptr<Frame> m_frame;
PolFilter m_pol_analyzer;
std::unique_ptr<IDetectorResolution> m_resolution;
std::unique_ptr<MaskStack> m_mask;
#endif // SWIG
};
#endif // BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
|