diff --git a/data/config/IODA2NCConfig_default b/data/config/IODA2NCConfig_default index 071a846374..f2c6d215f6 100644 --- a/data/config/IODA2NCConfig_default +++ b/data/config/IODA2NCConfig_default @@ -93,7 +93,8 @@ metadata_map = [ { key = "pressure"; val = "air_pressure,pressure"; }, { key = "height"; val = "height,height_above_mean_sea_level"; }, { key = "datetime"; val = "datetime,dateTime"; }, - { key = "elevation"; val = "elevation,station_elevation"; } + { key = "elevation"; val = "elevation,station_elevation"; }, + { key = "nlocs"; val = "Location"; } ]; // diff --git a/docs/Users_Guide/reformat_point.rst b/docs/Users_Guide/reformat_point.rst index 809639c249..b7738a120e 100644 --- a/docs/Users_Guide/reformat_point.rst +++ b/docs/Users_Guide/reformat_point.rst @@ -975,10 +975,12 @@ _____________________ { key = "station_id"; val = "station_id,report_identifier"; }, { key = "pressure"; val = "air_pressure,pressure"; }, { key = "height"; val = "height,height_above_mean_sea_level"; }, - { key = "elevation"; val = "elevation,station_elevation"; } + { key = "elevation"; val = "elevation,station_elevation"; }, + { key = "nlocs"; val = "Location"; } ]; This entry is an array of dictionaries, each containing a **key** string and **val** string which define a mapping of metadata for IODA data files. +The "nlocs" is for the dimension name of the locations. The following key can be added: "nstring", "latitude" and "longitude". _____________________ diff --git a/src/tools/other/ioda2nc/ioda2nc.cc b/src/tools/other/ioda2nc/ioda2nc.cc index 4e77447176..622d949f58 100644 --- a/src/tools/other/ioda2nc/ioda2nc.cc +++ b/src/tools/other/ioda2nc/ioda2nc.cc @@ -25,7 +25,6 @@ // //////////////////////////////////////////////////////////////////////// -using namespace std; #include #include @@ -35,7 +34,6 @@ using namespace std; #include #include -using namespace netCDF; #include "main.h" #include "apply_mask.h" @@ -52,13 +50,17 @@ using namespace netCDF; #include "nc_point_obs_out.h" #include "nc_summary.h" +using namespace std; +using namespace netCDF; + + //////////////////////////////////////////////////////////////////////// // // Constants // -static const char * DEF_CONFIG_NAME = "MET_BASE/config/IODA2NCConfig_default"; +static const char *DEF_CONFIG_NAME = "MET_BASE/config/IODA2NCConfig_default"; static const char *program_name = "ioda2nc"; @@ -130,7 +132,7 @@ static vector observations; // // Output NetCDF file, dimensions, and variables // -static NcFile *f_out = (NcFile *) 0; +static NcFile *f_out = (NcFile *) nullptr; //////////////////////////////////////////////////////////////////////// @@ -164,22 +166,23 @@ static void set_valid_beg_time(const StringArray &); static void set_valid_end_time(const StringArray &); static void set_verbosity(const StringArray &); -static bool check_core_data(const bool, const bool, StringArray &, StringArray &, e_ioda_format); +static bool check_core_data(const bool, const bool, + StringArray &, StringArray &, e_ioda_format); static bool check_missing_thresh(float value); -static ConcatString find_meta_name(StringArray, StringArray); +static ConcatString find_meta_name(string meta_key, StringArray available_names); static bool get_meta_data_float(NcFile *, StringArray &, const char *, float *, const int); static bool get_meta_data_strings(NcVar &, char *); static bool get_meta_data_strings(NcVar &, char **); static bool get_obs_data_float(NcFile *, const ConcatString, NcVar *, float *, int *, const int, const e_ioda_format); -static bool has_postfix(std::string const &, std::string const &); - +static bool has_postfix(const std::string &, std::string const &); +static bool is_in_metadata_map(string metadata_key, StringArray &available_list); + //////////////////////////////////////////////////////////////////////// int met_main(int argc, char *argv[]) { - int i; // Initialize static variables initialize(); @@ -191,7 +194,7 @@ int met_main(int argc, char *argv[]) { open_netcdf(); // Process each IODA file - for(i=0; i= debug_level_for_performance) { @@ -1139,7 +1148,7 @@ void clean_up() { if(f_out) { delete f_out; - f_out = (NcFile *) 0; + f_out = (NcFile *) nullptr; } return; @@ -1210,7 +1219,7 @@ bool check_core_data(const bool has_msg_type, const bool has_station_id, StringArray &t_core_dims = (ioda_format == ioda_v2) ? core_dims : core_dims_v1; for(int idx=0; idx " << "core dimension \"" << t_core_dims[idx] << "\" is missing.\n\n"; is_netcdf_ready = false; @@ -1219,7 +1228,7 @@ bool check_core_data(const bool has_msg_type, const bool has_station_id, if (ioda_format == ioda_v1) { if(has_msg_type || has_station_id) { - if(!dim_names.has("nstring")) { + if (!is_in_metadata_map("nstring", dim_names)) { mlog << Error << "\n" << method_name << "-> " << "core dimension \"nstring\" is missing.\n\n"; is_netcdf_ready = false; @@ -1228,19 +1237,7 @@ bool check_core_data(const bool has_msg_type, const bool has_station_id, } for(int idx=0; idx 0) { - for (int idx2=0; idx2 < alt_names.n(); idx2++) { - if (core_meta_vars[idx] != alt_names[idx2]) { - found = metadata_vars.has(alt_names[idx2]); - if (found) break; - } - } - } - } - if(!found) { + if(!is_in_metadata_map(core_meta_vars[idx], metadata_vars)) { mlog << Error << "\n" << method_name << "-> " << "core variable \"" << core_meta_vars[idx] << "\" is missing.\n\n"; is_netcdf_ready = false; @@ -1264,13 +1261,16 @@ bool check_missing_thresh(float value) { //////////////////////////////////////////////////////////////////////// -ConcatString find_meta_name(StringArray metadata_names, StringArray config_names) { +ConcatString find_meta_name(string meta_key, StringArray available_names) { ConcatString metadata_name; - - for(int idx =0; idx 0) { NcVar meta_var = get_var(f_in, metadata_name.c_str(), metadata_group_name); @@ -1388,9 +1387,11 @@ bool get_obs_data_float(NcFile *f_in, const ConcatString var_name, //////////////////////////////////////////////////////////////////////// -bool has_postfix(std::string const &str_buf, std::string const &postfix) { - if(str_buf.length() >= postfix.length()) { - return (0 == str_buf.compare(str_buf.length() - postfix.length(), postfix.length(), postfix)); +bool has_postfix(const std::string &str_buf, std::string const &postfix) { + auto buf_len = str_buf.length(); + auto postfix_len = postfix.length(); + if(buf_len >= postfix_len) { + return (0 == str_buf.compare(buf_len - postfix_len, postfix_len, postfix)); } else { return false; } @@ -1398,6 +1399,23 @@ bool has_postfix(std::string const &str_buf, std::string const &postfix) { //////////////////////////////////////////////////////////////////////// +bool is_in_metadata_map(std::string metadata_key, StringArray &available_list) { + bool found = available_list.has(metadata_key); + + if (!found) { + StringArray alt_names = conf_info.metadata_map[metadata_key]; + if (alt_names.n() > 0) { + for (int idx=0; idx #include #include @@ -25,6 +23,9 @@ using namespace std; #include "grib_strings.h" #include "vx_log.h" +using namespace std; + + //////////////////////////////////////////////////////////////////////// // // Code for class IODA2NCConfInfo @@ -94,8 +95,8 @@ void IODA2NCConfInfo::process_config() { int i; ConcatString s, mask_name; StringArray sa; - StringArray * sid_list = 0; - Dictionary *dict = (Dictionary *) 0; + StringArray * sid_list = nullptr; + Dictionary *dict = (Dictionary *) nullptr; static const char *method_name = "IODA2NCConfInfo::process_config() -> "; // Dump the contents of the config file diff --git a/src/tools/other/ioda2nc/ioda2nc_conf_info.h b/src/tools/other/ioda2nc/ioda2nc_conf_info.h index a806a66276..cab5ec6f6e 100644 --- a/src/tools/other/ioda2nc/ioda2nc_conf_info.h +++ b/src/tools/other/ioda2nc/ioda2nc_conf_info.h @@ -54,10 +54,10 @@ class IODA2NCConfInfo { ThreshArray missing_thresh; // Fill value thresh array ConcatString version; // Config file version - map obs_name_map; - map message_type_map; - map metadata_map; - map obs_to_qc_map; + std::map obs_name_map; + std::map message_type_map; + std::map metadata_map; + std::map obs_to_qc_map; StringArray surface_message_types; TimeSummaryInfo timeSummaryInfo; @@ -66,8 +66,8 @@ class IODA2NCConfInfo { void clear(); - map getObsVarMap() const { return obs_name_map; } - map getMessageTypeMap() const { return message_type_map; } + std::map getObsVarMap() const { return obs_name_map; } + std::map getMessageTypeMap() const { return message_type_map; } TimeSummaryInfo getSummaryInfo() const { return timeSummaryInfo; }; void read_config(const char *, const char *);