Changeset 1654:61fbdcb67aab in orange-bioinformatics for _bioinformatics/obiDicty.py


Ignore:
Timestamp:
05/21/12 10:25:29 (2 years ago)
Author:
mitar
Branch:
default
Children:
1655:9d3ae06d69be, 1657:edc96b23f6ef
Parents:
1653:508c7aa2e03c (diff), 1622:3d2f34a594e5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Tags:
2.5a1
Message:

Merge.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • _bioinformatics/obiDicty.py

    r1636 r1654  
    709709 
    710710        return et 
     711 
     712def bufferkeypipax(command, data): 
     713    """ Do not save password to the buffer! """ 
     714    command = command + " v7" #add version 
     715    if data != None: 
     716        data = data.copy() 
     717        if pipaparpass in data: 
     718            data.pop(pipaparpass) 
     719        return command + " " +  urllib.urlencode(sorted(data.items())) 
     720    else: 
     721        return command 
     722 
     723 
     724class PIPAx(PIPA): 
     725    """`PIPAx <http://pipa.biolab.si/?page_id=23>` api interface. 
     726    """ 
     727 
     728    API_ADDRESS = "https://pipa.biolab.si/pipax/api.py" 
     729 
     730    def __init__(self, address=API_ADDRESS, buffer=None, 
     731                 username=None, password=None): 
     732        self.address = address 
     733        self.db = DBInterface(address) 
     734        self.buffer = buffer 
     735        self.username = username 
     736        self.password = password 
     737 
     738    def genomes(self, reload=False, bufver="0"): 
     739        """Return a list of available genomes as a list of 
     740        (genome_id, genome_name) tuples. 
     741 
     742        >>> pipax.genomes() 
     743        [('dd', 'Dictyostelium discoideum'), ('dp', 'Dictyostelium purpureum')] 
     744 
     745        """ 
     746        data = {"action": "genomes"} 
     747        res, _ = self.sq("", data=data, reload=reload, bufver=bufver) 
     748        return [tuple(r) for r in res] 
     749 
     750    def mappings(self, reload=False, bufver="0"): 
     751        """Return a dictionary of {unique_id: dictionary_of_annotations} 
     752        where the keys for dictionary_of_annotations are 
     753        ["id", data_id", "data_name", "genomes_id"] 
     754 
     755        >>> mappings = pipax.mappings() 
     756 
     757        """ 
     758        data = self.add_auth({"action": "mappings"}) 
     759        res, legend = self.sq("", data=data, reload=reload, 
     760                              bufferkey=bufferkeypipax, 
     761                              bufver=bufver) 
     762 
     763        return dict((sa[0], dict(zip(legend[1:], sa[1:]))) for sa in res) 
     764 
     765    def result_types(self, reload=False, bufver="0"): 
     766        """Return a list of available result type templates. 
     767        """ 
     768        data = {"action": "results_templates"} 
     769        res, _ = self.sq("", data=data, reload=reload, bufver=bufver) 
     770        return sorted(tuple(a) for a in res) 
     771 
     772    def results_list(self, rtype, reload=False, bufver="0"): 
     773        """Return a list of available results for a result type template 
     774        `rtype` (a key from the `result_types` return value). 
     775 
     776        """ 
     777        data = {"action": "results", 
     778                "results_templates_id": rtype} 
     779        data = self.add_auth(data) 
     780        res, legend = self.sq("", data=data, reload=reload, 
     781                              bufferkey=bufferkeypipax, 
     782                              bufver=bufver) 
     783        # index by unique_id (last column) 
     784        res = splitTableOnColumn(res, -1) 
     785        return dict((id, dict(zip(legend, line[0]))) \ 
     786                    for id, line in res.items()) 
     787 
     788    def download_key_function(self): 
     789        data = self.add_auth({"action": "download", 
     790                              "ids": "$MULTI$"} 
     791                                ) 
     792        keynamingfn, _ = self.downloadMulti_bufcommand_replace_multi("", 
     793                         data=data, chunk=100, bufferkey=bufferkeypipax, 
     794                         transformfn=None) 
     795        return keynamingfn 
     796 
     797    def get_data(self, ids=None, result_type=None, 
     798                 exclude_constant_labels=False, average=median, 
     799                 callback=None, bufver="0", transform=None, 
     800                 allowed_labels=None): 
     801        """ 
     802        Get data in a single example table with labels of individual 
     803        attributes set to annotations for query and post-processing 
     804        instructions. 
     805 
     806        :param ids: If `result_type` is specified then this must 
     807            be a list of  `unique_id`s or (id, data_id) tuples as 
     808            returned by `mappings`. Else the `ids` must be a list 
     809            of `unique_id`s as returned by `results_list`. 
     810        :type ids: list 
     811 
     812        :param result_type: Result template type id as returned by 
     813             `result_types`. Not specified by default (see `ids`.) 
     814        :type result_type: str 
     815 
     816        :param exclude_constant_labels: If a label has the same value 
     817            in whole example table, remove it. 
     818        :type exclude_constant_labels: bool 
     819 
     820        :param average: Function used for combining multiple reading of 
     821            the same spot on a chip. If None, no averaging is done. 
     822            Function should take a list of floats and return an "averaged" 
     823            float (default `median`). 
     824        :type average: function 
     825 
     826        """ 
     827 
     828        def optcb(): 
     829            if callback: 
     830                callback() 
     831 
     832        def argsort(a): 
     833            sort = sorted([(map(int, item), i) for i, item in enumerate(a)]) 
     834            return [i for _, i in sort] 
     835 
     836        cbc = CallBack(len(ids), optcb, callbacks=10) 
     837 
     838        if result_type is not None: 
     839            ids_sort = argsort(ids) 
     840            res_list = self.results_list(result_type, reload=reload, 
     841                                         bufver=bufver) 
     842            # Map (data_id, mapping_id) to unique_id 
     843            res_types_to_unique_id = \ 
     844                dict(((annot["data_id"], annot["mappings_id"]), 
     845                      annot["unique_id"]) \ 
     846                     for annot in res_list.values()) 
     847 
     848            mappings = self.mappings(reload=reload, bufver=bufver) 
     849 
     850            def id_map(mappings_unique_id): 
     851                cbc() 
     852                if isinstance(mappings_unique_id, tuple): 
     853                    data_id, mappings_id = mappings_unique_id 
     854                else: 
     855                    annot = mappings[mappings_unique_id] 
     856                    data_id = annot["data_id"] 
     857                    mappings_id = annot["id"] 
     858                return res_types_to_unique_id[data_id, mappings_id] 
     859 
     860            ids = map(id_map, ids) 
     861        else: 
     862            result_type_set = set(id.rsplit("_", 1)[-1] for id in ids) 
     863            if len(result_type_set) != 1: 
     864                raise ValueError("""\ 
     865Can only retrieve a single result_template_type at a time""" 
     866) 
     867            result_type = result_type_set.pop() 
     868            res_list = self.results_list(result_type, reload=reload, 
     869                                         bufver=bufver) 
     870            sort_keys = [(int(res_list[id]["data_id"]), 
     871                          int(res_list[id]["mappings_id"]))\ 
     872                         for id in ids] 
     873            ids_sort = argsort(sort_keys) 
     874 
     875        # Sort the ids for use by pipax api 
     876        ids_sorted = [ids[i] for i in ids_sort] 
     877 
     878        read = {} 
     879        for a, b in res_list.items(): 
     880            read[a] = b.items() 
     881 
     882        cbc.end() 
     883 
     884        download_func = lambda x: self.download(x, reload=reload, 
     885                                                bufver=bufver) 
     886 
     887        cbc = CallBack(len(ids_sorted) + 3, optcb, 
     888                       callbacks=99 - 20) 
     889        et = self.exampleTables(ids_sorted, spotmap={}, callback=cbc, 
     890                            annots=read, 
     891                            exclude_constant_labels=exclude_constant_labels, 
     892                            chipfn=download_func, 
     893                            allowed_labels=allowed_labels) 
     894        cbc.end() 
     895 
     896        # Restore input ids order. 
     897        domain = orange.Domain([et.domain[id] for id in ids], None) 
     898        domain.addmetas(et.domain.getmetas()) 
     899        et = orange.ExampleTable(domain, et) 
     900 
     901        cbc = CallBack(2, optcb, callbacks=10) 
     902 
     903        #transformation is performed prior to averaging 
     904        if transform != None: 
     905            transformValues(et, fn=transform)  # in place transform 
     906            cbc() 
     907 
     908        #if average function is given, use it to join same spotids 
     909        if average != None: 
     910            et = averageAttributes(et, fn=average) 
     911            cbc() 
     912 
     913        cbc.end() 
     914 
     915        return et 
     916 
     917    def download(self, result_ids, reload=False, bufver="0"): 
     918        """result_ids must be sorted (by `(data_id, mappings_id)`) 
     919        """ 
     920        data = {"action": "download", "ids": "$MULTI$"} 
     921        data = self.add_auth(data) 
     922        antss = self.downloadMulti("", result_ids, data=data, chunk=10, 
     923                                   bufferkey=bufferkeypipax, bufreload=reload, 
     924                                   bufver=bufver) 
     925        for a, legend in antss: 
     926            yield a 
     927 
     928    def downloadMulti(self, command, ids, data=None, chunk=100, 
     929                      transformfn=None, bufferkey=None, separatefn=None, 
     930                      bufreload=False, bufver="0"): 
     931        """ 
     932        Downloads multiple results at once. 
     933        Results in the same order as in ids. 
     934 
     935        Bufferkey transforms command and data into buffer key. 
     936        bufver is a function returning buffer version for a given id. if 
     937            a string is given, use it for all ids 
     938        """ 
     939 
     940        sids = split(ids, chunk) 
     941 
     942        bufverfn = None 
     943        if isinstance(bufver, basestring): 
     944            bufverfn = lambda x: bufver 
     945        else: 
     946            bufverfn = bufver 
     947 
     948        bufcommand, replace_multi = \ 
     949                self.downloadMulti_bufcommand_replace_multi(command, 
     950                                data=data, chunk=chunk, bufferkey=bufferkey, 
     951                                transformfn=transformfn 
     952                                ) 
     953 
     954        for i, sidp in enumerate(sids): 
     955 
     956            buffered = [] 
     957            unbuffered = [] 
     958 
     959            for a in sidp: 
     960                if self.inBuffer(bufcommand(a)) == bufverfn(a) and \ 
     961                        bufreload == False: 
     962                    buffered.append(a) 
     963                else: 
     964                    unbuffered.append(a) 
     965 
     966            res = [] 
     967            legend = [] 
     968 
     969            if len(unbuffered) > 0: 
     970                com1, d1 = replace_multi(command, data, ",".join(unbuffered)) 
     971                # get unbuffered part 
     972                res, legend = self.sq(com1, data=d1, buffer=False) 
     973            else: 
     974                # get legend from buffer also 
     975                legend = self.fromBuffer(bufcommand(buffered[0]))[0] 
     976 
     977            legend = ["gene_id", "value"] 
     978            genes = nth(res, 0) 
     979 
     980            antss = {} 
     981            for i, cid in enumerate(unbuffered): 
     982                col = i + 1 
     983                vals = nth(res, col) 
     984                antss[cid] = [[a, b] for a, b in zip(genes, vals) if b != "?"] 
     985 
     986            #here save buffer 
     987            for a, b in antss.items(): 
     988                self.toBuffer(bufcommand(a), [legend] + b, bufverfn(a), 
     989                              autocommit=False) 
     990            self.bufferCommit() 
     991 
     992            #get buffered from the buffer 
     993            antssb = dict([(b, self.fromBuffer(bufcommand(b))[1:]) \ 
     994                           for b in buffered]) 
     995            antss.update(antssb) 
     996 
     997            #put results in order 
     998            for ci in sidp: 
     999                yield antss[ci], legend 
     1000 
    7111001 
    7121002class DictyExpress(DBCommon): 
Note: See TracChangeset for help on using the changeset viewer.