Changeset 1347:dd168923331f in orange-bioinformatics


Ignore:
Timestamp:
03/14/11 15:45:08 (3 years ago)
Author:
ales_erjavec <ales.erjavec@…>
Branch:
default
Convert:
8df185dbcf4d636279537ae981bb168c526610ce
Message:

Added some docstrings, added results parsing in the module level functions.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • doc/modules/obiArrayExpress-test.py

    r1345 r1347  
    11import obiArrayExpress 
     2from pprint import pprint 
    23 
    34# test the gene_atlas_summary 
    4 from pprint import pprint 
    55summary = obiArrayExpress.get_atlas_summary(["Kalrn", "Ptprd", "Mbp", "Cyfip2"], "Mus musculus") 
    66pprint(summary) 
    77 
     8# test query_atlas_simple 
     9results = obiArrayExpress.query_atlas_simple(genes=["Kalrn", "Ptprd", "Mbp", "Cyfip2"], organism="Mus musculus", regulation="up", condition="brain") 
     10pprint(results) 
     11 
    812# test Atlas Conditions 
    9  
    1013gene_cond1 = obiArrayExpress.AtlasConditionGeneProperty("Goterm", "Is", "translation") 
    1114gene_cond2 = obiArrayExpress.AtlasConditionGeneProperty("Disease", "Is", "cancer") 
     
    1316 
    1417conditions = obiArrayExpress.AtlasConditionList([gene_cond1, gene_cond2, org_cond]) 
    15 results = obiArrayExpress.query_atlas(conditions, format="json") 
    16 import json 
    17 results = json.load(results) 
     18results = obiArrayExpress.query_atlas(conditions) 
    1819pprint(results) 
    1920 
    2021# test ArrayExpress experiments, files query 
    2122 
    22 #from xml.dom.minidom import parse 
    23 from json import load as parse 
    24 results = parse(obiArrayExpress.query_experiments(accession="E-MEXP-31", format="json")) 
     23results = obiArrayExpress.query_experiments(accession="E-MEXP-31") 
    2524pprint(results) 
    2625 
    27 results = parse(obiArrayExpress.query_experiments(species="Homo sapines", expdesign="dose+response", ef="CellType", format="json")) 
     26results = obiArrayExpress.query_experiments(species="Homo sapines", expdesign="dose+response", ef="CellType") 
    2827pprint(results) 
    2928 
     29results = obiArrayExpress.query_experiments(species="Homo sapiens", gxa=True, assaycount=(1, 5), miamescore=(3, 5)) 
     30pprint(results) 
    3031 
    31  
     32results = obiArrayExpress.query_files(species="Mus musculus", gxa=True, keywords=["lung", "cancer"], miamescore=(3, 5), format="xml") 
     33print results 
  • obiArrayExpress.py

    r1345 r1347  
    99    >>> import obiArrayExpress 
    1010    >>> obiArrayExpress.query_experiments(accession='E-MEXP-31') 
    11     <addinfourl at ... 
    12      
    13      
    14      
     11    {u'experiments': ... 
     12     
     13    >>> obiArrayExpress.query_files(accession='E-MEXP-32', format="xml") 
     14    XMLNode(... 
     15    
     16.. note: Currently querying ArrayExpress files only works with the xml format. 
     17  
    1518""" 
    1619 
     
    2225import posixpath 
    2326import shelve 
     27import json 
    2428from collections import defaultdict 
    2529 
     30parse_json = json.load 
     31 
     32def parse_xml(stream): 
     33    #TODO: parse stream, return the same structure as parse_json             
     34    from Orange.misc.xml import parse 
     35    tree = parse(stream) 
     36    return tree 
     37     
     38#    raise NotImplementedError() 
     39 
     40 
     41# All searchable fields of ArrayExpress (see query_experiments docstring 
     42# for a description of the fields) 
    2643ARRAYEXPRESS_FIELDS = \ 
    27     ["accession", 
     44    ["keywords", 
     45     "accession", 
    2846     "array", 
    2947     "ef", 
     
    3553     "sa", 
    3654     "species", 
     55     "expandefo", 
     56     "directsub", 
     57     "assaycount", 
     58     "efcount", 
     59     "samplecount", 
     60     "sacount", 
     61     "rawcount", 
     62     "fgemcount", 
     63     "miamescore", 
     64     "date", 
     65     "wholewords", 
    3766    ] 
    3867 
    3968class ArrayExpressConnection(object): 
    40     """ A connection to the ArrayExpress database with query caching 
     69    """ A connection to the ArrayExpress database with query caching. 
    4170    """ 
    4271     
     
    5382    _ARGS_ORDER = ["keywords", "species", "array"] 
    5483     
    55     def __init__(self, address=None, cache=None, timeout=30): 
     84    def __init__(self, address=None, cache=None, timeout=30, 
     85                 username=None, password=None): 
     86        """ Initialize the connection object. 
     87         
     88        :param address: address of the ArrayExpress API 
     89        :param cache: a dict like object to use for caching 
     90        :param timeout: timeout for the socket connection 
     91         
     92        .. todo: implement user login (see Accessing Private Data in API docs) 
     93         
     94        """ 
    5695        self.address = address if address is not None else self.DEFAULT_ADDRESS 
    5796        self.cache = cache if cache is not None else self.DEFAULT_CACHE 
     
    5998         
    6099    def format_query(self, **kwargs): 
     100        """ Format the query arguments. 
     101         
     102        Example:: 
     103            >>> conn.format_query(gxa=True, efcount=(1, 5)) 
     104            'efcount=[1 TO 5]&gxa=true' 
     105             
     106        """ 
     107        # Formaters: 
     108        def format_default(val): 
     109            if isinstance(val, basestring): 
     110                return val 
     111            else: 
     112                return "+".join(val) 
    61113        def format_species(val): 
    62114            return '"%s"' % val.lower() 
    63         # TODO: range values (e.g. [1 TO 2]), handle AND, OR, +, check for valid keys 
     115        def format_gxa(val): 
     116            if val: 
     117                return "true" 
     118            else: 
     119                raise ValueError("gxa={0}".format(val)) 
     120        def format_expandefo(val): 
     121            if val: 
     122                return "on" 
     123            else: 
     124                raise ValueError("expandefo={0}".format(val)) 
     125        def format_true_false(val): 
     126            return "true" if val else "false" 
     127        def format_interval(val): 
     128            if isinstance(val, tuple): 
     129                return "[{0} TO {1}]".format(*val) 
     130            else: 
     131                raise ValueError("Must be an interval argument (min, max)!") 
     132        def format_date(val): 
     133            return val 
     134        def format_wholewords(val): 
     135            if val: 
     136                return "on" 
     137            else: 
     138                raise ValueError("wholewords={0}".format(val)) 
     139         
    64140        formaters = {"species": format_species, 
     141                     "gxa": format_gxa, 
     142                     "expandefo": format_expandefo, 
     143                     "directsub": format_true_false, 
     144                     "assaycount": format_interval, 
     145                     "efcount": format_interval, 
     146                     "samplecount": format_interval, 
     147                     "sacount": format_interval, 
     148                     "rawcount": format_interval, 
     149                     "fgemcount": format_interval, 
     150                     "miamescore": format_interval, 
     151                     "date": format_date, 
     152                     "wholewords": format_wholewords, 
    65153                     } 
    66154        parts = [] 
     
    68156        ordered = sorted(arg_items, key=lambda arg: self._ARGS_ORDER.index(arg[0]) \ 
    69157                         if arg[0] in self._ARGS_ORDER else 100) 
     158         
    70159        for key, value in kwargs.iteritems(): 
    71             fmt = formaters.get("key", lambda val: val) 
    72             value = fmt(value) 
    73             parts.append("{0}={1}".format(key, value))  
     160            if key == "format": 
     161                continue # format is handled in query_url 
     162            if key not in ARRAYEXPRESS_FIELDS: 
     163                raise ValueError("Invalid argument name: '{0}'".format(key)) 
     164            if value is not None and value != []: 
     165                fmt = formaters.get(key, format_default) 
     166                value = fmt(value) 
     167                parts.append("{0}={1}".format(key, value)) 
     168                  
    74169        return "&".join(parts) 
    75170         
    76171    def query_url(self, what="experiments", **kwargs): 
    77         """ Return a formated query url for the calls arguments 
     172        """ Return a formated query URL for the query arguments 
    78173         
    79174        Example:: 
    80175            >>> conn.query_url(accession="E-MEXP-31") 
    81             'http://www.ebi.ac.uk/arrayexpress/xml/v2/experiments?accession=E-MEXP-31' 
     176            'http://www.ebi.ac.uk/arrayexpress/json/v2/experiments?accession=E-MEXP-31' 
    82177             
    83178        """ 
     
    85180        url = posixpath.join(self.address, what) 
    86181        url = url.format(format=kwargs.get("format", self.DEFAULT_FORMAT)) 
    87         url = url + "?" + query 
     182        url = url + ("?" + query if query else "") 
    88183#        print url 
    89184        url = url.replace(" ", "%20") 
     
    101196     
    102197    def query_experiment(self, **kwargs): 
     198        """ Return an open stream to the experiments query results. 
     199         
     200        .. note: This member function takes the same arguments as the module 
     201                 level query_experiemnts function. 
     202           
     203        """ 
    103204        url = self.query_url_experiments(**kwargs) 
    104205        stream = urllib2.urlopen(url, timeout=self.timeout) 
    105         #  TODO: check stream for errors   
    106206        return stream 
    107207     
    108208    def query_files(self, **kwargs): 
     209        """ Return an open stream to the files query results. 
     210         
     211        .. note: This member function takes the same arguments as the module 
     212                 level query_files function. 
     213        """ 
    109214        url = self.query_url_files(**kwargs) 
    110215        stream = urllib2.urlopen(url, timeout=self.timeout) 
    111         #  TODO: check stream for errors   
    112216        return stream 
    113217     
     
    129233        """ 
    130234        from Orange.misc.xml import parse  
    131         files = parse(self.query_files(accession=accession)) 
     235        files = parse(self.query_files(accession=accession), format="xml") 
    132236        files = list(files.elements("file")) 
    133237        for file in files: 
     
    139243     
    140244     
    141 def query_experiments(**kwargs): 
     245def query_experiments(keywords=None, accession=None, array=None, ef=None, 
     246                      efv=None, expdesign=None, exptype=None, 
     247                      gxa=None, pmid=None, sa=None, species=None, 
     248                      expandefo=None, directsub=None, assaycount=None, 
     249                      efcount=None, samplecount=None, rawcount=None, 
     250                      fgemcount=None, miamescore=None, date=None,  
     251                      format="json", wholewords=None, connection=None): 
    142252    """ Query Array Express experiments. 
    143253     
     254    :param keywords: A list of keywords to search (e.g. ['gliobastoma'] 
     255    :param accession: Search by experiment accession (e.g. 'E-MEXP-31') 
     256    :param array: Search by array design name or accession (e.g. 'A-AFFY-33') 
     257    :param ef: Experimental factor (names of main variables of experiments) 
     258    :param efv: Experimental factor value (Has EFO expansion) 
     259    :param expdesign: Experiment design type. (e.g. ["dose", "response"]) 
     260    :param exptype: Experiment type (e.g. 'RNA-Seq', has EFO expansion) 
     261    :param gxa: If True limit the results to experiments from the Gene 
     262        Expreission Atlas only. 
     263    :param pmid: Search by PubMed identifier 
     264    :param sa: Sample attribute values (e.g. 'fibroblast', has EFO expansion) 
     265    :param species: Search by species (e.g. 'Homo sapiens', has EFO expansion) 
     266     
     267    :param expandefo: If True expand the search terms with all its child terms 
     268        in the Experimental Factor Ontology (EFO_) (e.g. keywords="cancer" 
     269        will be expanded to include for synonyms and sub types of cancer). 
     270    :param directsub: If True return only experiments submited directly to 
     271        Array Express else if False return only experiments imported from GEO 
     272        database (default None, return both) 
     273    :param assaycount: A two tuple (min, max) for filter on the number of 
     274        assays (e.g. (1, 5) will return only experiments with at least one 
     275        and no more then 5 assays). 
     276    :param efcount: Filter on the number of experimental factors (e.g. (1, 5)) 
     277    :param sacount: Filter on the number of sample attribute categories 
     278    :param rawcount: Filter on the number or raw files 
     279    :param fgemcount: Filter on the number of final gene expression matrix 
     280        (processed data) files 
     281    :param miamescore: Filter on the MIAME complience score (max 5) 
     282    :param date: Filter by release date 
     283     
    144284    Example :: 
    145285     
    146286        >>> query_experiments(species="Homo sapiens", ef="organism_part", efv="liver") 
    147         <addinfourl at ... 
    148          
    149     """ 
    150     return ArrayExpressConnection().query_experiment(**kwargs) 
     287        {u'experiments': ... 
     288         
     289    .. _EFO: http://www.ebi.ac.uk/efo/ 
     290     
     291    """ 
     292    if connection is None: 
     293        connection = ArrayExpressConnection() 
     294         
     295    stream = connection.query_experiment(keywords=keywords, accession=accession, 
     296                array=array, ef=ef, efv=efv, expdesign=expdesign, exptype=exptype, 
     297                gxa=gxa, pmid=pmid, sa=sa, species=species, expandefo=expandefo, 
     298                directsub=directsub, assaycount=assaycount, efcount=efcount, 
     299                samplecount=samplecount, rawcount=rawcount, fgemcount=fgemcount, 
     300                miamescore=miamescore, date=date,  format=format, 
     301                wholewords=wholewords) 
     302     
     303    if format == "json": 
     304        return parse_json(stream) 
     305    else: 
     306        return parse_xml(stream) 
    151307 
    152308def query_files(**kwargs): 
    153309    """ Query Array Express files. 
    154310     
     311    This function accepts the same arguments as `query_experiments`. 
     312     
    155313    Example :: 
    156314     
    157         >>> query_files(species="Mus musculus", ef="developmental_stage", efv="embryo") 
    158         <addinfourl at ... 
     315        >>> query_files(species="Mus musculus", ef="developmental_stage", efv="embryo", format="xml") 
     316        XMLNode(... 
    159317                         
    160318    """ 
    161     return ArrayExpressConnection().query_files(**kwargs) 
    162      
    163 # TODO: List all accepted keyword values for query_* functions. 
    164  
    165 """\ 
     319    connection = kwargs.get("connection", None) 
     320    if connection is None: 
     321        connection = ArrayExpressConnection() 
     322     
     323    stream = connection.query_files(**kwargs) 
     324    if kwargs.get("format", "json") == "json": 
     325        return parse_json(stream) 
     326    else: 
     327        return parse_xml(stream) 
     328     
     329__doc__ += """\ 
    166330Gene Expression Atlas 
    167331--------------------- 
     332 
     333Use `query_atlas_simple` for simple querys. 
     334 
     335Example (query human genes for experiments in which they are up regulated):: 
     336    >>> obiArrayExpress.query_atlas_simple(genes=["SORL1", "PSIP1", "CDKN1C"], regulation="up", organism="Homo sapiens") 
     337    {u'... 
     338     
    168339""" 
    169340 
    170341class GeneExpressionAtlasConenction(object): 
    171     """ A connection to Gene Expression Atlas database 
     342    """ A connection to Gene Expression Atlas database. 
    172343    """ 
    173344    try: 
     
    180351     
    181352    def __init__(self, address=None, cache=None, timeout=30): 
     353        """ Initialize the conenction. 
     354         
     355        :param address: Address of the server 
     356        :param cache: A dict like object to use for caching 
     357        :timeout: Socket timeout. 
     358         
     359        """ 
    182360        self.address = address if address is not None else self.DEFAULT_ADDRESS 
    183361        self.cache = cache if cache is not None else self.DEFAULT_CACHE 
     
    355533    def validate(self): 
    356534        # TODO: validate the factor and value 
    357 #        assert(self.factor in efv_ontology()) 
     535#        assert(self.factor in ef_ontology()) 
    358536        assert(self.regulation in ["up", "down", "updown"]) 
    359537         
     
    375553         
    376554     
    377 def query_atlas_simple(genes=None, regulated=None, organism=None, format="json"): 
     555def query_atlas_simple(genes=None, regulation=None, organism=None, 
     556                       condition=None, format="json", start=None, 
     557                       rows=None, indent=False): 
    378558    """ A simple Atlas query. 
    379559     
     560    :param genes: A list of gene names to search for. 
     561    :param regulation: Search for experiments in which `genes` are "up", 
     562        "down", "updown" or "none" regulated. If None all experiments 
     563        are searched. 
     564    :param organism: Search experiments for organism. If None all experiments 
     565        are searched. 
     566    :param condition: An EFO factor value (e.g. "brain") 
     567     
    380568    Example:: 
    381569         
    382570        >>> query_atlas_simple(genes=['Pou5f1', 'Dppa3'], organism="Mus musculus") 
    383         <addinfourl at ... 
    384          
    385         >>> query_atlas_simple(genes=['Pou5f1', 'Dppa3'], regulated="up", organism="Mus musculus") 
    386         <addinfourl at ... 
     571        {u'... 
     572         
     573        >>> query_atlas_simple(genes=['Pou5f1', 'Dppa3'], regulation="up", organism="Mus musculus") 
     574        {u'... 
     575         
     576        >>> query_atlas_simple(genes=['Pou5f1', 'Dppa3'], regulation="up", condition="liver", organism="Mus musculus") 
     577        {u'... 
    387578         
    388579    """ 
    389580    conditions = AtlasConditionList() 
    390581    conditions.append(AtlasConditionGeneProperty("Gene", "Is", genes)) 
    391     if regulated: 
    392         conditions.append(AtlasConditionExperimentalFactor("", regulated, 1, "")) 
     582    if regulation or condition: 
     583        regulation = "any" if regulation is None else regulation 
     584        condition = "" if condition is None else condition 
     585        conditions.append(AtlasConditionExperimentalFactor("", regulation, 1, condition)) 
    393586    if organism: 
    394587        conditions.append(AtlasConditionOrganism(organism)) 
     588         
    395589    connection = GeneExpressionAtlasConenction() 
    396     results = connection.query(conditions, format=format) 
    397     return results 
     590    results = connection.query(conditions, format=format, start=start, 
     591                               rows=rows) 
     592    if format == "json": 
     593        return parse_json(results) 
     594    else: 
     595        return parse_xml(results) 
    398596 
    399597"""\ 
    400 TODO: can this be implemented query_atlas(organism="...", Locuslink="...", Chebi="...", up3InCompound="..." downInEFO="...") 
     598.. TODO: can this be implemented query_atlas(organism="...", Locuslink="...", Chebi="...", up3InCompound="..." downInEFO="...") 
    401599      Need a full list of accepted factors  
    402600""" 
     
    407605    Example:: 
    408606         
    409         >>> #condition = AtlasConditionGeneProperty() 
     607        >>> condition1 = AtlasConditionGeneProperty("Goterm", "Is", "p53 binding") 
     608        >>> condition2 = AtlasConditionExperimentalFactor("Organism_part", "up", 3, "heart") 
     609        >>> condition = AtlasConditionList([condition1, condition2]) 
     610        >>> query_atlas(condition) 
     611        {u'... 
    410612         
    411613    """ 
     
    413615    results = connection.query(condition, format=format, start=start, 
    414616                               rows=rows, indent=indent) 
    415     return results 
     617    if format == "json": 
     618        return parse_json(results) 
     619    else: 
     620        return parse_xml(results) 
    416621 
    417622 
     
    438643    condition = AtlasConditionList([genes_condition, org_condition]) 
    439644    result = query_atlas(condition, format="json") 
    440     import json 
    441     result = json.load(result) 
    442645     
    443646    org_part = collect_ef_summary(result, "organism_part") 
     
    469672     
    470673     
    471 if __name__ == "__main__": 
     674def test(): 
    472675    from pprint import pprint     
    473676    pprint(get_atlas_summary(['Pou5f1', 'Dppa3'], 'Mus musculus')) 
     
    480683    doctest.testmod(optionflags=doctest.ELLIPSIS, extraglobs={"conn": conn}) 
    481684     
     685if __name__ == "__main__": 
     686    test() 
     687     
Note: See TracChangeset for help on using the changeset viewer.