Skip to content

Commit

Permalink
Feature #2560 Fire GridStat use case (#2769)
Browse files Browse the repository at this point in the history
* added config file and python scripts for fire weather use case

* Improved logic if multiple files were found to use the closest file to the valid time. Assuming that the files are in order, it will use the first file if multiple files match the valid hour or the last file if multiple files match 1 hour prior to the valid hour. This does not factor in if files before and after the valid time were found. Modifications are needed to obtain the correct file if, for example, the valid time is 12Z and there are 1258 and 1159 files available -- in this case the 1258 file will be used even though 1159 is closer.

* rename use case and update configuration to read data from appropriate directories

* per #2560, add new use case to automated tests

* turn of use case to prepare for PR

* removed comments

* added in-progress use case documentation - still needs updates

* fix formatting

* more formatting

* more doc formatting and cleanup

* remove notes from sections that were updated

* doc cleanup

* add thumbnail for new use case

* add description of fire use case category

* turn off use case

* fix SonarQube complaints

* update use case doc to match use case template

* minor formatting change to match template

* update path for kml schema file

* use wildcard to avoid having to reference namespace that includes insecure protocol

* Update documentation to resemble template

---------

Co-authored-by: j-opatz <59586397+j-opatz@users.noreply.github.com>
  • Loading branch information
