Example #1
0
def reconciliation_step_3(rec_list_1=[], rec_list_2=[], unparsed_meds_1=[], unparsed_meds_2=[], rec=[], stats={}):
    """Helper function to handle matching by brand names."""
    print "********** RECONCILIATION STEP 3 **********"
    print
    # Unpack the lists produced by the regular expression.findall,
    # and restore missing meds if they couldn't be parsed
    # rec_bn is a MatchResult object with the results of matching by brand name
    rec_bn = match_by_brand_name(rec_list_1, rec_list_2)
    pb1, pb2, bnrec = rec_bn.list1, rec_bn.list2, rec_bn.reconciled
    left1 = pb1 + unparsed_meds_1
    left2 = pb2 + unparsed_meds_2
    print "List 1 after brand name matching=\n", '\n'.join([str(x) for x in left1])
    print
    print "List 2 after brand name matching=\n", '\n'.join([str(x) for x in left2])
    print
    print "Reconciled after brand name matching=\n", '\n'.join([str(x) for x in bnrec])
    print
    if stats is not None:
        stats['reconciled_brand_name'] = len(bnrec)
    already_reconciled = [x for x in bnrec] + rec
    print "All reconciled=\n", '\n'.join([str(x) for x in already_reconciled])
    print "**********     END OF STEP 3     **********"
    return dict(
        pb1=pb1,
        pb2=pb2,
        unparsed_meds_1=unparsed_meds_1,
        unparsed_meds_2=unparsed_meds_2,
        already_reconciled=already_reconciled,
        stats=stats
    )
Example #2
0
def reconciliation_step_2(rec_list_1=[], rec_list_2=[], rec=[], stats={}):
    """Helper function to handle matching by brand names."""
    print "********** RECONCILIATION STEP 2 **********"
    print
    # Separate parsed and unparsed medications
    parsed_meds_1, unparsed_meds_1 = separate_parsed_from_unparsed(rec_list_1)
    parsed_meds_2, unparsed_meds_2 = separate_parsed_from_unparsed(rec_list_2)
    # Unpack the lists produced by the regular expression.findall,
    # and restore missing meds if they couldn't be parsed    
    print
    # rec_bn is a MatchResult object with the results of matching by brand name
    rec_bn = match_by_brand_name(parsed_meds_1, parsed_meds_2)
    pb1, pb2, bnrec = rec_bn.list1, rec_bn.list2, rec_bn.reconciled
    left1 = pb1 + unparsed_meds_1
    left2 = pb2 + unparsed_meds_2
    print "List 1 after brand name matching=\n", '\n'.join([str(x) for x in left1])
    print
    print "List 2 after brand name matching=\n", '\n'.join([str(x) for x in left2])
    print
    print "Reconciled after brand name matching=\n", '\n'.join([str(x) for x in bnrec])
    print 
    if stats is not None:
        stats['reconciled_brand_name'] = len(bnrec)
    already_reconciled = [x for x in bnrec] + rec.reconciled
    print "All reconciled=\n", '\n'.join([str(x) for x in already_reconciled])
    print "**********     END OF STEP 2     **********"
    return dict(
      pb1=pb1,
      pb2=pb2,
      unparsed_meds_1=unparsed_meds_1,
      unparsed_meds_2=unparsed_meds_2,
      already_reconciled=already_reconciled,
      stats=stats
    )
