Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
detectorfluxanalysis2d.cpp
Go to the documentation of this file.
1/**
2 * @file detectorfluxanalysis2d.cpp
3 * @brief Implements the detectorfluxanalysis2d physics/numerical component used by QPE experiments.
4 * @ingroup qpe_quantum
5 *
6 * Source: @c core/quantum/detectorfluxanalysis2d.cpp. This file is part of Quantum Phenomena Explorer (QPE),
7 * maintained by Officina Turini. See LICENSE_IT.txt / LICENSE.txt for the
8 * QPE freeware source-available terms and THIRD_PARTY_NOTICES.txt for
9 * third-party components.
10 */
11
13
14#include <algorithm>
15#include <cmath>
16
17namespace qpe {
18namespace {
19
20/**
21 * @brief Returns normalize.
22 * @param values The values value used by the operation.
23 */
24bool normalize(std::vector<double> &values)
25{
26 double sum = 0.0;
27 for (std::size_t i = 0u; i < values.size(); ++i) {
28 if (!std::isfinite(values[i]) || values[i] < 0.0) {
29 values[i] = 0.0;
30 }
31 sum += values[i];
32 }
33 if (!(sum > 0.0)) {
34 return false;
35 }
36 const double inv = 1.0 / sum;
37 for (std::size_t i = 0u; i < values.size(); ++i) {
38 values[i] *= inv;
39 }
40 return true;
41}
42
43std::size_t profileIndexToBin(std::size_t index,
44 std::size_t sampleCount,
45 std::size_t bins)
46{
47 if (sampleCount <= 1u || bins <= 1u) {
48 return 0u;
49 }
50 const double u = static_cast<double>(index) /
51 static_cast<double>(sampleCount - 1u);
52 std::size_t bin = static_cast<std::size_t>(u * static_cast<double>(bins));
53 if (bin >= bins) {
54 bin = bins - 1u;
55 }
56 return bin;
57}
58
59} // namespace
60
62 const std::vector<double> &fluxProfile,
63 std::size_t bins)
64{
65 if (bins == 0u || fluxProfile.empty()) {
66 return std::vector<double>();
67 }
68
69 std::vector<double> result(bins, 0.0);
70 for (std::size_t i = 0u; i < fluxProfile.size(); ++i) {
71 const double v = fluxProfile[i];
72 if (std::isfinite(v) && v > 0.0) {
73 result[profileIndexToBin(i, fluxProfile.size(), bins)] += v;
74 }
75 }
76 if (!normalize(result)) {
77 result.clear();
78 }
79 return result;
80}
81
83 const std::vector<double> &fluxProfile,
84 float dy,
85 const std::vector<PositionMeasurement2DPoint> &hits,
86 std::size_t bins)
87{
89 if (bins == 0u || fluxProfile.empty() || !(dy > 0.0f)) {
90 return result;
91 }
92
93 result.expectedProbability = rebinNormalizedProfile(fluxProfile, bins);
94 result.expectedValid = !result.expectedProbability.empty();
95
96 result.observedProbability.assign(bins, 0.0);
97 if (!hits.empty()) {
98 const double yMin = -0.5 * static_cast<double>(fluxProfile.size() - 1u) *
99 static_cast<double>(dy);
100 const double yMax = 0.5 * static_cast<double>(fluxProfile.size() - 1u) *
101 static_cast<double>(dy);
102 const double span = yMax - yMin;
103 if (span > 0.0) {
104 for (std::size_t i = 0u; i < hits.size(); ++i) {
105 const double y = static_cast<double>(hits[i].y);
106 if (y < yMin || y > yMax) {
107 continue;
108 }
109 double u = (y - yMin) / span;
110 u = std::max(0.0, std::min(1.0, u));
111 std::size_t bin = static_cast<std::size_t>(u * static_cast<double>(bins));
112 if (bin >= bins) {
113 bin = bins - 1u;
114 }
115 result.observedProbability[bin] += 1.0;
116 }
117 }
118 }
119 result.observedValid = normalize(result.observedProbability);
120 if (!result.observedValid) {
121 result.observedProbability.clear();
122 }
123
124 if (result.expectedValid && result.observedValid) {
125 double distance = 0.0;
126 for (std::size_t i = 0u; i < bins; ++i) {
127 distance += std::fabs(result.expectedProbability[i] -
128 result.observedProbability[i]);
129 }
130 result.totalVariationDistance = 0.5 * distance;
131 }
132 return result;
133}
134
135} // namespace qpe
static DetectorFluxAnalysis2DResult analyze(const std::vector< double > &fluxProfile, float dy, const std::vector< PositionMeasurement2DPoint > &hits, std::size_t bins)
Performs analyze.
static std::vector< double > rebinNormalizedProfile(const std::vector< double > &fluxProfile, std::size_t bins)
Performs rebin normalized profile.
Declares the detectorfluxanalysis2d physics/numerical component used by QPE experiments.
std::size_t profileIndexToBin(std::size_t index, std::size_t sampleCount, std::size_t bins)
Data record containing Detector Flux Analysis2D Result.