georgemccabe and j-opatz authored Nov 13, 2024
1 parent 5fadd22 commit b4c52c2
Show file tree
Hide file tree
Showing 10 changed files with 504 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .github/parm/use_case_groups.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
"index_list": "0-1",
"run": false
},
{
"category": "fire",
"index_list": "0",
"run": false
},
{
"category": "land_surface",
"index_list": "0",
Expand Down
1 change: 1 addition & 0 deletions docs/Contributors_Guide/add_use_case.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ one of the following:
* climate
* clouds
* data_assimilation
* fire
* extremes
* land_surface
* marine_and_cryosphere
Expand Down
6 changes: 4 additions & 2 deletions docs/Users_Guide/quicksearch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,15 @@ Use Cases by Application:
| `Air Quality and Composition <../search.html?q=AirQualityAndCompAppUseCase&check_keywords=yes&area=default>`_
| `Climate <../search.html?q=ClimateAppUseCase&check_keywords=yes&area=default>`_
| `Clouds <../search.html?q=CloudsAppUseCase&check_keywords=yes&area=default>`_
| `Short Range <../search.html?q=ShortRangeAppUseCase&check_keywords=yes&area=default>`_
| `Data Assimilation <../search.html?q=DataAssimilationAppUseCase&check_keywords=yes&area=default>`_
| `Ensemble <../search.html?q=EnsembleAppUseCase&check_keywords=yes&area=default>`_
| `Fire <../search.html?q=FireAppUseCase&check_keywords=yes&area=default>`_
| `Land Surface <../search.html?q=LandSurfaceAppUseCase&check_keywords=yes&area=default>`_
| `Marine and Cryosphere <../search.html?q=MarineAndCryosphereAppUseCase&check_keywords=yes&area=default>`_
| `Medium Range <../search.html?q=MediumRangeAppUseCase&check_keywords=yes&area=default>`_
| `PBL <../search.html?q=PBLAppUseCase&check_keywords=yes&area=default>`_
| `Precipitation <../search.html?q=PrecipitationAppUseCase&check_keywords=yes&area=default>`_
| `Short Range <../search.html?q=ShortRangeAppUseCase&check_keywords=yes&area=default>`_
| `Space Weather <../search.html?q=SpaceWeatherAppUseCase&check_keywords=yes&area=default>`_
| `Subseasonal to Seasonal <../search.html?q=S2SAppUseCase&check_keywords=yes&area=default>`_
| `Subseasonal to Seasonal: Madden-Julian Oscillation <../search.html?q=S2SMJOAppUseCase&check_keywords=yes&area=default>`_
Expand All @@ -95,14 +96,15 @@ Use Cases by Application:
| **Air Quality and Composition**: *AirQualityAndCompAppUseCase*
| **Climate**: *ClimateAppUseCase*
| **Clouds**: *CloudsAppUseCase*
| **Short Range**: *ShortRangeAppUseCase*
| **Data Assimilation**: *DataAssimilationAppUseCase*
| **Ensemble**: *EnsembleAppUseCase*
| **Fire**: *FireAppUseCase*
| **LandSurface**: *LandSurfaceAppUseCase*
| **Marine and Cryosphere**: *MarineAndCryosphereAppUseCase*
| **Medium Range**: *MediumRangeAppUseCase*
| **PBL**: *PBLAppUseCase*
| **Precipitation**: *PrecipitationAppUseCase*
| **Short Range**: *ShortRangeAppUseCase*
| **Space Weather**: *SpaceWeatherAppUseCase*
| **Subseasonal to Seasonal**: *S2SAppUseCase*
| **Subseasonal to Seasonal: Madden-Julian Oscillation**: *S2SMJOAppUseCase*
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
"""
GridStat: WRF and MMA Fire Perimeter
====================================
model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter.conf
"""
##############################################################################
# .. contents::
# :depth: 1
# :local:
# :backlinks: none

##############################################################################
# Scientific Objective
# --------------------
#
# This use case demonstrates the use of GridStat to evaluate the performance of the
# fire spread forecast from the WRF-Fire model for the 416 fire in Colorado in 2018.
# Using available fire perimeter observations and WRF-Fire forecasts,
# contingency statistics are produced to evaluate the forecast performance
# relative to the observed fire.

##############################################################################
# Version Added
# -------------
#
# METplus version 6.0

##############################################################################
# Datasets
# --------
#
#
# **Forecast:** WRF Fire
#
# **Observations:** Multimission Aircraft (MMA)
#
# **Location:** All of the input data required for this use case can be
# found in a sample data tarball. Each use case category will have
# one or more sample data tarballs. It is only necessary to download
# the tarball with the use case’s dataset and not the entire collection
# of sample data. Click here to access the METplus releases page and download sample data
# for the appropriate release: https://github.com/dtcenter/METplus/releases
# This tarball should be unpacked into the directory that you will
# set the value of INPUT_BASE. See :ref:`running-metplus` section for more information.
#


##############################################################################
# METplus Components
# ------------------
#
# This use case uses the UserScript wrapper to run a Python script to that
# converts KML fire perimeter files to the poly line format that can be read by
# MET. Then it runs GenVxMask to create gridded MET NetCDF files from the poly
# files. Then it runs GridStat to process the WRF fire forecast files and the
# observation mask files.
#

##############################################################################
# METplus Workflow
# ----------------
#
# **Beginning time (INIT_BEG):** 2018-06-01 at 16Z
#
# **End time (INIT_END):** 2018-06-01 at 16Z
#
# **Increment between beginning and end times (INIT_INCREMENT):** None
#
# **Sequence of forecast leads to process (LEAD_SEQ):** 4 hour, 23 hour, 32 hour
#
# This use case processes 3 forecast leads initialized at 16Z on June 1, 2018, running 3 times.
# First, the UserScript tool is called. This tool calls a Python script to convert the
# kml shapefiles to polylines. Then, GenVxMask is run to convert the shapefile
# produced by UserScript to a netCDF mask, providing the observation input for GridStat.
# Finally, GridStat is called to compare the WRF-Fire forecast of fire area to the
# observation mask created using the GenVxMask tool. The GridStat call uses Python Embedding
# in order to read the WRF-Fire subgrid into GridStat.

##############################################################################
# METplus Configuration
# ---------------------
#
# METplus first loads the default configuration file,
# then it loads any configuration files passed to METplus via the command line
# e.g. parm/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter.conf
#
# .. highlight:: bash
# .. literalinclude:: ../../../../parm/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter.conf
#

##############################################################################
# MET Configuration
# -----------------
#
# METplus sets environment variables based on user settings in the METplus
# configuration file. See :ref:`How METplus controls MET config file settings<metplus-control-met>` for more details.
#
# **YOU SHOULD NOT SET ANY OF THESE ENVIRONMENT VARIABLES YOURSELF! THEY WILL BE OVERWRITTEN BY METPLUS WHEN IT CALLS THE MET TOOLS!**
#
# If there is a setting in the MET configuration file that is currently
# not supported by METplus you’d like to control, please refer to:
# :ref:`Overriding Unsupported MET config file settings<met-config-overrides>`
#
# .. dropdown:: GridStatConfig_wrapped
#
# .. highlight:: bash
# .. literalinclude:: ../../../../parm/met_config/GridStatConfig_wrapped
#

##############################################################################
# Python Embedding
# ----------------
#
# This use case uses a Python embedding script to read the WRF-Fire forecast into GridStat.
# The script hard codes settings directly from WRF-Fire for the WRF-Fire netCDF variable name (FIRE_AREA)
# as well as the format of the WRF-Fire forecast file template. The input directory and valid time
# are read from the METplus script. Once the file(s) are found, the script sets attributes for
# initiation and valid times, variable name, level, and units in MET format and defines a grid
# based on the input WRF-Fire netCDF file's subgrid. The data from the FIRE_AREA variable and MET attributes
# are then printed to be read in by GridStat.
#
# .. dropdown:: parm/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter/read_wrfout_fire.py
#
# .. highlight:: python
# .. literalinclude:: ../../../../parm/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter/read_wrfout_fire.py
#
# For more information on the basic requirements to utilize Python Embedding in METplus,
# please refer to the MET User’s Guide section on `Python embedding <https://met.readthedocs.io/en/latest/Users_Guide/appendixF.html#appendix-f-python-embedding>`_

##############################################################################
# User Scripting
# --------------
#
# This use case calls a Python script to read MMA fire perimeter .kml files and convert them
# into a poly line file that can be read by GenVxMask. The script hard codes the filename template
# for the .kml files and a valid time format. This valid time format is provided by the METplus configuration file.
# The script the sets up a variable for the previous valid time and an output file path.
# If a .kml file is not found for the current valid time, the script searches for a .kml file
# from the previous hours. Once a file is found, the Python script parses the input file to find
# the set of coordinates that define the fire perimeter. These coordinates are then written to
# a text file (.poly file) in the order longitude, latitude, elevation for each point.
# This .poly file is then ready to be read in by the GenVxMask tool.
#
# .. dropdown:: parm/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter/find_and_read_fire_perim_poly.py
#
# .. highlight:: python
# .. literalinclude:: ../../../../parm/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter/find_and_read_fire_perim_poly.py
#



##############################################################################
# Running METplus
# ---------------
#
# Pass the use case configuration file to the run_metplus.py script
# along with any user-specific system configuration files if desired::
#
# run_metplus.py /path/to/METplus/parm/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter.conf /path/to/user_system.conf
#
# See :ref:`running-metplus` for more information.
#

##############################################################################
# Expected Output
# ---------------
#
# A successful run will output the following both to the screen and to the logfile::
#
# INFO: METplus has successfully finished running.
#
# Refer to the value set for **OUTPUT_BASE** to find where the output data was generated.
# There are three groups of outputs. First, three polyline files resulting from the UserScript tool
#
# * poly/fire_perim_20180601_20.poly
# * poly/fire_perim_20180602_15.poly
# * poly/fire_perim_20180603_00.poly
#
# Second, three netCDF files resulting from the GenVxMask tool containing fire perimeter observations
#
# * mask/fire_perim_20180601_20_mask.nc
# * mask/fire_perim_20180602_15_mask.nc
# * mask/fire_perim_20180603_00_mask.nc
#
# Finally, six files from the GridStat tool run with Python Embedding. The .stat files contain the
# CTC and CTS line types for the FIRE_AREA variable at the given lead time (two lines total per stat file).
# The netCDF files contain the following five fields: lat (latitude), lon (longitude),
# FCST_FIRE_AREA_Z0_FULL (fire spread area from the WRF-Fire forecast), OBS_FIRE_PERIM_all_all_FULL (fire spread area from the .kml observations),
# and DIFF_FIRE_AREA_Z0_FIRE_PERIM_all_all_FULL (both the forecast and observed fire spread areas, including overlaps and differences).
#
# * grid_stat/2018060120/grid_stat_040000L_20180601_200000V.stat
# * grid_stat/2018060120/grid_stat_040000L_20180601_200000V_pairs.nc
# * grid_stat/2018060215/grid_stat_230000L_20180602_150000V.stat
# * grid_stat/2018060215/grid_stat_230000L_20180602_150000V_pairs.nc
# * grid_stat/2018060300/grid_stat_320000L_20180603_000000V.stat
# * grid_stat/2018060300/grid_stat_320000L_20180603_000000V_pairs.nc
#

##############################################################################
# Keywords
# --------
#
# .. note::
#
# * UserScriptUseCase
# * GenVxMaskToolUseCase
# * GridStatToolUseCase
# * PythonEmbeddingFileUseCase
# * GRIB2FileUseCase
# * FireAppUseCase
#
# Navigate to the :ref:`quick-search` page to discover other similar use cases.
#
#
#
# sphinx_gallery_thumbnail_path = '_static/fire-GridStat_fcstWRF_obsMMA_fire_perimeter.png'
3 changes: 3 additions & 0 deletions docs/use_cases/model_applications/fire/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fire
----
Verification of fire weather-related atmospheric parameters and fire spread models
3 changes: 3 additions & 0 deletions internal/tests/use_cases/all_use_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ Category: data_assimilation
0::StatAnalysis_fcstHAFS_obsPrepBufr_JEDI_IODA_interface::model_applications/data_assimilation/StatAnalysis_fcstHAFS_obsPrepBufr_JEDI_IODA_interface.conf
1::StatAnalysis_fcstGFS_HofX_obsIODAv2_PyEmbed::model_applications/data_assimilation/StatAnalysis_fcstGFS_HofX_obsIODAv2_PyEmbed.conf:: py_embed

Category: fire
0::GridStat_fcstWRF_obsMMA_fire_perimeter::model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter.conf::py_embed


Category: land_surface
0::PointStat_fcstCESM_obsFLUXNET2015_TCI:: model_applications/land_surface/PointStat_fcstCESM_obsFLUXNET2015_TCI.conf:: metplotpy_env, py_embed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
[config]

###
# Processes to run
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#process-list
###

PROCESS_LIST = UserScript, GenVxMask, GridStat


###
# Time Info
# LOOP_BY options are INIT, VALID, RETRO, and REALTIME
# If set to INIT or RETRO:
# INIT_TIME_FMT, INIT_BEG, INIT_END, and INIT_INCREMENT must also be set
# If set to VALID or REALTIME:
# VALID_TIME_FMT, VALID_BEG, VALID_END, and VALID_INCREMENT must also be set
# LEAD_SEQ is the list of forecast leads to process
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#timing-control
###

USER_SCRIPT_RUNTIME_FREQ = RUN_ONCE_FOR_EACH

LOOP_BY = INIT
INIT_TIME_FMT = %Y%m%d%H
INIT_BEG = 2018060116
INIT_END = 2018060116
INIT_INCREMENT = 1d

LEAD_SEQ = 4H, 23H, 32H


###
# File I/O
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#directory-and-filename-template-info
###

SCRIPT_DIR = {PARM_BASE}/use_cases/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter

USER_SCRIPT_INPUT_DIR = {INPUT_BASE}/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter/mma
USER_SCRIPT_OUTPUT_DIR = {OUTPUT_BASE}/poly


GEN_VX_MASK_INPUT_DIR =
GEN_VX_MASK_INPUT_TEMPLATE = "lambert 472 472 37.402645 -107.88144 -107.808 0.02754 6371.229 37.461 N"

GEN_VX_MASK_INPUT_MASK_DIR =
GEN_VX_MASK_INPUT_MASK_TEMPLATE = {USER_SCRIPT_OUTPUT_DIR}/fire_perim_{valid?fmt=%Y%m%d_%H}.poly

GEN_VX_MASK_OUTPUT_DIR =
GEN_VX_MASK_OUTPUT_TEMPLATE = {OUTPUT_BASE}/mask/fire_perim_{valid?fmt=%Y%m%d_%H}_mask.nc

FCST_GRID_STAT_INPUT_DIR = {INPUT_BASE}/model_applications/fire/GridStat_fcstWRF_obsMMA_fire_perimeter/wrf
FCST_GRID_STAT_INPUT_TEMPLATE = PYTHON_NUMPY

OBS_GRID_STAT_INPUT_TEMPLATE = {GEN_VX_MASK_OUTPUT_TEMPLATE}

GRID_STAT_OUTPUT_DIR = {OUTPUT_BASE}/grid_stat
GRID_STAT_OUTPUT_TEMPLATE = {valid?fmt=%Y%m%d%H}


###
# UserScript Settings
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#userscript
###

USER_SCRIPT_COMMAND = python3 {SCRIPT_DIR}/find_and_read_fire_perim_poly.py {USER_SCRIPT_INPUT_DIR} {valid?fmt=%Y%m%d%H} {USER_SCRIPT_OUTPUT_DIR}


###
# GenVxMask Settings
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#genvxmask
###

GEN_VX_MASK_OPTIONS = -type poly


###
# GridStat Settings (optional)
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#gridstat
###

#LOG_GRID_STAT_VERBOSITY = 4

MODEL = WRF_FIRE
OBTYPE = FIRE_PERIM_KML

FCST_VAR1_NAME = {SCRIPT_DIR}/read_wrfout_fire.py {FCST_GRID_STAT_INPUT_DIR}/{init?fmt=%Y%m%d_%H} {valid?fmt=%Y%m%d_%H%M%S}
FCST_VAR1_LEVELS = L0
FCST_VAR1_THRESH = >0.5

OBS_VAR1_NAME = FIRE_PERIM
OBS_VAR1_LEVELS = "*,*"
OBS_VAR1_THRESH = ==1
OBS_VAR1_OPTIONS = set_attr_valid = "{valid?fmt=%Y%m%d_%H%M%S}"


GRID_STAT_REGRID_TO_GRID = FCST

GRID_STAT_OUTPUT_FLAG_CTC = STAT
GRID_STAT_OUTPUT_FLAG_CTS = STAT

GRID_STAT_NC_PAIRS_FLAG_LATLON = TRUE
Loading

0 comments on commit b4c52c2

Please sign in to comment.