diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index a39424d289..1c131a9580 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -69,6 +69,7 @@ The usage statement for the Ensemble Stat tool is shown below: [-grid_obs file] [-point_obs file] [-ens_mean file] + [-ctrl file] [-obs_valid_beg time] [-obs_valid_end time] [-outdir path] @@ -92,23 +93,23 @@ Optional arguments for ensemble_stat 4. To produce ensemble statistics using gridded observations, use the **-grid_obs file** option to specify a gridded observation file. This option may be used multiple times if your observations are in several files. +5. To produce ensemble statistics using point observations, use the **-point_obs file** option to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. -5. To produce ensemble statistics using point observations, use the **-point_obs file** to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. +6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** option specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** option from earlier versions of MET. +7. The **-ctrl file** option specifies an ensemble control member data file. The control member is included in the computation of the ensemble mean but excluded from the spread. -6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** from earlier versions of MET. +8. To filter point observations by time, use **-obs_valid_beg time** in YYYYMMDD[_HH[MMSS]] format to set the beginning of the matching observation time window. -7. To filter point observations by time, use **-obs_valid_beg time** in YYYYMMDD[_HH[MMSS]] format to set the beginning of the matching observation time window. +9. As above, use **-obs_valid_end time** in YYYYMMDD[_HH[MMSS]] format to set the end of the matching observation time window. -8. As above, use **-obs_valid_end time** in YYYYMMDD[_HH[MMSS]] format to set the end of the matching observation time window. +10. Specify the **-outdir path** option to override the default output directory (./). -9. Specify the **-outdir path** option to override the default output directory (./). +11. The **-log** file outputs log messages to the specified file. -10. The **-log** file outputs log messages to the specified file. +12. The **-v level** option indicates the desired level of verbosity. The value of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity will increase the amount of logging. -11. The **-v level** option indicates the desired level of verbosity. The value of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity will increase the amount of logging. - -12. The **-compress level** option indicates the desired level of compression (deflate level) for NetCDF variables. The valid level is between 0 and 9. The value of "level" will override the default setting of 0 from the configuration file or the environment variable MET_NC_COMPRESS. Setting the compression level to 0 will make no compression for the NetCDF output. Lower number is for fast compression and higher number is for better compression. +13. The **-compress level** option indicates the desired level of compression (deflate level) for NetCDF variables. The valid level is between 0 and 9. The value of "level" will override the default setting of 0 from the configuration file or the environment variable MET_NC_COMPRESS. Setting the compression level to 0 will make no compression for the NetCDF output. Lower number is for fast compression and higher number is for better compression. An example of the ensemble_stat calling sequence is shown below: diff --git a/met/docs/Users_Guide/reformat_grid.rst b/met/docs/Users_Guide/reformat_grid.rst index 191ef4e1a4..3f67a377a7 100644 --- a/met/docs/Users_Guide/reformat_grid.rst +++ b/met/docs/Users_Guide/reformat_grid.rst @@ -74,7 +74,7 @@ Required arguments for the pcp_combine Optional arguments for pcp_combine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -3. The **-field string** option defines the data to be extracted from the input files. Use this option when processing fields other than **APCP** or non-GRIB files. This option may be used multiple times and output will be created for each. +3. The **-field string** option defines the data to be extracted from the input files. Use this option when processing fields other than **APCP** or non-GRIB files. It can be used multiple times and output will be created for each. In general, the field string should include the **name** and **level** of the requested data and be enclosed in single quotes. It is processed as an inline configuration file and may also include data filtering, censoring, and conversion options. For example, use **-field ‘name=”ACPCP”; level=”A6”; convert(x)=x/25.4;’** to read 6-hourly accumulated convective precipitation from a GRIB file and convert from millimeters to inches. 4. The **-name list** option is a comma-separated list of output variable names which override the default choices. If specified, the number of names must match the number of variables to be written to the output file. diff --git a/met/src/basic/vx_util/num_array.cc b/met/src/basic/vx_util/num_array.cc index b681b901ee..446bf29034 100644 --- a/met/src/basic/vx_util/num_array.cc +++ b/met/src/basic/vx_util/num_array.cc @@ -1157,6 +1157,59 @@ double NumArray::wmean_fisher(const NumArray &wgt) const } + +//////////////////////////////////////////////////////////////////////// + + +double NumArray::variance(int skip_index) const + +{ + + if(n() == 0) return ( bad_data_double ); + + int j, count; + double s, s_sq, var; + + s = s_sq = 0.0; + count = 0; + + for(j=0; j 1) { + var = (s_sq - s*s/(double) count)/((double) (count - 1)); + if(is_eq(var, 0.0)) var = 0.0; + } + else { + var = bad_data_double; + } + + return(var); + +} + + +//////////////////////////////////////////////////////////////////////// + + +double NumArray::stdev(int skip_index) const + +{ + + double v = variance(skip_index); + + if ( !is_bad_data(v) ) v = sqrt(v); + + return(v); + +} + + //////////////////////////////////////////////////////////////////////// // diff --git a/met/src/basic/vx_util/num_array.h b/met/src/basic/vx_util/num_array.h index 207b512acd..623f7e39c8 100644 --- a/met/src/basic/vx_util/num_array.h +++ b/met/src/basic/vx_util/num_array.h @@ -21,6 +21,7 @@ #include #include "concat_string.h" +#include "is_bad_data.h" //////////////////////////////////////////////////////////////////////// @@ -107,6 +108,9 @@ class NumArray { double mean_sqrt() const; double mean_fisher() const; + double variance(int skip_index = bad_data_int) const; + double stdev(int skip_index = bad_data_int) const; + double wmean(const NumArray &) const; double wmean_sqrt(const NumArray &) const; double wmean_fisher(const NumArray &) const; diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index 5782cf6a0d..4811f66147 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -108,6 +108,7 @@ void PairDataEnsemble::clear() { n_ens = 0; n_pair = 0; + ctrl_index = bad_data_int; skip_const = false; skip_ba.clear(); @@ -121,6 +122,7 @@ void PairDataEnsemble::clear() { esum_na.clear(); esumsq_na.clear(); + esumn_na.clear(); mn_na.clear(); mn_oerr_na.clear(); @@ -170,6 +172,7 @@ void PairDataEnsemble::extend(int n) { var_plus_oerr_na.extend (n); esum_na.extend (n); esumsq_na.extend (n); + esumn_na.extend (n); mn_na.extend (n); mn_oerr_na.extend (n); @@ -222,6 +225,7 @@ void PairDataEnsemble::assign(const PairDataEnsemble &pd) { ign_na = pd.ign_na; pit_na = pd.pit_na; n_pair = pd.n_pair; + ctrl_index = pd.ctrl_index; skip_const = pd.skip_const; skip_ba = pd.skip_ba; @@ -231,6 +235,7 @@ void PairDataEnsemble::assign(const PairDataEnsemble &pd) { esum_na = pd.esum_na; esumsq_na = pd.esumsq_na; + esumn_na = pd.esumn_na; mn_na = pd.mn_na; mn_oerr_na = pd.mn_oerr_na; @@ -290,12 +295,14 @@ void PairDataEnsemble::add_ens_var_sums(int i_obs, double v) { if(i_obs >= esum_na.n()) { esum_na.add(0.0); esumsq_na.add(0.0); + esumn_na.add(0.0); } // Track sums of the raw ensemble member values if(!is_bad_data(v)) { esum_na.inc(i_obs, v); esumsq_na.inc(i_obs, v*v); + esumn_na.inc(i_obs, 1); } return; @@ -416,17 +423,17 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { else { // Compute the variance of the unperturbed ensemble members - var_unperturbed = compute_variance(esum_na[i], esumsq_na[i], v_na[i]); + var_unperturbed = compute_variance(esum_na[i], esumsq_na[i], esumn_na[i]); var_na.add(var_unperturbed); // Process the observation error information. ObsErrorEntry * e = (has_obs_error() ? obs_error_entry[i] : 0); if(e) { - // Compute perturbed ensemble mean and variance - cur_ens.compute_mean_variance(mean, var_perturbed); - mn_oerr_na.add(mean); - var_oerr_na.add(var_perturbed); + // Compute perturbed ensemble mean and variance + // Exclude the control member from the variance + mn_oerr_na.add(cur_ens.mean()); + var_oerr_na.add(cur_ens.variance(ctrl_index)); // Compute the variance plus observation error variance. var_plus_oerr_na.add(var_unperturbed + @@ -467,8 +474,12 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { crps_emp_na.add(compute_crps_emp(o_na[i], cur_ens)); crpscl_emp_na.add(compute_crps_emp(o_na[i], cur_clm)); + // Ensemble mean and standard deviation + // Exclude the control member from the standard deviation + mean = cur_ens.mean(); + stdev = cur_ens.stdev(ctrl_index); + // Store Gaussian CRPS stats - cur_ens.compute_mean_stdev(mean, stdev); crps_gaus_na.add(compute_crps_gaus(o_na[i], mean, stdev)); crpscl_gaus_na.add(compute_crps_gaus(o_na[i], cmn_na[i], csd_na[i])); ign_na.add(compute_ens_ign(o_na[i], mean, stdev)); @@ -613,7 +624,7 @@ struct ssvar_bin_comp { void PairDataEnsemble::compute_ssvar() { int i, j; - double mn, var; + double var; ssvar_bin_map bins; NumArray cur; @@ -644,21 +655,22 @@ void PairDataEnsemble::compute_ssvar() { if(skip_ba[i]) continue; // Store ensemble values for the current observation - for(j=0, cur.erase(); jflag) { @@ -1781,6 +1796,21 @@ void VxPairDataEnsemble::calc_obs_summary() { //////////////////////////////////////////////////////////////////////// +void VxPairDataEnsemble::set_ctrl_index(int index) { + + for(int i=0; i < n_msg_typ; i++){ + for(int j=0; j < n_mask; j++){ + for(int k=0; k < n_interp; k++){ + pd[i][j][k].ctrl_index = index; + } + } + } + + return; +} + +//////////////////////////////////////////////////////////////////////// + void VxPairDataEnsemble::set_skip_const(bool tf) { for(int i=0; i < n_msg_typ; i++){ diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.h b/met/src/libcode/vx_statistics/pair_data_ensemble.h index e9c2417e49..bee6b11838 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.h @@ -90,6 +90,7 @@ class PairDataEnsemble : public PairBase { int n_ens; // Number of ensemble members int n_pair; // Number of valid pairs, n_obs - sum(skip_ba) + int ctrl_index; // Index of the control member bool skip_const; // Skip cases where the observation and // all ensemble members are constant BoolArray skip_ba; // Flag for each observation [n_obs] @@ -106,6 +107,7 @@ class PairDataEnsemble : public PairBase { NumArray esum_na; // Sum of unperturbed ensemble values [n_obs] NumArray esumsq_na; // Sum of unperturbed ensemble squared values [n_obs] + NumArray esumn_na; // Count of ensemble values [n_obs] NumArray mn_na; // Ensemble mean value [n_obs] NumArray mn_oerr_na; // Mean of perturbed members [n_obs] @@ -293,6 +295,8 @@ class VxPairDataEnsemble { void calc_obs_summary(); + void set_ctrl_index(int); + void set_skip_const(bool); }; diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 6dfc98dee3..783691945b 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -61,6 +61,7 @@ // statistics in the ECNT line type. // 031 09/13/21 Seth Linden Changed obs_qty to obs_qty_inc. // Added code for obs_qty_exc. +// 032 10/07/21 Halley Gotway MET #1905 Add -ctrl option. // //////////////////////////////////////////////////////////////////////// @@ -124,7 +125,7 @@ static void do_rps (const EnsembleStatVxOpt &, const PairDataEnsemble *); static void clear_counts(); -static void track_counts(int, const DataPlane &); +static void track_counts(int, const DataPlane &, bool); static ConcatString get_ens_mn_var_name(int); @@ -135,10 +136,12 @@ static void setup_table (AsciiTable &); static void build_outfile_name(unixtime, const char *, ConcatString &); static void write_ens_nc(int, DataPlane &); -static void write_ens_var_float(int, float *, DataPlane &, +static void write_ens_var_float(int, float *, const DataPlane &, const char *, const char *); -static void write_ens_var_int(int, int *, DataPlane &, +static void write_ens_var_int(int, int *, const DataPlane &, const char *, const char *); +static void write_ens_data_plane(int, const DataPlane &, const DataPlane &, + const char *, const char *); static void write_orank_nc(PairDataEnsemble &, DataPlane &, int, int, int); static void write_orank_var_float(int, int, int, float *, DataPlane &, @@ -146,8 +149,8 @@ static void write_orank_var_float(int, int, int, float *, DataPlane &, static void write_orank_var_int(int, int, int, int *, DataPlane &, const char *, const char *); -static void add_var_att_local(VarInfo *, NcVar *, bool is_int, DataPlane &, - const char *, const char *); +static void add_var_att_local(VarInfo *, NcVar *, bool is_int, + const DataPlane &, const char *, const char *); static void finish_txt_files(); static void clean_up(); @@ -157,6 +160,7 @@ static void usage(); static void set_grid_obs(const StringArray &); static void set_point_obs(const StringArray &); static void set_ens_mean(const StringArray & a); +static void set_ctrl_file(const StringArray &); static void set_obs_valid_beg(const StringArray &); static void set_obs_valid_end(const StringArray &); static void set_outdir(const StringArray &); @@ -215,20 +219,18 @@ void process_command_line(int argc, char **argv) { cline.set_usage(usage); // - // add the options function calls + // add the option function calls + // quietly support deprecated -ssvar_mean option // - cline.add(set_grid_obs, "-grid_obs", 1); - cline.add(set_point_obs, "-point_obs", 1); - cline.add(set_ens_mean, "-ens_mean", 1); + cline.add(set_grid_obs, "-grid_obs", 1); + cline.add(set_point_obs, "-point_obs", 1); + cline.add(set_ens_mean, "-ens_mean", 1); + cline.add(set_ctrl_file, "-ctrl", 1); cline.add(set_obs_valid_beg, "-obs_valid_beg", 1); cline.add(set_obs_valid_end, "-obs_valid_end", 1); - cline.add(set_outdir, "-outdir", 1); - cline.add(set_compress, "-compress", 1); - - // - // quietly support deprecated -ssvar_mean option - // - cline.add(set_ens_mean, "-ssvar_mean", 1); + cline.add(set_outdir, "-outdir", 1); + cline.add(set_compress, "-compress", 1); + cline.add(set_ens_mean, "-ssvar_mean", 1); // // parse the command line @@ -291,6 +293,13 @@ void process_command_line(int argc, char **argv) { exit(1); } + // Prepend the control member, if specified + if(ctrl_file.nonempty()) { + ctrl_index = 0; + ens_file_list.insert(ctrl_index, ctrl_file.c_str()); + n_ens++; + } + // Check that the end_ut >= beg_ut if(obs_valid_beg_ut != (unixtime) 0 && obs_valid_end_ut != (unixtime) 0 && @@ -370,18 +379,19 @@ void process_command_line(int argc, char **argv) { shc.set_model(conf_info.model.c_str()); // Allocate arrays to store threshold counts - thresh_count_na = new NumArray [conf_info.get_max_n_thresh()]; - thresh_nbrhd_count_na = new NumArray * [conf_info.get_max_n_thresh()]; + thresh_cnt_na = new NumArray [conf_info.get_max_n_thresh()]; + thresh_nbrhd_cnt_na = new NumArray * [conf_info.get_max_n_thresh()]; for(i=0; i " + << "the control member file is not valid.\n\n"; + exit(1); + } + + // Otherwise, continue + continue; + } // Read the current field if(!get_data_plane(ens_file_list[j].c_str(), etype, - conf_info.ens_info[i], ens_dp, true)) continue; + conf_info.ens_info[i], ens_dp, true)) { + + // Error out if the control member data cannot be read + if(j==ctrl_index) { + mlog << Error << "\nprocess_ensemble() -> " + << "can't find \"" << conf_info.ens_info[i]->magic_str() + << "\" data in the control member file.\n\n"; + exit(1); + } + + // Otherwise, continue + continue; + } // Create a NetCDF file to store the ensemble output if(nc_out == (NcFile *) 0) { @@ -788,7 +821,7 @@ void process_ensemble() { } // Apply current data to the running sums and counts - track_counts(i, ens_dp); + track_counts(i, ens_dp, j == ctrl_index); // Keep track of the maximum initialization time if(is_bad_data(max_init_ut) || ens_dp.init() > max_init_ut) { @@ -802,8 +835,7 @@ void process_ensemble() { write_ens_nc(i, ens_dp); // Store the ensemble mean output file - ens_mean_file = - out_nc_file_list[out_nc_file_list.n() - 1]; + ens_mean_file = out_nc_file_list[out_nc_file_list.n() - 1]; } // end for i @@ -825,7 +857,7 @@ void process_vx() { if(point_obs_file_list.n() == 0 && grid_obs_file_list.n() == 0) { mlog << Error << "\nprocess_vx() -> " - << " when \"fcst.field\" is non-empty, you must use " + << "when \"fcst.field\" is non-empty, you must use " << "\"-point_obs\" and/or \"-grid_obs\" to specify the " << "verifying observations.\n\n"; exit(1); @@ -835,7 +867,7 @@ void process_vx() { conf_info.process_masks(grid); // Setup the PairDataEnsemble objects - conf_info.set_vx_pd(n_vx_vld); + conf_info.set_vx_pd(n_vx_vld, ctrl_index); // Process the point observations if(point_obs_flag) process_point_vx(); @@ -1080,7 +1112,8 @@ int process_point_ens(int i_ens, int &n_miss) { ens_mean_file : ens_mean_user); mlog << Debug(2) << "\n" << sep_str << "\n\n" - << "Processing " << file_type << " file: " << ens_file << "\n"; + << "Processing " << file_type << " file: " << ens_file + << (i_ens == ctrl_index ? " (control)\n" : "\n"); // Loop through each of the fields to be verified and extract // the forecast fields for verification @@ -1651,6 +1684,7 @@ void process_grid_vx() { pd_all.clear(); pd_all.set_ens_size(n_vx_vld[i]); pd_all.set_climo_cdf_info(conf_info.vx_opt[i].cdf_info); + pd_all.ctrl_index = conf_info.vx_opt[i].vx_pd.pd[0][0][0].ctrl_index; pd_all.skip_const = conf_info.vx_opt[i].vx_pd.pd[0][0][0].skip_const; // Apply the current mask to the fields and compute the pairs @@ -1813,7 +1847,7 @@ void process_grid_scores(int i_vx, ObsErrorEntry *e = (ObsErrorEntry *) 0; // Allocate memory in one big chunk based on grid size - pd.extend(grid.nx()*grid.ny()); + pd.extend(nxy); // Climatology flags bool emn_flag = (emn_dp.nx() == obs_dp.nx() && @@ -1880,7 +1914,8 @@ void process_grid_scores(int i_vx, pd.add_ens(j-n_miss, fcst_dp[j](x, y)); // Store the unperturbed ensemble value - pd.add_ens_var_sums(i, fraw_dp[j](x, y)); + // Exclude the control member from the variance + if(j != ctrl_index) pd.add_ens_var_sums(i, fraw_dp[j](x, y)); } } // end for j } // end for i @@ -1955,46 +1990,21 @@ void do_rps(const EnsembleStatVxOpt &vx_opt, //////////////////////////////////////////////////////////////////////// void clear_counts() { - int i, j, k; + int i, j; - // Allocate memory in one big chunk based on grid size, if needed - count_na.extend(nxy); - min_na.extend(nxy); - max_na.extend(nxy); - sum_na.extend(nxy); - sum_sq_na.extend(nxy); - for(i=0; i= MaxBuf[i] || is_bad_data(MaxBuf[i])) MaxBuf[i] = v; + // Ensemble sum + sum_na.buf()[i] += v; - SumBuf[i] += v; - SumSqBuf[i] += v*v; + // Ensemble min and max + if(v <= min_na.buf()[i] || is_bad_data(min_na.buf()[i])) min_na.buf()[i] = v; + if(v >= max_na.buf()[i] || is_bad_data(max_na.buf()[i])) max_na.buf()[i] = v; - for(j=0; j 0 @@ -2051,23 +2062,21 @@ void track_counts(int i_vx, const DataPlane &dp) { DataPlane frac_dp; // Loop over thresholds - for(i=0; i 0) thresh_nbrhd_count_na[i][j].inc(k, 1); + if(frac_dp.data()[k] > 0) thresh_nbrhd_cnt_na[i][j].inc(k, 1); } // end for k } // end for j @@ -2332,45 +2341,33 @@ void build_outfile_name(unixtime ut, const char *suffix, ConcatString &str) { //////////////////////////////////////////////////////////////////////// -void write_ens_nc(int i_ens, DataPlane &dp) { +void write_ens_nc(int i_var, DataPlane &ens_dp) { int i, j, k, l; double t, v; char type_str[max_str_len]; - DataPlane prob_dp, smooth_dp; - - // Arrays for storing ensemble data - float *ens_mean = (float *) 0; - float *ens_stdev = (float *) 0; - float *ens_minus = (float *) 0; - float *ens_plus = (float *) 0; - float *ens_min = (float *) 0; - float *ens_max = (float *) 0; - float *ens_range = (float *) 0; - int *ens_vld = (int *) 0; - float *ens_prob = (float *) 0; + DataPlane prob_dp, nbrhd_dp; // Allocate memory for storing ensemble data - ens_mean = new float [grid.nx()*grid.ny()]; - ens_stdev = new float [grid.nx()*grid.ny()]; - ens_minus = new float [grid.nx()*grid.ny()]; - ens_plus = new float [grid.nx()*grid.ny()]; - ens_min = new float [grid.nx()*grid.ny()]; - ens_max = new float [grid.nx()*grid.ny()]; - ens_range = new float [grid.nx()*grid.ny()]; - ens_vld = new int [grid.nx()*grid.ny()]; - ens_prob = new float [grid.nx()*grid.ny()]; + float * ens_mean = new float [nxy]; + float * ens_stdev = new float [nxy]; + float * ens_minus = new float [nxy]; + float * ens_plus = new float [nxy]; + float * ens_min = new float [nxy]; + float * ens_max = new float [nxy]; + float * ens_range = new float [nxy]; + int * ens_vld = new int [nxy]; // Store the threshold for the ratio of valid data points t = conf_info.vld_data_thresh; // Store the data - for(i=0; i 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" - << conf_info.ens_info[i_ens]->level_attr() + << conf_info.ens_info[i_var]->name_attr() << "_" + << conf_info.ens_info[i_var]->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -2625,16 +2590,16 @@ void write_ens_var_float(int i_ens, float *ens_data, DataPlane &dp, // if(strcmp(type_str, "ENS_MEAN") == 0) { name_str << cs_erase - << conf_info.ens_info[i_ens]->name_attr(); + << conf_info.ens_info[i_var]->name_attr(); } else { name_str << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" + << conf_info.ens_info[i_var]->name_attr() << "_" << type_str; } // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_ens], &ens_var, false, dp, + add_var_att_local(conf_info.ens_info[i_var], &ens_var, false, dp, name_str.c_str(), long_name_str); // Write the data @@ -2650,20 +2615,20 @@ void write_ens_var_float(int i_ens, float *ens_data, DataPlane &dp, //////////////////////////////////////////////////////////////////////// -void write_ens_var_int(int i_ens, int *ens_data, DataPlane &dp, +void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; // Append nc_pairs_var_str config file entry - cs = conf_info.ens_var_str[i_ens]; + cs = conf_info.ens_var_str[i_var]; if(cs.length() > 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" - << conf_info.ens_info[i_ens]->level_attr() + << conf_info.ens_info[i_var]->name_attr() << "_" + << conf_info.ens_info[i_var]->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -2678,11 +2643,11 @@ void write_ens_var_int(int i_ens, int *ens_data, DataPlane &dp, // Construct the variable name attribute name_str << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" + << conf_info.ens_info[i_var]->name_attr() << "_" << type_str; // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_ens], &ens_var, true, dp, + add_var_att_local(conf_info.ens_info[i_var], &ens_var, true, dp, name_str.c_str(), long_name_str); // Write the data @@ -2698,6 +2663,26 @@ void write_ens_var_int(int i_ens, int *ens_data, DataPlane &dp, //////////////////////////////////////////////////////////////////////// +void write_ens_data_plane(int i_var, const DataPlane &ens_dp, const DataPlane &dp, + const char *type_str, const char *long_name_str) { + + // Allocate memory for this data + float *ens_data = new float [nxy]; + + // Store the data in an array of floats + for(int i=0; i + + &MET_BIN;/ensemble_stat + + CENSOR_THRESH + CENSOR_VAL + SKIP_CONST FALSE + OUTPUT_PREFIX MASK_SID_CTRL + CONFIG_DIR &CONFIG_DIR; + + \ + 5 \ + &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib \ + &CONFIG_DIR;/EnsembleStatConfig_MASK_SID \ + -ctrl &DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ + -point_obs &OUTPUT_DIR;/ascii2nc/gauge_2012041012_24hr.nc \ + -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + + + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_MASK_SID_CTRL_20120410_120000V.stat + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_MASK_SID_CTRL_20120410_120000V_orank.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_MASK_SID_CTRL_20120410_120000V_ens.nc + + + &MET_BIN;/ensemble_stat