Files
dougal-software/etc/qc
D. Berge df3a0b4c50 Be explicit about what type of data is being QC'ed.
The source deviation QCs now tell the user whether raw
or final data is being QC'ed.
2021-05-07 21:29:39 +02:00
..

QC tests

Introduction

QC tests are defined and parametrised out of source in YAML files. In the project definition file, the qc.definitions and qc.parameters keys point to, respectively, the definition and parametrisation files for the QCs to be applied to a given project.

Different QCs may be defined for different projects by saving them to separate definition files; conversely, the same QCs may be reused across projects.

The parameters for each QC test are saved to a separate file. This is to allow QCs to be reused across projects, possibly with different parameters.

Running

For all projects that have QCs defined, the tests can be run by calling the lib/www/server/lib/qc.js script. This can be done from a cronjob, e.g.,:

# max-old-space-size increases the memory available to Node.js, to deal with complicated tests or large projects.
*/5 * * * * NODE_OPTIONS="--max-old-space-size=4096" node $HOME/software/lib/www/server/lib/qc.js >/dev/null

QC definition file

The QC definition YAML file should consist of a list of tests. These may be organised hierarchically if the user wishes to do so.

A QC definition consists of the following attributes:

Attribute Description
name A short name for the test or hierarchical group.
description A more detailed description. Markdown is accepted.
disabled If true, the test or branch will not be run.
iterate What to iterate over. It can take one of three values: shots, sequences or lines. If not present it defaults to shots, which means the script will be called once per every shot in the prospect.
labels Array of labels to apply to the test or to the branch.
children Any element having a children attribute becomes a branch. The contents of this attribute are a list of tests or branches, same as the top-level list.
check A script consisting of JavaScript code which defines the test that is to be run. Tests that pass should return true whereas failing tests should return a string with a message describing the failure. Note that it is valid to have both check and children in the same item.

Test definitions

Tests can be defined as arbitrary JavaScript, which will be run in a sandbox. The sandboxed code does not have access to the filesystem or the console object.

The result of the test is the last expression evaluated by the script. This should be the primitive true if the test is successful, or a string describing the failure if it is not.

The script has access to the following variables:

parameters

An object containing all the parameter definitions for the project, for instance:

{
  gunDepth: 6,
  gunDepthTolerance: 0.5,
  gunTiming: 0.9999,
  gunTimingSubarrayAverage: 0.5,
  gunPressureNominal: 2000,
  gunPressureToleranceRatio: 0.025,
  crosslineError: 12,
  crosslineErrorAverage: 9,
  inlineErrorRunningAverageValue: 2,
  inlineErrorRunningAverageShots: 40
}

currentItem

The item being iterated over. This can be of type Shot, Sequence, or Preplot depending on the value of this test's iterate attribute.

shots

An array of Shot objects.

Example:

{
  type: 'final',
  _id: [ 7, 1764 ],
  sequence: 7,
  line: 5500,
  point: 1764,
  objref: 3,
  tstamp: "2020-09-07T04:10:13.680Z",
  hash: '2173892:1599458941.3070147:1599458941.3070147:80621034',
  geometry: '{"type":"Point","coordinates":[2.471571453,59.169725413]}',
  error_i: 2.7102108739654795,
  error_j: -0.06460360411324473,
  preplot_geometry: '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:23031"}},"coordinates":[469883.4,6559284.9]}',
  raw_geometry: '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:23031"}},"coordinates":[469881.87,6559285.76]}',
  final_geometry: '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:23031"}},"coordinates":[469881.09,6559286.22]}',
  pp_meta: {},
  raw_meta: {
    smsrc: {
      guns: [Array],
      line: '1054980007S00000',
      mask: 38,
      shot: 1764,
      time: "b'20/09/07:04:10:13'",
      spare: '',
      header: '*SMSRC',
      spread: 3,
      volume: 3050,
      blk_siz: 2282,
      manifold: 2027,
      num_auto: 0,
      num_guns: 52,
      trg_mode: 'E',
      avg_delta: 0,
      num_delta: 0,
      std_delta: 0.073,
      baro_press: null,
      num_active: 52,
      num_nofire: 0,
      src_number: 2,
      num_subarray: 6
    }
  },
  final_meta: {},
  _: [Function]
}

sequences

An array of Sequence objects.

Example:

{
    "_id": 9,
    "sequence": 9,
    "line": 5562,
    "fsp": 2580,
    "lsp": 996,
    "fsp_final": 2548,
    "lsp_final": 1000,
    "ts0": "2020-09-07T08:34:13.112Z",
    "ts1": "2020-09-07T10:47:49.116Z",
    "ts0_final": "2020-09-07T08:36:58.984Z",
    "ts1_final": "2020-09-07T10:47:28.608Z",
    "duration": {
        "hours": 2,
        "minutes": 13,
        "seconds": 36,
        "milliseconds": 4
    },
    "duration_final": {
        "hours": 2,
        "minutes": 10,
        "seconds": 29,
        "milliseconds": 624
    },
    "num_preplots": 775,
    "num_points": 775,
    "missing_shots": 0,
    "length": 19350.1845360761,
    "azimuth": 26.443105805883572,
    "remarks": "",
    "remarks_final": "",
    "status": "final"
    _: [Function]
}

preplots

An array of Preplot objects.

Example:

{
  _id: [ null, 2348, 5130 ],
  line: 5130,
  point: 2348,
  class: 'V',
  ntba: false,
  geometry: '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:23031"}},"coordinates":[470769.8,6550688.8]}',
  meta: {},
  count: 0
}

The _ function

Each of the above objects has a function named _. This is a helper to quickly access own nested attributes without having to check if the attribute or one of its parents exist. For instance, on a Shot item, currentItem._('raw_meta.smsrc') will return the SmartSource gun data if it exists, or undefined if either smsrc or raw_meta are not defined.