Skip to content
Snippets Groups Projects
Commit aff58e56 authored by Van Herck, Walter's avatar Van Herck, Walter
Browse files

Added prototype RectangularDetector

parent 0e4b717f
No related branches found
No related tags found
No related merge requests found
// ************************************************************************** //
//
// BornAgain: simulate and fit scattering at grazing incidence
//
//! @file Algorithms/inc/RectangularDetector.h
//! @brief Defines class RectangularDetector.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2015
//! @authors Scientific Computing Group at MLZ Garching
//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
//
// ************************************************************************** //
#ifndef RECTANGULARDETECTOR_H_
#define RECTANGULARDETECTOR_H_
#include "IDetector2D.h"
#include "IDetectorResolution.h"
#include "SafePointerVector.h"
#include "EigenCore.h"
#include "DetectorMask.h"
#include "SimulationElement.h"
#include "Beam.h"
#include "IPixelMap.h"
class RectPixelMap;
//! @class RectangularDetector
//! @ingroup simulation
//! @brief A rectangular plane detector with axes and resolution function.
class BA_CORE_API_ RectangularDetector : public IDetector2D
{
public:
RectangularDetector();
RectangularDetector(const RectangularDetector &other);
RectangularDetector &operator=(const RectangularDetector &other);
virtual RectangularDetector* clone() const;
virtual ~RectangularDetector() {}
//! Adds parameters from local pool to external pool and call recursion over direct children.
virtual std::string addParametersToExternalPool(std::string path, ParameterPool *external_pool,
int copy_number = -1) const;
protected:
//! Create an IPixelMap for the given OutputData object and index
virtual IPixelMap* createPixelMap(size_t index) const;
virtual void print(std::ostream &ostr) const;
//! Registers some class members for later access via parameter pool.
virtual void init_parameters() {}
};
class RectPixelMap : public IPixelMap
{
public:
RectPixelMap(Bin1D alpha_bin, Bin1D phi_bin);
virtual ~RectPixelMap() {}
virtual RectPixelMap* clone() const;
virtual RectPixelMap* createZeroSizeMap(double x, double y) const;
virtual kvector_t getK(double x, double y, double wavelength) const;
virtual double getIntegrationFactor(double x, double y) const;
virtual double getSolidAngle() const;
private:
double m_alpha, m_phi;
double m_dalpha, m_dphi;
double m_solid_angle;
};
#endif /* RECTANGULARDETECTOR_H_ */
...@@ -19,16 +19,13 @@ ...@@ -19,16 +19,13 @@
#include "CustomBinAxis.h" #include "CustomBinAxis.h"
#include "ConstKBinAxis.h" #include "ConstKBinAxis.h"
Instrument::Instrument() Instrument::Instrument() : IParameterized("Instrument")
: IParameterized("Instrument")
{ {
mP_detector.reset(new SphericalDetector()); mP_detector.reset(new SphericalDetector());
init_parameters(); init_parameters();
} }
Instrument::Instrument(const Instrument& other) Instrument::Instrument(const Instrument &other) : IParameterized(), m_beam(other.m_beam)
: IParameterized()
, m_beam(other.m_beam)
{ {
mP_detector.reset(other.mP_detector->clone()); mP_detector.reset(other.mP_detector->clone());
setName(other.getName()); setName(other.getName());
...@@ -37,7 +34,7 @@ Instrument::Instrument(const Instrument& other) ...@@ -37,7 +34,7 @@ Instrument::Instrument(const Instrument& other)
Instrument &Instrument::operator=(const Instrument &other) Instrument &Instrument::operator=(const Instrument &other)
{ {
if (this!=&other) { if (this != &other) {
m_beam = other.m_beam; m_beam = other.m_beam;
mP_detector.reset(other.mP_detector->clone()); mP_detector.reset(other.mP_detector->clone());
setName(other.getName()); setName(other.getName());
...@@ -46,41 +43,46 @@ Instrument &Instrument::operator=(const Instrument &other) ...@@ -46,41 +43,46 @@ Instrument &Instrument::operator=(const Instrument &other)
return *this; return *this;
} }
void Instrument::matchDetectorParameters(const OutputData<double>& output_data) void Instrument::matchDetectorParameters(const OutputData<double> &output_data)
{ {
mP_detector->clear(); mP_detector->clear();
for(size_t i_axis=0; i_axis<output_data.getRank(); ++i_axis) { for (size_t i_axis = 0; i_axis < output_data.getRank(); ++i_axis) {
const IAxis *axis = output_data.getAxis(i_axis); const IAxis *axis = output_data.getAxis(i_axis);
mP_detector->addAxis(*axis); mP_detector->addAxis(*axis);
} }
} }
void Instrument::setDetectorParameters( void Instrument::setDetectorParameters(size_t n_phi, double phi_f_min, double phi_f_max,
size_t n_phi, double phi_f_min, double phi_f_max, size_t n_alpha, double alpha_f_min, double alpha_f_max,
size_t n_alpha, double alpha_f_min, double alpha_f_max, bool isgisaxs_style)
bool isgisaxs_style)
{ {
if(phi_f_max <= phi_f_min) { if (phi_f_max <= phi_f_min) {
throw LogicErrorException("Instrument::setDetectorParameters() -> Error! phi_f_max <= phi_f_min"); throw LogicErrorException(
"Instrument::setDetectorParameters() -> Error! phi_f_max <= phi_f_min");
} }
if(alpha_f_max <= alpha_f_min) { if (alpha_f_max <= alpha_f_min) {
throw LogicErrorException("Instrument::setDetectorParameters() -> Error! alpha_f_max <= alpha_f_min"); throw LogicErrorException(
"Instrument::setDetectorParameters() -> Error! alpha_f_max <= alpha_f_min");
} }
if(n_phi == 0) { if (n_phi == 0) {
throw LogicErrorException("Instrument::setDetectorParameters() -> Error! Number of n_phi bins can't be zero."); throw LogicErrorException(
"Instrument::setDetectorParameters() -> Error! Number of n_phi bins can't be zero.");
} }
if(n_alpha == 0) { if (n_alpha == 0) {
throw LogicErrorException("Instrument::setDetectorParameters() -> Error! Number of n_alpha bins can't be zero."); throw LogicErrorException(
"Instrument::setDetectorParameters() -> Error! Number of n_alpha bins can't be zero.");
} }
mP_detector->clear(); mP_detector->clear();
if(isgisaxs_style) { if (isgisaxs_style) {
mP_detector->addAxis(CustomBinAxis(BornAgain::PHI_AXIS_NAME, n_phi, phi_f_min, phi_f_max)); mP_detector->addAxis(CustomBinAxis(BornAgain::PHI_AXIS_NAME, n_phi, phi_f_min, phi_f_max));
mP_detector->addAxis(CustomBinAxis(BornAgain::ALPHA_AXIS_NAME, n_alpha, alpha_f_min, alpha_f_max)); mP_detector->addAxis(
CustomBinAxis(BornAgain::ALPHA_AXIS_NAME, n_alpha, alpha_f_min, alpha_f_max));
} else { } else {
mP_detector->addAxis(ConstKBinAxis(BornAgain::PHI_AXIS_NAME, n_phi, phi_f_min, phi_f_max)); mP_detector->addAxis(ConstKBinAxis(BornAgain::PHI_AXIS_NAME, n_phi, phi_f_min, phi_f_max));
mP_detector->addAxis(ConstKBinAxis(BornAgain::ALPHA_AXIS_NAME, n_alpha, alpha_f_min, alpha_f_max)); mP_detector->addAxis(
ConstKBinAxis(BornAgain::ALPHA_AXIS_NAME, n_alpha, alpha_f_min, alpha_f_max));
} }
} }
...@@ -101,12 +103,12 @@ void Instrument::setDetectorAxes(const IAxis &axis0, const IAxis &axis1) ...@@ -101,12 +103,12 @@ void Instrument::setDetectorAxes(const IAxis &axis0, const IAxis &axis1)
delete p_axis1; delete p_axis1;
} }
std::string Instrument::addParametersToExternalPool( std::string Instrument::addParametersToExternalPool(std::string path, ParameterPool *external_pool,
std::string path, int copy_number) const
ParameterPool* external_pool, int copy_number) const
{ {
// add own parameters // add own parameters
std::string new_path = IParameterized::addParametersToExternalPool(path, external_pool, copy_number); std::string new_path
= IParameterized::addParametersToExternalPool(path, external_pool, copy_number);
// add parameters of the beam // add parameters of the beam
m_beam.addParametersToExternalPool(new_path, external_pool, -1); m_beam.addParametersToExternalPool(new_path, external_pool, -1);
...@@ -120,16 +122,16 @@ std::string Instrument::addParametersToExternalPool( ...@@ -120,16 +122,16 @@ std::string Instrument::addParametersToExternalPool(
void Instrument::normalize(OutputData<double> *p_intensity) const void Instrument::normalize(OutputData<double> *p_intensity) const
{ {
// normalize by intensity, if strictly positive // normalize by intensity, if strictly positive
if (getIntensity()>0.0) { if (getIntensity() > 0.0) {
p_intensity->scaleAll(getIntensity()); p_intensity->scaleAll(getIntensity());
} }
kvector_t realpart(getBeam().getCentralK().x().real(), kvector_t realpart(getBeam().getCentralK().x().real(), getBeam().getCentralK().y().real(),
getBeam().getCentralK().y().real(), getBeam().getCentralK().z().real());
getBeam().getCentralK().z().real());
// normalize by detector cell sizes // normalize by detector cell sizes
double sin_alpha_i = std::abs(realpart.cosTheta()); double sin_alpha_i = std::abs(realpart.cosTheta());
if (sin_alpha_i==0.0) sin_alpha_i = 1.0; if (sin_alpha_i == 0.0)
sin_alpha_i = 1.0;
mP_detector->normalize(p_intensity, sin_alpha_i); mP_detector->normalize(p_intensity, sin_alpha_i);
} }
...@@ -138,25 +140,22 @@ std::vector<SimulationElement> Instrument::createSimulationElements() ...@@ -138,25 +140,22 @@ std::vector<SimulationElement> Instrument::createSimulationElements()
return mP_detector->createSimulationElements(m_beam); return mP_detector->createSimulationElements(m_beam);
} }
void Instrument::setDetectorResolutionFunction( void Instrument::setDetectorResolutionFunction(IResolutionFunction2D *p_resolution_function)
IResolutionFunction2D* p_resolution_function)
{ {
if(p_resolution_function) { if (p_resolution_function) {
mP_detector->setDetectorResolution( mP_detector->setDetectorResolution(
new ConvolutionDetectorResolution(p_resolution_function) ); new ConvolutionDetectorResolution(p_resolution_function));
} else { } else {
mP_detector->setDetectorResolution(0); mP_detector->setDetectorResolution(0);
} }
} }
void Instrument::setDetectorResolutionFunction( void Instrument::setDetectorResolutionFunction(const IResolutionFunction2D &p_resolution_function)
const IResolutionFunction2D &p_resolution_function)
{ {
mP_detector->setDetectorResolution( mP_detector->setDetectorResolution(new ConvolutionDetectorResolution(p_resolution_function));
new ConvolutionDetectorResolution(p_resolution_function) );
} }
void Instrument::applyDetectorResolution(OutputData<double>* p_intensity_map) const void Instrument::applyDetectorResolution(OutputData<double> *p_intensity_map) const
{ {
mP_detector->applyDetectorResolution(p_intensity_map); mP_detector->applyDetectorResolution(p_intensity_map);
} }
...@@ -165,7 +164,7 @@ void Instrument::init_parameters() ...@@ -165,7 +164,7 @@ void Instrument::init_parameters()
{ {
} }
void Instrument::print(std::ostream& ostr) const void Instrument::print(std::ostream &ostr) const
{ {
ostr << "Instrument: '" << getName() << "' " << m_parameters << std::endl; ostr << "Instrument: '" << getName() << "' " << m_parameters << std::endl;
ostr << " " << m_beam << std::endl; ostr << " " << m_beam << std::endl;
......
// ************************************************************************** //
//
// BornAgain: simulate and fit scattering at grazing incidence
//
//! @file Algorithms/src/RectangularDetector.cpp
//! @brief Implements class RectangularDetector.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2015
//! @authors Scientific Computing Group at MLZ Garching
//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
//
// ************************************************************************** //
#include "RectangularDetector.h"
#include "MessageService.h"
#include "BornAgainNamespace.h"
#include "FixedBinAxis.h"
#include "ConstKBinAxis.h"
#include "CustomBinAxis.h"
#include "Beam.h"
#include "Rectangle.h"
#include <iostream>
#include <Eigen/LU>
#include <boost/scoped_ptr.hpp>
RectangularDetector::RectangularDetector()
{
setName("Detector");
init_parameters();
}
RectangularDetector::RectangularDetector(const RectangularDetector &other)
: IDetector2D(other)
{
init_parameters();
}
RectangularDetector &RectangularDetector::operator=(const RectangularDetector &other)
{
if (this != &other) {
RectangularDetector tmp(other);
tmp.swapContent(*this);
}
return *this;
}
RectangularDetector *RectangularDetector::clone() const
{
return new RectangularDetector(*this);
}
IPixelMap *RectangularDetector::createPixelMap(size_t index) const
{
const IAxis &phi_axis = getAxis(BornAgain::X_AXIS_INDEX);
const IAxis &alpha_axis = getAxis(BornAgain::Y_AXIS_INDEX);
size_t phi_index = getAxisBinIndex(index, BornAgain::X_AXIS_INDEX);
size_t alpha_index = getAxisBinIndex(index, BornAgain::Y_AXIS_INDEX);
Bin1D alpha_bin = alpha_axis.getBin(alpha_index);
Bin1D phi_bin = phi_axis.getBin(phi_index);
return new RectPixelMap(alpha_bin, phi_bin);
}
std::string RectangularDetector::addParametersToExternalPool(std::string path, ParameterPool *external_pool,
int copy_number) const
{
// add own parameters
std::string new_path
= IParameterized::addParametersToExternalPool(path, external_pool, copy_number);
// add parameters of the resolution function
if (mP_detector_resolution) {
mP_detector_resolution->addParametersToExternalPool(new_path, external_pool, -1);
}
return new_path;
}
void RectangularDetector::print(std::ostream &ostr) const
{
ostr << "Detector: '" << getName() << "' " << m_parameters;
for (size_t i = 0; i < m_axes.size(); ++i) {
ostr << " IAxis:" << *m_axes[i] << std::endl;
}
}
RectPixelMap::RectPixelMap(Bin1D alpha_bin, Bin1D phi_bin)
: m_alpha(alpha_bin.m_lower), m_phi(phi_bin.m_lower),
m_dalpha(alpha_bin.getBinSize()), m_dphi(phi_bin.getBinSize())
{
m_solid_angle = std::abs(m_dphi*(std::sin(m_alpha+m_dalpha) - std::sin(m_alpha)));
}
RectPixelMap *RectPixelMap::clone() const
{
Bin1D alpha_bin(m_alpha, m_alpha+m_dalpha);
Bin1D phi_bin(m_phi, m_phi+m_dphi);
return new RectPixelMap(alpha_bin, phi_bin);
}
RectPixelMap *RectPixelMap::createZeroSizeMap(double x, double y) const
{
double alpha = m_alpha + x*m_dalpha;
double phi = m_phi + y*m_dphi;
Bin1D alpha_bin(alpha, alpha);
Bin1D phi_bin(phi, phi);
return new RectPixelMap(alpha_bin, phi_bin);
}
kvector_t RectPixelMap::getK(double x, double y, double wavelength) const
{
kvector_t result;
double alpha = m_alpha + x*m_dalpha;
double phi = m_phi + y*m_dphi;
result.setLambdaAlphaPhi(wavelength, alpha, phi);
return result;
}
double RectPixelMap::getIntegrationFactor(double x, double y) const
{
(void)y;
if (m_dalpha==0.0) return 1.0;
double alpha = m_alpha + x*m_dalpha;
return std::cos(alpha)*m_dalpha/(std::sin(m_alpha+m_dalpha)-std::sin(m_alpha));
}
double RectPixelMap::getSolidAngle() const
{
if (m_solid_angle<=0.0) return 1.0;
return m_solid_angle;
}
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
SphericalDetector::SphericalDetector() SphericalDetector::SphericalDetector()
{ {
setName("Detector"); setName("SphericalDetector");
init_parameters(); init_parameters();
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment