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 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.itervalues(): 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: 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.iteritems(): 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 length = len(self) 359 if 0 <= hit_key < length: 360 for idx, item in enumerate(self.iterhits()): 361 if idx == hit_key: 362 return item 363 elif -1 * length <= hit_key < 0: 364 for idx, item in enumerate(self.iterhits()): 365 if length + hit_key == idx: 366 return item 367 raise IndexError("list index out of range") 368 369 # if key is a string, then do a regular dictionary retrieval 370 return self._items[hit_key]
371
372 - def __setitem__(self, hit_key, hit):
373 # only accept string keys 374 if not isinstance(hit_key, basestring): 375 raise TypeError("QueryResult object keys must be a string.") 376 # hit must be a Hit object 377 if not isinstance(hit, Hit): 378 raise TypeError("QueryResult objects can only contain Hit objects.") 379 qid = self.id 380 hqid = hit.query_id 381 # and it must have the same query ID as this object's ID 382 # unless it's the query ID is None (default for empty objects), in which 383 # case we want to use the hit's query ID as the query ID 384 if qid is not None: 385 if hqid != qid: 386 raise ValueError("Expected Hit with query ID %r, found %r " 387 "instead." % (qid, hqid)) 388 else: 389 self.id = hqid 390 # same thing with descriptions 391 qdesc = self.description 392 hqdesc = hit.query_description 393 if qdesc is not None: 394 if hqdesc != qdesc: 395 raise ValueError("Expected Hit with query description %r, " 396 "found %r instead." % (qdesc, hqdesc)) 397 else: 398 self.description = hqdesc 399 400 self._items[hit_key] = hit
401
402 - def __delitem__(self, hit_key):
403 # if hit_key an integer or slice, get the corresponding key first 404 # and put it into a list 405 if isinstance(hit_key, int): 406 hit_keys = [list(self.hit_keys)[hit_key]] 407 # the same, if it's a slice 408 elif isinstance(hit_key, slice): 409 hit_keys = list(self.hit_keys)[hit_key] 410 # otherwise put it in a list 411 else: 412 hit_keys = [hit_key] 413 414 for key in hit_keys: 415 del self._items[key] 416 return
417 418 ## properties ## 419 id = optionalcascade('_id', 'query_id', """QueryResult ID string""") 420 description = optionalcascade('_description', 'query_description', 421 """QueryResult description""") 422 423 @property
424 - def hsps(self):
425 """HSP objects contained in the QueryResult.""" 426 return [hsp for hsp in chain(*self.hits)]
427 428 @property
429 - def fragments(self):
430 """HSPFragment objects contained in the QueryResult.""" 431 return [frag for frag in chain(*self.hsps)]
432 433 ## public methods ##
434 - def absorb(self, hit):
435 """Adds a Hit object to the end of QueryResult. If the QueryResult 436 already has a Hit with the same ID, append the new Hit's HSPs into 437 the existing Hit. 438 439 Arguments: 440 hit -- Hit object to absorb. 441 442 This method is used for file formats that may output the same Hit in 443 separate places, such as BLAT or Exonerate. In both formats, Hit 444 with different strands are put in different places. However, SearchIO 445 considers them to be the same as a Hit object should be all database 446 entries with the same ID, regardless of strand orientation. 447 448 """ 449 try: 450 self.append(hit) 451 except ValueError: 452 assert hit.id in self 453 for hsp in hit: 454 self[hit.id].append(hsp)
455
456 - def append(self, hit):
457 """Adds a Hit object to the end of QueryResult. 458 459 Parameters 460 hit -- Hit object to append. 461 462 Any Hit object appended must have the same `query_id` property as the 463 QueryResult's `id` property. If the hit key already exists, a 464 `ValueError` will be raised. 465 466 """ 467 # if a custom hit_key_function is supplied, use it to define th hit key 468 if self._hit_key_function is not None: 469 hit_key = self._hit_key_function(hit) 470 else: 471 hit_key = hit.id 472 473 if hit_key not in self: 474 self[hit_key] = hit 475 else: 476 raise ValueError("Hit '%s' already present in this QueryResult." % 477 hit_key)
478
479 - def hit_filter(self, func=None):
480 """Creates a new QueryResult object whose Hit objects pass the filter 481 function. 482 483 Arguments: 484 func -- Callback function that accepts a Hit object as its parameter, 485 does a boolean check, and returns True or False 486 487 Here is an example of using `hit_filter` to select Hits whose 488 description begins with the string 'Homo sapiens', case sensitive: 489 490 >>> from Bio import SearchIO 491 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 492 >>> def desc_filter(hit): 493 ... return hit.description.startswith('Homo sapiens') 494 ... 495 >>> len(qresult) 496 100 497 >>> filtered = qresult.hit_filter(desc_filter) 498 >>> len(filtered) 499 39 500 >>> print(filtered[:4]) 501 Program: blastn (2.2.27+) 502 Query: 33211 (61) 503 mir_1 504 Target: refseq_rna 505 Hits: ---- ----- ---------------------------------------------------------- 506 # # HSP ID + description 507 ---- ----- ---------------------------------------------------------- 508 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 509 1 2 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... 510 2 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... 511 3 1 gi|262205451|ref|NR_030222.1| Homo sapiens microRNA 51... 512 513 Note that instance attributes (other than the hits) from the unfiltered 514 QueryResult are retained in the filtered object. 515 516 >>> qresult.program == filtered.program 517 True 518 >>> qresult.target == filtered.target 519 True 520 521 """ 522 hits = list(filter(func, self.hits)) 523 obj = self.__class__(hits, self.id, self._hit_key_function) 524 self._transfer_attrs(obj) 525 return obj
526
527 - def hit_map(self, func=None):
528 """Creates a new QueryResult object, mapping the given function to its 529 Hits. 530 531 Arguments: 532 func -- Callback function that accepts a Hit object as its parameter and 533 also returns a Hit object. 534 535 Here is an example of using `hit_map` with a function that discards all 536 HSPs in a Hit except for the first one: 537 538 >>> from Bio import SearchIO 539 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 540 >>> print(qresult[:8]) 541 Program: blastn (2.2.27+) 542 Query: 33211 (61) 543 mir_1 544 Target: refseq_rna 545 Hits: ---- ----- ---------------------------------------------------------- 546 # # HSP ID + description 547 ---- ----- ---------------------------------------------------------- 548 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 549 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... 550 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... 551 3 2 gi|301171322|ref|NR_035857.1| Pan troglodytes microRNA... 552 4 1 gi|301171267|ref|NR_035851.1| Pan troglodytes microRNA... 553 5 2 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... 554 6 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... 555 7 1 gi|301171259|ref|NR_035850.1| Pan troglodytes microRNA... 556 557 >>> top_hsp = lambda hit: hit[:1] 558 >>> mapped_qresult = qresult.hit_map(top_hsp) 559 >>> print(mapped_qresult[:8]) 560 Program: blastn (2.2.27+) 561 Query: 33211 (61) 562 mir_1 563 Target: refseq_rna 564 Hits: ---- ----- ---------------------------------------------------------- 565 # # HSP ID + description 566 ---- ----- ---------------------------------------------------------- 567 0 1 gi|262205317|ref|NR_030195.1| Homo sapiens microRNA 52... 568 1 1 gi|301171311|ref|NR_035856.1| Pan troglodytes microRNA... 569 2 1 gi|270133242|ref|NR_032573.1| Macaca mulatta microRNA ... 570 3 1 gi|301171322|ref|NR_035857.1| Pan troglodytes microRNA... 571 4 1 gi|301171267|ref|NR_035851.1| Pan troglodytes microRNA... 572 5 1 gi|262205330|ref|NR_030198.1| Homo sapiens microRNA 52... 573 6 1 gi|262205302|ref|NR_030191.1| Homo sapiens microRNA 51... 574 7 1 gi|301171259|ref|NR_035850.1| Pan troglodytes microRNA... 575 576 """ 577 hits = [deepcopy(hit) for hit in self.hits] 578 if func is not None: 579 hits = [func(x) for x in hits] 580 obj = self.__class__(hits, self.id, self._hit_key_function) 581 self._transfer_attrs(obj) 582 return obj
583
584 - def hsp_filter(self, func=None):
585 """Creates a new QueryResult object whose HSP objects pass the filter 586 function. 587 588 `hsp_filter` is the same as `hit_filter`, except that it filters 589 directly on each HSP object in every Hit. If the filtering removes 590 all HSP objects in a given Hit, the entire Hit will be discarded. This 591 will result in the QueryResult having less Hit after filtering. 592 593 """ 594 hits = [x for x in (hit.filter(func) for hit in self.hits) if x] 595 obj = self.__class__(hits, self.id, self._hit_key_function) 596 self._transfer_attrs(obj) 597 return obj
598
599 - def hsp_map(self, func=None):
600 """Creates a new QueryResult object, mapping the given function to its 601 HSPs. 602 603 `hsp_map` is the same as `hit_map`, except that it applies the given 604 function to all HSP objects in every Hit, instead of the Hit objects. 605 606 """ 607 hits = [x for x in (hit.map(func) for hit in list(self.hits)[:]) if x] 608 obj = self.__class__(hits, self.id, self._hit_key_function) 609 self._transfer_attrs(obj) 610 return obj
611 612 # marker for default self.pop() return value 613 # this method is adapted from Python's built in OrderedDict.pop 614 # implementation 615 __marker = object() 616
617 - def pop(self, hit_key=-1, default=__marker):
618 """Removes the specified hit key and return the Hit object. 619 620 Arguments: 621 hit_key -- Integer index or string of hit key that points to a Hit 622 object. 623 default -- Value that will be returned if the Hit object with the 624 specified index or hit key is not found. 625 626 By default, `pop` will remove and return the last Hit object in the 627 QueryResult object. To remove specific Hit objects, you can use its 628 integer index or hit key. 629 630 >>> from Bio import SearchIO 631 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 632 >>> len(qresult) 633 100 634 >>> for hit in qresult[:5]: 635 ... print(hit.id) 636 ... 637 gi|262205317|ref|NR_030195.1| 638 gi|301171311|ref|NR_035856.1| 639 gi|270133242|ref|NR_032573.1| 640 gi|301171322|ref|NR_035857.1| 641 gi|301171267|ref|NR_035851.1| 642 643 # remove the last hit 644 >>> qresult.pop() 645 Hit(id='gi|397513516|ref|XM_003827011.1|', query_id='33211', 1 hsps) 646 647 # remove the first hit 648 >>> qresult.pop(0) 649 Hit(id='gi|262205317|ref|NR_030195.1|', query_id='33211', 1 hsps) 650 651 # remove hit with the given ID 652 >>> qresult.pop('gi|301171322|ref|NR_035857.1|') 653 Hit(id='gi|301171322|ref|NR_035857.1|', query_id='33211', 2 hsps) 654 655 """ 656 # if key is an integer (index) 657 # get the ID for the Hit object at that index 658 if isinstance(hit_key, int): 659 # raise the appropriate error if there is no hit 660 if not self: 661 raise IndexError("pop from empty list") 662 hit_key = list(self.hit_keys)[hit_key] 663 664 try: 665 return self._items.pop(hit_key) 666 except KeyError: 667 # if key doesn't exist and no default is set, raise a KeyError 668 if default is self.__marker: 669 raise KeyError(hit_key) 670 # if key doesn't exist but a default is set, return the default value 671 return default
672
673 - def index(self, hit_key):
674 """Returns the index of a given hit key, zero-based. 675 676 Arguments: 677 hit_key -- Hit ID string to look up. 678 679 This method is useful for finding out the integer index (usually 680 correlated with search rank) of a given hit key. 681 682 >>> from Bio import SearchIO 683 >>> qresult = next(SearchIO.parse('Blast/mirna.xml', 'blast-xml')) 684 >>> qresult.index('gi|301171259|ref|NR_035850.1|') 685 7 686 687 """ 688 if isinstance(hit_key, Hit): 689 return list(self.hit_keys).index(hit_key.id) 690 return list(self.hit_keys).index(hit_key)
691
692 - def sort(self, key=None, reverse=False, in_place=True):
693 # no cmp argument to make sort more Python 3-like 694 """Sorts the Hit objects. 695 696 Arguments: 697 key -- Function used to sort the Hit objects. 698 reverse -- Boolean, whether to reverse the sorting or not. 699 in_place -- Boolean, whether to perform sorting in place (in the same 700 object) or not (creating a new object). 701 702 `sort` defaults to sorting in-place, to mimick Python's `list.sort` 703 method. If you set the `in_place` argument to False, it will treat 704 return a new, sorted QueryResult object and keep the initial one 705 unsorted. 706 707 """ 708 if key is None: 709 # if reverse is True, reverse the hits 710 if reverse: 711 sorted_hits = list(self.hits)[::-1] 712 # otherwise (default options) make a copy of the hits 713 else: 714 sorted_hits = list(self.hits)[:] 715 else: 716 sorted_hits = sorted(self.hits, key=key, reverse=reverse) 717 718 # if sorting is in-place, don't create a new QueryResult object 719 if in_place: 720 new_hits = OrderedDict() 721 for hit in sorted_hits: 722 new_hits[self._hit_key_function(hit)] = hit 723 self._items = new_hits 724 # otherwise, return a new sorted QueryResult object 725 else: 726 obj = self.__class__(sorted_hits, self.id, self._hit_key_function) 727 self._transfer_attrs(obj) 728 return obj
729 730 731 # if not used as a module, run the doctest 732 if __name__ == "__main__": 733 from Bio._utils import run_doctest 734 run_doctest() 735