class SimpleDnMedium(DnMedium): def __init__(self) -> None: self.msgs = IntervalTree() def add_dn(self, msg: LoraMsg) -> None: t0 = Simulation.time2ticks(msg.xbeg) t1 = t0 + Simulation.time2ticks(msg.tpreamble()) self.msgs[t0:t1] = msg @staticmethod def overlap(i1: Interval, i2: Interval) -> int: return min(i1.end, i2.end) - max(i1.begin, i2.begin) # type: ignore def get_dn(self, rxon: int, rxtout: int, freq: int, rps: int, nsym: int = 4) -> Optional[LoraMsg]: rxw = Interval(rxon, rxon + rxtout) tpn = Simulation.time2ticks(LoraMsg.symtime(rps, nsym)) for i in self.msgs.overlap(rxw[0], rxw[1]): m = i.data # type: LoraMsg if m.match(freq, rps) and SimpleDnMedium.overlap(i, rxw) >= tpn: break else: return None self.msgs.remove(i) return m def prune(self, ticks: int) -> None: exp = self.msgs.envelop(0, ticks) if exp: self.msgs.remove_envelop(0, ticks) return exp
def to_intervaltree(data, t=None): """Create an intervaltree of all elements (elements, units, ...). :param t: :param data: """ if t is None: t = IntervalTree() overlaps = [] existing_values = [] existing_a_tags = [] for token, slices, _type in data: _from, _to = slices t[_from:_to] = (token, _type) if _type[0] == 'restricted_area': overlaps.append((_from, _to, token, _type)) a, b = token if a == 'a': existing_values.append(b) existing_a_tags.append((_from, _to)) # remove all elements in restricted_areas if overlaps: for begin, end, token, _type in overlaps: t.remove_envelop(begin, end) return t, existing_values, existing_a_tags
def run_batches(inputArray, threshold, batchsize=1, WM_size=sys.maxsize, ssResolver=None, verbose=False): ''' Seperates the input array in data batches and executes oPIEC for each batch, sequentially. The support set, the set of computed intervals and the remaining auxilary data are being updated between executions of oPIEC. inputArray <- List of probability values. threshold <- Lower bound of accepted interval probability. batchsize <- The length of each data batch. WM_size <- The maximum number of elements in the support set. ssResolver <- A tuple (funcName, helpData) where funcName is the name of the function employed for support set maintenance and helpData is a data structure with auxiliary information needed for ${funcName} (sometimes helpData is None). verbose <- blah blah. ''' def generate_batches(inputArray, batchsize): '''Create as many data batches with length of ${batchsize} as possible.''' for i in range(0, len(inputArray), batchsize): yield inputArray[i:i + batchsize] batch_generator = generate_batches(inputArray, batchsize) prev_prefix = 0 support_set = None resultTree = IntervalTree() ignore_value = sys.maxsize end_timestamp = -1 for batch in batch_generator: # Execute oPIEC and update information. batch_intervals, support_set, prev_prefix, ignore_value, end_timestamp = oPIEC( batch, threshold=threshold, start_timestamp=end_timestamp + 1, ignore_value=ignore_value, support_set=support_set, prev_prefix=prev_prefix, WM_size=WM_size, ssResolver=ssResolver, verbose=verbose) if verbose: print("Intervals of batch: " + str(batch_intervals)) for inter in batch_intervals: start = inter[0][0] end = inter[0][1] + 1 #Because they are right open prob = inter[1] resultTree.remove_envelop(start, end) tree_add_merge(resultTree, start, end, prob) #resultTree[start:end]=prob return stripIntervalTree(sorted(resultTree))
def mergeSegments(self,segs1,segs2,ignoreInsideEnvelope=True): """ Given two segmentations of the same file, return the merged set of them Two similar segments should be replaced by their union Those that are inside another should be removed (?) or the too-large one deleted? If ignoreInsideEnvelope is true this is the first of those, otherwise the second """ from intervaltree import Interval, IntervalTree t = IntervalTree() # Put the first set into the tree for s in segs1: t[s[0]:s[1]] = s # Decide whether or not to put each segment in the second set in for s in segs2: overlaps = t.search(s[0],s[1]) # If there are no overlaps, add it if len(overlaps)==0: t[s[0]:s[1]] = s else: # Search for any enveloped, if there are remove and add the new one envelops = t.search(s[0],s[1],strict=True) if len(envelops) > 0: if ignoreInsideEnvelope: # Remove any inside the envelope of the test point t.remove_envelop(s[0],s[1]) overlaps = t.search(s[0], s[1]) #print s[0], s[1], overlaps # Open out the region, delete the other for o in overlaps: if o.begin < s[0]: s[0] = o.begin t.remove(o) if o.end > s[1]: s[1] = o.end t.remove(o) t[s[0]:s[1]] = s else: # Check for those that intersect the ends, widen them out a bit for o in overlaps: if o.begin > s[0]: t[s[0]:o[1]] = (s[0],o[1]) t.remove(o) if o.end < s[1]: t[o[0]:s[1]] = (o[0],s[1]) t.remove(o) segs = [] for a in t: segs.append([a[0],a[1]]) return segs
class SimpleMedium(Medium): def __init__(self, put_up: Optional[Callable[[LoraMsg], None]]) -> None: self._put_up = put_up self.msgs = IntervalTree() def reset_medium(self) -> None: self.msgs.clear() def add_dn(self, msg: LoraMsg) -> None: t0 = Simulation.time2ticks(msg.xbeg) t1 = t0 + Simulation.time2ticks(msg.tpreamble()) self.msgs[t0:t1] = msg @staticmethod def overlap(i1: Interval, i2: Interval) -> int: return min(i1.end, i2.end) - max(i1.begin, i2.begin) # type: ignore def get_dn(self, rxon: int, rxtout: int, freq: int, rps: int, nsym: int = 4, peek=False) -> Optional[LoraMsg]: rxw = Interval(rxon, rxon + rxtout) tpn = Simulation.time2ticks(LoraMsg.symtime(rps, nsym)) for i in self.msgs.overlap(rxw[0], rxw[1]): m = i.data # type: LoraMsg if m.match(freq, rps) and (peek or SimpleMedium.overlap(i, rxw) >= tpn): break else: return None if not peek: self.msgs.remove(i) return m def prune(self, ticks: int) -> List[LoraMsg]: exp = cast(List[Interval], self.msgs.envelop(0, ticks)) if exp: self.msgs.remove_envelop(0, ticks) return [iv[2] for iv in exp]