#!/usr/bin/env python # coding: utf-8 # ## SlideRule ATL06 Computation: Interactive Tutorial # ### IPython Widgets Example # # ### Purpose # Demonstrate common uses of the `ipysliderule` module # #### Load necessary packages # In[ ]: import warnings warnings.filterwarnings('ignore') # turn off warnings for demo from sliderule import icesat2, ipysliderule, io, sliderule import geopandas import logging get_ipython().run_line_magic('load_ext', 'autoreload') get_ipython().run_line_magic('autoreload', '2') # ### Initiate SlideRule API # - Sets the URL for accessing the SlideRule service # - Builds a table of servers available for processing data # In[ ]: # set the url for the sliderule service # set the logging level icesat2.init("slideruleearth.io", loglevel=logging.WARNING) # ### Set options for making science data processing requests to SlideRule # # SlideRule follows a streamlined version of the [ATL06 land ice height algorithm](https://nsidc.org/sites/nsidc.org/files/technical-references/ICESat2_ATL06_ATBD_r005.pdf). # # SlideRule also can use different sources for photon classification before calculating the average segment height. # This is useful for example, in cases where there may be a vegetated canopy affecting the spread of the photon returns. # - ATL03 photon confidence values, based on algorithm-specific classification types for land, ocean, sea-ice, land-ice, or inland water # - [ATL08 Land and Vegetation Height product](https://nsidc.org/data/atl08) photon classification # - Experimental YAPC (Yet Another Photon Classification) photon-density-based classification # In[ ]: # display widgets for setting SlideRule parameters SRwidgets = ipysliderule.widgets() SRwidgets.VBox(SRwidgets.atl06()) # ### Interactive Mapping with Leaflet # # Interactive maps within the SlideRule python API are built upon [ipyleaflet](https://ipyleaflet.readthedocs.io). # # #### Leaflet Basemaps and Layers # # There are 3 projections available within SlideRule for mapping ([Global](https://epsg.io/3857), [North](https://epsg.io/5936) and [South](https://epsg.io/3031)). There are also contextual layers available for each projection. # # # # # # # # # # # # # # #
Global (Web Mercator, EPSG:3857)North (Alaska Polar Stereographic, EPSG:5936)South (Antarctic Polar Stereographic, EPSG:3031)
# # # # # #
# # In addition, most [xyzservice providers](https://xyzservices.readthedocs.io/en/stable/introduction.html) can be added as contextual layers to the global Web Mercator maps # In[ ]: SRwidgets.VBox([ SRwidgets.projection, SRwidgets.layers, SRwidgets.raster_functions ]) # ### Select regions of interest for submitting to SlideRule # # Here, we create polygons or bounding boxes for our regions of interest. # This map is also our viewer for inspecting our SlideRule ICESat-2 data returns. # In[ ]: # create ipyleaflet map in specified projection m = ipysliderule.leaflet(SRwidgets.projection.value) m.map # In[ ]: m.add_layer( layers=SRwidgets.layers.value, rendering_rule=SRwidgets.rendering_rule ) # ### Build and transmit requests to SlideRule # # - SlideRule will query the [NASA Common Metadata Repository (CMR)](https://cmr.earthdata.nasa.gov/) for ATL03 data within our region of interest # - When using the `icesat2` asset, the ICESat-2 ATL03 data are then accessed from the NSIDC AWS s3 bucket in `us-west-2` # - The ATL03 granules is spatially subset within SlideRule to our exact region of interest # - SlideRule then uses our specified parameters to calculate average height segments from the ATL03 data in parallel # - The completed data is streamed concurrently back and combined into a geopandas GeoDataFrame within the Python client # In[ ]: get_ipython().run_cell_magic('time', '', '# build sliderule parameters using latest values from widget\nparms = SRwidgets.build_atl06()\n\n# clear existing geodataframe results\nelevations = [sliderule.emptyframe()]\n\n# for each region of interest\nsliderule.logger.warning(\'No valid regions to run\') if not m.regions else None\nfor poly in m.regions:\n # add polygon from map to sliderule parameters\n parms["poly"] = poly\n # make the request to the SlideRule (ATL06-SR) endpoint\n # and pass it the request parameters to request ATL06 Data\n elevations.append(icesat2.atl06p(parms))\ngdf = geopandas.pd.concat(elevations)\n') # ### Review GeoDataFrame output # Can inspect the columns, number of returns and returns at the top of the GeoDataFrame. # # See the [ICESat-2 documentation](https://slideruleearth.io/rtd/user_guide/ICESat-2.html#elevations) for descriptions of each column # In[ ]: print(f'Returned {gdf.shape[0]} records') gdf.head() # ### Add GeoDataFrame to map # # For stability of the leaflet map, SlideRule will as a default limit the plot to have up to 10000 points from the GeoDataFrame # # GeoDataFrames can be plotted in any available [matplotlib colormap](https://matplotlib.org/stable/tutorials/colors/colormaps.html) # In[ ]: SRwidgets.VBox([ SRwidgets.variable, SRwidgets.cmap, SRwidgets.reverse, ]) # In[ ]: get_ipython().run_line_magic('matplotlib', 'inline') # ATL06-SR fields for hover tooltip fields = gdf.leaflet.default_atl06_fields() gdf.leaflet.GeoData(m.map, column_name=SRwidgets.variable.value, cmap=SRwidgets.colormap, max_plot_points=10000, tooltip=True, colorbar=True, fields=fields) # install handlers and callbacks gdf.leaflet.set_observables(SRwidgets) gdf.leaflet.add_selected_callback(SRwidgets.atl06_click_handler) m.add_region_callback(gdf.leaflet.handle_region) # ### Create plots for a single track # - cycles: Will plot all available cycles of data returned by SlideRule for a single RGT and ground track # - scatter: Will plot data returned by SlideRule for a single RGT, ground track and cycle # - (to select a track from the leaflet plot above, click on one of the plotted elevations and the RGT and Cycle will automatically get populated below) # # The cycles plots should only be used in regions with [repeat Reference Ground Track (RGT) pointing](https://icesat-2.gsfc.nasa.gov/science/specs) # In[ ]: SRwidgets.VBox([ SRwidgets.plot_kind, SRwidgets.rgt, SRwidgets.ground_track, SRwidgets.cycle, ]) # In[ ]: get_ipython().run_line_magic('matplotlib', 'widget') # default is to skip cycles with significant off-pointing gdf.icesat2.plot(kind=SRwidgets.plot_kind.value, cycle_start=3, legend=True, legend_frameon=False, **SRwidgets.plot_kwargs) # ### Save GeoDataFrame to output file # In[ ]: display(SRwidgets.filesaver) # In[ ]: # append sliderule api version to attributes version = sliderule.get_version() parms['version'] = version['icesat2']['version'] parms['commit'] = version['icesat2']['commit'] # save to file in format (HDF5 or netCDF) io.to_file(gdf, SRwidgets.file, format=SRwidgets.format, parameters=parms, regions=m.regions, verbose=True) # ### Read GeoDataFrame from input file # In[ ]: display(SRwidgets.fileloader) # In[ ]: # read from file in format (HDF5 or netCDF) gdf,parms,regions = io.from_file(SRwidgets.file, format=SRwidgets.format, return_parameters=True, return_regions=True) # ### Review GeoDataFrame input from file # In[ ]: gdf.head() # ### Set parameters and add saved regions to map # In[ ]: SRwidgets.set_values(parms) m.add_region(regions) # In[ ]: