geowatch.demo.metrics_demo.site_perterbing module

Functions to perterb or “jitter” truth that gradually degrade the site models in specified ways. This can be used to check the scoring metrics at various levels of accuracy / inaccuracy.

geowatch.demo.metrics_demo.site_perterbing.perterb_site_model(sites, rng=None, **kwargs)[source]

Given a true site models from a region, perterb them to make “demo” predicted site models.

Parameters:
  • sites (List[geojson.FeatureCollection]) – geojson site observations

  • rng – random seed or generator

  • **kwargs – factors to control per-site perterbations. See perterb_single_site_model() for available options.

Returns:

modified site models

Return type:

List[geojson.FeatureCollection]

Example

>>> from geowatch.demo.metrics_demo.site_perterbing import *  # NOQA
>>> _, sites, _ = demo_truth.random_region_model(rng=12345)
>>> pred_sites1 = perterb_site_model(sites, noise=1, rng=34567)
>>> pred_sites2 = perterb_site_model(sites, noise=0, rng=34567)
class geowatch.demo.metrics_demo.site_perterbing.PerterbModel(noise=0.0, performer_id='alice', rng=None, **kwargs)[source]

Bases: object

Todo

consume the functionality of perterb_single_site_model

Example

>>> from geowatch.demo.metrics_demo.site_perterbing import *  # NOQA
>>> self = PerterbModel()

Example

>>> from geowatch.demo.metrics_demo.site_perterbing import *  # NOQA
>>> from geowatch.demo.metrics_demo import demo_truth
>>> region_id = 'DR_0042'
>>> site_id = 'DR_0042_9001'
>>> rng = kwarray.ensure_rng(4222)
>>> region_corners = kwimage.Boxes([[5, 7, 11, 13]], 'xywh').to_ltrb().corners()
>>> observables = demo_truth.random_observables(15, rng=rng)
>>> p_observe = 0.5
>>> site_summary, site = demo_truth.random_site_model(
>>>     region_id, site_id, region_corners, observables,
>>>     p_observe=p_observe, p_transition=0.4,  rng=rng)
>>> kwargs = dict(noise=10, drop_limit=0.1)
>>> self = PerterbModel(**kwargs)
>>> pred_site = self.perterb_single_site(site)
>>> # xdoctest: +REQUIRES(--show)
>>> # xdoctest: +REQUIRES(module:kwplot)
>>> import kwplot
>>> kwplot.autompl()
>>> import geopandas as gpd
>>> # Draw our true and perterbed site model
>>> orig_site_gdf = gpd.GeoDataFrame.from_features(site)
>>> pred_site_gdf = gpd.GeoDataFrame.from_features(pred_site)
>>> total_poly1 = orig_site_gdf['geometry'].unary_union
>>> total_poly2 = pred_site_gdf['geometry'].unary_union
>>> total_poly = total_poly1.union(total_poly2)
>>> minx, miny, maxx, maxy = total_poly.bounds
>>> fig = kwplot.figure(doclf=True, fnum=1)
>>> phases = demo_truth.SiteModelGenerator.SITE_PHASES
>>> phase_to_color = ub.udict(ub.dzip(phases, kwimage.Color.distinct(len(phases))))
>>> pnum_ = kwplot.PlotNums(nRows=4, nSubplots=len(observables) + 1)
>>> boundary_colors = ub.udict({'true': 'limegreen', 'pred': 'dodgerblue'}).map_values(lambda c: kwimage.Color(c).as01())
>>> for obs in observables:
>>>     title = obs['datetime'].isoformat()
>>>     trues = orig_site_gdf[orig_site_gdf['observation_date'] == obs['datetime'].date().isoformat()]
>>>     preds = pred_site_gdf[pred_site_gdf['observation_date'] == obs['datetime'].date().isoformat()]
>>>     fig = kwplot.figure(pnum=pnum_(), title=title)
>>>     ax = fig.gca()
>>>     if len(trues):
>>>         colors = list(phase_to_color.take(trues['current_phase']))
>>>         trues.plot(ax=ax, alpha=0.5, color=colors)
>>>         trues.boundary.plot(ax=ax, alpha=0.5, color=boundary_colors['true'], linewidth=3)
>>>         trues.centroid.plot(ax=ax, alpha=0.5, color=boundary_colors['true'])
>>>     if len(preds):
>>>         colors = list(phase_to_color.take(preds['current_phase']))
>>>         preds.plot(ax=ax, alpha=0.5, color=colors)
>>>         preds.boundary.plot(ax=ax, alpha=0.5, color=boundary_colors['pred'], linewidth=3)
>>>         preds.centroid.plot(ax=ax, alpha=0.5, color=boundary_colors['pred'])
>>>     ax.set_xlim(minx, maxx)
>>>     ax.set_ylim(miny, maxy)
>>> legend1 = kwimage.draw_header_text(kwplot.make_legend_img(phase_to_color), 'Face Key', fit=True)
>>> legend2 = kwimage.draw_header_text(kwplot.make_legend_img(boundary_colors), 'Border Key', fit=True)
>>> legend = kwimage.stack_images([legend1, legend2], axis=0, resize='smaller')
>>> kwplot.imshow(legend, pnum=pnum_())
>>> kwplot.show_if_requested()
perterb_single_site(site, idx=None)[source]
geowatch.demo.metrics_demo.site_perterbing.perterb_single_site_model(site, noise=0.0, warp_noise=1.0, performer_id='alice', idx=None, rng=None, **kwargs)[source]

