tnql 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.hound.yml +10 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +11 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/Guardfile +15 -0
- data/LICENSE.txt +21 -0
- data/README.md +74 -0
- data/Rakefile +12 -0
- data/bin/console +10 -0
- data/bin/setup +7 -0
- data/code_safety.yml +272 -0
- data/lib/tnql.rb +4 -0
- data/lib/tnql/constants.rb +8 -0
- data/lib/tnql/grammars.rb +16 -0
- data/lib/tnql/grammars/age.treetop +63 -0
- data/lib/tnql/grammars/batch_types.treetop +65 -0
- data/lib/tnql/grammars/dates.treetop +35 -0
- data/lib/tnql/grammars/diagnosis.treetop +23 -0
- data/lib/tnql/grammars/e_base_records.treetop +86 -0
- data/lib/tnql/grammars/main.treetop +54 -0
- data/lib/tnql/grammars/patient.treetop +39 -0
- data/lib/tnql/grammars/provider.treetop +21 -0
- data/lib/tnql/grammars/registration_status.treetop +11 -0
- data/lib/tnql/grammars/registry.treetop +15 -0
- data/lib/tnql/grammars/staging.treetop +23 -0
- data/lib/tnql/grammars/treatment.treetop +35 -0
- data/lib/tnql/grammars/tumour_type.treetop +54 -0
- data/lib/tnql/grammars/vital_status.treetop +19 -0
- data/lib/tnql/nodes.rb +25 -0
- data/lib/tnql/nodes/age.rb +82 -0
- data/lib/tnql/nodes/batch_types.rb +52 -0
- data/lib/tnql/nodes/dates.rb +50 -0
- data/lib/tnql/nodes/diagnosis.rb +31 -0
- data/lib/tnql/nodes/e_base_records.rb +61 -0
- data/lib/tnql/nodes/main.rb +11 -0
- data/lib/tnql/nodes/patient.rb +9 -0
- data/lib/tnql/nodes/provider.rb +24 -0
- data/lib/tnql/nodes/registration_status.rb +27 -0
- data/lib/tnql/nodes/registry.rb +33 -0
- data/lib/tnql/nodes/staging.rb +17 -0
- data/lib/tnql/nodes/treatment.rb +45 -0
- data/lib/tnql/nodes/tumour_type.rb +74 -0
- data/lib/tnql/nodes/vital_status.rb +15 -0
- data/lib/tnql/parser.rb +56 -0
- data/lib/tnql/treetop/extensions.rb +20 -0
- data/lib/tnql/version.rb +4 -0
- data/tnql.gemspec +39 -0
- metadata +286 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module Tnql
|
2
|
+
grammar Staging
|
3
|
+
rule stage
|
4
|
+
space stage_detail word_break
|
5
|
+
end
|
6
|
+
|
7
|
+
rule stage_detail
|
8
|
+
('stage' space stages:stage_value* / 'unstaged' / 'valid stage') <Nodes::StageDetailNode>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule stage_value
|
12
|
+
number / unstageable / insufficient_info
|
13
|
+
end
|
14
|
+
|
15
|
+
rule unstageable
|
16
|
+
'u'
|
17
|
+
end
|
18
|
+
|
19
|
+
rule insufficient_info
|
20
|
+
'?'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Tnql
|
2
|
+
grammar Treatment
|
3
|
+
rule treatment
|
4
|
+
treated_keyword conditions:treatment_conditions+
|
5
|
+
end
|
6
|
+
|
7
|
+
rule treated_keyword
|
8
|
+
space 'treated' word_break
|
9
|
+
end
|
10
|
+
|
11
|
+
rule treatment_conditions
|
12
|
+
treatmentdate_range / treatmentdate_detail / treatment_provider
|
13
|
+
end
|
14
|
+
|
15
|
+
rule treatmentdate_range
|
16
|
+
space 'between' space start:date_fragment space 'and' space finish:date_fragment <Nodes::TreatmentDateRangeNode>
|
17
|
+
end
|
18
|
+
|
19
|
+
rule treatmentdate_detail
|
20
|
+
space ('in' / 'on') space date_fragment <Nodes::TreatmentPreciseDateNode>
|
21
|
+
end
|
22
|
+
|
23
|
+
rule treatment_provider
|
24
|
+
space 'at' space provider:(treatment_provider_code / treatment_provider_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
rule treatment_provider_name
|
28
|
+
(!(space provider_type) .)+ space provider_type <Nodes::TreatmentProviderNameNode>
|
29
|
+
end
|
30
|
+
|
31
|
+
rule treatment_provider_code
|
32
|
+
provider_type space code:(!' ' .)+ <Nodes::TreatmentProviderCodeNode>
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Tnql
|
2
|
+
grammar TumourType
|
3
|
+
rule behaviour
|
4
|
+
space behaviour_detail word_break
|
5
|
+
end
|
6
|
+
|
7
|
+
rule behaviour_detail
|
8
|
+
('behaviour' space number / 'noninvasive' / 'non-invasive' / 'invasive' / 'metastatic') <Nodes::BehaviourDetailNode>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule tumour_type
|
12
|
+
space (site_group / names_type / sites) word_break
|
13
|
+
end
|
14
|
+
|
15
|
+
rule site_group
|
16
|
+
('brain' / 'breast' / 'endocrine' / 'gynaecological'
|
17
|
+
/ 'haematological' / 'head' space 'and' space 'neck'
|
18
|
+
/ 'lower' space 'gi' / 'lung' / 'other' / 'sarcoma'
|
19
|
+
/ 'skin' / 'upper' space 'gi' / 'urological') <Nodes::SiteGroupNode>
|
20
|
+
end
|
21
|
+
|
22
|
+
rule names_type
|
23
|
+
( melanoma / non_melanoma ) word_break
|
24
|
+
end
|
25
|
+
|
26
|
+
rule melanoma
|
27
|
+
'melanoma' <Nodes::MelanomaNode>
|
28
|
+
end
|
29
|
+
|
30
|
+
rule non_melanoma
|
31
|
+
('nmsc' / 'non-melanoma' / 'non' space 'melanoma') <Nodes::NonMelanomaNode>
|
32
|
+
end
|
33
|
+
|
34
|
+
rule sites
|
35
|
+
first:site rest:more_sites* <Nodes::SitesNode>
|
36
|
+
end
|
37
|
+
|
38
|
+
rule more_sites
|
39
|
+
','? space? ('and' space)? site <Nodes::AdditionalSiteNode>
|
40
|
+
end
|
41
|
+
|
42
|
+
rule site
|
43
|
+
(icd_site / snomed_site) <Nodes::SingleSiteNode>
|
44
|
+
end
|
45
|
+
|
46
|
+
rule icd_site
|
47
|
+
[cd] [0-9] [0-9] '.'? [0-9]?
|
48
|
+
end
|
49
|
+
|
50
|
+
rule snomed_site
|
51
|
+
't' [0-9fxy] [0-9fxy] [0-9fxy]? [0-9fxy]? [0-9y]?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Tnql
|
2
|
+
grammar VitalStatus
|
3
|
+
rule dead_or_alive
|
4
|
+
space vital_status:('dead' / 'alive') word_break <Nodes::DeadOrAliveNode>
|
5
|
+
end
|
6
|
+
|
7
|
+
rule death_certificate
|
8
|
+
have_keyword space modifier:('no' / 'a') death_certificate_keywords <Nodes::DeathCertificateNode>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule death_certificate_keywords
|
12
|
+
space 'death' space 'certificate' word_break
|
13
|
+
end
|
14
|
+
|
15
|
+
rule have_keyword
|
16
|
+
space 'have' word_break
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/tnql/nodes.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# These file contain custom mixins for treetop
|
2
|
+
# nodes that enable them to generate meta_data_items, etc.
|
3
|
+
|
4
|
+
# Treetop documentation seems to be out of date;
|
5
|
+
# it says to create subclasses of nodes. However,
|
6
|
+
# treetop 1.4.10 expects to extend the node with
|
7
|
+
# the specified <MODULE> from the grammar.
|
8
|
+
|
9
|
+
require 'tnql/treetop/extensions'
|
10
|
+
require 'tnql/constants'
|
11
|
+
|
12
|
+
require 'tnql/nodes/age'
|
13
|
+
require 'tnql/nodes/batch_types'
|
14
|
+
require 'tnql/nodes/dates'
|
15
|
+
require 'tnql/nodes/diagnosis'
|
16
|
+
require 'tnql/nodes/e_base_records'
|
17
|
+
require 'tnql/nodes/main'
|
18
|
+
require 'tnql/nodes/patient'
|
19
|
+
require 'tnql/nodes/provider'
|
20
|
+
require 'tnql/nodes/registration_status'
|
21
|
+
require 'tnql/nodes/registry'
|
22
|
+
require 'tnql/nodes/staging'
|
23
|
+
require 'tnql/nodes/treatment'
|
24
|
+
require 'tnql/nodes/tumour_type'
|
25
|
+
require 'tnql/nodes/vital_status'
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Tnql #:nodoc: all
|
2
|
+
module Nodes
|
3
|
+
module AgeNode
|
4
|
+
def to_limits
|
5
|
+
age.to_limits
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ExactAgeNode
|
10
|
+
def to_exact
|
11
|
+
text_value.to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_limits
|
15
|
+
i = to_exact
|
16
|
+
[i, i]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module FuzzyAgeNode
|
21
|
+
def to_limits
|
22
|
+
[start.to_exact, finish.to_exact]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module AgeAtDiagnosisNode
|
27
|
+
def meta_data_item
|
28
|
+
{ 'patient.age' => { Tnql::LIMITS => age.to_limits } }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module DeathDateNode
|
33
|
+
def meta_data_item
|
34
|
+
range = fuzzy_date.to_daterange
|
35
|
+
{
|
36
|
+
'patient.deathdate' => {
|
37
|
+
Tnql::LIMITS => [
|
38
|
+
range.date1.try(:to_date).try(:iso8601), range.date2.try(:to_date).try(:iso8601)
|
39
|
+
]
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module BirthDateNode
|
46
|
+
def meta_data_item
|
47
|
+
range = fuzzy_date.to_daterange
|
48
|
+
{
|
49
|
+
'patient.birthdate' => {
|
50
|
+
Tnql::LIMITS => [
|
51
|
+
range.date1.try(:to_date).try(:iso8601), range.date2.try(:to_date).try(:iso8601)
|
52
|
+
]
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module CtyaNode
|
59
|
+
def meta_data_item
|
60
|
+
{ 'patient.age' => { Tnql::LIMITS => [0, 24] } }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module PaediatricNode
|
65
|
+
def meta_data_item
|
66
|
+
{ 'patient.age' => { Tnql::LIMITS => [0, 15] } }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
module TeenageNode
|
71
|
+
def meta_data_item
|
72
|
+
{ 'patient.age' => { Tnql::LIMITS => [16, 18] } }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module YoungAdultNode
|
77
|
+
def meta_data_item
|
78
|
+
{ 'patient.age' => { Tnql::LIMITS => [19, 24] } }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Tnql #:nodoc: all
|
2
|
+
module Nodes
|
3
|
+
module BatchTypeNode
|
4
|
+
def to_type
|
5
|
+
string = respond_to?(:normalise) ? normalise : text_value
|
6
|
+
string.upcase
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module USomNode
|
11
|
+
def normalise
|
12
|
+
'usom'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module UPathNode
|
17
|
+
def normalise
|
18
|
+
'upath'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module UPasNode
|
23
|
+
def normalise
|
24
|
+
'upas'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module UCwtNode
|
29
|
+
def normalise
|
30
|
+
'ucwt'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module UCdNode
|
35
|
+
def normalise
|
36
|
+
'ucd'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module UNcdNode
|
41
|
+
def normalise
|
42
|
+
'uncd'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module UExtregNode
|
47
|
+
def normalise
|
48
|
+
'uextreg'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'chronic'
|
2
|
+
require 'ndr_support/daterange'
|
3
|
+
|
4
|
+
module Tnql #:nodoc: all
|
5
|
+
module Nodes
|
6
|
+
module FuzzyDateNode
|
7
|
+
def to_daterange
|
8
|
+
date.to_daterange
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module SpecificDateNode
|
13
|
+
def to_daterange
|
14
|
+
date_fragment.to_daterange
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module FragmentedDateRangeNode
|
19
|
+
def to_daterange
|
20
|
+
d1 = start.to_daterange.date1
|
21
|
+
d2 = finish.to_daterange.date2
|
22
|
+
|
23
|
+
Daterange.new(d1, d2)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module DateFragmentNode
|
28
|
+
def to_daterange
|
29
|
+
fragment.to_daterange
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module DateRangeNode
|
34
|
+
def to_daterange
|
35
|
+
Daterange.new(text_value.to_s)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module ChronicDateNode
|
40
|
+
def to_daterange
|
41
|
+
chronic = Chronic.parse(text_value.to_s, context: :past, guess: false)
|
42
|
+
if chronic.instance_of?(Chronic::Span)
|
43
|
+
Daterange.new(chronic.begin, chronic.end - 1.day)
|
44
|
+
else
|
45
|
+
Daterange.new(chronic)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Tnql #:nodoc: all
|
2
|
+
module Nodes
|
3
|
+
module DiagnosisDateRangeNode
|
4
|
+
def meta_data_item
|
5
|
+
{
|
6
|
+
'tumour.diagnosisdate' => {
|
7
|
+
Tnql::LIMITS => [
|
8
|
+
start.to_daterange.date1.try(:to_date).try(:iso8601),
|
9
|
+
finish.to_daterange.date2.try(:to_date).try(:iso8601)
|
10
|
+
]
|
11
|
+
}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module DiagnosisDetailNode
|
17
|
+
def meta_data_item
|
18
|
+
range = date_fragment.to_daterange
|
19
|
+
|
20
|
+
{
|
21
|
+
'tumour.diagnosisdate' => {
|
22
|
+
Tnql::LIMITS => [
|
23
|
+
range.date1.try(:to_date).try(:iso8601),
|
24
|
+
range.date2.try(:to_date).try(:iso8601)
|
25
|
+
]
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Tnql #:nodoc: all
|
2
|
+
module Nodes
|
3
|
+
module EBaseRecordsNode
|
4
|
+
def meta_data_item
|
5
|
+
filter =
|
6
|
+
if types.empty?
|
7
|
+
{ Tnql::ALL => true }
|
8
|
+
else
|
9
|
+
{ Tnql::EQUALS => types.to_list }
|
10
|
+
end
|
11
|
+
{ 'unprocessed_records.sources' => filter }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module BatchTypesNode
|
16
|
+
def to_list
|
17
|
+
allowed_types.to_list
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module AllowedTypesNode
|
22
|
+
def to_list
|
23
|
+
list = [batch_type.to_type]
|
24
|
+
list.concat types.elements.map(&:extract_type)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module MoreTypesNode
|
29
|
+
def extract_type
|
30
|
+
batch_type.to_type
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module ActionsNode
|
35
|
+
def meta_data_item
|
36
|
+
{ 'action.actioninitiated' => { Tnql::EQUALS => action_type.text_value.upcase.strip } }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module ActionProviderCodeNode
|
41
|
+
def meta_data_item
|
42
|
+
# default to provider
|
43
|
+
key = provider_type.text_value == 'cancer network' ? 'cn_ukacr' : 'providercode'
|
44
|
+
{ "action.#{key}" => { Tnql::EQUALS => code.text_value.upcase } }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module ActionProviderNameNode
|
49
|
+
def meta_data_item
|
50
|
+
# default to provider
|
51
|
+
key = provider_type.text_value == 'cancer network' ? 'cn_ukacrname' : 'providername'
|
52
|
+
{
|
53
|
+
"action.#{key}" => {
|
54
|
+
Tnql::BEGINS => short_desc.text_value.upcase,
|
55
|
+
:interval => interval
|
56
|
+
}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|