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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.hound.yml +10 -0
  4. data/.rubocop.yml +7 -0
  5. data/.travis.yml +11 -0
  6. data/CODE_OF_CONDUCT.md +13 -0
  7. data/Gemfile +4 -0
  8. data/Guardfile +15 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +74 -0
  11. data/Rakefile +12 -0
  12. data/bin/console +10 -0
  13. data/bin/setup +7 -0
  14. data/code_safety.yml +272 -0
  15. data/lib/tnql.rb +4 -0
  16. data/lib/tnql/constants.rb +8 -0
  17. data/lib/tnql/grammars.rb +16 -0
  18. data/lib/tnql/grammars/age.treetop +63 -0
  19. data/lib/tnql/grammars/batch_types.treetop +65 -0
  20. data/lib/tnql/grammars/dates.treetop +35 -0
  21. data/lib/tnql/grammars/diagnosis.treetop +23 -0
  22. data/lib/tnql/grammars/e_base_records.treetop +86 -0
  23. data/lib/tnql/grammars/main.treetop +54 -0
  24. data/lib/tnql/grammars/patient.treetop +39 -0
  25. data/lib/tnql/grammars/provider.treetop +21 -0
  26. data/lib/tnql/grammars/registration_status.treetop +11 -0
  27. data/lib/tnql/grammars/registry.treetop +15 -0
  28. data/lib/tnql/grammars/staging.treetop +23 -0
  29. data/lib/tnql/grammars/treatment.treetop +35 -0
  30. data/lib/tnql/grammars/tumour_type.treetop +54 -0
  31. data/lib/tnql/grammars/vital_status.treetop +19 -0
  32. data/lib/tnql/nodes.rb +25 -0
  33. data/lib/tnql/nodes/age.rb +82 -0
  34. data/lib/tnql/nodes/batch_types.rb +52 -0
  35. data/lib/tnql/nodes/dates.rb +50 -0
  36. data/lib/tnql/nodes/diagnosis.rb +31 -0
  37. data/lib/tnql/nodes/e_base_records.rb +61 -0
  38. data/lib/tnql/nodes/main.rb +11 -0
  39. data/lib/tnql/nodes/patient.rb +9 -0
  40. data/lib/tnql/nodes/provider.rb +24 -0
  41. data/lib/tnql/nodes/registration_status.rb +27 -0
  42. data/lib/tnql/nodes/registry.rb +33 -0
  43. data/lib/tnql/nodes/staging.rb +17 -0
  44. data/lib/tnql/nodes/treatment.rb +45 -0
  45. data/lib/tnql/nodes/tumour_type.rb +74 -0
  46. data/lib/tnql/nodes/vital_status.rb +15 -0
  47. data/lib/tnql/parser.rb +56 -0
  48. data/lib/tnql/treetop/extensions.rb +20 -0
  49. data/lib/tnql/version.rb +4 -0
  50. data/tnql.gemspec +39 -0
  51. 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
@@ -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
@@ -0,0 +1,11 @@
1
+ require 'active_support/core_ext/object/blank'
2
+
3
+ module Tnql #:nodoc: all
4
+ module Nodes
5
+ module RecordCountNode
6
+ def meta_data_item
7
+ { 'limit' => { Tnql::EQUALS => number.text_value.to_i } }
8
+ end
9
+ end
10
+ end
11
+ end