data_to_gregorian_cal.c File Reference

Convert 360-days or no-leap calendar to standard Gregorian calendar. More...

#include <utils.h>
Include dependency graph for data_to_gregorian_cal.c:

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.

Detailed Description

Convert 360-days or no-leap calendar to standard Gregorian calendar.

Definition in file data_to_gregorian_cal.c.


Function Documentation

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.

Parameters:
[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.

Parameters:
[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 }


Generated on 12 May 2016 for DSCLIM by  doxygen 1.6.1