52 return QStringLiteral(
"batch");
72 json[QLatin1String(
"id")] =
id;
73 json[QLatin1String(
"op_type")] =
opType;
74 json[QLatin1String(
"exec_mode")] = execModeToString(
execMode);
77 json[QLatin1String(
"attributes")] = QJsonObject::fromVariantMap(
attributes);
82 inputArr.append(p.toJson());
83 json[QLatin1String(
"inputs")] = inputArr;
87 outputArr.append(p.toJson());
88 json[QLatin1String(
"outputs")] = outputArr;
92 json[QLatin1String(
"ipc_command")] =
ipcCommand;
94 for (
const QString& arg :
ipcArgs)
96 json[QLatin1String(
"ipc_args")] = argsArr;
97 json[QLatin1String(
"ipc_work_dir")] =
ipcWorkDir;
103 json[QLatin1String(
"script")] =
script.toJson();
108 if (!verObj.isEmpty()) {
109 json[QLatin1String(
"verification")] = verObj;
116 json[QLatin1String(
"executed_at")] =
executedAt.toString(Qt::ISODate);
117 json[QLatin1String(
"dirty")] =
dirty;
127 node.
id = json[QLatin1String(
"id")].toString();
128 node.
opType = json[QLatin1String(
"op_type")].toString();
129 node.
execMode = execModeFromString(json[QLatin1String(
"exec_mode")].toString());
131 node.
attributes = json[QLatin1String(
"attributes")].toObject().toVariantMap();
134 QJsonArray inputArr = json[QLatin1String(
"inputs")].toArray();
135 for (
const QJsonValue& v : inputArr)
138 QJsonArray outputArr = json[QLatin1String(
"outputs")].toArray();
139 for (
const QJsonValue& v : outputArr)
143 node.
ipcCommand = json[QLatin1String(
"ipc_command")].toString();
144 QJsonArray argsArr = json[QLatin1String(
"ipc_args")].toArray();
145 for (
const QJsonValue& v : argsArr)
146 node.
ipcArgs.append(v.toString());
147 node.
ipcWorkDir = json[QLatin1String(
"ipc_work_dir")].toString();
148 node.
ipcTransport = json[QLatin1String(
"ipc_transport")].toString();
151 if (json.contains(QLatin1String(
"script"))) {
156 if (json.contains(QLatin1String(
"verification"))) {
161 node.
toolVersion = json[QLatin1String(
"tool_version")].toString();
162 QString execStr = json[QLatin1String(
"executed_at")].toString();
163 if (!execStr.isEmpty())
164 node.
executedAt = QDateTime::fromString(execStr, Qt::ISODate);
165 node.
dirty = json[QLatin1String(
"dirty")].toBool(
true);
167 static const QSet<QString> knownKeys = {
168 QStringLiteral(
"id"), QStringLiteral(
"op_type"),
169 QStringLiteral(
"exec_mode"), QStringLiteral(
"attributes"),
170 QStringLiteral(
"inputs"), QStringLiteral(
"outputs"),
171 QStringLiteral(
"ipc_command"), QStringLiteral(
"ipc_args"),
172 QStringLiteral(
"ipc_work_dir"), QStringLiteral(
"ipc_transport"),
173 QStringLiteral(
"script"), QStringLiteral(
"verification"),
174 QStringLiteral(
"tool_version"), QStringLiteral(
"executed_at"),
175 QStringLiteral(
"dirty")
177 for (
auto it = json.constBegin(); it != json.constEnd(); ++it) {
178 if (!knownKeys.contains(it.key()))
179 node.
extras.insert(it.key(), it.value());
189 QCborMap cbor = QCborMap::fromJsonObject(
extras);
190 cbor[QLatin1String(
"id")] =
id;
191 cbor[QLatin1String(
"op_type")] =
opType;
192 cbor[QLatin1String(
"exec_mode")] = execModeToString(
execMode);
194 cbor[QLatin1String(
"attributes")] = QCborMap::fromJsonObject(QJsonObject::fromVariantMap(
attributes));
198 inputArr.append(p.toCbor());
199 cbor[QLatin1String(
"inputs")] = inputArr;
201 QCborArray outputArr;
203 outputArr.append(p.toCbor());
204 cbor[QLatin1String(
"outputs")] = outputArr;
207 cbor[QLatin1String(
"ipc_command")] =
ipcCommand;
209 for (
const QString& arg :
ipcArgs)
211 cbor[QLatin1String(
"ipc_args")] = argsArr;
212 cbor[QLatin1String(
"ipc_work_dir")] =
ipcWorkDir;
217 cbor[QLatin1String(
"script")] =
script.toCbor();
221 if (!verCbor.isEmpty()) {
222 cbor[QLatin1String(
"verification")] = verCbor;
228 cbor[QLatin1String(
"executed_at")] =
executedAt.toString(Qt::ISODate);
229 cbor[QLatin1String(
"dirty")] =
dirty;
239 node.
id = cbor[QLatin1String(
"id")].toString();
240 node.
opType = cbor[QLatin1String(
"op_type")].toString();
241 node.
execMode = execModeFromString(cbor[QLatin1String(
"exec_mode")].toString());
243 QCborMap attrCbor = cbor[QLatin1String(
"attributes")].toMap();
244 node.
attributes = attrCbor.toJsonObject().toVariantMap();
246 QCborArray inputArr = cbor[QLatin1String(
"inputs")].toArray();
247 for (
const QCborValue& v : inputArr)
250 QCborArray outputArr = cbor[QLatin1String(
"outputs")].toArray();
251 for (
const QCborValue& v : outputArr)
254 node.
ipcCommand = cbor[QLatin1String(
"ipc_command")].toString();
255 QCborArray argsArr = cbor[QLatin1String(
"ipc_args")].toArray();
256 for (
const QCborValue& v : argsArr)
257 node.
ipcArgs.append(v.toString());
258 node.
ipcWorkDir = cbor[QLatin1String(
"ipc_work_dir")].toString();
259 node.
ipcTransport = cbor[QLatin1String(
"ipc_transport")].toString();
261 if (cbor.contains(QLatin1String(
"script"))) {
264 if (cbor.contains(QLatin1String(
"verification"))) {
268 node.
toolVersion = cbor[QLatin1String(
"tool_version")].toString();
269 QString execStr = cbor[QLatin1String(
"executed_at")].toString();
270 if (!execStr.isEmpty())
271 node.
executedAt = QDateTime::fromString(execStr, Qt::ISODate);
272 node.
dirty = cbor[QLatin1String(
"dirty")].toBool(
true);
274 static const QSet<QString> knownKeys = {
275 QStringLiteral(
"id"), QStringLiteral(
"op_type"),
276 QStringLiteral(
"exec_mode"), QStringLiteral(
"attributes"),
277 QStringLiteral(
"inputs"), QStringLiteral(
"outputs"),
278 QStringLiteral(
"ipc_command"), QStringLiteral(
"ipc_args"),
279 QStringLiteral(
"ipc_work_dir"), QStringLiteral(
"ipc_transport"),
280 QStringLiteral(
"script"), QStringLiteral(
"verification"),
281 QStringLiteral(
"tool_version"), QStringLiteral(
"executed_at"),
282 QStringLiteral(
"dirty")
284 QJsonObject cborJson = cbor.toJsonObject();
285 for (
auto it = cborJson.constBegin(); it != cborJson.constEnd(); ++it) {
286 if (!knownKeys.contains(it.key()))
287 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)