示例#1
0
 def testLookup(self):
     """Test that a DrugProblemKB instance returns the expected problem 
     lists in the expected order, given a CUI."""
     fields = ('probName', 'patientCount', 'ratio')
     # Manually created & sorted lists of expected problems for the
     # given CUIs from our test data
     C0983887 = [
         drug_problem_kb.problem_relation_factory(
             *map(self.dpkbData[0].get, fields))
     ]
     C0004147 = [
         drug_problem_kb.problem_relation_factory(
             *map(self.dpkbData[2].get, fields)),
         drug_problem_kb.problem_relation_factory(
             *map(self.dpkbData[0].get, fields)),
     ]
     C0065374 = [
         drug_problem_kb.problem_relation_factory(
             *map(self.dpkbData[4].get, fields))
     ]
     dpdict = defaultdict(set)
     fields = ('probName', 'patientCount', 'ratio')
     for dp in self.dpkbData:
         pr = drug_problem_kb.problem_relation_factory(*map(dp.get, fields))
         for cui in dp['cuis']:
             dpdict[cui].add(pr)
     dpkb = drug_problem_kb.DrugProblemKB(dpdict)
     self.assertEqual(dpkb.problem_by_drug_cui('C0983887'), C0983887)
     self.assertEqual(dpkb.problem_by_drug_cui('C0004147'), C0004147)
     self.assertEqual(dpkb.problem_by_drug_cui('C0065374'), C0065374)
示例#2
0
 def testLookup(self):
     """Test that a DrugProblemKB instance returns the expected problem 
     lists in the expected order, given a CUI."""
     fields = ('probName', 'patientCount', 'ratio')
     # Manually created & sorted lists of expected problems for the 
     # given CUIs from our test data
     C0983887 = [drug_problem_kb.problem_relation_factory(*map(self.dpkbData[0].get, fields))]
     C0004147 = [drug_problem_kb.problem_relation_factory(*map(self.dpkbData[2].get, fields)),
                 drug_problem_kb.problem_relation_factory(*map(self.dpkbData[0].get, fields)),]
     C0065374 = [drug_problem_kb.problem_relation_factory(*map(self.dpkbData[4].get, fields))]
     dpdict = defaultdict(set)
     fields = ('probName', 'patientCount', 'ratio')
     for dp in self.dpkbData:
         pr = drug_problem_kb.problem_relation_factory(*map(dp.get, fields))
         for cui in dp['cuis']:
             dpdict[cui].add(pr)
     dpkb = drug_problem_kb.DrugProblemKB(dpdict)
     self.assertEqual(dpkb.problem_by_drug_cui('C0983887'), C0983887)
     self.assertEqual(dpkb.problem_by_drug_cui('C0004147'), C0004147)
     self.assertEqual(dpkb.problem_by_drug_cui('C0065374'), C0065374)
from collections import defaultdict

def display_count(count, dot_threshold=1000, pipe_threshold=10000, 
                  newline_threshold=50000, output_stream=sys.stderr):
    if count % dot_threshold == 0:
        output_stream.write(".")
        output_stream.flush()
    if count % pipe_threshold == 0:
        output_stream.write("|")
        output_stream.flush()
    if count % newline_threshold == 0:
        print >>output_stream, " %d" % count
        output_stream.flush()

src_file = sys.argv[1]
save_file = sys.argv[2]
drug_problem_mapping = defaultdict(set)
print >>sys.stderr, "Reading Drug/Problem data"
infile = csv.DictReader(bz2.BZ2File(src_file, 'r'))
for row in infile:
    cuis, name, patientcount, ratio = row['mcuis'].split('|'), row['problem'], int(row['patientcount']), float(row['ratio'])
    pr = drug_problem_kb.problem_relation_factory(name, patientcount, ratio)
    for cui in cuis:
        drug_problem_mapping[cui].add(pr)
    
print >>sys.stderr

