Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature 2429 tc pairs members #2451

Merged
merged 14 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/Users_Guide/tc-pairs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,11 @@ ____________________
members = [ "MOD1", "MOD2", "MOD3" ];
required = [ true, false, false ];
min_req = 2;
write_members = TRUE;
}
];

The **consensus** field allows the user to generate a user-defined consensus forecasts from any number of models. All models used in the consensus forecast need to be included in the **model** field (first entry in **TCPairsConfig_default**). The name field is the desired consensus model name. The **members** field is a comma-separated list of model IDs that make up the members of the consensus. The **required** field is a comma-separated list of true/false values associated with each consensus member. If a member is designated as true, the member is required to be present in order for the consensus to be generated. If a member is false, the consensus will be generated regardless of whether the member is present. The length of the required array must be the same length as the members array. The **min_req** field is the number of members required in order for the consensus to be computed. The required and min_req field options are applied at each forecast lead time. If any member of the consensus has a non-valid position or intensity value, the consensus for that valid time will not be generated. If a consensus model is indicated in the configuration file there will be non-missing output for the consensus track variables in the output file (NUM_MEMBERS, TRACK_SPREAD, TRACK_STDEV, MSLP_STDEV, MAX_WIND_STDEV). See the TCMPR line type definitions below.
The **consensus** field allows the user to generate a user-defined consensus forecasts from any number of models. All models used in the consensus forecast need to be included in the **model** field (first entry in **TCPairsConfig_default**). The name field is the desired consensus model name. The **members** field is a comma-separated list of model IDs that make up the members of the consensus. The **required** field is a comma-separated list of true/false values associated with each consensus member. If a member is designated as true, the member is required to be present in order for the consensus to be generated. If a member is false, the consensus will be generated regardless of whether the member is present. The length of the required array must be the same length as the members array. The **min_req** field is the number of members required in order for the consensus to be computed. The required and min_req field options are applied at each forecast lead time. If any member of the consensus has a non-valid position or intensity value, the consensus for that valid time will not be generated. The **write_members** field is a boolean that indicates whether or not to write output for the individual consensus members. If set to true, standard output will show up for all members. If set to false, output for the consensus members is excluded from the output, even if they are used to define other consensus tracks in the configuration file. If a consensus model is defined in the configuration file, there will be non-missing output for the consensus track variables in the output file (NUM_MEMBERS, TRACK_SPREAD, TRACK_STDEV, MSLP_STDEV, MAX_WIND_STDEV). See the TCMPR line type definitions below.

____________________

Expand Down
7 changes: 7 additions & 0 deletions internal/test_unit/config/TCPairsConfig_CONSENSUS
Original file line number Diff line number Diff line change
Expand Up @@ -107,42 +107,49 @@ consensus = [
"UE35" ];
required = [];
min_req = 36;
write_members = FALSE;
},
{
name = "HCCA_CONS";
members = [ "AEMI", "GFSI", "CTCI", "DSHP", "EGRI", "EMN2", "EMXI", "HWFI", "LGEM" ];
required = [];
min_req = 8;
write_members = TRUE;
},
{
name = "GFEX_CONS";
members = [ "GFSI", "EMXI" ];
required = [];
min_req = 2;
write_members = TRUE;
},
{
name = "TVCA_CONS";
members = [ "GFSI", "EGRI", "HWFI", "EMHI", "CTCI", "EMNI" ];
required = [];
min_req = 2;
write_members = TRUE;
},
{
name = "TVCX_CONS";
members = [ "GFSI", "EMXI", "EMXI", "HWFI", "CTCI", "EGRI" ];
required = [ TRUE, TRUE, FALSE, FALSE, FALSE, FALSE ];
min_req = 2;
write_members = TRUE;
},
{
name = "ICON_CONS";
members = [ "DSHP", "LGEM", "HWFI", "HMNI" ];
required = [ TRUE, TRUE, TRUE, TRUE ];
min_req = 4;
write_members = TRUE;
},
{
name = "IVCN_CONS";
members = [ "DSHP", "LGEM", "HWFI", "HMNI", "CTCI" ];
required = [];
min_req = 2;
write_members = TRUE;
}
];

