Package Bio :: Package SearchIO :: Package _model :: Module query
[hide private]
[frames] | no frames]

Source Code for Module Bio.SearchIO._model.query

  1  # Copyright 2012 by Wibowo Arindrarto.  All rights reserved. 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5   
  6  """Bio.SearchIO object to model search results from a single query.""" 
  7   
  8  from __future__ import print_function 
  9  from Bio._py3k import basestring 
 10   
 11  from copy import deepcopy 
 12  from itertools import chain 
 13   
 14  from Bio._py3k import OrderedDict 
 15  from Bio._py3k import filter 
 16   
 17  from Bio._utils import trim_str 
 18  from Bio.SearchIO._utils import optionalcascade 
 19   
 20  from ._base import _BaseSearchObject 
 21  from .hit import Hit 
22 23 24 -class QueryResult(_BaseSearchObject):
25 26 """Class representing search results from a single query. 27 28 QueryResult is the container object that stores all search hits from a 29 single search query. It is the top-level object returned by SearchIO's two 30 main functions, `read` and `parse`. Depending on the search results and 31 search output format, a QueryResult object will contain zero or more Hit 32 objects (see Hit). 33 34 You can take a quick look at a QueryResult's contents and attributes by 35 invoking `print` on it: 36 37 >>> from Bio import SearchIO 38 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 39 >>> print(qresult) 40 Program: blastn (2.2.27+) 41 Query: 33211 (61) 42 mir_1 43 Target: refseq_rna 44 Hits: ---- ----- ---------------------------------------------------------- 45 # # HSP ID + description 46 ---- ----- ---------------------------------------------------------- 47 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 48 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... 49 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... 50 3 2 gi|301171322|ref|NR_035857.1| Pan troglodytes microRNA... 51 4 1 gi|301171267|ref|NR_035851.1| Pan troglodytes microRNA... 52 5 2 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... 53 6 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... 54 7 1 gi|301171259|ref|NR_035850.1| Pan troglodytes microRNA... 55 8 1 gi|262205451|ref|NR_030222.1| Homo sapiens microRNA 51... 56 9 2 gi|301171447|ref|NR_035871.1| Pan troglodytes microRNA... 57 10 1 gi|301171276|ref|NR_035852.1| Pan troglodytes microRNA... 58 11 1 gi|262205290|ref|NR_030188.1| Homo sapiens microRNA 51... 59 ... 60 61 If you just want to know how many hits a QueryResult has, you can invoke 62 `len` on it. Alternatively, you can simply type its name in the interpreter: 63 64 >>> len(qresult) 65 100 66 >>> qresult 67 QueryResult(id='33211', 100 hits) 68 69 QueryResult behaves like a hybrid of Python's built-in list and dictionary. 70 You can retrieve its items (Hit objects) using the integer index of the 71 item, just like regular Python lists: 72 73 >>> first_hit = qresult[0] 74 >>> first_hit 75 Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) 76 77 You can slice QueryResult objects as well. Slicing will return a new 78 QueryResult object containing only the sliced hits: 79 80 >>> sliced_qresult = qresult[:3] # slice the first three hits 81 >>> len(qresult) 82 100 83 >>> len(sliced_qresult) 84 3 85 >>> print(sliced_qresult) 86 Program: blastn (2.2.27+) 87 Query: 33211 (61) 88 mir_1 89 Target: refseq_rna 90 Hits: ---- ----- ---------------------------------------------------------- 91 # # HSP ID + description 92 ---- ----- ---------------------------------------------------------- 93 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 94 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... 95 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... 96 97 Like Python dictionaries, you can also retrieve hits using the hit's ID. 98 This is useful for retrieving hits that you know should exist in a given 99 search: 100 101 >>> hit = qresult['gi|262205317|ref|NR_030195.1|'] 102 >>> hit 103 Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) 104 105 You can also replace a Hit in QueryResult with another Hit using either the 106 integer index or hit key string. Note that the replacing object must be a 107 Hit that has the same `query_id` property as the QueryResult object. 108 109 If you're not sure whether a QueryResult contains a particular hit, you can 110 use the hit ID to check for membership first: 111 112 >>> 'gi|262205317|ref|NR_030195.1|' in qresult 113 True 114 >>> 'gi|262380031|ref|NR_023426.1|' in qresult 115 False 116 117 Or, if you just want to know the rank / position of a given hit, you can 118 use the hit ID as an argument for the `index` method. Note that the values 119 returned will be zero-based. So zero (0) means the hit is the first in the 120 QueryResult, three (3) means the hit is the fourth item, and so on. If the 121 hit does not exist in the QueryResult, a `ValueError` will be raised. 122 123 >>> qresult.index('gi|262205317|ref|NR_030195.1|') 124 0 125 >>> qresult.index('gi|262205330|ref|NR_030198.1|') 126 5 127 >>> qresult.index('gi|262380031|ref|NR_023426.1|') 128 Traceback (most recent call last): 129 ... 130 ValueError: ... 131 132 To ease working with a large number of hits, QueryResult has several 133 `filter` and `map` methods, analogous to Python's built-in functions with 134 the same names. There are `filter` and `map` methods available for 135 operations over both Hit objects or HSP objects. As an example, here we are 136 using the `hit_map` method to rename all hit IDs within a QueryResult: 137 138 >>> def renamer(hit): 139 ... hit.id = hit.id.split('|')[3] 140 ... return hit 141 >>> mapped_qresult = qresult.hit_map(renamer) 142 >>> print(mapped_qresult) 143 Program: blastn (2.2.27+) 144 Query: 33211 (61) 145 mir_1 146 Target: refseq_rna 147 Hits: ---- ----- ---------------------------------------------------------- 148 # # HSP ID + description 149 ---- ----- ---------------------------------------------------------- 150 0 1 NR_030195.1 Homo sapiens microRNA 520b (MIR520B), micr... 151 1 1 NR_035856.1 Pan troglodytes microRNA mir-520b (MIR520B... 152 2 1 NR_032573.1 Macaca mulatta microRNA mir-519a (MIR519A)... 153 ... 154 155 The principle for other `map` and `filter` methods are similar: they accept 156 a function, applies it, and returns a new QueryResult object. 157 158 There are also other methods useful for working with list-like objects: 159 `append`, `pop`, and `sort`. More details and examples are available in 160 their respective documentations. 161 162 Finally, just like Python lists and dictionaries, QueryResult objects are 163 iterable. Iteration over QueryResults will yield Hit objects: 164 165 >>> for hit in qresult[:4]: # iterate over the first four items 166 ... hit 167 ... 168 Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) 169 Hit(id='gi|301171311|ref|NR_035856.1|', query_id='33211', 1 hsps) 170 Hit(id='gi|270133242|ref|NR_032573.1|', query_id='33211', 1 hsps) 171 Hit(id='gi|301171322|ref|NR_035857.1|', query_id='33211', 2 hsps) 172 173 If you need access to all the hits in a QueryResult object, you can get 174 them in a list using the `hits` property. Similarly, access to all hit IDs is 175 available through the `hit_keys` property. 176 177 >>> qresult.hits 178 [Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps), ...] 179 >>> qresult.hit_keys 180 ['gi|262205317|ref|NR_030195.1|', 'gi|301171311|ref|NR_035856.1|', ...] 181 182 """ 183 184 # attributes we don't want to transfer when creating a new QueryResult class 185 # from this one 186 _NON_STICKY_ATTRS = ('_items',) 187
188 - def __init__(self, hits=[], id=None, 189 hit_key_function=lambda hit: hit.id):
190 """Initializes a QueryResult object. 191 192 Arguments: 193 id -- String of query sequence ID. 194 hits -- Iterator returning Hit objects. 195 hit_key_function -- Function to define hit keys, defaults to a function 196 that return Hit object IDs. 197 198 """ 199 # default values 200 self._id = id 201 self._hit_key_function = hit_key_function 202 self._items = OrderedDict() 203 self._description = None 204 self.program = '<unknown program>' 205 self.target = '<unknown target>' 206 self.version = '<unknown version>' 207 208 # validate Hit objects and fill up self._items 209 for hit in hits: 210 # validation is handled by __setitem__ 211 self.append(hit)
212 213 # handle Python 2 OrderedDict behavior 214 if hasattr(OrderedDict, 'iteritems'): 215
216 - def __iter__(self):
217 return iter(self.iterhits())
218 219 @property
220 - def hits(self):
221 """Hit objects contained in the QueryResult.""" 222 return self._items.values()
223 224 @property
225 - def hit_keys(self):
226 """Hit IDs of the Hit objects contained in the QueryResult.""" 227 return self._items.keys()
228 229 @property
230 - def items(self):
231 """List of tuples of Hit IDs and Hit objects.""" 232 return self._items.items()
233
234 - def iterhits(self):
235 """Returns an iterator over the Hit objects.""" 236 for hit in self._items.values(): 237 yield hit
238
239 - def iterhit_keys(self):
240 """Returns an iterator over the ID of the Hit objects.""" 241 for hit_id in self._items.keys(): 242 yield hit_id
243
244 - def iteritems(self):
245 """Returns an iterator yielding tuples of Hit ID and Hit objects.""" 246 for item in self._items.items(): 247 yield item
248 249 else: 250
251 - def __iter__(self):
252 return iter(self.hits)
253 254 @property
255 - def hits(self):
256 """Hit objects contained in the QueryResult.""" 257 return list(self._items.values())
258 259 @property
260 - def hit_keys(self):
261 """Hit IDs of the Hit objects contained in the QueryResult.""" 262 return list(self._items.keys())
263 264 @property
265 - def items(self):
266 """List of tuples of Hit IDs and Hit objects.""" 267 return list(self._items.items())
268
269 - def iterhits(self):
270 """Returns an iterator over the Hit objects.""" 271 for hit in self._items.values(): 272 yield hit
273
274 - def iterhit_keys(self):
275 """Returns an iterator over the ID of the Hit objects.""" 276 for hit_id in self._items: 277 yield hit_id
278
279 - def iteritems(self):
280 """Returns an iterator yielding tuples of Hit ID and Hit objects.""" 281 for item in self._items.items(): 282 yield item
283
284 - def __contains__(self, hit_key):
285 if isinstance(hit_key, Hit): 286 return self._hit_key_function(hit_key) in self._items 287 return hit_key in self._items
288
289 - def __len__(self):
290 return len(self._items)
291 292 #Python 3:
293 - def __bool__(self):
294 return bool(self._items)
295 296 #Python 2: 297 __nonzero__= __bool__ 298
299 - def __repr__(self):
300 return "QueryResult(id=%r, %r hits)" % (self.id, len(self))
301
302 - def __str__(self):
303 lines = [] 304 305 # set program and version line 306 lines.append('Program: %s (%s)' % (self.program, self.version)) 307 308 # set query id line 309 qid_line = ' Query: %s' % self.id 310 if hasattr(self, 'seq_len'): 311 qid_line += ' (%i)' % self.seq_len 312 if self.description: 313 qid_line += trim_str('\n %s' % self.description, 80, '...') 314 lines.append(qid_line) 315 316 # set target line 317 lines.append(' Target: %s' % self.target) 318 319 # set hit lines 320 if not self.hits: 321 lines.append(' Hits: 0') 322 else: 323 lines.append(' Hits: %s %s %s' % ('-'*4, '-'*5, '-'*58)) 324 pattern = '%13s %5s %56s' 325 lines.append(pattern % ('#', '# HSP', 326 'ID + description'.ljust(58))) 327 lines.append(pattern % ('-'*4, '-'*5, '-'*58)) 328 for idx, hit in enumerate(self.hits): 329 if idx < 30: 330 hid_line = '%s %s' % (hit.id, hit.description) 331 if len(hid_line) > 58: 332 hid_line = hid_line[:55] + '...' 333 lines.append(pattern % (idx, str(len(hit)), 334 hid_line.ljust(58))) 335 elif idx > len(self.hits) - 4: 336 hid_line = '%s %s' % (hit.id, hit.description) 337 if len(hid_line) > 58: 338 hid_line = hid_line[:55] + '...' 339 lines.append(pattern % (idx, str(len(hit)), 340 hid_line.ljust(58))) 341 elif idx == 30: 342 lines.append('%14s' % '~~~') 343 344 return '\n'.join(lines)
345
346 - def __getitem__(self, hit_key):
347 # retrieval using slice objects returns another QueryResult object 348 if isinstance(hit_key, slice): 349 # should we return just a list of Hits instead of a full blown 350 # QueryResult object if it's a slice? 351 hits = list(self.hits)[hit_key] 352 obj = self.__class__(hits, self.id, self._hit_key_function) 353 self._transfer_attrs(obj) 354 return obj 355 356 # if key is an int, then retrieve the Hit at the int index 357 elif isinstance(hit_key, int): 358 return list(self._items.values())[hit_key] 359 360 # if key is a string, then do a regular dictionary retrieval 361 return self._items[hit_key]
362
363 - def __setitem__(self, hit_key, hit):
364 # only accept string keys 365 if not isinstance(hit_key, basestring): 366 raise TypeError("QueryResult object keys must be a string.") 367 # hit must be a Hit object 368 if not isinstance(hit, Hit): 369 raise TypeError("QueryResult objects can only contain Hit objects.") 370 # and it must have the same query ID as this object's ID 371 # unless it's the query ID is None (default for empty objects), in which 372 # case we want to use the hit's query ID as the query ID 373 if self.id is not None: 374 if hit.query_id != self.id: 375 raise ValueError("Expected Hit with query ID %r, found %r " 376 "instead." % (self.id, hit.query_id)) 377 else: 378 self.id = hit.query_id 379 # same thing with descriptions 380 if self.description is not None: 381 if hit.query_description != self.description: 382 raise ValueError("Expected Hit with query description %r, " 383 "found %r instead." % (self.description, 384 hit.query_description)) 385 else: 386 self.description = hit.query_description 387 388 self._items[hit_key] = hit
389
390 - def __delitem__(self, hit_key):
391 # if hit_key an integer or slice, get the corresponding key first 392 # and put it into a list 393 if isinstance(hit_key, int): 394 hit_keys = [list(self.hit_keys)[hit_key]] 395 # the same, if it's a slice 396 elif isinstance(hit_key, slice): 397 hit_keys = list(self.hit_keys)[hit_key] 398 # otherwise put it in a list 399 else: 400 hit_keys = [hit_key] 401 402 for key in hit_keys: 403 del self._items[key] 404 return
405 406 ## properties ## 407 id = optionalcascade('_id', 'query_id', """QueryResult ID string""") 408 description = optionalcascade('_description', 'query_description', 409 """QueryResult description""") 410 411 @property
412 - def hsps(self):
413 """HSP objects contained in the QueryResult.""" 414 return [hsp for hsp in chain(*self.hits)]
415 416 @property
417 - def fragments(self):
418 """HSPFragment objects contained in the QueryResult.""" 419 return [frag for frag in chain(*self.hsps)]
420 421 ## public methods ##
422 - def absorb(self, hit):
423 """Adds a Hit object to the end of QueryResult. If the QueryResult 424 already has a Hit with the same ID, append the new Hit's HSPs into 425 the existing Hit. 426 427 Arguments: 428 hit -- Hit object to absorb. 429 430 This method is used for file formats that may output the same Hit in 431 separate places, such as BLAT or Exonerate. In both formats, Hit 432 with different strands are put in different places. However, SearchIO 433 considers them to be the same as a Hit object should be all database 434 entries with the same ID, regardless of strand orientation. 435 436 """ 437 try: 438 self.append(hit) 439 except ValueError: 440 assert hit.id in self 441 for hsp in hit: 442 self[hit.id].append(hsp)
443
444 - def append(self, hit):
445 """Adds a Hit object to the end of QueryResult. 446 447 Parameters 448 hit -- Hit object to append. 449 450 Any Hit object appended must have the same `query_id` property as the 451 QueryResult's `id` property. If the hit key already exists, a 452 `ValueError` will be raised. 453 454 """ 455 # if a custom hit_key_function is supplied, use it to define th hit key 456 if self._hit_key_function is not None: 457 hit_key = self._hit_key_function(hit) 458 else: 459 hit_key = hit.id 460 461 if hit_key not in self: 462 self[hit_key] = hit 463 else: 464 raise ValueError("Hit '%s' already present in this QueryResult." % 465 hit_key)
466
467 - def hit_filter(self, func=None):
468 """Creates a new QueryResult object whose Hit objects pass the filter 469 function. 470 471 Arguments: 472 func -- Callback function that accepts a Hit object as its parameter, 473 does a boolean check, and returns True or False 474 475 Here is an example of using `hit_filter` to select Hits whose 476 description begins with the string 'Homo sapiens', case sensitive: 477 478 >>> from Bio import SearchIO 479 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 480 >>> def desc_filter(hit): 481 ... return hit.description.startswith('Homo sapiens') 482 ... 483 >>> len(qresult) 484 100 485 >>> filtered = qresult.hit_filter(desc_filter) 486 >>> len(filtered) 487 39 488 >>> print(filtered[:4]) 489 Program: blastn (2.2.27+) 490 Query: 33211 (61) 491 mir_1 492 Target: refseq_rna 493 Hits: ---- ----- ---------------------------------------------------------- 494 # # HSP ID + description 495 ---- ----- ---------------------------------------------------------- 496 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 497 1 2 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... 498 2 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... 499 3 1 gi|262205451|ref|NR_030222.1| Homo sapiens microRNA 51... 500 501 Note that instance attributes (other than the hits) from the unfiltered 502 QueryResult are retained in the filtered object. 503 504 >>> qresult.program == filtered.program 505 True 506 >>> qresult.target == filtered.target 507 True 508 509 """ 510 hits = list(filter(func, self.hits)) 511 obj = self.__class__(hits, self.id, self._hit_key_function) 512 self._transfer_attrs(obj) 513 return obj
514
515 - def hit_map(self, func=None):
516 """Creates a new QueryResult object, mapping the given function to its 517 Hits. 518 519 Arguments: 520 func -- Callback function that accepts a Hit object as its parameter and 521 also returns a Hit object. 522 523 Here is an example of using `hit_map` with a function that discards all 524 HSPs in a Hit except for the first one: 525 526 >>> from Bio import SearchIO 527 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 528 >>> print(qresult[:8]) 529 Program: blastn (2.2.27+) 530 Query: 33211 (61) 531 mir_1 532 Target: refseq_rna 533 Hits: ---- ----- ---------------------------------------------------------- 534 # # HSP ID + description 535 ---- ----- ---------------------------------------------------------- 536 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 537 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... 538 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... 539 3 2 gi|301171322|ref|NR_035857.1| Pan troglodytes microRNA... 540 4 1 gi|301171267|ref|NR_035851.1| Pan troglodytes microRNA... 541 5 2 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... 542 6 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... 543 7 1 gi|301171259|ref|NR_035850.1| Pan troglodytes microRNA... 544 545 >>> top_hsp = lambda hit: hit[:1] 546 >>> mapped_qresult = qresult.hit_map(top_hsp) 547 >>> print(mapped_qresult[:8]) 548 Program: blastn (2.2.27+) 549 Query: 33211 (61) 550 mir_1 551 Target: refseq_rna 552 Hits: ---- ----- ---------------------------------------------------------- 553 # # HSP ID + description 554 ---- ----- ---------------------------------------------------------- 555 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 556 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... 557 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... 558 3 1 gi|301171322|ref|NR_035857.1| Pan troglodytes microRNA... 559 4 1 gi|301171267|ref|NR_035851.1| Pan troglodytes microRNA... 560 5 1 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... 561 6 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... 562 7 1 gi|301171259|ref|NR_035850.1| Pan troglodytes microRNA... 563 564 """ 565 hits = [deepcopy(hit) for hit in self.hits] 566 if func is not None: 567 hits = [func(x) for x in hits] 568 obj = self.__class__(hits, self.id, self._hit_key_function) 569 self._transfer_attrs(obj) 570 return obj
571
572 - def hsp_filter(self, func=None):
573 """Creates a new QueryResult object whose HSP objects pass the filter 574 function. 575 576 `hsp_filter` is the same as `hit_filter`, except that it filters 577 directly on each HSP object in every Hit. If the filtering removes 578 all HSP objects in a given Hit, the entire Hit will be discarded. This 579 will result in the QueryResult having less Hit after filtering. 580 581 """ 582 hits = [x for x in (hit.filter(func) for hit in self.hits) if x] 583 obj = self.__class__(hits, self.id, self._hit_key_function) 584 self._transfer_attrs(obj) 585 return obj
586
587 - def hsp_map(self, func=None):
588 """Creates a new QueryResult object, mapping the given function to its 589 HSPs. 590 591 `hsp_map` is the same as `hit_map`, except that it applies the given 592 function to all HSP objects in every Hit, instead of the Hit objects. 593 594 """ 595 hits = [x for x in (hit.map(func) for hit in list(self.hits)[:]) if x] 596 obj = self.__class__(hits, self.id, self._hit_key_function) 597 self._transfer_attrs(obj) 598 return obj
599 600 # marker for default self.pop() return value 601 # this method is adapted from Python's built in OrderedDict.pop 602 # implementation 603 __marker = object() 604
605 - def pop(self, hit_key=-1, default=__marker):
606 """Removes the specified hit key and return the Hit object. 607 608 Arguments: 609 hit_key -- Integer index or string of hit key that points to a Hit 610 object. 611 default -- Value that will be returned if the Hit object with the 612 specified index or hit key is not found. 613 614 By default, `pop` will remove and return the last Hit object in the 615 QueryResult object. To remove specific Hit objects, you can use its 616 integer index or hit key. 617 618 >>> from Bio import SearchIO 619 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 620 >>> len(qresult) 621 100 622 >>> for hit in qresult[:5]: 623 ... print(hit.id) 624 ... 625 gi|262205317|ref|NR_030195.1| 626 gi|301171311|ref|NR_035856.1| 627 gi|270133242|ref|NR_032573.1| 628 gi|301171322|ref|NR_035857.1| 629 gi|301171267|ref|NR_035851.1| 630 631 # remove the last hit 632 >>> qresult.pop() 633 Hit(id='gi|397513516|ref|XM_003827011.1|', query_id='33211', 1 hsps) 634 635 # remove the first hit 636 >>> qresult.pop(0) 637 Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) 638 639 # remove hit with the given ID 640 >>> qresult.pop('gi|301171322|ref|NR_035857.1|') 641 Hit(id='gi|301171322|ref|NR_035857.1|', query_id='33211', 2 hsps) 642 643 """ 644 # if key is an integer (index) 645 # get the ID for the Hit object at that index 646 if isinstance(hit_key, int): 647 # raise the appropriate error if there is no hit 648 if not self: 649 raise IndexError("pop from empty list") 650 hit_key = list(self.hit_keys)[hit_key] 651 652 try: 653 return self._items.pop(hit_key) 654 except KeyError: 655 # if key doesn't exist and no default is set, raise a KeyError 656 if default is self.__marker: 657 raise KeyError(hit_key) 658 # if key doesn't exist but a default is set, return the default value 659 return default
660
661 - def index(self, hit_key):
662 """Returns the index of a given hit key, zero-based. 663 664 Arguments: 665 hit_key -- Hit ID string to look up. 666 667 This method is useful for finding out the integer index (usually 668 correlated with search rank) of a given hit key. 669 670 >>> from Bio import SearchIO 671 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 672 >>> qresult.index('gi|301171259|ref|NR_035850.1|') 673 7 674 675 """ 676 if isinstance(hit_key, Hit): 677 return list(self.hit_keys).index(hit_key.id) 678 return list(self.hit_keys).index(hit_key)
679
680 - def sort(self, key=None, reverse=False, in_place=True):
681 # no cmp argument to make sort more Python 3-like 682 """Sorts the Hit objects. 683 684 Arguments: 685 key -- Function used to sort the Hit objects. 686 reverse -- Boolean, whether to reverse the sorting or not. 687 in_place -- Boolean, whether to perform sorting in place (in the same 688 object) or not (creating a new object). 689 690 `sort` defaults to sorting in-place, to mimick Python's `list.sort` 691 method. If you set the `in_place` argument to False, it will treat 692 return a new, sorted QueryResult object and keep the initial one 693 unsorted. 694 695 """ 696 if key is None: 697 # if reverse is True, reverse the hits 698 if reverse: 699 sorted_hits = list(self.hits)[::-1] 700 # otherwise (default options) make a copy of the hits 701 else: 702 sorted_hits = list(self.hits)[:] 703 else: 704 sorted_hits = sorted(self.hits, key=key, reverse=reverse) 705 706 # if sorting is in-place, don't create a new QueryResult object 707 if in_place: 708 new_hits = OrderedDict() 709 for hit in sorted_hits: 710 new_hits[self._hit_key_function(hit)] = hit 711 self._items = new_hits 712 # otherwise, return a new sorted QueryResult object 713 else: 714 obj = self.__class__(sorted_hits, self.id, self._hit_key_function) 715 self._transfer_attrs(obj) 716 return obj
717 718 719 # if not used as a module, run the doctest 720 if __name__ == "__main__": 721 from Bio._utils import run_doctest 722 run_doctest() 723