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

Refactor detector analyzer properties

parent 490d94fc
No related branches found
No related tags found
No related merge requests found
......@@ -17,18 +17,11 @@
#include "Exceptions.h"
#include "Complex.h"
namespace {
// Calculates the vector 2*T*E*d from an analyzer operator, where
// T: total transmission
// E: efficiency
// d: unit vector (if non-zero) of analyzer direction
kvector_t CalculateDifferenceTimesDirection(Eigen::Matrix2cd analyzer_op);
}
DetectionProperties::DetectionProperties()
{
initPolarizationOperator();
}
: m_direction {}
, m_efficiency {}
, m_total_transmission { 1.0 }
{}
void DetectionProperties::setAnalyzerProperties(const kvector_t direction, double efficiency,
double total_transmission)
......@@ -36,41 +29,47 @@ void DetectionProperties::setAnalyzerProperties(const kvector_t direction, doubl
if (!checkAnalyzerProperties(direction, efficiency, total_transmission))
throw Exceptions::ClassInitializationException("IDetector2D::setAnalyzerProperties: the "
"given properties are not physical");
m_analyzer_operator = calculateAnalyzerOperator(direction, efficiency, total_transmission);
if (efficiency==0.0 || total_transmission==0.0 || direction.mag()==0.0) {
m_direction = kvector_t {};
m_efficiency = 0.0;
} else {
m_direction = direction.unit();
m_efficiency = efficiency;
}
m_total_transmission = total_transmission;
}
Eigen::Matrix2cd DetectionProperties::analyzerOperator() const
{
return m_analyzer_operator;
if (m_direction.mag()==0.0 || m_efficiency==0.0)
return m_total_transmission*Eigen::Matrix2cd::Identity();
Eigen::Matrix2cd result;
double x = m_direction.x()/m_direction.mag();
double y = m_direction.y()/m_direction.mag();
double z = m_direction.z()/m_direction.mag();
double sum = m_total_transmission * 2.0;
double diff = m_total_transmission * m_efficiency * 2.0;
complex_t im(0.0, 1.0);
result(0, 0) = (sum + diff*z) / 2.0;
result(0, 1) = diff*(x - im * y) / 2.0;
result(1, 0) = diff*(x + im * y) / 2.0;
result(1, 1) = (sum - diff*z) / 2.0;
return result;
}
kvector_t DetectionProperties::analyzerDirection() const
{
double T = analyzerTotalTransmission();
auto diffdir = CalculateDifferenceTimesDirection(m_analyzer_operator);
if (T<=0.0 || diffdir.mag()==0.0)
return {};
return diffdir.unit();
return m_direction;
}
double DetectionProperties::analyzerEfficiency() const
{
double T = analyzerTotalTransmission();
if (T<=0.0)
return 0.0;
auto diffdir = CalculateDifferenceTimesDirection(m_analyzer_operator);
return diffdir.mag()/T/2.0;
return m_efficiency;
}
double DetectionProperties::analyzerTotalTransmission() const
{
return std::abs(m_analyzer_operator.trace())/2.0;
}
void DetectionProperties::initPolarizationOperator()
{
m_analyzer_operator = Eigen::Matrix2cd::Identity();
return m_total_transmission;
}
bool DetectionProperties::checkAnalyzerProperties(
......@@ -86,31 +85,3 @@ bool DetectionProperties::checkAnalyzerProperties(
return false;
return true;
}
Eigen::Matrix2cd DetectionProperties::calculateAnalyzerOperator(
const kvector_t direction, double efficiency, double total_transmission) const
{
Eigen::Matrix2cd result;
double x = direction.x()/direction.mag();
double y = direction.y()/direction.mag();
double z = direction.z()/direction.mag();
double sum = total_transmission * 2.0;
double diff = total_transmission * efficiency * 2.0;
complex_t im(0.0, 1.0);
result(0, 0) = (sum + diff*z) / 2.0;
result(0, 1) = diff*(x - im * y) / 2.0;
result(1, 0) = diff*(x + im * y) / 2.0;
result(1, 1) = (sum - diff*z) / 2.0;
return result;
}
namespace {
kvector_t CalculateDifferenceTimesDirection(Eigen::Matrix2cd analyzer_op)
{
double x = 2.0*analyzer_op(0, 1).real();
double y = 2.0*analyzer_op(1, 0).imag();
double z = (analyzer_op(0, 0) - analyzer_op(1, 1)).real();
return { x, y, z };
}
}
......@@ -39,17 +39,13 @@ public:
double analyzerEfficiency() const;
double analyzerTotalTransmission() const;
private:
//! Initialize polarization
void initPolarizationOperator();
Eigen::Matrix2cd calculateAnalyzerOperator(
const kvector_t direction, double efficiency, double total_transmission = 1.0) const;
//! Verify if the given analyzer properties are physical
bool checkAnalyzerProperties(const kvector_t direction, double efficiency,
double total_transmission) const;
Eigen::Matrix2cd m_analyzer_operator; //!< polarization analyzer operator
kvector_t m_direction; //!< direction of polarization analysis
double m_efficiency; //!< efficiency of polarization analysis
double m_total_transmission; //!< total transmission of polarization analysis
};
#endif // DETECTIONPROPERTIES_H
......@@ -324,17 +324,16 @@ TEST_F(RectangularDetectorTest, AnalyzerProperties)
EXPECT_NEAR(detector.analyzerDirection().y(), unit_direction.y(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().z(), unit_direction.z(), 1e-8);
// maximum efficiency and negative efficiency (calculated efficiency will always be positive
// and the returned direction will be inverted)
// maximum efficiency and negative efficiency
direction = kvector_t(0.0, -1.0, -1.0);
efficiency = -1.0;
total_transmission = 0.5;
unit_direction = direction.unit();
detector.setAnalyzerProperties(direction, efficiency, total_transmission);
EXPECT_NEAR(detector.analyzerEfficiency(), -efficiency, 1e-8);
EXPECT_NEAR(detector.analyzerEfficiency(), efficiency, 1e-8);
EXPECT_NEAR(detector.analyzerTotalTransmission(), total_transmission, 1e-8);
EXPECT_NEAR(detector.analyzerDirection().x(), -unit_direction.x(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().y(), -unit_direction.y(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().z(), -unit_direction.z(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().x(), unit_direction.x(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().y(), unit_direction.y(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().z(), unit_direction.z(), 1e-8);
}
......@@ -443,9 +443,9 @@ TEST_F(SphericalDetectorTest, AnalyzerProperties)
unit_direction = direction.unit();
detector.setAnalyzerProperties(direction, efficiency, total_transmission);
EXPECT_NEAR(detector.analyzerEfficiency(), -efficiency, 1e-8);
EXPECT_NEAR(detector.analyzerEfficiency(), efficiency, 1e-8);
EXPECT_NEAR(detector.analyzerTotalTransmission(), total_transmission, 1e-8);
EXPECT_NEAR(detector.analyzerDirection().x(), -unit_direction.x(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().y(), -unit_direction.y(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().z(), -unit_direction.z(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().x(), unit_direction.x(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().y(), unit_direction.y(), 1e-8);
EXPECT_NEAR(detector.analyzerDirection().z(), unit_direction.z(), 1e-8);
}
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