File: LambdaScan.cpp

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 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 (94 lines) | stat: -rw-r--r-- 3,571 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
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sim/Scan/LambdaScan.cpp
//! @brief     Implements class LambdaScan.
//!
//! @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)
//
//  ************************************************************************************************

#include "Sim/Scan/LambdaScan.h"
#include "Base/Axis/MakeScale.h"
#include "Base/Axis/Scale.h"
#include "Base/Vector/GisasDirection.h"
#include "Device/Beam/Beam.h"
#include "Device/Beam/IFootprint.h"
#include "Param/Distrib/ParameterSample.h"
#include "Resample/Element/ScanElement.h"
#include <algorithm> // is_sorted
#include <numbers>

using std::numbers::pi;

LambdaScan::LambdaScan(const Scale& lambdaScale)
    : PhysicalScan(lambdaScale)
{
    std::vector<double> axis_values = m_axis->binCenters();
    if (!std::is_sorted(axis_values.begin(), axis_values.end()))
        throw std::runtime_error("LambdaScan: wavelength values are not "
                                 "sorted in ascending order.");
    if (axis_values.front() <= 0)
        throw std::runtime_error("LambdaScan: non-positive wavelengths.");

    for (size_t i = 0; i < nScan(); i++) {
        auto* beam = new Beam(defaultIntensity, m_axis->binCenter(i), defaultGrazingAngle);
        m_beams.push_back(beam);
    }
}

LambdaScan::LambdaScan(std::vector<double> points)
    : LambdaScan(ListScan("lambda (nm)", std::move(points)))
{
}

LambdaScan::LambdaScan(int nbins, double lambda_min, double lambda_max)
    : LambdaScan(EquiScan("lambda (nm)", nbins, lambda_min, lambda_max))
{
}

LambdaScan::~LambdaScan() = default;

LambdaScan* LambdaScan::clone() const
{
    auto* result = new LambdaScan(*m_axis);
    copyPhysicalScan(result);
    return result;
}

std::vector<ScanElement> LambdaScan::generateElements() const
{
    std::vector<ScanElement> result;
    result.reserve(nElements());

    for (size_t i = 0; i < m_axis->size(); ++i) {
        const std::vector<ParameterSample> alphaDistrib =
            drawDistribution(m_alpha_distrib.get(), grazingAngleAt(i));
        const std::vector<ParameterSample> lambdaDistrib =
            drawDistribution(m_lambda_distrib.get(), wavelengthAt(i));
        const std::vector<ParameterSample> phiDistrib =
            drawDistribution(m_phi_distrib.get(), azimuthalAngleAt(i));
        for (auto ad : alphaDistrib) {
            const double alpha = ad.value;
            for (auto ld : lambdaDistrib) {
                const double lambda = ld.value;
                for (auto pd : phiDistrib) {
                    const double phi = pd.value;
                    const R3 kvec = vecOfLambdaAlphaPhi(lambda, -alpha, -phi);
                    const bool computable =
                        lambda > 0 && alpha >= 0 && alpha <= (pi / 2) && kvec.z() <= 0;
                    const double weight = ad.weight * ld.weight * pd.weight;
                    const double footprint = footprintAt(i) ? footprintAt(i)->calculate(alpha) : 1;
                    result.emplace_back(i, computable, weight, intensityAt(i), footprint,
                                        polarizerMatrixAt(i), analyzerMatrix(), lambda, alpha, phi,
                                        kvec);
                }
            }
        }
    }
    return result;
}