Q2NS dev
ns-3 module
Loading...
Searching...
No Matches
q2nsviz-trace.h
Go to the documentation of this file.
1/*-----------------------------------------------------------------------------
2 * Q2NS - Quantum Network Simulator
3 * Copyright (c) 2026 quantuminternet.it
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *---------------------------------------------------------------------------*/
9#pragma once
10
11#include "ns3/nstime.h"
12#include "ns3/q2nsviz-trace-writer.h"
13#include <initializer_list>
14#include <sstream>
15#include <string>
16#include <utility>
17#include <vector>
18
19/*
20 v1 NDJSON schema (viewer.html expects these):
21 - createNode {t_ns, label, x, y}
22 - createChannel {t_ns, from, to, kind}
23 - createBit {t_ns, node, label, kind, color}
24 - setBitColor {t_ns, bit, color}
25 - entangle {t_ns, bits:[...]} // or {t_ns, duration_ns, bits:[...]}
26 - measure {t_ns, bit, base, b0} // or {t_ns, duration_ns, bit, base}
27 - graphMeasure {t_ns, bit, base, supportNode} // or {t_ns, duration_ns, bit, base, supportNode}
28 - sendBit {t0_ns, t1_ns, bit, from, to, kind}
29 - sendPacket {t0_ns, t1_ns, from, to, label}
30 - traceText {t_ns, text} // trace panel (persistent)
31 - traceText {t_ns, node, text} // node-local (one step)
32*/
33
34/*-----------------------------------------------------------------------------
35 * StrCat: concatenate any streamable parts into a std::string
36 *---------------------------------------------------------------------------*/
37template <typename... Ts> inline std::string StrCat(Ts&&... parts) {
38 std::ostringstream _oss;
39 (void) std::initializer_list<int>{((_oss << std::forward<Ts>(parts)), 0)...};
40 return _oss.str();
41}
42
43inline uint64_t NowNs() {
44 return ns3::Simulator::Now().GetNanoSeconds();
45}
46
47
48/*-----------------------------------------------------------------------------
49 * Nodes & Channels
50 *---------------------------------------------------------------------------*/
51inline void TraceCreateNode(const std::string& label, int xPct, int yPct) {
52 std::ostringstream o;
53 o << "{"
54 << "\"type\":\"createNode\",\"t_ns\":0,"
55 << "\"label\":" << J(label) << ",\"x\":" << xPct << ",\"y\":" << yPct << "}";
57}
58
59inline void TraceCreateChannel(const std::string& from, const std::string& to,
60 const std::string& kind) {
61 std::ostringstream o;
62 o << "{"
63 << "\"type\":\"createChannel\",\"t_ns\":0,"
64 << "\"from\":" << J(from) << ",\"to\":" << J(to) << ",\"kind\":" << J(kind) << "}";
66}
67
68/*-----------------------------------------------------------------------------
69 * Bits: create / color / entangle / measure
70 *---------------------------------------------------------------------------*/
71inline void TraceCreateBit(const std::string& node, const std::string& bitLabel,
72 const std::string& kind, const std::string& color) {
73 std::ostringstream o;
74 o << "{"
75 << "\"type\":\"createBit\",\"t_ns\":" << JTns() << ",\"node\":" << J(node)
76 << ",\"label\":" << J(bitLabel) << ",\"kind\":" << J(kind) << ",\"color\":" << J(color) << "}";
78}
79
80inline void TraceSetBitColor(const std::string& bitLabel, const std::string& color) {
81 std::ostringstream o;
82 o << "{"
83 << "\"type\":\"setBitColor\",\"t_ns\":" << JTns() << ",\"bit\":" << J(bitLabel)
84 << ",\"color\":" << J(color) << "}";
86}
87
88inline void TraceEntangle(const std::vector<std::string>& bits) {
89 std::ostringstream o;
90 o << "{"
91 << "\"type\":\"entangle\",\"t_ns\":" << JTns() << ",\"bits\":[";
92 for (size_t i = 0; i < bits.size(); ++i) {
93 if (i)
94 o << ",";
95 o << J(bits[i]);
96 }
97 o << "]}";
99}
100
101/* TraceEntangle with gate duration for physical accuracy.
102 The visualizer computes t0 = t_ns - duration_ns. */
103inline void TraceEntangle(const std::vector<std::string>& bits, uint64_t duration_ns) {
104 std::ostringstream o;
105 o << "{"
106 << "\"type\":\"entangle\",\"t_ns\":" << JTns() << ",\"duration_ns\":" << duration_ns
107 << ",\"bits\":[";
108 for (size_t i = 0; i < bits.size(); ++i) {
109 if (i)
110 o << ",";
111 o << J(bits[i]);
112 }
113 o << "]}";
114 TraceWriter::Instance().Write(o.str());
115}
116inline void TraceEntangle(const std::vector<std::string>& bits, ns3::Time duration) {
117 TraceEntangle(bits, duration.GetNanoSeconds());
118}
119
120/* Measure/collapse a bit: removes the bit from any entanglement going forward.
121 Optional measurement basis (default "Z"). */
122inline void TraceMeasure(const std::string& bitLabel, const std::string& base = "Z") {
123 std::ostringstream o;
124 o << "{"
125 << "\"type\":\"measure\",\"t_ns\":" << JTns() << ",\"bit\":" << J(bitLabel)
126 << ",\"base\":" << J(base) << "}";
127 TraceWriter::Instance().Write(o.str());
128}
129
130/* TraceMeasure with gate duration for physical accuracy.
131 The visualizer computes t0 = t_ns - duration_ns. */
132inline void TraceMeasure(const std::string& bitLabel, uint64_t duration_ns,
133 const std::string& base = "Z") {
134 std::ostringstream o;
135 o << "{"
136 << "\"type\":\"measure\",\"t_ns\":" << JTns() << ",\"duration_ns\":" << duration_ns
137 << ",\"bit\":" << J(bitLabel) << ",\"base\":" << J(base) << "}";
138 TraceWriter::Instance().Write(o.str());
139}
140inline void TraceMeasure(const std::string& bitLabel, ns3::Time duration,
141 const std::string& base = "Z") {
142 TraceMeasure(bitLabel, duration.GetNanoSeconds(), base);
143}
144
145/* Graph state measurement: visualization for graph-state operations. */
146inline void TraceGraphMeasure(const std::string& bitLabel, const std::string& base = "Z",
147 const std::string& supportNode = "") {
148 std::ostringstream o;
149 o << "{"
150 << "\"type\":\"graphMeasure\",\"t_ns\":" << JTns() << ",\"bit\":" << J(bitLabel)
151 << ",\"base\":" << J(base);
152 if (!supportNode.empty()) {
153 o << ",\"supportNode\":" << J(supportNode);
154 }
155 o << "}";
156 TraceWriter::Instance().Write(o.str());
157}
158
159/* TraceGraphMeasure with gate duration for physical accuracy.
160 The visualizer computes t0 = t_ns - duration_ns. */
161inline void TraceGraphMeasure(const std::string& bitLabel, uint64_t duration_ns,
162 const std::string& base = "Z",
163 const std::string& supportNode = "") {
164 std::ostringstream o;
165 o << "{"
166 << "\"type\":\"graphMeasure\",\"t_ns\":" << JTns() << ",\"duration_ns\":" << duration_ns
167 << ",\"bit\":" << J(bitLabel) << ",\"base\":" << J(base);
168 if (!supportNode.empty()) {
169 o << ",\"supportNode\":" << J(supportNode);
170 }
171 o << "}";
172 TraceWriter::Instance().Write(o.str());
173}
174inline void TraceGraphMeasure(const std::string& bitLabel, ns3::Time duration,
175 const std::string& base = "Z",
176 const std::string& supportNode = "") {
177 TraceGraphMeasure(bitLabel, duration.GetNanoSeconds(), base, supportNode);
178}
179
180inline void TraceRemoveBit(const std::string& bitLabel, uint64_t t_ns = NowNs()) {
181 std::ostringstream o;
182 o << "{"
183 << "\"type\":\"removeBit\","
184 << "\"t_ns\":" << t_ns << ",\"bit\":" << J(bitLabel) << "}";
185 TraceWriter::Instance().Write(o.str());
186}
187
188
189/*-----------------------------------------------------------------------------
190 * Movement: sendBit & sendPacket
191 *---------------------------------------------------------------------------*/
192inline void TraceSendBit(const std::string& bitLabel, const std::string& from,
193 const std::string& to, const std::string& kind, uint64_t t0_ns,
194 uint64_t t1_ns) {
195 std::ostringstream o;
196 o << "{"
197 << "\"type\":\"sendBit\",\"t0_ns\":" << t0_ns << ",\"t1_ns\":" << t1_ns
198 << ",\"bit\":" << J(bitLabel) << ",\"from\":" << J(from) << ",\"to\":" << J(to)
199 << ",\"kind\":" << J(kind) << "}";
200 TraceWriter::Instance().Write(o.str());
201}
202inline void TraceSendBit(const std::string& bitLabel, const std::string& from,
203 const std::string& to, const std::string& kind, ns3::Time t0,
204 ns3::Time t1) {
205 TraceSendBit(bitLabel, from, to, kind, t0.GetNanoSeconds(), t1.GetNanoSeconds());
206}
207
208inline void TraceSendPacket(const std::string& from, const std::string& to, uint64_t t0_ns,
209 uint64_t t1_ns, const std::string& label) {
210 std::ostringstream o;
211 o << "{"
212 << "\"type\":\"sendPacket\",\"t0_ns\":" << t0_ns << ",\"t1_ns\":" << t1_ns
213 << ",\"from\":" << J(from) << ",\"to\":" << J(to) << ",\"label\":" << J(label) << "}";
214 TraceWriter::Instance().Write(o.str());
215}
216inline void TraceSendPacket(const std::string& from, const std::string& to, ns3::Time t0,
217 ns3::Time t1, const std::string& label) {
218 TraceSendPacket(from, to, t0.GetNanoSeconds(), t1.GetNanoSeconds(), label);
219}
220
221/*-----------------------------------------------------------------------------
222 * Traces: HUD (persistent) and node-local (one-step)
223 *---------------------------------------------------------------------------*/
224inline void _TraceString(const std::string& text) {
225 std::ostringstream o;
226 o << "{"
227 << "\"type\":\"traceText\",\"t_ns\":" << JTns() << ",\"text\":" << J(text) << "}";
228 TraceWriter::Instance().Write(o.str());
229}
230
231inline void Trace(const std::string& text) {
232 _TraceString(text);
233}
234
235template <typename... Ts> inline void Trace(Ts&&... parts) {
236 _TraceString(StrCat(std::forward<Ts>(parts)...));
237}
238
239inline void _TraceNodeTextString(const std::string& node, const std::string& text) {
240 std::ostringstream o;
241 o << "{"
242 << "\"type\":\"traceText\",\"t_ns\":" << JTns() << ",\"node\":" << J(node)
243 << ",\"text\":" << J(text) << "}";
244 TraceWriter::Instance().Write(o.str());
245}
246
247inline void TraceNodeText(const std::string& node, const std::string& text) {
248 _TraceNodeTextString(node, text);
249}
250
251template <typename... Ts> inline void TraceNodeText(const std::string& node, Ts&&... parts) {
252 _TraceNodeTextString(node, StrCat(std::forward<Ts>(parts)...));
253}
static TraceWriter & Instance()
void Write(const std::string &line)
std::string J(const std::string &s)
uint64_t JTns()
std::string StrCat(Ts &&... parts)
void Trace(const std::string &text)
void TraceNodeText(const std::string &node, const std::string &text)
void TraceEntangle(const std::vector< std::string > &bits)
void TraceRemoveBit(const std::string &bitLabel, uint64_t t_ns=NowNs())
void TraceSendPacket(const std::string &from, const std::string &to, uint64_t t0_ns, uint64_t t1_ns, const std::string &label)
void TraceCreateBit(const std::string &node, const std::string &bitLabel, const std::string &kind, const std::string &color)
void TraceMeasure(const std::string &bitLabel, const std::string &base="Z")
void TraceGraphMeasure(const std::string &bitLabel, const std::string &base="Z", const std::string &supportNode="")
uint64_t NowNs()
void TraceCreateNode(const std::string &label, int xPct, int yPct)
void TraceCreateChannel(const std::string &from, const std::string &to, const std::string &kind)
void _TraceString(const std::string &text)
void TraceSendBit(const std::string &bitLabel, const std::string &from, const std::string &to, const std::string &kind, uint64_t t0_ns, uint64_t t1_ns)
void _TraceNodeTextString(const std::string &node, const std::string &text)
void TraceSetBitColor(const std::string &bitLabel, const std::string &color)