File: IDetector.h

package info (click to toggle)
bornagain 23.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,948 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (154 lines) | stat: -rw-r--r-- 6,262 bytes parent folder | download
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