From a9a0ae7cc86a3877c9f4a1a790f9c497c8919d8c Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 14:22:26 -0600 Subject: [PATCH 01/11] #2155 Keep the same login but to avoid the SonarQube findings --- src/basic/vx_util/data_line.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/basic/vx_util/data_line.cc b/src/basic/vx_util/data_line.cc index ca1e8db145..f7692fdeb0 100644 --- a/src/basic/vx_util/data_line.cc +++ b/src/basic/vx_util/data_line.cc @@ -334,7 +334,7 @@ if ( ! read_single_text_line(ldf) ) { clear(); return ( 0 ); } size_t len, tpos = std::string::npos; -if (!Line.find_first_not_of(Delimiter)) { // no leading delimiter +if (0 == Line.find_first_not_of(Delimiter)) { // no leading delimiter ++count; Offset.push_back(pos); Items.push_back(Line.substr(pos, Line.find_first_of(Delimiter, pos) - pos)); From 96a1a04f37a8f59a2716b3250a77cb7c9ca1aa58 Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 14:33:48 -0600 Subject: [PATCH 02/11] #2155 SonarQube: correct hdr_arr_len for header, Check obs_arr is OBS_ARRAY_LEN (5) --- src/tools/dev_utils/met_nc_file.cc | 129 +++++++++++++++-------------- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/src/tools/dev_utils/met_nc_file.cc b/src/tools/dev_utils/met_nc_file.cc index 20e11cbeaf..4ed5bed21c 100644 --- a/src/tools/dev_utils/met_nc_file.cc +++ b/src/tools/dev_utils/met_nc_file.cc @@ -101,13 +101,13 @@ bool MetNcFile::readFile(const int desired_grib_code, _nhdrDim = &nhdrDim; _nobsDim = &nobsDim; _strlDim = &strlDim; - + hdrArrVar = get_nc_var(_ncFile, "hdr_arr"); hdrTypeVar = get_nc_var(_ncFile, "hdr_typ"); hdrSidVar = get_nc_var(_ncFile, "hdr_sid"); hdrVldVar = get_nc_var(_ncFile, "hdr_vld"); obsArrVar = get_nc_var(_ncFile, "obs_arr"); - + _hdrArrVar = &hdrArrVar ; _hdrTypeVar = &hdrTypeVar; _hdrSidVar = &hdrSidVar ; @@ -161,16 +161,16 @@ bool MetNcFile::readFile(const int desired_grib_code, // Loop through the observations, saving the ones that we are // interested in - + //int buf_size = ((nobs_count > DEF_NC_BUFFER_SIZE) ? DEF_NC_BUFFER_SIZE : (nobs_count)); int buf_size = obs_count; int hdr_buf_size = hdr_count; - + // // Allocate space to store the data // - + char hdr_typ_str_full[hdr_buf_size][typ_len]; char hdr_sid_str_full[hdr_buf_size][sid_len]; char hdr_vld_str_full[hdr_buf_size][vld_len]; @@ -182,7 +182,7 @@ bool MetNcFile::readFile(const int desired_grib_code, long offsets[2] = { 0, 0 }; long lengths[2] = { 1, 1 }; - + lengths[0] = hdr_buf_size; // @@ -224,10 +224,10 @@ bool MetNcFile::readFile(const int desired_grib_code, << "trouble getting hdr_arr\n\n"; exit(1); } - + //for(int i_start=0; i_start<nobs_count; i_start+=buf_size) { // buf_size = ((nobs_count-i_start) > DEF_NC_BUFFER_SIZE) ? DEF_NC_BUFFER_SIZE : (nobs_count-i_start); - + offsets[0] = 0; lengths[0] = buf_size; lengths[1] = obs_arr_len; @@ -243,81 +243,82 @@ bool MetNcFile::readFile(const int desired_grib_code, // mlog << Error << "\nmain() -> trouble getting obs_arr\n\n"; // exit(1); //} - - for (unsigned int i = 0; i < GET_NC_SIZE_P(_nobsDim); ++i) - { - - // Copy the current observation message - for (int k=0; k < obs_arr_len; k++) - obs_arr[k] = obs_arr_block[i][k]; - if (obs_arr[0] >= 1.0E10 && obs_arr[1] >= 1.0E10) - break; + if (OBS_ARRAY_LEN == obs_arr_len) { + for (unsigned int i = 0; i < GET_NC_SIZE_P(_nobsDim); ++i) + { + + // Copy the current observation message + for (int k=0; k < obs_arr_len; k++) + obs_arr[k] = obs_arr_block[i][k]; - // Read the current observation quality flag + if (obs_arr[0] >= 1.0E10 && obs_arr[1] >= 1.0E10) + break; - // Get the header index and variable type for this observation. + // Read the current observation quality flag - int hdr_index = nint(obs_arr[0]); - int grib_code = nint(obs_arr[1]); + // Get the header index and variable type for this observation. - // Check if we want to plot this variable type. + int hdr_index = nint(obs_arr[0]); + int grib_code = nint(obs_arr[1]); - if (grib_code != desired_grib_code) - continue; + // Check if we want to plot this variable type. - // Get the corresponding header message type - // Read the corresponding header array for this observation - for (int k=0; k < obs_arr_len; k++) - hdr_arr[k] = hdr_arr_full[hdr_index][k]; - - int str_length; - char message_type_buffer[max_str_len]; - char station_id_buffer[max_str_len]; - char hdr_vld_buffer[max_str_len]; - // Read the corresponding header type for this observation - str_length = m_strlen(hdr_typ_str_full[hdr_index]); - if (str_length > typ_len) str_length = typ_len; - m_strncpy(message_type_buffer, hdr_typ_str_full[hdr_index], str_length, - method_name.c_str(), "message_type_buffer"); - message_type_buffer[str_length] = bad_data_char; + if (grib_code != desired_grib_code) + continue; - // Read the corresponding header Station ID for this observation - str_length = m_strlen(hdr_sid_str_full[hdr_index]); - if (str_length > sid_len) str_length = sid_len; - m_strncpy(station_id_buffer, hdr_sid_str_full[hdr_index], str_length, - method_name.c_str(), "station_id_buffer"); - station_id_buffer[str_length] = bad_data_char; + // Get the corresponding header message type + // Read the corresponding header array for this observation + for (int k=0; k < hdr_arr_len; k++) + hdr_arr[k] = hdr_arr_full[hdr_index][k]; - // Read the corresponding valid time for this observation - str_length = m_strlen(hdr_vld_str_full[hdr_index]); - if (str_length > vld_len) str_length = vld_len; - m_strncpy(hdr_vld_buffer, hdr_vld_str_full[hdr_index], str_length, - method_name.c_str(), "hdr_vld_buffer"); - hdr_vld_buffer[str_length] = bad_data_char; - + int str_length; + char message_type_buffer[max_str_len]; + char station_id_buffer[max_str_len]; + char hdr_vld_buffer[max_str_len]; + // Read the corresponding header type for this observation + str_length = m_strlen(hdr_typ_str_full[hdr_index]); + if (str_length > typ_len) str_length = typ_len; + m_strncpy(message_type_buffer, hdr_typ_str_full[hdr_index], str_length, + method_name.c_str(), "message_type_buffer"); + message_type_buffer[str_length] = bad_data_char; - string message_type = message_type_buffer; + // Read the corresponding header Station ID for this observation + str_length = m_strlen(hdr_sid_str_full[hdr_index]); + if (str_length > sid_len) str_length = sid_len; + m_strncpy(station_id_buffer, hdr_sid_str_full[hdr_index], str_length, + method_name.c_str(), "station_id_buffer"); + station_id_buffer[str_length] = bad_data_char; - if (message_type != desired_message_type) - continue; + // Read the corresponding valid time for this observation + str_length = m_strlen(hdr_vld_str_full[hdr_index]); + if (str_length > vld_len) str_length = vld_len; + m_strncpy(hdr_vld_buffer, hdr_vld_str_full[hdr_index], str_length, + method_name.c_str(), "hdr_vld_buffer"); + hdr_vld_buffer[str_length] = bad_data_char; - // Get the corresponding header station id - string station_id = station_id_buffer; - if (station_id != desired_station_id) - continue; + string message_type = message_type_buffer; - // Get the corresponding header valid time + if (message_type != desired_message_type) + continue; + // Get the corresponding header station id + string station_id = station_id_buffer; - // If we get here, this is an observation that we want to use + if (station_id != desired_station_id) + continue; - SDObservation obs(hdr_vld_buffer, obs_arr[4]); + // Get the corresponding header valid time - observations.push_back(obs); - } // end for i + // If we get here, this is an observation that we want to use + + SDObservation obs(hdr_vld_buffer, obs_arr[4]); + + observations.push_back(obs); + } // end for i + } // Cleanup if (obs_arr) { delete [] obs_arr; obs_arr = (float *) 0; } From 69d009e5d5323599b247296ba4a406b2ec16706b Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 14:34:36 -0600 Subject: [PATCH 03/11] #2155 SonarQube: release memory --- src/libcode/vx_seeps/seeps.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libcode/vx_seeps/seeps.cc b/src/libcode/vx_seeps/seeps.cc index fa8ce18715..d620e781b0 100644 --- a/src/libcode/vx_seeps/seeps.cc +++ b/src/libcode/vx_seeps/seeps.cc @@ -121,11 +121,11 @@ SeepsClimoRecord *SeepsClimo::create_climo_record( //////////////////////////////////////////////////////////////////////// SeepsRecord *SeepsClimo::get_record(int sid, int month, int hour) { - SeepsRecord *record = 0; + SeepsRecord *record = NULL; const char *method_name = "SeepsClimo::get_record() -> "; if (seeps_ready) { - SeepsClimoRecord *climo_record = 0; + SeepsClimoRecord *climo_record = NULL; map<int,SeepsClimoRecord *>::iterator it; if (hour < 6 || hour >= 18) { it = seeps_score_00_map.find(sid); @@ -199,12 +199,13 @@ float SeepsClimo::get_score(int sid, float p_fcst, float p_obs, float score = (float)bad_data_double; SeepsRecord *record = get_record(sid, month, hour); - if (record) { + if (NULL != record) { // Determine location in contingency table int ic = (p_obs>record->t1)+(p_obs>record->t2); int jc = (p_fcst>record->t1)+(p_fcst>record->t2); score = record->scores[(jc*3)+ic]; + delete record; } return score; @@ -214,10 +215,10 @@ float SeepsClimo::get_score(int sid, float p_fcst, float p_obs, SeepsScore *SeepsClimo::get_seeps_score(int sid, float p_fcst, float p_obs, int month, int hour) { - SeepsScore *score = 0; + SeepsScore *score = NULL; SeepsRecord *record = get_record(sid, month, hour); - if (record) { + if (NULL != record) { score = new SeepsScore(); score->p1 = record->p1; score->p2 = record->p1; @@ -227,6 +228,7 @@ SeepsScore *SeepsClimo::get_seeps_score(int sid, float p_fcst, score->obs_cat = (p_obs>record->t1)+(p_obs>record->t2); score->model_cat = (p_fcst>record->t1)+(p_fcst>record->t2); score->score = record->scores[(score->model_cat*3)+score->obs_cat]; + delete record; } return score; From f3557eabfef86c8013eafdd67531593418a19432 Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 14:35:25 -0600 Subject: [PATCH 04/11] #2155 SonarQube: initialize is_ugrid and is_vgrid --- src/tools/core/point_stat/point_stat.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/core/point_stat/point_stat.cc b/src/tools/core/point_stat/point_stat.cc index 0d0dbbd1b4..670fe779d4 100644 --- a/src/tools/core/point_stat/point_stat.cc +++ b/src/tools/core/point_stat/point_stat.cc @@ -736,6 +736,7 @@ void process_obs_file(int i_nc) { // Perform GRIB table lookups, if needed if(!use_var_id) conf_info.process_grib_codes(); + is_vgrd = is_ugrd = false; int hdr_count = met_point_obs->get_hdr_cnt(); int obs_count = met_point_obs->get_obs_cnt(); From 67a625f89c963610c8b68bdf4587a1efbf56437c Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 14:36:35 -0600 Subject: [PATCH 05/11] #2155 SonarQube: release array variable --- src/libcode/vx_data2d_nc_met/get_met_grid.cc | 2 +- src/libcode/vx_nc_util/grid_output.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcode/vx_data2d_nc_met/get_met_grid.cc b/src/libcode/vx_data2d_nc_met/get_met_grid.cc index c6882057e3..a2d224fd48 100644 --- a/src/libcode/vx_data2d_nc_met/get_met_grid.cc +++ b/src/libcode/vx_data2d_nc_met/get_met_grid.cc @@ -783,7 +783,7 @@ long count = get_data_size(&nc_var); double * data_values = new double[ count ]; get_nc_data(&nc_var, data_values); for(int i=0; i<count; i++) out_na.add(data_values[i]); -if(data_values) { delete data_values; data_values = (double *) 0; } +if(data_values) { delete [] data_values; data_values = (double *) 0; } return; diff --git a/src/libcode/vx_nc_util/grid_output.cc b/src/libcode/vx_nc_util/grid_output.cc index 1b9a0b1ccd..4a23516d78 100644 --- a/src/libcode/vx_nc_util/grid_output.cc +++ b/src/libcode/vx_nc_util/grid_output.cc @@ -749,7 +749,7 @@ if ( standard_name_str ) add_att(&nc_var, standard_name_att_name, standard_name put_nc_data(&nc_var, &var_data[0], nc_dim->getSize(), 0); -if ( var_data ) { delete var_data; var_data = (float *) 0; } +if ( var_data ) { delete [] var_data; var_data = (float *) 0; } // // done From 15d9f57ddbcab4c53fb8d993911df91f74221636 Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 14:37:10 -0600 Subject: [PATCH 06/11] #2155 SonarQube: to avoid a finding --- src/tools/other/mode_time_domain/mm_engine.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/other/mode_time_domain/mm_engine.cc b/src/tools/other/mode_time_domain/mm_engine.cc index 200823c9c5..820594c8ce 100644 --- a/src/tools/other/mode_time_domain/mm_engine.cc +++ b/src/tools/other/mode_time_domain/mm_engine.cc @@ -268,7 +268,8 @@ if ( mlog.verbosity_level() > 5 ) { s << "Composites ...\n"; - for (j=0; j<N_Composites; ++j) { + int tmp_len = comp_to_eq.n(); + for (j=0; j<tmp_len; ++j) { s << ' ' << comp_to_eq[j]; From 145f73fee0b2c96d815f6c7ae8fee33678b3eeeb Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 14:37:49 -0600 Subject: [PATCH 07/11] #21565 Support month and year unit --- src/basic/vx_cal/is_leap_year.cc | 73 +++++++++++++++++++++++++----- src/libcode/vx_nc_util/nc_utils.cc | 10 +++- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/basic/vx_cal/is_leap_year.cc b/src/basic/vx_cal/is_leap_year.cc index 42cc100a76..6faeeddcaf 100644 --- a/src/basic/vx_cal/is_leap_year.cc +++ b/src/basic/vx_cal/is_leap_year.cc @@ -90,24 +90,73 @@ void increase_one_month(int &year, int &month) { //////////////////////////////////////////////////////////////////////// -unixtime add_to_unixtime(unixtime base_unixtime, - int sec_per_unit, double time_value, bool no_leap) { +#define SEC_MONTH (86400*30) +#define SEC_YEAR (86400*30*12) +#define DAY_EPSILON 0.00002 + +unixtime add_to_unixtime(unixtime base_unixtime, int sec_per_unit, + double time_value, bool no_leap) { unixtime ut; + int month, day, year, hour, minute, second; unixtime time_value_ut = (unixtime)time_value; double time_fraction = time_value - time_value_ut; - if (!no_leap || sec_per_unit != 86400) { + const char *method_name = "add_to_unixtime() -->"; + + if (sec_per_unit == SEC_MONTH || sec_per_unit == SEC_YEAR) { + if (time_value < 0) { + mlog << Error << "\n" << method_name + << " the negative offset (" << time_value + << ") is not supported for unit months and years\n\n"; + exit(-1); + } + + unix_to_mdyhms(base_unixtime, month, day, year, hour, minute, second); + + bool day_adjusted = false; + int day_org, day_offset, month_offset; + day_org = day; + if (sec_per_unit == SEC_YEAR) { + time_fraction *= 12; // 12 months/year + month_offset = (unixtime)time_fraction; + time_fraction -= month_offset; + } + else month_offset = time_value_ut; + // Add 0.00002 for the precisiton - 0.3 becomes 0.299988 + day += ((abs(time_fraction-0.5) < DAY_EPSILON)) + ? 14 : (int)((time_fraction+DAY_EPSILON) * 30); + + for (int idx=0; idx<month_offset; idx++) { + increase_one_month(year, month); + } + int max_day = monthly_days[month-1]; + if (day > max_day) { + day = max_day; + day_adjusted = true; + if (month == 2 && is_leap_year(year)) { + if (day_org == 29) day_adjusted = false; + day = 29; + } + } + ut = mdyhms_to_unix(month, day, year, hour, minute, second); + if (day_adjusted) { + mlog << Debug(2) << method_name << "adjusted day " << day_org + << " to " << day << " for " << year << "-" << month << "\n"; + } + } + else if (!no_leap || sec_per_unit != 86400) { + // seconds, minute, hours, and day unit with leap year bool use_ut = true; + // For the precision: case 1: 1.9999 to 2 + // case 2: 2.0001 to 2 + // Other cases are as floating number if ((1.0 - time_fraction) < TIME_EPSILON) time_value_ut += 1; else if (time_fraction > TIME_EPSILON) use_ut = false; if (use_ut) ut = (unixtime)(base_unixtime + sec_per_unit * time_value_ut); else ut = (unixtime)(base_unixtime + sec_per_unit * time_value); } - else { - int day_offset; - int month, day, year, hour, minute, second; - + else { // no_leap year && unit = day unix_to_mdyhms(base_unixtime, month, day, year, hour, minute, second); - day_offset = day + (int)time_value; + int day_offset = day + (int)time_value; if (day_offset < 0) { while (day_offset < 0) { decrease_one_month(year, month); @@ -125,11 +174,11 @@ unixtime add_to_unixtime(unixtime base_unixtime, ut = mdyhms_to_unix(month, day, year, hour, minute, second); if (time_fraction > (1-TIME_EPSILON) ) ut += sec_per_unit; else if (time_fraction > TIME_EPSILON) ut += (time_fraction * sec_per_unit); - mlog << Debug(5) << "add_to_unixtime() -> " - << unix_to_yyyymmdd_hhmmss(base_unixtime) - << " plus " << time_value << " days = " - << unix_to_yyyymmdd_hhmmss(ut) << "\n"; } + mlog << Debug(5) << method_name + << unix_to_yyyymmdd_hhmmss(base_unixtime) + << " plus " << time_value << " days = " + << unix_to_yyyymmdd_hhmmss(ut) << "\n"; return ut; } diff --git a/src/libcode/vx_nc_util/nc_utils.cc b/src/libcode/vx_nc_util/nc_utils.cc index dcfa3a2ea3..7975828dc2 100644 --- a/src/libcode/vx_nc_util/nc_utils.cc +++ b/src/libcode/vx_nc_util/nc_utils.cc @@ -3226,7 +3226,7 @@ unixtime get_reference_unixtime(NcVar *time_var, int &sec_per_unit, if (get_var_units(time_var, time_unit_str)) { parse_cf_time_string(time_unit_str.c_str(), ref_ut, sec_per_unit); - no_leap_year = (86400 == sec_per_unit) ? get_att_no_leap_year(time_var) : false; + no_leap_year = (sec_per_day == sec_per_unit) ? get_att_no_leap_year(time_var) : false; } else { sec_per_unit = 1; @@ -3304,7 +3304,13 @@ void parse_cf_time_string(const char *str, unixtime &ref_ut, tok.has("h")) sec_per_unit = 3600; else if(tok.has("day") || tok.has("days") || - tok.has("d")) sec_per_unit = 86400; + tok.has("d")) sec_per_unit = sec_per_day; + else if(tok.has("month") || + tok.has("months") || + tok.has("m")) sec_per_unit = sec_per_day * 30; + else if(tok.has("year") || + tok.has("years") || + tok.has("y")) sec_per_unit = sec_per_day * 30 * 12; else { mlog << Warning << "\n" << method_name << "Unsupported time step in the CF convention time unit \"" From a8ca8a5e462b0427161f315fae7d3cdbec0303c2 Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Fri, 7 Oct 2022 15:52:49 -0600 Subject: [PATCH 08/11] #2155 SonarQube: to avoid a finding --- src/tools/other/mode_time_domain/mm_engine.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/other/mode_time_domain/mm_engine.cc b/src/tools/other/mode_time_domain/mm_engine.cc index 820594c8ce..f114544f56 100644 --- a/src/tools/other/mode_time_domain/mm_engine.cc +++ b/src/tools/other/mode_time_domain/mm_engine.cc @@ -268,8 +268,7 @@ if ( mlog.verbosity_level() > 5 ) { s << "Composites ...\n"; - int tmp_len = comp_to_eq.n(); - for (j=0; j<tmp_len; ++j) { + for (j=0; j<index_list.n(); ++j) { s << ' ' << comp_to_eq[j]; From d10bff5e18d1051c09d18628c0217bc8d95e7b6c Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Wed, 12 Oct 2022 11:01:45 -0600 Subject: [PATCH 09/11] #2155Added months and years units --- docs/Users_Guide/data_io.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Users_Guide/data_io.rst b/docs/Users_Guide/data_io.rst index 6c05461f43..395b66a96d 100644 --- a/docs/Users_Guide/data_io.rst +++ b/docs/Users_Guide/data_io.rst @@ -109,6 +109,8 @@ MET gets the valid time from the time variable and the "forecast_reference_time" "minutes since YYYY-MM-DD HH:MM:SS", "hours since YYYY-MM-DD HH:MM:SS", "days since YYYY-MM-DD HH:MM:SS", + "months since YYYY-MM-DD HH:MM:SS", + "years since YYYY-MM-DD HH:MM:SS", Accepts "Y", "YY", "YYY", "M", "D", "HH", and "HH:MM". "HH:MM:SS" is optional - "degrees_north", From 1b1102ec7d0638c849a3d3813aa4f838351ae43f Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Wed, 12 Oct 2022 11:02:26 -0600 Subject: [PATCH 10/11] #2155 Added unit test for months and years units --- internal/test_unit/xml/unit_netcdf.xml | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/internal/test_unit/xml/unit_netcdf.xml b/internal/test_unit/xml/unit_netcdf.xml index 5c0b255240..a6e98311a9 100644 --- a/internal/test_unit/xml/unit_netcdf.xml +++ b/internal/test_unit/xml/unit_netcdf.xml @@ -111,4 +111,60 @@ </output> </test> + <test name="netcdf_months_units"> + <exec>&MET_BIN;/regrid_data_plane</exec> + <param> \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_month_376p5.nc \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_month_376p5.nc \ + &OUTPUT_DIR;/netcdf/regrid_data_plane_months_units.nc \ + -field 'name="t_an"; level="(0,0,*,*)";' \ + -v 1 + </param> + <output> + <grid_nc>&OUTPUT_DIR;/netcdf/regrid_data_plane_months_units.nc</grid_nc> + </output> + </test> + + <test name="netcdf_months_units_from_day2"> + <exec>&MET_BIN;/regrid_data_plane</exec> + <param> \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_month_376p5_day2.nc \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_month_376p5_day2.nc \ + &OUTPUT_DIR;/netcdf/regrid_data_plane_months_units_day2.nc \ + -field 'name="t_an"; level="(0,0,*,*)";' \ + -v 1 + </param> + <output> + <grid_nc>&OUTPUT_DIR;/netcdf/regrid_data_plane_months_units_day2.nc</grid_nc> + </output> + </test> + + <test name="netcdf_months_units_to_next_month"> + <exec>&MET_BIN;/regrid_data_plane</exec> + <param> \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_month_d25_3p66.nc \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_month_d25_3p66.nc\ + &OUTPUT_DIR;/netcdf/regrid_data_plane_months_units_to_next_month.nc \ + -field 'name="t_an"; level="(0,0,*,*)";' \ + -v 1 + </param> + <output> + <grid_nc>&OUTPUT_DIR;/netcdf/regrid_data_plane_months_units_to_next_month.nc</grid_nc> + </output> + </test> + + <test name="netcdf_years_units"> + <exec>&MET_BIN;/regrid_data_plane</exec> + <param> \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_year_3p66.nc \ + &DATA_DIR_MODEL;/nccf/woa18_decav_t05_04_small_year_3p66.nc \ + &OUTPUT_DIR;/netcdf/regrid_data_plane_years_units.nc \ + -field 'name="t_an"; level="(0,0,*,*)";' \ + -v 1 + </param> + <output> + <grid_nc>&OUTPUT_DIR;/netcdf/regrid_data_plane_years_units.nc</grid_nc> + </output> + </test> + </met_test> From 21db2102975a9f9912685d1491539c8496080546 Mon Sep 17 00:00:00 2001 From: Howard Soh <hsoh@seneca.rap.ucar.edu> Date: Wed, 12 Oct 2022 11:05:42 -0600 Subject: [PATCH 11/11] #2155 months and years units are proessed differently when the start day is the first of ythe month --- src/basic/vx_cal/is_leap_year.cc | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/basic/vx_cal/is_leap_year.cc b/src/basic/vx_cal/is_leap_year.cc index 6faeeddcaf..efc5f66f05 100644 --- a/src/basic/vx_cal/is_leap_year.cc +++ b/src/basic/vx_cal/is_leap_year.cc @@ -112,22 +112,40 @@ unixtime add_to_unixtime(unixtime base_unixtime, int sec_per_unit, unix_to_mdyhms(base_unixtime, month, day, year, hour, minute, second); - bool day_adjusted = false; - int day_org, day_offset, month_offset; - day_org = day; + int month_offset; + double day_offset; if (sec_per_unit == SEC_YEAR) { - time_fraction *= 12; // 12 months/year + year += time_value_ut; + time_fraction *= 12; // 12 months/year month_offset = (unixtime)time_fraction; time_fraction -= month_offset; } else month_offset = time_value_ut; - // Add 0.00002 for the precisiton - 0.3 becomes 0.299988 - day += ((abs(time_fraction-0.5) < DAY_EPSILON)) - ? 14 : (int)((time_fraction+DAY_EPSILON) * 30); for (int idx=0; idx<month_offset; idx++) { increase_one_month(year, month); } + if (day == 1) { + if (abs(time_fraction-0.5) < DAY_EPSILON) day = 15; + else { + day_offset = time_fraction * 30; + day += (int)day_offset; + if (day_offset - (int)day_offset > 0.5) day++; + } + } + else { + day_offset = time_fraction * 30; + time_value_ut = (int)day_offset; + day += time_value_ut; + if (day_offset - time_value_ut > 0.5) day++; + if (day > 30) { + day -= 30; + increase_one_month(year, month); + } + } + + int day_org = day; + bool day_adjusted = false; int max_day = monthly_days[month-1]; if (day > max_day) { day = max_day;