Example #3
0
class TestFunctions(unittest.TestCase):
    """A set of unit tests to exercise the functions in the 'match' module. 
    """
    medString1 = 'Lisinopril 5 MG Tablet;TAKE  TABLET TWICE DAILY; Rx'
    pMed1 = ParsedMedication(medString1, mappings)
    pMed1CUIs = set(['C0065374'])
    pMed1Tradenames = [
        'C0591228', 'C0591229', 'C0678140', 'C0701176', 'C0722805', 'C1602677',
        'C2368718', 'C2368722', 'C2368725'
    ]
    medString2 = 'Pramipexole 0.5 MG Tablet;TAKE 1 TABLET 3 TIMES DAILY.; Rx'
    pMed2 = ParsedMedication(medString2, mappings)
    pMed2CUIs = set(['C0074710'])
    pMed2Tradenames = ['C0721754']
    medString2a = 'PRAMIPEXOLE 0.5 MG TABLET;take 1 tablet 3 times daily.; rx'
    pMed2a = ParsedMedication(medString2a, mappings)
    pMed2aCUIs = set(['C0074710'])
    pMed2aTradenames = ['C0721754']
    medString2b = 'Mirapex 0.5 MG Tablet;TAKE 1 TABLET 3 TIMES DAILY.; Rx'
    pMed2b = ParsedMedication(medString2b, mappings)
    pMed2bCUIs = set(['C0721754'])
    pMed2bTradenames = []
    medString3 = 'Warfarin Sodium 2.5 MG Tablet;TAKE AS DIRECTED.; Rx'
    pMed3 = ParsedMedication(medString3, mappings)
    pMed3CUIs = set(['C0376218'])
    pMed3Tradenames = []
    medString4 = 'Protonix 40 MG Tablet Delayed Release;TAKE 1 TABLET DAILY.; Rx'
    pMed4 = ParsedMedication(medString4, mappings)
    medString5 = 'Pantoprazole Sodium 40 MG Tablet Delayed Release;TAKE 1 TABLET DAILY.; Rx'
    pMed5 = ParsedMedication(medString5, mappings)
    medString6 = 'Paroxetine 20 MG Tablet; TAKE 1 TABLET DAILY.; Rx'
    pMed6 = ParsedMedication(medString6, mappings)
    medString7 = 'Sertraline 50 MG Tablet;TAKE 1 TABLET BY MOUTH EVERY DAY; Rx'
    pMed7 = ParsedMedication(medString7, mappings)
    medString8 = 'Razadyne 16 MG Capsule Extended Release 24 Hour;TAKE 1 CAPSULE DAILY IN THE MORNING take with meal daily; Rx.'
    pMed8 = ParsedMedication(medString8, mappings)
    medString9 = 'Cyclandelate 16 MG Capsule Extended Release 24 Hour;TAKE 1 CAPSULE DAILY IN THE MORNING take with meal daily; Rx.'
    pMed9 = ParsedMedication(medString9, mappings)
    medString10 = 'docosahexaenoic acid 200 mg capsules; one cap BID'
    pMed10 = ParsedMedication(medString10, mappings)
    medString11 = 'Exelon 4.6 MG/24HR Transdermal Patch 24 Hour;APPLY 1 PATCH DAILY AS DIRECTED.; Rx'
    pMed11 = ParsedMedication(medString11, mappings)
    list1 = [pMed1, pMed2]
    list1rev = [pMed2, pMed1]
    list2 = [pMed2a, pMed3]
    list2rev = [pMed3, pMed2a]
    list3 = [pMed2b, pMed3]
    list3rev = [pMed3, pMed2b]
    medication_list_test_CUIs = [
        pMed1CUIs, pMed2CUIs, pMed2aCUIs, pMed3CUIs, pMed2bCUIs, pMed3CUIs
    ]
    medication_list_test_tradenames = [
        pMed1Tradenames, pMed2Tradenames, pMed2aTradenames, pMed3Tradenames,
        pMed2bTradenames, pMed3Tradenames
    ]
    test_objects = None
    if test_match_objects:
        test_objects = test_match_objects['TestFunctions']
    matched_by_strings = match.match_by_strings(list1, list2)
    matched_by_strings_rev = match.match_by_strings(list1rev, list2rev)
    if mappings:
        matched_by_brand_name1 = match.match_by_brand_name(list1, list3)
        matched_by_brand_name1_rev = match.match_by_brand_name(
            list1rev, list3rev)
        matched_by_brand_name2 = match.match_by_brand_name(list3, list1)
        matched_by_ingredients_above = match.match_by_ingredients(
            [pMed4], [pMed5], min_match_threshold=0.6)
        matched_by_ingredients_below = match.match_by_ingredients(
            [pMed4], [pMed5], min_match_threshold=0.7)
        matched_by_ingredients_rev_above = match.match_by_ingredients(
            [pMed5], [pMed4], min_match_threshold=0.6)
        matched_by_ingredients_rev_below = match.match_by_ingredients(
            [pMed5], [pMed4], min_match_threshold=0.7)
        if mappings.treatment:
            matched_by_treatment_above = match.match_by_treatment(
                [pMed6], [pMed7], mappings, match_acceptance_threshold=0.3)
            matched_by_treatment_below = match.match_by_treatment([pMed6],
                                                                  [pMed7],
                                                                  mappings)
            matched_by_treatment_05_yes = match.match_by_treatment(
                [pMed8], [pMed9], mappings, match_acceptance_threshold=0.5)
            matched_by_treatment_05_no = match.match_by_treatment(
                [pMed8], [pMed9], mappings, match_acceptance_threshold=0.51)
            matched_by_treatment_04_yes = match.match_by_treatment(
                [pMed10], [pMed11], mappings, match_acceptance_threshold=0.4)
            matched_by_treatment_04_no = match.match_by_treatment(
                [pMed10], [pMed11], mappings, match_acceptance_threshold=0.43)
    # Use the demo lists for testing; this code was previously  in TestMatchResult
    demo_list_1 = [
        pm for pm in [
            make_medication(x, mappings, "List 1")
            for x in constants.demo_list_1
        ] if isinstance(pm, ParsedMedication)
    ]
    demo_list_2 = [
        pm for pm in [
            make_medication(x, mappings, "List 2")
            for x in constants.demo_list_2
        ] if isinstance(pm, ParsedMedication)
    ]
    demo_matched_by_strings = match.match_by_strings(demo_list_1, demo_list_2)
    demo_matched_by_strings_rev = match.match_by_strings(
        demo_list_2, demo_list_1)
    if mappings:
        demo_matched_by_brand_name = match.match_by_brand_name(
            demo_list_1, demo_list_2)
        demo_matched_by_brand_name_rev = match.match_by_brand_name(
            demo_list_2, demo_list_1)
        demo_matched_by_ingredients = match.match_by_ingredients(
            demo_list_1, demo_list_2)
        demo_matched_by_ingredients_rev = match.match_by_ingredients(
            demo_list_2, demo_list_1)

    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_strings(self):
        "Test that the MatchResult from a by-string match contains the lists we expect."
        self.assertEqual(self.matched_by_strings,
                         self.test_objects['matched_by_strings'])

    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_strings_rev(self):
        """Test that the MatchResult from a by-string match is order-independent
        with respect to the order the medication lists are passed in."""
        self.assertEqual(self.matched_by_strings_rev,
                         self.test_objects['matched_by_strings_rev'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    def test_medication_list_CUIs(self):
        "Test the operation of match.medication_list_CUIs()"
        cuis = match.medication_list_CUIs(self.list1 + self.list2 + self.list3)
        self.assertEqual(cuis, self.medication_list_test_CUIs)

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_medication_list_tradenames(self):
        "Test the operation of match.medication_list_tradenames()"
        tradenames = match.medication_list_tradenames(self.list1 + self.list2 +
                                                      self.list3)
        self.assertEqual(tradenames, self.medication_list_test_tradenames)

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_brand_name1(self):
        """Test that the MatchResult from a by-brand-name match contains the 
        lists we expect."""
        self.assertEqual(self.matched_by_brand_name1,
                         self.test_objects['matched_by_brand_name1'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_brand_name1_rev(self):
        """Test that the MatchResult from a by-brand-name match is order-independent
        with respect to the order the medication lists are passed in."""
        self.assertEqual(self.matched_by_brand_name1_rev,
                         self.test_objects['matched_by_brand_name1_rev'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_brand_name2(self):
        """Test that the MatchResult from a by-brand-name match contains the
        lists we expect."""
        self.assertEqual(self.matched_by_brand_name2,
                         self.test_objects['matched_by_brand_name2'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_ingredients_above(self):
        """Test reconcilation of medications by treatment intent that should
        match at a threshold of 0.6."""
        self.assertEqual(self.matched_by_ingredients_above,
                         self.test_objects['matched_by_ingredients_above'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_ingredients_below(self):
        """Test reconcilation of medications by treatment intent that should
        not match at a threshold of 0.7."""
        self.assertEqual(self.matched_by_ingredients_below,
                         self.test_objects['matched_by_ingredients_below'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_ingredients_rev_above(self):
        """Test order independence of the reconcilation of medications by 
        treatment intent that should match at a threshold of 0.6."""
        self.assertEqual(self.matched_by_ingredients_rev_above,
                         self.test_objects['matched_by_ingredients_rev_above'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_match_by_ingredients_rev_below(self):
        """Test order independence of the reconcilation of medications by 
        treatment intent that should not match at a threshold of 0.7."""
        self.assertEqual(self.matched_by_ingredients_rev_below,
                         self.test_objects['matched_by_ingredients_rev_below'])

    @unittest.skipUnless(test_objects, 'missing test_objects data')
    def test_demo_match_by_strings(self):
        """Use demo lists to test matching by strings."""
        self.assertEqual(self.demo_matched_by_strings,
                         self.test_objects['demo_matched_by_strings'])

    @unittest.skipUnless(test_objects, 'missing test_objects data')
    def test_demo_match_by_strings_rev(self):
        """Use demo lists to test order independence of matching by strings."""
        self.assertEqual(self.demo_matched_by_strings_rev,
                         self.test_objects['demo_matched_by_strings_rev'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(mappings and test_objects,
                         'missing MappingContext with RXNORM data')
    def test_demo_match_by_brand_name(self):
        """Use demo lists to test matching by brand names."""
        self.assertEqual(self.demo_matched_by_brand_name,
                         self.test_objects['demo_matched_by_brand_name'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(mappings and test_objects,
                         'missing MappingContext with RXNORM data')
    def test_demo_match_by_brand_name_rev(self):
        """Use demo lists to test order independence of matching by brand names."""
        self.assertEqual(self.demo_matched_by_brand_name_rev,
                         self.test_objects['demo_matched_by_brand_name_rev'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(mappings and test_objects,
                         'missing MappingContext with RXNORM data')
    def test_demo_match_by_ingredients_list(self):
        """Use demo lists to test matching by ingredients."""
        self.assertEqual(self.demo_matched_by_ingredients,
                         self.test_objects['demo_matched_by_ingredients'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(test_objects, 'missing test_match data')
    def test_demo_match_by_ingredients_list_rev(self):
        """Use demo lists to test order independence of matching by ingredients."""
        self.assertEqual(self.demo_matched_by_ingredients_rev,
                         self.test_objects['demo_matched_by_ingredients_rev'])

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(mappings and mappings.treatment,
                         'MappingContext lacks treatment data')
    def test_match_by_treatment_above(self):
        """These two medications should match by treatment if the 
        match_acceptance_threshold is set to 0.3; note that this
        behavior may change as the underlying 'treats' data change."""
        self.assertEqual(len(self.matched_by_treatment_above.reconciled), 1)

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(mappings and mappings.treatment,
                         'MappingContext lacks treatment data')
    def test_match_by_treatment_below(self):
        """These two medications should not match by treatment if the
        match_acceptance_threshold is set to default (0.5); note that this
        behavior may change as the underlying 'treats' data change."""
        self.assertEqual(len(self.matched_by_treatment_below.reconciled), 0)

    @unittest.skipUnless(mappings, 'missing MappingContext with RXNORM data')
    @unittest.skipUnless(mappings and mappings.treatment,
                         'MappingContext lacks treatment data')
    def test_match_by_treatment_varies(self):
        """Test matching by treatment intent, varying thresholds to induce
        matches and non-matches on the same two sets of medication lists.
        """
        self.assertEqual(len(self.matched_by_treatment_05_yes.reconciled), 1)
        self.assertEqual(len(self.matched_by_treatment_05_no.reconciled), 0)
        self.assertEqual(len(self.matched_by_treatment_04_yes.reconciled), 1)
        self.assertEqual(len(self.matched_by_treatment_04_no.reconciled), 0)