print >>sys.stderr, "Saving drug/problem knowledgebase to", save_file
dpkb = drug_problem_kb.DrugProblemKB(drug_problem_mapping)
pickle.dump(dpkb, bz2.BZ2File(save_file, 'wb'), pickle.HIGHEST_PROTOCOL)
示例#4
0
 def testIdentity(self):
     """Test that the factory constructs only one ProblemRelation instance 
     for each particular tuple of of data."""
     pr1 = drug_problem_kb.problem_relation_factory(*self.stenosis[0])
     pr2 = drug_problem_kb.problem_relation_factory(*self.stenosis[0])
     self.assertTrue(pr1 is pr2)
示例#5
0
 def testConstruction(self):
     """Test that each of our bits of test data can be initialized as a
     ProblemRelation instance."""
     for tpl in self.atenolol + self.naproxen + self.stenosis:
         pr = drug_problem_kb.problem_relation_factory(*tpl)
         self.assertTrue(isinstance(pr, drug_problem_kb.ProblemRelation))
示例#6
0
 def testIdentity(self):
     """Test that the factory constructs only one ProblemRelation instance 
     for each particular tuple of of data."""
     pr1 = drug_problem_kb.problem_relation_factory(*self.stenosis[0])
     pr2 = drug_problem_kb.problem_relation_factory(*self.stenosis[0])
     self.assertTrue(pr1 is pr2)
示例#7
0
 def testConstruction(self):
     """Test that each of our bits of test data can be initialized as a
     ProblemRelation instance."""
     for tpl in self.atenolol + self.naproxen + self.stenosis:
         pr = drug_problem_kb.problem_relation_factory(*tpl)
         self.assertTrue(isinstance(pr, drug_problem_kb.ProblemRelation))
                  newline_threshold=50000,
                  output_stream=sys.stderr):
    if count % dot_threshold == 0:
        output_stream.write(".")
        output_stream.flush()
    if count % pipe_threshold == 0:
        output_stream.write("|")
        output_stream.flush()
    if count % newline_threshold == 0:
        print >> output_stream, " %d" % count
        output_stream.flush()


src_file = sys.argv[1]
save_file = sys.argv[2]
drug_problem_mapping = defaultdict(set)
print >> sys.stderr, "Reading Drug/Problem data"
infile = csv.DictReader(bz2.BZ2File(src_file, 'r'))
for row in infile:
    cuis, name, patientcount, ratio = row['mcuis'].split(
        '|'), row['problem'], int(row['patientcount']), float(row['ratio'])
    pr = drug_problem_kb.problem_relation_factory(name, patientcount, ratio)
    for cui in cuis:
        drug_problem_mapping[cui].add(pr)

print >> sys.stderr

