Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
quantumbackflowplotwidget.cpp
Go to the documentation of this file.
1/**
2 * @file quantumbackflowplotwidget.cpp
3 * @brief Implements the quantumbackflowplotwidget visualization component used by QPE.
4 * @ingroup qpe_graphics
5 *
6 * Source: @c graphics/renderer/quantumbackflowplotwidget.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 <QPainter>
15#include <QPainterPath>
16#include <QPaintEvent>
17#include <algorithm>
18#include <cmath>
19
21 : QWidget(parent) {}
22
24{
25 history_ = &history;
26 update();
27}
28
30{
31 history_ = nullptr;
32 update();
33}
34
36{
37 return QSize(650, 430);
38}
39
41{
42 Q_UNUSED(event);
43 QPainter p(this);
44 p.setRenderHint(QPainter::Antialiasing, true);
45 p.fillRect(rect(), QColor(10, 14, 20));
46
47 QFont bold = font();
48 bold.setBold(true);
49 p.setFont(bold);
50 p.setPen(QColor(225, 235, 244));
51 p.drawText(QRect(12, 7, width() - 24, 24), Qt::AlignLeft | Qt::AlignVCenter,
52 QStringLiteral("Quantum backflow — positive momentum, negative probability current"));
53
54 if (!history_ || !history_->configured() || history_->samples().empty()) {
55 p.setFont(font());
56 p.setPen(QColor(150, 166, 180));
57 p.drawText(QRect(20, 50, width() - 40, height() - 70),
58 Qt::AlignCenter | Qt::TextWordWrap,
59 QStringLiteral("Load Quantum Backflow and press Play"));
60 return;
61 }
62
63 const auto &s = history_->samples();
64 const auto &cfg = history_->config();
65 const auto &last = s.back();
66
67 const int left = 62;
68 const int right = 18;
69 const int top = 42;
70 const int gap = 28;
71 const int bottomH = 155;
72 QRect currentR(left, top, std::max(140, width() - left - right),
73 std::max(145, height() - top - gap - bottomH - 30));
74 QRect probR(left, currentR.bottom() + gap, currentR.width(),
75 std::max(110, height() - (currentR.bottom() + gap) - 28));
76
77 p.setPen(QColor(55, 72, 88));
78 p.setBrush(QColor(5, 9, 15));
79 p.drawRect(currentR);
80 p.drawRect(probR);
81
82 const double tmax = std::max(cfg.analysisEndTime, last.time);
83 auto tx = [&](double t) {
84 return currentR.left() + t / std::max(1.0e-12, tmax) * currentR.width();
85 };
86
87 double maxAbsJ = 1.0e-6;
88 for (const auto &a : s) maxAbsJ = std::max(maxAbsJ, std::abs(a.detectorCurrent));
89 maxAbsJ *= 1.12;
90 auto jy = [&](double j) {
91 return currentR.center().y() - j / maxAbsJ * (0.46 * currentR.height());
92 };
93
94 const double zeroY = jy(0.0);
95 p.setPen(QPen(QColor(90, 105, 120), 1.0, Qt::DashLine));
96 p.drawLine(QPointF(currentR.left(), zeroY), QPointF(currentR.right(), zeroY));
97
98 // Shade samples that are genuinely flowing backwards.
99 p.setPen(Qt::NoPen);
100 p.setBrush(QColor(220, 70, 95, 40));
101 for (std::size_t i = 1; i < s.size(); ++i) {
102 if (s[i - 1].detectorCurrent < 0.0 || s[i].detectorCurrent < 0.0) {
103 const double xa = tx(s[i - 1].time);
104 const double xb = tx(s[i].time);
105 p.drawRect(QRectF(std::min(xa, xb), currentR.top(), std::abs(xb - xa) + 1.0, currentR.height()));
106 }
107 }
108
109 QPainterPath currentPath;
110 for (std::size_t i = 0; i < s.size(); ++i) {
111 QPointF q(tx(s[i].time), jy(s[i].detectorCurrent));
112 if (i == 0) currentPath.moveTo(q); else currentPath.lineTo(q);
113 }
114 p.setPen(QPen(QColor(105, 220, 255), 2.1));
115 p.drawPath(currentPath);
116
117 auto py = [&](double v) {
118 return probR.bottom() - std::max(0.0, std::min(1.0, v)) * probR.height();
119 };
120 double maxFlux = std::max(0.01, history_->maximumBackwardFlux());
121 auto fy = [&](double v) {
122 return probR.bottom() - std::max(0.0, v) / maxFlux * (0.45 * probR.height());
123 };
124
125 QPainterPath leftPath, fluxPath;
126 for (std::size_t i = 0; i < s.size(); ++i) {
127 QPointF a(tx(s[i].time), py(s[i].probabilityLeft));
128 QPointF b(tx(s[i].time), fy(s[i].cumulativeBackwardFlux));
129 if (i == 0) { leftPath.moveTo(a); fluxPath.moveTo(b); }
130 else { leftPath.lineTo(a); fluxPath.lineTo(b); }
131 }
132 p.setPen(QPen(QColor(120, 235, 160), 2.0));
133 p.drawPath(leftPath);
134 p.setPen(QPen(QColor(255, 209, 102), 1.8));
135 p.drawPath(fluxPath);
136
137 p.setFont(font());
138 p.setPen(QColor(180, 198, 212));
139 p.drawText(QRect(currentR.left(), currentR.bottom() + 3, currentR.width(), 20), Qt::AlignCenter,
140 QStringLiteral("time cyan: integrated Jx at detector red shade: Jx < 0"));
141 p.drawText(QRect(probR.left(), probR.bottom() + 4, probR.width(), 20), Qt::AlignCenter,
142 QStringLiteral("green: P(x < detector) yellow: accumulated backward flux"));
143
144 p.setPen(QColor(232, 238, 244));
145 const QString state = last.detectorCurrent < 0.0 ? QStringLiteral("BACKFLOW") : QStringLiteral("forward flow");
146 p.drawText(QRect(currentR.left() + 8, currentR.top() + 5, currentR.width() - 16, 22),
147 Qt::AlignLeft | Qt::AlignVCenter,
148 QStringLiteral("p_x>0 fraction=%1 Jmin=%2 backflow=%3 now: %4")
149 .arg(history_->positiveMomentumFraction(), 0, 'f', 9)
150 .arg(history_->minimumCurrent(), 0, 'g', 5)
151 .arg(history_->maximumBackwardFlux(), 0, 'g', 5)
152 .arg(state));
153}
QSize minimumSizeHint() const override
Performs minimum size hint.
const qpe::QuantumBackflowHistory2D * history_
QuantumBackflowPlotWidget(QWidget *parent=nullptr)
Performs quantum backflow plot widget.
void paintEvent(QPaintEvent *event) override
Paints event.
void setData(const qpe::QuantumBackflowHistory2D &history)
Sets data.
Implements the Quantum Backflow History2D component.
const QuantumBackflow2DConfig & config() const noexcept
Returns config.
double minimumCurrent() const noexcept
Carries out minimum current.
const std::vector< QuantumBackflowSample2D > & samples() const noexcept
Samples s.
bool configured() const noexcept
Returns configured.
double maximumBackwardFlux() const noexcept
Carries out maximum backward flux.
double positiveMomentumFraction() const noexcept
Carries out positive momentum fraction.
Declares the quantumbackflowplotwidget visualization component used by QPE.