45 json[QStringLiteral(
"id")] =
id;
47 json[QStringLiteral(
"phase")] =
phase;
48 json[QStringLiteral(
"expression")] =
expression;
49 if (!
script.code.isEmpty()) {
50 json[QStringLiteral(
"script")] =
script.toJson();
52 json[QStringLiteral(
"severity")] =
severity;
54 json[QStringLiteral(
"on_fail")] =
onFail;
64 c.
id = json.value(QStringLiteral(
"id")).toString();
65 c.
description = json.value(QStringLiteral(
"description")).toString();
66 c.
phase = json.value(QStringLiteral(
"phase")).toString();
67 c.
expression = json.value(QStringLiteral(
"expression")).toString();
68 if (json.contains(QStringLiteral(
"script"))) {
71 c.
severity = json.value(QStringLiteral(
"severity")).toString();
72 c.
onFail = json.value(QStringLiteral(
"on_fail")).toString();
81 cbor.insert(QStringLiteral(
"id"),
id);
82 cbor.insert(QStringLiteral(
"description"),
description);
83 cbor.insert(QStringLiteral(
"phase"),
phase);
84 cbor.insert(QStringLiteral(
"expression"),
expression);
85 if (!
script.code.isEmpty()) {
86 cbor.insert(QStringLiteral(
"script"),
script.toCbor());
88 cbor.insert(QStringLiteral(
"severity"),
severity);
90 cbor.insert(QStringLiteral(
"on_fail"),
onFail);
100 c.
id = cbor.value(QStringLiteral(
"id")).toString();
101 c.
description = cbor.value(QStringLiteral(
"description")).toString();
102 c.
phase = cbor.value(QStringLiteral(
"phase")).toString();
103 c.
expression = cbor.value(QStringLiteral(
"expression")).toString();
104 if (cbor.contains(QStringLiteral(
"script"))) {
107 c.
severity = cbor.value(QStringLiteral(
"severity")).toString();
108 c.
onFail = cbor.value(QStringLiteral(
"on_fail")).toString();
119 json[QStringLiteral(
"check_id")] =
checkId;
120 json[QStringLiteral(
"passed")] =
passed;
121 json[QStringLiteral(
"severity")] =
severity;
122 json[QStringLiteral(
"message")] =
message;
123 json[QStringLiteral(
"actual_value")] = QJsonValue::fromVariant(
actualValue);
125 json[QStringLiteral(
"evaluated_at")] =
evaluatedAt.toString(Qt::ISODateWithMs);
135 r.
checkId = json.value(QStringLiteral(
"check_id")).toString();
136 r.
passed = json.value(QStringLiteral(
"passed")).toBool(
false);
137 r.
severity = json.value(QStringLiteral(
"severity")).toString();
138 r.
message = json.value(QStringLiteral(
"message")).toString();
139 r.
actualValue = json.value(QStringLiteral(
"actual_value")).toVariant();
140 r.
evaluatedAt = QDateTime::fromString(json.value(QStringLiteral(
"evaluated_at")).toString(), Qt::ISODateWithMs);
149 cbor.insert(QStringLiteral(
"check_id"),
checkId);
150 cbor.insert(QStringLiteral(
"passed"),
passed);
151 cbor.insert(QStringLiteral(
"severity"),
severity);
152 cbor.insert(QStringLiteral(
"message"),
message);
153 cbor.insert(QStringLiteral(
"actual_value"), QCborValue::fromVariant(
actualValue));
155 cbor.insert(QStringLiteral(
"evaluated_at"),
evaluatedAt.toString(Qt::ISODateWithMs));
165 r.
checkId = cbor.value(QStringLiteral(
"check_id")).toString();
166 r.
passed = cbor.value(QStringLiteral(
"passed")).toBool();
167 r.
severity = cbor.value(QStringLiteral(
"severity")).toString();
168 r.
message = cbor.value(QStringLiteral(
"message")).toString();
169 r.
actualValue = cbor.value(QStringLiteral(
"actual_value")).toVariant();
170 r.
evaluatedAt = QDateTime::fromString(cbor.value(QStringLiteral(
"evaluated_at")).toString(), Qt::ISODateWithMs);
185 hashObj.insert(it.key(), it.value());
187 json[QStringLiteral(
"input_hashes")] = hashObj;
193 attrObj.insert(it.key(), QJsonValue::fromVariant(it.value()));
195 json[QStringLiteral(
"resolved_attributes")] = attrObj;
201 json[QStringLiteral(
"qt_version")] =
qtVersion;
205 json[QStringLiteral(
"os_info")] =
osInfo;
207 json[QStringLiteral(
"host_name")] =
hostName;
212 json[QStringLiteral(
"started_at")] =
startedAt.toString(Qt::ISODateWithMs);
214 json[QStringLiteral(
"finished_at")] =
finishedAt.toString(Qt::ISODateWithMs);
216 json[QStringLiteral(
"wall_time_ms")] =
wallTimeMs;
220 json[QStringLiteral(
"random_seed")] =
randomSeed;
231 const QJsonObject hashObj = json.value(QStringLiteral(
"input_hashes")).toObject();
232 for (
auto it = hashObj.constBegin(); it != hashObj.constEnd(); ++it) {
233 p.
inputHashes.insert(it.key(), it.value().toString());
236 const QJsonObject attrObj = json.value(QStringLiteral(
"resolved_attributes")).toObject();
237 for (
auto it = attrObj.constBegin(); it != attrObj.constEnd(); ++it) {
241 p.
mneCppVersion = json.value(QStringLiteral(
"mne_cpp_version")).toString();
242 p.
qtVersion = json.value(QStringLiteral(
"qt_version")).toString();
243 p.
compilerInfo = json.value(QStringLiteral(
"compiler_info")).toString();
244 p.
osInfo = json.value(QStringLiteral(
"os_info")).toString();
245 p.
hostName = json.value(QStringLiteral(
"host_name")).toString();
248 p.
startedAt = QDateTime::fromString(json.value(QStringLiteral(
"started_at")).toString(), Qt::ISODateWithMs);
249 p.
finishedAt = QDateTime::fromString(json.value(QStringLiteral(
"finished_at")).toString(), Qt::ISODateWithMs);
250 p.
wallTimeMs =
static_cast<qint64
>(json.value(QStringLiteral(
"wall_time_ms")).toDouble(0));
251 p.
peakMemoryBytes =
static_cast<qint64
>(json.value(QStringLiteral(
"peak_memory_bytes")).toDouble(0));
252 p.
randomSeed =
static_cast<qint64
>(json.value(QStringLiteral(
"random_seed")).toDouble(-1));
266 hashMap.insert(it.key(), it.value());
268 cbor.insert(QStringLiteral(
"input_hashes"), hashMap);
274 attrMap.insert(it.key(), QCborValue::fromVariant(it.value()));
276 cbor.insert(QStringLiteral(
"resolved_attributes"), attrMap);
280 cbor.insert(QStringLiteral(
"mne_cpp_version"),
mneCppVersion);
282 cbor.insert(QStringLiteral(
"qt_version"),
qtVersion);
284 cbor.insert(QStringLiteral(
"compiler_info"),
compilerInfo);
286 cbor.insert(QStringLiteral(
"os_info"),
osInfo);
288 cbor.insert(QStringLiteral(
"host_name"),
hostName);
293 cbor.insert(QStringLiteral(
"started_at"),
startedAt.toString(Qt::ISODateWithMs));
295 cbor.insert(QStringLiteral(
"finished_at"),
finishedAt.toString(Qt::ISODateWithMs));
297 cbor.insert(QStringLiteral(
"wall_time_ms"),
wallTimeMs);
301 cbor.insert(QStringLiteral(
"random_seed"),
randomSeed);
312 const QCborMap hashMap = cbor.value(QStringLiteral(
"input_hashes")).toMap();
313 for (
auto it = hashMap.constBegin(); it != hashMap.constEnd(); ++it) {
314 p.
inputHashes.insert(it.key().toString(), it.value().toString());
317 const QCborMap attrMap = cbor.value(QStringLiteral(
"resolved_attributes")).toMap();
318 for (
auto it = attrMap.constBegin(); it != attrMap.constEnd(); ++it) {
322 p.
mneCppVersion = cbor.value(QStringLiteral(
"mne_cpp_version")).toString();
323 p.
qtVersion = cbor.value(QStringLiteral(
"qt_version")).toString();
324 p.
compilerInfo = cbor.value(QStringLiteral(
"compiler_info")).toString();
325 p.
osInfo = cbor.value(QStringLiteral(
"os_info")).toString();
326 p.
hostName = cbor.value(QStringLiteral(
"host_name")).toString();
329 p.
startedAt = QDateTime::fromString(cbor.value(QStringLiteral(
"started_at")).toString(), Qt::ISODateWithMs);
330 p.
finishedAt = QDateTime::fromString(cbor.value(QStringLiteral(
"finished_at")).toString(), Qt::ISODateWithMs);
331 p.
wallTimeMs = cbor.value(QStringLiteral(
"wall_time_ms")).toInteger(0);
332 p.
peakMemoryBytes = cbor.value(QStringLiteral(
"peak_memory_bytes")).toInteger(0);
333 p.
randomSeed = cbor.value(QStringLiteral(
"random_seed")).toInteger(-1);
353 arr.append(c.toJson());
355 json[QStringLiteral(
"checks")] = arr;
361 arr.append(r.toJson());
363 json[QStringLiteral(
"pre_results")] = arr;
369 arr.append(r.toJson());
371 json[QStringLiteral(
"post_results")] = arr;
375 if (!provObj.isEmpty()) {
376 json[QStringLiteral(
"provenance")] = provObj;
388 v.
explanation = json.value(QStringLiteral(
"explanation")).toString();
390 const QJsonArray checksArr = json.value(QStringLiteral(
"checks")).toArray();
391 for (
const QJsonValue& val : checksArr) {
395 const QJsonArray preArr = json.value(QStringLiteral(
"pre_results")).toArray();
396 for (
const QJsonValue& val : preArr) {
400 const QJsonArray postArr = json.value(QStringLiteral(
"post_results")).toArray();
401 for (
const QJsonValue& val : postArr) {
405 if (json.contains(QStringLiteral(
"provenance"))) {
419 cbor.insert(QStringLiteral(
"explanation"),
explanation);
425 arr.append(c.toCbor());
427 cbor.insert(QStringLiteral(
"checks"), arr);
433 arr.append(r.toCbor());
435 cbor.insert(QStringLiteral(
"pre_results"), arr);
441 arr.append(r.toCbor());
443 cbor.insert(QStringLiteral(
"post_results"), arr);
447 if (!provMap.isEmpty()) {
448 cbor.insert(QStringLiteral(
"provenance"), provMap);
460 v.
explanation = cbor.value(QStringLiteral(
"explanation")).toString();
462 const QCborArray checksArr = cbor.value(QStringLiteral(
"checks")).toArray();
463 for (
const QCborValue& val : checksArr) {
467 const QCborArray preArr = cbor.value(QStringLiteral(
"pre_results")).toArray();
468 for (
const QCborValue& val : preArr) {
472 const QCborArray postArr = cbor.value(QStringLiteral(
"post_results")).toArray();
473 for (
const QCborValue& val : postArr) {
477 if (cbor.contains(QStringLiteral(
"provenance"))) {
Verification, declarative checks, evaluation results and provenance snapshot attached to every MNALIB...
MNE Analysis Container Format (mna/mnx).
static MnaScript fromJson(const QJsonObject &json)
static MnaScript fromCbor(const QCborMap &cbor)
Verification check for a graph node.
QString severity
"error" (abort), "warning" (log + continue), "info" (always continue)
QString expression
MnaParamTree expression over attributes, inputs and (post) outputs: "rank > 0".
QString phase
"pre" (before execution) or "post" (after execution)
QString description
Human-readable: "Covariance matrix must be positive-definite".
static MnaVerificationCheck fromCbor(const QCborMap &cbor)
QString onFail
Optional remediation hint.
static MnaVerificationCheck fromJson(const QJsonObject &json)
QString id
Unique check identifier within the node (e.g. "cov_posdef").
QJsonObject toJson() const
static MnaVerificationResult fromCbor(const QCborMap &cbor)
QString message
Formatted message: "PASS: ..." or "FAIL [error]: ...".
QString checkId
References MnaVerificationCheck::id.
QVariant actualValue
The evaluated expression result.
QJsonObject toJson() const
QString severity
Echoed from the check definition.
QDateTime evaluatedAt
When this check was evaluated.
bool passed
true if the expression evaluated to true
static MnaVerificationResult fromJson(const QJsonObject &json)
Provenance record for reproducibility.
QJsonObject toJson() const
static MnaProvenance fromCbor(const QCborMap &cbor)
QString externalToolVersion
e.g. "FreeSurfer 7.4.1", "Python 3.11.5"
QString osInfo
e.g. "macOS 15.4 arm64"
qint64 peakMemoryBytes
Peak RSS (if measurable), 0 otherwise.
QString qtVersion
e.g. "6.11.0"
QString compilerInfo
e.g. "AppleClang 16.0.0"
qint64 wallTimeMs
Wall-clock duration in milliseconds.
QString hostName
Machine name (for cluster provenance).
QVariantMap resolvedAttributes
qint64 randomSeed
-1 if not applicable
QMap< QString, QString > inputHashes
portName → SHA-256
static MnaProvenance fromJson(const QJsonObject &json)
QString mneCppVersion
e.g. "2.2.0"
Verification, explanation, and provenance for a graph node.
MnaProvenance provenance
Complete provenance snapshot (populated by executor).
QString explanation
Human-readable explanation of what this node does and why.
static MnaVerification fromJson(const QJsonObject &json)
QList< MnaVerificationCheck > checks
Declarative checks (authored by user, evaluated by executor).
QJsonObject toJson() const
QList< MnaVerificationResult > preResults
Results of pre-execution checks (populated by executor).
QList< MnaVerificationResult > postResults
Results of post-execution checks (populated by executor).
static MnaVerification fromCbor(const QCborMap &cbor)