tnql 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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