v2.0.0
Loading...
Searching...
No Matches
mna_node.cpp
Go to the documentation of this file.
1//=============================================================================================================
34
35//=============================================================================================================
36// INCLUDES
37//=============================================================================================================
38
39#include "mna_node.h"
40
41#include <QJsonArray>
42#include <QCborArray>
43
44//=============================================================================================================
45// USED NAMESPACES
46//=============================================================================================================
47
48using namespace MNALIB;
49
50//=============================================================================================================
51// STATIC HELPERS
52//=============================================================================================================
53
54static QString execModeToString(MnaNodeExecMode mode)
55{
56 switch (mode) {
57 case MnaNodeExecMode::Batch: return QStringLiteral("batch");
58 case MnaNodeExecMode::Stream: return QStringLiteral("stream");
59 case MnaNodeExecMode::Ipc: return QStringLiteral("ipc");
60 case MnaNodeExecMode::Script: return QStringLiteral("script");
61 }
62 return QStringLiteral("batch");
63}
64
65//=============================================================================================================
66
67static MnaNodeExecMode execModeFromString(const QString& str)
68{
69 if (str == QLatin1String("stream")) return MnaNodeExecMode::Stream;
70 if (str == QLatin1String("ipc")) return MnaNodeExecMode::Ipc;
71 if (str == QLatin1String("script")) return MnaNodeExecMode::Script;
73}
74
75//=============================================================================================================
76// DEFINE MEMBER METHODS
77//=============================================================================================================
78
79QJsonObject MnaNode::toJson() const
80{
81 QJsonObject json = extras;
82 json[QLatin1String("id")] = id;
83 json[QLatin1String("op_type")] = opType;
84 json[QLatin1String("exec_mode")] = execModeToString(execMode);
85
86 // Attributes
87 json[QLatin1String("attributes")] = QJsonObject::fromVariantMap(attributes);
88
89 // Ports
90 QJsonArray inputArr;
91 for (const MnaPort& p : inputs)
92 inputArr.append(p.toJson());
93 json[QLatin1String("inputs")] = inputArr;
94
95 QJsonArray outputArr;
96 for (const MnaPort& p : outputs)
97 outputArr.append(p.toJson());
98 json[QLatin1String("outputs")] = outputArr;
99
100 // IPC config
102 json[QLatin1String("ipc_command")] = ipcCommand;
103 QJsonArray argsArr;
104 for (const QString& arg : ipcArgs)
105 argsArr.append(arg);
106 json[QLatin1String("ipc_args")] = argsArr;
107 json[QLatin1String("ipc_work_dir")] = ipcWorkDir;
108 json[QLatin1String("ipc_transport")] = ipcTransport;
109 }
110
111 // Script config
113 json[QLatin1String("script")] = script.toJson();
114 }
115
116 // Verification & provenance
117 QJsonObject verObj = verification.toJson();
118 if (!verObj.isEmpty()) {
119 json[QLatin1String("verification")] = verObj;
120 }
121
122 // Metadata
123 if (!toolVersion.isEmpty())
124 json[QLatin1String("tool_version")] = toolVersion;
125 if (executedAt.isValid())
126 json[QLatin1String("executed_at")] = executedAt.toString(Qt::ISODate);
127 json[QLatin1String("dirty")] = dirty;
128
129 return json;
130}
131
132//=============================================================================================================
133
134MnaNode MnaNode::fromJson(const QJsonObject& json)
135{
136 MnaNode node;
137 node.id = json[QLatin1String("id")].toString();
138 node.opType = json[QLatin1String("op_type")].toString();
139 node.execMode = execModeFromString(json[QLatin1String("exec_mode")].toString());
140
141 node.attributes = json[QLatin1String("attributes")].toObject().toVariantMap();
142
143 // Ports
144 QJsonArray inputArr = json[QLatin1String("inputs")].toArray();
145 for (const QJsonValue& v : inputArr)
146 node.inputs.append(MnaPort::fromJson(v.toObject()));
147
148 QJsonArray outputArr = json[QLatin1String("outputs")].toArray();
149 for (const QJsonValue& v : outputArr)
150 node.outputs.append(MnaPort::fromJson(v.toObject()));
151
152 // IPC
153 node.ipcCommand = json[QLatin1String("ipc_command")].toString();
154 QJsonArray argsArr = json[QLatin1String("ipc_args")].toArray();
155 for (const QJsonValue& v : argsArr)
156 node.ipcArgs.append(v.toString());
157 node.ipcWorkDir = json[QLatin1String("ipc_work_dir")].toString();
158 node.ipcTransport = json[QLatin1String("ipc_transport")].toString();
159
160 // Script
161 if (json.contains(QLatin1String("script"))) {
162 node.script = MnaScript::fromJson(json[QLatin1String("script")].toObject());
163 }
164
165 // Verification
166 if (json.contains(QLatin1String("verification"))) {
167 node.verification = MnaVerification::fromJson(json[QLatin1String("verification")].toObject());
168 }
169
170 // Metadata
171 node.toolVersion = json[QLatin1String("tool_version")].toString();
172 QString execStr = json[QLatin1String("executed_at")].toString();
173 if (!execStr.isEmpty())
174 node.executedAt = QDateTime::fromString(execStr, Qt::ISODate);
175 node.dirty = json[QLatin1String("dirty")].toBool(true);
176
177 static const QSet<QString> knownKeys = {
178 QStringLiteral("id"), QStringLiteral("op_type"),
179 QStringLiteral("exec_mode"), QStringLiteral("attributes"),
180 QStringLiteral("inputs"), QStringLiteral("outputs"),
181 QStringLiteral("ipc_command"), QStringLiteral("ipc_args"),
182 QStringLiteral("ipc_work_dir"), QStringLiteral("ipc_transport"),
183 QStringLiteral("script"), QStringLiteral("verification"),
184 QStringLiteral("tool_version"), QStringLiteral("executed_at"),
185 QStringLiteral("dirty")
186 };
187 for (auto it = json.constBegin(); it != json.constEnd(); ++it) {
188 if (!knownKeys.contains(it.key()))
189 node.extras.insert(it.key(), it.value());
190 }
191
192 return node;
193}
194
195//=============================================================================================================
196
197QCborMap MnaNode::toCbor() const
198{
199 QCborMap cbor = QCborMap::fromJsonObject(extras);
200 cbor[QLatin1String("id")] = id;
201 cbor[QLatin1String("op_type")] = opType;
202 cbor[QLatin1String("exec_mode")] = execModeToString(execMode);
203
204 cbor[QLatin1String("attributes")] = QCborMap::fromJsonObject(QJsonObject::fromVariantMap(attributes));
205
206 QCborArray inputArr;
207 for (const MnaPort& p : inputs)
208 inputArr.append(p.toCbor());
209 cbor[QLatin1String("inputs")] = inputArr;
210
211 QCborArray outputArr;
212 for (const MnaPort& p : outputs)
213 outputArr.append(p.toCbor());
214 cbor[QLatin1String("outputs")] = outputArr;
215
217 cbor[QLatin1String("ipc_command")] = ipcCommand;
218 QCborArray argsArr;
219 for (const QString& arg : ipcArgs)
220 argsArr.append(arg);
221 cbor[QLatin1String("ipc_args")] = argsArr;
222 cbor[QLatin1String("ipc_work_dir")] = ipcWorkDir;
223 cbor[QLatin1String("ipc_transport")] = ipcTransport;
224 }
225
227 cbor[QLatin1String("script")] = script.toCbor();
228 }
229
230 QCborMap verCbor = verification.toCbor();
231 if (!verCbor.isEmpty()) {
232 cbor[QLatin1String("verification")] = verCbor;
233 }
234
235 if (!toolVersion.isEmpty())
236 cbor[QLatin1String("tool_version")] = toolVersion;
237 if (executedAt.isValid())
238 cbor[QLatin1String("executed_at")] = executedAt.toString(Qt::ISODate);
239 cbor[QLatin1String("dirty")] = dirty;
240
241 return cbor;
242}
243
244//=============================================================================================================
245
246MnaNode MnaNode::fromCbor(const QCborMap& cbor)
247{
248 MnaNode node;
249 node.id = cbor[QLatin1String("id")].toString();
250 node.opType = cbor[QLatin1String("op_type")].toString();
251 node.execMode = execModeFromString(cbor[QLatin1String("exec_mode")].toString());
252
253 QCborMap attrCbor = cbor[QLatin1String("attributes")].toMap();
254 node.attributes = attrCbor.toJsonObject().toVariantMap();
255
256 QCborArray inputArr = cbor[QLatin1String("inputs")].toArray();
257 for (const QCborValue& v : inputArr)
258 node.inputs.append(MnaPort::fromCbor(v.toMap()));
259
260 QCborArray outputArr = cbor[QLatin1String("outputs")].toArray();
261 for (const QCborValue& v : outputArr)
262 node.outputs.append(MnaPort::fromCbor(v.toMap()));
263
264 node.ipcCommand = cbor[QLatin1String("ipc_command")].toString();
265 QCborArray argsArr = cbor[QLatin1String("ipc_args")].toArray();
266 for (const QCborValue& v : argsArr)
267 node.ipcArgs.append(v.toString());
268 node.ipcWorkDir = cbor[QLatin1String("ipc_work_dir")].toString();
269 node.ipcTransport = cbor[QLatin1String("ipc_transport")].toString();
270
271 if (cbor.contains(QLatin1String("script"))) {
272 node.script = MnaScript::fromCbor(cbor[QLatin1String("script")].toMap());
273 }
274 if (cbor.contains(QLatin1String("verification"))) {
275 node.verification = MnaVerification::fromCbor(cbor[QLatin1String("verification")].toMap());
276 }
277
278 node.toolVersion = cbor[QLatin1String("tool_version")].toString();
279 QString execStr = cbor[QLatin1String("executed_at")].toString();
280 if (!execStr.isEmpty())
281 node.executedAt = QDateTime::fromString(execStr, Qt::ISODate);
282 node.dirty = cbor[QLatin1String("dirty")].toBool(true);
283
284 static const QSet<QString> knownKeys = {
285 QStringLiteral("id"), QStringLiteral("op_type"),
286 QStringLiteral("exec_mode"), QStringLiteral("attributes"),
287 QStringLiteral("inputs"), QStringLiteral("outputs"),
288 QStringLiteral("ipc_command"), QStringLiteral("ipc_args"),
289 QStringLiteral("ipc_work_dir"), QStringLiteral("ipc_transport"),
290 QStringLiteral("script"), QStringLiteral("verification"),
291 QStringLiteral("tool_version"), QStringLiteral("executed_at"),
292 QStringLiteral("dirty")
293 };
294 QJsonObject cborJson = cbor.toJsonObject();
295 for (auto it = cborJson.constBegin(); it != cborJson.constEnd(); ++it) {
296 if (!knownKeys.contains(it.key()))
297 node.extras.insert(it.key(), it.value());
298 }
299
300 return node;
301}
MnaNode struct declaration — one operation in the computational graph.
MNE Analysis Container Format (mna/mnx).
MnaNodeExecMode
Definition mna_types.h:123
@ Batch
Runs once on static file-based inputs (default).
Definition mna_types.h:124
@ Ipc
Delegates to an external process via inter-process communication.
Definition mna_types.h:126
@ Stream
Runs continuously on real-time data (MNE Scan mode).
Definition mna_types.h:125
@ Script
Inline code executed via interpreter (Python, shell, R, …).
Definition mna_types.h:127
Graph node representing a processing step.
Definition mna_node.h:75
MnaNodeExecMode execMode
Execution mode.
Definition mna_node.h:83
QString toolVersion
Version of tool that last executed this node.
Definition mna_node.h:98
QString ipcCommand
External executable command.
Definition mna_node.h:86
QStringList ipcArgs
Command-line arguments (supports {{placeholder}} tokens).
Definition mna_node.h:87
bool dirty
Whether node needs re-execution.
Definition mna_node.h:100
MnaScript script
Inline source code, interpreter, language.
Definition mna_node.h:92
QList< MnaPort > inputs
Input ports.
Definition mna_node.h:80
QCborMap toCbor() const
Definition mna_node.cpp:197
QVariantMap attributes
Operation parameters.
Definition mna_node.h:78
QDateTime executedAt
Timestamp of last execution.
Definition mna_node.h:99
static MnaNode fromJson(const QJsonObject &json)
Definition mna_node.cpp:134
QString opType
Operation type (looked up in MnaOpRegistry).
Definition mna_node.h:77
MnaVerification verification
Explanation, checks, results, and provenance snapshot.
Definition mna_node.h:95
QString ipcWorkDir
Working directory for external process.
Definition mna_node.h:88
QString ipcTransport
"stdio", "tcp", "shm", "file"
Definition mna_node.h:89
static MnaNode fromCbor(const QCborMap &cbor)
Definition mna_node.cpp:246
QList< MnaPort > outputs
Output ports.
Definition mna_node.h:81
QJsonObject toJson() const
Definition mna_node.cpp:79
QString id
Unique node identifier.
Definition mna_node.h:76
QJsonObject extras
Unknown keys preserved for lossless round-trip.
Definition mna_node.h:101
Graph port descriptor.
Definition mna_port.h:68
static MnaPort fromJson(const QJsonObject &json)
Definition mna_port.cpp:145
static MnaPort fromCbor(const QCborMap &cbor)
Definition mna_port.cpp:202
static MnaScript fromJson(const QJsonObject &json)
static MnaScript fromCbor(const QCborMap &cbor)
static MnaVerification fromJson(const QJsonObject &json)
static MnaVerification fromCbor(const QCborMap &cbor)