Mercurial > repos > yufei-luo > s_mart
comparison SMART/Java/Python/structure/Interval.py @ 6:769e306b7933
Change the repository level.
author | yufei-luo |
---|---|
date | Fri, 18 Jan 2013 04:54:14 -0500 |
parents | |
children | 94ab73e8a190 |
comparison
equal
deleted
inserted
replaced
5:ea3082881bf8 | 6:769e306b7933 |
---|---|
1 # | |
2 # Copyright INRA-URGI 2009-2010 | |
3 # | |
4 # This software is governed by the CeCILL license under French law and | |
5 # abiding by the rules of distribution of free software. You can use, | |
6 # modify and/ or redistribute the software under the terms of the CeCILL | |
7 # license as circulated by CEA, CNRS and INRIA at the following URL | |
8 # "http://www.cecill.info". | |
9 # | |
10 # As a counterpart to the access to the source code and rights to copy, | |
11 # modify and redistribute granted by the license, users are provided only | |
12 # with a limited warranty and the software's author, the holder of the | |
13 # economic rights, and the successive licensors have only limited | |
14 # liability. | |
15 # | |
16 # In this respect, the user's attention is drawn to the risks associated | |
17 # with loading, using, modifying and/or developing or reproducing the | |
18 # software by the user in light of its specific status of free software, | |
19 # that may mean that it is complicated to manipulate, and that also | |
20 # therefore means that it is reserved for developers and experienced | |
21 # professionals having in-depth computer knowledge. Users are therefore | |
22 # encouraged to load and test the software's suitability as regards their | |
23 # requirements in conditions enabling the security of their systems and/or | |
24 # data to be ensured and, more generally, to use and operate it in the | |
25 # same conditions as regards security. | |
26 # | |
27 # The fact that you are presently reading this means that you have had | |
28 # knowledge of the CeCILL license and that you accept its terms. | |
29 # | |
30 | |
31 from SMART.Java.Python.structure.Bins import * | |
32 from commons.core.coord.Range import Range | |
33 | |
34 class Interval(Range): | |
35 """ | |
36 Store a genomic interval | |
37 @ivar name: name of the interval [optional] | |
38 @type name: string | |
39 @ivar id: id of the interval [optional] | |
40 @type id: int | |
41 @ivar bin: bin in which the interval should be if stored in a database [computed] | |
42 @type bin: int | |
43 @ival tags: information about the transcript [optional] | |
44 @type tags: dict | |
45 @ivar verbosity: verbosity | |
46 @type verbosity: int [default: 0] | |
47 """ | |
48 | |
49 def __init__(self, interval = None, verbosity = 0): | |
50 """ | |
51 Constructor | |
52 @param interval: interval to be copied | |
53 @type interval: class L{Interval<Interval>} | |
54 @param verbosity: verbosity | |
55 @type verbosity: int | |
56 """ | |
57 Range.__init__(self) | |
58 self.name = None | |
59 self.id = None | |
60 self.bin = None | |
61 self.verbosity = verbosity | |
62 self.tags = {} | |
63 if interval != None: | |
64 self.copy(interval) | |
65 | |
66 #!!!! Warning: two methods getStart() and getEnd() give the information maximum and minimum in interval.!!!!# | |
67 #In case strand = "+", start < end; strand = "-", start > end | |
68 def getStart(self): | |
69 if self.start == -1: | |
70 return -1 | |
71 if self.end == -1: | |
72 return self.start | |
73 return self.getMin() | |
74 | |
75 | |
76 def getEnd(self): | |
77 if self.end == -1: | |
78 return -1 | |
79 if self.start == -1: | |
80 return self.end | |
81 return self.getMax() | |
82 | |
83 | |
84 def getChromosome(self): | |
85 return self.getSeqname() | |
86 | |
87 | |
88 def getDirection(self): | |
89 return 1 if self.getStrand() == "+" else -1 | |
90 | |
91 | |
92 def getName(self): | |
93 return self.name | |
94 | |
95 | |
96 def isSet(self): | |
97 """ | |
98 Check if the interval is set | |
99 """ | |
100 return self.getStart() == None and self.getEnd() == None | |
101 | |
102 | |
103 def copy(self, interval): | |
104 """ | |
105 Copy method | |
106 @param interval: interval to be copied | |
107 @type interval: class L{Interval<Interval>} | |
108 """ | |
109 self.setStart(interval.getStart()) | |
110 self.setEnd(interval.getEnd()) | |
111 self.setChromosome(interval.getChromosome()) | |
112 self.setDirection(interval.getDirection()) | |
113 self.name = interval.name | |
114 self.id = interval.id | |
115 self.bin = interval.bin | |
116 self.tags = {} | |
117 for tag in interval.tags: | |
118 self.tags[tag] = interval.tags[tag] | |
119 self.verbosity = interval.verbosity | |
120 | |
121 | |
122 def setName(self, name): | |
123 """ | |
124 Set the name | |
125 @param name: name of the interval | |
126 @type name: string | |
127 """ | |
128 if len(name) > 100: | |
129 name = name[:100] | |
130 self.name = name | |
131 | |
132 | |
133 def setChromosome(self, chromosome=""): | |
134 """ | |
135 Set the chromosome | |
136 @param chromosome: chromosome on which the interval is | |
137 @type chromosome: string | |
138 """ | |
139 if not chromosome: | |
140 self.seqname = None | |
141 else: | |
142 self.seqname = chromosome.replace(".", "_").replace("|", "_") | |
143 | |
144 | |
145 def setStart(self, start): | |
146 """ | |
147 Set the start point | |
148 Possibly reset bin | |
149 @param start: start point of the interval | |
150 @type start: int | |
151 """ | |
152 self.bin = None | |
153 direction = self.getDirection() | |
154 if self.start == -1: | |
155 self.start = start | |
156 elif self.end == -1: | |
157 self.end = start | |
158 else: | |
159 if direction == 1: | |
160 self.start = start | |
161 else: | |
162 self.end = start | |
163 if direction == 1: | |
164 self.start, self.end = min(self.start, self.end), max(self.start, self.end) | |
165 else: | |
166 self.start, self.end = max(self.start, self.end), min(self.start, self.end) | |
167 | |
168 | |
169 def setEnd(self, end): | |
170 """ | |
171 Set the end point | |
172 Possibly reset bin | |
173 @param end: end point of the interval of the interval | |
174 @type end: int | |
175 """ | |
176 self.bin = None | |
177 direction = self.getDirection() | |
178 if self.end == -1: | |
179 self.end = end | |
180 elif self.start == -1: | |
181 self.start = end | |
182 else: | |
183 if direction == 1: | |
184 self.end = end | |
185 else: | |
186 self.start = end | |
187 if direction == 1: | |
188 self.start, self.end = min(self.start, self.end), max(self.start, self.end) | |
189 else: | |
190 self.start, self.end = max(self.start, self.end), min(self.start, self.end) | |
191 | |
192 | |
193 def setSize(self, size): | |
194 """ | |
195 Possibly modify the end point | |
196 @param size: size of the transcript | |
197 @type size: int | |
198 """ | |
199 if self.end == None and self.start != None: | |
200 self.setEnd(self.start + self.getSize() - 1) | |
201 elif self.start == None and self.end != None: | |
202 self.setStart(self.end - self.getSize() + 1) | |
203 | |
204 | |
205 def getSize(self): | |
206 """ | |
207 Get the size | |
208 """ | |
209 return self.getEnd() - self.getStart() + 1 | |
210 | |
211 | |
212 def _setDirection(self, direction): | |
213 """ | |
214 Set the direction of the interval (connection to Range) | |
215 @param direction: direction of the transcript (+ / -) | |
216 @type direction: int (1 or -1) | |
217 """ | |
218 if direction * self.getDirection() < 0: | |
219 self.reverse() | |
220 | |
221 | |
222 def setDirection(self, direction): | |
223 """ | |
224 Set the direction of the interval | |
225 Possibly parse different formats | |
226 @param direction: direction of the transcript (+ / -) | |
227 @type direction: int or string | |
228 """ | |
229 if type(direction).__name__ == 'int': | |
230 self._setDirection(direction / abs(direction)) | |
231 elif type(direction).__name__ == 'str': | |
232 if direction == "+": | |
233 self._setDirection(1) | |
234 elif direction == "-": | |
235 self._setDirection(-1) | |
236 elif direction == "1" or direction == "-1": | |
237 self._setDirection(int(direction)) | |
238 elif direction.lower() == "plus": | |
239 self._setDirection(1) | |
240 elif direction.lower() == "minus": | |
241 self._setDirection(-1) | |
242 else: | |
243 raise Exception("Cannot understand direction %s" % (direction)) | |
244 else: | |
245 raise Exception("Cannot understand direction %s" % (direction)) | |
246 | |
247 | |
248 def extendStart(self, size): | |
249 """ | |
250 Extend the interval by the 5' end | |
251 @param size: the size to be exended | |
252 @type size: int | |
253 """ | |
254 if self.getDirection() == 1: | |
255 self.setStart(max(0, self.getStart() - size)) | |
256 else: | |
257 self.setEnd(self.getEnd() + size) | |
258 self.bin = None | |
259 | |
260 | |
261 def extendEnd(self, size): | |
262 """ | |
263 Extend the interval by the 3' end | |
264 @param size: the size to be exended | |
265 @type size: int | |
266 """ | |
267 if self.getDirection() == 1: | |
268 self.setEnd(self.getEnd() + size) | |
269 else: | |
270 self.setStart(max(0, self.getStart() - size)) | |
271 self.bin = None | |
272 | |
273 | |
274 def restrictStart(self, size = 1): | |
275 """ | |
276 Restrict the interval by some nucleotides, start from its start position | |
277 Remove the exons | |
278 @param size: the size to be restricted to | |
279 @type size: int | |
280 """ | |
281 if self.getDirection() == 1: | |
282 self.setEnd(min(self.getEnd(), self.getStart() + size - 1)) | |
283 else: | |
284 self.setStart(max(self.getStart(), self.getEnd() - size + 1)) | |
285 self.bin = None | |
286 | |
287 | |
288 def restrictEnd(self, size = 1): | |
289 """ | |
290 Restrict the interval by some nucleotides, end from its end position | |
291 Remove the exons | |
292 @param size: the size to be restricted to | |
293 @type size: int | |
294 """ | |
295 if self.getDirection() == 1: | |
296 self.setStart(max(self.getStart(), self.getEnd() - size + 1)) | |
297 else: | |
298 self.setEnd(min(self.getEnd(), self.getStart() + size - 1)) | |
299 self.bin = None | |
300 | |
301 | |
302 | |
303 def setTagValue(self, name, value): | |
304 """ | |
305 Set a tag | |
306 @param name: name of the tag | |
307 @type name: string | |
308 @param value: value of the tag | |
309 @type value: int or string | |
310 """ | |
311 self.tags[name] = value | |
312 | |
313 | |
314 def getTagNames(self): | |
315 """ | |
316 Get all the names of the tags | |
317 """ | |
318 return self.tags.keys() | |
319 | |
320 | |
321 def getTagValue(self, tag): | |
322 """ | |
323 Get the value of a tag | |
324 @param tag: name of a tag | |
325 @type tag: string | |
326 """ | |
327 if tag not in self.tags: | |
328 return None | |
329 return self.tags[tag] | |
330 | |
331 | |
332 def getTagValues(self, tagSep = "; ", fieldSep = " ", surrounder = ""): | |
333 """ | |
334 Get the formatted tag values | |
335 @param tagSep: separator between tags | |
336 @type tagSep: string | |
337 @param fieldSep: separator between tag name and tag value | |
338 @type fieldSep: string | |
339 @param surrounder: string which optionally surround values | |
340 @type surrounder: string | |
341 """ | |
342 tags = [] | |
343 for name in self.tags: | |
344 value = self.tags[name] | |
345 if value == None: | |
346 continue | |
347 if isinstance(value, basestring): | |
348 tags.append("%s%s%s%s%s" % (name, fieldSep, surrounder, self.tags[name], surrounder)) | |
349 elif type(value) is int: | |
350 tags.append("%s%s%s%i%s" % (name, fieldSep, surrounder, self.tags[name], surrounder)) | |
351 elif type(value) is float: | |
352 tags.append("%s%s%s%f%s" % (name, fieldSep, surrounder, self.tags[name], surrounder)) | |
353 else: | |
354 raise Exception("Do not know how to print '" + value + "'.") | |
355 if self.getName() != None: | |
356 tags.append("%s%s%s%s%s" % ("Name", fieldSep, surrounder, self.getName(), surrounder)) | |
357 return tagSep.join(tags) | |
358 | |
359 | |
360 def setTagValues(self, tags, tagSep = "; ", fieldSep = " "): | |
361 """ | |
362 Set the tag values using given string | |
363 @param tags: the tags, concatenated | |
364 @type tags: string | |
365 @param tagSep: separator between tags | |
366 @type tagSep: string | |
367 @param fieldSep: separator between tag name and tag value | |
368 @type fieldSep: string | |
369 """ | |
370 if tags == "": | |
371 self.tags = {} | |
372 return | |
373 for splittedTag in tags.split(tagSep): | |
374 if fieldSep not in splittedTag: | |
375 raise Exception("Weird field '%s' in tags '%s'" % (splittedTag, tags)) | |
376 tag, value = splittedTag.split(fieldSep, 1) | |
377 if tag == "Name": | |
378 self.setName(value) | |
379 continue | |
380 try: | |
381 intValue = int(value) | |
382 self.tags[tag] = intValue | |
383 except ValueError: | |
384 try: | |
385 floatValue = float(value) | |
386 self.tags[tag] = floatValue | |
387 except ValueError: | |
388 self.tags[tag] = value | |
389 | |
390 | |
391 def deleteTag(self, tag): | |
392 """ | |
393 Remove a tag | |
394 @param tag: the tag to be removed | |
395 @type tag: string | |
396 """ | |
397 if tag in self.tags: | |
398 del self.tags[tag] | |
399 | |
400 | |
401 def setNbOccurrences(self, nbOccurrences): | |
402 """ | |
403 Set the number of occurrences of the interval | |
404 @param nbOccurrences: number of occurrences of the interval | |
405 @type nbOccurrences: int | |
406 """ | |
407 self.setTagValue("nbOccurrences", nbOccurrences) | |
408 | |
409 | |
410 def setOccurrence(self, occurrence): | |
411 """ | |
412 Set the occurrence of this interval | |
413 @param occurrence: an occurrence for this transcript | |
414 @type occurrence: int | |
415 """ | |
416 self.setTagValue("occurrence", occurrence) | |
417 | |
418 def __eq__(self, interval): | |
419 """ | |
420 Whether two intervals are equal (start and end at same position) | |
421 @param interval: object to be compared to | |
422 @type interval: class L{Interval<Interval>} | |
423 """ | |
424 if not interval: | |
425 return False | |
426 return self.getChromosome() == interval.getChromosome() and self.getStart() == interval.getStart() and self.getEnd() == interval.getEnd() and self.getDirection() == interval.getDirection() | |
427 | |
428 | |
429 def overlapWith(self, interval, nbNucleotides = 1): | |
430 """ | |
431 Whether two intervals overlap | |
432 @param interval: object to be compared to | |
433 @type interval: class L{Interval<Interval>} | |
434 @param nbNucleotides: minimum number of nucleotides to declare and overlap | |
435 @type nbNucleotides: int | |
436 """ | |
437 if self.getChromosome() != interval.getChromosome(): | |
438 return False | |
439 return (min(self.getEnd(), interval.getEnd()) - max(self.getStart(), interval.getStart()) + 1 >= nbNucleotides) | |
440 | |
441 def isIncludeIn(self, interval): | |
442 return interval.include(self) | |
443 | |
444 | |
445 def include(self, interval): | |
446 """ | |
447 Whether this interval includes the other one | |
448 @param interval: object to be compared to | |
449 @type interval: class L{Interval<Interval>} | |
450 """ | |
451 if self.getChromosome() != interval.getChromosome(): | |
452 return False | |
453 return ((self.getStart() <= interval.getStart()) and (self.getEnd() >= interval.getEnd())) | |
454 | |
455 | |
456 def getDifference(self, interval, sameStrand = False): | |
457 """ | |
458 Get the difference between this cluster and another one | |
459 @param interval: object to be compared to | |
460 @type interval: class L{Interval<Interval>} | |
461 @param sameStrand: do the comparison iff the intervals are on the same strand | |
462 @type sameStrand: boolean | |
463 @return: a (possibly empty) list of intervals | |
464 """ | |
465 newInterval = Interval() | |
466 newInterval.copy(self) | |
467 if self.getChromosome() != interval.getChromosome(): | |
468 return [newInterval] | |
469 if not self.overlapWith(interval): | |
470 return [newInterval] | |
471 if sameStrand and self.getDirection() != interval.getDirection(): | |
472 return [newInterval] | |
473 intervals = [] | |
474 if self.getStart() < interval.getStart(): | |
475 newInterval = Interval() | |
476 newInterval.copy(self) | |
477 newInterval.setEnd(min(self.getEnd(), interval.getStart() - 1)) | |
478 intervals.append(newInterval) | |
479 if self.getEnd() > interval.getEnd(): | |
480 newInterval = Interval() | |
481 newInterval.copy(self) | |
482 newInterval.setStart(max(self.getStart(), interval.getEnd() + 1)) | |
483 intervals.append(newInterval) | |
484 return intervals | |
485 | |
486 | |
487 def getIntersection(self, interval): | |
488 """ | |
489 Get the intersection between this interval and another one | |
490 @param interval: object to be compared to | |
491 @type interval: class L{Interval<Interval>} | |
492 @return: an other interval | |
493 """ | |
494 if not self.overlapWith(interval): | |
495 return None | |
496 newInterval = Interval() | |
497 newInterval.setChromosome(self.getChromosome()) | |
498 newInterval.setDirection(self.getDirection()) | |
499 newInterval.setName("%s_intersect_%s" % (self.getName(), interval.getName())) | |
500 newInterval.setStart(max(self.getStart(), interval.getStart())) | |
501 newInterval.setEnd(min(self.getEnd(), interval.getEnd())) | |
502 return newInterval | |
503 | |
504 | |
505 def getDistance(self, interval): | |
506 """ | |
507 Get the distance between two intervals (a non-negative value) | |
508 @param interval: another interval | |
509 @type interval: class L{Interval<Interval>} | |
510 """ | |
511 if self.overlapWith(interval): | |
512 return 0 | |
513 if self.getChromosome() != interval.getChromosome(): | |
514 raise Exception("Cannot get the distance between %s and %s" % (str(self), str(interval))) | |
515 return min(abs(self.getStart() - interval.getEnd()), abs(self.getEnd() - interval.getStart())) | |
516 | |
517 | |
518 def getRelativeDistance(self, interval): | |
519 """ | |
520 Get the distance between two intervals (negative if first interval is before) | |
521 @param interval: another interval | |
522 @type interval: class L{Interval<Interval>} | |
523 """ | |
524 if self.overlapWith(interval): | |
525 return 0 | |
526 if self.getChromosome() != interval.getChromosome(): | |
527 raise Exception("Cannot get the distance between %s and %s" % (str(self), str(interval))) | |
528 if self.getEnd() < interval.getStart(): | |
529 distance = interval.getStart() - self.getEnd() | |
530 else: | |
531 distance = interval.getEnd() - self.getStart() | |
532 distance *= self.getDirection() | |
533 return distance | |
534 | |
535 | |
536 def merge(self, interval, normalization = False): | |
537 """ | |
538 Merge two intervals | |
539 @param interval: another interval | |
540 @type interval: class L{Interval<Interval>} | |
541 @param normalization: whether the sum of the merge should be normalized wrt the number of mappings of each elements | |
542 @type normalization: boolean | |
543 """ | |
544 if self.getChromosome() != interval.getChromosome(): | |
545 raise Exception("Cannot merge '%s' and '%s' for they are on different chromosomes." % (str(self), str(interval))) | |
546 direction = None | |
547 if self.getStart() == self.getEnd(): | |
548 direction = interval.getDirection() | |
549 elif interval.getStart() == interval.getEnd(): | |
550 direction = self.getDirection() | |
551 elif self.getDirection() != interval.getDirection(): | |
552 raise Exception("Cannot merge '%s' and '%s' for they are on different strands." % (str(self), str(interval))) | |
553 self.setStart(min(self.getStart(), interval.getStart())) | |
554 self.setEnd(max(self.getEnd(), interval.getEnd())) | |
555 if direction != None: | |
556 self.setDirection(direction) | |
557 nbElements = 0.0 | |
558 for element in (self, interval): | |
559 for tagName in ("nbElements", "nbOccurrences"): | |
560 if tagName not in element.getTagNames(): | |
561 element.setTagValue(tagName, 1) | |
562 nbElements += float(element.getTagValue("nbElements")) / float(element.getTagValue("nbOccurrences")) if normalization else float(element.getTagValue("nbElements")) | |
563 self.setTagValue("nbElements", nbElements) | |
564 self.bin = None | |
565 for tagName in ("identity", "nbOccurrences", "occurrence", "nbMismatches", "nbGaps", "rank", "evalue", "bestRegion"): | |
566 if tagName in self.getTagNames(): | |
567 del self.tags[tagName] | |
568 | |
569 | |
570 def getBin(self): | |
571 """ | |
572 Get the bin of the interval | |
573 Computed on the fly | |
574 """ | |
575 if self.bin == None: | |
576 self.bin = getBin(self.getStart(), self.getEnd()) | |
577 return self.bin | |
578 | |
579 | |
580 def getBins(self): | |
581 """ | |
582 Get all the bin this interval could fall into | |
583 """ | |
584 return getOverlappingBins(self.getStart(), self.getEnd()) | |
585 | |
586 | |
587 def getSqlVariables(cls): | |
588 """ | |
589 Get the properties of the object that should be saved in a database | |
590 """ | |
591 variables = ["name", "chromosome", "start", "end", "direction", "tags", "bin"] | |
592 return variables | |
593 getSqlVariables = classmethod(getSqlVariables) | |
594 | |
595 | |
596 def setSqlValues(self, array): | |
597 """ | |
598 Set the values of the properties of this object as given by a results line of a SQL query | |
599 """ | |
600 self.id = array[0] | |
601 self.name = array[1].strip("'") | |
602 self.setChromosome(array[2].strip("'")) | |
603 self.setStart(array[3]) | |
604 self.setEnd(array[4]) | |
605 self.setDirection(array[5]) | |
606 self.setTagValues(array[6].strip("'"), ";", "=") | |
607 self.bin = array[7] | |
608 | |
609 | |
610 def getSqlValues(self): | |
611 """ | |
612 Get the values of the properties that should be saved in a database | |
613 """ | |
614 values = dict() | |
615 values["name"] = self.name | |
616 values["chromosome"] = self.getChromosome() | |
617 values["start"] = self.getStart() | |
618 values["end"] = self.getEnd() | |
619 values["direction"] = self.getDirection() | |
620 values["tags"] = self.getTagValues(";", "=") | |
621 values["bin"] = self.getBin() | |
622 return values | |
623 | |
624 | |
625 def getSqlTypes(cls): | |
626 """ | |
627 Get the values of the properties that should be saved in a database | |
628 """ | |
629 types = dict() | |
630 types["name"] = "varchar" | |
631 types["chromosome"] = "varchar" | |
632 types["start"] = "int" | |
633 types["end"] = "int" | |
634 types["direction"] = "tinyint" | |
635 types["tags"] = "varchar" | |
636 types["bin"] = "int" | |
637 return types | |
638 getSqlTypes = classmethod(getSqlTypes) | |
639 | |
640 | |
641 def getSqlSizes(cls): | |
642 """ | |
643 Get the sizes of the properties that should be saved in a database | |
644 """ | |
645 sizes = dict() | |
646 sizes["name"] = 255 | |
647 sizes["chromosome"] = 255 | |
648 sizes["start"] = 11 | |
649 sizes["end"] = 11 | |
650 sizes["direction"] = 4 | |
651 sizes["tags"] = 1023 | |
652 sizes["bin"] = 11 | |
653 return sizes | |
654 getSqlSizes = classmethod(getSqlSizes) | |
655 | |
656 | |
657 def printCoordinates(self): | |
658 """ | |
659 Print start and end positions (depending on the direction of the interval) | |
660 """ | |
661 if self.getDirection() == 1: | |
662 return "%d-%d" % (self.getStart(), self.getEnd()) | |
663 else: | |
664 return "%d-%d" % (self.getEnd(), self.getStart()) | |
665 | |
666 | |
667 def extractSequence(self, parser): | |
668 """ | |
669 Get the sequence corresponding to this interval | |
670 @param parser: a parser to a FASTA file | |
671 @type parser: class L{SequenceListParser<SequenceListParser>} | |
672 @return : a instance of L{Sequence<Sequence>} | |
673 """ | |
674 return parser.getSubSequence(self.getChromosome(), self.getStart(), self.getEnd(), self.getDirection(), self.name) | |
675 | |
676 | |
677 def extractWigData(self, parser): | |
678 """ | |
679 Get the data retrieved from a wig file | |
680 @param parser: a parser class to a WIG file | |
681 @type parser: class L{WigParser<WigParser>} | |
682 """ | |
683 data = parser.getRange(self.getChromosome(), self.getStart(), self.getEnd()) | |
684 if self.getDirection() == -1: | |
685 if parser.strands: | |
686 newData = {} | |
687 for strand in data: | |
688 data[strand].reverse() | |
689 newData[-strand] = data[strand] | |
690 data = newData | |
691 else: | |
692 data.reverse() | |
693 return data | |
694 | |
695 | |
696 def __str__(self): | |
697 """ | |
698 Output a simple representation of this interval | |
699 """ | |
700 direction = "+" | |
701 if self.getDirection() == -1: | |
702 direction = "-" | |
703 string = "%s:%d-%d (%s)" % (self.getChromosome(), self.getStart(), self.getEnd(), direction) | |
704 if self.name != "": | |
705 string = "(%s) %s" % (self.name, string) | |
706 return string | |
707 |