From 17d8041945dce971e87ba6a46e4eacd2580dc3bc Mon Sep 17 00:00:00 2001 From: "D. Berge" Date: Thu, 10 Sep 2020 23:36:13 +0200 Subject: [PATCH] Update standard QC definitions + parameters --- etc/qc/default/definitions.yaml | 167 +++++++++++++++++++++----------- etc/qc/default/parameters.yaml | 7 +- 2 files changed, 117 insertions(+), 57 deletions(-) diff --git a/etc/qc/default/definitions.yaml b/etc/qc/default/definitions.yaml index 318c982..e8501a3 100644 --- a/etc/qc/default/definitions.yaml +++ b/etc/qc/default/definitions.yaml @@ -1,61 +1,118 @@ # QC definition file -shot: - #- - #group: "Gun QC" - #children: - #- - #group: "Single gun / cluster" - #children: - #- - #group: "Source depth" - #check: | - #let _result_; - #_depth=10; - #const gunData = currentShot._("meta.smsrc.guns"); - #if (!gunData) { - #_result_ = "Missing gun data"; - #} else if (gunData.every(gun => Math.abs(gun[_depth]-parameters.gunDepth) <= parameters.gunDepthTolerance)) { - #_result_ = true; - #} else { - #const bad_guns = gunData.filter(gun => Math.abs(gun[_depth]-parameters.gunDepth) > parameters.gunDepthTolerance).map(gun => { - #return `source ${gun[2]}, string ${gun[0]}, gun ${gun[1]}, depth: ${gun[10]}`; - #}); - #_result_ = `Depth error: ${bad_guns.join("; ")}`; - #} - #_result_ - #- - #group: "Autofire" - #check: | - #let _result_; - #_autofire=5; - #const gunData = currentShot._("meta.smsrc.guns"); - #if (!gunData) { - #_result_ = "Missing gun data"; - #} else if (gunData.every(gun => gun[_autofire] == false)) { - #_result_ = true; - #} else { - #const bad_guns = gunData.filter(gun => gun[_autofire]).map(gun => { - #return `source ${gun[2]}, string ${gun[0]}, gun ${gun[1]}, depth: ${gun[10]}`; - #}); - #_result_ = `Depth error: ${bad_guns.join("; ")}`; - #} - #_result_ +- + name: "Missing shots" + iterate: "sequences" + labels: [ "QCFail" ] + check: | + const sequence = currentItem; + const sp0 = Math.min(sequence.fsp, sequence.lsp); + const sp1 = Math.max(sequence.fsp, sequence.lsp); + const missing = preplots.filter(r => r.line == sequence.line && + r.point >= sp0 && r.point <= sp1 && + !sequence.shots.find(s => s.point == r.point) + ); - - - group: "Centre of source preplot deviation" - children: - - - group: "Crossline" - check: | - Math.abs(currentShot.error_i) <= parameters.crosslineError - || `Crossline error: ${currentShot.error_i.toFixed(1)} > ${parameters.crosslineError}` + missing.length == 0 || missing.map(r => `Missing shot: ${r.point}`).join("\n") +- + name: "Gun QC" + disabled: false + labels: [ "QCFail", "QCGuns" ] + children: + - + name: "Missing gun data" + check: | + !!currentItem._("raw_meta.smsrc.guns") || "Missing gun data" + - + name: "Single gun / cluster" + children: + - + name: "Source depth" + check: | + const currentShot = currentItem; + let _result_; + _depth=10; + const gunData = currentShot._("raw_meta.smsrc.guns"); + if (!gunData) { + // We check for missing data elsewhere, so don't fail this test + _result_ = true + } else if (gunData.every(gun => Math.abs(gun[_depth]-parameters.gunDepth) <= parameters.gunDepthTolerance)) { + _result_ = true; + } else { + const bad_guns = gunData.filter(gun => Math.abs(gun[_depth]-parameters.gunDepth) > parameters.gunDepthTolerance).map(gun => { + return `source ${gun[2]}, string ${gun[0]}, gun ${gun[1]}, depth: ${gun[10]}`; + }); + _result_ = `Depth error: ${bad_guns.join("; ")}`; + } + _result_ + - + name: "Autofire" + check: | + const currentShot = currentItem; + let _result_; + _autofire=5; + const gunData = currentShot._("raw_meta.smsrc.guns"); + if (!gunData) { + // We check for missing data elsewhere, so don't fail this test + _result_ = true; + } else if (gunData.every(gun => gun[_autofire] == false)) { + _result_ = true; + } else { + const bad_guns = gunData.filter(gun => gun[_autofire]).map(gun => { + return `source ${gun[2]}, string ${gun[0]}, gun ${gun[1]}, depth: ${gun[10]}`; + }); + _result_ = `Depth error: ${bad_guns.join("; ")}`; + } + _result_ - - - group: "Inline" - check: | - Math.abs(currentShot.error_j) <= parameters.inlineError - || `Inline error: ${currentShot.error_j.toFixed(1)} > ${parameters.inlineError}` +- + name: "Centre of source preplot deviation (single shots)" + labels: [ "QCFail", "QCNav" ] + disabled: false + children: + - + name: "Crossline" + check: | + const currentShot = currentItem; + Math.abs(currentShot.error_i) <= parameters.crosslineError + || `Crossline error: ${currentShot.error_i.toFixed(1)} > ${parameters.crosslineError}` +- + name: "Centre of source preplot deviation (moving average)" + labels: [ "QCFail", "QCNav" ] + children: + - + name: "Crossline" + iterate: "sequences" + parameters: [ "crosslineErrorAverage" ] + check: | + const currentSequence = currentItem; + const i_err = currentSequence.shots.filter(s => s.error_i != null).map(a => a.error_i); + if (i_err.length) { + const avg = i_err.reduce( (a, b) => a+b)/i_err.length; + avg <= parameters.crosslineErrorAverage || + `Average crossline error: ${avg.toFixed(1)} > ${parameters.crosslineErrorAverage}` + } else { + `Sequence ${currentSequence.sequence} has no shots within preplot` + } -sequence: + - + name: "Inline" + iterate: "sequences" + parameters: [ "inlineErrorRunningAverageShots" ] + check: | + const currentSequence = currentItem; + const n = parameters.inlineErrorRunningAverageShots; // For brevity + const results = currentSequence.shots.slice(n/2, -n/2).map( (shot, index) => { + const shots = currentSequence.shots.slice(index, index+n).map(i => i.error_j).filter(i => i !== null); + if (!shots.length) { + // We are outside the preplot + // Nothing to see here, move along + return true; + } + const mean = shots.reduce( (a, b) => a+b ) / shots.length; + return Math.abs(mean) <= parameters.inlineErrorRunningAverageValue || + `Running average inline error: shot ${shot.point}, ${mean.toFixed(1)} > ${parameters.inlineErrorRunningAverageValue}` + }).filter(i => i !== true); + + results.length == 0 || results.join("\n"); diff --git a/etc/qc/default/parameters.yaml b/etc/qc/default/parameters.yaml index d6d9c5a..c161c33 100644 --- a/etc/qc/default/parameters.yaml +++ b/etc/qc/default/parameters.yaml @@ -1,5 +1,8 @@ gunDepth: 6.0 gunDepthTolerance: 0.5 -crosslineError: 9 -inlineError: 2 +crosslineError: 12 +crosslineErrorAverage: 9 +inlineErrorRunningAverageValue: 2 +inlineErrorRunningAverageShots: 40 +