Skip to content

Commit 6067865

Browse files
committed
Fix Kanban board issues
1 parent 82ce516 commit 6067865

File tree

5 files changed

+50
-21
lines changed

5 files changed

+50
-21
lines changed

parsers/duration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def get_readable(self, duration=None, duration_max=None, duration_unit=None):
2020

2121
# for x [more] days
2222
class DurationParserForXDays(DurationParser):
23-
pattern = r'(?:for|x)\s*(?P<duration>' + RE_RANGE + r')\s*(?:more)?\s?(?P<duration_unit>year|month|week|day|yr\b|mon\b|wk\b|d\b)'
23+
pattern = r'(?:for|\bf|x)\s*(?P<duration>' + RE_RANGE + r')\s*(?:more)?\s?(?P<duration_unit>year(?:s)|month(?:s)|week(?:s)|day(?:s)|yr(?:s)\b|mon(?:s)\b|wk(?:s)?|d\b|w\b)'
2424
def normalize_match(self, match):
2525
duration_range = split_range(match.group('duration'))
2626
duration_text_start, duration_text_end = match.span()
@@ -33,7 +33,7 @@ def normalize_match(self, match):
3333

3434
# up to x days
3535
class DurationParserUpToXDays(DurationParser):
36-
pattern = r'(?:for )?up to (?P<duration>' + RE_RANGE + r')\s?(?P<duration_unit>year|month|week|day|yr\b|mon\b|wk\b|d\b)'
36+
pattern = r'(?:for )?up to (?P<duration>' + RE_RANGE + r')\s?(?P<duration_unit>year(?:s)|month(?:s)|week(?:s)|day(?:s)|yr(?:s)\b|mon(?:s)\b|wk(?:s)|d\b)'
3737
def normalize_match(self, match):
3838
duration_range = split_range(match.group('duration'))
3939
duration_text_start, duration_text_end = match.span()

parsers/indication.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# TODO: replace wildcard indication search with INDICATIONS list from normalize.py
66
class IndicationParser(Parser):
77
parser_type = 'indication'
8-
pattern = r'(?P<as_needed>as needed for|if needed for|as needed|if needed|prn for|prf|prn)(?:\s?(?P<indication>.{,250}))?'
8+
pattern = r'(?P<as_needed>as needed for|if needed for|as needed|to prevent|if needed|prn for|prnf|prf|prn)(?:\s?(?P<indication>.{,250}))?'
99
match_keys = ['as_needed', 'indication', 'indication_text_start', 'indication_text_end', 'indication_text', 'indication_readable']
1010
def normalize_match(self, match):
1111
as_needed = 1
@@ -30,7 +30,7 @@ def get_readable(self, as_needed=None, indication=None):
3030
return readable
3131

3232
class ChronicIndicationParser(IndicationParser):
33-
pattern = r'(?!as needed|if needed|prn|prf) for (?P<indication>.{,250})(?!' + RE_RANGE + r')'
33+
pattern = r'(?!as needed |if needed |prn |prf |prnf )(?:for|indications) (?P<indication>.{,250})(?!' + RE_RANGE + r')'
3434
def normalize_match(self, match):
3535
indication_text = match.group('indication')
3636
indication = (get_indication(indication_text) if indication_text != None else indication_text)

