source: orange-bioinformatics/orangecontrib/bio/obiGeneAtlas.py @ 1887:b0dce8ef683c

Revision 1887:b0dce8ef683c, 24.5 KB checked in by Ales Erjavec <ales.erjavec@…>, 6 months ago (diff)

Fixes for obiGeneAtlas.

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