/* Return value expressed in hours. */ static double cdToHours(double value, cdUnitTime unit){ double result = 0; switch(unit){ case cdSecond: result = value/3600.0; break; case cdMinute: result = value/60.0; break; case cdHour: result = value; break; case cdDay: result = 24.0 * value; break; case cdWeek: result = 168.0 * value; break; default: cdError("invalid unit in conversion"); break; } return result; }
/* Map to old timetypes */ int cdToOldTimetype(cdCalenType newtype, CdTimeType* oldtype) { switch(newtype){ case cdStandard: *oldtype = CdChron; break; case cdJulian: *oldtype = CdJulianCal; break; case cdNoLeap: *oldtype = CdChronNoLeap; break; case cd360: *oldtype = CdChron360; break; case cd366: *oldtype = CdChron366; break; case cdClim: *oldtype = CdClim; break; case cdClimLeap: *oldtype = CdClimLeap; break; case cdClim360: *oldtype = CdClim360; break; default: cdError("Error on relative units conversion, invalid timetype = %d",newtype); return 1; } return 0; }
void CdDayOfYear(CdTime *date, int *doy) { int leap_add = 0; /* add 1 day if leap year */ int month; /* month */ long year; month = date->month; if (month < 1 || month > 12) { cdError( "Day-of-year error; month: %d\n", month); month = 1; } if(!(date->timeType & CdChronCal)) /* Ignore year for Clim calendar */ year = 0; else if(!(date->timeType & CdBase1970)) /* year is offset from base for relative time */ year = date->baseYear + date->year; else year = date->year; if (ISLEAP(year,date->timeType) && month > 2) leap_add = 1; if( ((date->timeType) & Cd365) || ((date->timeType) & Cd366) ) { *doy = days_sum[month-1] + date->day + leap_add ; } else { /* date->timeType & Cd360 */ *doy = 30*(month-1) + date->day + leap_add ; } return; }
/* Value is in hours. Translate to units. */ double cdFromHours(double value, cdUnitTime unit){ double result; switch(unit){ case cdSecond: result = value * 3600.0; break; case cdMinute: result = value * 60.0; break; case cdHour: result = value; break; case cdDay: result = value/24.0; break; case cdWeek: result = value/168.0; break; case cdMonth: case cdSeason: case cdYear: case cdFraction: default: cdError("Error on conversion from hours to vague unit"); result = 0; break; } return result; }
/* Validate the component time, return 0 if valid, 1 if not */ int cdValidateTime(cdCalenType timetype, cdCompTime comptime) { if(comptime.month<1 || comptime.month>12){ cdError("Error on time conversion: invalid month = %hd\n",comptime.month); return 1; } if(comptime.day<1 || comptime.day>31){ cdError("Error on time conversion: invalid day = %hd\n",comptime.day); return 1; } if(comptime.hour<0.0 || comptime.hour>24.0){ cdError("Error on time conversion: invalid hour = %lf\n",comptime.hour); return 1; } return 0; }
long cdNdimIntersect(long dsetid, long varid, const long order[], const double first[], const double last[], const double modulus[], cdIntersectPolicy policy, long start[], long count[], long stride[]){ CuFile* file; /* Input file */ CuType dtype; /* cdunif file datatype */ int cufileid, cuvid; /* cdunif ids */ int ndims; /* number of dimensions */ int i,j; /* i = user array index, j = file array index */ int dimids[CU_MAX_VAR_DIMS]; /* variable cdunif dimension IDs, in file order */ long transpose[CU_MAX_VAR_DIMS]; /* transpose vector */ double *dvalues; /* Dimension values returned from cw_dimmap */ double xdf, xdl; /* Actual first and last values of dimension */ double cycle[CU_MAX_VAR_DIMS]; /* Modulus vector, in user order */ char dimname[CU_MAX_NAME+1]; /* Dimension name */ char varname[CU_MAX_NAME+1]; /* Variable name */ long idf, idl; /* First and last dimension indices */ /* Map from CDMS to cdunif ids */ cufileid = cd2cuFileid(dsetid); cuvid = cd2cuVarid(varid); /* Lookup the file */ if((file=CuLookupFile(cufileid)) == (CuFile*)0) return 0; /* Get the number of dimensions, dimension IDs, and file datatype */ if(cuvarinq(cufileid, cuvid, varname, &dtype, &ndims, dimids, 0)==-1){ return 0; } /* Set the transpose vector. Default order is [0, 1, ..., ndims-1] */ for(i=0; i<ndims; i++){ transpose[i] = (order ? order[i] : i); cycle[i] = (modulus ? modulus[i] : 0.0); } /* Map dimension ranges to indices. Free memory allocated in cw_dimget */ for(i=0; i<ndims; i++){ dvalues = (double *)0; /* Must be initialized for cw_dimmap !!! */ if(cw_dimmap(cufileid, dimids[transpose[i]], first[i], last[i], (CwRoundPolicy)policy, 1.0e-5, cycle[i]>0.0, cycle[i], &dvalues, &idf, &idl, &xdf, &xdl)){ if(cudiminq(cufileid, dimids[transpose[i]], dimname, 0, 0, 0, 0, 0)==-1) return 0; cdError("Error mapping range [%lf,%lf] onto dimension %s, variable %s, file %s", first[i], last[i], dimname, varname, file->controlpath); return 0; } free((void *)dvalues); start[i] = idf; if(idl >= idf){ count[i] = idl-idf+1; stride[i] = 1; } else{ count[i] = idf-idl+1; stride[i] = -1; } } return 1; }
long cdSlabRead(long dsetid, long varid, const long order[], const double first[], const double last[], const double modulus[], cdIntersectPolicy policy, cdType usertype, void *values){ CuFile* file; /* Input file */ int cufileid, cuvid; /* cdunif ids */ int ndims; /* number of dimensions */ int i; /* i = user array index */ long transpose[CU_MAX_VAR_DIMS]; /* transpose vector */ long start[CU_MAX_VAR_DIMS]; /* Start indices in user order */ long count[CU_MAX_VAR_DIMS]; /* Counts, in user order */ long stride[CU_MAX_VAR_DIMS]; /* Strides, in user order */ char varname[CU_MAX_NAME+1]; /* Variable name */ /* Map from CDMS to cdunif ids */ cufileid = cd2cuFileid(dsetid); cuvid = cd2cuVarid(varid); /* Lookup the file */ if((file=CuLookupFile(cufileid)) == (CuFile*)0) return 0; /* Get the number of dimensions, dimension IDs, and file datatype */ if(cuvarinq(cufileid, cuvid, varname, 0, &ndims, 0, 0)==-1){ return 0; } /* Set the transpose vector. Default order is [0, 1, ..., ndims-1] */ for(i=0; i<ndims; i++){ transpose[i] = (order ? order[i] : i); } /* Map dimension ranges to indices. Free memory allocated in cw_dimget */ if(cdNdimIntersect(dsetid, varid, order, first, last, modulus, policy, start, count, stride)==0) return 0; /* Read the data */ if(cuvargets(cufileid, cuvid, transpose, start, count, stride, (CuType)usertype, values)==-1){ cdError("Error reading data for file %s, variable %s", varname, file->controlpath); return 0; } return 1; }
void cdComp2Rel(cdCalenType timetype, cdCompTime comptime, char* relunits, double* reltime) { cdCompTime base_comptime; CdDeltaTime deltime; CdTime humantime; CdTimeType old_timetype; cdUnitTime unit; double base_etm, etm, delta=0.; long ndel, hoursInYear; /* Parse the relunits */ if(cdParseRelunits(timetype, relunits, &unit, &base_comptime)) return; /* Handle mixed Julian/Gregorian calendar */ if (timetype == cdMixed){ switch(unit){ case cdWeek: case cdDay: case cdHour: case cdMinute: case cdSecond: cdComp2RelMixed(comptime, unit, base_comptime, reltime); return; case cdYear: case cdSeason: case cdMonth: timetype = cdStandard; break; case cdFraction: case cdBadUnit: cdError("invalid unit in conversion"); break; } } /* Convert basetime to epochal */ humantime.year = base_comptime.year; humantime.month = base_comptime.month; humantime.day = base_comptime.day; humantime.hour = base_comptime.hour; humantime.baseYear = 1970; /* Map to old-style timetype */ if(cdToOldTimetype(timetype,&old_timetype)) return; humantime.timeType = old_timetype; Cdh2e(&humantime,&base_etm); /* Map end time to epochal */ humantime.year = comptime.year; humantime.month = comptime.month; humantime.day = comptime.day; humantime.hour = comptime.hour; Cdh2e(&humantime,&etm); /* Calculate relative time value for months or hours */ deltime.count = 1; deltime.units = (CdTimeUnit)unit; switch(unit){ case cdWeek: case cdDay: case cdHour: case cdMinute: case cdSecond: delta = etm - base_etm; if(!(timetype & cdStandardCal)){ /* Climatological time */ hoursInYear = (timetype & cd365Days) ? 8760. : (timetype & cdHasLeap) ? 8784. : 8640.; /* Normalize delta to interval [0,hoursInYear) */ if(delta < 0.0 || delta >= hoursInYear) delta -= hoursInYear * floor(delta/hoursInYear); } break; case cdYear: case cdSeason: case cdMonth: CdDivDelTime(base_etm, etm, deltime, old_timetype, 1970, &ndel); break; case cdFraction: case cdBadUnit: cdError("invalid unit in conversion"); break; } /* Convert to output units */ switch(unit){ case cdSecond: *reltime = 3600.0 * delta; break; case cdMinute: *reltime = 60.0 * delta; break; case cdHour: *reltime = delta; break; case cdDay: *reltime = delta/24.0; break; case cdWeek: *reltime = delta/168.0; break; case cdMonth: case cdSeason: case cdYear: /* Already in correct units */ if(timetype & cdStandardCal) *reltime = (base_etm <= etm) ? (double)ndel : (double)(-ndel); else /* Climatological time is already normalized*/ *reltime = (double)ndel; break; default: cdError("invalid unit in conversion"); break; } return; }
void cdChar2Comp(cdCalenType timetype, char* chartime, cdCompTime* comptime) { double sec; int ihr, imin, nconv; long year; short day; short month; comptime->year = CD_NULL_YEAR; comptime->month = CD_NULL_MONTH; comptime->day = CD_NULL_DAY; comptime->hour = CD_NULL_HOUR; if(timetype & cdStandardCal){ nconv = sscanf(chartime,"%ld-%hd-%hd %d:%d:%lf",&year,&month,&day,&ihr,&imin,&sec); if(nconv==EOF || nconv==0){ cdError("Error on character time conversion, string = %s\n",chartime); return; } if(nconv >= 1){ comptime->year = year; } if(nconv >= 2){ comptime->month = month; } if(nconv >= 3){ comptime->day = day; } if(nconv >= 4){ if(ihr<0 || ihr>23){ cdError("Error on character time conversion: invalid hour = %d\n",ihr); return; } comptime->hour = (double)ihr; } if(nconv >= 5){ if(imin<0 || imin>59){ cdError("Error on character time conversion: invalid minute = %d\n",imin); return; } comptime->hour += (double)imin/60.; } if(nconv >= 6){ if(sec<0.0 || sec>60.0){ cdError("Error on character time conversion: invalid second = %lf\n",sec); return; } comptime->hour += sec/3600.; } } else{ /* Climatological */ nconv = sscanf(chartime,"%hd-%hd %d:%d:%lf",&month,&day,&ihr,&imin,&sec); if(nconv==EOF || nconv==0){ cdError("Error on character time conversion, string = %s",chartime); return; } if(nconv >= 1){ comptime->month = month; } if(nconv >= 2){ comptime->day = day; } if(nconv >= 3){ if(ihr<0 || ihr>23){ cdError("Error on character time conversion: invalid hour = %d\n",ihr); return; } comptime->hour = (double)ihr; } if(nconv >= 4){ if(imin<0 || imin>59){ cdError("Error on character time conversion: invalid minute = %d\n",imin); return; } comptime->hour += (double)imin/60.; } if(nconv >= 5){ if(sec<0.0 || sec>60.0){ cdError("Error on character time conversion: invalid second = %lf\n",sec); return; } comptime->hour += sec/3600.; } } (void)cdValidateTime(timetype,*comptime); return; }
/* Divide ('endEtm' - 'begEtm') by 'delTime', * return the integer portion of the result in 'nDel'. */ void CdDivDelTime(double begEtm, double endEtm, CdDeltaTime delTime, CdTimeType timeType, long baseYear, long *nDel) { double delHours, frange; long delMonths, range; CdTime bhtime, ehtime; int hoursInYear; extern void Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime); switch(delTime.units){ case CdYear: delMonths = 12; break; case CdSeason: delMonths = 3; break; case CdMonth: delMonths = 1; break; case CdWeek: delHours = 168.0; break; case CdDay: delHours = 24.0; break; case CdHour: delHours = 1.0; break; case CdMinute: delHours = 1./60.; break; case CdSecond: delHours = 1./3600.; break; default: cdError("Invalid delta time units: %d\n",delTime.units); return; } switch(delTime.units){ case CdYear: case CdSeason: case CdMonth: delMonths *= delTime.count; Cde2h(begEtm,timeType,baseYear,&bhtime); Cde2h(endEtm,timeType,baseYear,&ehtime); if(timeType & CdChronCal){ /* Chron and Rel time */ range = 12*(ehtime.year - bhtime.year) + (ehtime.month - bhtime.month); } else{ /* Clim time, ignore year */ range = (ehtime.month - bhtime.month); if(range < 0) range += 12; } *nDel = abs(range)/delMonths; break; case CdWeek: case CdDay: case CdHour: case CdMinute: case CdSecond: delHours *= (double)delTime.count; if(timeType & CdChronCal){ /* Chron and Rel time */ frange = fabs(endEtm - begEtm); } else{ /* Clim time, ignore year, but */ /* wraparound relative to hours-in-year*/ frange = endEtm - begEtm; if(timeType & Cd366) { hoursInYear = 8784; } else { hoursInYear = (timeType & Cd365) ? 8760. : 8640.; } /* Normalize frange to interval [0,hoursInYear) */ if(frange < 0.0 || frange >= hoursInYear) frange -= hoursInYear * floor(frange/hoursInYear); } *nDel = (frange + 1.e-10*delHours)/delHours; break; default: cdError("Invalid delta time units: %d\n",delTime.units); } return; }
/* Function returns 1 if error, 0 on success */ int cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTime* base_comptime) { char charunits[CD_MAX_RELUNITS]; char relword[CD_MAX_CHARTIME]; char basetime_1[CD_MAX_CHARTIME]; char basetime_2[CD_MAX_CHARTIME]; char basetime[CD_MAX_CHARTIME]; int nconv, nconv1, nconv2; /* Allow ISO-8601 "T" date-time separator as well as blank separator */ nconv1 = sscanf(relunits,"%s %s %[^T]T%s",charunits,relword,basetime_1,basetime_2); if(nconv1==EOF || nconv1==0){ cdError("Error on relative units conversion, string = %s\n",relunits); return 1; } nconv2 = sscanf(relunits,"%s %s %s %s",charunits,relword,basetime_1,basetime_2); if(nconv2==EOF || nconv2==0){ cdError("Error on relative units conversion, string = %s\n",relunits); return 1; } if(nconv1 < nconv2) { nconv = nconv2; } else { nconv = sscanf(relunits,"%s %s %[^T]T%s",charunits,relword,basetime_1,basetime_2); } /* * Mods for NCL: allow for upper or lower case (since/SINCE) * and for multiple "relative" words (since,after,ref,from) */ if(nconv==EOF || nconv==0){ cdError("Error on relative units conversion, string = %s\n",relunits); return 1; } if(nconv >=3 && strcasecmp(relword,"since") && strcasecmp(relword,"after") && strcasecmp(relword,"ref") && strcasecmp(relword,"from")) { cdError("Error on relative units conversion, string = %s\n",relunits); return 1; } /* Get the units */ cdTrim(charunits,CD_MAX_RELUNITS); /* * Mods for NCL: allow for upper or lower case units (hours/HOURS). * Simply changed "strncmp" and "strcmp" to "strncasecmp" and "strcasecmp". */ if(!strncasecmp(charunits,"sec",3) || !strcasecmp(charunits,"s")){ *unit = cdSecond; } else if(!strncasecmp(charunits,"min",3) || !strcasecmp(charunits,"mn")){ *unit = cdMinute; } else if(!strncasecmp(charunits,"hour",4) || !strcasecmp(charunits,"hr")){ *unit = cdHour; } else if(!strncasecmp(charunits,"day",3) || !strcasecmp(charunits,"dy")){ *unit = cdDay; } else if(!strncasecmp(charunits,"week",4) || !strcasecmp(charunits,"wk")){ *unit = cdWeek; } else if(!strncasecmp(charunits,"month",5) || !strcasecmp(charunits,"mo")){ *unit = cdMonth; } else if(!strncasecmp(charunits,"season",6)){ *unit = cdSeason; } else if(!strncasecmp(charunits,"year",4) || !strcasecmp(charunits,"yr")){ if(!(timetype & cdStandardCal)){ cdError("Error on relative units conversion: climatological units cannot be 'years'.\n"); return 1; } *unit = cdYear; } else { cdError("Error on relative units conversion: invalid units = %s\n",charunits); return 1; } /* Build the basetime, if any (default is 1979), */ /* or month 1 for climatological time. */ if(nconv == 1){ if(timetype & cdStandardCal) strcpy(basetime,CD_DEFAULT_BASEYEAR); else strcpy(basetime,"1"); } /* Convert the basetime to component, then epochal (hours since 1970) */ else{ if(nconv == 2){ cdTrim(basetime_1,CD_MAX_CHARTIME); strcpy(basetime,basetime_1); } else{ cdTrim(basetime_1,CD_MAX_CHARTIME); cdTrim(basetime_2,CD_MAX_CHARTIME); sprintf(basetime,"%s %s",basetime_1,basetime_2); } } cdChar2Comp(timetype, basetime, base_comptime); return 0; }
/* Add 'nDel' times 'delTime' to epochal time 'begEtm', * return the result in epochal time 'endEtm'. */ void CdAddDelTime(double begEtm, long nDel, CdDeltaTime delTime, CdTimeType timeType, long baseYear, double *endEtm) { double delHours; long delMonths, delYears; CdTime bhtime, ehtime; extern void Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime); extern void Cdh2e(CdTime *htime, double *etime); switch(delTime.units){ case CdYear: delMonths = 12; break; case CdSeason: delMonths = 3; break; case CdMonth: delMonths = 1; break; case CdWeek: delHours = 168.0; break; case CdDay: delHours = 24.0; break; case CdHour: delHours = 1.0; break; case CdMinute: delHours = 1./60.; break; case CdSecond: delHours = 1./3600.; break; default: cdError("Invalid delta time units: %d\n",delTime.units); return; } switch(delTime.units){ case CdYear: case CdSeason: case CdMonth: Cde2h(begEtm,timeType,baseYear,&bhtime); delMonths = delMonths * nDel * delTime.count + bhtime.month - 1; delYears = (delMonths >= 0 ? (delMonths/12) : (delMonths+1)/12 - 1); ehtime.year = bhtime.year + delYears; ehtime.month = delMonths - (12 * delYears) + 1; ehtime.day = 1; ehtime.hour = 0.0; ehtime.timeType = timeType; ehtime.baseYear = !(timeType & CdChronCal) ? 0 : (timeType & CdBase1970) ? 1970 : baseYear; /* base year is 0 for Clim, */ /* 1970 for Chron, */ /* or input base year for Rel */ Cdh2e(&ehtime,endEtm); break; case CdWeek: case CdDay: case CdHour: case CdMinute: case CdSecond: delHours *= (nDel * delTime.count); *endEtm = begEtm + delHours; break; default: cdError("Invalid delta time units: %d\n",delTime.units); } return; }
void cdRel2Comp(cdCalenType timetype, char* relunits, double reltime, cdCompTime* comptime) { CdDeltaTime deltime; CdTime humantime; CdTimeType old_timetype; cdCompTime base_comptime; cdUnitTime unit, baseunits; double base_etm, result_etm; double delta=0.; long idelta=0; /* Parse the relunits */ if(cdParseRelunits(timetype, relunits, &unit, &base_comptime)) return; if (timetype == cdMixed){ switch(unit){ case cdWeek: case cdDay: case cdHour: case cdMinute: case cdSecond: cdRel2CompMixed(reltime, unit, base_comptime, comptime); return; case cdYear: case cdSeason: case cdMonth: timetype = cdStandard; break; case cdFraction: case cdBadUnit: cdError("invalid unit in conversion"); break; } } baseunits =cdBadUnit; switch(unit){ case cdSecond: delta = reltime/3600.0; baseunits = cdHour; break; case cdMinute: delta = reltime/60.0; baseunits = cdHour; break; case cdHour: delta = reltime; baseunits = cdHour; break; case cdDay: delta = 24.0 * reltime; baseunits = cdHour; break; case cdWeek: delta = 168.0 * reltime; baseunits = cdHour; break; case cdMonth: idelta = (long)(reltime + (reltime<0 ? -1.e-10 : 1.e-10)); baseunits = cdMonth; break; case cdSeason: idelta = (long)(3.0 * reltime + (reltime<0 ? -1.e-10 : 1.e-10)); baseunits = cdMonth; break; case cdYear: idelta = (long)(12 * reltime + (reltime<0 ? -1.e-10 : 1.e-10)); baseunits = cdMonth; break; default: cdError("invalid unit in conversion"); break; } deltime.count = 1; deltime.units = (CdTimeUnit)baseunits; humantime.year = base_comptime.year; humantime.month = base_comptime.month; humantime.day = base_comptime.day; humantime.hour = base_comptime.hour; humantime.baseYear = 1970; /* Map to old-style timetype */ if(cdToOldTimetype(timetype,&old_timetype)) return; humantime.timeType = old_timetype; Cdh2e(&humantime,&base_etm); /* If months, seasons, or years, */ if(baseunits == cdMonth){ /* Calculate new epochal time from integer months. */ /* Convert back to human, then comptime. */ /* For zero reltime, just return the basetime*/ if(reltime != 0.0){ CdAddDelTime(base_etm,idelta,deltime,old_timetype,1970,&result_etm); Cde2h(result_etm, old_timetype, 1970, &humantime); } } /* Calculate new epochal time. */ /* Convert back to human, then comptime. */ else{ Cde2h(base_etm+delta, old_timetype, 1970, &humantime); } comptime->year = humantime.year; comptime->month = humantime.month; comptime->day = humantime.day; comptime->hour = humantime.hour; return; }
long cdDimGetDouble(long dsetid, long dimid, long start, long count, long stride, double modulus, double *values){ CuType dtype; char *cp; double *dp, *ddp; float *fp; int *ip; int cufileid, cudimid; int i,k,newk; int direc; long *lp; long dlen, dlenbytes; long kcycle, kbase; #if !defined(sgi) && !defined(__alpha) && !defined(__ia64) && !defined(__x86_64__) long double *ldp; #endif short *sp; void *dim; cufileid = cd2cuFileid(dsetid); cudimid = cd2cuVarid(dimid); /* Retrieve the dimension type and length */ if(cudiminq(cufileid,cudimid,0,0,&dtype,0,0,&dlen)==-1) return 0; /* Get memory for the dimension */ dlenbytes = dlen*cutypelen(dtype); if((dim = malloc(dlenbytes)) == (void*)0){ cdError("Cannot allocate %d bytes of memory for dsetid = %d, dimid = %d",dlenbytes,dsetid,dimid); return 0; } /* Get the dimension */ if(cudimget(cufileid,cudimid,dim)==-1) return 0; switch(dtype){ case cdDouble: ddp = (double *)dim; direc = (*ddp<=*(ddp+dlen-1) ? 1 : -1); for(i=0, k=start, dp=values; i<count; i++, k+=stride){ kcycle = (k>=0 ? k/dlen : ((k+1)/dlen)-1); kbase = k - kcycle*dlen; *dp++ = (double)ddp[kbase] + kcycle*direc*modulus; } break; case cdFloat: fp = (float *)dim; direc = (*fp<=*(fp+dlen-1) ? 1 : -1); for(i=0, k=start, dp=values; i<count; i++, k+=stride){ kcycle = (k>=0 ? k/dlen : ((k+1)/dlen)-1); kbase = k - kcycle*dlen; *dp++ = (double)fp[kbase] + kcycle*direc*modulus; } break; case cdInt: ip = (int *)dim; direc = (*ip<=*(ip+dlen-1) ? 1 : -1); for(i=0, k=start, dp=values; i<count; i++, k+=stride){ kcycle = (k>=0 ? k/dlen : ((k+1)/dlen)-1); kbase = k - kcycle*dlen; *dp++ = (double)ip[kbase] + kcycle*direc*modulus; } break; case cdLong: lp = (long*)dim; direc = (*lp<=*(lp+dlen-1) ? 1 : -1); for(i=0, k=start, dp=values; i<count; i++, k+=stride){ kcycle = (k>=0 ? k/dlen : ((k+1)/dlen)-1); kbase = k - kcycle*dlen; *dp++ = (double)lp[kbase] + kcycle*direc*modulus; } break; case cdShort: sp = (short*)dim; direc = (*sp<=*(sp+dlen-1) ? 1 : -1); for(i=0, k=start, dp=values; i<count; i++, k+=stride){ kcycle = (k>=0 ? k/dlen : ((k+1)/dlen)-1); kbase = k - kcycle*dlen; *dp++ = (double)sp[kbase] + kcycle*direc*modulus; } break; case cdChar: case cdByte: cp = (char*)dim; direc = (*cp<=*(cp+dlen-1) ? 1 : -1); for(i=0, k=start, dp=values; i<count; i++, k+=stride){ kcycle = (k>=0 ? k/dlen : ((k+1)/dlen)-1); kbase = k - kcycle*dlen; *dp++ = (double)cp[kbase] + kcycle*direc*modulus; } break; #if !defined(sgi) && !defined(__alpha) && !defined(__ia64) && !defined(__x86_64__) case cdLongDouble: ldp = (long double*)dim; direc = (*ldp<=*(ldp+dlen-1) ? 1 : -1); for(i=0, k=start, dp=values; i<count; i++, k+=stride){ kcycle = (k>=0 ? k/dlen : ((k+1)/dlen)-1); kbase = k - kcycle*dlen; *dp++ = (double)ldp[kbase] + kcycle*direc*modulus; } break; #endif default: cdError("Invalid dimension datatype %d",dtype); return 0; } free(dim); return 1; }