BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
IDetector.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Device/Detector/IDetector.cpp
6 //! @brief Implements 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 
21 
23 {
25 }
26 
28  : ICloneable(), INode(), m_axes(other.m_axes),
29  m_detection_properties(other.m_detection_properties)
30 {
31  if (other.mP_detector_resolution)
33  setName(other.getName());
35 }
36 
37 IDetector::~IDetector() = default;
38 
39 void IDetector::addAxis(const IAxis& axis)
40 {
41  m_axes.push_back(axis.clone());
42 }
43 
44 size_t IDetector::dimension() const
45 {
46  return m_axes.size();
47 }
48 
50 {
51  m_axes.clear();
52 }
53 
54 const IAxis& IDetector::getAxis(size_t index) const
55 {
56  if (index < dimension())
57  return *m_axes[index];
58  throw std::runtime_error("Error in IDetector::getAxis: not so many axes in this detector.");
59 }
60 
61 size_t IDetector::axisBinIndex(size_t index, size_t selected_axis) const
62 {
63  const size_t dim = dimension();
64  size_t remainder(index);
65  size_t i_axis = dim;
66  for (size_t i = 0; i < dim; ++i) {
67  --i_axis;
68  if (selected_axis == i_axis)
69  return remainder % m_axes[i_axis]->size();
70  remainder /= m_axes[i_axis]->size();
71  }
72  throw std::runtime_error("IDetector::getAxisBinIndex() -> "
73  "Error! No axis with given number");
74 }
75 
76 std::unique_ptr<IAxis> IDetector::createAxis(size_t index, size_t n_bins, double min,
77  double max) const
78 {
79  if (max <= min)
80  throw Exceptions::LogicErrorException("IDetector::createAxis() -> Error! max <= min");
81  if (n_bins == 0)
83  "IDetector::createAxis() -> Error! Number n_bins can't be zero.");
84  return std::make_unique<FixedBinAxis>(axisName(index), n_bins, min, max);
85 }
86 
87 size_t IDetector::totalSize() const
88 {
89  const size_t dim = dimension();
90  if (dim == 0)
91  return 0;
92  size_t result = 1;
93  for (size_t i_axis = 0; i_axis < dim; ++i_axis)
94  result *= m_axes[i_axis]->size();
95  return result;
96 }
97 
98 void IDetector::setAnalyzerProperties(const kvector_t direction, double efficiency,
99  double total_transmission)
100 {
101  m_detection_properties.setAnalyzerProperties(direction, efficiency, total_transmission);
102 }
103 
104 void IDetector::setDetectorResolution(const IDetectorResolution& p_detector_resolution)
105 {
106  mP_detector_resolution.reset(p_detector_resolution.clone());
108 }
109 
110 // TODO: pass dimension-independent argument to this function
112 {
113  ConvolutionDetectorResolution convFunc(resFunc);
114  setDetectorResolution(convFunc);
115 }
116 
118 {
119  if (!p_intensity_map)
120  throw std::runtime_error("IDetector::applyDetectorResolution() -> "
121  "Error! Null pointer to intensity map");
123  mP_detector_resolution->applyDetectorResolution(p_intensity_map);
124  if (detectorMask() && detectorMask()->hasMasks()) {
125  // sets amplitude in masked areas to zero
126  std::unique_ptr<OutputData<double>> buff(new OutputData<double>());
127  buff->copyShapeFrom(*p_intensity_map);
128 
129  iterate([&](const_iterator it) {
130  (*buff)[it.roiIndex()] = (*p_intensity_map)[it.roiIndex()];
131  });
132  p_intensity_map->setRawDataVector(buff->getRawDataVector());
133  }
134  }
135 }
136 
138 {
139  mP_detector_resolution.reset();
140 }
141 
143 {
144  return mP_detector_resolution.get();
145 }
146 
148 IDetector::createDetectorIntensity(const std::vector<SimulationElement>& elements) const
149 {
150  std::unique_ptr<OutputData<double>> detectorMap(createDetectorMap());
151  if (!detectorMap)
152  throw Exceptions::RuntimeErrorException("Instrument::createDetectorIntensity:"
153  "can't create detector map.");
154 
155  setDataToDetectorMap(*detectorMap, elements);
157  applyDetectorResolution(detectorMap.get());
158 
159  return detectorMap.release();
160 }
161 
162 std::unique_ptr<OutputData<double>> IDetector::createDetectorMap() const
163 {
164  const size_t dim = dimension();
165  if (dim == 0)
166  throw std::runtime_error(
167  "Error in IDetector::createDetectorMap: dimensions of the detector are undefined");
168 
169  std::unique_ptr<OutputData<double>> result(new OutputData<double>);
170  for (size_t i = 0; i < dim; ++i)
171  if (auto roi = regionOfInterest())
172  result->addAxis(*roi->clipAxisToRoi(i, getAxis(i)));
173  else
174  result->addAxis(getAxis(i));
175 
176  return result;
177 }
178 
180  const std::vector<SimulationElement>& elements) const
181 {
182  if (elements.empty())
183  return;
184  iterate([&](const_iterator it) {
185  detectorMap[it.roiIndex()] = elements[it.elementIndex()].getIntensity();
186  });
187 }
188 
190 {
191  size_t result(0);
192  iterate([&result](const_iterator) { ++result; });
193  return result;
194 }
195 
196 std::vector<const INode*> IDetector::getChildren() const
197 {
198  return std::vector<const INode*>() << &m_detection_properties << mP_detector_resolution;
199 }
200 
201 void IDetector::iterate(std::function<void(IDetector::const_iterator)> func, bool visit_masks) const
202 {
203  if (this->dimension() == 0)
204  return;
205 
206  if (visit_masks) {
207  SimulationRoiArea area(this);
208  for (SimulationRoiArea::iterator it = area.begin(); it != area.end(); ++it)
209  func(it);
210  } else {
211  SimulationArea area(this);
212  for (SimulationArea::iterator it = area.begin(); it != area.end(); ++it)
213  func(it);
214  }
215 }
Defines class ConvolutionDetectorResolution.
Defines class DetectorMask.
Defines common detector interface.
Defines class RegionOfInterest.
Defines class SimulationArea.
Defines class SimulationElement.
void push_back(T *t)
Convolutes the intensity in 1 or 2 dimensions with a resolution function.
void setAnalyzerProperties(const kvector_t direction, double efficiency, double total_transmission)
Sets the polarization analyzer characteristics of the detector.
Interface for one-dimensional axes.
Definition: IAxis.h:25
virtual IAxis * clone() const =0
clone function
Interface for polymorphic classes that should not be copied, except by explicit cloning.
Definition: ICloneable.h:25
Interface for detector resolution algorithms.
virtual IDetectorResolution * clone() const =0
Abstract detector interface.
Definition: IDetector.h:36
void setDataToDetectorMap(OutputData< double > &detectorMap, const std::vector< SimulationElement > &elements) const
Definition: IDetector.cpp:179
void applyDetectorResolution(OutputData< double > *p_intensity_map) const
Applies the detector resolution to the given intensity maps.
Definition: IDetector.cpp:117
std::unique_ptr< IDetectorResolution > mP_detector_resolution
Definition: IDetector.h:128
virtual std::string axisName(size_t index) const =0
Returns the name for the axis with given index.
virtual ~IDetector()
virtual const DetectorMask * detectorMask() const =0
Returns detector masks container.
void clear()
Definition: IDetector.cpp:49
size_t dimension() const
Returns actual dimensionality of the detector (number of defined axes)
Definition: IDetector.cpp:44
size_t axisBinIndex(size_t index, size_t selected_axis) const
Calculate axis index for given global index.
Definition: IDetector.cpp:61
virtual std::unique_ptr< IAxis > createAxis(size_t index, size_t n_bins, double min, double max) const
Generates an axis with correct name and default binning for given index.
Definition: IDetector.cpp:76
std::vector< const INode * > getChildren() const override
Returns a vector of children (const).
Definition: IDetector.cpp:196
size_t totalSize() const
Returns total number of pixels.
Definition: IDetector.cpp:87
size_t numberOfSimulationElements() const
Returns number of simulation elements.
Definition: IDetector.cpp:189
const IAxis & getAxis(size_t index) const
Definition: IDetector.cpp:54
void setResolutionFunction(const IResolutionFunction2D &resFunc)
Definition: IDetector.cpp:111
DetectionProperties m_detection_properties
Definition: IDetector.h:127
CloneableVector< IAxis > m_axes
Definition: IDetector.h:126
void setAnalyzerProperties(const kvector_t direction, double efficiency, double total_transmission)
Sets the polarization analyzer characteristics of the detector.
Definition: IDetector.cpp:98
void addAxis(const IAxis &axis)
Definition: IDetector.cpp:39
OutputData< double > * createDetectorIntensity(const std::vector< SimulationElement > &elements) const
Returns new intensity map with detector resolution applied.
Definition: IDetector.cpp:148
void setDetectorResolution(const IDetectorResolution &p_detector_resolution)
Sets the detector resolution.
Definition: IDetector.cpp:104
std::unique_ptr< OutputData< double > > createDetectorMap() const
Returns empty detector map in given axes units.
Definition: IDetector.cpp:162
void iterate(std::function< void(const_iterator)> func, bool visit_masks=false) const
Definition: IDetector.cpp:201
const IDetectorResolution * detectorResolution() const
Returns a pointer to detector resolution object.
Definition: IDetector.cpp:142
void removeDetectorResolution()
Removes detector resolution function.
Definition: IDetector.cpp:137
virtual const RegionOfInterest * regionOfInterest() const =0
Returns region of interest if exists.
Base class for tree-like structures containing parameterized objects.
Definition: INode.h:49
void registerChild(INode *node)
Definition: INode.cpp:58
const std::string & getName() const
void setName(const std::string &name)
Interface providing two-dimensional resolution function.
void setRawDataVector(const std::vector< T > &data_vector)
Sets new values to raw data vector.
Definition: OutputData.h:559
An iterator for SimulationArea.
Holds iteration logic over active detector channels in the presence of masked areas and RegionOfInter...
SimulationAreaIterator begin()
SimulationAreaIterator end()
Holds iteration logic over active detector channels in the presence of ROI.