Skip to content
Snippets Groups Projects
Commit 35bc7237 authored by Yurov, Dmitry's avatar Yurov, Dmitry
Browse files

SpecularData container in SimulationElement

Redmine: #1910
Temporary solution to transfer specular data
parent e21478d4
No related branches found
No related tags found
No related merge requests found
...@@ -25,25 +25,28 @@ SimulationElement::SimulationElement(double wavelength, double alpha_i, double p ...@@ -25,25 +25,28 @@ SimulationElement::SimulationElement(double wavelength, double alpha_i, double p
, m_phi_i(phi_i) , m_phi_i(phi_i)
, m_intensity(0.0) , m_intensity(0.0)
, mP_pixel(std::move(pixel)) , mP_pixel(std::move(pixel))
, m_contains_specular(false)
{ {
initPolarization(); initPolarization();
} }
SimulationElement::SimulationElement(const SimulationElement& other) SimulationElement::SimulationElement(const SimulationElement& other)
: m_wavelength(other.m_wavelength), m_alpha_i(other.m_alpha_i), m_phi_i(other.m_phi_i) : m_wavelength(other.m_wavelength), m_alpha_i(other.m_alpha_i), m_phi_i(other.m_phi_i)
, m_intensity(other.m_intensity), m_contains_specular(other.m_contains_specular) , m_intensity(other.m_intensity)
{ {
mP_pixel.reset(other.mP_pixel->clone()); mP_pixel.reset(other.mP_pixel->clone());
if (other.m_specular_data)
m_specular_data.reset(new SpecularData(*other.m_specular_data));
m_polarization = other.m_polarization; m_polarization = other.m_polarization;
m_analyzer_operator = other.m_analyzer_operator; m_analyzer_operator = other.m_analyzer_operator;
} }
SimulationElement::SimulationElement(const SimulationElement& other, double x, double y) SimulationElement::SimulationElement(const SimulationElement& other, double x, double y)
: m_wavelength(other.m_wavelength), m_alpha_i(other.m_alpha_i), m_phi_i(other.m_phi_i) : m_wavelength(other.m_wavelength), m_alpha_i(other.m_alpha_i), m_phi_i(other.m_phi_i)
, m_intensity(other.m_intensity), m_contains_specular(other.m_contains_specular) , m_intensity(other.m_intensity)
{ {
mP_pixel.reset(other.mP_pixel->createZeroSizePixel(x, y)); mP_pixel.reset(other.mP_pixel->createZeroSizePixel(x, y));
if (other.m_specular_data)
m_specular_data.reset(new SpecularData(*other.m_specular_data));
m_polarization = other.m_polarization; m_polarization = other.m_polarization;
m_analyzer_operator = other.m_analyzer_operator; m_analyzer_operator = other.m_analyzer_operator;
} }
...@@ -56,7 +59,7 @@ SimulationElement::SimulationElement(SimulationElement&& other) noexcept ...@@ -56,7 +59,7 @@ SimulationElement::SimulationElement(SimulationElement&& other) noexcept
, m_polarization(std::move(other.m_polarization)) , m_polarization(std::move(other.m_polarization))
, m_analyzer_operator(std::move(other.m_analyzer_operator)) , m_analyzer_operator(std::move(other.m_analyzer_operator))
, mP_pixel(std::move(other.mP_pixel)) , mP_pixel(std::move(other.mP_pixel))
, m_contains_specular(other.m_contains_specular) , m_specular_data(std::move(other.m_specular_data))
{ {
} }
...@@ -108,7 +111,7 @@ void SimulationElement::swapContent(SimulationElement &other) ...@@ -108,7 +111,7 @@ void SimulationElement::swapContent(SimulationElement &other)
std::swap(m_polarization, other.m_polarization); std::swap(m_polarization, other.m_polarization);
std::swap(m_analyzer_operator, other.m_analyzer_operator); std::swap(m_analyzer_operator, other.m_analyzer_operator);
std::swap(mP_pixel, other.mP_pixel); std::swap(mP_pixel, other.mP_pixel);
std::swap(m_contains_specular, other.m_contains_specular); std::swap(m_specular_data, other.m_specular_data);
} }
void SimulationElement::initPolarization() void SimulationElement::initPolarization()
...@@ -127,14 +130,14 @@ double SimulationElement::getPhi(double x, double y) const ...@@ -127,14 +130,14 @@ double SimulationElement::getPhi(double x, double y) const
return getKf(x,y).phi(); return getKf(x,y).phi();
} }
bool SimulationElement::containsSpecularWavevector() const void SimulationElement::setSpecular()
{ {
return m_contains_specular; m_specular_data.reset(new SpecularData);
} }
void SimulationElement::setSpecular(bool contains_specular) void SimulationElement::setSpecular(std::unique_ptr<SpecularData> specular_data)
{ {
m_contains_specular = contains_specular; m_specular_data = std::move(specular_data);
} }
double SimulationElement::getIntegrationFactor(double x, double y) const { double SimulationElement::getIntegrationFactor(double x, double y) const {
...@@ -152,3 +155,26 @@ void addElementsWithWeight(std::vector<SimulationElement>::const_iterator first, ...@@ -152,3 +155,26 @@ void addElementsWithWeight(std::vector<SimulationElement>::const_iterator first,
for (std::vector<SimulationElement>::const_iterator it = first; it != last; ++it, ++result) for (std::vector<SimulationElement>::const_iterator it = first; it != last; ++it, ++result)
result->addIntensity(it->getIntensity() * weight); result->addIntensity(it->getIntensity() * weight);
} }
SpecularData::SpecularData() : data_type_used(DATA_TYPE::Invalid) {}
SpecularData::SpecularData(MatrixVector coefficients)
: data(std::move(coefficients))
, data_type_used(DATA_TYPE::Matrix)
{}
SpecularData::SpecularData(ScalarVector coefficients)
: data(std::move(coefficients))
, data_type_used(DATA_TYPE::Scalar)
{}
const ILayerRTCoefficients& SpecularData::operator[](size_t index) const
{
if (data_type_used == DATA_TYPE::Invalid)
throw std::runtime_error(
"Error in SpecularData::operator[]: attempt to access uninitialized data");
if (data_type_used == DATA_TYPE::Scalar)
return (*boost::get<ScalarVector>(&data))[index];
else
return (*boost::get<MatrixVector>(&data))[index];
}
...@@ -20,10 +20,14 @@ ...@@ -20,10 +20,14 @@
#include "EigenCore.h" #include "EigenCore.h"
#include "Vectors3D.h" #include "Vectors3D.h"
#include "IPixel.h" #include "IPixel.h"
#include "MatrixRTCoefficients.h"
#include "ScalarRTCoefficients.h"
#include <boost/variant.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
class IPixel; class IPixel;
class SpecularData;
//! Data stucture containing both input and output of a single detector cell. //! Data stucture containing both input and output of a single detector cell.
//! @ingroup simulation //! @ingroup simulation
...@@ -80,11 +84,12 @@ public: ...@@ -80,11 +84,12 @@ public:
double getAlpha(double x, double y) const; double getAlpha(double x, double y) const;
double getPhi(double x, double y) const; double getPhi(double x, double y) const;
//! check if element contains given wavevector //! check if element corresponds to specular peak
bool containsSpecularWavevector() const; SpecularData* specularData() const {return m_specular_data.get();}
//! indicate that this element contains the specular wavevector //! Turn on specular data
void setSpecular(bool contains_specular); void setSpecular();
void setSpecular(std::unique_ptr<SpecularData> specular_data);
private: private:
void swapContent(SimulationElement &other); void swapContent(SimulationElement &other);
...@@ -99,7 +104,7 @@ private: ...@@ -99,7 +104,7 @@ private:
Eigen::Matrix2cd m_analyzer_operator; //!< polarization analyzer operator Eigen::Matrix2cd m_analyzer_operator; //!< polarization analyzer operator
#endif #endif
std::unique_ptr<IPixel> mP_pixel; std::unique_ptr<IPixel> mP_pixel;
bool m_contains_specular; std::unique_ptr<SpecularData> m_specular_data;
}; };
...@@ -109,4 +114,29 @@ void addElementsWithWeight(std::vector<SimulationElement>::const_iterator first, ...@@ -109,4 +114,29 @@ void addElementsWithWeight(std::vector<SimulationElement>::const_iterator first,
std::vector<SimulationElement>::iterator result, std::vector<SimulationElement>::iterator result,
double weight); double weight);
//! Helper class for SimulationElement to carry specular information
//! @ingroup simulation
class SpecularData
{
// FIXME: find a better way to carry the specular data in SimulationElement
using ScalarVector = std::vector<ScalarRTCoefficients>;
using MatrixVector = std::vector<MatrixRTCoefficients>;
public:
SpecularData();
SpecularData(MatrixVector coefficients);
SpecularData(ScalarVector coefficients);
const ILayerRTCoefficients& operator[](size_t index) const;
bool isInited() const {return data_type_used != DATA_TYPE::Invalid;}
private:
enum class DATA_TYPE { Invalid = -1, Scalar, Matrix };
boost::variant<ScalarVector, MatrixVector> data;
DATA_TYPE data_type_used;
};
#endif // SIMULATIONELEMENT_H #endif // SIMULATIONELEMENT_H
...@@ -17,12 +17,13 @@ void SpecularComputationTerm::eval(ProgressHandler*, ...@@ -17,12 +17,13 @@ void SpecularComputationTerm::eval(ProgressHandler*,
return; return;
for (auto it = begin_it; it != end_it; ++it) for (auto it = begin_it; it != end_it; ++it)
if (it->containsSpecularWavevector()) if (it->specularData())
evalSingle(it); evalSingle(it);
} }
void SpecularComputationTerm::evalSingle(const std::vector<SimulationElement>::iterator& iter) const void SpecularComputationTerm::evalSingle(const std::vector<SimulationElement>::iterator& iter) const
{ {
complex_t R = mp_fresnel_map->getInCoefficients(*iter, 0)->getScalarR(); mp_fresnel_map->fillSpecularData(*iter);
iter->setIntensity(std::norm(R)); const ILayerRTCoefficients& layer_data = (*iter->specularData())[0];
iter->setIntensity(std::norm(layer_data.getScalarR()));
} }
...@@ -111,7 +111,7 @@ std::vector<SimulationElement> IDetector2D::createSimulationElements(const Beam ...@@ -111,7 +111,7 @@ std::vector<SimulationElement> IDetector2D::createSimulationElements(const Beam
sim_element.setPolarization(beam_polarization); sim_element.setPolarization(beam_polarization);
sim_element.setAnalyzerOperator(analyzer_operator); sim_element.setAnalyzerOperator(analyzer_operator);
if (it.index()==spec_index) { if (it.index()==spec_index) {
sim_element.setSpecular(true); sim_element.setSpecular();
} }
result.push_back(std::move(sim_element)); result.push_back(std::move(sim_element));
} }
......
...@@ -80,7 +80,7 @@ std::vector<SimulationElement> SpecularDetector1D::createSimulationElements(cons ...@@ -80,7 +80,7 @@ std::vector<SimulationElement> SpecularDetector1D::createSimulationElements(cons
std::make_unique<SpecularPixel>(alpha_i)); std::make_unique<SpecularPixel>(alpha_i));
sim_element.setPolarization(beam_polarization); sim_element.setPolarization(beam_polarization);
sim_element.setAnalyzerOperator(analyzer_operator); sim_element.setAnalyzerOperator(analyzer_operator);
sim_element.setSpecular(true); sim_element.setSpecular();
result.push_back(std::move(sim_element)); result.push_back(std::move(sim_element));
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
class ILayerRTCoefficients; class ILayerRTCoefficients;
class MultiLayer; class MultiLayer;
class SimulationElement; class SimulationElement;
struct SpecularData;
//! Holds the necessary information to calculate the radiation wavefunction in every layer //! Holds the necessary information to calculate the radiation wavefunction in every layer
//! for different incoming (outgoing) angles of the beam in the top layer //! for different incoming (outgoing) angles of the beam in the top layer
...@@ -43,6 +44,9 @@ public: ...@@ -43,6 +44,9 @@ public:
virtual const ILayerRTCoefficients* getInCoefficients( virtual const ILayerRTCoefficients* getInCoefficients(
const SimulationElement& sim_element, size_t layer_index) const =0; const SimulationElement& sim_element, size_t layer_index) const =0;
//! Fills simulation element specular data
virtual void fillSpecularData(SimulationElement& sim_element) const = 0;
//! Sets the multilayer to be used for the Fresnel calculations. //! Sets the multilayer to be used for the Fresnel calculations.
virtual void setMultilayer(const MultiLayer& multilayer); virtual void setMultilayer(const MultiLayer& multilayer);
......
...@@ -46,6 +46,17 @@ MatrixFresnelMap::getInCoefficients(const SimulationElement& sim_element, size_t ...@@ -46,6 +46,17 @@ MatrixFresnelMap::getInCoefficients(const SimulationElement& sim_element, size_t
return getCoefficients(sim_element.getKi(), layer_index, *mP_multilayer, m_hash_table_in); return getCoefficients(sim_element.getKi(), layer_index, *mP_multilayer, m_hash_table_in);
} }
void MatrixFresnelMap::fillSpecularData(SimulationElement& sim_element) const
{
const auto& kvec = sim_element.getKi();
std::vector<MatrixRTCoefficients> coef_vector;
if (m_use_cache)
coef_vector = getCoefficientsFromCache(kvec, *mP_multilayer, m_hash_table_in);
else
coef_vector = calculateCoefficients(*mP_multilayer, kvec);
sim_element.setSpecular(std::make_unique<SpecularData>(std::move(coef_vector)));
}
const ILayerRTCoefficients* MatrixFresnelMap::getCoefficients(kvector_t kvec, size_t layer_index, const ILayerRTCoefficients* MatrixFresnelMap::getCoefficients(kvector_t kvec, size_t layer_index,
const MultiLayer& multilayer, const MultiLayer& multilayer,
CoefficientHash& hash_table) const CoefficientHash& hash_table) const
......
...@@ -44,6 +44,9 @@ public: ...@@ -44,6 +44,9 @@ public:
void setMultilayer(const MultiLayer& multilayer) final override; void setMultilayer(const MultiLayer& multilayer) final override;
//! Fills simulation element specular data
virtual void fillSpecularData(SimulationElement& sim_element) const override;
typedef std::unordered_map<kvector_t, std::vector<MatrixRTCoefficients>, HashKVector> typedef std::unordered_map<kvector_t, std::vector<MatrixRTCoefficients>, HashKVector>
CoefficientHash; CoefficientHash;
......
...@@ -42,6 +42,17 @@ const ILayerRTCoefficients* ScalarFresnelMap::getInCoefficients( ...@@ -42,6 +42,17 @@ const ILayerRTCoefficients* ScalarFresnelMap::getInCoefficients(
return getCoefficients(sim_element.getKi(), layer_index); return getCoefficients(sim_element.getKi(), layer_index);
} }
void ScalarFresnelMap::fillSpecularData(SimulationElement& sim_element) const
{
const auto& kvec = sim_element.getKi();
std::vector<ScalarRTCoefficients> coef_vector;
if (m_use_cache)
coef_vector = getCoefficientsFromCache(kvec);
else
coef_vector = calculateCoefficients(*mP_multilayer, kvec);
sim_element.setSpecular(std::make_unique<SpecularData>(std::move(coef_vector)));
}
const ScalarRTCoefficients* ScalarFresnelMap::getCoefficients( const ScalarRTCoefficients* ScalarFresnelMap::getCoefficients(
kvector_t kvec, size_t layer_index) const kvector_t kvec, size_t layer_index) const
{ {
......
...@@ -44,6 +44,9 @@ public: ...@@ -44,6 +44,9 @@ public:
virtual const ILayerRTCoefficients* getInCoefficients( virtual const ILayerRTCoefficients* getInCoefficients(
const SimulationElement& sim_element, size_t layer_index) const final override; const SimulationElement& sim_element, size_t layer_index) const final override;
//! Fills simulation element specular data
virtual void fillSpecularData(SimulationElement& sim_element) const override;
private: private:
const ScalarRTCoefficients* getCoefficients(kvector_t kvec, size_t layer_index) const; const ScalarRTCoefficients* getCoefficients(kvector_t kvec, size_t layer_index) const;
const std::vector<ScalarRTCoefficients>& getCoefficientsFromCache(kvector_t kvec) const; const std::vector<ScalarRTCoefficients>& getCoefficientsFromCache(kvector_t kvec) const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment