source: orange-bioinformatics/_bioinformatics/obiGeneAtlas.py @ 1825:7187e6ba2114

Revision 1825:7187e6ba2114, 24.3 KB checked in by Flashpoint <vid.flashpoint@…>, 10 months ago (diff)

Added some missing info to the obiGeneAtlas.py API

Line 
1"""
2========================================
3Gene Expression Atlas (``obiGeneAtlas``)
4========================================
5
6Interface to Gene Expression Atlas.
7
8`Gene Expression Atlas <http://www.ebi.ac.uk/gxa/>`_ is a curated subset of
9gene expression experiments in Array Express Archive.
10
11.. autofunction:: gene_expression_atlas
12
13.. autofunction:: default_gene_matcher
14
15.. autofunction:: to_taxid
16
17"""
18
19from __future__ import absolute_import
20
21import os, shelve, sys
22from collections import defaultdict, namedtuple
23from contextlib import closing
24
25from Orange.orng import orngServerFiles
26from Orange.utils import serverfiles
27
28from . import obiGene
29
30GeneResults = namedtuple("GeneResults", "id name synonyms expressions")
31ExpressionResults = namedtuple("ExpressionResults", "ef efv up down experiments")
32ExperimentExpression = namedtuple("ExperimentExpression", "accession expression pvalue")
33
34##
35GeneAtlasResult = GeneResults
36AtlasExpressions = ExpressionResults
37AtlasExperiment = ExperimentExpression
38##
39
40CACHE_VERSION = 1
41
42
43def _cache(name="AtlasGeneResult.shelve"):
44    """ Return a open cache instance (a shelve object).
45    """
46    if not os.path.exists(orngServerFiles.localpath("GeneAtlas")):
47        try:
48            os.makedirs(orngServerFiles.localpath("GeneAtlas"))
49        except OSError:
50            pass
51    cache = shelve.open(orngServerFiles.localpath("GeneAtlas", name))
52    if cache.get(name + "__CACHE_VERSION__", None) == CACHE_VERSION:
53        return cache
54    else:
55        cache.close()
56        cache = shelve.open(orngServerFiles.localpath("GeneAtlas", name), "n")
57        cache[name + "__CACHE_VERSION__"] = CACHE_VERSION
58        return cache
59
60
61SLEEP_TIME_MULTIPLIER = 3.0
62
63def gene_expression_atlas(genes, progress_callback=None):
64    """ Return GeneResults instances for genes (genes must be valid ensembl ids).
65    """
66    import time
67    genes = list(genes)
68    result_dict = {}
69    genes_not_cached = []
70    # See which genes are already cached
71    with closing(_cache()) as cache:
72        for gene in genes:
73            if str(gene) in cache:
74                result_dict[gene] = cache[str(gene)]
75            else:
76                genes_not_cached.append(gene)
77   
78    batch_size = 10
79    start = 0
80    res = []
81    while start < len(genes_not_cached):
82        batch = genes_not_cached[start: start + batch_size]
83        start += batch_size
84        start_time = time.time()
85        batch_res = batch_gene_atlas_expression(batch)
86        # Cache the new results.
87        # TODO: handle genes without any results.
88        genes_with_no_results = set(batch) - set(r.id for r in batch_res) 
89        with closing(_cache()) as cache:
90            for atlas_res in batch_res:
91                cache[str(atlas_res.id)] = atlas_res
92                result_dict[atlas_res.id] = atlas_res
93            for g in genes_with_no_results:
94                cache[str(g)] = None
95        res.extend(batch_res)
96        # Sleep
97        if start % (batch_size * 10) == 0:
98            # every 10 batches wait one minute before continuing.
99            time.sleep(60)
100        else:
101            time.sleep(min(20.0, SLEEP_TIME_MULTIPLIER*(time.time() - start_time)))
102           
103        if progress_callback:
104            progress_callback(100.0 * start / len(genes_not_cached))
105   
106    return [result_dict.get(g, None) for g in genes]
107
108   
109def batch_gene_atlas_expression(genes):
110    cond = GenePropertyCondition("Ensgene", "Is", genes)
111    res = run_query(cond, format="json")
112    results = res["results"]
113    results_genes = []
114    for one_result in results:
115        gene = one_result["gene"]
116        id = gene["id"]
117        name = gene["name"]
118        synonyms = gene.get("synonyms", [])
119        expressions = one_result["expressions"]
120        result_expressions = []
121        for expression in expressions:
122            ef = expression["ef"]
123            efv = expression["efv"]
124            up = expression["upExperiments"]
125            down = expression["downExperiments"]
126            experiments = expression["experiments"]
127            result_experiment = []
128            for exp in experiments:
129                if "accession" in exp:
130                    exp_accession = exp["accession"]
131                elif "experimentAccession" in exp:
132                    exp_accession = exp["experimentAccession"]
133                else:
134                    raise KeyError()
135                if "expression" in exp:
136                    updown = exp["expression"]
137                elif "updn" in exp:
138                    updown = exp["updn"]
139                else:
140                    raise KeyError
141                pval = exp["pvalue"]
142                result_experiment.append(ExperimentExpression(exp_accession, updown, pval))
143            result_expressions.append(ExpressionResults(ef, efv, up, down, result_experiment))
144        results_genes.append(GeneResults(id, name, synonyms, result_expressions))
145    return results_genes
146
147
148def default_gene_matcher(organism):
149    """ Return a default gene matcher for organism
150    (targeting Ensembl gene ids).
151   
152    """
153    taxid = to_taxid(organism)
154    matcher = obiGene.matcher([obiGene.GMEnsembl(taxid),
155                               obiGene.GMNCBI(taxid)])
156    matcher.set_targets(obiGene.EnsembleGeneInfo(taxid).keys())
157    return matcher
158
159from Orange.utils import lru_cache
160
161@lru_cache(maxsize=3)
162def _cached_default_gene_matcher(organism): 
163    return default_gene_matcher(organism)
164   
165
166def get_atlas_summary(genes, organism, gene_matcher=None,
167                      progress_callback=None):
168    """ Return 3 dictionaries containing a summary of atlas information
169    about three experimental factors:
170   
171        - Organism Part (OP)
172        - Disease State (DS)
173        - Cell type (CT)
174   
175    Each dictionary contains query genes as keys. Values are dictionaries
176    mapping factor values to a 2-tuple containig the count of up regulated
177    and down regulated experiments.
178   
179    Example ::
180   
181        >>> get_atlas_summary(["RUNX1"], "Homo sapiens")
182        ({u'RUNX1': ...
183       
184    """
185    if gene_matcher is None:
186        gene_matcher = _cached_default_gene_matcher(organism)
187       
188    matched, unmatched = [], []
189    for gene, match in zip(genes, map(gene_matcher.umatch, genes)):
190        if match:
191            matched.append(match)
192        else:
193            unmatched.append(gene)
194    if unmatched:
195        import warnings
196        warnings.warn("Unmatched genes " + "," .join(["%r" % g for g in unmatched]))
197   
198    results = gene_expression_atlas(matched, progress_callback=progress_callback)
199   
200    def collect_ef_summary(result, ef, summary):
201        for exp in result.expressions:
202            if exp.ef == ef:
203                if any([exp.up, exp.down]):
204                    summary[result.name][exp.efv] = (exp.up, exp.down)
205       
206           
207    op, ds, ct = defaultdict(dict), defaultdict(dict), defaultdict(dict)
208    for res in results:
209        if res:
210            collect_ef_summary(res, "organism_part", op)
211            collect_ef_summary(res, "disease_state", ds)
212            collect_ef_summary(res, "cell_type", ct)
213       
214    return dict(op), dict(ds), dict(ct)
215
216def drop_none(iter):
217    """ Drop all ``None`` from the iterator.
218    """
219    for e in iter:
220        if e is not None:
221            yield e
222           
223def construct_atlas_gene_sets(genes, organism, factors=["organism_part",
224                                    "disease_state", "cell_type"],
225                              max_pvalue=1e-5):
226    """ Construct gene sets for atlas experimental factor values in
227    ``factors``.
228    """
229    results = gene_expression_atlas(genes)
230    sets = defaultdict(list)
231   
232    for res in drop_none(results):
233        for exp in res.expressions:
234            if exp.ef not in factors:
235                continue
236            diff_exp = [e for e in exp.experiments \
237                        if e.pvalue <= max_pvalue]
238            if diff_exp:
239                sets[exp.ef, exp.efv].append(res.id)
240
241    organism = "+".join(organism.lower().split())
242    from .obiGeneSets import GeneSets, GeneSet
243   
244    def display_string(name):
245        return name.capitalize().replace("_", " ")
246   
247    gene_sets = []
248    for (ef, efv), genes in sets.items():
249        ef_display = display_string(ef)
250        gs = GeneSet(genes, "Diff. expressed in %s=%s." % (ef_display, efv), id=ef + ":" + efv,
251                     description="Diff. expressed in %s=%s" % (ef_display, efv),
252                     link="http://www.ebi.ac.uk/gxa/qrs?specie_0={organism}&gprop_0=&gnot_0=&gval_0=&fact_1=&fexp_1=UPDOWN&fmex_1=&fval_1=%22{efv}%22+&view=hm".format( \
253                            organism=organism, efv="+".join(efv.lower().split())),
254                     hierarchy=("Gene expression atlas", ef_display))
255        gene_sets.append(gs)
256    return GeneSets(gene_sets)
257
258
259# Mapping for common taxids from obiTaxonomy
260TAXID_TO_ORG = {"": "Anopheles gambiae",
261                "3702": "Arabidopsis thaliana",
262                "9913": "Bos taurus",
263                "6239": "Caenorhabditis elegans",
264                "7955": "Danio rerio",
265                "7227": "Drosophila melanogaster",
266                "": "Epstein barr virus",
267                "": "Gallus gallus",
268                "9606": "Homo sapiens",
269                "": "Human cytomegalovirus",
270                "": "Kaposi sarcoma-associated herpesvirus",
271                "10090": "Mus musculus",
272                "10116": "Rattus norvegicus",
273                "4932": "Saccharomyces cerevisiae",
274                "4896": "Schizosaccharomyces pombe",
275                "8355": "Xenopus laevis"
276     }
277
278def to_taxid(name):
279    dd = dict((v, k) for k, v in TAXID_TO_ORG.items())
280    if name in dd:
281        return dd[name]
282    else:
283        from . import obiTaxonomy as tax
284        ids = tax.to_taxid(name, mapTo=TAXID_TO_ORG.keys())
285        if ids:
286            return ids.pop()
287        else:
288            raise ValueError("Unknown organism.")
289
290
291__doc__ += """\
292Low level REST query interface
293------------------------------
294
295Use `query_atlas_simple` for simple querys.
296
297Example (query human genes for experiments in which they are up regulated) ::
298
299    >>> run_simple_query(genes=["SORL1", "PSIP1", "CDKN1C"], regulation="up", organism="Homo sapiens")
300    {u'...
301   
302Or use the `AtlasCondition` subclasses in this module to construct a more
303advanced query and use the `run_query` function.
304
305Example (query human genes annotated to the GO term 'transporter activity'
306that are up regulated in the liver in at least three experiments) ::
307
308    >>> go_cond = GenePropertyCondition("Goterm", "Is", "transporter activity")
309    >>> liver_cond = ExperimentalFactorCondition("Organism_part", "up", 3, "liver")
310    >>> org_cond = OrganismCondition("Homo sapiens")
311    >>> cond_list = ConditionList([go_cond, liver_cond, org_cond])
312    >>> run_query(cond_list)
313    {u'...
314
315"""
316
317import urllib2
318from  StringIO import StringIO
319import json
320from xml.etree.ElementTree import ElementTree
321
322parse_json = json.load
323
324
325def parse_xml(stream):
326    """ Parse an xml stream into an instance of xml.etree.ElementTree.ElementTree.
327    """
328    return ElementTree(file=stream)
329
330
331class GeneExpressionAtlasConenction(object):
332    """ A connection to Gene Expression Atlas database.
333    """
334    DEFAULT_ADDRESS = "http://www.ebi.ac.uk:80/gxa/"
335    DEFAULT_CACHE = orngServerFiles.localpath("GeneAtlas", "GeneAtlasConnectionCache.shelve")
336    def __init__(self, address=None, timeout=30, cache=None):
337        """ Initialize the conenction.
338       
339        :param address: Address of the server.
340        :param timeout: Socket timeout.
341        :param cache : A dict like object to use as a cache.
342       
343        """
344        self.address = address if address is not None else self.DEFAULT_ADDRESS
345        self.timeout = timeout
346        self.cache = cache if cache is not None else self.DEFAULT_CACHE
347   
348    def query(self, condition, format="json", start=None, rows=None, indent=False):
349        url = self.address + "api/vx?" + condition.rest()
350        if start is not None and rows is not None:
351            url += "&start={0}&rows={1}".format(start, rows)
352        url += "&format={0}".format(format)
353        if indent:
354            url += "&indent"
355        #print url
356
357        if self.cache is not None:
358            return self._query_cached(url, format)
359        else:
360            return urllib2.urlopen(url)
361        return response
362   
363    def _query_cached(self, url, format):
364        if self.cache is not None:
365            with self.open_cache() as cache:
366                cached = url in cache
367           
368            if not cached:
369                response = urllib2.urlopen(url)
370                contents = response.read()
371                # Test if the contents is a valid json or xml string (some
372                # times the stream just stops in the middle, so this makes
373                # sure we don't cache an invalid response
374                # TODO: what about errors (e.g. 'cannot handle the
375                # query in a timely fashion'
376                if format == "json":
377                    parse_json(StringIO(contents))
378                else:
379                    parse_xml(StringIO(contents))
380                   
381                with self.open_cache() as cache:
382                    cache[url] = contents
383            else:
384                with self.open_cache() as cache:
385                    contents = cache[url]
386            return StringIO(contents)
387        else:
388            return urllib2.urlopen(url)
389       
390    def open_cache(self):
391        if isinstance(self.cache, basestring):
392            return closing(shelve.open(self.cache))
393        elif hasattr(self.cache, "close"):
394            return closing(self.cache)
395        elif self.cache is None:
396            return fake_closing({})
397        else:
398            return fake_closing(self.cache)
399       
400       
401from contextlib import contextmanager
402@contextmanager
403def fake_closing(obj):
404    yield obj
405   
406   
407# Names of all Gene Property filter names
408GENE_FILTERS = \
409    ["Name", # Gene name
410     "Goterm", #Gene Ontology Term
411     "Interproterm", #InterPro Term
412     "Disease", #Gene-Disease Assocation
413     "Keyword", #Gene Keyword
414     "Protein", #Protein
415
416     "Dbxref", #Other Database Cross-Refs
417     "Embl", #EMBL-Bank ID
418     "Ensfamily", #Ensembl Family
419     "Ensgene", #Ensembl Gene ID
420
421     "Ensprotein", #Ensembl Protein ID
422     "Enstranscript", #Ensembl Transcript ID
423     "Goid", #Gene Ontology ID
424     "Image", #IMAGE ID
425     "Interproid", #InterPro ID
426     "Locuslink", #Entrez Gene ID
427
428     "Omimid", #OMIM ID
429     "Orf", #ORF
430     "Refseq", #RefSeq ID
431     "Unigene", #UniGene ID
432     "Uniprot", #UniProt Accession
433
434     "Hmdb", #HMDB ID
435     "Chebi", #ChEBI ID
436     "Cas", #CAS
437     "Uniprotmetenz", #Uniprotmetenz
438     "Gene", #Gene Name or Identifier
439     "Synonym", #Gene Synonym
440     ]
441   
442# Valid Gene Property filter qualifiers
443GENE_FILTER_QUALIFIERS =\
444    ["Is",
445     "IsNot"
446     ]
447
448# Organisms in the Atlas
449ATLAS_ORGANISMS = \
450    ["Anopheles gambiae",
451     "Arabidopsis thaliana",
452     "Bacillus subtilis",
453     "Bos taurus",
454     "Caenorhabditis elegans",
455     "Canis familiaris",
456     "Ciona intestinalis",
457     "Ciona savignyi",
458     "Danio rerio",
459     "Dasypus novemcinctus",
460     "Drosophila melanogaster",
461     "Epstein barr virus",
462     "Equus caballus",
463     "Gallus gallus",
464     "Gorilla gorilla",
465     "Homo sapiens",
466     "Human cytomegalovirus",
467     "Human immunodeficiency virus",
468     "Kaposi sarcoma-associated herpesvirus",
469     "Macaca mulatta",
470     "Monodelphis domestica",
471     "Mus musculus",
472     "Ornithorhynchus anatinus",
473     "Oryza sativa",
474     "Pan troglodytes",
475     "Pongo abelii",
476     "Populus trichocarpa",
477     "Rattus norvegicus",
478     "Saccharomyces cerevisiae",
479     "Schizosaccharomyces pombe",
480     "Sus scrofa",
481     "Unknown",
482     "Vitis vinifera",
483     "Xenopus laevis",
484     "Xenopus tropicalis"
485     ]
486   
487def ef_ontology():
488    """ Return the `EF <http://www.ebi.ac.uk/efo/>`_ (Experimental Factor) ontology
489    """
490    from . import obiOntology
491    from Orange.utils import serverfiles
492    # Should this be in the OBOFoundry (Ontology) domain
493    try:
494        file = open(serverfiles.localpath_download("ArrayExpress", "efo.obo"), "rb")
495    except urllib2.HTTPError:
496        file = urllib2.urlopen("http://efo.svn.sourceforge.net/svnroot/efo/trunk/src/efoinobo/efo.obo")
497    return obiOntology.OBOOntology(file)
498
499
500class Condition(object):
501    """ Base class for Gene Expression Atlas query condition
502    """
503    def validate(self):
504        """ Validate condition in a subclass.
505        """
506        raise NotImplementedError
507   
508    def rest(self):
509        """ Return a REST query part in a subclass.
510        """
511        raise NotImplementedError
512   
513   
514class ConditionList(list, Condition):
515    """ A list of AtlasCondition instances.
516    """ 
517    def validate(self):
518        for item in self:
519            item.validate()
520       
521    def rest(self):
522        return "&".join(cond.rest() for cond in self)
523
524
525class GenePropertyCondition(Condition):
526    """ An atlas gene filter condition.
527   
528    :param property: Property of the gene. If None or "" all properties
529        will be searched.
530    :param qualifier: Qualifier can be 'Is' or 'IsNot'
531    :param value: The value to search for.
532   
533    Example ::
534   
535        >>> # Condition on a gene name
536        >>> condition = GenePropertyCondition("Name", "Is", "AS3MT")
537        >>> # Condition on genes from a GO Term
538        >>> condition = GenePropertyCondition("Goterm", "Is", "p53 binding")
539        >>> # Condition on disease association
540        >>> condition = GenePropertyCondition("Disease", "Is", "cancer")
541       
542    """
543    def __init__(self, property, qualifier, value):
544        self.property = property or ""
545        self.qualifier = qualifier
546        if isinstance(value, basestring):
547            self.value = value.replace(" ", "+")
548        elif isinstance(value, list):
549            self.value = "+".join(value)
550        else:
551            raise ValueError(value)
552       
553        self.validate()
554       
555    def validate(self):
556        assert(self.property in GENE_FILTERS + [""])
557        assert(self.qualifier in GENE_FILTER_QUALIFIERS + [""])
558       
559    def rest(self):
560        return "gene{property}{qualifier}={value}".format(**self.__dict__)
561       
562       
563class ExperimentalFactorCondition(Condition):
564    """ An atlas experimental factor filter condition.
565   
566    :param factor: EFO experiamntal factor
567    :param regulation: "up", "down", "updown", "any" or "none"
568    :param n: Minimum number of of experimants with this condition
569    :param value: Experimantal factor value
570   
571    Example ::
572   
573        >>> # Any genes up regulated in at least 3 experiments involving cancer.
574        >>> condition = ExperimentalFactorCondition("", "up", 3, "cancer")
575        >>> # Only genes which are up/down regulated in the heart in at least one experiment.
576        >>> condition = ExperimentalFactorCondition("Organism_part", "updown", 1, "heart")
577       
578    """
579    def __init__(self, factor, regulation, n, value):
580        self.factor = factor
581        self.regulation = regulation
582        self.n = n
583        self.value = value
584        self.validate()
585       
586    def validate(self):
587        # TODO: validate the factor and value
588#        assert(self.factor in ef_ontology())
589        assert(self.regulation in ["up", "down", "updown", "none", "any"])
590       
591    def rest(self):
592        return "{regulation}{n}In{factor}={value}".format(**self.__dict__)
593       
594       
595class OrganismCondition(Condition):
596    """ Condition on organism.
597    """
598    def __init__(self, organism):
599        self.organism = organism
600        self.validate()
601       
602    def validate(self):
603        assert(self.organism in ATLAS_ORGANISMS)
604       
605    def rest(self):
606        return "species={0}".format(self.organism.replace(" ", "+").lower())
607       
608       
609class ExperimentCondition(Condition):
610    """ Condition on experiement
611   
612    :param property: Property of the experiment. If None or "" all properties
613        will be searched.
614    :param qualifier: Qualifier can be 'Has' or 'HasNot'
615    :param value: The value to search for.
616   
617    Example ::
618   
619        >>> # Condition on a experiemnt acession
620        >>> condition = ExperimentCondition("", "", "E-GEOD-24283")
621        >>> # Condition on experiments involving lung
622        >>> condition = ExperimentCondition("Organism_part", "Has", "lung")
623       
624    """
625    EXPERIMENT_FILTER_QUALIFIERS = [
626                "Has",
627                "HasNot"]
628   
629    def __init__(self, property, qualifier, value):
630        self.property = property
631        self.qualifier = qualifier
632        if isinstance(value, basestring):
633            self.value = value.replace(" ", "+")
634        elif isinstance(value, list):
635            self.value = "+".join(value)
636        else:
637            raise ValueError(value)
638       
639        self.validate()
640       
641    def validate(self):
642        # TODO: check to EFO factors
643#        assert(self.property in EXPERIMENT_FILTERS + [""])
644        assert(self.qualifier in self.EXPERIMENT_FILTER_QUALIFIERS + [""])
645       
646    def rest(self):
647        return "experiment{property}{qualifier}={value}".format(**self.__dict__)
648       
649       
650class GeneExpressionAtlasError(Exception):
651    """ An error response from the Atlas server.
652    """
653    pass
654   
655   
656def __check_atlas_error_json(response):
657    if "error" in response:
658        raise GeneExpressionAtlasError(response["error"])
659    return response
660 
661     
662def __check_atlas_error_xml(response):
663    error = response.find("error")
664    if error is not None:
665        raise GeneExpressionAtlasError(error.text)
666    return response
667   
668       
669def run_simple_query(genes=None, regulation=None, organism=None,
670                     condition=None, format="json", start=None,
671                     rows=None):
672    """ A simple Gene Atlas query.
673   
674    :param genes: A list of gene names to search for.
675    :param regulation: Search for experiments in which `genes` are "up",
676        "down", "updown", "any" or "none" regulated. If "any" all experiments
677        are searched.
678    :param organism: Search experiments for organism. If None all experiments
679        are searched.
680    :param condition: An EFO factor value (e.g. "brain")
681   
682    Example ::
683       
684        >>> run_simple_query(genes=['Pou5f1', 'Dppa3'], organism="Mus musculus")
685        {u'...
686       
687        >>> run_simple_query(genes=['Pou5f1', 'Dppa3'], regulation="up", organism="Mus musculus")
688        {u'...
689       
690        >>> run_simple_query(genes=['Pou5f1', 'Dppa3'], regulation="up", condition="liver", organism="Mus musculus")
691        {u'...
692       
693    """
694    conditions = ConditionList()
695    if genes:
696        conditions.append(GenePropertyCondition("Gene", "Is", genes))
697    if regulation or condition:
698        regulation = "any" if regulation is None else regulation
699        condition = "" if condition is None else condition
700        conditions.append(ExperimentalFactorCondition("", regulation, 1, condition))
701    if organism:
702        conditions.append(OrganismCondition(organism))
703       
704    connection = GeneExpressionAtlasConenction()
705    results = connection.query(conditions, format=format, start=start,
706                               rows=rows)
707    if format == "json":
708        return parse_json(results)
709    else:
710        return parse_xml(results)
711
712"""\
713.. todo:: can this be implemented query_atlas(organism="...", Locuslink="...", Chebi="...", up3InCompound="..." downInEFO="...")
714      Need a full list of accepted factors
715"""
716
717def run_query(condition, format="json", start=None, rows=None, indent=False, connection=None):
718    """ Query Atlas based on a `condition` (instance of :class:`Condition`)
719   
720    Example ::
721       
722        >>> condition1 = GenePropertyCondition("Goterm", "Is", "p53 binding")
723        >>> condition2 = ExperimentalFactorCondition("Organism_part", "up", 3, "heart")
724        >>> condition = ConditionList([condition1, condition2])
725        >>> run_query(condition)
726        {u'...
727       
728    """
729    if connection is None:
730        connection = GeneExpressionAtlasConenction()
731    results = connection.query(condition, format=format, start=start,
732                               rows=rows, indent=indent)
733    if format == "json":
734        response = parse_json(results)
735        return __check_atlas_error_json(response)
736    else:
737        response = parse_xml(results)
738        return __check_atlas_error_xml(response)
739   
740def test():
741    from pprint import pprint   
742    pprint(get_atlas_summary(['Pou5f1', 'Dppa3'], 'Mus musculus'))
743       
744    pprint(get_atlas_summary(['PDLIM5', 'FGFR2' ], 'Homo sapiens'))
745    import doctest 
746    doctest.testmod(optionflags=doctest.ELLIPSIS)
747   
748if __name__ == "__main__":
749    test()
Note: See TracBrowser for help on using the repository browser.