Expand Down
1 change: 1 addition & 0 deletions src/basic/vx_config/config_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,7 @@ static const char conf_key_consensus[] = "consensus";
static const char conf_key_members[] = "members";
static const char conf_key_required[] = "required";
static const char conf_key_min_req[] = "min_req";
static const char conf_key_write_members[] = "write_members";
static const char conf_key_lag_time[] = "lag_time";
static const char conf_key_best_technique[] = "best_technique";
static const char conf_key_best_baseline[] = "best_baseline";
Expand Down
17 changes: 15 additions & 2 deletions src/tools/tc_utils/tc_pairs/tc_pairs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
// 012 07/06/22 Howard Soh METplus-Internal #19 Rename main to met_main
// 013 09/28/22 Prestopnik MET #2227 Remove namespace std from header files
// 014 10/06/22 Halley Gotway MET #392 Incorporate diagnostics
// 015 02/20/23 Seth Linden MET #2429 Added option to prevent output of consensus track members
//
////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -811,19 +812,30 @@ bool is_keeper(const ATCFLineBase * line) {

void filter_tracks(TrackInfoArray &tracks) {
int i, j;
int n_name, n_vld, n_mask_init, n_mask_vld, n_req_lead;
int n_name, n_vld, n_mask_init, n_mask_vld, n_req_lead, n_members;
bool status;
TrackInfoArray t = tracks;

// Initialize
tracks.clear();
n_name = n_vld = n_mask_init = n_mask_vld = n_req_lead = 0;
n_name = n_vld = n_mask_init = n_mask_vld = n_req_lead = n_members = 0;

// Loop through the tracks and determine which should be retained
// The is_keeper() function has already filtered by model, storm id,
// basin, cyclone, and timing information.
for(i=0; i<t.n(); i++) {

// Check if we should skip output for certain consensus members
// The StringArray conf_info.SkipConsensusMembers contains the members to skip
if(conf_info.SkipConsensusMembers.n() > 0 &&
conf_info.SkipConsensusMembers.has(t[i].technique())) {
mlog << Debug(4)
<< "Discarding track " << i+1 << " since it is listed in SkipConsensusMembers: "
<< t[i].technique() << "\n";
n_members++;
continue;
}

// Check storm name
if(conf_info.StormName.n() > 0 &&
!conf_info.StormName.has(t[i].storm_name())) {
Expand Down Expand Up @@ -922,6 +934,7 @@ void filter_tracks(TrackInfoArray &tracks) {
mlog << Debug(3)
<< "Total tracks read = " << t.n() << "\n"
<< "Total tracks kept = " << tracks.n() << "\n"
<< "Rejected for skip members = " << n_members << "\n"
<< "Rejected for storm name = " << n_name << "\n"
<< "Rejected for valid time = " << n_vld << "\n"
<< "Rejected for required lead times = " << n_req_lead << "\n"
Expand Down
10 changes: 9 additions & 1 deletion src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ void TCPairsConfInfo::clear() {
Basin.clear();
Cyclone.clear();
StormName.clear();
SkipConsensusMembers.clear();
InitBeg = InitEnd = (unixtime) 0;
InitInc.clear();
InitExc.clear();
Expand Down Expand Up @@ -240,11 +241,13 @@ void TCPairsConfInfo::process_config() {
// Loop over the consensus entries
for(i=0; i<NConsensus; i++) {

// Conf: Consensus: name, members, required, min_req
// Conf: Consensus: name, members, required, min_req, write_members
Consensus[i].Name = (*dict)[i]->dict_value()->lookup_string(conf_key_name);
Consensus[i].Members = (*dict)[i]->dict_value()->lookup_string_array(conf_key_members);
Consensus[i].Required = (*dict)[i]->dict_value()->lookup_num_array(conf_key_required);
Consensus[i].MinReq = (*dict)[i]->dict_value()->lookup_int(conf_key_min_req);
Consensus[i].WriteMembers = true;
Consensus[i].WriteMembers = (*dict)[i]->dict_value()->lookup_bool(conf_key_write_members);

// If required is empty, default to 0
if(Consensus[i].Required.n_elements() == 0) {
Expand All @@ -260,6 +263,11 @@ void TCPairsConfInfo::process_config() {
<< "or the same length as \"consensus.members\".\n\n";
exit(1);
}

// If WriteMembers is false, save the Members to skip output for
if(!Consensus[i].WriteMembers) {
SkipConsensusMembers.add(Consensus[i].Members);
}
}

// Conf: LagTime
Expand Down
4 changes: 3 additions & 1 deletion src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct ConsensusInfo {
StringArray Members;
NumArray Required;
int MinReq;
bool WriteMembers;
};

////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -63,7 +64,8 @@ class TCPairsConfInfo {
StringArray Basin; // List of basin names
StringArray Cyclone; // List of cyclone numbers
StringArray StormName; // List of storm names

StringArray SkipConsensusMembers; // List of consensus members to skip output for

// Timing information
unixtime InitBeg, InitEnd;
TimeArray InitInc;
Expand Down