48 return QStringLiteral(
"batch");
50 return QStringLiteral(
"stream");
52 return QStringLiteral(
"ipc");
54 return QStringLiteral(
"script");
56 return QStringLiteral(
"batch");
63 if (str == QLatin1String(
"stream"))
65 if (str == QLatin1String(
"ipc"))
67 if (str == QLatin1String(
"script"))
79 json[QLatin1String(
"id")] =
id;
80 json[QLatin1String(
"op_type")] =
opType;
81 json[QLatin1String(
"exec_mode")] = execModeToString(
execMode);
84 json[QLatin1String(
"attributes")] = QJsonObject::fromVariantMap(
attributes);
89 inputArr.append(p.toJson());
90 json[QLatin1String(
"inputs")] = inputArr;
94 outputArr.append(p.toJson());
95 json[QLatin1String(
"outputs")] = outputArr;
99 json[QLatin1String(
"ipc_command")] =
ipcCommand;
101 for (
const QString& arg :
ipcArgs)
103 json[QLatin1String(
"ipc_args")] = argsArr;
104 json[QLatin1String(
"ipc_work_dir")] =
ipcWorkDir;
110 json[QLatin1String(
"script")] =
script.toJson();
115 if (!verObj.isEmpty()) {
116 json[QLatin1String(
"verification")] = verObj;
123 json[QLatin1String(
"executed_at")] =
executedAt.toString(Qt::ISODate);
124 json[QLatin1String(
"dirty")] =
dirty;
134 node.
id = json[QLatin1String(
"id")].toString();
135 node.
opType = json[QLatin1String(
"op_type")].toString();
136 node.
execMode = execModeFromString(json[QLatin1String(
"exec_mode")].toString());
138 node.
attributes = json[QLatin1String(
"attributes")].toObject().toVariantMap();
141 QJsonArray inputArr = json[QLatin1String(
"inputs")].toArray();
142 for (
const QJsonValue& v : inputArr)
145 QJsonArray outputArr = json[QLatin1String(
"outputs")].toArray();
146 for (
const QJsonValue& v : outputArr)
150 node.
ipcCommand = json[QLatin1String(
"ipc_command")].toString();
151 QJsonArray argsArr = json[QLatin1String(
"ipc_args")].toArray();
152 for (
const QJsonValue& v : argsArr)
153 node.
ipcArgs.append(v.toString());
154 node.
ipcWorkDir = json[QLatin1String(
"ipc_work_dir")].toString();
155 node.
ipcTransport = json[QLatin1String(
"ipc_transport")].toString();
158 if (json.contains(QLatin1String(
"script"))) {
163 if (json.contains(QLatin1String(
"verification"))) {
168 node.
toolVersion = json[QLatin1String(
"tool_version")].toString();
169 QString execStr = json[QLatin1String(
"executed_at")].toString();
170 if (!execStr.isEmpty())
171 node.
executedAt = QDateTime::fromString(execStr, Qt::ISODate);
172 node.
dirty = json[QLatin1String(
"dirty")].toBool(
true);
174 static const QSet<QString> knownKeys = {
175 QStringLiteral(
"id"), QStringLiteral(
"op_type"),
176 QStringLiteral(
"exec_mode"), QStringLiteral(
"attributes"),
177 QStringLiteral(
"inputs"), QStringLiteral(
"outputs"),
178 QStringLiteral(
"ipc_command"), QStringLiteral(
"ipc_args"),
179 QStringLiteral(
"ipc_work_dir"), QStringLiteral(
"ipc_transport"),
180 QStringLiteral(
"script"), QStringLiteral(
"verification"),
181 QStringLiteral(
"tool_version"), QStringLiteral(
"executed_at"),
182 QStringLiteral(
"dirty")};
183 for (
auto it = json.constBegin(); it != json.constEnd(); ++it) {
184 if (!knownKeys.contains(it.key()))
185 node.
extras.insert(it.key(), it.value());
195 QCborMap cbor = QCborMap::fromJsonObject(
extras);
196 cbor[QLatin1String(
"id")] =
id;
197 cbor[QLatin1String(
"op_type")] =
opType;
198 cbor[QLatin1String(
"exec_mode")] = execModeToString(
execMode);
200 cbor[QLatin1String(
"attributes")] = QCborMap::fromJsonObject(QJsonObject::fromVariantMap(
attributes));
204 inputArr.append(p.toCbor());
205 cbor[QLatin1String(
"inputs")] = inputArr;
207 QCborArray outputArr;
209 outputArr.append(p.toCbor());
210 cbor[QLatin1String(
"outputs")] = outputArr;
213 cbor[QLatin1String(
"ipc_command")] =
ipcCommand;
215 for (
const QString& arg :
ipcArgs)
217 cbor[QLatin1String(
"ipc_args")] = argsArr;
218 cbor[QLatin1String(
"ipc_work_dir")] =
ipcWorkDir;
223 cbor[QLatin1String(
"script")] =
script.toCbor();
227 if (!verCbor.isEmpty()) {
228 cbor[QLatin1String(
"verification")] = verCbor;
234 cbor[QLatin1String(
"executed_at")] =
executedAt.toString(Qt::ISODate);
235 cbor[QLatin1String(
"dirty")] =
dirty;
245 node.
id = cbor[QLatin1String(
"id")].toString();
246 node.
opType = cbor[QLatin1String(
"op_type")].toString();
247 node.
execMode = execModeFromString(cbor[QLatin1String(
"exec_mode")].toString());
249 QCborMap attrCbor = cbor[QLatin1String(
"attributes")].toMap();
250 node.
attributes = attrCbor.toJsonObject().toVariantMap();
252 QCborArray inputArr = cbor[QLatin1String(
"inputs")].toArray();
253 for (
const QCborValue& v : inputArr)
256 QCborArray outputArr = cbor[QLatin1String(
"outputs")].toArray();
257 for (
const QCborValue& v : outputArr)
260 node.
ipcCommand = cbor[QLatin1String(
"ipc_command")].toString();
261 QCborArray argsArr = cbor[QLatin1String(
"ipc_args")].toArray();
262 for (
const QCborValue& v : argsArr)
263 node.
ipcArgs.append(v.toString());
264 node.
ipcWorkDir = cbor[QLatin1String(
"ipc_work_dir")].toString();
265 node.
ipcTransport = cbor[QLatin1String(
"ipc_transport")].toString();
267 if (cbor.contains(QLatin1String(
"script"))) {
270 if (cbor.contains(QLatin1String(
"verification"))) {
274 node.
toolVersion = cbor[QLatin1String(
"tool_version")].toString();
275 QString execStr = cbor[QLatin1String(
"executed_at")].toString();
276 if (!execStr.isEmpty())
277 node.
executedAt = QDateTime::fromString(execStr, Qt::ISODate);
278 node.
dirty = cbor[QLatin1String(
"dirty")].toBool(
true);
280 static const QSet<QString> knownKeys = {
281 QStringLiteral(
"id"), QStringLiteral(
"op_type"),
282 QStringLiteral(
"exec_mode"), QStringLiteral(
"attributes"),
283 QStringLiteral(
"inputs"), QStringLiteral(
"outputs"),
284 QStringLiteral(
"ipc_command"), QStringLiteral(
"ipc_args"),
285 QStringLiteral(
"ipc_work_dir"), QStringLiteral(
"ipc_transport"),
286 QStringLiteral(
"script"), QStringLiteral(
"verification"),
287 QStringLiteral(
"tool_version"), QStringLiteral(
"executed_at"),
288 QStringLiteral(
"dirty")};
289 QJsonObject cborJson = cbor.toJsonObject();
290 for (
auto it = cborJson.constBegin(); it != cborJson.constEnd(); ++it) {
291 if (!knownKeys.contains(it.key()))
292 node.
extras.insert(it.key(), it.value());
One operation in an MNA graph — opType, typed I/O ports, attributes, execution mode (Batch / Stream /...
MNE Analysis Container Format (mna/mnx).
@ Batch
Runs once on static file-based inputs (default).
@ Ipc
Delegates to an external process via inter-process communication.
@ Stream
Runs continuously on real-time data (MNE Scan mode).
@ Script
Inline code executed via interpreter (Python, shell, R, …).
Single executable step in an MNA pipeline graph, with attributes, typed ports, exec mode,...
MnaNodeExecMode execMode
Execution mode.
QString toolVersion
Version of tool that last executed this node.
QString ipcCommand
External executable command.
QStringList ipcArgs
Command-line arguments (supports {{placeholder}} tokens).
bool dirty
Whether node needs re-execution.
MnaScript script
Inline source code, interpreter, language.
QList< MnaPort > inputs
Input ports.
QVariantMap attributes
Operation parameters.
QDateTime executedAt
Timestamp of last execution.
static MnaNode fromJson(const QJsonObject &json)
QString opType
Operation type (looked up in MnaOpRegistry).
MnaVerification verification
Explanation, checks, results, and provenance snapshot.
QString ipcWorkDir
Working directory for external process.
QString ipcTransport
"stdio", "tcp", "shm", "file"
static MnaNode fromCbor(const QCborMap &cbor)
QList< MnaPort > outputs
Output ports.
QJsonObject toJson() const
QString id
Unique node identifier.
QJsonObject extras
Unknown keys preserved for lossless round-trip.
Named, typed port on an MNA graph node with upstream link and optional real-time stream binding.
static MnaPort fromJson(const QJsonObject &json)
static MnaPort fromCbor(const QCborMap &cbor)
static MnaScript fromJson(const QJsonObject &json)
static MnaScript fromCbor(const QCborMap &cbor)
static MnaVerification fromJson(const QJsonObject &json)
static MnaVerification fromCbor(const QCborMap &cbor)