changed BlockGenerator to select multiple columns at once, to handle cases where...
[pygr.git] / pygr / xnestedlist.py
blobb83de2a8f375fe0bdbd63411f0d97db3ef757a83
1 import cnestedlist
2 from nlmsa_utils import EmptySliceError,EmptySlice
3 import sequence
5 class NLMSAServer(cnestedlist.NLMSA):
6 'serves NLMSA via serializable method calls for XMLRPC'
7 xmlrpc_methods={'getSlice':0,'getInfo':0}
8 def getSlice(self,seqID,start,stop):
9 'perform an interval query and return results as raw ivals'
10 try:
11 seq=self.seqDict[seqID]
12 nlmsa_id,ns,offset=self.seqs[seq] # GET UNION INFO FOR THIS SEQ
13 except KeyError:
14 return '' # failure code
15 ival=sequence.absoluteSlice(seq,start,stop) # GET THE INTERVAL
16 try:
17 myslice=self[ival] # DO THE QUERY
18 except EmptySliceError:
19 return 'EMPTY'
20 except KeyError:
21 return '' # FAILURE CODE
22 ivals=myslice.rawIvals() # GET RAW INTERVAL DATA
23 d={}
24 d[nlmsa_id]=self.seqs.IDdict[str(nlmsa_id)] # SAVE INDEX INFO FOR SOURCE SEQ
25 for v in ivals: # SAVE INDEX INFO FOR TARGET SEQS
26 id=v[2] # target_id NLMSA_ID
27 if not self.seqlist.is_lpo(id): # ONLY NON-LPO SEQS STORED IN THIS INDEX
28 d[id]=self.seqs.IDdict[str(id)]
29 l=[(key,val) for key,val in d.items()] # XMLRPC CAN'T HANDLE int DICT, SO USE LIST
30 return nlmsa_id,ivals,l # LIST OF ALIGNED IVALS, LIST OF (nlmsa_id,(seqID,nsID))
31 def getInfo(self):
32 'return list of tuples describing NLMSASequences in this NLMSA'
33 l=[]
34 for ns in self.seqlist:
35 l.append((ns.id,ns.is_lpo,ns.length,ns.is_union))
36 return l
39 class NLMSAClient(cnestedlist.NLMSA):
40 'client for accessing NLMSAServer via XMLRPC'
41 def __init__(self,url=None,name=None,idDictClass=dict,**kwargs):
42 cnestedlist.NLMSA.__init__(self,mode='xmlrpc',idDictClass=idDictClass,**kwargs)
43 import coordinator
44 self.server=coordinator.get_connection(url,name) # GET CONNECTION TO THE SERVER
45 self.url=url
46 self.name=name
47 l=self.server.getInfo() # READ NS INFO TABLE
48 for nsID,is_lpo,nsLength,is_union in l:
49 ns=cnestedlist.NLMSASequence(self,None,None,'onDemand',is_union,nsLength) # is_lpo AUTOMATIC
50 self.addToSeqlist(ns) # ADD THIS TO THE INDEX
51 def close(self):
52 pass # required interface, but nothing to do
53 def doSlice(self,seq):
54 'getSlice from the server, and create an NLMSASlice object from results'
55 result=self.server.getSlice(self.seqs.getSeqID(seq),seq.start,seq.stop)
56 if result=='':
57 raise KeyError('this interval is not aligned!')
58 elif result == 'EMPTY':
59 raise EmptySliceError
60 id,l,d=result
61 for nlmsaID,(seqID,nsID) in d: # SAVE SEQ INFO TO INDEX
62 self.seqs.saveSeq(seqID,nsID,0,nlmsaID)
63 return id,l # HAND BACK THE RAW INTEGER INTERVAL DATA
64 def __getitem__(self,k):
65 'directly call slice without any ID lookup -- will be done server-side'
66 try:
67 return cnestedlist.NLMSASlice(self.seqlist[0],k.start,k.stop,-1,-1,k)
68 except EmptySliceError:
69 return EmptySlice(k)
70 def __getstate__(self):
71 return dict(url=self.url,name=self.name,seqDict=self.seqDict)