def testIntersectSimple(self): """test RangeSet with simple intersections of ranges""" r1 = RangeSet("4-34") r2 = RangeSet("27-42") r1.intersection_update(r2) self.assertEqual(str(r1), "27-34") self.assertEqual(len(r1), 8) r1 = RangeSet("2-450,654-700,800") r2 = RangeSet("500-502,690-820,830-840,900") r1.intersection_update(r2) self.assertEqual(str(r1), "690-700,800") self.assertEqual(len(r1), 12) r1 = RangeSet("2-450,654-700,800") r3 = r1.intersection(r2) self.assertEqual(str(r3), "690-700,800") self.assertEqual(len(r3), 12) r1 = RangeSet("2-450,654-700,800") r3 = r1 & r2 self.assertEqual(str(r3), "690-700,800") self.assertEqual(len(r3), 12) r1 = RangeSet() r3 = r1.intersection(r2) self.assertEqual(str(r3), "") self.assertEqual(len(r3), 0)
def testIntersectionLength(self): """test RangeSet intersection/length""" r1 = RangeSet("115-117,130,166-170,4780-4999") self.assertEqual(len(r1), 229) r2 = RangeSet("116-117,130,4781-4999") self.assertEqual(len(r2), 222) res = r1.intersection(r2) self.assertEqual(len(res), 222) r1 = RangeSet("115-200") self.assertEqual(len(r1), 86) r2 = RangeSet("116-117,119,123-131,133,149,199") self.assertEqual(len(r2), 15) res = r1.intersection(r2) self.assertEqual(len(res), 15) # StopIteration test r1 = RangeSet("115-117,130,166-170,4780-4999,5003") self.assertEqual(len(r1), 230) r2 = RangeSet("116-117,130,4781-4999") self.assertEqual(len(r2), 222) res = r1.intersection(r2) self.assertEqual(len(res), 222) # StopIteration test2 r1 = RangeSet("130,166-170,4780-4999") self.assertEqual(len(r1), 226) r2 = RangeSet("116-117") self.assertEqual(len(r2), 2) res = r1.intersection(r2) self.assertEqual(len(res), 0)
def calculate_non_overlapping_range_with(self, occupied): # convert block occurrences into ranges potential_block_range = RangeSet() for occurrence in self.block_occurrences(): potential_block_range.add_range( occurrence, occurrence + self.minimum_block_length) #check the intersection with the already occupied ranges block_intersection = potential_block_range.intersection(occupied) if not block_intersection: # no overlap, return complete block_range return potential_block_range # There is overlap with occupied range # we need to deal with it real_block_range = RangeSet() for lower in potential_block_range.contiguous(): # TODO: what I really want here is a find first over a generator upper = [ x for x in block_intersection.contiguous() if x[0] >= lower[0] ] if upper: lower = lower[0] upper = upper[0][0] if lower != upper: real_block_range.add_range(lower, upper) if not real_block_range: # There is complete overlap, so return None return None # Assert: check that the first slice is not larger than potential block length! first_range = next(real_block_range.contiguous()) if first_range[-1] - first_range[0] + 1 > self.minimum_block_length: raise PartialOverlapException() return real_block_range
def calculate_non_overlapping_range_with(self, occupied): # convert block occurrences into ranges potential_block_range = RangeSet() for occurrence in self.block_occurrences(): potential_block_range.add_range(occurrence, occurrence + self.minimum_block_length) #check the intersection with the already occupied ranges block_intersection = potential_block_range.intersection(occupied) if not block_intersection: # no overlap, return complete block_range return potential_block_range # There is overlap with occupied range # we need to deal with it real_block_range = RangeSet() for lower in potential_block_range.contiguous(): # TODO: what I really want here is a find first over a generator upper = [x for x in block_intersection.contiguous() if x[0] >= lower[0]] if upper: lower = lower[0] upper = upper[0][0] if lower != upper: real_block_range.add_range(lower, upper) if not real_block_range: # There is complete overlap, so return None return None # Assert: check that the first slice is not larger than potential block length! first_range = real_block_range.contiguous().next() if first_range[-1]-first_range[0]+1>self.minimum_block_length: raise PartialOverlapException() return real_block_range