Search code examples
pythonparsingpubmed

How to parse pure MEDLINE format file


I need to process the MEDLINE file with the following structure:

PMID- 1
OWN - NLM
STAT- MEDLINE
DCOM- 20121113
TI  - Formate assay in body fluids: application in methanol poisoning.

PMID- 2
OWN - NLM
STAT- MEDLINE
DCOM- 20121113
TI  - Delineation of the intimate details of the backbone conformation of pyridine
      nucleotide coenzymes in aqueous solution.

PMID- 21
OWN - NLM
STAT- MEDLINE
DCOM- 20121113
TI  - [Biochemical studies on camomile components/III. In vitro studies about the
      antipeptic activity of (--)-alpha-bisabolol (author's transl)].
AB  - (--)-alpha-Bisabolol has a primary antipeptic action depending on dosage, which
      is not caused by an alteration of the pH-value. The proteolytic activity of
      pepsin is reduced by 50 percent through addition of bisabolol in the ratio of
      1/0.5. The antipeptic action of bisabolol only occurs in case of direct contact.
      In case of a previous contact with the substrate, the inhibiting effect is lost.

The main task is to print lines belonging to PMID, TI, and AB fields only. However, I started with the script pasted below.

Question: Don't know why med.records object is empty at the end of processing? Any idea is appreciated.

import re

class Medline:
    """ MEDLINE file structure """
    def __init__(self, in_file=None):
        """ Initialize and parse input """
        self.records = []
        if in_file:
            self.parse(in_file)

    def parse(self, in_file):
        """ Parse input file """
        self.current_tag = None
        self.current_record = None
        prog = re.compile("^(....)- (.*)")
        lines = []
        # Skip blank lines
        for line in in_file:
            line = line.rstrip()
            if line == "":
                continue
            if not line.startswith("      "):
                match = prog.match(line)
                if match:
                    tag = match.groups()[0]
                    field = match.groups()[1]
                    self.process_field(tag, field)

    def process_field(self, tag, field):
        """ Process MEDLINE file field """
        if tag == "PMID":
            self.current_record = {tag: field}

def main():
    """ Test the code """
    import pprint
    with open("medline_file.txt", "rt") as medline_file:
        med = Medline(medline_file)
        pp = pprint.PrettyPrinter()
        pp.pprint(med.records)

if __name__ == "__main__":
    main()

Solution

  • It's a typo.

    You save your tag and field in process_field(self, tag, field) in self.current_record.

    self.current_record = {tag: field}
    

    But later on you don't do anything. And in main you print the field records:

    pp.pprint(med.records)
    

    Which you never append anything into it. So of course it would be empty.

    One solution would be:

    def process_field(self, tag, field):
        """ Process MEDLINE file field """
        if tag == "PMID":
            self.records.append({tag: field})
    

    Which would generate the output:

    [{'PMID': '1'}, {'PMID': '2'}, {'PMID': '21'}]
    

    And in addition: You say the field AB is important. Don't forget because you have this line: if not line.startswith(" "): only the first line of AB will saved as tag (for example: AB - (--)-alpha-Bisabolol has a primary antipeptic action depending on dosage, which )and all the other lines are filtered.