diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 50913df2e3..2229dabbae 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -52,10 +52,10 @@ static void process_ensemble(); static bool get_data_plane(const char *, GrdFileType, VarInfo *, DataPlane &); static void clear_counts(); -static void track_counts(int, const DataPlane &, +static void track_counts(int, const DataPlane &, bool, const DataPlane &, const DataPlane &); -static void setup_nc_file(unixtime, const char *); +static void setup_nc_file(); static void write_ens_nc(int, int, const DataPlane &, const DataPlane &, const DataPlane &); static void write_ens_var_float(int, float *, const DataPlane &, @@ -197,12 +197,16 @@ void process_command_line(int argc, char **argv) { mlog << " " << ens_files[i] << "\n"; } + // List the control member file + mlog << Debug(1) << "Ensemble Control: " + << (ctrl_file.empty() ? "NONE" : ctrl_file.c_str()) << "\n"; + // Check for missing non-python ensemble files for(i=0; i " - << "can't open input ensemble file: " + << "cannot open input ensemble file: " << ens_files[i] << "\n\n"; ens_file_vld.add(0); } @@ -260,6 +264,9 @@ bool get_data_plane(const char *infile, GrdFileType ftype, // Setup the verification grid, if necessary if(nxy == 0) process_grid(mtddf->grid()); + // Create the output file, if necessary + if(nc_out == (NcFile *) 0) setup_nc_file(); + // Regrid, if requested and necessary if(!(mtddf->grid() == grid)) { mlog << Debug(1) @@ -294,7 +301,7 @@ bool get_data_plane(const char *infile, GrdFileType ftype, void process_ensemble() { int i_var, i_file, n_ens_vld; bool need_reset; - DataPlane ens_dp, cmn_dp, csd_dp; + DataPlane ens_dp, ctrl_dp, cmn_dp, csd_dp; unixtime max_init_ut = bad_data_ll; // Loop through each of the ensemble fields to be processed @@ -304,8 +311,11 @@ void process_ensemble() { << "Processing ensemble field: " << conf_info.ens_info[i_var]->magic_str() << "\n"; - // Loop through each of the input forecast files - for(i_file=0, n_ens_vld=0, need_reset=true; i_file " << "ensemble field \"" << conf_info.ens_info[i_var]->magic_str() << "\" not found in file \"" << ens_files[i_file] << "\"\n\n"; + continue; } else { n_ens_vld++; } - // Create a NetCDF file to store the ensemble output - if(nc_out == (NcFile *) 0) { - setup_nc_file(ens_dp.valid(), "_ens.nc"); - } - // Reinitialize for the current variable if(need_reset) { @@ -334,7 +340,25 @@ void process_ensemble() { // Reset the running sums and counts clear_counts(); - // Read climatology data for this variable + // Read ensemble control member data, if provided + if(ctrl_file.nonempty()) { + + // Error out if missing + if(!get_data_plane(ctrl_file.c_str(), etype, + conf_info.ens_info[i_var], ctrl_dp)) { + mlog << Error << "\nprocess_ensemble() -> " + << "control member ensemble field \"" + << conf_info.ens_info[i_var]->magic_str() + << "\" not found in file \"" << ctrl_file << "\"\n\n"; + exit(1); + } + + // Apply current data to the running sums and counts + track_counts(i_var, ctrl_dp, true, cmn_dp, csd_dp); + + } // end if ctrl_file + + // Read climatology data for this field cmn_dp = read_climo_data_plane( conf_info.conf.lookup_array(conf_key_climo_mean_field, false), i_var, ens_valid_ut, grid); @@ -344,14 +368,16 @@ void process_ensemble() { i_var, ens_valid_ut, grid); mlog << Debug(3) - << "Found " << (cmn_dp.is_empty() ? 0 : 1) - << " climatology mean field(s) and " << (csd_dp.is_empty() ? 0 : 1) + << "Found " << (ctrl_dp.is_empty() ? 0 : 1) + << " control member, " << (cmn_dp.is_empty() ? 0 : 1) + << " climatology mean, and " << (csd_dp.is_empty() ? 0 : 1) << " climatology standard deviation field(s) for \"" << conf_info.ens_info[i_var]->magic_str() << "\".\n"; - } + + } // end if need_reset // Apply current data to the running sums and counts - track_counts(i_var, ens_dp, cmn_dp, csd_dp); + track_counts(i_var, ens_dp, false, cmn_dp, csd_dp); // Keep track of the maximum initialization time if(is_bad_data(max_init_ut) || ens_dp.init() > max_init_ut) { @@ -383,46 +409,18 @@ void process_ensemble() { //////////////////////////////////////////////////////////////////////// void clear_counts() { - int i, j, k; - - // Allocate memory in one big chunk based on grid size, if needed - cnt_na.extend(nxy); - min_na.extend(nxy); - max_na.extend(nxy); - sum_na.extend(nxy); - ssq_na.extend(nxy); - for(i=0; i= max_buf[i] || is_bad_data(max_buf[i])) max_buf[i] = ens; - - // Sum and sum of squares - sum_buf[i] += ens; - ssq_buf[i] += ens*ens; + if(ens <= min_na.buf()[i] || is_bad_data(min_na.buf()[i])) min_na.buf()[i] = ens; + if(ens >= max_na.buf()[i] || is_bad_data(max_na.buf()[i])) max_na.buf()[i] = ens; + + // Standard deviation sum, sum of squares, and count, excluding control member + if(!is_ctrl) { + sum_na.buf()[i] += ens; + ssq_na.buf()[i] += ens*ens; + stdev_cnt_na.buf()[i] += 1; + } // Event frequency for(j=0; j