Files
dougal-software/etc/qc/README.md
2020-09-12 22:25:45 +02:00

188 lines
6.0 KiB
Markdown

# 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`](/lib/www/server/lib/qc.js) script. This can be done from a cronjob, e.g.,:
```cron
# 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:
```javascript
{
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:
```javascript
{
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:
```javascript
{
"_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:
```javascript
{
_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.