print >> sys.stderr, "Saving drug/problem knowledgebase to", save_file
dpkb = drug_problem_kb.DrugProblemKB(drug_problem_mapping)
pickle.dump(dpkb, bz2.BZ2File(save_file, 'wb'), pickle.HIGHEST_PROTOCOL)
示例#9
0
class TestParsedMedication(unittest.TestCase):
    original = 'Protonix 40 MG Tablet Delayed Release;TAKE 1 TABLET DAILY.; Rx'
    normalized = 'PROTONIX 40 MG TABLET DELAYED RELEASE;TAKE 1 TABLET DAILY.; RX'
    multi_tradenames = 'Naproxen 500 MG Tablet;TAKE 1 TABLET EVERY 12 HOURS AS NEEDED.; Rx'
    original_generic = 'Sertraline 50 MG Tablet;TAKE 1 TABLET DAILY.; RPT'
    name = 'Protonix'
    normalized_name = 'PROTONIX'
    dose = '40'
    normalized_dose = '40'
    units = 'MG'
    normalized_units = 'MG'
    formulation = 'Tablet Delayed Release'
    normalized_formulation = 'TABLET DELAYED RELEASE'
    instructions = 'TAKE 1 TABLET DAILY.; Rx'
    normalized_instructions = 'TAKE 1 TABLET DAILY.; RX'
    normalized_dose = '40 MG*1*1'
    provenance = 'List 42'
    generic_formula = [
        'PANTOPRAZOLE (AS PANTOPRAZOLE SODIUM SESQUIHYDRATE)',
        'PANTOPRAZOLE SODIUM'
    ]
    generic_formula.sort()
    CUIs = ['C0876139']
    tradenames = [
        'C0002800', 'C0591117', 'C0591706', 'C0591843', 'C0591844', 'C0591891',
        'C0592014', 'C0592068', 'C0592182', 'C0593835', 'C0594335', 'C0699095',
        'C0700017', 'C0718343', 'C0721957', 'C0731332', 'C0731333', 'C0875956',
        'C1170025', 'C1186767', 'C1186768', 'C1186779', 'C1631235', 'C1724066',
        'C2343621', 'C2684675', 'C2725144', 'C2911866', 'C2911868', 'C3194766'
    ]
    original_dict = {
        'medication_name': normalized_name,
        'dose': dose,
        'units': units,
        'formulation': normalized_formulation,
        'instructions': normalized_instructions,
        'original_string': original,
        'provenance': provenance,
        'normalized_dose': normalized_dose,
        'frequency': '1',
    }
    drug_names_tobe_normalized = [
        'MetFORMIN HCl', 'Dextromethorphan Hydrobromide'
    ]
    drug_names_normalized = [
        'METFORMIN HYDROCHLORIDE', 'DEXTROMETHORPHAN HYDROBROMIDE'
    ]
    ne_name = 'Protronix 40 MG Tablet Delayed Release;TAKE 1 TABLET DAILY.; Rx'
    ne_dose = 'Protonix 20 MG Tablet Delayed Release;TAKE 1 TABLET DAILY.; Rx'
    ne_units = 'Protonix 20 ml Tablet Delayed Release;TAKE 1 TABLET DAILY.; Rx'
    ne_formulation = 'Protonix 20 ml Capsule;TAKE 1 TABLET DAILY.; Rx'
    ne_instructions = 'Protonix 20 ml Capsule;TAKE 2 TABLETS DAILY.; Rx'
    constructed = medication.ParsedMedication(original, provenance=provenance)
    constructed_mappings = medication.ParsedMedication(original, mappings,
                                                       provenance)
    constructed_multitradenames = medication.ParsedMedication(
        multi_tradenames, mappings)
    problemList = [
        problem_relation_factory(*t) for t in (
            ('Chronic Reflux Esophagitis', 3, 0.750000),
            ('Esophageal Reflux', 9, 0.236842),
        )
    ]

    def test_construct_no_text(self):
        """Test that constructor requires at least one argument."""
        self.assertRaises(TypeError, medication.ParsedMedication)

    def test_c_original_string_equals(self):
        """Test that the original string arg to the constructor becomes the 
        .original_string attribute of the object."""
        self.assertEqual(
            self.constructed.original_string, self.original,
            "ParsedMedication class wasn't properly initialized from constructor."
        )

    def test_cm_original_string_equals(self):
        """Test that the original string arg to the constructor becomes the 
        .original_string attribute of the object when the object is initialized
        with a mappings arg."""
        self.assertEqual(
            self.constructed_mappings.original_string, self.original,
            "ParsedMedication class wasn't properly initialized from constructor."
        )

    def test_c_original_string_readonly(self):
        """Test that the .original_string property is immutable."""
        self.assertRaises(AttributeError, self.constructed.__setattr__,
                          'original_string', 'foo')

    def test_c_normalized_string_equals(self):
        """Test that the original string is normalized as expected."""
        self.assertEqual(
            self.constructed.normalized_string, self.normalized,
            "ParsedMedication class wasn't properly initialized from constructor."
        )

    def test_cm_normalized_string_equals(self):
        """Test that the original string is normalized as expected when the 
        object is initialized with a mappings arg."""
        self.assertEqual(
            self.constructed_mappings.normalized_string, self.normalized,
            "ParsedMedication class wasn't properly initialized from constructor."
        )

    def test_c_normalized_string_readonly(self):
        """Test that the .normalized_string property is immutable."""
        self.assertRaises(AttributeError, self.constructed.__setattr__,
                          'normalized_string', 'foo')

    def test_name_ne(self):
        """Test that a difference in name makes ParsedMedication objects unequal."""
        name_ne = medication.ParsedMedication(self.ne_name, mappings)
        self.assertNotEqual(self.constructed, name_ne)

    def test_dose_ne(self):
        """Test that a difference in dose makes ParsedMedication objects unequal."""
        dose_ne = medication.ParsedMedication(self.ne_dose, mappings)
        self.assertNotEqual(self.constructed, dose_ne)

    def test_units_ne(self):
        """Test that a difference in units makes ParsedMedication objects unequal."""
        units_ne = medication.ParsedMedication(self.ne_units, mappings)
        self.assertNotEqual(self.constructed, units_ne)

    def test_formulation_ne(self):
        """Test that a difference in formulation makes ParsedMedication objects unequal."""
        formulation_ne = medication.ParsedMedication(self.ne_formulation,
                                                     mappings)
        self.assertNotEqual(self.constructed, formulation_ne)

    def test_instructions_ne(self):
        """Test that a difference in instructions makes ParsedMedication objects unequal."""
        instructions_ne = medication.ParsedMedication(self.ne_instructions,
                                                      mappings)
        self.assertNotEqual(self.constructed, instructions_ne)

    def test_name_sort(self):
        """Test that ParsedMedications that differ in name sort in the correct order."""
        orig = medication.ParsedMedication(self.original, mappings)
        orig_generic = medication.ParsedMedication(self.original_generic,
                                                   mappings)
        self.assertLess(orig, orig_generic)
        self.assertGreater(orig_generic, orig)

    def test_formulation_sort(self):
        """Test that ParsedMedications that differ in formulation sort in the correct order."""
        ne_units = medication.ParsedMedication(self.ne_units, mappings)
        ne_formulation = medication.ParsedMedication(self.ne_formulation,
                                                     mappings)
        self.assertLess(ne_formulation, ne_units)
        self.assertGreater(ne_units, ne_formulation)

    def test_normalized_dose_sort(self):
        """Test that ParsedMedications that differ in normalized dose sort in the correct order."""
        ne_dose = medication.ParsedMedication(self.ne_dose, mappings)
        original = medication.ParsedMedication(self.original, mappings)
        self.assertLess(ne_dose, original)
        self.assertGreater(original, ne_dose)

    def test_name_get(self):
        """Test that the .name property has the expected value."""
        self.assertEqual(self.constructed.name, self.normalized_name)

    def test_name_readonly(self):
        """Test that the .name property is immutable."""
        self.assertRaises(AttributeError, self.constructed.__setattr__, 'name',
                          "Dr. Jimson's Pantonic Remedy")

    def test_dose_get(self):
        """Test that the .dose property has the expected value."""
        self.assertEqual(self.constructed.dose, self.dose)

    def test_dose_readonly(self):
        """Test that the .dose property is immutable."""
        self.assertRaises(AttributeError, self.constructed.__setattr__, 'dose',
                          '1')

    def test_units_get(self):
        """Test that the .units property has the expected value."""
        self.assertEqual(self.constructed.units, self.normalized_units)

    def test_units_readonly(self):
        """Test that the .units property is immutable."""
        self.assertRaises(AttributeError, self.constructed.__setattr__,
                          'units', 'bottle')

    def test_formulation_get(self):
        """Test that the .formulation property has the expected value."""
        self.assertEqual(self.constructed.formulation,
                         self.normalized_formulation)

    def test_formulation_readonly(self):
        """Test that the .formulation property is immutable."""
        self.assertRaises(AttributeError, self.constructed.__setattr__,
                          'formulation', 'elixir')

    def test_instructions_get(self):
        """Test that the .instructions property has the expected value."""
        self.assertEqual(self.constructed.instructions,
                         self.normalized_instructions)

    def test_instructions_readonly(self):
        """Test that the .instructions property is immutable."""
        self.assertRaises(AttributeError, self.constructed.__setattr__,
                          'instructions', 'Drink 1 tblsp every 4 hours')

    def test_normalized_dose_get(self):
        """Test that the .normalized_dose property has the expected value."""
        self.assertEqual(self.constructed.normalized_dose,
                         self.normalized_dose)

    def test_normalized_dose_readonly(self):
        """Test that the .normalized_dose property is immutable."""
        self.assertRaises(AttributeError,
                          self.constructed_mappings.__setattr__,
                          'normalized_dose', '1 Tblsp*6*1')

    def test_provenance_get(self):
        """Test that the .provenance property has the expected value."""
        self.assertEqual(self.constructed_mappings.provenance, self.provenance)

    def test_provenance_readonly(self):
        """Test that the .provenance property is immutable."""
        self.assertRaises(AttributeError,
                          self.constructed_mappings.__setattr__, 'provenance',
                          'Lot 49')

    def test_as_dictionary(self):
        """Test that the dictionary representation of the ParsedMedication 
        object contains the expected items."""
        test_dict_set = set(self.original_dict.items())
        obj_dict_set = set(self.constructed.as_dictionary().items())
        test_dict_set.add(('id', self.constructed.as_dictionary()['id']))
        self.assertTrue(test_dict_set <= obj_dict_set)

    @unittest.skipUnless(os.path.isfile(rxnormFname),
                         'missing needed test data from rxnorm.pickle.bz2')
    def test_generic_formula_get(self):
        """Test that the .generic_formula property has the expected value."""
        generic_formula = self.constructed_mappings.generic_formula
        self.assertEqual(set(generic_formula), set(self.generic_formula))

    def test_generic_formula_readonly(self):
        """Test that the .generic_formula property is immutable."""
        self.assertRaises(AttributeError,
                          self.constructed_mappings.__setattr__,
                          'generic_formula', 'Generic Elixir')

    def test_generic_formula_nomappings(self):
        """Test that a MappingContextError is raised when the 
        .generic_formula property of an object initialized without a 
        MappingContext is accessed."""
        self.assertRaises(medication.MappingContextError,
                          self.constructed.__getattribute__, 'generic_formula')

    @unittest.skipUnless(os.path.isfile(rxnormFname),
                         'missing needed test data from rxnorm.pickle.bz2')
    def test_CUIs_get(self):
        """Test that we get the expected CUIs from our test object."""
        CUIs = list(self.constructed_mappings.CUIs)
        self.assertEqual(set(CUIs), set(self.CUIs))

    def test_CUIs_readonly(self):
        """Test that the CUIs property is immutable."""
        self.assertRaises(AttributeError,
                          self.constructed_mappings.__setattr__, 'CUIs',
                          {'C02', 'C01'})

    def test_CUIs_nomappings(self):
        """A ParsedMedication object initialized without CUIs should raise an
        error when the CUIs are accessed."""
        self.assertRaises(medication.MappingContextError,
                          self.constructed.__getattribute__, 'CUIs')

    @unittest.skipUnless(os.path.isfile(rxnormFname),
                         'missing needed test data from rxnorm.pickle.bz2')
    def test_tradenames_get(self):
        """Test that we get the expected tradenames from our test object."""
        tradenames = list(self.constructed_multitradenames.tradenames)
        tradenames.sort()
        self.assertEqual(tradenames, self.tradenames)

    def test_tradenames_readonly(self):
        """Test that the tradenames property is immutable."""
        self.assertRaises(AttributeError,
                          self.constructed_mappings.__setattr__, 'tradenames',
                          {'C02', 'C01'})

    def test_tradenames_nomappings(self):
        """A ParsedMedication object initialized without a MappingContext 
        should raise a MappingContextError when .CUIs is accessed."""
        self.assertRaises(medication.MappingContextError,
                          self.constructed.__getattribute__, 'tradenames')

    @unittest.skipUnless(
        os.path.isfile(drugProbFname),
        'missing needed test data from drug_problem_relations.pickle.bz2')
    def test_problems(self):
        """Test that the ParsedMedication initialized with the mappings has
        the expected problem list."""
        self.assertEqual(self.constructed_mappings.problems, self.problemList)

    def test__normalize_drug_name(self):
        """Test that the ._normalize_drug_name() class method normalizes 
        drug names as expected."""
        normalized_drug_names = []
        for drug_name in self.drug_names_tobe_normalized:
            normalized_drug_name = self.constructed._normalize_drug_name(
                drug_name)
            normalized_drug_names.append(normalized_drug_name)
        self.assertEqual(set(normalized_drug_names),
                         set(self.drug_names_normalized))

    def test_fieldwise_comparison(self):
        """Test that fieldwise comparison of two ParsedMedication objects 
        yields the expected results."""
        desired_results = [
            'UNITS', 'NORMALIZED_DOSE', 'DOSE', 'SIG', 'FORMULATION'
        ]
        pm1 = medication.ParsedMedication(
            'Sertraline 50 MG Tablet;TAKE 1 TABLET DAILY.; RPT', mappings)
        pm2 = medication.ParsedMedication(
            'Zoloft 50 MG Tablet;TAKE 1 TABLET DAILY.; RPT', mappings)
        self.assertEqual(set(pm1.fieldwise_comparison(pm2)),
                         set(desired_results))

    def test_factory_m1(self):
        """Test that a Medication initialized with an unparseable string and 
        a provenance yields the expected results."""
        med_line = "Take 2 aspirin and call me in the morning"
        provenance = "List 2"
        m = medication.make_medication(med_line, provenance=provenance)
        self.assertTrue(isinstance(m, medication.Medication))
        self.assertEqual(m.original_string, med_line)
        self.assertEqual(m.provenance, provenance)

    def test_factory_m2(self):
        """Test that a Medication initialized with an unparseable string and 
        without a provenance yields the expected results."""
        med_line = "James Beam (for medicinal purposes only)"
        provenance = ""
        m = medication.make_medication(med_line)
        self.assertTrue(isinstance(m, medication.Medication))
        self.assertEqual(m.original_string, med_line)
        self.assertEqual(m.provenance, provenance)

    def test_factory_pm1(self):
        """Test that a ParsedMedication initialized with a parseable string 
        and a provenance yields the expected results."""
        provenance = "List 1"
        pm = medication.make_medication(self.original,
                                        provenance=provenance,
                                        mappings=mappings)
        self.assertTrue(isinstance(pm, medication.ParsedMedication))
        self.assertEqual(pm.original_string, self.original)
        self.assertEqual(pm.provenance, provenance)

    def test_factory_pm2(self):
        """Test that a ParsedMedication initialized with a dictionary 
        and a provenance yields the expected results."""
        original = 'Protonix 40 MG Tablet Delayed Release; TAKE 1 TABLET DAILY.; Rx'
        dikt = dict(
            name=self.name,
            units=self.units,
            dose=self.dose,
            formulation=self.formulation,
            instructions=self.instructions,
            original_line=original,
        )
        provenance = "List 3"
        pm = medication.make_medication(dikt,
                                        provenance=provenance,
                                        mappings=mappings)
        self.assertTrue(isinstance(pm, medication.ParsedMedication))
        self.assertEqual(pm.original_string, original)
        self.assertEqual(pm.provenance, provenance)

    def test_factory_pm3(self):
        """Test that a ParsedMedication initialized with a dictionary 
        containing a provenance and with a provenance yields 
        the expected results."""
        dikt = dict(name=self.name,
                    units=self.units,
                    dose=self.dose,
                    formulation=self.formulation,
                    instructions=self.instructions,
                    original_line=self.original)
        provenance = "List 3"
        pm = medication.make_medication(dikt,
                                        provenance=provenance,
                                        mappings=mappings)
        self.assertTrue(isinstance(pm, medication.ParsedMedication))
        self.assertEqual(pm.original_string, self.original)
        self.assertEqual(pm.provenance, provenance)