Convert 360-days or no-leap calendar to standard Gregorian calendar. More...
#include <utils.h>
Go to the source code of this file.
Functions | |
int | data_to_gregorian_cal_d (double **bufout, double **outtimeval, int *ntimeout, double *bufin, double *intimeval, char *tunits_in, char *tunits_out, char *cal_type, int ni, int nj, int ntimein) |
Convert 360-days or no-leap calendar to standard Gregorian calendar for double input/output buffer. | |
int | data_to_gregorian_cal_f (float **bufout, double **outtimeval, int *ntimeout, float *bufin, double *intimeval, char *tunits_in, char *tunits_out, char *cal_type, int ni, int nj, int ntimein) |
Convert 360-days or no-leap calendar to standard Gregorian calendar for float input/output buffer. |
Convert 360-days or no-leap calendar to standard Gregorian calendar.
Definition in file data_to_gregorian_cal.c.
int data_to_gregorian_cal_d | ( | double ** | bufout, | |
double ** | outtimeval, | |||
int * | ntimeout, | |||
double * | bufin, | |||
double * | intimeval, | |||
char * | tunits_in, | |||
char * | tunits_out, | |||
char * | cal_type, | |||
int | ni, | |||
int | nj, | |||
int | ntimein | |||
) |
Convert 360-days or no-leap calendar to standard Gregorian calendar for double input/output buffer.
[out] | bufout | Output 3D buffer which have been adjusted to standard Gregorian Calendar |
[out] | outtimeval | Output new time vector adjusted to standard Gregorian Calendar |
[out] | ntimeout | Number of times in new output 3D buffer |
[in] | bufin | Input 3D buffer with non-standard calendar |
[in] | intimeval | Input time vector with non-standard calendar |
[in] | tunits_in | Input time units with non-standard calendar |
[out] | tunits_out | Output time units |
[in] | cal_type | Input calendar type (non-standard calendar) |
[in] | ni | First dimension length |
[in] | nj | Second dimension length |
[in] | ntimein | Input time dimension length with non-standard calendar |
Just recopy the data when calendar type is standard or gregorian
Non-standard calendar type
Definition at line 69 of file data_to_gregorian_cal.c.
References alloc_error().
Referenced by main(), and read_large_scale_fields().
00070 { 00085 ut_unit *timeslice; /* Time slicing used to compute the new standard calendar */ 00086 double val; /* Temporary value */ 00087 double curtime; /* Current time */ 00088 double ccurtime; /* Current time in non-standard calendar */ 00089 00090 int ref_year; /* A given year */ 00091 int ref_month; /* A given month */ 00092 int ref_day; /* A given day */ 00093 int ref_hour; /* A given hour */ 00094 int ref_minutes; /* A given minute */ 00095 float ref_seconds; /* A given second */ 00096 00097 int t; /* Time loop counter */ 00098 int tt; /* Time loop counter */ 00099 int i; /* Loop counter */ 00100 int j; /* Loop counter */ 00101 int istat; /* Diagnostic status */ 00102 00103 char *utstring = NULL; /* Time unit string */ 00104 ut_system *unitSystem = NULL; /* Unit System (udunits) */ 00105 ut_unit *dataunit_in = NULL; /* Input data units (udunits) */ 00106 ut_unit *dataunit_out = NULL; /* Output data units (udunits) */ 00107 cv_converter *conv_in = NULL; /* Converter for time units (udunits) */ 00108 ut_unit *tunit = NULL; /* For calculation of offset by time to Epoch */ 00109 ut_unit *usecond = NULL; /* Unit of second handle */ 00110 double sec_int, sec_intm1; /* Number of seconds since Epoch */ 00111 00112 int *year = NULL; /* Year time vector */ 00113 int *month = NULL; /* Month time vector */ 00114 int *day = NULL; /* Day time vector */ 00115 int *hour = NULL; /* Hour time vector */ 00116 int *minutes = NULL; /* Minutes time vector */ 00117 double *seconds = NULL; /* Seconds time vector */ 00118 00119 int cyear; /* A given year */ 00120 int cmonth; /* A given month */ 00121 int cday; /* A given day */ 00122 int chour; /* A given hour */ 00123 int cminutes; /* A given minute */ 00124 double cseconds; /* A given second */ 00125 00126 int sup = 0; /* To indicate supplemental duplicated timestep for end of period out of weird calendars like 360_day */ 00127 00128 /* Initializing */ 00129 *bufout = NULL; 00130 *outtimeval = NULL; 00131 *ntimeout = 0; 00132 00134 if ( !strcmp(cal_type, "standard") || !strcmp(cal_type, "gregorian") ) { 00135 *ntimeout = ntimein; 00136 /* Allocate memory */ 00137 (*bufout) = (double *) malloc(ni*nj*(*ntimeout) * sizeof(double)); 00138 if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__); 00139 (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double)); 00140 if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__); 00141 00142 /* Loop over all times and gridpoints */ 00143 for (t=0; t<(*ntimeout); t++) { 00144 for (j=0; j<nj; j++) 00145 for (i=0; i<ni; i++) 00146 /* Get value */ 00147 (*bufout)[i+j*ni+t*ni*nj] = (double) bufin[i+j*ni+t*ni*nj]; 00148 /* Construct time vector */ 00149 (*outtimeval)[t] = (double) intimeval[t]; 00150 } 00151 } 00152 else { 00155 /* Allocate memory */ 00156 year = (int *) malloc(ntimein * sizeof(int)); 00157 if (year == NULL) alloc_error(__FILE__, __LINE__); 00158 month = (int *) malloc(ntimein * sizeof(int)); 00159 if (month == NULL) alloc_error(__FILE__, __LINE__); 00160 day = (int *) malloc(ntimein * sizeof(int)); 00161 if (day == NULL) alloc_error(__FILE__, __LINE__); 00162 hour = (int *) malloc(ntimein * sizeof(int)); 00163 if (hour == NULL) alloc_error(__FILE__, __LINE__); 00164 minutes = (int *) malloc(ntimein * sizeof(int)); 00165 if (minutes == NULL) alloc_error(__FILE__, __LINE__); 00166 seconds = (double *) malloc(ntimein * sizeof(double)); 00167 if (seconds == NULL) alloc_error(__FILE__, __LINE__); 00168 00169 /* Initialize udunits */ 00170 ut_set_error_message_handler(ut_ignore); 00171 unitSystem = ut_read_xml(NULL); 00172 ut_set_error_message_handler(ut_write_to_stderr); 00173 00174 /* Generate time units strings */ 00175 dataunit_in = ut_parse(unitSystem, tunits_in, UT_ASCII); 00176 dataunit_out = ut_parse(unitSystem, tunits_out, UT_ASCII); 00177 00178 /* Loop over all times */ 00179 for (t=0; t<ntimein; t++) { 00180 /* Calculate date using non-standard calendar */ 00181 istat = utCalendar2_cal(intimeval[t], dataunit_in, &(year[t]), &(month[t]), &(day[t]), &(hour[t]), &(minutes[t]), &(seconds[t]), 00182 cal_type); 00183 if (istat < 0) { 00184 (void) free(year); 00185 (void) free(month); 00186 (void) free(day); 00187 (void) free(hour); 00188 (void) free(minutes); 00189 (void) free(seconds); 00190 (void) ut_free(dataunit_in); 00191 (void) ut_free(dataunit_out); 00192 (void) ut_free_system(unitSystem); 00193 return -1; 00194 } 00195 #if DEBUG > 7 00196 istat = utInvCalendar2_cal((year[t]), (month[t]), (day[t]), (hour[t]), (minutes[t]), (seconds[t]), dataunit_in, &ccurtime, cal_type); 00197 printf("%s: %d %lf %lf %d %d %d %d %d %lf\n",__FILE__,t,intimeval[t],ccurtime,year[t],month[t],day[t],hour[t],minutes[t],seconds[t]); 00198 if (istat < 0) { 00199 (void) free(year); 00200 (void) free(month); 00201 (void) free(day); 00202 (void) free(hour); 00203 (void) free(minutes); 00204 (void) free(seconds); 00205 (void) ut_free(dataunit_in); 00206 (void) ut_free(dataunit_out); 00207 (void) ut_free_system(unitSystem); 00208 return -1; 00209 } 00210 #endif 00211 /* Check that we really have daily data */ 00212 if (t > 0) { 00213 /* Prepare converter for basis seconds since Epoch */ 00214 usecond = ut_get_unit_by_name(unitSystem, "second"); 00215 tunit = ut_offset_by_time(usecond, ut_encode_time(1970, 1, 1, 0, 0, 0.0)); 00216 /* Generate converter */ 00217 conv_in = ut_get_converter(dataunit_in, tunit); 00218 /* Seconds since Epoch */ 00219 sec_int = cv_convert_double(conv_in, intimeval[t]); 00220 sec_intm1 = cv_convert_double(conv_in, intimeval[t-1]); 00221 if ( (sec_int - sec_intm1) != 86400.0 ) { 00222 (void) fprintf(stderr, 00223 "%s: Fatal error: only daily data can be an input. Found %d seconds between timesteps %d and %d!\n", 00224 __FILE__, (int) (sec_int - sec_intm1), t-1, t); 00225 (void) free(year); 00226 (void) free(month); 00227 (void) free(day); 00228 (void) free(hour); 00229 (void) free(minutes); 00230 (void) free(seconds); 00231 (void) ut_free(usecond); 00232 (void) ut_free(tunit); 00233 (void) ut_free(usecond); 00234 (void) ut_free(dataunit_in); 00235 (void) ut_free(dataunit_out); 00236 (void) cv_free(conv_in); 00237 (void) ut_free_system(unitSystem); 00238 return -10; 00239 } 00240 } 00241 } 00242 00243 /* For noleap/365-day or 360-day calendar types */ 00244 if ( !strcmp(cal_type, "noleap") || !strcmp(cal_type, "365_day") || !strcmp(cal_type, "360_day") ) { 00245 00246 /* Compute the new output total timesteps (days) in a standard year */ 00247 /* 00248 * NB: The following specification gives both 00249 * the start time and the sampling interval (1 day). 00250 */ 00251 00252 /* Set 1 day as a timestep to compute number of days in standard calendar */ 00253 utstring = (char *) malloc(1000 * sizeof(char)); 00254 if (utstring == NULL) alloc_error(__FILE__, __LINE__); 00255 (void) sprintf(utstring, "1 day since %d-%d-%d", year[0], month[0], day[0]); 00256 timeslice = ut_parse(unitSystem, utstring, UT_ASCII); 00257 (void) free(utstring); 00258 00259 /* Set end period date */ 00260 ref_year = year[ntimein-1]; 00261 ref_month = month[ntimein-1]; 00262 ref_day = day[ntimein-1]; 00263 /* End Dec 31st and not Dec 30th... for 360-days calendar */ 00264 if (!strcmp(cal_type, "360_day") && 00265 (ref_month == 1 || ref_month == 3 || ref_month == 5 || ref_month == 7 || ref_month == 8 || ref_month == 10 || ref_month == 12) 00266 && ref_day == 30) { 00267 ref_day = 31; 00268 sup = 1; 00269 } 00270 ref_hour = hour[ntimein-1]; 00271 ref_minutes = 0; 00272 ref_seconds = 0.0; 00273 00274 /* Get number of timesteps (days) */ 00275 istat = utInvCalendar2(ref_year, ref_month, ref_day, ref_hour, ref_minutes, ref_seconds, timeslice, &val); 00276 *ntimeout = (int) val + 1; 00277 00278 /* Allocate memory */ 00279 (*bufout) = (double *) malloc(ni*nj*(*ntimeout) * sizeof(double)); 00280 if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__); 00281 (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double)); 00282 if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__); 00283 00284 /* Set start period date */ 00285 ref_year = year[0]; 00286 ref_month = month[0]; 00287 ref_day = day[0]; 00288 ref_hour = hour[0]; 00289 ref_minutes = 0; 00290 ref_seconds = 0.0; 00291 00292 /* Loop over all times */ 00293 for (t=0; t<(*ntimeout); t++) { 00294 /* Get current day */ 00295 istat = utInvCalendar2(ref_year, ref_month, ref_day+t, ref_hour, ref_minutes, ref_seconds, dataunit_out, &curtime); 00296 /* Get standard calendar date from output time units */ 00297 istat = utCalendar2(curtime, dataunit_out, &cyear, &cmonth, &cday, &chour, &cminutes, &cseconds); 00298 /* Get corresponding time units in special calendar type */ 00299 istat = utInvCalendar2_cal(cyear, cmonth, cday, chour, cminutes, cseconds, dataunit_in, &ccurtime, cal_type); 00300 /* Find that time in the input time vector */ 00301 for (tt=0; tt<ntimein; tt++) { 00302 if ((int) ccurtime == (int) intimeval[tt]) { 00303 /* Found it */ 00304 for (j=0; j<nj; j++) 00305 for (i=0; i<ni; i++) 00306 (*bufout)[i+j*ni+t*ni*nj] = (double) bufin[i+j*ni+tt*ni*nj]; 00307 /* Get current day with hour, minutes and seconds at 00:00:00 */ 00308 istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime); 00309 /* Construct new time vector */ 00310 (*outtimeval)[t] = (double) curtime; 00311 /* Exit loop */ 00312 tt = ntimein+10; 00313 } 00314 } 00315 if ( (sup == 1) && (tt < (ntimein+10)) ) { 00316 /* Copy it */ 00317 for (j=0; j<nj; j++) 00318 for (i=0; i<ni; i++) 00319 (*bufout)[i+j*ni+t*ni*nj] = (double) bufin[i+j*ni+(ntimein-1)*ni*nj]; 00320 /* Get current day with hour, minutes and seconds at 00:00:00 */ 00321 istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime); 00322 /* Construct new time vector */ 00323 (*outtimeval)[t] = (double) curtime; 00324 tt = ntimein+10; 00325 } 00326 if (tt < (ntimein+10)) { 00327 /* We didn't found the time in the input time vector... */ 00328 (void) fprintf(stderr, "%s: Cannot generate new time vector!! Algorithm internal error!\n", __FILE__); 00329 (void) free(year); 00330 (void) free(month); 00331 (void) free(day); 00332 (void) free(hour); 00333 (void) free(minutes); 00334 (void) free(seconds); 00335 (void) ut_free(timeslice); 00336 (void) ut_free(dataunit_in); 00337 (void) ut_free(dataunit_out); 00338 (void) ut_free_system(unitSystem); 00339 return -11; 00340 } 00341 } 00342 } 00343 else { 00344 /* Non-supported calendar */ 00345 (void) fprintf(stderr, "%s: not-supported calendar. Sorry!\n", __FILE__); 00346 (void) free(year); 00347 (void) free(month); 00348 (void) free(day); 00349 (void) free(hour); 00350 (void) free(minutes); 00351 (void) free(seconds); 00352 (void) ut_free(dataunit_in); 00353 (void) ut_free(dataunit_out); 00354 (void) ut_free_system(unitSystem); 00355 return -1; 00356 } 00357 00358 /* Free memory */ 00359 (void) free(year); 00360 (void) free(month); 00361 (void) free(day); 00362 (void) free(hour); 00363 (void) free(minutes); 00364 (void) free(seconds); 00365 00366 /* Terminate udunits */ 00367 (void) ut_free(dataunit_in); 00368 (void) ut_free(dataunit_out); 00369 (void) ut_free_system(unitSystem); 00370 } 00371 00372 /* Success status */ 00373 return 0; 00374 }
int data_to_gregorian_cal_f | ( | float ** | bufout, | |
double ** | outtimeval, | |||
int * | ntimeout, | |||
float * | bufin, | |||
double * | intimeval, | |||
char * | tunits_in, | |||
char * | tunits_out, | |||
char * | cal_type, | |||
int | ni, | |||
int | nj, | |||
int | ntimein | |||
) |
Convert 360-days or no-leap calendar to standard Gregorian calendar for float input/output buffer.
[out] | bufout | Output 3D buffer which have been adjusted to standard Gregorian Calendar |
[out] | outtimeval | Output new time vector adjusted to standard Gregorian Calendar |
[out] | ntimeout | Number of times in new output 3D buffer |
[in] | bufin | Input 3D buffer with non-standard calendar |
[in] | intimeval | Input time vector with non-standard calendar |
[in] | tunits_in | Input time units with non-standard calendar |
[out] | tunits_out | Output time units |
[in] | cal_type | Input calendar type (non-standard calendar) |
[in] | ni | First dimension length |
[in] | nj | Second dimension length |
[in] | ntimein | Input time dimension length with non-standard calendar |
Just recopy the data when calendar type is standard or gregorian
Non-standard calendar type
Definition at line 378 of file data_to_gregorian_cal.c.
References alloc_error().
Referenced by main().
00379 { 00394 ut_unit *timeslice; /* Time slicing used to compute the new standard calendar */ 00395 double val; /* Temporary value */ 00396 double curtime; /* Current time */ 00397 double ccurtime; /* Current time in non-standard calendar */ 00398 00399 int ref_year; /* A given year */ 00400 int ref_month; /* A given month */ 00401 int ref_day; /* A given day */ 00402 int ref_hour; /* A given hour */ 00403 int ref_minutes; /* A given minute */ 00404 double ref_seconds; /* A given second */ 00405 00406 int t; /* Time loop counter */ 00407 int tt; /* Time loop counter */ 00408 int i; /* Loop counter */ 00409 int j; /* Loop counter */ 00410 int istat; /* Diagnostic status */ 00411 00412 char *utstring = NULL; /* Time unit string */ 00413 ut_system *unitSystem = NULL; /* Unit System (udunits) */ 00414 ut_unit *dataunit_in = NULL; /* Input data units (udunits) */ 00415 ut_unit *dataunit_out = NULL; /* Output data units (udunits) */ 00416 cv_converter *conv_in = NULL; /* Converter for time units (udunits) */ 00417 ut_unit *tunit = NULL; /* For calculation of offset by time to Epoch */ 00418 ut_unit *usecond = NULL; /* Unit of second handle */ 00419 double sec_int, sec_intm1; /* Number of seconds since Epoch */ 00420 00421 int *year = NULL; /* Year time vector */ 00422 int *month = NULL; /* Month time vector */ 00423 int *day = NULL; /* Day time vector */ 00424 int *hour = NULL; /* Hour time vector */ 00425 int *minutes = NULL; /* Minutes time vector */ 00426 double *seconds = NULL; /* Seconds time vector */ 00427 00428 int cyear; /* A given year */ 00429 int cmonth; /* A given month */ 00430 int cday; /* A given day */ 00431 int chour; /* A given hour */ 00432 int cminutes; /* A given minute */ 00433 double cseconds; /* A given second */ 00434 00435 int sup = 0; /* To indicate supplemental duplicated timestep for end of period out of weird calendars like 360_day */ 00436 00437 /* Initializing */ 00438 *bufout = NULL; 00439 *outtimeval = NULL; 00440 *ntimeout = 0; 00441 00443 if ( !strcmp(cal_type, "standard") || !strcmp(cal_type, "gregorian") ) { 00444 *ntimeout = ntimein; 00445 /* Allocate memory */ 00446 (*bufout) = (float *) malloc(ni*nj*(*ntimeout) * sizeof(float)); 00447 if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__); 00448 (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double)); 00449 if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__); 00450 00451 /* Loop over all times and gridpoints */ 00452 for (t=0; t<(*ntimeout); t++) { 00453 for (j=0; j<nj; j++) 00454 for (i=0; i<ni; i++) 00455 /* Get value */ 00456 (*bufout)[i+j*ni+t*ni*nj] = (float) bufin[i+j*ni+t*ni*nj]; 00457 /* Construct time vector */ 00458 (*outtimeval)[t] = (double) intimeval[t]; 00459 } 00460 } 00461 else { 00464 /* Allocate memory */ 00465 year = (int *) malloc(ntimein * sizeof(int)); 00466 if (year == NULL) alloc_error(__FILE__, __LINE__); 00467 month = (int *) malloc(ntimein * sizeof(int)); 00468 if (month == NULL) alloc_error(__FILE__, __LINE__); 00469 day = (int *) malloc(ntimein * sizeof(int)); 00470 if (day == NULL) alloc_error(__FILE__, __LINE__); 00471 hour = (int *) malloc(ntimein * sizeof(int)); 00472 if (hour == NULL) alloc_error(__FILE__, __LINE__); 00473 minutes = (int *) malloc(ntimein * sizeof(int)); 00474 if (minutes == NULL) alloc_error(__FILE__, __LINE__); 00475 seconds = (double *) malloc(ntimein * sizeof(double)); 00476 if (seconds == NULL) alloc_error(__FILE__, __LINE__); 00477 00478 /* Initialize udunits */ 00479 ut_set_error_message_handler(ut_ignore); 00480 unitSystem = ut_read_xml(NULL); 00481 ut_set_error_message_handler(ut_write_to_stderr); 00482 00483 /* Generate time units strings */ 00484 dataunit_in = ut_parse(unitSystem, tunits_in, UT_ASCII); 00485 dataunit_out = ut_parse(unitSystem, tunits_out, UT_ASCII); 00486 00487 /* Loop over all times */ 00488 for (t=0; t<ntimein; t++) { 00489 /* Calculate date using non-standard calendar */ 00490 istat = utCalendar2_cal(intimeval[t], dataunit_in, &(year[t]), &(month[t]), &(day[t]), &(hour[t]), &(minutes[t]), &(seconds[t]), 00491 cal_type); 00492 if (istat < 0) { 00493 (void) free(year); 00494 (void) free(month); 00495 (void) free(day); 00496 (void) free(hour); 00497 (void) free(minutes); 00498 (void) free(seconds); 00499 (void) ut_free(dataunit_in); 00500 (void) ut_free(dataunit_out); 00501 (void) ut_free_system(unitSystem); 00502 return -1; 00503 } 00504 #if DEBUG > 7 00505 istat = utInvCalendar2_cal((year[t]), (month[t]), (day[t]), (hour[t]), (minutes[t]), (seconds[t]), dataunit_in, &ccurtime, cal_type); 00506 printf("%s: %d %lf %lf %d %d %d %d %d %lf\n",__FILE__,t,intimeval[t],ccurtime,year[t],month[t],day[t],hour[t],minutes[t],seconds[t]); 00507 if (istat < 0) { 00508 (void) free(year); 00509 (void) free(month); 00510 (void) free(day); 00511 (void) free(hour); 00512 (void) free(minutes); 00513 (void) free(seconds); 00514 (void) ut_free(dataunit_in); 00515 (void) ut_free(dataunit_out); 00516 (void) ut_free_system(unitSystem); 00517 return -1; 00518 } 00519 #endif 00520 /* Check that we really have daily data */ 00521 if (t > 0) { 00522 /* Prepare converter for basis seconds since Epoch */ 00523 usecond = ut_get_unit_by_name(unitSystem, "second"); 00524 tunit = ut_offset_by_time(usecond, ut_encode_time(1970, 1, 1, 0, 0, 0.0)); 00525 /* Generate converter */ 00526 conv_in = ut_get_converter(dataunit_in, tunit); 00527 /* Seconds since Epoch */ 00528 sec_int = cv_convert_double(conv_in, intimeval[t]); 00529 sec_intm1 = cv_convert_double(conv_in, intimeval[t-1]); 00530 if ( (sec_int - sec_intm1) != 86400.0 ) { 00531 (void) fprintf(stderr, 00532 "%s: Fatal error: only daily data can be an input. Found %d seconds between timesteps %d and %d!\n", 00533 __FILE__, (int) (sec_int - sec_intm1), t-1, t); 00534 (void) free(year); 00535 (void) free(month); 00536 (void) free(day); 00537 (void) free(hour); 00538 (void) free(minutes); 00539 (void) free(seconds); 00540 (void) ut_free(usecond); 00541 (void) ut_free(tunit); 00542 (void) ut_free(usecond); 00543 (void) ut_free(dataunit_in); 00544 (void) ut_free(dataunit_out); 00545 (void) cv_free(conv_in); 00546 (void) ut_free_system(unitSystem); 00547 return -10; 00548 } 00549 } 00550 } 00551 00552 /* For noleap/365-day or 360-day calendar types */ 00553 if ( !strcmp(cal_type, "noleap") || !strcmp(cal_type, "365_day") || !strcmp(cal_type, "360_day") ) { 00554 00555 /* Compute the new output total timesteps (days) in a standard year */ 00556 /* 00557 * NB: The following specification gives both 00558 * the start time and the sampling interval (1 day). 00559 */ 00560 00561 /* Set 1 day as a timestep to compute number of days in standard calendar */ 00562 utstring = (char *) malloc(1000 * sizeof(char)); 00563 if (utstring == NULL) alloc_error(__FILE__, __LINE__); 00564 (void) sprintf(utstring, "1 day since %d-%d-%d", year[0], month[0], day[0]); 00565 timeslice = ut_parse(unitSystem, utstring, UT_ASCII); 00566 (void) free(utstring); 00567 00568 /* Set end period date */ 00569 ref_year = year[ntimein-1]; 00570 ref_month = month[ntimein-1]; 00571 ref_day = day[ntimein-1]; 00572 /* End Dec 31st and not Dec 30th... for 360-days calendar */ 00573 if (!strcmp(cal_type, "360_day") && 00574 (ref_month == 1 || ref_month == 3 || ref_month == 5 || ref_month == 7 || ref_month == 8 || ref_month == 10 || ref_month == 12) 00575 && ref_day == 30) { 00576 ref_day = 31; 00577 sup = 1; 00578 } 00579 ref_hour = hour[ntimein-1]; 00580 ref_minutes = 0; 00581 ref_seconds = 0.0; 00582 00583 /* Get number of timesteps (days) */ 00584 istat = utInvCalendar2(ref_year, ref_month, ref_day, ref_hour, ref_minutes, ref_seconds, timeslice, &val); 00585 *ntimeout = (int) val + 1; 00586 00587 /* Allocate memory */ 00588 (*bufout) = (float *) malloc(ni*nj*(*ntimeout) * sizeof(float)); 00589 if ( (*bufout) == NULL) alloc_error(__FILE__, __LINE__); 00590 (*outtimeval) = (double *) malloc((*ntimeout) * sizeof(double)); 00591 if ( (*outtimeval) == NULL) alloc_error(__FILE__, __LINE__); 00592 00593 /* Set start period date */ 00594 ref_year = year[0]; 00595 ref_month = month[0]; 00596 ref_day = day[0]; 00597 ref_hour = hour[0]; 00598 ref_minutes = 0; 00599 ref_seconds = 0.0; 00600 00601 /* Loop over all times */ 00602 for (t=0; t<(*ntimeout); t++) { 00603 /* Get current day */ 00604 istat = utInvCalendar2(ref_year, ref_month, ref_day+t, ref_hour, ref_minutes, ref_seconds, dataunit_out, &curtime); 00605 /* Get standard calendar date from output time units */ 00606 istat = utCalendar2(curtime, dataunit_out, &cyear, &cmonth, &cday, &chour, &cminutes, &cseconds); 00607 /* Get corresponding time units in special calendar type */ 00608 istat = utInvCalendar2_cal(cyear, cmonth, cday, chour, cminutes, cseconds, dataunit_in, &ccurtime, cal_type); 00609 /* Find that time in the input time vector */ 00610 for (tt=0; tt<ntimein; tt++) { 00611 if ((int) ccurtime == (int) intimeval[tt]) { 00612 /* Found it */ 00613 for (j=0; j<nj; j++) 00614 for (i=0; i<ni; i++) 00615 (*bufout)[i+j*ni+t*ni*nj] = (float) bufin[i+j*ni+tt*ni*nj]; 00616 /* Get current day with hour, minutes and seconds at 00:00:00 */ 00617 istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime); 00618 /* Construct new time vector */ 00619 (*outtimeval)[t] = (double) curtime; 00620 /* Exit loop */ 00621 tt = ntimein+10; 00622 } 00623 } 00624 if ( (sup == 1) && (tt < (ntimein+10)) ) { 00625 /* Copy it */ 00626 for (j=0; j<nj; j++) 00627 for (i=0; i<ni; i++) 00628 (*bufout)[i+j*ni+t*ni*nj] = (float) bufin[i+j*ni+(ntimein-1)*ni*nj]; 00629 /* Get current day with hour, minutes and seconds at 00:00:00 */ 00630 istat = utInvCalendar2(ref_year, ref_month, ref_day+t, 0, 0, 0.0, dataunit_out, &curtime); 00631 /* Construct new time vector */ 00632 (*outtimeval)[t] = (double) curtime; 00633 tt = ntimein+10; 00634 } 00635 if (tt < (ntimein+10)) { 00636 /* We didn't found the time in the input time vector... */ 00637 (void) fprintf(stderr, "%s: Cannot generate new time vector!! Algorithm internal error!\n", __FILE__); 00638 (void) free(year); 00639 (void) free(month); 00640 (void) free(day); 00641 (void) free(hour); 00642 (void) free(minutes); 00643 (void) free(seconds); 00644 (void) ut_free(timeslice); 00645 (void) ut_free(dataunit_in); 00646 (void) ut_free(dataunit_out); 00647 (void) ut_free_system(unitSystem); 00648 return -11; 00649 } 00650 } 00651 } 00652 else { 00653 /* Non-supported calendar */ 00654 (void) fprintf(stderr, "%s: not-supported calendar. Sorry!\n", __FILE__); 00655 (void) free(year); 00656 (void) free(month); 00657 (void) free(day); 00658 (void) free(hour); 00659 (void) free(minutes); 00660 (void) free(seconds); 00661 (void) ut_free(dataunit_in); 00662 (void) ut_free(dataunit_out); 00663 (void) ut_free_system(unitSystem); 00664 return -1; 00665 } 00666 00667 /* Free memory */ 00668 (void) free(year); 00669 (void) free(month); 00670 (void) free(day); 00671 (void) free(hour); 00672 (void) free(minutes); 00673 (void) free(seconds); 00674 00675 /* Terminate udunits */ 00676 (void) ut_free(dataunit_in); 00677 (void) ut_free(dataunit_out); 00678 (void) ut_free_system(unitSystem); 00679 } 00680 00681 /* Success status */ 00682 return 0; 00683 }