Given a true site model, perterb it to make a “demo” predicted site model.

Parameters:
  • site (geojson.FeatureCollection) – geojson site observations

  • noise (float) – Magnitude of all noise. This factor modulates all other noise values. Setting to 0 disables all perterbation. Typically 1 is the largest “reasonable” value. Setting any noise magnitude higher than 1 may result in pathological perterbations.

  • warp_noise (float) – magnitude of random warp that we will use to perterb the boundary of the true site polygons.

  • performer_id (str) – used in the originator property

  • idx (int) – the index of this new site model. If unspecified, the same site id is used in truth and pred.

  • rng – random seed or generator

  • **kwargs – other PerterbModel params

Returns:

modified site model

Return type:

geojson.FeatureCollection

Example

>>> # Demo case with a lot of noise
>>> from geowatch.demo.metrics_demo.site_perterbing import *  # NOQA
>>> rng = kwarray.ensure_rng(43240830)
>>> _, sites, _ = demo_truth.random_region_model(num_observations=20, rng=rng)
>>> site = sites[0]
>>> pred_site = perterb_single_site_model(site, noise=1.0, rng=rng)
>>> # xdoctest: +REQUIRES(--show)
>>> # xdoctest: +REQUIRES(module:kwplot)
>>> import kwplot
>>> kwplot.autompl()
>>> # Draw our true and perterbed site model
>>> orig_site_gdf = gpd.GeoDataFrame.from_features(site)
>>> pred_site_gdf = gpd.GeoDataFrame.from_features(pred_site)
>>> fig = kwplot.figure(doclf=True, fnum=1)
>>> ax = fig.gca()
>>> total_poly = pred_site_gdf['geometry'].unary_union.union(orig_site_gdf['geometry'].unary_union)
>>> minx, miny, maxx, maxy = total_poly.bounds
>>> ax.set_xlim(minx, maxx)
>>> ax.set_ylim(miny, maxy)
>>> pred_site_gdf.plot(ax=ax, alpha=0.5, color='orange', edgecolor='purple')
>>> orig_site_gdf.plot(ax=ax, alpha=0.5, color='limegreen', edgecolor='black')
>>> orig_site_gdf.centroid.plot(ax=ax, alpha=0.5, color='green')
>>> pred_site_gdf.centroid.plot(ax=ax, alpha=0.5, color='red')
>>> kwplot.show_if_requested()

Example

>>> # Demo case with almost zero noise
>>> from geowatch.demo.metrics_demo.site_perterbing import *  # NOQA
>>> rng = kwarray.ensure_rng(43240830)
>>> _, sites, _ = demo_truth.random_region_model(num_observations=20, rng=rng)
>>> site = sites[0]
>>> pred_site = perterb_single_site_model(site, noise=1e-2, rng=rng)
>>> # xdoctest: +REQUIRES(--show)
>>> # xdoctest: +REQUIRES(module:kwplot)
>>> import kwplot
>>> kwplot.autompl()
>>> # Draw our true and perterbed site model
>>> orig_site_gdf = gpd.GeoDataFrame.from_features(site)
>>> pred_site_gdf = gpd.GeoDataFrame.from_features(pred_site)
>>> fig = kwplot.figure(doclf=True, fnum=2)
>>> ax = fig.gca()
>>> total_poly = pred_site_gdf['geometry'].unary_union.union(orig_site_gdf['geometry'].unary_union)
>>> minx, miny, maxx, maxy = total_poly.bounds
>>> ax.set_xlim(minx, maxx)
>>> ax.set_ylim(miny, maxy)
>>> pred_site_gdf.plot(ax=ax, alpha=0.5, color='orange', edgecolor='purple')
>>> orig_site_gdf.plot(ax=ax, alpha=0.5, color='limegreen', edgecolor='black')
>>> orig_site_gdf.centroid.plot(ax=ax, alpha=0.5, color='green')
>>> pred_site_gdf.centroid.plot(ax=ax, alpha=0.5, color='red')
>>> kwplot.show_if_requested()