diff --git a/met/data/config/TCPairsConfig_default b/met/data/config/TCPairsConfig_default index 8c62d1dce3..aa4afb51b6 100644 --- a/met/data/config/TCPairsConfig_default +++ b/met/data/config/TCPairsConfig_default @@ -50,10 +50,17 @@ init_inc = []; init_exc = []; // -// Valid model time window +// Valid model time windows to include or exclude // valid_beg = ""; valid_end = ""; +valid_inc = []; +valid_exc = []; + +// +// Valid times for which output should be written +// +write_valid = []; // // Model initialization hours diff --git a/met/docs/Users_Guide/config_options_tc.rst b/met/docs/Users_Guide/config_options_tc.rst index f3fcc75450..b9542a878d 100644 --- a/met/docs/Users_Guide/config_options_tc.rst +++ b/met/docs/Users_Guide/config_options_tc.rst @@ -92,6 +92,8 @@ or exclude (exc). Tracks whose initial time meets the specified criteria will be used. An empty string indicates that all times should be used. +In TC-Stat, the **-init_beg**, **-init_end**, **init_inc** and **-int_exc** job command options can be used to further refine these selections. + For example: | init_beg = "20100101"; @@ -107,26 +109,34 @@ For example: init_inc = []; init_exc = []; +.. _valid_beg end inc exc_1: -.. _valid_beg, valid_end_1: - -:ref:`valid_beg, valid_end ` - -Specify a model valid time window in YYYYMMDD[_HH[MMSS]] format. -Tracks for which all valid times fall within the time window will be used. -An empty string indicates that all times should be used. + ref:`valid_beg, valid_end, valid_inc, valid_exc ` + +Specify a model valid time window YYYYMMDD[_HH[MMSS]] format or provide a +list of specific valid times to include (inc) or exclude (exc). If a time +window is specified, only tracks for which all points are contained within +the window will be used. If valid times to include or exclude are specified, +tracks will be subset down to the points which meet that criteria. Empty +begin/end time strings and empty include/exclude lists indicate that all +valid times should be used. +In TC-Stat, the **-valid_beg**, **-valid_end**, **valid_inc** and **-valid_exc** job command options can be used to further refine these selections. For example: - + | valid_beg = "20100101"; -| valid_end = "20101231"; -| +| valid_end = "20101231_12"; +| valid_inc = [ "20101231_06" ]; +| valid_exc = [ "20101231_00" ]; +| .. code-block:: none - + valid_beg = ""; valid_end = ""; + valid_inc = []; + valid_exc = []; .. _init_hour_1: @@ -422,7 +432,6 @@ by basin or sub-basin. Note that if your model data and best track do not use the same basin identifier conventions, using an empty list for this parameter will result in missed matches. - .. code-block:: none basin_map = [ @@ -481,9 +490,9 @@ For example: valid_inc = []; valid_exc = []; -.. _ini valid_hour lead req: +.. _init valid_hour lead req: -:ref:`ini_hour, valid_hour, lead, lead_req ` +:ref:`init_hour, valid_hour, lead, lead_req ` Stratify by the initialization and valid hours and lead time. Specify a comma-separated list of initialization hours, diff --git a/met/docs/Users_Guide/tc-pairs.rst b/met/docs/Users_Guide/tc-pairs.rst index f2ce129846..b32cbc15b1 100644 --- a/met/docs/Users_Guide/tc-pairs.rst +++ b/met/docs/Users_Guide/tc-pairs.rst @@ -99,6 +99,8 @@ ____________________ init_exc = []; valid_beg = ""; valid_end = ""; + valid_inc = []; + valid_exc = []; init_hour = []; init_mask = []; lead_req = []; @@ -118,6 +120,14 @@ The **model** variable contains a list of comma-separated models to be used. Eac ____________________ +.. code-block:: none + + write_valid = [ "20101231_06" ]; + +The **write_valid** entry specifies a comma-separated list of valid time strings in YYYYMMDD[_HH[MMSS]] format for which output should be written. An empty list indicates that data for all valid times should be written. This option may be useful when verifying track forecasts in realtime. If evaluating performance for a single valid time, this option can limit the output to that time and skip output for earlier track points. + +____________________ + .. code-block:: none check_dup = FALSE; @@ -315,7 +325,7 @@ TC-Pairs produces output in TCST format. The default output file name can be ove - Valid time masking grid applied * - 13 - LINE_TYPE - - Output line type (TCMPR or PROBRI) + - Output line type (TCMPR or PROBRIRW) .. _TCMPR Line Type: @@ -462,9 +472,9 @@ TC-Pairs produces output in TCST format. The default output file name can be ove - A/BDEPTH - system depth, D-deep, M-medium, S-shallow, X-unknown -.. _PROBRI Line Type: +.. _PROBRIRW Line Type: -.. list-table:: Format information for PROBRIRW (Probability of Rapid Intensification) output line type. +.. list-table:: Format information for PROBRIRW (Probability of Rapid Intensification/Weakening) output line type. :widths: auto :header-rows: 2 @@ -475,8 +485,8 @@ TC-Pairs produces output in TCST format. The default output file name can be ove - Header Column Name - Description * - 13 - - PROBRI - - Probability of Rapid Intensification line type + - PROBRIRW + - Probability of Rapid Intensification/Weakening line type * - 14 - ALAT - Latitude position of edeck model diff --git a/met/docs/Users_Guide/tc-stat.rst b/met/docs/Users_Guide/tc-stat.rst index ee774eee0d..7052e80958 100644 --- a/met/docs/Users_Guide/tc-stat.rst +++ b/met/docs/Users_Guide/tc-stat.rst @@ -139,6 +139,8 @@ _________________________ init_exc = []; valid_beg = ""; valid_end = ""; + valid_inc = []; + valid_exc = []; init_hour = []; lead_req = []; init_mask = []; @@ -161,15 +163,6 @@ The **amodel** and **bmodel** fields stratify by the amodel and bmodel columns b _________________________ -.. code-block:: none - - valid_inc = []; - valid_exc = []; - -The **valid_inc** and **valid_exc** fields stratify by valid times, based on a comma-separated list of specific valid times to include (inc) or exclude (exc). Time strings are defined by YYYYMMDD[_HH[MMSS]]. Using the **-valid_inc** and **-valid_exc** options within the job command lines may further refine these selections. - -_________________________ - .. code-block:: none valid_hour = []; @@ -372,7 +365,7 @@ _________________________ -job summary -line_type TCMPR -column TK_ERR -dump_row ./tc_summary_job.tcst -job rirw -line_type TCMPR -rirw_time 24 -rirw_exact false -rirw_thresh ge20 -job probrirw -line_type PROBRIRW -column_thresh RI_WINDOW ==24 \ - -probri_thresh 30 -probri_prob_thresh ==0.25 + -probrirw_thresh 30 -probrirw_prob_thresh ==0.25 .. _tc_stat-output: @@ -466,12 +459,12 @@ The PROBRIRW job produces probabilistic contingency table counts and statistics • The **-prob_exact bool** option is a boolean defining whether the exact or maximum BEST track intensity change over the time window should be used. If true, the values in the **BDELTA** column are used. If false, the values in the **BDELTA_MAX** column are used. The default is true. -• The **-probri_bdelta_thresh** threshold option defines the BEST track intensity change event threshold. This should typically be set consistent with the probability threshold (**-prob_thresh**) chosen above. The default is greater than or equal to 30 kts. +• The **-probrirw_bdelta_thresh** threshold option defines the BEST track intensity change event threshold. This should typically be set consistent with the probability threshold (**-prob_thresh**) chosen above. The default is greater than or equal to 30 kts. -• The **-probri_prob_thresh threshold_list** option defines the probability thresholds used to create the output Nx2 contingency table. The default is probability bins of width 0.1. These probabilities may be specified as a list (>0.00,>0.25,>0.50,>0.75,>1.00) or using shorthand notation (==0.25) for bins of equal width. +• The **-probrirw_prob_thresh threshold_list** option defines the probability thresholds used to create the output Nx2 contingency table. The default is probability bins of width 0.1. These probabilities may be specified as a list (>0.00,>0.25,>0.50,>0.75,>1.00) or using shorthand notation (==0.25) for bins of equal width. • The **-out_line_type** option defines the output data that should be written. This job can write PCT, PSTD, PJC, and PRC output line types. The default is PCT and PSTD. Please see :numref:`table_PS_format_info_PCT` through :numref:`table_PS_format_info_PRC` for more details. Users may also specify the **-out_alpha** option to define the alpha value for the confidence intervals in the PSTD output line type. Multiple values in the **RI_WINDOW** column cannot be combined in a single PROBRIRW job since the BEST track intensity threshold should change for each. Using the **-by RI_WINDOW** option or **-column_thresh RI_WINDOW ==24** option provide convenient ways avoiding this problem. -Users should note that for the PROBRIRW line type, **PROBRI_PROB** is a derived column name. The -probri_thresh option defines the probabilities of interest (e.g. **-probri_thresh 30**) and the **PROBRI_PROB** column name refers to those probability values, regardless of their column number. For example, the job command options **-probri_thresh 30 -column_thresh PROBRI_PROB >0** select 30 kt probabilities and match probability values greater than 0. +Users should note that for the PROBRIRW line type, **PROBRI_PROB** is a derived column name. The -probrirw_thresh option defines the probabilities of interest (e.g. **-probrirw_thresh 30**) and the **PROBRI_PROB** column name refers to those probability values, regardless of their column number. For example, the job command options **-probrirw_thresh 30 -column_thresh PROBRI_PROB >0** select 30 kt probabilities and match probability values greater than 0. diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index 34fe74c978..81bd59589e 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -1012,6 +1012,7 @@ static const char conf_key_valid_end[] = "valid_end"; static const char conf_key_valid_inc[] = "valid_inc"; static const char conf_key_valid_exc[] = "valid_exc"; static const char conf_key_valid_hour[] = "valid_hour"; +static const char conf_key_write_valid[] = "write_valid"; static const char conf_key_lead[] = "lead"; static const char conf_key_lead_req[] = "lead_req"; static const char conf_key_init_mask[] = "init_mask"; diff --git a/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc b/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc index 61b69cc125..ce38bdfe97 100644 --- a/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc +++ b/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc @@ -453,3 +453,20 @@ bool ProbRIRWPairInfoArray::add(const ProbRIRWInfo &p, const TrackInfo &t) { //////////////////////////////////////////////////////////////////////// +void ProbRIRWPairInfoArray::subset_write_valid(const TimeArray &ta) { + + // Check for no work to do + if(ta.n() == 0) return; + + ProbRIRWPairInfoArray new_pairs; + for(int i=0; i i) { - hdr.set_desc((string)p.line(i)->get_item("DESC", false)); + hdr.set_desc((string)p.line(i)->get_item("DESC", false)); } // Write the header columns @@ -191,7 +191,7 @@ void write_prob_rirw_row(TcHdrColumns &hdr, const ProbRIRWPairInfo &p, // Pass the description from the input line to the output if(p.line().n_items() > 0) { - hdr.set_desc((string)p.line().get_item("DESC", false)); + hdr.set_desc((string)p.line().get_item("DESC", false)); } // Write one line for all the probabilities diff --git a/met/src/libcode/vx_tc_util/track_pair_info.cc b/met/src/libcode/vx_tc_util/track_pair_info.cc index b82d0a5f0d..5a03a9c0fc 100644 --- a/met/src/libcode/vx_tc_util/track_pair_info.cc +++ b/met/src/libcode/vx_tc_util/track_pair_info.cc @@ -309,6 +309,14 @@ void TrackPairInfo::initialize(const TCStatLine &l) { void TrackPairInfo::set_keep(int i, int val) { + // Check range + if(i < 0 || i >= NPoints) { + mlog << Error + << "\nTrackPairInfo::set_keep(int, int) -> " + << "range check error for index value " << i << "\n\n"; + exit(1); + } + Keep.set(i, val); return; @@ -780,13 +788,23 @@ TrackPairInfo TrackPairInfo::keep_subset() const { TrackPairInfo tpi; // Loop over the points - for(i=0; i " @@ -215,25 +215,25 @@ void process_command_line(int argc, char **argv) { } // List the input ADECK track files - for(i=0; i 0) { + if(adeck_source.n() > 0) { process_adecks(bdeck_tracks); } // Process EDECK files - if(edeck_source.n_elements() > 0) { + if(edeck_source.n() > 0) { process_edecks(bdeck_tracks); } @@ -291,7 +291,7 @@ void process_bdecks(TrackInfoArray &bdeck_tracks) { files, files_model_suffix); mlog << Debug(2) - << "Processing " << files.n_elements() << " BDECK file(s).\n"; + << "Processing " << files.n() << " BDECK file(s).\n"; process_track_files(files, files_model_suffix, bdeck_tracks, false, (conf_info.AnlyTrack == TrackType_BDeck || conf_info.AnlyTrack == TrackType_Both)); @@ -314,7 +314,7 @@ void process_adecks(const TrackInfoArray &bdeck_tracks) { files, files_model_suffix); mlog << Debug(2) - << "Processing " << files.n_elements() << " ADECK file(s).\n"; + << "Processing " << files.n() << " ADECK file(s).\n"; process_track_files(files, files_model_suffix, adeck_tracks, true, (conf_info.AnlyTrack == TrackType_ADeck || conf_info.AnlyTrack == TrackType_Both)); @@ -340,7 +340,7 @@ void process_adecks(const TrackInfoArray &bdeck_tracks) { // Derive lag forecasts from the ADECK tracks mlog << Debug(2) - << "Deriving " << conf_info.LagTime.n_elements() + << "Deriving " << conf_info.LagTime.n() << " ADECK lag model(s).\n"; i = derive_lag(adeck_tracks); mlog << Debug(2) @@ -348,8 +348,8 @@ void process_adecks(const TrackInfoArray &bdeck_tracks) { // Derive CLIPER/SHIFOR forecasts from the ADECK/BDECK tracks mlog << Debug(2) - << "Deriving " << conf_info.OperBaseline.n_elements() + - conf_info.BestBaseline.n_elements() + << "Deriving " << conf_info.OperBaseline.n() + + conf_info.BestBaseline.n() << " CLIPER/SHIFOR baseline model(s).\n"; i = derive_baseline(adeck_tracks, bdeck_tracks); mlog << Debug(2) @@ -403,6 +403,14 @@ void process_adecks(const TrackInfoArray &bdeck_tracks) { << pairs.serialize_r() << "\n"; } + // Subset pairs based on requested valid output times + if(conf_info.WriteValid.n() > 0) { + mlog << Debug(3) << "Subsetting output for " + << conf_info.WriteValid.n() + << " requested valid time(s).\n"; + pairs.subset_write_valid(conf_info.WriteValid); + } + // Write out the track pairs write_tracks(pairs); @@ -423,7 +431,7 @@ void process_edecks(const TrackInfoArray &bdeck_tracks) { files, files_model_suffix); mlog << Debug(2) - << "Processing " << files.n_elements() + << "Processing " << files.n() << " EDECK file(s).\n"; process_prob_files(files, files_model_suffix, edeck_probs); @@ -483,6 +491,14 @@ void process_edecks(const TrackInfoArray &bdeck_tracks) { << prob_rirw_pairs.serialize_r() << "\n"; } + // Subset pairs based on requested valid output times + if(conf_info.WriteValid.n() > 0) { + mlog << Debug(3) << "Subsetting output for " + << conf_info.WriteValid.n() + << " requested valid time(s).\n"; + prob_rirw_pairs.subset_write_valid(conf_info.WriteValid); + } + // Write out the ProbRIRW pairs if(prob_rirw_pairs.n_pairs() > 0) write_prob_rirw(prob_rirw_pairs); @@ -498,7 +514,7 @@ void get_atcf_files(const StringArray &source, StringArray cur_source, cur_files; int i, j; - if(source.n_elements() != model_suffix.n_elements()) { + if(source.n() != model_suffix.n()) { mlog << Error << "\nget_atcf_files() -> " << "the source and suffix arrays must be equal length!\n\n"; @@ -510,12 +526,12 @@ void get_atcf_files(const StringArray &source, files_model_suffix.clear(); // Build list of files and corresponding model suffix list - for(i=0; iwarning_time(), m, d, y, h, mm, s); // Check model - if(conf_info.Model.n_elements() > 0 && + if(conf_info.Model.n() > 0 && !conf_info.Model.has(line->technique())) keep = false; // Check storm id - else if(conf_info.StormId.n_elements() > 0 && + else if(conf_info.StormId.n() > 0 && !has_storm_id(conf_info.StormId, line->basin(), line->cyclone_number(), line->warning_time())) keep = false; // Check basin - else if(conf_info.Basin.n_elements() > 0 && + else if(conf_info.Basin.n() > 0 && !conf_info.Basin.has(line->basin())) keep = false; // Check cyclone - else if(conf_info.Cyclone.n_elements() > 0 && + else if(conf_info.Cyclone.n() > 0 && !conf_info.Cyclone.has(line->cyclone_number())) keep = false; @@ -752,17 +768,24 @@ bool is_keeper(const ATCFLineBase * line) { conf_info.InitBeg > line->warning_time()) || (conf_info.InitEnd > 0 && conf_info.InitEnd < line->warning_time()) || - (conf_info.InitInc.n_elements() > 0 && + (conf_info.InitInc.n() > 0 && !conf_info.InitInc.has(line->warning_time())) || - (conf_info.InitExc.n_elements() > 0 && + (conf_info.InitExc.n() > 0 && conf_info.InitExc.has(line->warning_time()))) keep = false; // Initialization hour - else if(conf_info.InitHour.n_elements() > 0 && + else if(conf_info.InitHour.n() > 0 && !conf_info.InitHour.has(hms_to_sec(h, mm, s))) keep = false; + // Valid time include/exclude + else if((conf_info.ValidInc.n() > 0 && + !conf_info.ValidInc.has(line->valid())) || + (conf_info.ValidExc.n() > 0 && + conf_info.ValidExc.has(line->valid()))) + keep = false; + // Return the keep status return(keep); } @@ -781,11 +804,11 @@ void filter_tracks(TrackInfoArray &tracks) { // Loop through the tracks and determine which should be retained // The is_keeper() function has already filtered by model, storm id, - // basin, cyclone, initialization time, and initialization hour. + // basin, cyclone, and timing information. for(i=0; i 0 && + if(conf_info.StormName.n() > 0 && !conf_info.StormName.has(t[i].storm_name())) { mlog << Debug(4) << "Discarding track " << i+1 << " for storm name mismatch: " @@ -812,10 +835,10 @@ void filter_tracks(TrackInfoArray &tracks) { // These are used in determining whether to keep or discard a track; keep a track // if all the required lead times are present. If no required lead times are // specified in the config file, then ignore checking and proceed as usual. - if(conf_info.LeadReq.n_elements() > 0) { + if(conf_info.LeadReq.n() > 0) { // Loop over the required lead times - for(j=0, status=true; jstorm_name()); - // Write the current TrackPairInfo object + // Write the current ProbRIRWPairInfo object write_prob_rirw_row(tchc, p[i], out_at, i_row); } @@ -2159,11 +2182,11 @@ void set_atcf_source(const StringArray & a, ConcatString cs, suffix; // Check for optional suffix sub-argument - for(i=0; i " << "the model suffix must be specified as " @@ -2177,7 +2200,7 @@ void set_atcf_source(const StringArray & a, } // Parse the remaining sources - for(i=0; i - LEAD_REQ + VALID_INC + WRITE_VALID + LEAD_REQ &MET_BIN;/tc_pairs \ @@ -70,6 +72,9 @@ &MET_BIN;/tc_pairs + + WRITE_VALID + \ -edeck &DATA_DIR;/edeck/*2015*.dat \ -bdeck &DATA_DIR;/bdeck/*2015*.dat \ @@ -100,7 +105,9 @@ - LEAD_REQ "96","108" + VALID_INC + WRITE_VALID + LEAD_REQ "96","108" &MET_BIN;/tc_pairs \ @@ -116,4 +123,42 @@ + + + VALID_INC "20100814_12", "20100815_00" + WRITE_VALID "20100815_00" + LEAD_REQ + + &MET_BIN;/tc_pairs + \ + -adeck &DATA_DIR;/adeck/*2010.dat \ + -bdeck &DATA_DIR;/bdeck/*2010.dat \ + -config &CONFIG_DIR;/TCPairsConfig_ALAL2010 \ + -out &OUTPUT_DIR;/tc_pairs/alal2010_WRITE_VALID \ + -log &OUTPUT_DIR;/tc_pairs/tc_pairs_WRITE_VALID.log \ + -v 2 + + + &OUTPUT_DIR;/tc_pairs/alal2010_WRITE_VALID.tcst + + + + + &MET_BIN;/tc_pairs + + WRITE_VALID "20150512" + + \ + -edeck &DATA_DIR;/edeck/*2015*.dat \ + -bdeck &DATA_DIR;/bdeck/*2015*.dat \ + -config &CONFIG_DIR;/TCPairsConfig_PROBRIRW \ + -out &OUTPUT_DIR;/tc_pairs/alal2015_WRITE_VALID \ + -log &OUTPUT_DIR;/tc_pairs/tc_pairs_WRITE_VALID_PROBRIRW.log \ + -v 3 + + + &OUTPUT_DIR;/tc_pairs/alal2015_WRITE_VALID_PROBRIRW.tcst + + +