Changeset 52


Ignore:
Timestamp:
May 18, 2009, 8:14:33 PM (11 years ago)
Author:
pvkouteren
Message:

Adjusted parsers to ParserFactory? / GenericParser? idea. The parsers that didn't output a container object now do.
Hapmap parser doesn't seem complete yet.
RefSeq? is not finished yet.

Location:
parsers
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • parsers/fasta.py

    r7 r52  
     1"""
     2This FastaParser can parse various FASTA files. Note that the definition file in the FASTA file is crucial.
     3According to http://en.wikipedia.org/wiki/Fasta_format#Sequence_identifiers, there are different definition files.
     4Currently supported: dbSNP and SwissProt. More to come soon.
     5@author: Jan Bot
     6@author: Patrick van Kouteren <H.J.W.vanKouteren@student.tudelft.nl>
     7@version: 0.1
     8"""
     9
    110import numpy
    2 
     11import genericparser
    312import container
    413
    5 class fasta:
    6     def __init__(self, file_loc, con, mapper):
    7         self.interesting = mapper.keys()
    8         print self.interesting
    9         self.loc = file_loc
    10         self.con = con
    11         print mapper
    12         self.mapper = mapper
     14class FastaParser(genericparser.GenericParser):
     15    def __init__(self):
     16        self.fileformats = ['fa', 'mpfa', 'fna', 'faa', 'fsa', 'fas', 'fasta']
     17        self.prerequisites = []
     18
     19    def getSupportedFileFormats(self):
     20        return self.fileformats
     21   
     22    def getPrerequisites(self):
     23        return self.prerequisites
    1324
    1425    def flush_record(self, info, sequence):
    15         if(len(info) == len(self.interesting) ):
    16             info.append(sequence)
    17             self.con.append(*info)
     26        if(info is not None and self.interesting is not None):
     27            if (len(info) == len(self.interesting)):
     28                info.append(sequence)
     29                self.con.append(*info)
    1830       
    1931
    20     def parse(self):
     32    def parse(self, file_loc, con = None, mapper= None):
     33        self.loc = file_loc
    2134        self.file = open(self.loc)
     35       
     36        # Set con and mapper regardless if it's None or something else
     37        self.con = con
     38        self.mapper = mapper
     39        if (mapper is not None):
     40            self.interesting = mapper.keys()
     41        else:
     42            self.interesting = None
     43       
    2244        info = []
    2345        sequence = ""
     46        l = 0
    2447        for line in self.file:
     48            l+=1
    2549            if(line.startswith('>')):
    2650                self.flush_record(info, sequence)
     
    3256            elif(len(line.strip()) == 0):
    3357                self.flush_record(info, sequence)
    34                 inf0 = []
     58                info = []
    3559                sequence = ""
    3660        return self.con
    3761               
    3862    def process_info(self, line):
     63        # These three if statements are only executed if no mapper and container are given at the start of parsing
     64        if (self.mapper is None):
     65            # determine mapper
     66            self.mapper = self.get_default_functions(line)
     67            self.interesting = self.mapper.keys()
     68        if (self.con is None):
     69            # determine container
     70            self.con = self.get_default_container(line)
     71        # do the actual work of processing the info.
    3972        fields = line.split('|')
    4073        t = [self.mapper[i](fields[i]) for i in self.interesting]
    4174        return t
    42 
    43 def get_default_dbSNP_container():
     75       
     76    """
     77    Based on a line which starts with '>', we can determine which of the sequence identifiers
     78    (@see: http://en.wikipedia.org/wiki/Fasta_format#Sequence_identifiers) is used in this file
    4479    """
    45     Returns the default Ibidas table format for dbSNP (fasta) data. This table
    46     can then be used to link other data to.
     80    def get_default_container(self, line):
     81        fields = line.split('|')
     82        return {
     83                'gnl' : self.get_default_general_database_container(),
     84                'sp' : self.get_default_swiss_prot_container(),
     85                'gi' : self.get_default_gi_container(line)
     86        }[fields[0]]
     87   
     88    def get_default_functions(self, line):
     89        fields = line.split('|')
     90        return {
     91                'gnl' : self.get_default_general_database_functions(),
     92                'sp' : self.get_default_swiss_prot_functions(),
     93                'gi' : self.get_default_gi_functions(line)
     94        }[fields[0]]
     95   
    4796    """
    48     c = container.table(fieldnames=["rs_id", "position", "length", "class", "sequence"], \
    49         fieldtypes=['str(uint8)', 'str(uint8)', 'str(uint8)', 'int32', 'str(uint8)'], \
    50         modifiable=True)
    51     return c
    52 
    53 def get_dbSNP_snp_types():
     97    Specific containers
    5498    """
    55     Returns a term capable table which holds the information on the different SNP
    56     types found in dbSNP.
    57     See for the specification: ftp://ftp.ncbi.nih.gov/snp/specs/docsum_2005.asn
    58     and: ftp://ftp.ncbi.nih.gov/snp/specs/00readme.txt
    59     FIXME: for now just returns a dict holding the names of the associated types.
     99   
     100    def get_default_general_database_container(self):
     101        """
     102        Returns the default Ibidas table format for dbSNP (fasta) data. This table
     103        can then be used to link other data to.
     104        """
     105        c = container.table(fieldnames=["rs_id", "position", "length", "class", "sequence"], \
     106            fieldtypes=['str(uint8)', 'str(uint8)', 'str(uint8)', 'int32', 'str(uint8)'], \
     107            modifiable=True)
     108        return c
     109   
     110    def get_default_swiss_prot_container(self):
     111        c = container.table(fieldnames=["accession", "id", "sequence"], \
     112                            fieldtypes=['str(uint8)', 'str(uint8)', 'str(uint8)'], \
     113                            modifiable=True)
     114        return c
     115   
     116    def get_default_gi_container(self, line):
     117        fields = line.split("|")
     118        return {
     119                'ref' : self._get_default_refseq_container()
     120        }[fields[2]]
     121   
     122    def _get_default_refseq_container(self):
     123        c = container.table(fieldnames=["id", "accession", "definition", "sequence"], \
     124                            fieldtypes=["str(uint8)", "str(uint8)", "str(uint8)", "str(uint8)"], \
     125                            modifiable=True)
     126        return c
     127   
    60128    """
    61     snp_class = {
    62         1: 'snp',
    63         2: 'in-del',
    64         3: 'heterozygous',
    65         4: 'microsatellite',
    66         5: 'named-locus',
    67         6: 'no-variation',
    68         7: 'mixed',
    69         8: 'multinucleotide-polymorphism'
    70     }
    71     return snp_class
    72 
    73 def get_default_dbSNP_functions():
     129    Specific functions
    74130    """
    75     Creates the parser functions needed to map the input data to the array format
    76     used by Ibidas. They are placed in a dict so the correct function can be
    77     called on a particular column in the input file.
     131   
     132    def get_default_swiss_prot_functions(self):
     133        functions = {}
     134        functions[1] = lambda x: x
     135        functions[2] = lambda x: x.split(" ")[0]
     136        #functions[7] = lambda x: x.split('=')[1]
     137        return functions
     138   
     139    def get_default_general_database_functions(self):
     140        """
     141        Creates the parser functions needed to map the input data to the array format
     142        used by Ibidas. They are placed in a dict so the correct function can be
     143        called on a particular column in the input file.
     144        """
     145        functions = {}
     146        functions[2] = lambda x: x.split()[0]
     147        functions[3] = lambda x: x[4:]
     148        functions[4] = lambda x: x[4:]
     149        return functions
     150   
     151    def get_default_gi_functions(self, line):
     152        fields = line.split("|")
     153        return {
     154                'ref' : self._get_default_refseq_functions()
     155        }[fields[2]]
     156       
     157    """
     158    We would actually like to devide functions[4] in two functions as the organism is defined between square brackets
     159    """ 
     160    def _get_default_refseq_functions(self):
     161        functions = {}
     162        functions[1] = lambda x: x
     163        functions[3] = lambda x: x
     164        functions[4] = lambda x: x
     165        return functions
     166   
    78167    """
    79     functions = {}
    80     functions[2] = lambda x: x.split()[0]
    81     functions[3] = lambda x: x[4:]
    82     functions[4] = lambda x: x[4:]
    83     functions[7] = lambda x: x.split('=')[1]
    84     return functions
     168    Types
     169    """
    85170   
     171    def get_dbSNP_snp_types(self):
     172        """
     173        Returns a term capable table which holds the information on the different SNP
     174        types found in dbSNP.
     175        See for the specification: ftp://ftp.ncbi.nih.gov/snp/specs/docsum_2005.asn
     176        and: ftp://ftp.ncbi.nih.gov/snp/specs/00readme.txt
     177        FIXME: for now just returns a dict holding the names of the associated types.
     178        """
     179        snp_class = {
     180            1: 'snp',
     181            2: 'in-del',
     182            3: 'heterozygous',
     183            4: 'microsatellite',
     184            5: 'named-locus',
     185            6: 'no-variation',
     186            7: 'mixed',
     187            8: 'multinucleotide-polymorphism'
     188        }
     189        return snp_class
  • parsers/gff.py

    r20 r52  
    99from parsers import liner
    1010from parsers import utils
     11import genericparser
    1112
    12 fieldnames = ['seqname', 'source', 'feature', 'start', 'end', 'score', 'strand', \
    13     'frame']
     13fieldnames = ['seqname', 'source', 'feature', 'start', 'end', 'score', 'strand', 'frame']
    1414
    1515#FIXME: strand and frame should be something similar to 'char'
     
    2525}
    2626
    27 class GFFParser:
    28     def __init__(self, filename):
    29         self.filename = filename
     27class GFFParser(genericparser.GenericParser):
     28    def __init__(self):
     29        self.fileformats = ['gff']
     30        self.prerequisites = []
    3031
    31     def parse(self):
     32    def getSupportedFileFormats(self):
     33        return self.fileformats
     34   
     35    def getPrerequisites(self):
     36        return self.prerequisites
     37
     38    def parse(self, filename):
    3239        """Function to be called for the 'real' parsing."""
    3340        #FIXME: For now ignoring the attributes and comments
    3441        fts = [fieldtypes[name] for name in fieldnames]
    3542        mapper = utils.getSimpleMapper(*range(0,len(fieldnames)))
    36         out = liner.parse(self.filename, fieldnames, fts, mapper, sepchar="\t", \
    37             comment=['#'])
     43        out = liner.parse(filename, fieldnames, fts, mapper, sepchar="\t", comment=['#'])
    3844        return out
  • parsers/hapmap.py

    r8 r52  
    22import parsers.liner
    33import parsers.utils
    4 
    5 def getDefaultHapmapLDMapper():
    6     """
    7     Structure of Hapmap file:
    8     Col1: Chromosomal position of marker1
    9     Col2: chromosomal position of marker2
    10     Col3: population code
    11     Col4: rs# for marker1
    12     Col5: rs# for marker2
    13     Col6: Dprime
    14     Col7: R square
    15     Col8: LOD
    16     Col9: fbin ( index based on Col1 )
    17     """
    18     return parsers.utils.getSimpleMapper(0,1,2,3,4,5,6,7,8)
    19 
    20 def getDefaultHapmapLDContainer():
    21     c = container.table(fieldnames=LDFieldNames, fieldtypes=LDFieldTypes, \
    22         modifiable = True)
    23     return c
    24 
    25 def parseHapmapLDFile(file, container, mapper):
    26    
    27     fieldnames = ['pos1', 'pos2', 'population', 'rs_id1', 'rs_id2', 'Dprime', \
    28         'R_square', 'LOD', 'fbin']
    29     fieldtypes = ['int32', 'int32', 'str(uint8)', 'str(uint8)', 'str(uint8)', \
    30         'float64', 'float64', 'float64', 'int32']
    31     return parsers.liner.parse(file, fieldnames, fieldtypes, mapper, sepchar=' ')
    32 
    33 def getDefaultHapmapFreqMapper():
    34     """
    35     Structure of Hapmap file:
    36     rs# chrom pos strand build center protLSID assayLSID panelLSID QC_code
    37     refhom-gt refhom-freq refhom-count het-gt het-freq het-count otherhom-gt
    38     otherhom-freq otherhom-count totalcount
    39     """
    40     return parsers.utils.getSimpleMapper(0, 1, 2, 3, 4, 13, 14, 16, 17, 19)
    41 
    42 def getDefaultHapmapFreqContainer():
    43     pass
    44 
    45 def parseHapmapFreqFile(file, fieldnames, fieldtypes, mapper):
    46     return parsers.liner.parse(file, fieldnames, fieldtypes, mapper, \
    47     sepchar=' ', hasheader=True)
     4import genericparser
    485
    496freqFieldNames = ['rs_id', 'chromosome', 'position', 'strand', 'build', 'center', \
     
    518    'refhom-count', 'het-gt', 'het-freq', 'het-count', 'otherhom-gt', 'otherhom-freq', \
    529    'otherhom-count', 'totalcount']
     10 
    5311freqFieldTypes = ['str(uint8)', 'str(uint8)', 'uint32', 'str(uint8)', 'str(uint8)', \
    5412    'str(uint8)', 'str(uint8)', 'str(uint8)', 'str(uint8)', 'str(uint8)', \
    5513    'str(uint8)', 'float64', 'int32', 'str(uint8)', 'float64', 'int32', 'str(uint8)', \
    5614    'float64', 'int32', 'int32']
    57 
     15   
    5816LDFieldNames = ['pos1', 'pos2', 'population', 'rs_id1', 'rs_id2', 'Dprime', \
    5917    'R_square', 'LOD', 'fbin']
     18
    6019LDFieldTypes = ['int32', 'int32', 'str(uint8)', 'str(uint8)', 'str(uint8)', \
    6120    'float64', 'float64', 'float64', 'int32']
    6221
     22class HapmapParser(genericparser.GenericParser):
     23    def __init__(self):
     24        self.fileformats = ['txt']
     25        self.prerequisites = []
     26
     27    def getSupportedFileFormats(self):
     28        return self.fileformats
     29   
     30    def getPrerequisites(self):
     31        return self.prerequisites
     32       
     33    def getDefaultHapmapLDMapper(self):
     34        """
     35        Structure of Hapmap file:
     36        Col1: Chromosomal position of marker1
     37        Col2: chromosomal position of marker2
     38        Col3: population code
     39        Col4: rs# for marker1
     40        Col5: rs# for marker2
     41        Col6: Dprime
     42        Col7: R square
     43        Col8: LOD
     44        Col9: fbin ( index based on Col1 )
     45        """
     46        return parsers.utils.getSimpleMapper(0,1,2,3,4,5,6,7,8)
     47   
     48    def getDefaultHapmapLDContainer(self):
     49        c = container.table(fieldnames=LDFieldNames, fieldtypes=LDFieldTypes, \
     50            modifiable = True)
     51        return c
     52   
     53    def parseHapmapLDFile(self, file, container, mapper):
     54       
     55        fieldnames = ['pos1', 'pos2', 'population', 'rs_id1', 'rs_id2', 'Dprime', \
     56            'R_square', 'LOD', 'fbin']
     57        fieldtypes = ['int32', 'int32', 'str(uint8)', 'str(uint8)', 'str(uint8)', \
     58            'float64', 'float64', 'float64', 'int32']
     59        return parsers.liner.parse(file, fieldnames, fieldtypes, mapper, sepchar=' ')
     60   
     61    def getDefaultHapmapFreqMapper(self):
     62        """
     63        Structure of Hapmap file:
     64        rs# chrom pos strand build center protLSID assayLSID panelLSID QC_code
     65        refhom-gt refhom-freq refhom-count het-gt het-freq het-count otherhom-gt
     66        otherhom-freq otherhom-count totalcount
     67        """
     68        return parsers.utils.getSimpleMapper(0, 1, 2, 3, 4, 13, 14, 16, 17, 19)
     69   
     70    def getDefaultHapmapFreqContainer(self):
     71        pass
     72   
     73    def parseHapmapFreqFile(file, fieldnames, fieldtypes, mapper):
     74        return parsers.liner.parse(file, fieldnames, fieldtypes, mapper, \
     75        sepchar=' ', hasheader=True)
  • parsers/msigdb.py

    r40 r52  
    1313import xml.sax
    1414import genericparser
     15import parsers.utils
     16
     17fieldnames = ['category_code', 'identifier', 'organism', 'members']
    1518
    1619"""
     
    2427    """
    2528    def __init__(self):
    26         self.fileformats = []
    27         self.fileformats.append("xml")
    28         self.prerequisites = []
    29         self.prerequisites.append("NCBI")
     29        self.fileformats = ['xml']
     30        self.prerequisites = ['NCBI']
    3031        self.parser = xml.sax.make_parser()
    3132        self.handler = MSigDBXMLHandler()
     
    3940        self.parser.parse(filename)
    4041        #print self.handler.elements
    41         return self.handler.result
    42         #return container.table(self.handler.result, None, None, True)
     42        #return self.handler.result
     43        #return container.table(self.handler.result, fieldnames, fieldtypes, True)
     44        return parsers.utils.dictListToContainer(self.handler.result, fieldnames)
    4345   
    4446    def getSupportedFileFormats(self):
     
    9698             parsed = ()
    9799             try:
     100                 """
     101                 Due to the fact that the specification is not obeyed by v2.5 formatted files, it's hard to extract some
     102                 features
     103                 """
     104                 """
    98105                 if (x == "PMID"):
    99                     parsed = getattr(self, '_parse_literature', None)((attributes.getValue(x), attributes.getValue("AUTHORS")))
     106                    #parsed = getattr(self, '_parse_literature', None)((attributes.getValue(x), attributes.getValue("AUTHORS")))
    100107                    func = 'literature'
    101108                    args = (attributes.getValue(x), attributes.getValue("AUTHORS"))
    102                  if (x == "EXTERNAL_DETAILS_URL"):
     109                 elif (x == "EXTERNAL_DETAILS_URL"):
    103110                    func = 'references'
    104111                    args = (attributes.getValue("CONTRIBUTOR_ORG"), attributes.getValue(x))
     
    107114                    args = attributes.getValue(x)
    108115                    #parsed = getattr(self, '_parse_' + x.lower(), None)(attributes.getValue(x))
     116                 """
     117                 
     118                 # Temporary solution for above:
     119                 func = x
     120                 args = attributes.getValue(x)
    109121               
    110122                 parsed = getattr(self, '_parse_' + func.lower(), None)(args)
     123                 
    111124                 if parsed is not None:
    112125                     res[parsed[0]] = parsed[1]
     
    114127                 """ Function not found. Skip this. """
    115128                 pass
     129           
    116130        return res
    117131   
  • parsers/obo.py

    r41 r52  
    4343        file = open(self.filename, 'r')
    4444        rec_type_fields = self.record_types.keys()
    45         print rec_type_fields
     45        #print rec_type_fields
    4646       
    4747        records = []
  • parsers/parserfactory.py

    r41 r52  
    1010"""
    1111
     12import logging
    1213import container
    1314import os, types, sys
     
    2223        self.imported_databases = []
    2324        self.available_parsers = []
     25        #self.available_parsers = self.getAvailableParsers()
    2426        self.parsers_by_format = {}
    2527
     
    4244    """
    4345    def getAvailableParsers(self):
    44        parserdir = sys.path[0] + "/parsers"
    45        classnames = []
    46        parserfiles = []
    47        for subdir, dirs, files in os.walk(parserdir):
    48            for file in files:
    49                if file.endswith(".py") and not file.startswith("__"):
    50                    parserfiles.append(parserdir + "/" + file)
    51        for parserfile in parserfiles:
    52            fileobject = open(parserfile)
    53            content = fileobject.read()
    54            importfound = 0
    55            for l in content.splitlines():
    56                if l.startswith("import"):
     46        parserdir = sys.path[0] + "/parsers"
     47        classnames = []
     48        parserfiles = []
     49        for subdir, dirs, files in os.walk(parserdir):
     50            for file in files:
     51                if file.endswith(".py") and not file.startswith("__"):
     52                    parserfiles.append(parserdir + "/" + file)
     53        for parserfile in parserfiles:
     54            fileobject = open(parserfile)
     55            content = fileobject.read()
     56            importfound = 0
     57            for l in content.splitlines():
     58                if l.startswith("import"):
    5759                   """ If this line contains genericparser, we know that this file is interesting """
    5860                   if l.find("genericparser") > 0:
    5961                       importfound += 1
    60                """
    61                If we:
    62                 * find a class definition
    63                 * have found an import of generic parser
    64                 * find a genericparser argument
    65                Then we know that this parser is a subclass of genericparser 
    66                """
    67                if l.startswith("class") and importfound > 0 and l.find("genericparser") > 0:
     62                """
     63                If we:
     64                 * find a class definition
     65                 * have found an import of generic parser
     66                 * find a genericparser argument
     67                Then we know that this parser is a subclass of genericparser 
     68                """
     69                if l.startswith("class") and importfound > 0 and l.find("genericparser") > 0:
    6870                   import re
    6971                   m = re.split("\W+", l)
     
    7274                   thisfilename = parserfile[parserfile.rfind(u"/")+1:]
    7375                   ppath = "parsers." + thisfilename[:thisfilename.rfind(u".")]+"." + classname
    74                    #print "the full import path will become " + ppath
     76                   #print "the full import path will become " + ppath                       
    7577                   classnames.append(ppath)
    76        return classnames
     78        return classnames
    7779   
    7880    """
     
    179181       
    180182    def findParser(self, file):
    181         parserlist = self.getAvailableParsers()
    182         for parser in parserlist:
    183             p = self._get_func(parser)()
    184             self.available_parsers.append(p)
    185             formats = self.getSupportedFileFormatForParser(p)
    186             for f in formats:
    187                 f = f.lower()
    188                 if not self.parsers_by_format.__contains__(f):
    189                     self.parsers_by_format[f] = []
    190                     self.parsers_by_format[f].append(p)
    191                 else:
    192                     self.parsers_by_format[f].append(p)
     183        if (self.parsers_by_format == {}):
     184            parserlist = self.getAvailableParsers()
     185            for parser in parserlist:
     186                p = self._get_func(parser)()
     187                self.available_parsers.append(p)
     188                formats = self.getSupportedFileFormatForParser(p)
     189                for f in formats:
     190                    f = f.lower()
     191                    if not self.parsers_by_format.__contains__(f):
     192                        self.parsers_by_format[f] = []
     193                        self.parsers_by_format[f].append(p)
     194                    else:
     195                        if not self.parsers_by_format[f].__contains__(p):
     196                            self.parsers_by_format[f].append(p)
    193197        #if len(self.parsers_by_format) > 0:
    194198        #    print "There are parsers for this extension available. The best one matching will be returned."
     
    206210        #print self.parsers_by_format
    207211        # Search for file extension
    208         print "Checking file extension.."
     212        logging.info("Checking file extension..")
    209213        ext = file[file.rfind(u".")+1:].lower()
    210214        if self.parsers_by_format.__contains__(ext):
    211             print "Parsers for extension ." + ext + " found. Attempting to find the best one.."
     215            logging.info("Parsers for extension ." + ext + " found. Attempting to find the best one..")
     216            if (len(self.parsers_by_format[ext]) == 1):
     217                # We have only one parser
     218                return self.parsers_by_format[ext][0]
     219            else:
     220                # There are multiple parsers available
     221                logging.info("Multiple parsers available")
    212222        else:
    213             print "Didn't find a parser for this extension."
     223            logging.info("Didn't find a parser for the extension " + ext)
     224            return None
    214225       
    215226        #print "Best matching parser is: None yet. Function has to be implemented!"
    216         return None
    217227
    218228    """
     
    229239                        parser = self.getParserByModule(prsr)
    230240                    except:
    231                         print "The parser specified is not known. Attempting to find an appropriate one.."
     241                        logging.info("The parser specified is not known. Attempting to find an appropriate one..")
    232242                        parser = self.findParser(file)
    233243                else:
    234                     print "Parser not specified. Attempting to find an appropriate one.."
     244                    logging.info("Parser not specified. Attempting to find an appropriate one..")
    235245                    parser = self.findParser(file)
    236246            else:
     
    238248            if parser is not None:
    239249                plist.append((file, parser))
    240             else:
    241                 print "No appropriate parser found for " + file + " !"
    242                 print "> This file will be skipped."
     250                logging.info("Found the right parser for file " + file)
     251            else:
     252                logging.info("No appropriate parser found for " + file + " !")
     253                logging.info("> This file will be skipped.")
    243254        # sorting to do here!
    244255        list = self.order(plist)
     
    256267        imported_dbs = self.imported_databases
    257268        unsat = []
    258         for file, parser in file_parserlist:
     269        #print file_parserlist
     270        for file,parser in file_parserlist:
    259271            ppre = parser.getPrerequisites()
    260272            # Check if all prerequisites are satisfied
     
    265277            if sat == len(ppre):
    266278                imported_dbs.append("Database name here..")
    267                 result.append((file, parser))
    268             else:
    269                 unsat.append((file, parser))
     279                result.append((file,parser))
     280            else:
     281                unsat.append((file,parser))
    270282        """
    271283        Now process all unsatisfied parsers.
     
    277289        #    for
    278290           
    279         return result
     291        #return result
     292        return file_parserlist
  • parsers/uniprot.py

    r23 r52  
    33http://www.ebi.ac.uk/IPI/UniProtFormat.html
    44"""
     5import genericparser
     6import utils
     7
    58#FIXME: sequence lines (after the first one) are not yet handled correctly.
    69
     
    2427}
    2528
    26 class IPIParser:
    27     def __init__(self, filename):
    28         self.filename = filename
     29class IPIParser(genericparser.GenericParser):
     30    def __init__(self):
     31        self.fileformats = ['dat']
     32        self.prerequisites = ['NCBI']
     33   
     34    def getSupportedFileFormats(self):
     35        return self.fileformats
     36   
     37    def getPrerequisites(self):
     38        return self.prerequisites
    2939
    3040    def _clean_ac(self, lines):
     
    130140        return out
    131141
    132     def parse(self):
     142    def parse(self, filename):
     143        self.filename = filename
    133144        raw_recs = map(self._split_record, self._load_records())
    134145        clean_recs = []
     
    140151            clean['literature'] = self._clean_r(raw['R'])
    141152            clean_recs.append(clean)
    142         return clean_recs
     153        return utils.dictListToContainer(clean_recs, clean.keys())
  • parsers/utils.py

    r40 r52  
    44import parsers.parserfactory
    55import container
     6import re
     7import os
     8import tarfile
     9import bz2
    610
    711"""
     
    1216    def __init__(self):
    1317        self.parserfactory = parsers.parserfactory.ParserFactory()
    14    
     18        # @attention: These should get into the config file soon!
     19        self.tempfolder = "/home/patrick/workspace/Ibidas/test/" # Temp folder to store downloads
     20        self.remove_archives = 0 # Remove archives once decompressed. 0 = no, 1 = yes
    1521   
    1622    def importSources(self, sources):
     23        # testing
     24        #c = Compressor()
     25        #c.decompress(self.tempfolder, self.remove_archives)
     26        #print sources
     27        #self.parseList(sources)
     28
    1729        if isinstance(sources, str):
    1830            # we get a string: this is just one source!
    1931            s = []
    2032            s.append(sources)
    21             self.parseList(s)
    22         else:
    23             self.parseList(sources)
     33            self.importSources(s)
     34        else:
     35            #print "printing sources:"
     36            todo = []
     37            for source in sources:
     38                # check if source is a url
     39                if isinstance(source[0], list):
     40                    url_regex = "((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)"
     41                    base_url = re.compile(url_regex).search(source[0][0]).group(0)
     42                    if base_url is not None:
     43                        d = Downer(base_url, self.tempfolder , source[0][1])
     44                        d.run()
     45                        # Let the compressor decide if things can be decompressed
     46                        c = Compressor()
     47                        c.decompress(self.tempfolder, self.remove_archives)
     48                        unzipped = c.result
     49                        for uz in unzipped:
     50                            todo.append((uz, source[1]))
     51                else:
     52                    todo.append(source)               
     53            self.parseList(todo)
    2454           
    2555    """
     
    3464            for file, parser in file_parser:
    3565                print "About to parse file " + file
    36                 parser.parse(file)
     66                result = parser.parse(file)
     67                print result
    3768            print "Done parsing!"
    3869        else:
     
    5788                raise parserError
    5889    """
    59            
     90   
     91class Compressor:
     92   
     93    def __init__(self):
     94        self.supportedformats = ['zip', 'gz', 'tar', 'bz2']
     95        self.result = []
     96   
     97    def decompress(self, dir_or_files, removefiles_afterwards):
     98       if not isinstance(dir_or_files, list) and os.path.isdir(dir_or_files):
     99            # list the files
     100            fs = os.listdir(dir_or_files)
     101            files = []
     102            if not dir_or_files.endswith("/"):
     103                    dir_or_files += "/"
     104            for file in fs:
     105                for format in self.supportedformats:
     106                    if file.endswith(format):
     107                        files.append(dir_or_files + file)
     108            self.decompress(files, removefiles_afterwards)
     109       elif isinstance(dir_or_files, str):
     110            # just one file
     111            l = []
     112            l.append(dir_or_files)
     113            self.decompress(l, removefiles_afterwards)
     114       elif isinstance(dir_or_files, list):
     115            # list of files
     116            for filename in dir_or_files:
     117                #print "Decompressing " + filename
     118                ext = filename[filename.rfind(u".")+1:].lower()
     119                folder = filename[:filename.rfind(u"/")] + "/"
     120               
     121                resultlist = getattr(self, '_decompress_'+ext, None)(filename)
     122                if isinstance(resultlist, list):
     123                    for r in resultlist:
     124                        self.result.append(r)
     125                elif isinstance(resultlist, str):
     126                    self.result.append(resultlist)
     127               
     128                # If removefiles_afterwards = 1, we remove them
     129                if (removefiles_afterwards == 1):
     130                    os.remove(filename)
     131
     132            if (removefiles_afterwards == 1):
     133                print "Decompressing done. The archives were removed."
     134            else:
     135                print "Decompressing done. The archives are maintained in the temp folder."
     136            # Below refuses to return the result
     137            #return result
     138       
     139    def _decompress_zip(self, file):
     140        import zipfile
     141        result = []
     142        folder = file[:file.rfind(u"/")] + "/"
     143        fileObj = zipfile.ZipFile(file, 'r')
     144        isdir = os.path.isdir
     145        join = os.path.join
     146        norm = os.path.normpath
     147        split = os.path.split
     148                   
     149        for each in fileObj.namelist():
     150            if not each.endswith('/'):
     151                # It's a file
     152                root, name = split(each)
     153                #directory = norm(join("", root))
     154                #print directory
     155                if not isdir(folder):
     156                    os.makedir(folder)
     157                    #print directory
     158                fname = (join(folder, name.replace('.zip', '')))
     159                fileObjOut = open(fname, 'wb')
     160                fileObjOut.write(fileObj.read(each))
     161                fileObjOut.close()
     162                result.append(fname)
     163        return result
     164   
     165    def _decompress_gz(self, filename):
     166        import gzip
     167        result = []
     168        fileObj = gzip.GzipFile(filename, 'rb');
     169        fname = filename.replace('.gz','')
     170        fileObjOut = open(fname, 'wb');
     171        while 1:
     172            lines = fileObj.readline()
     173            if lines == '':
     174                break
     175            fileObjOut.write(lines)
     176        fileObj.close()
     177        fileObjOut.close()
     178        return fname
     179
    60180
    61181class Downer(threading.Thread):
     
    68188    def __init__(self, baseURL, localdir, filenames):
    69189        threading.Thread.__init__(self)
    70         self.baseURL = baseURL
     190        if not baseURL.endswith("/"):
     191            self.baseURL = baseURL + "/"
     192        else:
     193            self.baseURL = baseURL
    71194        self.localdir = localdir
    72195        self.filenames = filenames
    73196
    74197    def run(self):
     198        import os
    75199        for file in self.filenames:
    76200            remote = self.baseURL + file
    77             local = self.localdir + file
    78             print "Downloading: " + file
     201            if not os.path.isdir(self.localdir):
     202                os.mkdir(self.localdir)
     203            if not self.localdir.endswith("/"):
     204                local = self.localdir + "/" +file
     205            else:
     206                local = self.localdir + file
     207            # replace spaces as these can cause problems
     208            local = local.replace(" ", "_")
     209            print "Downloading " + file + " to " + self.localdir
    79210            (location, message) = urllib.urlretrieve(remote, local)
    80211
     
    107238                t.append(defaults[name])
    108239        m.append(tuple(t))
    109     print m
    110     print set(map(len,m))
     240    #print m
     241    #print set(map(len, m))
    111242    cont = container.table(m, fieldnames, fieldtypes, True)
    112243    return cont
Note: See TracChangeset for help on using the changeset viewer.