diff --git a/met/.cproject b/met/.cproject deleted file mode 100644 index a4fe10144f..0000000000 --- a/met/.cproject +++ /dev/null @@ -1,362 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/met/.project b/met/.project deleted file mode 100644 index fcf9456036..0000000000 --- a/met/.project +++ /dev/null @@ -1,78 +0,0 @@ - - - MET_svn - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - ?name? - - - - org.eclipse.cdt.make.core.append_environment - true - - - org.eclipse.cdt.make.core.autoBuildTarget - all - - - org.eclipse.cdt.make.core.buildArguments - - - - org.eclipse.cdt.make.core.buildCommand - make - - - org.eclipse.cdt.make.core.cleanBuildTarget - clean - - - org.eclipse.cdt.make.core.contents - org.eclipse.cdt.make.core.activeConfigSettings - - - org.eclipse.cdt.make.core.enableAutoBuild - false - - - org.eclipse.cdt.make.core.enableCleanBuild - true - - - org.eclipse.cdt.make.core.enableFullBuild - true - - - org.eclipse.cdt.make.core.fullBuildTarget - all - - - org.eclipse.cdt.make.core.stopOnError - true - - - org.eclipse.cdt.make.core.useDefaultBuildCmd - true - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.ccnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - diff --git a/met/data/table_files/grib1_ncep_129_7.txt b/met/data/table_files/grib1_ncep_129_7.txt index aec86c19f3..eef20ff595 100644 --- a/met/data/table_files/grib1_ncep_129_7.txt +++ b/met/data/table_files/grib1_ncep_129_7.txt @@ -234,10 +234,10 @@ GRIB1 232 129 7 -1 "OZMAX8" "Ozone Daily Max from 8-hour Average" "ppbV" 233 129 7 -1 "PDMAX1" "PM 2.5 Daily Max from 1-hour Average" "mcg/m^3" 234 129 7 -1 "PDMX24" "PM 2.5 Daily Max from 24-hour Average" "mcg/m^3" -235 129 7 -1 "MAXREF" "Hourly Maximum of Simulated Reflectivity at 1 km AGL" "dbZ" -236 129 7 -1 "MXUPHL" "Hourly Maximum of Updraft Helicity over layer 2km to 5 km AGL" "m^2/s^2" -237 129 7 -1 "MAXUVV" "Hourly Maximum of Upward Vertical Velocity in the lowest 400hPa" "m/s" -238 129 7 -1 "MAXDVV" "Hourly Maximum of Downward Vertical Velocity in the lowest 400hPa" "m/s" +235 129 7 -1 "MAXREF" "Hourly Maximum of Simulated Reflectivity" "dbZ" +236 129 7 -1 "MXUPHL" "Hourly Maximum of Updraft Helicity" "m^2/s^2" +237 129 7 -1 "MAXUVV" "Hourly Maximum of Upward Vertical Velocity" "m/s" +238 129 7 -1 "MAXDVV" "Hourly Maximum of Downward Vertical Velocity" "m/s" 239 129 7 -1 "MAXVIG" "Hourly Maximum of Column Vertical Integrated Graupel" "kg/m^2" 240 129 7 -1 "RETOP" "Radar Echo Top (18.3 DBZ)" "m" 241 129 7 -1 "VRATE" "Ventilation Rate" "m^2/s" diff --git a/met/data/table_files/grib2_all.txt b/met/data/table_files/grib2_all.txt index c41a244178..270675890f 100644 --- a/met/data/table_files/grib2_all.txt +++ b/met/data/table_files/grib2_all.txt @@ -421,11 +421,11 @@ GRIB2 0 1 0 255 0 0 1 97 "MASSDS" "Mass Density of Snow" "kg/m^3" 0 1 0 255 0 0 20 2 "MASSMR" "Mass Mixing Ratio (Mass Fraction in Air)" "kg/kg" 0 1 0 255 0 0 1 28 "MAXAH" "Maximum Absolute Humidity" "kg/m^3" -0 0 0 255 7 1 2 221 "MAXDVV" "Hourly Maximum of Downward Vertical Velocity in the lowest 400hPa" "m/s" +0 0 0 255 7 1 2 221 "MAXDVV" "Hourly Maximum of Downward Vertical Velocity" "m/s" 0 1 0 255 0 0 2 21 "MAXGUST" "Maximum Wind Speed" "m/s" -0 0 0 255 7 1 16 198 "MAXREF" "Hourly Maximum of Simulated Reflectivity at 1 km AGL" "dB" +0 0 0 255 7 1 16 198 "MAXREF" "Hourly Maximum of Simulated Reflectivity" "dB" 0 1 0 255 0 0 1 27 "MAXRH" "Maximum Relative Humidity" "%" -0 0 0 255 7 1 2 220 "MAXUVV" "Hourly Maximum of Upward Vertical Velocity in the lowest 400hPa" "m/s" +0 0 0 255 7 1 2 220 "MAXUVV" "Hourly Maximum of Upward Vertical Velocity" "m/s" 0 0 0 255 7 1 2 222 "MAXUW" "U Component of Hourly Maximum 10m Wind Speed" "m/s" 0 0 0 255 7 1 2 223 "MAXVW" "V Component of Hourly Maximum 10m Wind Speed" "m/s" 10 1 0 255 0 0 0 24 "MAXWH" "Maximum Individual Wave Height" "m" @@ -460,7 +460,7 @@ GRIB2 0 1 0 255 0 0 19 28 "MWTURB" "Mountain Wave Turbulence (Eddy Dissipation Rate)" "m2/3s-1" 0 0 0 255 7 1 19 192 "MXSALB" "Maximum Snow Albedo" "%" 0 1 0 255 0 0 19 17 "MXSALB" "Maximum Snow Albedosee Note 1" "%" -0 0 0 255 7 1 7 199 "MXUPHL" "Hourly Maximum of Updraft Helicity over Layer 2km to 5 km AGL" "m^2/s^2" +0 0 0 255 7 1 7 199 "MXUPHL" "Hourly Maximum of Updraft Helicity" "m^2/s^2" 10 1 0 255 0 0 0 30 "MZPTSW" "Mean Zero-Crossing Period of The Total Swell" "s" 10 1 0 255 0 0 0 29 "MZPWW" "Mean Zero-Crossing Period of The Wind Waves" "s" 10 1 0 255 0 0 0 28 "MZWPER" "Mean Zero-Crossing Wave Period" "s" @@ -1016,4 +1016,4 @@ GRIB2 4 1 0 255 0 0 6 1 "XLONG" "Solar X-ray Flux (XRS Long)" "W/m^2" 4 1 0 255 0 0 8 0 "XRAYRAD" "X-Ray Radiance" "W/sr/m^2" 4 1 0 255 0 0 6 2 "XSHRT" "Solar X-ray Flux (XRS Short)" "W/m^2" -10 1 0 255 0 0 2 10 "ZVCICEP" "Zonal Vector Component of Vertically Integrated Ice Internal Pressure" "Pa*m" \ No newline at end of file +10 1 0 255 0 0 2 10 "ZVCICEP" "Zonal Vector Component of Vertically Integrated Ice Internal Pressure" "Pa*m" diff --git a/met/data/table_files/met_header_columns_V10.0.txt b/met/data/table_files/met_header_columns_V10.0.txt index 851ae5e3ee..d2c8ae5c4f 100644 --- a/met/data/table_files/met_header_columns_V10.0.txt +++ b/met/data/table_files/met_header_columns_V10.0.txt @@ -17,7 +17,7 @@ V10.0 : STAT : PJC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID V10.0 : STAT : PRC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_THRESH) THRESH_[0-9]* PODY_[0-9]* POFD_[0-9]* V10.0 : STAT : PSTD : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_THRESH) BASER BASER_NCL BASER_NCU RELIABILITY RESOLUTION UNCERTAINTY ROC_AUC BRIER BRIER_NCL BRIER_NCU BRIERCL BRIERCL_NCL BRIERCL_NCU BSS BSS_SMPL THRESH_[0-9]* V10.0 : STAT : ECLV : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASER VALUE_BASER (N_PTS) CL_[0-9]* VALUE_[0-9]* -V10.0 : STAT : ECNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_ENS CRPS CRPSS IGN ME RMSE SPREAD ME_OERR RMSE_OERR SPREAD_OERR SPREAD_PLUS_OERR +V10.0 : STAT : ECNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_ENS CRPS CRPSS IGN ME RMSE SPREAD ME_OERR RMSE_OERR SPREAD_OERR SPREAD_PLUS_OERR CRPSCL CRPS_EMP CRPSCL_EMP CRPSS_EMP V10.0 : STAT : RPS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_PROB RPS_REL RPS_RES RPS_UNC RPS RPSS RPSS_SMPL RPS_COMP V10.0 : STAT : RHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_RANK) RANK_[0-9]* V10.0 : STAT : PHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BIN_SIZE (N_BIN) BIN_[0-9]* diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index d5ad94b01a..05905e9c67 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -887,9 +887,9 @@ ________________________________________________ CRPS ~~~~ -Called "CRPS" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` +Called "CRPS", "CRPSCL", "CRPS_EMP", and "CRPSCL_EMP" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` -The continuous ranked probability score (CRPS) is the integral, over all possible thresholds, of the Brier scores (:ref:`Gneiting et al., 2004 `). In MET, the CRPS calculation uses a normal distribution fit to the ensemble forecasts. In many cases, use of other distributions would be better. +The continuous ranked probability score (CRPS) is the integral, over all possible thresholds, of the Brier scores (:ref:`Gneiting et al., 2004 `). In MET, the CRPS is calculated two ways: using a normal distribution fit to the ensemble forecasts (CRPS and CRPSCL), and using the empirical ensemble distribution (CRPS_EMP and CRPSCL_EMP). In some cases, use of other distributions would be better. WARNING: The normal distribution is probably a good fit for temperature and pressure, and possibly a not horrible fit for winds. However, the normal approximation will not work on most precipitation forecasts and may fail for many other atmospheric variables. @@ -906,12 +906,14 @@ The score can be interpreted as a continuous version of the mean absolute error CRPS Skill Score ~~~~~~~~~~~~~~~~ -Called "CRPSS" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` +Called "CRPSS" and "CRPSS_EMP" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` The continuous ranked probability skill score (CRPSS) is similar to the MSESS and the BSS, in that it compares its namesake score to that of a reference forecast to produce a positively oriented score between 0 and 1. .. math:: \text{CRPSS} = 1 - \frac{\text{CRPS}_{fcst}}{ \text{CRPS}_{ref}} +For the normal distribution fit (CRPSS), the reference CRPS is computed using the climatological mean and standard deviation. For the empirical distribution (CRPSS_EMP), the reference CRPS is computed by sampling from the assumed normal climatological distribution defined by the mean and standard deviation. + IGN ~~~ diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index 60ef284b97..99532dcaf6 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -31,7 +31,7 @@ Often, the goal of ensemble forecasting is to reproduce the distribution of obse The relative position (RELP) is a count of the number of times each ensemble member is closest to the observation. For stochastic or randomly derived ensembles, this statistic is meaningless. For specified ensemble members, however, it can assist users in determining if any ensemble member is performing consistently better or worse than the others. -The ranked probability score (RPS) is included in the Ranked Probability Score (RPS) line type. It is the mean of the Brier scores computed from ensemble probabilities derived for each probability category threshold (prob_cat_thresh) specified in the configuration file. The continuous ranked probability score (CRPS) is the average the distance between the forecast (ensemble) cumulative distribution function and the observation cumulative distribution function. It is an analog of the Brier score, but for continuous forecast and observation fields. (:ref:`Gneiting et al., 2004 `). The CRPS statistic is included in the Ensemble Continuous Statistics (ECNT) line type, along with other statistics quantifying the ensemble spread and ensemble mean skill. +The ranked probability score (RPS) is included in the Ranked Probability Score (RPS) line type. It is the mean of the Brier scores computed from ensemble probabilities derived for each probability category threshold (prob_cat_thresh) specified in the configuration file. The continuous ranked probability score (CRPS) is the average the distance between the forecast (ensemble) cumulative distribution function and the observation cumulative distribution function. It is an analog of the Brier score, but for continuous forecast and observation fields. The CRPS statistic is computed using two methods: assuming a normal distribution defined by the ensemble mean and spread (:ref:`Gneiting et al., 2004 `) and using the empirical ensemble distribution (:ref:`Hersbach, 2000 `). The CRPS statistic is included in the Ensemble Continuous Statistics (ECNT) line type, along with other statistics quantifying the ensemble spread and ensemble mean skill. Ensemble observation error ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -587,10 +587,10 @@ The format of the STAT and ASCII output of the Ensemble-Stat tool are described - Number of ensemble values * - 27 - CRPS - - The Continuous Ranked Probability Score + - The Continuous Ranked Probability Score (normal distribution) * - 28 - CRPSS - - The Continuous Ranked Probability Skill Score + - The Continuous Ranked Probability Skill Score (normal distribution) * - 29 - IGN - The Ignorance Score @@ -615,6 +615,18 @@ The format of the STAT and ASCII output of the Ensemble-Stat tool are described * - 36 - SPREAD_PLUS_OERR - The square root of the sum of unperturbed ensemble variance and the observation error variance + * - 37 + - CRPSCL + - Climatological Continuous Ranked Probability Score (normal distribution) + * - 38 + - CRPS_EMP + - The Continuous Ranked Probability Score (empirical distribution) + * - 39 + - CRPSCL_EMP + - Climatological Continuous Ranked Probability Score (empirical distribution) + * - 40 + - CRPSS_EMP + - The Continuous Ranked Probability Skill Score (empirical distribution) .. _table_ES_header_info_es_out_RPS: diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index 5756e40cd5..1ec6fdacb9 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -170,7 +170,7 @@ When the "prob" entry is set as a dictionary to define the field of interest, se Measures for comparison against climatology ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -For each of the types of statistics mentioned above (categorical, continuous, and probabilistic), it is possible to calculate measures of skill relative to climatology. MET will accept a climatology file provided by the user, and will evaluate it as a reference forecast. Further, anomalies, i.e. departures from average conditions, can be calculated. As with all other statistics, the available measures will depend on the nature of the forecast. Common statistics that use a climatological reference include: the mean squared error skill score (MSESS), the Anomaly Correlation (ANOM_CORR and ANOM_CORR_UNCNTR), scalar and vector anomalies (SAL1L2 and VAL1L2), continuous ranked probability skill score (CRPSS), Brier Skill Score (BSS) (:ref:`Wilks, 2011 `; :ref:`Mason, 2004 `). +For each of the types of statistics mentioned above (categorical, continuous, and probabilistic), it is possible to calculate measures of skill relative to climatology. MET will accept a climatology file provided by the user, and will evaluate it as a reference forecast. Further, anomalies, i.e. departures from average conditions, can be calculated. As with all other statistics, the available measures will depend on the nature of the forecast. Common statistics that use a climatological reference include: the mean squared error skill score (MSESS), the Anomaly Correlation (ANOM_CORR and ANOM_CORR_UNCNTR), scalar and vector anomalies (SAL1L2 and VAL1L2), continuous ranked probability skill score (CRPSS and CRPSS_EMP), Brier Skill Score (BSS) (:ref:`Wilks, 2011 `; :ref:`Mason, 2004 `). Often, the sample climatology is used as a reference by a skill score. The sample climatology is the average over all included observations and may be transparent to the user. This is the case in most categorical skill scores. The sample climatology will probably prove more difficult to improve upon than a long term climatology, since it will be from the same locations and time periods as the forecasts. This may mask legitimate forecast skill. However, a more general climatology, perhaps covering many years, is often easier to improve upon and is less likely to mask real forecast skill. diff --git a/met/docs/Users_Guide/refs.rst b/met/docs/Users_Guide/refs.rst index 269242adb3..7e02dcb6d1 100644 --- a/met/docs/Users_Guide/refs.rst +++ b/met/docs/Users_Guide/refs.rst @@ -132,6 +132,12 @@ References | forecasts. *Monthly Weather Review*, 129, 550-560. | +.. _Hersbach-2000: + +| Hersbach, H., 2000: Decomposition of the Continuous Ranked Probability Score +| for Ensemble Prediction Systems. *Weather and Forecasting*, 15, 559-570. +| + .. _Jolliffe-2012: | Jolliffe, I.T., and D.B. Stephenson, 2012: *Forecast verification. A* diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index 4c3eb561bb..679c9e7fbf 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -29,22 +29,26 @@ Version `10.0.0-beta3 `_ release no * When reading MET NetCDF files, parse the "init_time" and "valid_time" attributes (`#1346 `_). * Python embedding enhancements: - * Complete support for Python XArray embedding (`#1534 `_). - * Correct error messages from Python embedding (`#1473 `_). + + * Complete support for Python XArray embedding (`#1534 `_). + * Correct error messages from Python embedding (`#1473 `_). * Application code: * Enhance Plot-Point-Obs to support regridding in the config file (`#1627 `_). * Update ASCII2NC and Point2Grid to create empty output files for zero input observations instead of erroring out (`#1630 `_). * Point2Grid Tool: - * Improve the Point2Grid runtime performance (`#1421 `_). - * Process point observations by variable name instead of GRIB code (`#1408 `_). - * Support the 2-dimensional time variable in Himawari data files (`#1580 `_). + + * Improve the Point2Grid runtime performance (`#1421 `_). + * Process point observations by variable name instead of GRIB code (`#1408 `_). + * Support the 2-dimensional time variable in Himawari data files (`#1580 `_). + * TC-Gen Tool: - * Overhaul the Tropical Cyclone genesis matching logic, add the development and operational scoring algorithms, and add many config file options (`#1448 `_). - * Add config file options to filter data by initialization time (init_inc and init_exc) and hurricane basin (basin_mask) (`#1626 `_). - * Add the genesis matched pair (GENMPR) output line type (`#1597 `_). - * Add a gridded NetCDF output file with counts for genesis events and track points (`#1430 `_). + + * Overhaul the Tropical Cyclone genesis matching logic, add the development and operational scoring algorithms, and add many config file options (`#1448 `_). + * Add config file options to filter data by initialization time (init_inc and init_exc) and hurricane basin (basin_mask) (`#1626 `_). + * Add the genesis matched pair (GENMPR) output line type (`#1597 `_). + * Add a gridded NetCDF output file with counts for genesis events and track points (`#1430 `_). Version `10.0.0-beta2 `_ release notes (20201207) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/met/scripts/Rscripts/plot_cnt.R b/met/scripts/Rscripts/plot_cnt.R index c36bb7f616..5af8a378db 100644 --- a/met/scripts/Rscripts/plot_cnt.R +++ b/met/scripts/Rscripts/plot_cnt.R @@ -22,20 +22,22 @@ ## file_list ## [-column name] ## [-out name] +## [-met_base path] ## [-save] ## ## Arguments: -## "file_list" is one or more files containing CNT lines. -## "-column name" specifies a CNT statistic to be plotted (multiple). -## "-out name" specifies an output PDF file name. -## "-save" calls save.image() before exiting R. +## "file_list" is one or more files containing CNT lines. +## "-column name" specifies a CNT statistic to be plotted (multiple). +## "-out name" specifies an output PDF file name. +## "-met_base path" is MET_INSTALL_DIR/share/met for the headers. +## "-save" calls save.image() before exiting R. ## ## Details: -## Updated for MET version 6.0. +## Updated on 02/03/2021 to parse version-specific headers. ## ## Examples: ## Rscript plot_cnt.R \ -## met-6.0/out/point_stat/*_cnt.txt +## out/point_stat/*_cnt.txt ## ## Author: ## John Halley Gotway (johnhg@ucar.edu), NCAR-RAL/DTC @@ -51,40 +53,8 @@ library(stats) # ######################################################################## -# Header for the CNT line type (MET version 6.0) -cnt_header <- c("VERSION", "MODEL", "DESC", - "FCST_LEAD", "FCST_VALID_BEG", "FCST_VALID_END", - "OBS_LEAD", "OBS_VALID_BEG", "OBS_VALID_END", - "FCST_VAR", "FCST_LEV", - "OBS_VAR", "OBS_LEV", - "OBTYPE", "VX_MASK", - "INTERP_MTHD", "INTERP_PNTS", - "FCST_THRESH", "OBS_THRESH", "COV_THRESH", - "ALPHA", "LINE_TYPE", "TOTAL", - "FBAR", "FBAR_NCL", "FBAR_NCU", "FBAR_BCL", "FBAR_BCU", - "FSTDEV", "FSTDEV_NCL", "FSTDEV_NCU", "FSTDEV_BCL", "FSTDEV_BCU", - "OBAR", "OBAR_NCL", "OBAR_NCU", "OBAR_BCL", "OBAR_BCU", - "OSTDEV", "OSTDEV_NCL", "OSTDEV_NCU", "OSTDEV_BCL", "OSTDEV_BCU", - "PR_CORR", "PR_CORR_NCL", "PR_CORR_NCU", "PR_CORR_BCL", "PR_CORR_BCU", - "SP_CORR", - "KT_CORR", "RANKS", "FRANK_TIES", "ORANK_TIES", - "ME", "ME_NCL", "ME_NCU", "ME_BCL", "ME_BCU", - "ESTDEV", "ESTDEV_NCL", "ESTDEV_NCU", "ESTDEV_BCL", "ESTDEV_BCU", - "MBIAS", "MBIAS_BCL", "MBIAS_BCU", - "MAE", "MAE_BCL", "MAE_BCU", - "MSE", "MSE_BCL", "MSE_BCU", - "BCMSE", "BCMSE_BCL", "BCMSE_BCU", - "RMSE", "RMSE_BCL", "RMSE_BCU", - "E10", "E10_BCL", "E10_BCU", - "E25", "E25_BCL", "E25_BCU", - "E50", "E50_BCL", "E50_BCU", - "E75", "E75_BCL", "E75_BCU", - "E90", "E90_BCL", "E90_BCU", - "EIQR", "EIQR_BCL", "EIQR_BCU", - "MAD", "MAD_BCL", "MAD_BCU") - # Temporary input file name -tmp_file <- "cnt_input.tmp" +tmp_file = "cnt_input.tmp" # Default output file name out_file = "cnt_plots.pdf" @@ -103,21 +73,24 @@ args = commandArgs(TRUE) # Check the number of arguments if(length(args) < 1) { - cat("Usage: plot_cnt.R\n") - cat(" cnt_file_list\n") - cat(" [-column name]\n") - cat(" [-out name]\n") - cat(" [-save]\n") - cat(" where \"file_list\" is one or more files containing CNT lines.\n") - cat(" \"-column name\" specifies a CNT statistic to be plotted (multiple).\n") - cat(" \"-out name\" specifies an output PDF file name.\n") - cat(" \"-save\" calls save.image() before exiting R.\n\n") - quit() + cat("Usage: plot_cnt.R\n") + cat(" file_list\n") + cat(" [-column name]\n") + cat(" [-out name]\n") + cat(" [-met_base path]\n") + cat(" [-save]\n") + cat(" where \"file_list\" is one or more files containing CNT lines.\n") + cat(" \"-column name\" specifies a CNT statistic to be plotted (multiple).\n") + cat(" \"-out name\" specifies an output PDF file name.\n") + cat(" \"-met_base path\" is MET_INSTALL_DIR/share/met for the headers.\n") + cat(" \"-save\" calls save.image() before exiting R.\n\n") + quit() } # Initialize file_list = c() stat_list = c() +met_base = '' save = FALSE # Parse the arguments @@ -133,6 +106,12 @@ while(i <= length(args)) { out_file = args[i+1] i = i+1 + } else if(args[i] == "-met_base") { + + # Set MET_BASE variable + met_base = args[i+1] + i = i+1 + } else if(args[i] == "-column") { # Add column name to the stat list @@ -158,6 +137,12 @@ if(length(stat_list) <= 0) stat_list <- default_stat_list # ######################################################################## +# Check for input files +if(is.null(file_list)) { + cat("ERROR: No input files specified!\n") + quit() +} + # Initialize data <- c() @@ -183,8 +168,44 @@ for(i in 1:length(file_list)) { system(cmd) } +# Check for no data +if(is.null(data)) { + cat("ERROR: No CNT data found!\n") + quit() +} + +# Store version from the data +version = unlist(strsplit(as.character(data[1,1]), '\\.')) +vXY = paste(version[1], version[2], sep='.') + +# Check met_base +if(nchar(met_base) == 0) { + met_base = Sys.getenv("MET_BASE") +} +if(nchar(met_base) == 0) { + cat("ERROR: The -met_base command line option or MET_BASE environment variable must be set!\n", + "ERROR: Define it as {MET INSTALLATION DIRECTORY}/share/met.\n", sep='') + quit() +} + +# Get the header columns +header_file = paste(met_base, "/table_files/met_header_columns_", vXY, ".txt", sep='') +print(paste("Reading Header File:", header_file)) +lty_str = paste(" : CNT ", sep='') +hdr_line = grep(lty_str, readLines(header_file), value=TRUE) +hdr_cols = trimws(unlist(strsplit(hdr_line, ':'))[4]) +hdr_lty = unlist(strsplit(hdr_cols, ' ')) + +# Check that header and data columns match +if(length(hdr_lty) != dim(data)[2]) { + cat("ERROR: The number of data (", dim(data)[2], + ") and header (", length(hdr_lty), + ") columns do not match!\n", sep='') + quit() +} + # After constructing the input data, attach column names -colnames(data) <- cnt_header +colnames(data) <- hdr_lty # Convert date/time columns to date/time objects data$FCST_VALID_BEG <- as.POSIXct(strptime(data$FCST_VALID_BEG, @@ -202,7 +223,7 @@ data$OBS_VALID_END <- as.POSIXct(strptime(data$OBS_VALID_END, # ######################################################################## -# Construct an idex +# Construct an index data$index <- paste(data$MODEL, data$FCST_VAR, data$FCST_LEV, data$OBS_VAR, data$OBS_LEV, diff --git a/met/scripts/Rscripts/plot_ensemble.R b/met/scripts/Rscripts/plot_ensemble.R index 27903dbbfc..6c5272da83 100644 --- a/met/scripts/Rscripts/plot_ensemble.R +++ b/met/scripts/Rscripts/plot_ensemble.R @@ -21,20 +21,22 @@ ## file_list ## [-line_type name] ## [-out name] +## [-met_base path] ## [-save] ## ## Arguments: -## "file_list" is one or more files containing CNT lines. +## "file_list" is one or more files containing CNT lines. ## "-line_type name" specifies a line type to process (multiple). -## "-out name" specifies an output PDF file name. -## "-save" calls save.image() before exiting R. +## "-out name" specifies an output PDF file name. +## "-met_base path" is MET_INSTALL_DIR/share/met for the headers. +## "-save" calls save.image() before exiting R. ## ## Details: -## Updated for MET version 8.0. +## Updated on 02/03/2021 to parse version-specific headers. ## ## Examples: ## Rscript plot_ensemble.R \ -## met-8.0/out/ensemble_stat/*.stat +## out/ensemble_stat/*.stat ## ## Author: ## John Halley Gotway (johnhg@ucar.edu), NCAR-RAL/DTC @@ -50,19 +52,6 @@ library(stats) # ######################################################################## -# MET version 8.0 header columns -met_header <- c("VERSION", "MODEL", "DESC", - "FCST_LEAD", "FCST_VALID_BEG", "FCST_VALID_END", - "OBS_LEAD", "OBS_VALID_BEG", "OBS_VALID_END", - "FCST_VAR", "FCST_LEV", "OBS_VAR", "OBS_LEV", - "OBTYPE", "VX_MASK", "INTERP_MTHD", "INTERP_PNTS", - "FCST_THRESH", "OBS_THRESH", "COV_THRESH", "ALPHA", - "LINE_TYPE"); -rhist_header <-c("TOTAL", "N_RANK", "RANK_"); -relp_header <-c("TOTAL", "N_ENS", "RELP_"); -ecnt_header <-c("TOTAL", "N_ENS", "CRPS", "CRPSS", "IGN", "ME", "RMSE", - "SPREAD", "ME_OERR", "RMSE_OERR", "SPREAD_OERR", "SPREAD_PLUS_OERR"); - # Temporary input file name tmp_file <- "ensemble_input.tmp" @@ -83,21 +72,24 @@ args = commandArgs(TRUE) # Check the number of arguments if(length(args) < 1) { - cat("Usage: plot_ensemble.R\n") - cat(" file_list\n") - cat(" [-line_type name]\n") - cat(" [-out name]\n") - cat(" [-save]\n") - cat(" where \"file_list\" is one or more files containing ensemble output.\n") - cat(" \"-line_type name\" specifies a line type to process (multiple).\n") - cat(" \"-out name\" specifies an output PDF file name.\n") - cat(" \"-save\" calls save.image() before exiting R.\n\n") - quit() + cat("Usage: plot_ensemble.R\n") + cat(" file_list\n") + cat(" [-line_type name]\n") + cat(" [-out name]\n") + cat(" [-met_base path]\n") + cat(" [-save]\n") + cat(" where \"file_list\" is one or more files containing ensemble output.\n") + cat(" \"-line_type name\" specifies a line type to process (multiple).\n") + cat(" \"-out name\" specifies an output PDF file name.\n") + cat(" \"-met_base path\" is MET_INSTALL_DIR/share/met for the headers.\n") + cat(" \"-save\" calls save.image() before exiting R.\n\n") + quit() } # Initialize file_list = c() line_types = c() +met_base = '' save = FALSE # Parse the arguments @@ -119,6 +111,12 @@ while(i <= length(args)) { line_types = c(line_types, args[i+1]) i = i+1 + } else if(args[i] == "-met_base") { + + # Set MET_BASE variable + met_base = args[i+1] + i = i+1 + } else { # Add input file to the file list @@ -138,6 +136,12 @@ if(length(line_types) <= 0) line_types <- default_line_types # ######################################################################## +# Check for input files +if(is.null(file_list)) { + cat("ERROR: No input files specified!\n") + quit() +} + read_line_type = function(line_type) { # Initialize @@ -149,7 +153,7 @@ read_line_type = function(line_type) { cat("Reading:", file_list[i], "\n") # Select lines out of the input file and write it to a temp file - cmd <- paste("egrep \"", line_type, "\"", file_list[i], ">", tmp_file) + cmd <- paste("grep \"", line_type, "\"", file_list[i], ">", tmp_file) system(cmd) # Try to read the input file @@ -167,19 +171,40 @@ read_line_type = function(line_type) { system(cmd) } - # Add column headers - if(line_type == "RHIST") { - h <- c(met_header, rhist_header) - } else if(line_type == "RELP") { - h <- c(met_header, relp_header) - } else if(line_type == "ECNT") { - h <- c(met_header, ecnt_header) - } else { - h <- met_header + # Check for no data + if(is.null(d)) { + return(d) } - colnames(d) <- h - return(d); + # Store version from the data + version = unlist(strsplit(as.character(d[1,1]), '\\.')) + vXY = paste(version[1], version[2], sep='.') + + # Check met_base + if(nchar(met_base) == 0) { + met_base = Sys.getenv("MET_BASE") + } + if(nchar(met_base) == 0) { + cat("ERROR: The -met_base command line option or MET_BASE environment variable must be set!\n", + "ERROR: Define it as {MET INSTALLATION DIRECTORY}/share/met.\n", sep='') + quit() + } + + # Get that header columns + header_file = paste(met_base, "/table_files/met_header_columns_", vXY, ".txt", sep='') + print(paste("Reading Header File:", header_file)) + lty_str = paste(" : ", line_type, " ", sep='') + hdr_line = grep(lty_str, readLines(header_file), value=TRUE) + hdr_line = gsub('[\\(,\\)]', '', hdr_line) # Strip parens from header line + hdr_cols = trimws(unlist(strsplit(hdr_line, ':'))[4]) + hdr_lty = unlist(strsplit(hdr_cols, ' ')) + + # Do not check that the number of header and data columns match + # since RHIST and RELP line types have variable length. + + colnames(d) <- hdr_lty + + return(d) } ######################################################################## @@ -197,7 +222,9 @@ plot_rhist = function(data, main_info, case_info) { n_rank <- max(data$N_RANK) - counts <- colSums(data[,25:(25+n_rank-1)]) + i_n_rank <- grep("N_RANK", colnames(data)) + + counts <- colSums(data[,(i_n_rank+1):(i_n_rank+n_rank)]) names(counts) <- as.character(seq(1,n_rank)) barplot(counts, main=title, xlab="Ranks"); @@ -207,7 +234,7 @@ plot_rhist = function(data, main_info, case_info) { ######################################################################## # -# Plot the Relative Performance Histogram +# Plot the Relative Performance Histogram. # ######################################################################## @@ -220,7 +247,9 @@ plot_relp = function(data, main_info, case_info) { n_ens <- max(data$N_ENS) - counts <- colSums(data[,25:(25+n_ens-1)]) + i_n_ens <- grep("N_ENS", colnames(data)) + + counts <- colSums(data[,(i_n_ens+1):(i_n_ens+n_ens)]) names(counts) <- as.character(seq(1,n_ens)) barplot(counts, main=title, xlab="Ensemble Member"); @@ -230,7 +259,7 @@ plot_relp = function(data, main_info, case_info) { ######################################################################## # -# Plot the Continuous Ensemble Statistics +# Plot the Continuous Ensemble Statistics. # ######################################################################## @@ -275,7 +304,7 @@ plot_ecnt_spread_skill = function(data, main_info, case_info) { ######################################################################## # -# Process the input data +# Process the input data. # ######################################################################## @@ -288,6 +317,13 @@ for(i in 1:length(line_types)) { data = read_line_type(line_types[i]); + # Check for no data found + if(length(data) == 0) { + cat("WARNING: No input data for line type ", + line_types[i], "!\n", sep='') + next + } + # Convert date/time columns to date/time objects data$FCST_VALID_BEG <- as.POSIXct(strptime(data$FCST_VALID_BEG, format="%Y%m%d_%H%M%S")) @@ -298,7 +334,7 @@ for(i in 1:length(line_types)) { data$OBS_VALID_END <- as.POSIXct(strptime(data$OBS_VALID_END, format="%Y%m%d_%H%M%S")) - # Construct an idex + # Construct an index data$index <- paste(data$MODEL, data$DESC, data$FCST_VAR, data$FCST_LEV, data$OBS_VAR, data$OBS_LEV, diff --git a/met/scripts/Rscripts/plot_mpr.R b/met/scripts/Rscripts/plot_mpr.R index 81d595e520..e548b188eb 100644 --- a/met/scripts/Rscripts/plot_mpr.R +++ b/met/scripts/Rscripts/plot_mpr.R @@ -21,19 +21,22 @@ ## file_list ## [-wind_rose] ## [-out name] +## [-met_base path] ## [-save] ## ## Arguments: -## "file_list" is one or more files containing MPR lines. -## "-out name" specifies an output PDF file name. -## "-save" calls save.image() before exiting R. +## "file_list" is one or more files containing MPR lines. +## "-wind_rose" enables plotting of wind vectors. +## "-out name" specifies an output PDF file name. +## "-met_base path" is MET_INSTALL_DIR/share/met for the headers. +## "-save" calls save.image() before exiting R. ## ## Details: -## Updated for MET version 6.0. +## Updated on 02/03/2021 to parse version-specific headers. ## ## Examples: ## Rscript plot_mpr.R \ -## met-6.0/out/point_stat/*_mpr.txt +## out/point_stat/*_mpr.txt ## ## Author: ## John Halley Gotway (johnhg@ucar.edu), NCAR-RAL/DTC @@ -62,19 +65,6 @@ plot_wind_rose <- function(u, v, title) { # ######################################################################## -# Header for the MPR line type (MET version 6.0) -mpr_header <- c("VERSION", "MODEL", "DESC", - "FCST_LEAD", "FCST_VALID_BEG", "FCST_VALID_END", - "OBS_LEAD", "OBS_VALID_BEG", "OBS_VALID_END", - "FCST_VAR", "FCST_LEV", - "OBS_VAR", "OBS_LEV", - "OBTYPE", "VX_MASK", - "INTERP_MTHD", "INTERP_PNTS", - "FCST_THRESH", "OBS_THRESH", "COV_THRESH", - "ALPHA", "LINE_TYPE", - "TOTAL", "INDEX", "OBS_SID", "OBS_LAT", "OBS_LON", - "OBS_LVL", "OBS_ELV", "FCST", "OBS", "CLIMO") - # Temporary input file name tmp_file <- "mpr_input.tmp" @@ -92,22 +82,25 @@ args = commandArgs(TRUE) # Check the number of arguments if(length(args) < 1) { - cat("Usage: plot_mpr.R\n") - cat(" mpr_file_list\n") - cat(" [-wind_rose]\n") - cat(" [-out name]\n") - cat(" [-save]\n") - cat(" where \"file_list\" is one or more files containing MPR lines.\n") - cat(" \"-wind_rose\" enables plotting of vector winds.\n") - cat(" \"-out name\" specifies an output PDF file name.\n") - cat(" \"-save\" calls save.image() before exiting R.\n\n") - quit() + cat("Usage: plot_mpr.R\n") + cat(" file_list\n") + cat(" [-wind_rose]\n") + cat(" [-out name]\n") + cat(" [-met_base path]\n") + cat(" [-save]\n") + cat(" where \"file_list\" is one or more files containing MPR lines.\n") + cat(" \"-wind_rose\" enables plotting of vector winds.\n") + cat(" \"-out name\" specifies an output PDF file name.\n") + cat(" \"-met_base path\" is MET_INSTALL_DIR/share/met for the headers.\n") + cat(" \"-save\" calls save.image() before exiting R.\n\n") + quit() } # Initialize -save = FALSE -wind_rose = FALSE file_list = c() +wind_rose = FALSE +met_base = '' +save = FALSE # Parse the arguments i=1 @@ -124,6 +117,12 @@ while(i <= length(args)) { out_file = args[i+1] i = i+1 + } else if(args[i] == "-met_base") { + + # Set MET_BASE variable + met_base = args[i+1] + i = i+1 + } else { # Add input file to the file list @@ -140,6 +139,12 @@ while(i <= length(args)) { # ######################################################################## +# Check for input files +if(is.null(file_list)) { + cat("ERROR: No input files specified!\n") + quit() +} + # Initialize data <- c() @@ -165,8 +170,44 @@ for(i in 1:length(file_list)) { system(cmd) } +# Check for no data +if(is.null(data)) { + cat("ERROR: No MPR data found!\n") + quit() +} + +# Store version from the data +version = unlist(strsplit(as.character(data[1,1]), '\\.')) +vXY = paste(version[1], version[2], sep='.') + +# Check met_base +if(nchar(met_base) == 0) { + met_base = Sys.getenv("MET_BASE") +} +if(nchar(met_base) == 0) { + cat("ERROR: The -met_base command line option or MET_BASE environment variable must be set!\n", + "ERROR: Define it as {MET INSTALLATION DIRECTORY}/share/met.\n", sep='') + quit() +} + +# Get the header columns +header_file = paste(met_base, "/table_files/met_header_columns_", vXY, ".txt", sep='') +print(paste("Reading Header File:", header_file)) +lty_str = paste(" : MPR ", sep='') +hdr_line = grep(lty_str, readLines(header_file), value=TRUE) +hdr_cols = trimws(unlist(strsplit(hdr_line, ':'))[4]) +hdr_lty = unlist(strsplit(hdr_cols, ' ')) + +# Check that header and data columns match +if(length(hdr_lty) != dim(data)[2]) { + cat("ERROR: The number of data (", dim(data)[2], + ") and header (", length(hdr_lty), + ") columns do not match!\n", sep='') + quit() +} + # After constructing the input data, attach column names -colnames(data) <- mpr_header +colnames(data) <- hdr_lty ######################################################################## # @@ -174,10 +215,10 @@ colnames(data) <- mpr_header # ######################################################################## -# Construct an idex +# Construct an index data$index <- paste(data$MODEL, data$FCST_VAR, data$FCST_LEV, - data$OBS_VAR, data$OBS_LEV, + data$OBS_VAR, data$OBS_LEV, data$OBTYPE, data$VX_MASK, data$INTERP_MTHD, data$INTERP_PNTS, sep='_') diff --git a/met/src/basic/vx_util/num_array.cc b/met/src/basic/vx_util/num_array.cc index 0481f4516c..bf80325736 100644 --- a/met/src/basic/vx_util/num_array.cc +++ b/met/src/basic/vx_util/num_array.cc @@ -540,7 +540,7 @@ void NumArray::sort_array() { -sort(e, Nelements); +if(!Sorted) sort(e, Nelements); Sorted = true; @@ -784,7 +784,7 @@ double var; compute_mean_variance(mn, var); -stdev = square_root(var); +stdev = (is_bad_data(var) ? bad_data_double : square_root(var)); return; diff --git a/met/src/basic/vx_util/stat_column_defs.h b/met/src/basic/vx_util/stat_column_defs.h index 33d52d7156..d5a8cf0c1a 100644 --- a/met/src/basic/vx_util/stat_column_defs.h +++ b/met/src/basic/vx_util/stat_column_defs.h @@ -260,7 +260,9 @@ static const char * ecnt_columns [] = { "TOTAL", "N_ENS", "CRPS", "CRPSS", "IGN", "ME", "RMSE", "SPREAD", "ME_OERR", - "RMSE_OERR", "SPREAD_OERR", "SPREAD_PLUS_OERR" + "RMSE_OERR", "SPREAD_OERR", "SPREAD_PLUS_OERR", + "CRPSCL", "CRPS_EMP", "CRPSCL_EMP", + "CRPSS_EMP" }; static const char * rps_columns [] = { diff --git a/met/src/libcode/vx_data2d/var_info.cc b/met/src/libcode/vx_data2d/var_info.cc index 1a4851e4e1..e72a761096 100644 --- a/met/src/libcode/vx_data2d/var_info.cc +++ b/met/src/libcode/vx_data2d/var_info.cc @@ -416,11 +416,19 @@ void VarInfo::set_magic(const ConcatString &nstr, const ConcatString &lstr) { if((unsigned int) nstr.length() != strcspn(nstr.c_str(), " \t") || (unsigned int) lstr.length() != strcspn(lstr.c_str(), " \t")) { mlog << Error << "\nVarInfo::set_magic() -> " - << "embedded whitespace found in the nstr \"" << nstr - << "\" or lstr \"" << lstr << "\".\n\n"; + << "embedded whitespace found in the name \"" << nstr + << "\" or level \"" << lstr << "\" string.\n\n"; exit(1); } + // Format as {name}/{level} or {name}{level} + if(lstr.nonempty() && lstr[0] != '(') { + MagicStr << cs_erase << nstr << "/" << lstr; + } + else { + MagicStr << cs_erase << nstr << lstr; + } + return; } diff --git a/met/src/libcode/vx_data2d_grib/var_info_grib.cc b/met/src/libcode/vx_data2d_grib/var_info_grib.cc index 1de21c8112..7594a1d1e6 100644 --- a/met/src/libcode/vx_data2d_grib/var_info_grib.cc +++ b/met/src/libcode/vx_data2d_grib/var_info_grib.cc @@ -198,18 +198,6 @@ void VarInfoGrib::set_tri(int v) { /////////////////////////////////////////////////////////////////////////////// -void VarInfoGrib::set_magic(const ConcatString &nstr, const ConcatString &lstr) { - - // Validate the magic_string - VarInfo::set_magic(nstr, lstr); - - // Store the magic string - MagicStr << cs_erase << nstr << "/" << lstr; - -} - -/////////////////////////////////////////////////////////////////////////////// - void VarInfoGrib::add_grib_code (Dictionary &dict) { ConcatString field_name = dict.lookup_string(conf_key_name, false); diff --git a/met/src/libcode/vx_data2d_grib/var_info_grib.h b/met/src/libcode/vx_data2d_grib/var_info_grib.h index d8267737c2..1fd2e8eca2 100644 --- a/met/src/libcode/vx_data2d_grib/var_info_grib.h +++ b/met/src/libcode/vx_data2d_grib/var_info_grib.h @@ -89,7 +89,6 @@ class VarInfoGrib : public VarInfo // set stuff // - void set_magic(const ConcatString &, const ConcatString &); void set_dict(Dictionary &); void add_grib_code(Dictionary &); diff --git a/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc b/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc index 99e7d7291e..b35efcd8b4 100644 --- a/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc +++ b/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc @@ -257,19 +257,6 @@ void VarInfoGrib2::set_ipdtmpl_val(const IntArray &v) { return; } - -/////////////////////////////////////////////////////////////////////////////// - -void VarInfoGrib2::set_magic(const ConcatString &nstr, const ConcatString &lstr) { - - // Validate the magic_string - VarInfo::set_magic(nstr, lstr); - - // Store the magic string - MagicStr << cs_erase << nstr << "/" << lstr; - -} - /////////////////////////////////////////////////////////////////////////////// void VarInfoGrib2::set_dict(Dictionary & dict) { diff --git a/met/src/libcode/vx_data2d_grib2/var_info_grib2.h b/met/src/libcode/vx_data2d_grib2/var_info_grib2.h index 17ee3c461b..27ba9c396b 100644 --- a/met/src/libcode/vx_data2d_grib2/var_info_grib2.h +++ b/met/src/libcode/vx_data2d_grib2/var_info_grib2.h @@ -97,7 +97,6 @@ class VarInfoGrib2 : public VarInfo // set stuff // - void set_magic(const ConcatString &, const ConcatString &); void set_dict(Dictionary &); void set_record(int); diff --git a/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc b/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc index 07c26cb2ae..49f14705ec 100644 --- a/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc +++ b/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc @@ -141,11 +141,8 @@ void VarInfoNcMet::set_magic(const ConcatString &nstr, const ConcatString &lstr) ConcatString tmp_str; char *ptr = (char *) 0, *ptr2 = (char *) 0, *ptr3 = (char *) 0, *save_ptr = (char *) 0; - // Validate the magic string - VarInfo::set_magic(nstr, lstr); - // Store the magic string - MagicStr << cs_erase << nstr << lstr; + VarInfo::set_magic(nstr, lstr); // Set the requested name and default output name set_req_name(nstr.c_str()); diff --git a/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc b/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc index 61d1e58613..02da4ac8ac 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc +++ b/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc @@ -141,17 +141,14 @@ void VarInfoNcPinterp::set_magic(const ConcatString &nstr, const ConcatString &l ConcatString tmp_str; char *ptr = (char *) 0, *ptr2 = (char *) 0, *ptr3 = (char *) 0, *save_ptr = (char *) 0; - // Validate the magic string - VarInfo::set_magic(nstr, lstr); - // Store the magic string - MagicStr << cs_erase << nstr << lstr; + VarInfo::set_magic(nstr, lstr); // Set the requested name and default output name set_req_name(nstr.c_str()); set_name(nstr); - // If there's no level specification, assume (0,*, *) + // If there's no level specification, assume (0,*,*) if(strchr(lstr.c_str(), '(') == NULL) { Level.set_req_name("0,*,*"); Level.set_name("0,*,*"); diff --git a/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc b/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc index aafc8a5aa7..24ed320c3c 100644 --- a/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc +++ b/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc @@ -143,11 +143,8 @@ void VarInfoNcCF::set_magic(const ConcatString &nstr, const ConcatString &lstr) char *save_ptr = 0; const char *method_name = "VarInfoNcCF::set_magic() -> "; - // Validate the magic string - VarInfo::set_magic(nstr, lstr); - // Store the magic string - MagicStr << cs_erase << nstr << lstr; + VarInfo::set_magic(nstr, lstr); // Set the requested name and default output name set_req_name(nstr.c_str()); diff --git a/met/src/libcode/vx_data2d_python/var_info_python.cc b/met/src/libcode/vx_data2d_python/var_info_python.cc index 006f4d7ba7..81fb4e8045 100644 --- a/met/src/libcode/vx_data2d_python/var_info_python.cc +++ b/met/src/libcode/vx_data2d_python/var_info_python.cc @@ -147,21 +147,6 @@ void VarInfoPython::set_file_type(const GrdFileType t) { /////////////////////////////////////////////////////////////////////////////// -void VarInfoPython::set_magic(const ConcatString &nstr, const ConcatString &lstr) { - - // Validate the magic_string - VarInfo::set_magic(nstr, lstr); - - // Store the magic string - MagicStr << cs_erase << nstr << "/" << lstr; - - return; -} - - -/////////////////////////////////////////////////////////////////////////////// - - void VarInfoPython::set_dict(Dictionary & dict) { VarInfo::set_dict(dict); diff --git a/met/src/libcode/vx_data2d_python/var_info_python.h b/met/src/libcode/vx_data2d_python/var_info_python.h index 78348445ba..9df494c98d 100644 --- a/met/src/libcode/vx_data2d_python/var_info_python.h +++ b/met/src/libcode/vx_data2d_python/var_info_python.h @@ -56,7 +56,6 @@ class VarInfoPython : public VarInfo // void set_file_type(const GrdFileType); - void set_magic(const ConcatString &, const ConcatString &); void set_dict(Dictionary &); // diff --git a/met/src/libcode/vx_stat_out/stat_columns.cc b/met/src/libcode/vx_stat_out/stat_columns.cc index 09905b4f08..570977fb17 100644 --- a/met/src/libcode/vx_stat_out/stat_columns.cc +++ b/met/src/libcode/vx_stat_out/stat_columns.cc @@ -3659,11 +3659,12 @@ void write_ecnt_cols(const ECNTInfo &ecnt_info, // // Ensemble Continuous Statistics // Dump out the ECNT line: - // TOTAL, N_ENS, - // CRPS, CRPSS, IGN, - // ME, RMSE, SPREAD, - // ME_OERR, RMSE_OERR, SPREAD_OERR, - // SPREAD_PLUS_OERR + // TOTAL, N_ENS, CRPS, + // CRPSS, IGN, ME, + // RMSE, SPREAD, ME_OERR, + // RMSE_OERR, SPREAD_OERR, SPREAD_PLUS_OERR, + // CRPSCL, CRPS_EMP, CRPSCL_EMP, + // CRPSS_EMP // at.set_entry(r, c+0, // Total Number of Pairs ecnt_info.n_pair); @@ -3672,10 +3673,10 @@ void write_ecnt_cols(const ECNTInfo &ecnt_info, ecnt_info.n_ens); at.set_entry(r, c+2, // Continuous Ranked Probability Score - ecnt_info.crps); + ecnt_info.crps_gaus); at.set_entry(r, c+3, // Continuous Ranked Probability Skill Score - ecnt_info.crpss); + ecnt_info.crpss_gaus); at.set_entry(r, c+4, // Ignorance Score ecnt_info.ign); @@ -3701,6 +3702,18 @@ void write_ecnt_cols(const ECNTInfo &ecnt_info, at.set_entry(r, c+11, // Mean of unperturbed spread plus observation error ecnt_info.spread_plus_oerr); + at.set_entry(r, c+12, // Gaussian climatological CRPS + ecnt_info.crpscl_gaus); + + at.set_entry(r, c+13, // Empirical ensemble CRPS + ecnt_info.crps_emp); + + at.set_entry(r, c+14, // Empirical climatological CRPS + ecnt_info.crpscl_emp); + + at.set_entry(r, c+15, // Empirical CRPSS + ecnt_info.crpss_emp); + return; } diff --git a/met/src/libcode/vx_statistics/compute_stats.cc b/met/src/libcode/vx_statistics/compute_stats.cc index 674c3c59d3..7e6e74f66f 100644 --- a/met/src/libcode/vx_statistics/compute_stats.cc +++ b/met/src/libcode/vx_statistics/compute_stats.cc @@ -1306,12 +1306,23 @@ void compute_ecnt_mean(const ECNTInfo *ecnt_info, int n, ecnt_mean.n_pair = na.sum(); // Compute unweighted mean for each statistic + for(i=0,na.erase(); i= all ensemble members + if(is_eq(obs_cdf, 0.0)) integral += (obs - fcst); + + return(integral); +} + +//////////////////////////////////////////////////////////////////////// +// +// Compute the Gaussian continuous ranked probability score (CRPS), +// the ignorance score (IGN), and probability integral transform (PIT) +// +//////////////////////////////////////////////////////////////////////// + +void compute_crps_gaus_ign_pit(double obs, const NumArray &ens_na, + double &crps, double &ign, double &pit) { double m, s, z; // Mean and standard deviation of the ensemble values @@ -1755,7 +1820,7 @@ void compute_crps_ign_pit(double obs, const NumArray &ens_na, z = (obs - m)/s; - // Compute CRPS + // Compute Gaussian CRPS crps = s*(z*(2.0*znorm(z) - 1) + 2.0*dnorm(z) - 1.0/sqrt(pi)); // Compute IGN @@ -1763,6 +1828,7 @@ void compute_crps_ign_pit(double obs, const NumArray &ens_na, // Compute PIT pit = normal_cdf(obs, m, s); + } return; @@ -1805,9 +1871,10 @@ PairDataEnsemble subset_climo_cdf_bin(const PairDataEnsemble &pd, // required for ensemble output line types. // // Include in subset: - // wgt_na, o_na, cmn_na, csd_na, cdf_na, v_na, r_na, crps_na, - // ign_na, pit_na, var_na, var_oerr_na, - // var_plus_oerr_na, mn_na, mn_oerr_na, e_na + // wgt_na, o_na, cmn_na, csd_na, cdf_na, v_na, r_na, + // crps_emp_na, crps_gaus_na, ign_na, pit_na, + // var_na, var_oerr_na, var_plus_oerr_na, + // mn_na, mn_oerr_na, e_na // // Exclude from subset: // sid_sa, lat_na, lon_na, x_na, y_na, vld_ta, lvl_ta, elv_ta, @@ -1820,7 +1887,8 @@ PairDataEnsemble subset_climo_cdf_bin(const PairDataEnsemble &pd, out_pd.cdf_na.add(pd.cdf_na[i]); out_pd.v_na.add(pd.v_na[i]); out_pd.r_na.add(pd.r_na[i]); - out_pd.crps_na.add(pd.crps_na[i]); + out_pd.crps_emp_na.add(pd.crps_emp_na[i]); + out_pd.crps_gaus_na.add(pd.crps_gaus_na[i]); out_pd.ign_na.add(pd.ign_na[i]); out_pd.pit_na.add(pd.pit_na[i]); out_pd.skip_ba.add(false); diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.h b/met/src/libcode/vx_statistics/pair_data_ensemble.h index 7fa90737bf..49a848dd95 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.h @@ -78,11 +78,14 @@ class PairDataEnsemble : public PairBase { NumArray *e_na; // Ensemble values [n_ens][n_obs] NumArray v_na; // Number of valid ensemble values [n_obs] NumArray r_na; // Observation ranks [n_obs] - NumArray crps_na; // Continuous Ranked Probability Score [n_obs] + + NumArray crps_emp_na; // Empirical Continuous Ranked Probability Score [n_obs] + NumArray crps_gaus_na; // Gaussian CRPS [n_obs] + NumArray ign_na; // Ignorance Score [n_obs] NumArray pit_na; // Probability Integral Transform [n_obs] - int n_ens; // Number of ensemble members + int n_ens; // Number of ensemble members int n_pair; // Number of valid pairs, n_obs - sum(skip_ba) bool skip_const; // Skip cases where the observation and // all ensemble members are constant @@ -107,7 +110,11 @@ class PairDataEnsemble : public PairBase { double ssvar_bin_size; // Variance bin size for spread/skill SSVARInfo *ssvar_bins; // Ensemble spread/skill bin information [n_ssvar_bin] - double crpss; // Continuous ranked probability skill score + double crpscl_emp; // Empirical climatological CRPS score + double crpss_emp; // Empirical CRPS skill score + double crpscl_gaus; // Guassian climatological CRPS score + double crpss_gaus; // Guassian CRPS skill score + double me; // ME for ensemble mean double rmse; // RMSE for ensemble mean double me_oerr; // ME for mean of perturbed members @@ -290,8 +297,10 @@ class VxPairDataEnsemble { // //////////////////////////////////////////////////////////////////////// -extern void compute_crps_ign_pit(double, const NumArray &, double &, - double &, double &); +extern double compute_crps_emp(double, const NumArray &); + +extern void compute_crps_gaus_ign_pit(double, const NumArray &, + double &, double &, double &); // Subset pairs for a specific climatology CDF bin extern PairDataEnsemble subset_climo_cdf_bin(const PairDataEnsemble &, diff --git a/met/src/tools/core/stat_analysis/aggr_stat_line.cc b/met/src/tools/core/stat_analysis/aggr_stat_line.cc index 686a7cd87a..034afdb0cb 100644 --- a/met/src/tools/core/stat_analysis/aggr_stat_line.cc +++ b/met/src/tools/core/stat_analysis/aggr_stat_line.cc @@ -2514,7 +2514,7 @@ void aggr_ecnt_lines(LineDataFile &f, STATAnalysisJob &job, AggrENSInfo aggr; ECNTData cur; ConcatString key; - double crps_fcst, crps_climo, v; + double crps_emp, crpscl_emp, crps_gaus, crpscl_gaus, v; map::iterator it; // @@ -2553,7 +2553,8 @@ void aggr_ecnt_lines(LineDataFile &f, STATAnalysisJob &job, // if(m.count(key) == 0) { aggr.ens_pd.clear(); - aggr.crps_climo_na.clear(); + aggr.crpscl_emp_na.clear(); + aggr.crpscl_gaus_na.clear(); aggr.hdr.clear(); m[key] = aggr; } @@ -2571,7 +2572,10 @@ void aggr_ecnt_lines(LineDataFile &f, STATAnalysisJob &job, // // Store the current statistics and weight (TOTAL column) // - m[key].ens_pd.crps_na.add(cur.crps); + m[key].ens_pd.crps_emp_na.add(cur.crps_emp); + m[key].crpscl_emp_na.add(cur.crpscl_emp); + m[key].ens_pd.crps_gaus_na.add(cur.crps_gaus); + m[key].crpscl_gaus_na.add(cur.crpscl_gaus); m[key].ens_pd.ign_na.add(cur.ign); m[key].ens_pd.var_na.add(square(cur.spread)); m[key].ens_pd.var_oerr_na.add(square(cur.spread_oerr)); @@ -2590,18 +2594,6 @@ void aggr_ecnt_lines(LineDataFile &f, STATAnalysisJob &job, bad_data_double : cur.rmse_oerr * cur.rmse_oerr)); - // - // Compute and store climatological CRPS - // - if(!is_bad_data(cur.crps) && !is_bad_data(cur.crpss) && - !is_eq(cur.crpss, 1.0)) { - crps_climo = cur.crps / (1.0 - cur.crpss); - m[key].crps_climo_na.add(crps_climo); - } - else { - m[key].crps_climo_na.add(bad_data_double); - } - // // Keep track of the unique header column entries // @@ -2627,17 +2619,20 @@ void aggr_ecnt_lines(LineDataFile &f, STATAnalysisJob &job, v = it->second.mse_oerr_na.wmean(it->second.ens_pd.wgt_na); it->second.ens_pd.rmse_oerr = (is_bad_data(v) ? bad_data_double : sqrt(v)); - crps_fcst = it->second.ens_pd.crps_na.wmean(it->second.ens_pd.wgt_na); - crps_climo = it->second.crps_climo_na.wmean(it->second.ens_pd.wgt_na); + crps_emp = it->second.ens_pd.crps_emp_na.wmean(it->second.ens_pd.wgt_na); + crpscl_emp = it->second.crpscl_emp_na.wmean(it->second.ens_pd.wgt_na); + crps_gaus = it->second.ens_pd.crps_gaus_na.wmean(it->second.ens_pd.wgt_na); + crpscl_gaus = it->second.crpscl_gaus_na.wmean(it->second.ens_pd.wgt_na); - // Compute aggregated CRPSS - if(!is_bad_data(crps_fcst) && !is_bad_data(crps_climo) && - !is_eq(crps_climo, 0.0)) { - it->second.ens_pd.crpss = (crps_climo - crps_fcst)/crps_climo; - } - else { - it->second.ens_pd.crpss = bad_data_double; - } + // Compute aggregated empirical CRPSS + it->second.ens_pd.crpss_emp = + (is_bad_data(crps_emp) || is_bad_data(crpscl_emp) && is_eq(crpscl_emp, 0.0) ? + bad_data_double : (crpscl_emp - crps_emp)/crpscl_emp); + + // Compute aggregated Gaussian CRPSS + it->second.ens_pd.crpss_gaus = + (is_bad_data(crps_gaus) || is_bad_data(crpscl_gaus) && is_eq(crpscl_gaus, 0.0) ? + bad_data_double : (crpscl_gaus - crps_gaus)/crpscl_gaus); } // end for it @@ -3008,7 +3003,7 @@ void aggr_orank_lines(LineDataFile &f, STATAnalysisJob &job, ORANKData cur; ConcatString key; int i, n_valid, n_bin; - double esum, esumsq, crps, ign, pit; + double esum, esumsq, crps_gaus, ign, pit; map::iterator it; // @@ -3102,9 +3097,10 @@ void aggr_orank_lines(LineDataFile &f, STATAnalysisJob &job, m[key].ens_pd.esumsq_na.add(esumsq); m[key].ens_pd.v_na.add(n_valid); - // Compute CRPS, IGN, and PIT for the current point - compute_crps_ign_pit(cur.obs, cur.ens_na, crps, ign, pit); - m[key].ens_pd.crps_na.add(crps); + // Compute Empirical and Gaussian CRPS, IGN, and PIT for the current point + m[key].ens_pd.crps_emp_na.add(compute_crps_emp(cur.obs, cur.ens_na)); + compute_crps_gaus_ign_pit(cur.obs, cur.ens_na, crps_gaus, ign, pit); + m[key].ens_pd.crps_gaus_na.add(crps_gaus); m[key].ens_pd.ign_na.add(ign); m[key].ens_pd.pit_na.add(pit); diff --git a/met/src/tools/core/stat_analysis/aggr_stat_line.h b/met/src/tools/core/stat_analysis/aggr_stat_line.h index 05f404cf6e..071645ade9 100644 --- a/met/src/tools/core/stat_analysis/aggr_stat_line.h +++ b/met/src/tools/core/stat_analysis/aggr_stat_line.h @@ -151,7 +151,7 @@ struct AggrISCInfo { struct AggrENSInfo { StatHdrInfo hdr; PairDataEnsemble ens_pd; - NumArray crps_climo_na; + NumArray crpscl_emp_na, crpscl_gaus_na; NumArray me_na, mse_na, me_oerr_na, mse_oerr_na; }; diff --git a/met/src/tools/core/stat_analysis/parse_stat_line.cc b/met/src/tools/core/stat_analysis/parse_stat_line.cc index e2d10201a0..365be05c90 100644 --- a/met/src/tools/core/stat_analysis/parse_stat_line.cc +++ b/met/src/tools/core/stat_analysis/parse_stat_line.cc @@ -347,10 +347,15 @@ void parse_ecnt_line(STATLine &l, ECNTData &e_data) { e_data.total = atoi(l.get_item("TOTAL")); e_data.n_ens = atof(l.get_item("N_ENS")); - e_data.crps = atof(l.get_item("CRPS")); - e_data.crpss = atof(l.get_item("CRPSS")); - e_data.ign = atof(l.get_item("IGN")); + e_data.crps_emp = atof(l.get_item("CRPS_EMP")); + e_data.crpscl_emp = atof(l.get_item("CRPSCL_EMP")); + e_data.crpss_emp = atof(l.get_item("CRPSS_EMP")); + + e_data.crps_gaus = atof(l.get_item("CRPS")); + e_data.crpscl_gaus = atof(l.get_item("CRPSCL")); + e_data.crpss_gaus = atof(l.get_item("CRPSS")); + e_data.ign = atof(l.get_item("IGN")); e_data.me = atof(l.get_item("ME")); e_data.rmse = atof(l.get_item("RMSE")); e_data.spread = atof(l.get_item("SPREAD")); diff --git a/met/src/tools/core/stat_analysis/parse_stat_line.h b/met/src/tools/core/stat_analysis/parse_stat_line.h index d3c6cbdf91..4f6dafa43b 100644 --- a/met/src/tools/core/stat_analysis/parse_stat_line.h +++ b/met/src/tools/core/stat_analysis/parse_stat_line.h @@ -62,8 +62,9 @@ struct MPRData { // Ensemble continuous statistics (ECNT) data structure struct ECNTData { int total, n_ens; - double crps, crpss, ign; - double me, rmse, spread; + double crps_emp, crpscl_emp, crpss_emp; + double crps_gaus, crpscl_gaus, crpss_gaus; + double ign, me, rmse, spread; double me_oerr, rmse_oerr, spread_oerr; double spread_plus_oerr; }; diff --git a/met/src/tools/other/point2grid/point2grid.cc b/met/src/tools/other/point2grid/point2grid.cc index 70f1c7b117..f5a5f57e3b 100644 --- a/met/src/tools/other/point2grid/point2grid.cc +++ b/met/src/tools/other/point2grid/point2grid.cc @@ -405,10 +405,12 @@ void process_data_file() { // Open the output file open_nc(to_grid, run_cs); - if (goes_data) + if (goes_data) { process_goes_file(nc_in, config, vinfo, fr_grid, to_grid); - else if (TYPE_OBS == obs_type) + } + else if (TYPE_OBS == obs_type) { process_point_file(nc_in, config, vinfo, fr_grid, to_grid); + } else if (TYPE_NCCF == obs_type) { process_point_nccf_file(nc_in, config, vinfo, fr_mtddf, to_grid); unsetenv(nc_att_met_point_nccf); @@ -657,6 +659,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, // Check and read obs_vid and obs_var if exists bool success_to_read = true; + bool empty_input = (nhdr == 0 && nobs == 0); NcVar obs_vid_var = get_var(nc_in, nc_var_obs_vid); if (IS_VALID_NC(obs_vid_var)) { if (success_to_read) success_to_read = get_nc_data_int_array(nc_in, nc_var_obs_vid, obs_ids); @@ -671,30 +674,32 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, } } - if (success_to_read) - success_to_read = get_nc_data_int_array(nc_in, nc_var_obs_hid, obs_hids); - if (success_to_read) - success_to_read = get_nc_data_int_array(nc_in, nc_var_hdr_vld, hdr_vld_ids); - if (success_to_read) - success_to_read = get_nc_data_int_array(nc_in, nc_var_hdr_typ, hdr_typ_ids); - if (success_to_read) - success_to_read = get_nc_data_int_array(nc_in, nc_var_obs_qty, obs_qty_ids); - if (success_to_read) - success_to_read = get_nc_data_float_array(nc_in, nc_var_hdr_lat, hdr_lats); - if (success_to_read) - success_to_read = get_nc_data_float_array(nc_in, nc_var_hdr_lon, hdr_lons); - if (success_to_read) - success_to_read = get_nc_data_float_array(nc_in, nc_var_obs_lvl, obs_lvls); - if (success_to_read) - success_to_read = get_nc_data_float_array(nc_in, nc_var_obs_hgt, obs_hgts); - if (success_to_read) - success_to_read = get_nc_data_float_array(nc_in, nc_var_obs_val, obs_vals); - if (success_to_read) - success_to_read = get_nc_data_string_array( - nc_in, nc_var_hdr_vld_tbl, &hdr_valid_times); - if (success_to_read) - success_to_read = get_nc_data_string_array( - nc_in, nc_var_obs_qty_tbl, &qc_tables); + if (!empty_input) { + if (success_to_read) + success_to_read = get_nc_data_int_array(nc_in, nc_var_obs_hid, obs_hids); + if (success_to_read) + success_to_read = get_nc_data_int_array(nc_in, nc_var_hdr_vld, hdr_vld_ids); + if (success_to_read) + success_to_read = get_nc_data_int_array(nc_in, nc_var_hdr_typ, hdr_typ_ids); + if (success_to_read) + success_to_read = get_nc_data_int_array(nc_in, nc_var_obs_qty, obs_qty_ids); + if (success_to_read) + success_to_read = get_nc_data_float_array(nc_in, nc_var_hdr_lat, hdr_lats); + if (success_to_read) + success_to_read = get_nc_data_float_array(nc_in, nc_var_hdr_lon, hdr_lons); + if (success_to_read) + success_to_read = get_nc_data_float_array(nc_in, nc_var_obs_lvl, obs_lvls); + if (success_to_read) + success_to_read = get_nc_data_float_array(nc_in, nc_var_obs_hgt, obs_hgts); + if (success_to_read) + success_to_read = get_nc_data_float_array(nc_in, nc_var_obs_val, obs_vals); + if (success_to_read) + success_to_read = get_nc_data_string_array( + nc_in, nc_var_hdr_vld_tbl, &hdr_valid_times); + if (success_to_read) + success_to_read = get_nc_data_string_array( + nc_in, nc_var_obs_qty_tbl, &qc_tables); + } if (success_to_read) { bool has_qc_flags = (qc_flags.n() > 0); IntArray qc_idx_array = prepare_qc_array(qc_flags, qc_tables); @@ -723,7 +728,9 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, obs_count_zero_to = obs_count_non_zero_to = 0; obs_count_zero_from = obs_count_non_zero_from = 0; for(int i=0; iclear(); @@ -743,7 +750,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, else { if (use_var_id) { if (!var_names.has(vname, var_idx_or_gc)) { - exit_by_field_name_error = true;; + exit_by_field_name_error = true; error_msg << "The variable \"" << vname << "\" is not available.\n"; } } @@ -758,7 +765,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, sprintf(grib_code, "%d", var_idx_or_gc); } else { - exit_by_field_name_error = true;; + exit_by_field_name_error = true; error_msg << "Invalid GRIB code [" << vname << "]\n"; } } @@ -771,7 +778,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, } } if (not_found_grib_code) { - exit_by_field_name_error = true;; + exit_by_field_name_error = true; error_msg << "No data for the GRIB code [" << vname << "]\n"; } } @@ -797,11 +804,17 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, } } } - mlog << Error << "\n" << method_name - << error_msg - << "Try setting the \"name\" in the \"-field\" command line option to one of the available names:\n" - << "\t" << log_msg << "\n\n"; - exit(1); + if (empty_input) { + mlog << Warning << "\n" << method_name + << error_msg << "\tBut ignored because of empty input\n\n"; + } + else { + mlog << Error << "\n" << method_name + << error_msg + << "Try setting the \"name\" in the \"-field\" command line option to one of the available names:\n" + << "\t" << log_msg << "\n\n"; + exit(1); + } } // Check the time range. Apply the time window @@ -877,7 +890,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, continue; } - //Filter by QC flag + // Filter by QC flag if (has_qc_flags && !qc_idx_array.has(obs_qty_ids[idx])) { filtered_by_qc++; continue; @@ -1923,7 +1936,7 @@ static bool get_grid_mapping(Grid fr_grid, Grid to_grid, IntArray *cellMapping, int to_lat_count = to_grid.ny(); int to_lon_count = to_grid.nx(); - int from_lat_count = fr_grid.ny();; + int from_lat_count = fr_grid.ny(); int from_lon_count = fr_grid.nx(); // Override the from nx & ny from NetCDF if exists @@ -2026,7 +2039,7 @@ void get_grid_mapping(Grid fr_grid, Grid to_grid, IntArray *cellMapping, clock_t start_clock = clock(); int to_lat_count = to_grid.ny(); int to_lon_count = to_grid.nx(); - int from_lat_count = fr_grid.ny();; + int from_lat_count = fr_grid.ny(); int from_lon_count = fr_grid.nx(); bool has_coord_input = false; diff --git a/met/src/tools/other/point2grid/point2grid_conf_info.cc b/met/src/tools/other/point2grid/point2grid_conf_info.cc index 2dd1bc1245..73c1f3a78b 100644 --- a/met/src/tools/other/point2grid/point2grid_conf_info.cc +++ b/met/src/tools/other/point2grid/point2grid_conf_info.cc @@ -50,7 +50,7 @@ void PointToGridConfInfo::clear() { quality_mark_thresh = bad_data_int; version.clear(); valid_time = 0; - //def_var_name_map.clear(); + def_var_name_map.clear(); var_name_map.clear(); return; @@ -126,7 +126,7 @@ void PointToGridConfInfo::process_config() { ConcatString PointToGridConfInfo::get_var_id(const ConcatString var_name) { ConcatString var_id; - + map::iterator ptr; for (ptr=var_name_map.begin(); ptr != var_name_map.end(); ptr++) { if( ptr->second == var_name ) { @@ -134,14 +134,16 @@ ConcatString PointToGridConfInfo::get_var_id(const ConcatString var_name) { break; } } + if( var_id.empty() ) { - for (ptr=def_var_name_map.begin(); ptr != var_name_map.end(); ptr++) { + for (ptr=def_var_name_map.begin(); ptr != def_var_name_map.end(); ptr++) { if( ptr->second == var_name ) { var_id = ptr->first; break; } } } + return var_id; } diff --git a/test/hdr/met_10_0.hdr b/test/hdr/met_10_0.hdr index 1c3004e680..8355e557a3 100644 --- a/test/hdr/met_10_0.hdr +++ b/test/hdr/met_10_0.hdr @@ -17,7 +17,7 @@ PJC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_L PRC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_THRESH _VAR_ PSTD : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_THRESH BASER BASER_NCL BASER_NCU RELIABILITY RESOLUTION UNCERTAINTY ROC_AUC BRIER BRIER_NCL BRIER_NCU BRIERCL BRIERCL_NCL BRIERCL_NCU BSS BSS_SMPL _VAR_ ECLV : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASE N_PTS _VAR_ -ECNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_ENS CRPS CRPSS IGN ME RMSE SPREAD ME_OERR RMSE_OERR SPREAD_OERR SPREAD_PLUS_OERR +ECNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_ENS CRPS CRPSS IGN ME RMSE SPREAD ME_OERR RMSE_OERR SPREAD_OERR SPREAD_PLUS_OERR CRPSCL CRPS_EMP CRPSCL_EMP CRPSS_EMP RPS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_PROB RPS_REL RPS_RES RPS_UNC RPS RPSS RPSS_SMPL RPS_COMP RHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL CRPS IGN N_RANK CRPSS SPREAD _VAR_ PHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BIN_SIZE N_BIN _VAR_