def test_create_regionset(self): bounds = Region([0, 0], [100, 100]) regionset = RegionSet(bounds=bounds) regions = bounds.random_regions(10) for region in regions: regionset.add(region) self._test_regionset(regionset, len(regions), bounds, regions)
def results(cls, alg: str, ctx: Any, *args, **kwargs) -> RegionSet: """ Compute and return the results of the query with the specified algorithm with the given context object (must have the 'dimension' attribute). Args: alg: The name of the algorithm to retrieve. ctx: The context object. args, kwargs: Additional arguments to be passed to the 'prepare' class method of the algorithm's implementation class. Returns: The resulting values for the query evaluation. """ assert alg in cls.algorithms assert ctx is not None and hasattr(ctx, 'dimension') results = RegionSet(dimension=ctx.dimension) enumerator = cls.get(alg, ctx, *args, **kwargs) for region, _ in enumerator(): results.add(region) return results
def test_regiontimeln_ordering(self): regions = RegionSet(dimension=2) regions.add(Region([0, 0], [3, 5], 'A')) regions.add(Region([3, 1], [5, 5], 'B')) regions.add(Region([2, 5], [6, 5], 'C')) bbox = regions.bbox oracle = [ [("Init" , 0, bbox), ("Begin", 0, regions[0]), ("Begin", 2, regions[2]), ("End" , 3, regions[0]), ("Begin", 3, regions[1]), ("End" , 5, regions[1]), ("End" , 6, regions[2]), ("Done" , 6, bbox)], [("Init" , 0, bbox), ("Begin", 0, regions[0]), ("Begin", 1, regions[1]), ("End" , 5, regions[0]), ("End" , 5, regions[1]), ("Begin", 5, regions[2]), ("End" , 5, regions[2]), ("Done" , 5, bbox)] ] for d in range(regions.dimension): for i, event in enumerate(regions.timeline.events(d)): #print(f'{d},{i}: {event}') self.assertEqual(event.kind, RegionEvtKind[oracle[d][i][0]]) self.assertEqual(event.when, float(oracle[d][i][1])) if event.kind == RegionEvtKind.Begin or event.kind == RegionEvtKind.End: self.assertIs(event.context, oracle[d][i][2]) self.assertTrue(-1 <= event.order <= 1) elif event.kind == RegionEvtKind.Init: self.assertEqual(i, 0) self.assertEqual(event.order, -2) else: self.assertEqual(event.order, 2)
def test_regionsweep_simple(self): regionset = RegionSet(dimension=2) regionset.add(Region([0, 0], [3, 5])) regionset.add(Region([3, 1], [5, 5])) regionset.add(Region([2, 4], [6, 6])) for i in range(regionset.dimension): expect = regionset.overlaps(i) actual = self._evaluate_regionsweep(regionset, i) #for pair in expect: print(f'Expect {i}:\t{pair[0]}\n\t{pair[1]}') #for pair in actual: print(f'Actual {i}:\t{pair[0]}\n\t{pair[1]}') for pair in expect: #passed = "Passed" if pair in actual else "Failed" #print(f'{passed} {i}: {pair[0]} {pair[1]}') self.assertTrue(pair in actual) self.assertEqual(len(expect), len(actual))
def test_regionset_outofbounds(self): regionset = RegionSet(bounds=Region([0, 0], [10, 10])) with self.assertRaises(AssertionError): regionset.add(Region([-1, -1], [5, 5]))
def test_regionset_dimension_mismatch(self): regionset = RegionSet(dimension=2) with self.assertRaises(AssertionError): regionset.add(Region([0] * 3, [1] * 3))
def visualenum(cls, source: FileIO, output: FileIO, srckind: str, outkind: str, queries: List[str] = [], **kwargs): """ Enumerate over the set or graph of Regions in the given input source file. Generate and output a visualization of the collection of Regions or Region intersection graph, based on the specified visual to output, and color codes the results based on the number of intersecting Regions involved in each enumerated intersection. Saves the visualization to the given destination image file. If no Regions given in the query, enumerate all intersecting Regions. If a single Region is given in the query, enumerate all intersecting Regions that includes that Region. If multiple Regions given in the query, enumerate all intersecting Regions amongst the subset of Regions. \f Args: source: The input source file to load. output: The dest image file to save visualization. srckind: The input data type. outkind: The output visualization type. queries: The Regions to be queried. kwargs: Additional arguments. Keyword Args: colormap: The name of a built-in matplotlib colormap to color code the enumerated intersecting Regions by, based on the number of intersecting Regions involved in each enumerated intersection. forced: Boolean flag whether or not to force apart the unconnected clusters (nodes and edges) within the graph. tightbounds: Boolean flag for whether or not to reduce the bounding size to the minimum bounding Region, instead of the defined bounds. """ figure, ax = pyplot.subplots(subplot_kw={'aspect': 'equal'}, figsize=(20, 10)) regions, rigraph = cls.bundle(cls.read(source, srckind)) intersects = RegionSet(dimension=regions.dimension) enumerator = cls.enumerator('slig', rigraph, list(queries)) vmin, vmax = 1, 2 for region, intersect in enumerator(): k = len(intersect) if vmax < k: vmax = k intersects.add(region) cmap = get_cmap(kwargs.pop('colormap')) cnorm = Normalize(vmin=vmin, vmax=vmax) colors = ScalarMappable(norm=cnorm, cmap=cmap) ctx = cls.unbundle((regions, rigraph), outkind) get_color = lambda i: tuple(colors.to_rgba(i)[0:3]) draw_plot = draw_regions if isinstance(ctx, RegionSet) else draw_rigraph for r in regions: r['color'] = tuple([0.5] * 3) for r in [regions[q] for q in queries]: r['color'] = get_color(vmin) for r in intersects: intersect = r['intersect'] r['color'] = color = get_color(len(intersect)) if isinstance(ctx, NxGraph): for i, a in enumerate(intersect): a['color'] = color for b in intersect[i + 1:]: rigraph.region((a, b))['color'] = color if isinstance(ctx, RegionSet): ctx = ctx.merge([intersects]) draw_plot(ctx, ax, colored=True, **kwargs) figure.savefig(output, bbox_inches='tight') pyplot.close(figure)
def enumerate(cls, source: FileIO, output: FileIO, srckind: str, queries: List[str] = [], **kwargs): """ Enumerate over the set or graph of Regions in the given input source file. Outputs the results to as a JSON with performance data and the results as a RegionSet of intersecting Regions. If no Regions given in the query, enumerate all intersecting Regions. If a single Region is given in the query, enumerate all intersecting Regions that includes that Region. If multiple Regions given in the query, enumerate all intersecting Regions amongst the subset of Regions. \f Args: source: The input source file to load. output: The destination file to save results. srckind: The input data type. queries: The Regions to be queried. kwargs: Additional arguments. Keyword Args: naive: Boolean flag for whether to use the naive sweep-line algorithm instead of querying via the region intersection graph. """ queries = list(queries) context = cls.read(source, srckind) intersects = RegionSet(dimension=context.dimension) counts = {} def get_header(ctx: Context) -> Dict: header = { 'id': ctx.id, 'type': type(ctx).__name__, 'dimension': ctx.dimension, 'length': len(ctx) } if elapse_ctor is None: header['elapse_query'] = elapse_query else: header['elapse_query'] = elapse_query - elapse_ctor header['elapse_ctor'] = elapse_ctor return header def get_enumerator(): if isinstance(context, NxGraph): return (None, cls.enumerator('slig', context, queries)) if kwargs.get('naive', False): return (0, cls.enumerator('naive', context, queries)) graph = NxGraphSweepCtor.prepare(context)() elapsed = perf_counter() - start return (elapsed, cls.enumerator('slig', graph, queries)) start = perf_counter() elapse_ctor, enumerator = get_enumerator() for region, intersect in enumerator(): k = len(intersect) if k not in counts: counts[k] = 0 counts[k] += 1 intersects.add(region) elapse_query = perf_counter() - start header = get_header(context) cls.write( output, { 'header': { **header, 'query': queries, 'count': counts }, 'results': intersects })