parsers/services/normalize.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
# NOTE: periodUnit 'day' should include pretty much all of 'when' array
6767
# for FHIR conversion: https://www.hl7.org/fhir/valueset-units-of-time.html
6868
PERIOD_UNIT = {
69-
'day': [ 'daily', 'dialy', 'nightly', 'days', 'day', r'\bd\b', 'morning', 'morn', 'am', 'afternoon', 'aft', 'pm', 'evening at bedtime', 'bedtime', 'evening', 'eve', 'night', 'hs' ],
69+
'day': [ 'daily', 'dialy', 'nightly', 'days', 'day', r'\bd\b', 'morning', 'morn', 'am', 'afternoon', 'aft', 'pm', r'evening at bed(?:\s)?time', r'bed(?:\s)?time', 'evening', 'eve', 'night', 'hs' ],
7070
'week': [ 'weekly', 'weeks', 'week', 'wks', 'wk', r'\bw\b' ],
7171
'month': [ 'monthly', 'months', 'month', 'mon', 'mo' ],
7272
'hour': [ 'hourly', 'hours', 'hour', 'hrs', 'hr', r'\bh\b' ],
@@ -90,10 +90,10 @@
9090
WHEN = {
9191
'in the morning': [ r'(?:in the|every|each)\s?(?:morn(?:ing)?|a m\b|am)', r'a m\b', r'\bam\b', r'\bqam\b', r'q am\b' ],
9292
'in the afternoon': [ r'(?:in the|every|each|at)\s?(?:aft(?:ernoon)?|p m\b|pm)', r'\bqpm\b', 'q afternoon' ],
93-
'in the evening at bedtime': [r'(?:in the|every)\s?evening at bedtime'],
94-
'in the evening': [ r'(?:in the|every|each)\s?eve(?:ning)?(?! at bedtime)' ],
95-
'at night': [ r'(?:in the|at|every|each)\s?night(?! at bedtime)', r'nightly(?! at bedtime)' ],
96-
'at bedtime': [ r'(?!eve(?:ning) )(?:in the|at|every|every night at|nightly at|each)\s?bedtime', r'\bqhs\b', r'q hs\b', 'bedtime', r'\bhs\b' ],
93+
'in the evening at bedtime': [r'(?:in the|every)\s?evening at bed(?:\s)?time'],
94+
'in the evening': [ r'(?:in the|every|each)\s?eve(?:ning)?(?! at bed(?:\s)?time)' ],
95+
'at night': [ r'(?:in the|at|every|each)\s?night(?! at bed(?:\s)?time)', r'nightly(?! at bed(?:\s)?time)' ],
96+
'at bedtime': [ r'(?!eve(?:ning) )(?:in the|at|every|before|every night at|nightly at|each)\s?bed(?:\s)?time', r'\bqhs\b', r'q hs\b', r'bed(?:\s)?time', r'\bhs\b' ],
9797
'with meal': [ r'(?:with|each|every|at)?\s?meal(?:s)?', r'c c\b', r'\bcc\b' ],
9898
'with breakfast': [ r'(?:with|each|every|at)? breakfast' ],
9999
'with lunch': [ r'(?:with|each|every|at)?\s?lunch', r'\bcd\b', r'c d\b' ],
@@ -123,7 +123,7 @@
123123
'use': [],
124124
'push': [],
125125
'give': [],
126-
'take': [r'\btk(?:\b|\d)', r'^t(?:\b|\d)'],
126+
'take': [r'\btk(?:\b|\d)', r'^t(?:\b|\d)', 'taking'],
127127
'swallow': [],
128128
'instill': [],
129129
'chew': [],
@@ -181,13 +181,13 @@
181181
'by mouth': ['by oral route', 'oral', r'orally(?! disintegrating)', r'po\b', r'p o\b', r'oral\b'],
182182
'in left ear': [r'(?:in to |into |in |to |per )?(?:the )?left ear', r'\ba\.s\.\b'],
183183
'in right ear': [r'(?:in to |into |in |to |per )?(?:the )?right ear', r'\ba\.d\.\b'],
184-
'in each ear': [r'(?:in to |into |in |to |per )?(?:both ears|each ear|(?!affected )ears)', r'\ba\.u\.\b', r'\bau\b'],
184+
'in each ear': [r'(?:in to |into |in |to |per )?(?:bilateral ears|both ears|each ear|(?!affected )ears)', r'\ba\.u\.\b', r'\bau\b'],
185185
'in affected ear': [r'(?:in to |into |in |to |per )?(?:the )?affected ear\b'],
186186
'in ear(s)': ['by ear', 'otically', 'otic', r'(?:in to |into |in |to |per )?(?:the )?(?!affected )ear\b'],
187187
'in left nostril': [r'(?:in to |into |in |to |per )?(?:the )?left (?:nose|nostril|nare)'],
188188
'in right nostril': [r'(?:in to |into |in |to |per )?(?:the )?right (?:nose|nostril|nare)'],
189189
'in each nostril': [r'(?:in to |into |in |to |per )?(?:both nostrils|each nostril|(?<!affected )nostrils|each nare)', r'\bien\b'],
190-
'in nostril(s)': ['by nose', 'nasally', r'nasal(?! spray)', 'intranasal', r'(?:in to |into |in |to |per )?(?:the )?(?!each|left|right|both)(?:affected)?(?:nose|nostrils|nostril|nare)\b'],
190+
'in nostril(s)': [r'\bvn\b', 'by nose', 'nasally', r'nasal(?! spray)', 'intranasal', r'(?:in to |into |in |to |per )?(?:the )?(?!each|left|right|both)(?:affected)?(?:nose|nostrils|nostril|nare)\b'],
191191
'in left eye': [r'(?:in to |into |in |to |per )?(?:the )?left eye', r'\bo\.s\.\b', r'\bos\b'],
192192
'in right eye': [r'(?:in to |into |in |to |per )?(?:the )?right eye', r'\bo\.d\.\b', r'\bod\b'],
193193
'in each eye': [r'(?:in to |into |in |to |per )?(?:both eyes|each eye|(?!affected )eyes)', r'\bo\.u\.\b', r'\bou\b'],
@@ -198,7 +198,7 @@
198198
'under the tongue': ['sublingually', 'sublingual', r'under (?:the )?tongue', r'sub(?: |-)?lingual(?:ly)?', r'\bs\.l\.\b', r'\bsl\b'],
199199
'under the skin': ['subcutaneously', 'subcutaneous', r'(?:into|in|under) (?:the )?skin', r'sub(?: |-)*cutaneous(?:ly)?', r'subq\b', r'sub\.q\.', r'sc\b', r'subcu\b', r's\.c\.', r'sq\b', r's\.q\.', 's/q'],
200200
'rectally': ['rectal', r'p\.r\.\b', r'pr\b', r'in(?:to)* (?:the )?(?:butt|anus|rectum)'],
201-
'into the muscle': ['intramuscularly', r'i\.m\.\b', r'\bim\b', 'intramuscular', r'in(?:to)?(?: the)? muscle' ],
201+
'into the muscle': ['intramuscularly', r'i\.m\.\b', r'\bim\b', 'intramuscular', r'in(?:to)?(?: the)? muscle', 'intramuscularrly'],
202202
'intravenously': [r'i\.v\.', r'\biv\b', 'intravenous'],
203203
'cutaneously': [r'\bcutaneous'],
204204
'to the skin': ['transdermally', 'transdermal', 'patch', 'patches'],
@@ -347,13 +347,15 @@
347347
"""
348348

349349
TOPICAL_ROUTES = {
350-
'topically': [r'topical\b', 'application', 'apply', 'patch'],
350+
'topically': [r'topical\b', r'\btop\b', 'application', 'apply', 'patch'],
351351
'affected areas': [r'involved (?:areas|sites)'],
352352
'affected area': [r'\baa\b', r'involved (?:area|site)\b'],
353353
'back': [],
354354
'scalp': [],
355355
'torso': [],
356356
'arms': [],
357+
'legs': [],
358+
'abdomen': [],
357359
'arm': [],
358360
'eyelids': ['eye lids'],
359361
'eyelid': [r'eye lid\b'],
@@ -366,6 +368,8 @@
366368
'buttocks': [r'butt\b'],
367369
'blood blister': [],
368370
'face': [],
371+
'chest': [],
372+
'shoulders': [],
369373
}
370374

371375
INHALATION_ROUTES = {
@@ -441,7 +445,7 @@
441445
# tablet
442446
# TODO: add all synonyms to exclusion for tablet
443447
# ERROR: make sure "tablespoon" does not match on "tab" -- use a negative lookahead
444-
'tablet': [r'(?<!film-coated)(?<!effervescentgastro-resistant)(?<!orodispersible)(?<!prolonged-release)(?<!vaginal)(?<!effervescent vaginal)(?<!modified-release)(?<!chewable)(?<!sublingual)(?<!buccalmuco-adhesive buccal)(?<!soluble)(?<!dispersible)(?<!delayed-release particles)(?<!oral)(?<!inhalation vapor)(?<!implantation)(?<!extended-release film coated)(?<!ultramicronized)(?<!extended-release)(?<!extended-release enteric coated)(?<!delayed-release)(?<!coated particles)(?<!sustained-release buccal)(?<!multilayer)\s*tab(?:let)?(?:s)?', r't\b', r'ts\b'],
448+
'tablet': [r'(?<!film-coated)(?<!effervescentgastro-resistant)(?<!orodispersible)(?<!prolonged-release)(?<!vaginal)(?<!effervescent vaginal)(?<!modified-release)(?<!chewable)(?<!sublingual)(?<!buccalmuco-adhesive buccal)(?<!soluble)(?<!dispersible)(?<!delayed-release particles)(?<!oral)(?<!inhalation vapor)(?<!implantation)(?<!extended-release film coated)(?<!ultramicronized)(?<!extended-release)(?<!extended-release enteric coated)(?<!delayed-release)(?<!coated particles)(?<!sustained-release buccal)(?<!multilayer)\s*tab(?:let)?(?:s)?', r'tb\b', r't\b', r'ts\b'],
445449
'film-coated tablet': [r'(?:film-coated|film coated) tab(?:let)?(?:s)?'],
446450
'effervescent tablet': [r'effervescent tab(?:let)?(?:s)?'],
447451
'gastro-resistant tablet': [r'(?:gastro-resistant|gastro resistant) tab(?:let)?(?:s)?'],
@@ -482,7 +486,6 @@
482486
'prolonged-release capsule': [r'(?:prolonged-release|prolonged release) cap(?:sule)?(?:s)?\b'],
483487
'coated pellets capsule': [r'coated pellets cap(?:sule)?(?:s)?\b'],
484488
'delayed-release capsule': [r'(?:delayed-release|delayed release|d.r.|dr) cap(?:sule)?(?:s)?\b'],
485-
'oral capsule': [r'oral cap(?:sule)?(?:s)?\b'],
486489
'extended-release film coated capsule': [r'(?:extended-release|extended release|e.r.|er) (?:film coated|film-coated) cap(?:sule)?(?:s)?\b'],
487490
'extended-release coated capsule': [r'(?:extended-release|extended release|e.r.|er) coated cap(?:sule)?(?:s)?\b'],
488491
'extended-release capsule': [r'(?:extended-release|extended release|e.r.|er) cap(?:sule)?(?:s)?\b'],
@@ -540,6 +543,7 @@
540543
'cutaneous aerosol': [],
541544
'metered dose aerosol': [],
542545
# gum
546+
'gummie': [],
543547
'gum': [],
544548
'oral gum': [],
545549
'medicated chewing-gum': [r'medicated chewing gum'],
@@ -630,7 +634,7 @@
630634
'pen': [],
631635
'applicatorful': ['applicatorsful', 'applicator'],
632636
# NOTE: have a separate parser for generic application keywords (i.e. 'apply')
633-
'application': [r'app\b', r'applic\b'],
637+
'application': [ r'applic\b', r'appl\b', r'app\b'],
634638
'capful': [],
635639
'injection': [],
636640
'packet': ['pkt'],
@@ -645,6 +649,8 @@
645649
'swab': [],
646650
'squirt': [],
647651
'pump': [],
652+
'troche': [],
653+
'cartridge': ['cartridges'],
648654
}
649655

650656
PAIN_SEVERITIES = {
@@ -669,6 +675,8 @@
669675
'eye': [],
670676
'muscle/joint': [],
671677
'muscle': [],
678+
'nerve': [],
679+
'neuropathic': [],
672680
'joint': [],
673681
'throat': [],
674682
'back': [],
@@ -719,9 +727,12 @@
719727
'bladder irritation': [],
720728
'bladder spasm': [],
721729
'bleeding': [],
730+
'blood glucose monitoring': [],
722731
'blood sugar less than': [],
732+
'blood pressure': [],
723733
'bradycardia': [],
724734
'burning with urination': [],
735+
'cholesterol': ['choleserol'],
725736
'chest pain': [],
726737
'cold sore': ['cold sores'],
727738
'cold': [],
@@ -735,6 +746,7 @@
735746
'demand feeding': [],
736747
'depression': [],
737748
'diarrhea': [],
749+
'diabetes': ['type 2 diabetes'],
738750
'difficulty breathing': [],
739751
'discomfort': [],
740752
'dizziness': [],
@@ -763,16 +775,23 @@
763775
'hallucination': [],
764776
'headache': [],
765777
'heartburn': [],
778+
'heart rate': ['heart rates', r'\bhr\b'],
766779
'hiccups': [],
780+
'heart failure': [],
781+
'heart': [],
767782
'hemorrhoids': [],
783+
'hair': [],
768784
'high blood pressure': [],
769785
'high blood sugar': [],
786+
'high cholesterol': ['hyperlipidemia'],
770787
'hives': [],
771788
'hypoglycemia': [],
789+
'hypothyroidism': ['underactive thyroid'],
772790
'incontinence': [],
773791
'indigestion': [],
774792
'infection': [],
775793
'inflammation': [],
794+
'inflammatory bowel disease': [r'\bibd\b'],
776795
'insomnia': [],
777796
'intercourse': [],
778797
'irritation': [],
@@ -782,22 +801,28 @@
782801
'low blood sugar': [],
783802
'low heart rate': [],
784803
'migraine': [],
804+
'mood': [],
785805
'mucositis': [],
786806
'movement disorder': [],
787807
'muscle spasm': [],
788808
'nasal congestion': [],
789809
'nasal dryness': [],
790810
'nausea': [],
791811
'numbness': [],
812+
'opioid dependence': [],
792813
'opioid reversal': [],
793814
'outbreak': [],
815+
'overdose': [],
794816
'palpitations': [],
817+
'panic attack': [],
795818
'perianal irritation': [],
796819
'pharyngitis': [],
820+
'prostate': [],
797821
'rash': [],
798822
'reflux': [],
799823
'respiratory distress': [],
800824
'respiratory depression': [],
825+
'restlessness': [],
801826
'rhinitis': [],
802827
'rigors': [],
803828
'seasonal allergies': [],
@@ -822,14 +847,18 @@
822847
'soreness': [],
823848
'spasm': [],
824849
'stomatitis': [],
850+
'stroke': [],
825851
'swelling': [],
826852
'teething': [],
827853
'thrush': [],
828854
'thyroid': [],
855+
'tick bite': [],
829856
'tremor': ['tremors'],
857+
'ulcerative colitis': [],
830858
'unable to take po': [],
831859
'urge to smoke': [],
832860
'urinary burning': [],
861+
'urinary tract infection': [r'\buti'],
833862
'urinary tract irritation': [],
834863
'urinary tract symptoms': [],
835864
'vertigo': [],

parsers/sig.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class SigParser(Parser):
2424
}
2525
# TODO: make this match_keys assignment more elegant
2626
#match_keys = ['original_sig_text'] + ['sig_text', 'sig_readable'] + method.parsers[0].match_keys + dose.parsers[0].match_keys + strength.parsers[0].match_keys + route.parsers[0].match_keys + frequency.parsers[0].match_keys + when.parsers[0].match_keys + duration.parsers[0].match_keys + indication.parsers[0].match_keys + max.parsers[0].match_keys + additional_info.parsers[0].match_keys
27-
match_keys = ['original_sig_text', 'sig_text', 'sig_readable', 'max_dose_per_day'] + method.parsers[0].match_keys + dose.parsers[0].match_keys + strength.parsers[0].match_keys + route.parsers[0].match_keys + frequency.parsers[0].match_keys + when.parsers[0].match_keys + duration.parsers[0].match_keys + indication.parsers[0].match_keys + max.parsers[0].match_keys + additional_info.parsers[0].match_keys
27+
match_keys = ['sig_text', 'sig_readable', 'max_dose_per_day'] + method.parsers[0].match_keys + dose.parsers[0].match_keys + strength.parsers[0].match_keys + route.parsers[0].match_keys + frequency.parsers[0].match_keys + when.parsers[0].match_keys + duration.parsers[0].match_keys + indication.parsers[0].match_keys + max.parsers[0].match_keys + additional_info.parsers[0].match_keys
2828
parser_type = 'sig'
2929

3030
def get_normalized_sig_text(self, sig_text):
@@ -120,7 +120,7 @@ def get_max_dose_per_day(self, match_dict):
120120

121121
def parse(self, sig_text):
122122
match_dict = dict(self.match_dict)
123-
match_dict['original_sig_text'] = sig_text
123+
#match_dict['original_sig_text'] = sig_text
124124
sig_text = self.get_normalized_sig_text(sig_text)
125125
match_dict['sig_text'] = sig_text
126126
for parser_type, parsers in self.parsers.items():
@@ -267,7 +267,7 @@ def print_progress_bar (iteration, total, prefix = 'progress:', suffix = 'comple
267267
print()
268268

269269
#print(SigParser().infer(ndc='68788640709'))
270-
parsed_sigs = SigParser().parse_sig_csv()
270+
#parsed_sigs = SigParser().parse_sig_csv()
271271
#parsed_sigs = SigParser().parse_validate_sig_csv()
272272
#print(parsed_sigs)
273273

parsers/when.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class WhenParser(Parser):
77
parser_type = 'when'
88
match_keys = ['when', 'when_text_start', 'when_text_end', 'when_text', 'when_readable']
9-
pattern = r'(?P<when_relation>with|\bc\.|\bc|before|\ba|\ba\.|after|\bp|\bp\.|in the|at|every|each|\bq|\bq.|night)(?: each| every)?(?P<when_time>\s?(?:c\b|c\.\b|meal(?:s)? and at bedtime|meal(?:s)?|c\.m\.\b|cm\b|breakfast|c\.d\.\b|cd\b|lunch|c\.v\.\b|cv\b|dinner|morning before breakfast|morning|morn|a\.m\.\b|am\b|evening at bedtime|bedtime|evening|eve|aft(?:ernoon)?|p\.m\.\b|pm\b|night at bedtime|night|hs\b|h\.s\.\b|ly))'
9+
pattern = r'(?P<when_relation>with|\bc\.|\bc|before|\ba|\ba\.|after|\bp|\bp\.|in the|at|every|each|\bq|\bq.|night)(?: each| every)?(?P<when_time>\s?(?:c\b|c\.\b|meal(?:s)? and at bed(?:\s)?time|meal(?:s)?|c\.m\.\b|cm\b|breakfast|c\.d\.\b|cd\b|lunch|c\.v\.\b|cv\b|dinner|morning before breakfast|morning|morn|a\.m\.\b|am\b|evening at bed(?:\s)?time|bed(?:\s)?time|evening|eve|aft(?:ernoon)?|p\.m\.\b|pm\b|night at bed(?:\s)?time|night|hs\b|h\.s\.\b|ly))'
1010
def normalize_match(self, match):
1111
# TODO: normalize before to 'a' and after to 'p', etc
1212
# TODO: normalize meals to 'm', etc

0 commit comments

Comments
 (0)