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 2155 time units months and years #2300

Merged
merged 11 commits into from
Oct 18, 2022
2 changes: 2 additions & 0 deletions docs/Users_Guide/data_io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
56 changes: 56 additions & 0 deletions internal/test_unit/xml/unit_netcdf.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
91 changes: 79 additions & 12 deletions src/basic/vx_cal/is_leap_year.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,91 @@ 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);

int month_offset;
double day_offset;
if (sec_per_unit == SEC_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;

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;
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);
Expand All @@ -125,11 +192,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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/basic/vx_util/data_line.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion src/libcode/vx_data2d_nc_met/get_met_grid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/libcode/vx_nc_util/grid_output.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions src/libcode/vx_nc_util/nc_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 \""
Expand Down
12 changes: 7 additions & 5 deletions src/libcode/vx_seeps/seeps.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/tools/core/point_stat/point_stat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading