### Install glmtools using Conda Source: https://github.com/deeplycloudy/glmtools/blob/master/docs/index.md Clone the repository, create a conda environment from environment.yml, activate it, and install the package in editable mode. This is the recommended installation method for glmtools. ```bash git clone https://github.com/deeplycloudy/glmtools.git cd glmtools conda env create -f environment.yml conda activate glmval pip install -e . ``` -------------------------------- ### Install Siphon for OPeNDAP Data Access Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb Install the siphon library to enable loading GLM data via OPeNDAP from remote servers. ```bash conda install -c conda-forge siphon ``` -------------------------------- ### Placeholder for Grid Setup Source: https://github.com/deeplycloudy/glmtools/blob/master/docs/newgrid.md This snippet represents a placeholder in the grid setup process. It indicates where grid definitions are managed. ```python grid.make_grids ``` -------------------------------- ### Install nb_conda_kernels and ipywidgets Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb Before running this notebook, install these essential packages for conda environments. ```bash conda install -c conda-forge nb_conda_kernels ``` ```bash conda install -c conda-forge ipywidgets ``` -------------------------------- ### Set Time Coordinate for GLM Data Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/aggregate_and_plot.ipynb Demonstrates how to set the time coordinate to the start time of each time bin for GLM data. This is useful for aligning temporal data accurately. ```python # Set the time coordinate to the start time of each time bin (could also choose mid) minimum_flash_area (time, y, x) float32 dask.array goes_imager_projection (time) int32 -2147483647 nominal_satellite_subpoint_lat (time) float64 0.0 nominal_satellite_subpoint_lon (time) float64 -75.0 Attributes: cdm_data_type: Image Conventions: CF-1.7 id: 93cb84a3-31ef-4823-89f5-c09d88fc89e8 institution: DOC/NOAA/NESDIS > U.S. Department of Commerce,... instrument_type: GOES R Series Geostationary Lightning Mapper iso_series_metadata_id: f5816f53-fd6d-11e3-a3ac-0800200c9a66 keywords: ATMOSPHERE > ATMOSPHERIC ELECTRICITY > LIGHTNI... keywords_vocabulary: NASA Global Change Master Directory (GCMD) Ear... license: Unclassified data. Access is restricted to ap... Metadata_Conventions: Unidata Dataset Discovery v1.0 naming_authority: gov.nesdis.noaa processing_level: National Aeronautics and Space Administration ... project: GOES standard_name_vocabulary: CF Standard Name Table (v25, 05 July 2013) summary: The Lightning Detection Gridded product genera... title: GLM L2 Lightning Detection Gridded Product dataset_name: OR_GLM-L2-GLMF-M3_G16_s20180660440000_e2018066... date_created: 2019-08-11T21:03:08.271071Z instrument_ID: GLM-1 orbital_slot: GOES-East platform_ID: G16 production_data_source: Postprocessed production_environment: DE production_site: TTU scene_id: Full Disk spatial_resolution: 2km at nadir time_coverage_end: 2018-03-07T04:43:00 time_coverage_start: 2018-03-07T04:40:00 timeline_id: ABI Mode 3 ``` -------------------------------- ### Load Sample GLM Data Path Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb Retrieve the path to sample GLM data files included with the glmtools library. This is useful for testing and examples. ```python from glmtools.test.common import get_sample_data_path sample_path = get_sample_data_path() samples = [ "OR_GLM-L2-LCFA_G16_s20181830433000_e20181830433200_c20181830433231.nc", "OR_GLM-L2-LCFA_G16_s20181830433200_e20181830433400_c20181830433424.nc", "OR_GLM-L2-LCFA_G16_s20181830433400_e20181830434000_c20181830434029.nc", ] samples = [os.path.join(sample_path, s) for s in samples] filename = samples[0] ``` -------------------------------- ### Import GLMTools Plotting Function and Widgets Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb Imports the necessary `plot_flash` function from `glmtools.plot.locations` and `ipywidgets` for interactive elements. This is a common setup for GLMTools visualization tasks. ```python from glmtools.plot.locations import plot_flash import ipywidgets as widgets ``` -------------------------------- ### Generate GraphViz Call Graph with pycallgraph Source: https://github.com/deeplycloudy/glmtools/blob/master/docs/callgraph.md This command generates a GraphViz call graph for specified Python modules, including per-function timing. It outputs to a .dot file and can also create a PNG graphic. Ensure pycallgraph and pygraphviz are installed. ```bash pycallgraph -i glmtools.* -i lmatools.* -i stormdrain.* -s -d graphviz -- \ glmtools/examples/grid/make_GLM_grids.py -o /data/GOES16oklmaMCS/subgrid/ \ --fixed_grid --subdivide_grid=1 --goes_position test --goes_sector conus \ --ctr_lon 0.0 --ctr_lat 0.0 --split_events --dx=2.0 --dy=2.0 \ --start=2017-10-22T04:09:00 --end=2017-10-22T04:10:00 \ OR_GLM-L2-LCFA_G16_s20172950409000_e20172950409200_c20172950410031.nc \ OR_GLM-L2-LCFA_G16_s20172950409200_e20172950409400_c20172950409431.nc \ OR_GLM-L2-LCFA_G16_s20172950409400_e20172950410000_c20172950410031.nc > pycallgraph.dot ``` -------------------------------- ### Initialize Plotting and Define Fields Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb Sets up the plotting environment and defines the fields to be visualized. Requires Matplotlib and glmtools.plot.grid. ```python %matplotlib notebook import matplotlib.pyplot as plt from glmtools.plot.grid import plot_glm_grid fields_6panel = ['flash_extent_density', 'average_flash_area','total_energy', 'group_extent_density', 'average_group_area', 'group_centroid_density'] def plot(w, fig=None, time_widget=None, field_widget=None, subplots=(2,3), fields=None): t = pd.to_datetime(time_widget.value) n_subplots = subplots[0] * subplots[1] if fields is None: if n_subplots == 1: fields = [field_widget.value] else: fields = fields_6panel[0:n_subplots] mapax, cbar_obj = plot_glm_grid(fig, glm_grids, t, fields, subplots=subplots, axes_facecolor = (1.0, 1.0, 1.0), map_color = (0.2, 0.2, 0.2)) fig = plt.figure(figsize=(18,12)) plt.show() ``` -------------------------------- ### Initialize GOES-R Navigators and Calculate Lightning Vector Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/stereo_renav_GLM.ipynb Initializes GOESR_Navigator objects for GOES-16 and GOES-18 datasets and calculates the ECEF vector for a given lightning location (longitude, latitude, altitude). Prints the satellite and lightning vectors. ```python g16_nav = GOESR_Navigator(g16.dataset) g18_nav = GOESR_Navigator(g18.dataset) ltg_lon, ltg_lat, ltg_alt = -101.5, 33.5, 12000.0 print(g16_nav.sat_vec) # seems ok as ECEF ltg_vec = np.vstack(g16_nav.grs80lla.toECEF(ltg_lon, ltg_lat, ltg_alt)) print(ltg_vec) # seems ok as ECEF ``` -------------------------------- ### Initialize GLMDataset and Print Dataset Info Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb Initializes a GLMDataset object with the provided filename and prints the dataset's structure and metadata. This is useful for understanding the available variables and dimensions. ```python from glmtools.io import GLMDataset glm = GLMDataset(filename) print(glm.dataset) ``` -------------------------------- ### Get Gridded Plot Axis Limits Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb Retrieves the axis limits of the first subplot in the current figure, which is assumed to be a gridded plot. This is often used to set consistent limits for other plots. ```python # Get the limits of the gridded plot, and use for this plot ax_lim_grid = fig.axes[0].axis() print(ax_lim_grid) ``` -------------------------------- ### Load sample GLM data paths Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb Retrieves paths to sample GLM data files for testing and analysis. Ensure sample data is available. ```python from glmtools.test.common import get_sample_data_path sample_path = get_sample_data_path() samples = [ "OR_GLM-L2-LCFA_G16_s20181830433000_e20181830433200_c20181830433231.nc", "OR_GLM-L2-LCFA_G16_s20181830433200_e20181830433400_c20181830433424.nc", "OR_GLM-L2-LCFA_G16_s20181830433400_e20181830434000_c20181830434029.nc", ] samples = [os.path.join(sample_path, s) for s in samples] ``` -------------------------------- ### Initialize Dask Client for Parallel Computation Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/aggregate_and_plot.ipynb Sets up a Dask distributed client to leverage multiple CPU cores for processing datasets that may not fit into memory. This is essential for performance when working with large amounts of GLM data. ```python import xarray as xr import pandas as pd import numpy as np import dask # This will automatically use multiple cores to perform the computation over datasets that don't fit in memory from dask.distributed import Client client = Client() client ``` -------------------------------- ### Set Time Coordinate and Rename Dimension Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/aggregate_and_plot.ipynb This snippet sets the time coordinate to the start time of each time bin and renames the 'time_bins' dimension to 'time'. This is useful for preparing time-series data for analysis. ```python agglm['time_bins'] = [v.left for v in agglm.time_bins.values] glglm_grids = agglm.rename({'time_bins':'time'}) print(glm_grids) ``` -------------------------------- ### Initialize Lambert Conformal Conic Projection Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Initializes a MapProjection object for Lambert Conformal Conic projection using parameters extracted from the hrrr dataset. This is useful for coordinate transformations. ```python hrrrproj={ 'lat_0':hrrr.LambertConformal_Projection.latitude_of_projection_origin, 'lon_0':hrrr.LambertConformal_Projection.longitude_of_central_meridian, 'lat_1':hrrr.LambertConformal_Projection.standard_parallel, 'R':hrrr.LambertConformal_Projection.earth_radius, } from lmatools.coordinateSystems import MapProjection lcc = MapProjection(projection='lcc', ctrLat=hrrrproj['lat_0'],ctrLon=hrrrproj['lon_0'], **hrrrproj) ``` -------------------------------- ### Get Point Plot Extent in Plate Carree Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb Retrieves the geographic extent of the point plot axes in the Plate Carree coordinate system. This is useful for understanding the latitude and longitude boundaries of the plotted data. ```python ax.get_extent(ccrs.PlateCarree()) ``` -------------------------------- ### Prepare Data for Interpolation Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Prepares the lightning data for interpolation by selecting valid locations, handling NaNs, and adjusting coordinate orientation. This ensures accurate interpolation onto the target grid. ```python from scipy.interpolate import griddata interp_loc = np.vstack((reg_lat.flatten(), reg_lon.flatten())).T # GLM variables are filled with nan everywhere there is no lightning, # so set those locations corresponding to valid earth locations to zero. # Also flip the north-south coordinate to match the fact that the GLM data # coordinate begins from the upper left instead of lower right corner. good = np.isfinite(lon_ltg[::-1, :]) data_loc = np.vstack((lat_ltg[::-1, :][good], lon_ltg[::-1, :][good])).T interp_data = glm.flash_extent_density.data[::-1, :][good] print(finite_max(interp_data)) interp_data[~np.isfinite(interp_data)] = 0 print(finite_max(interp_data) ``` -------------------------------- ### Embed Interactive GLM Plots in Notebook Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot/README.md Use the plot_glm function from the plots module to create interactive GLM grid visualizations within a Jupyter notebook. This example demonstrates setting up widgets for time and field selection to dynamically update plots. ```python from plots import plot_glm fields_6panel = ['flash_extent_density', 'average_flash_area','total_energy', 'group_extent_density', 'average_group_area', 'group_centroid_density'] def plot(w, fig=None, time_widget=None, field_widget=None, subplots=(2,3), fields=None): t = pd.to_datetime(time_widget.value) n_subplots = subplots[0] * subplots[1] if fields is None: if n_subplots == 1: fields = [field_widget.value] else: fields = fields_6panel[0:n_subplots] plot_glm(fig, glm_grids, t, fields, subplots=subplots) fig = plt.figure(figsize=(18,12)) from ipywidgets import widgets time_options = [str(t0) for t0 in glm_grids.time.to_series()] time_options.sort() field_options = list(glm_grids.variables.keys()) for v in ['x', 'y', 'time', 'goes_imager_projection', 'DQF']: field_options.remove(v) field_dropdown = widgets.Dropdown(options=field_options) time_slider = widgets.SelectionSlider(options=time_options) glm_select = widgets.HBox([field_dropdown, time_slider]) from functools import partial plot = partial(plot, fig=fig, field_widget=field_dropdown, time_widget=time_slider) time_slider.observe(plot) field_dropdown.observe(plot) display(glm_select) time_slider.value = time_slider.options[3] ``` -------------------------------- ### Initialize GLM Data File Collections Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/glm_test_data_new_grid_dev.ipynb This code snippet initializes various GLM data file collections using `glob` to find files matching specific naming conventions based on date, resolution, and data type. It sets up collections for different GLM products. ```python res = '056' dtdx_base = '{0}_1src_{1}urad-dx'.format(int(duration.total_seconds()), res) glM_init_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_flash_init.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_fed_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_flash_extent.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_ed_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_source.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_energy_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_total_energy.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_foot_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_footprint.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_grinit_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_group_init.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_ged_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_group_extent.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_grfoot_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_group_area.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) glM_minarea_files = glob.glob(os.path.join(grid_dir_base, '{0}/*_{1}_flash_area_min.nc'.format(startdate.strftime('%Y/%b/%d'), dtdx_base))) ``` -------------------------------- ### Convert Fixed Grid Coordinates to Longitude/Latitude Source: https://github.com/deeplycloudy/glmtools/blob/master/docs/fixedgridguide.md This snippet demonstrates how to read GLM time series data, extract 1D fixed grid coordinates, convert them to 2D longitude and latitude arrays using `glmtools`, and save the results to a NetCDF file. Ensure `glmtools` and `xarray` are installed and necessary data files are accessible. ```python # Load the GLM data glm = open_glm_time_series(['~/glmtools/glmtools/test/data/conus/2018/Jul/02/OR_GLM-L2-GLMC-M3_G16_s20181830433000_e20181830434000_c20182551446.nc']) x_1d = glm.x y_1d = glm.y # Convert the 1D fixed grid coordinates to 2D lon, lat from lmatools.grid.fixed import get_GOESR_coordsys x,y = np.meshgrid(x_1d, y_1d) # Two 2D arrays of fixed grid coordinates nadir = -75.0 geofixCS, grs80lla = get_GOESR_coordsys(nadir) z=np.zeros_like(x) lon,lat,alt=grs80lla.fromECEF(*geofixCS.toECEF(x,y,z)) lon.shape = x.shape lat.shape = y.shape # Add the 2D arrays back to the original dataset and save to disk. # This doesn't have the CF standard name metadata or unit information, # but that isn't too hard to add. import xarray as xr glm['longitude'] = xr.DataArray(lon, dims=('y', 'x')) glm['latitude'] = xr.DataArray(lat, dims=('y', 'x')) glm.to_netcdf('glm_aggregate.nc') ``` -------------------------------- ### Import GLM and Coordinate System Tools Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Imports specific modules from glmtools and lmatools for handling lightning ellipses and coordinate systems. ```python from glmtools.io.lightning_ellipse import lightning_ellipse_rev from lmatools.coordinateSystems import CoordinateSystem from lmatools.grid.fixed import get_GOESR_coordsys ``` -------------------------------- ### Load GLM Datasets Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/stereo_renav_GLM.ipynb Loads GLM Level 2 Compact data files for Geostationary Lightning Mapper (GLM) for GOES-16 and GOES-18 satellites. ```python g16 = GLMDataset('/data/20240528-WTLMA/GLM/OR_GLM-L2-LCFA_G16_s20241492318200_e20241492318400_c20241492318416.nc') g18 = GLMDataset('/data/20240528-WTLMA/GLM/OR_GLM-L2-LCFA_G18_s20241492318200_e20241492318400_c20241492318418.nc') ``` -------------------------------- ### List GLM Data Files Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/aggregate_and_plot.ipynb This is a placeholder command to list files in a directory. In a real scenario, you would use this to identify the GLM data files you intend to process. ```python # ls /data/LCFA-production/GLM-L2-LCFA_G16_s201905_tests/slowdown/2018Mar07/2018/Mar/07/ ``` -------------------------------- ### Construct and execute GLM gridding command Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/glm_test_data_new_grid_dev.ipynb Builds a shell command to run the `make_GLM_grids.py` script with specified parameters for creating gridded data. The script is executed using `subprocess.check_output`. ```python import subprocess import os, glob import tempfile tmpdir = tempfile.TemporaryDirectory() import glmtools from glmtools.test.common import get_sample_data_path # glmtools_path = os.path.abspath(glmtools.__path__[0]) glmtools_path = os.path.abspath('.') # Set the start time and duration startdate = datetime(2018, 7, 2, 4, 30) duration = timedelta(0, 60*5) enddate = startdate+duration cmd = "python {0}/../examples/grid/make_GLM_grids.py -o {1}" cmd += " --fixed_grid --split_events --goes_position=east --goes_sector=meso" cmd += " --ctr_lat=33.5 --ctr_lon=-101.5 --dx=2.0 --dy=2.0" cmd += " --start={3} --end={4} {2}" cmd = cmd.format(glmtools_path, tmpdir.name, ' '.join(samples), startdate.isoformat(), enddate.isoformat()) # print (cmd) out_bytes = subprocess.check_output(cmd.split()) # print(out_bytes.decode('utf-8')) grid_dir_base = tmpdir.name nc_files = glob.glob(os.path.join(grid_dir_base, startdate.strftime('%Y/%b/%d'),'*.nc')) # print(nc_files) ``` -------------------------------- ### Initialize LMAgridFileCollection Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/glm_test_data_new_grid_dev.ipynb Initializes an LMAgridFileCollection object, which is used for managing and accessing gridded data files. ```python from lmatools.grid.grid_collection import LMAgridFileCollection ``` -------------------------------- ### Import GLMtools Imagery Functions Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/aggregate_and_plot.ipynb Imports necessary functions, `open_glm_time_series` and `aggregate`, from the `glmtools.io.imagery` module. These functions are central to the data aggregation and accumulation process. ```python import os from glmtools.io.imagery import open_glm_time_series, aggregate ``` -------------------------------- ### Download NWP Model Data and Coordinates Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Use siphon to download a single variable and its coordinate information from an NWP model. This snippet sets up a query for a specific time and variable from a THREDDS catalog. ```python from siphon.catalog import TDSCatalog from datetime import datetime vtime = datetime.strptime('2020020219','%Y%m%d%H') model_url = "https://thredds.ucar.edu/thredds/catalog/grib/NCEP/HRRR/CONUS_2p5km_ANA/latest.html?dataset=grib/NCEP/HRRR/CONUS_2p5km_ANA/HRRR_CONUS_2p5km_ana_20200202_1900.grib2" model = TDSCatalog(model_url) ds = model.datasets[0] ncss = ds.subset() query = ncss.query() query.accept('netcdf4') query.time(vtime) # Set to the analysis hour only query.add_lonlat() query.variables('Categorical_freezing_rain_surface') ``` -------------------------------- ### Configure Colormap and Display Parameters Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/glm_test_data_new_grid_dev.ipynb This section configures a custom colormap for GLM data, adjusting alpha values for transparency. It then defines display parameters for various GLM grid collections, including product labels, normalization schemes (LogNorm, Normalize), and file tags. ```python from matplotlib.cm import get_cmap from matplotlib.colors import LogNorm, Normalize glM_cmap = get_cmap('viridis') glM_cmap._init() alphas = np.linspace(1.0, 1.0, glm_cmap.N+3) glM_cmap._lut[:,-1] = alphas glM_cmap._lut[0,-1] = 0.0 glM_flctr_grids = LMAgridFileCollection(glm_init_files, 'flash_centroid_density', x_name='x', y_name='y', t_name='time') display_params[glm_flctr_grids] = { 'product_label':"GLM Flash Centroid Density (count)", 'glm_norm':Normalize(vmin=0, vmax=5), 'file_tag':'flash_init' } glM_fed_grids = LMAgridFileCollection(glm_fed_files, 'flash_extent_density', x_name='x', y_name='y', t_name='time') display_params[glm_fed_grids] = { 'product_label':"GLM Flash Extent Density (count)", 'glm_norm':LogNorm(vmin=0.9, vmax=48), 'file_tag':'flash_extent', } glM_ged_grids = LMAgridFileCollection(glm_ged_files, 'group_extent_density', x_name='x', y_name='y', t_name='time') display_params[glm_ged_grids] = { 'product_label':"GLM Group Extent Density (count)", 'glm_norm':Normalize(vmin=0, vmax=200), 'file_tag':'group_extent', } glM_ed_grids = LMAgridFileCollection(glm_ed_files, 'event_density', x_name='x', y_name='y', t_name='time') display_params[glm_ed_grids] = { 'product_label':"GLM Event Density (count)", 'glm_norm':Normalize(vmin=0, vmax=200), 'file_tag':'event_density', } glM_energy_grids = LMAgridFileCollection(glm_energy_files, 'total_energy', x_name='x', y_name='y', t_name='time') display_params[glm_energy_grids] = { 'product_label':"GLM Total Energy (J)", 'glm_norm':LogNorm(vmin=1e-18, vmax=1e-12), 'file_tag':'total_energy' } # display_params[glm_energy_grids]['glm_cmap'].set_bad('w',0) glM_flarea_grids = LMAgridFileCollection(glm_foot_files, 'average_flash_area', x_name='x', y_name='y', t_name='time') display_params[glm_flarea_grids] = { 'product_label':"GLM Average Flash Area (km^2)", 'glm_norm':LogNorm(vmin=32, vmax=.5e4), 'file_tag':'flash_area' } glM_grarea_grids = LMAgridFileCollection(glm_grfoot_files, 'average_group_area', x_name='x', y_name='y', t_name='time') display_params[glm_grarea_grids] = { 'product_label':"GLM Average Group Area (km^2)", 'glm_norm':LogNorm(vmin=32, vmax=.5e4), 'file_tag':'group_area' } glM_minflarea_grids = LMAgridFileCollection(glm_minarea_files, 'minimum_flash_area', x_name='x', y_name='y', t_name='time') display_params[glm_minflarea_grids] = { 'product_label':"GLM Minimum Flash Area (km^2)", 'glm_norm':LogNorm(vmin=32, vmax=.5e4), 'file_tag':'flash_area_min' } ``` -------------------------------- ### Prepare and Interpolate Grid Data Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Prepares data for interpolation by filtering finite values and then uses `griddata` to interpolate the field onto a new grid. Requires `numpy` and `scipy.griddata`. ```python good = np.isfinite(lccx[::-1,:]) data_loc = np.vstack((lccx [good]/1e3, lccy[::-1,:][good]/1e3)).T interp_data = glm.flash_extent_density.data[good] print(interp_data.max()) interp_data[~np.isfinite(interp_data)] = 0 interp_field = griddata(data_loc, interp_data, interp_loc, method='linear') ``` -------------------------------- ### Prepare for Grid Interpolation Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Prepares the grid points for interpolation using scipy.interpolate.griddata. It creates a meshgrid of hrrr x and y coordinates and flattens them into an array of points. ```python from scipy.interpolate import griddata hrrx, hrrry = np.meshgrid(hrrr.x, hrrr.y) interp_loc = np.vstack((hrrrx.flatten(), hrrry.flatten())).T # GLM variables are filled with nan everywhere there is no lightning, # so set those locations corresponding to valid earth locations to zero. # Also flip the north-south coordinate to match the fact that the GLM data ``` -------------------------------- ### Run GLM Grid Plotting Script Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot/README.md Execute the plot_glm_file.py script to generate PNG files for each minute in the GLM dataset. Specify an output directory and the input NetCDF file pattern. ```bash python plot_glm_file.py -o ./loop \ ./GLM_GRID/2018/Oct/28/OR_GLM-L2-GLMC-M3_G16_s2018301201*.nc ``` -------------------------------- ### Import necessary libraries for GLM stereo renavigation Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/stereo_renav_GLM.ipynb Imports required libraries including numpy, scipy.optimize, and specific modules from glmtools and lmatools for coordinate system transformations and data handling. ```python from datetime import datetime import numpy as np from scipy.optimize import least_squares from glmtools.io.glm import GLMDataset from glmtools.io.lightning_ellipse import ltg_ellps_radii, ltg_ellpse_rev, ltg_ellps_lon_lat_to_fixed_grid from lmatools.grid.fixed import get_GOESR_coordsys ``` -------------------------------- ### Display log file content Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb This bash command displays the content of the log file generated by the gridding process. Use this to inspect the gridding results and identify any errors. ```bash # cat make_GLM_grid.log ``` -------------------------------- ### Print Projection Definitions Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Confirms the projection parameters for geocentric and geostationary coordinate systems. Use this to verify that the correct ellipsoids and parameters (e.g., semi-major axis, flattening factor) are being used for calculations. ```python print(geofix_ltg.ECEFxyz) print(geofix_ltg.fixedgrid) print(lla_ltg.ERSxyz) print(lla_ltg.ERSlla) ``` -------------------------------- ### Load GLM Data from Catalog Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb This snippet shows how to load data from the most recent minute or two of GOES-16 GLM data using THREDDS catalog. It requires the siphon library for catalog access. ```python from siphon.catalog import TDSCatalog g16url = "http://thredds-test.unidata.ucar.edu/thredds/catalog/satellite/goes16/GRB16/GLM/LCFA/current/catalog.xml" satcat = TDSCatalog(g16url) filename = satcat.datasets[-1].access_urls['OPENDAP'] ``` -------------------------------- ### Create Interactive Flash Plotter Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb Sets up an interactive plot for flash data using ipywidgets. A SelectionSlider is created to choose flash IDs, and the `do_plot` function is linked to it to display the plot for the selected flash. ```python fl_id_vals = list(flashes_subset.flash_id.data) fl_id_vals.sort() flash_slider = widgets.SelectionSlider( description='Flash', options=fl_id_vals, ) def do_plot(flash_id): fig = plot_flash(glm, flash_id) widgets.interact(do_plot, flash_id=flash_slider) ``` -------------------------------- ### Perform and Display Interpolation Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Interpolates the prepared lightning data onto the defined regular grid and displays the result as an image. This visualizes the spatial distribution of lightning extent density on a uniform grid. ```python interp_field = griddata(data_loc, interp_data, interp_loc, method='linear') interp_field.shape = reg_lon.shape fig,ax = plt.subplots(1,1,figsize=(7,7), dpi=144) plt.imshow(interp_field, extent=(reg_lon.min(), reg_lon.max(), reg_lat.min(), reg_lat.max()), origin='lower') # ax.axis((-700,-300,650,1000)) ``` -------------------------------- ### Open NetCDF Dataset Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Opens a NetCDF dataset for processing. Ensure the file path is correct. ```python klbb = xr.open_dataset('/Users/ebruning/Downloads/KLBB20180702_043208_V06.nc') ``` -------------------------------- ### Generate GLM grids using a shell command Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb Constructs and executes a shell command to create GLM grids. This command processes specified GLM data files into a fixed grid format. Ensure the `make_GLM_grids.py` script is accessible. ```python import subprocess import os, glob import tempfile tmpdir = tempfile.TemporaryDirectory() import glmtools from glmtools.test.common import get_sample_data_path glmtools_path = os.path.abspath(glmtools.__path__[0]) # Set the start time and duration startdate = datetime(2018, 7, 2, 4, 30) duration = timedelta(0, 60*5) enddate = startdate+duration cmd = "python /Users/ebruning/code/glmtools/examples/grid/make_GLM_grids.py" cmd += " -o {1}/{{start_time:%Y/%b/%d}}/{{dataset_name}}" cmd += " --fixed_grid --split_events --float_output" cmd += " --goes_position=east --goes_sector=meso" cmd += " --ctr_lat=33.5 --ctr_lon=-101.5 --dx=2.0 --dy=2.0" cmd += " --start={3} --end={4} {2}" cmd = cmd.format(glmtools_path, tmpdir.name, ' '.join(samples), startdate.isoformat(), enddate.isoformat()) # print (cmd) out_bytes = subprocess.check_output(cmd.split()) # print(out_bytes.decode('utf-8')) grid_dir_base = tmpdir.name nc_files = glob.glob(os.path.join(grid_dir_base, startdate.strftime('%Y/%b/%d'),'*.nc')) print(nc_files) ``` -------------------------------- ### Import necessary libraries Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb Imports essential libraries for data manipulation, file operations, and GLM dataset handling. ```python import os import numpy as np import pandas as pd import ipywidgets as widgets from glmtools.io.glm import GLMDataset from datetime import datetime, timedelta ``` -------------------------------- ### List temporary directory contents (Bash) Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/glm_test_data_new_grid_dev.ipynb Lists the contents of the temporary directory where gridded files were saved. This is a bash command for inspecting the output. ```bash # ls /var/folders/sp/7k9p40wj1x9fdvwjbdrs4ffm0000gn/T/tmp7f3_aeir/2018/Jul/02 # ncdump -h /var/folders/sp/7k9p40wj1x9fdvwjbdrs4ffm0000gn/T/tmp7f3_aeir/2018/Jul/02/GLM-00-00_20180702_043000_300_1src_056urad-dx_flash_area_min.nc ``` -------------------------------- ### Print Projection and Coordinate Information Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Prints the Lambert Conformal Projection details, x, and y coordinates from the hrrr dataset. ```python print(hrrr.LambertConformal_Projection) print('-----') print(hrrr.x) print('-----') print(hrrr.y) ``` -------------------------------- ### Overlay Radar and Lightning Data Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Generates a plot overlaying radar reflectivity data with lightning flash extent density. This helps in visualizing the spatial relationship between lightning activity and storm structure. ```python x_sub = slice(500, None) y_sub = slice(None, None) fig, ax = plt.subplots(1,1,figsize=(9,5), dpi=144) im = ax.pcolormesh(lon_ltg_edge[y_sub, x_sub], lat_ltg_edge[y_sub, x_sub], np.log10(glm.flash_extent_density[y_sub, x_sub]), vmin=0, vmax=1.0, alpha=0.5, zorder=10) plt.colorbar(im, ax=ax) radar_im=ax.pcolormesh(radar_lon, radar_lat, dbz, zorder=0, vmin=0, vmax=60, cmap='gist_ncar', alpha=0.5) plt.colorbar(radar_im, ax=ax) if False: for l2 in l2s: ax.plot(l2.event_lon, l2.event_lat, linestyle='', marker='s', markersize=3, linewidth=0.5, markeredgecolor='r', markerfacecolor='none') # ax.axis((-120, -65, 10, 55)) ax.axis((-103, -98, 30, 35)) ``` -------------------------------- ### Reduce Dataset to Specific Flashes Source: https://github.com/deeplycloudy/glmtools/blob/master/README.md Load a GLM dataset and extract a subset of flashes based on a list of flash IDs. This is useful for focusing analysis on particular events. ```python from glmtools.io.glm import GLMDataset filename = 'OR_GLM-L2-LCFA_G16_s20180040537000_e20180040537200_c20180040537226.nc' glm = GLMDataset(filename) flash_id_list = glm.dataset.flash_id[20:30] smaller_dataset = glm.get_flashes(flash_id_list) ``` -------------------------------- ### Plot GLM Flash Extent Density with L2 Locations Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb This code visualizes GLM flash extent density using `pcolormesh` with parallax-corrected edge locations and overlays original L2 lightning event locations marked in red. ```python x_sub = slice(500, None) y_sub = slice(None, None) fig, ax = plt.subplots(1,1,figsize=(9,5), dpi=144) im = ax.pcolormesh(lon_ltg_edge[y_sub, x_sub], lat_ltg_edge[y_sub, x_sub], np.log10(glm.flash_extent_density[y_sub, x_sub]), vmin=0, vmax=1.0) plt.colorbar(im, ax=ax) if True: for l2 in l2s: ax.plot(l2.event_lon, l2.event_lat, linestyle='', marker='s', markersize=3, linewidth=0.5, markeredgecolor='r', markerfacecolor='none') # ax.axis((-120, -65, 10, 55)) ax.axis((-103, -98, 30, 35)) ``` -------------------------------- ### Create Interactive Widgets for Plotting Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb Generates dropdown and slider widgets for selecting time and fields, and sets up an observer pattern to update the plot interactively. Requires ipywidgets. ```python from ipywidgets import widgets time_options = [str(t0) for t0 in glm_grids.time.to_series()] time_options.sort() field_options = list(k for k in glm_grids.variables.keys() if 'nominal' not in k) for v in ['x', 'y', 'time', 'goes_imager_projection', 'DQF']: field_options.remove(v) field_dropdown = widgets.Dropdown(options=field_options) time_slider = widgets.SelectionSlider(options=time_options) glm_select = widgets.HBox([field_dropdown, time_slider]) from functools import partial plot = partial(plot, fig=fig, field_widget=field_dropdown, time_widget=time_slider) time_slider.observe(plot) field_dropdown.observe(plot) display(glm_select) # plot('yo') time_slider.value = time_slider.options[3] ``` -------------------------------- ### Placeholder for Accumulating Minimums Source: https://github.com/deeplycloudy/glmtools/blob/master/docs/newgrid.md This snippet represents a custom accumulation function to calculate the minimum of flash areas, replacing the default summation. ```python accumulate_min_on_grid ``` -------------------------------- ### Import Libraries for GLM Tools Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Imports necessary libraries including xarray for data handling, numpy for numerical operations, and pyproj for coordinate system transformations. ```python import xarray as xr import numpy as np import pyproj as proj4 # print(proj4.pj_ellps['GRS80']) ``` -------------------------------- ### Convert DOT call graph to PDF Source: https://github.com/deeplycloudy/glmtools/blob/master/docs/callgraph.md This command converts a GraphViz DOT file into a PDF format with a looser layout. This is useful for visualizing complex call graphs. ```bash dot -n1 -Tpdf pycallgraph.dot > pycallgraph.pdf ``` -------------------------------- ### Import Libraries for GLM Data Handling Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/basic_read_plot.ipynb Import necessary libraries including os, numpy, matplotlib, and GLMDataset for data manipulation and visualization. ```python import os %matplotlib inline import numpy as np import matplotlib.pyplot as plt from glmtools.io.glm import GLMDataset ``` -------------------------------- ### Placeholder for Grid Processing Source: https://github.com/deeplycloudy/glmtools/blob/master/docs/newgrid.md This snippet indicates a placeholder for grid processing logic, specifically related to reading and replicating data for fixed grid quads. ```python io.mimic_lma.fast_fixed_grid_read_flash_chunk ``` -------------------------------- ### Display Image from Generated Sequence Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/plot_glm_test_data.ipynb This snippet displays a specific image from the previously generated sequence using IPython.display.Image. Ensure the 'images_out' list is populated before use. ```python if False: from IPython.display import Image Image(images_out[3]) ``` -------------------------------- ### Plotting GLM Grid Data Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/aggregate_and_plot.ipynb Sets up and displays a plot of GLM grid data using matplotlib and glmtools. Requires glm_grids and a time variable. ```python %matplotlib notebook import matplotlib.pyplot as plt from glmtools.plot.grid import plot_glm_grid fields_6panel = ['flash_extent_density', 'minimum_flash_area','total_energy', 'group_extent_density', 'average_group_area', 'group_centroid_density'] def plot(w, fig=None, time_widget=None, field_widget=None, subplots=(2,3), fields=None): t = pd.to_datetime(time_widget.value) n_subplots = subplots[0] * subplots[1] if fields is None: if n_subplots == 1: fields = [field_widget.value] else: fields = fields_6panel[0:n_subplots] mapax, cbar_obj = plot_glm_grid(fig, glm_grids, t, fields, subplots=subplots, axes_facecolor = (1.0, 1.0, 1.0), map_color = (0.2, 0.2, 0.2)) fig = plt.figure(figsize=(18,12)) plt.show() ``` -------------------------------- ### Plot Uncorrected GLM Flash Extent Density Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb This code visualizes GLM flash extent density using `pcolormesh` with uncorrected edge locations and overlays original L2 lightning event locations marked in red. ```python x_sub = slice(500, None) y_sub = slice(None, None) fig, ax = plt.subplots(1,1,figsize=(9,5), dpi=144) im = ax.pcolormesh(lon_edge[y_sub, x_sub], lat_edge[y_sub, x_sub], np.log10(glm.flash_extent_density[y_sub, x_sub]), vmin=0, vmax=1.0) plt.colorbar(im, ax=ax) if True: for l2 in l2s: ax.plot(l2.event_lon, l2.event_lat, linestyle='', marker='s', markersize=3, linewidth=0.5, markeredgecolor='r', markerfacecolor='none') # ax.axis((-120, -65, 30, 35)) ax.axis((-103, -98, 30, 35)) ``` -------------------------------- ### Load GLM L2 LCFA Point Data Files Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Loads multiple GLM L2 LCFA point data files into a list of xarray Datasets. These files contain lightning event data. ```python l2files = ['/Users/ebruning/code/glmtools/glmtools/test/data/OR_GLM-L2-LCFA_G16_s20181830433000_e20181830433200_c20181830433231.nc', '/Users/ebruning/code/glmtools/glmtools/test/data/OR_GLM-L2-LCFA_G16_s20181830433200_e20181830433400_c20181830433424.nc', '/Users/ebruning/code/glmtools/glmtools/test/data/OR_GLM-L2-LCFA_G16_s20181830433400_e20181830434000_c20181830434029.nc'] l2s = [xr.open_dataset(ds) for ds in l2files] ``` -------------------------------- ### Visualize Interpolated Data on LCC Grid Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/parallax-corrected-latlon.ipynb Creates a pseudocolor plot of GLM flash extent density interpolated onto the LCC grid. It uses edge coordinates for the pcolormesh and sets specific axis limits for the visualization. ```python lccx_edge = centers_to_edges_2d(lccx) lccy_edge = centers_to_edges_2d(lccy) fig,ax = plt.subplots(1,1,figsize=(9,7), dpi=144) ax.pcolormesh(lccx_edge[y_sub,x_sub]/1000.0, lccy_edge[y_sub,x_sub]/1000.0, glm.flash_extent_density[y_sub,x_sub]) ax.axis((-700,-300,650,1000)) ``` -------------------------------- ### Interactive GLM Data Selection Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/aggregate_and_plot.ipynb Creates interactive dropdown and slider widgets for selecting GLM fields and time, then links them to a plotting function. Requires ipywidgets. ```python from ipywidgets import widgets time_options = [str(t0) for t0 in glm_grids.time.to_series()] time_options.sort() field_options = list(k for k in glm_grids.variables.keys() if 'nominal' not in k) print(field_options) for v in ['x', 'y', 'time', 'goes_imager_projection']: field_options.remove(v) field_dropdown = widgets.Dropdown(options=field_options) time_slider = widgets.SelectionSlider(options=time_options) glm_select = widgets.HBox([field_dropdown, time_slider]) from functools import partial plot = partial(plot, fig=fig, field_widget=field_dropdown, time_widget=time_slider) time_slider.observe(plot) field_dropdown.observe(plot) display(glm_select) plot('yo') # trigger plot since slider won't adjust with only one time. time_slider.value = time_slider.options[0] ``` -------------------------------- ### Plot Mirrored GOES West CONUS Grid Source: https://github.com/deeplycloudy/glmtools/blob/master/examples/FixedGridDomains.ipynb Creates a GOES West CONUS grid that is a mirror image of the GOES East CONUS grid. This is achieved by copying the West grid and negating its East-West center coordinate. Use this to visualize a mirrored view. ```python gridspec_paconus = fixed.get_GOESR_grid(position='west', view='conus', resolution='2.0km').copy() gridspec_econus = fixed.get_GOESR_grid(position='east', view='conus', resolution='2.0km').copy() gridspec = gridspec_paconus.copy() gridspec['centerEW'] = -gridspec_econus['centerEW'] plot_domain(gridspec, title='GOES West (mirror of East CONUS)') ```