/* * Function: XWorkstationClassInitialize * * Description: * * In Args: * * Out Args: * * Scope: * Returns: * Side Effect: */ static NhlErrorTypes XWorkstationClassInitialize #if NhlNeedProto ( void ) #else () #endif { _NhlEnumVals cmvals[] = { {NhlSHARE, "Share"}, {NhlSHARE, "Shared"}, {NhlPRIVATE, "Private"}, {NhlMIXED, "Mixed"} }; (void)_NhlRegisterEnumType(NhlxWorkstationClass,NhlTXColorMode,cmvals, NhlNumber(cmvals)); Qtitle = NrmStringToQuark(NhlNwkTitle); Qicon_title = NrmStringToQuark(NhlNwkIconTitle); return NhlNOERROR; }
NclMultiDValData guiGetVarAttMV(NclFile thefile, const char* varname, const char *attname) { NclQuark varquark = NrmStringToQuark(varname); NclQuark attquark = NrmStringToQuark(attname); return (_NclFileReadVarAtt(thefile,varquark,attquark,NULL)); }
NclFile NclCreateAdvancedFile(const char *path) { NclAdvancedFile nclfile; NclQuark qpath = NrmStringToQuark(path); nclfile = _NclCreateAdvancedFile(NULL,NULL,Ncl_File,0,TEMPORARY,qpath,-1); return (NclFile) nclfile; }
NclQuark *splitString(NclQuark inq, int *num) { NclQuark *qs = NULL; int i, m, n = 1; char *iname = NrmQuarkToString(inq); char buffer[NCL_MAX_STRING]; char *instr = NULL; char *tmpstr; instr = &buffer[0]; strcpy(instr, iname); /* *fprintf(stderr, "\nEnter splitString, file: %s, line: %d\n", __FILE__, __LINE__); *fprintf(stderr, "\tinput str: <%s>\n", instr); */ if('/' == instr[0]) instr = instr + 1; /* *fprintf(stderr, "\tinput str: <%s>\n", instr); */ for(i = 0; i < strlen(instr); ++i) { if('/' == instr[i]) ++n; } if(n) qs = (NclQuark *)NclMalloc(n * sizeof(NclQuark)); m = 0; tmpstr = strtok(instr, "/"); while(tmpstr != NULL) { for(i = 0; i < strlen(tmpstr); ++i) { if(!isalnum(tmpstr[i])) tmpstr[i] = '_'; } qs[m] = NrmStringToQuark(tmpstr); ++m; tmpstr = strtok(NULL, "/"); } *num = m; /* *fprintf(stderr, "\tnum = %d\n", *num); *fprintf(stderr, "Leave splitString, file: %s, line: %d\n\n", __FILE__, __LINE__); */ return qs; }
static NhlErrorTypes CairoWorkstationClassInitialize(void) { static int classInitialized = 0; if (!classInitialized) { _NhlEnumVals documentFormats[] = { {NhlCPS, "PS"}, {NhlCPS, "NEWPS"}, {NhlCPDF, "PDF"}, {NhlCPDF, "NEWPDF"}, {NhlCEPS, "EPS"} }; _NhlEnumVals imageFormats[] = { {NhlCPNG, "NEWPNG"}, {NhlCPNG, "PNG"}, {NhlCTIFF, "TIFF"} }; _NhlEnumVals windowFormats[] = { {NhlCX11, "X11"} }; _NhlEnumVals orientvals[] = { {NhlPORTRAIT, "Portrait"}, {NhlLANDSCAPE, "Landscape"} }; (void) _NhlRegisterEnumType(NhlcairoDocumentWorkstationClass, NhlTCairoFormat, documentFormats, NhlNumber(documentFormats)); (void) _NhlRegisterEnumType(NhlcairoImageWorkstationClass, NhlTCairoFormat, imageFormats, NhlNumber(imageFormats)); (void) _NhlRegisterEnumType(NhlcairoWindowWorkstationClass, NhlTCairoFormat, windowFormats, NhlNumber(windowFormats)); (void) _NhlRegisterEnumType(NhlcairoDocumentWorkstationClass, NhlTWorkOrientation, orientvals, NhlNumber(orientvals)); fnameQ = NrmStringToQuark(NhlNwkFileName); classInitialized = 1; } return NhlNOERROR; }
NhlErrorTypes get_ncl_version_W(void) { char *version; NrmQuark *sversion; int len; ng_size_t ret_size = 1; /* * There are no input arguments to retrieve. * Just get the version number and return it. */ len = strlen(GetNCLVersion()); version = (char *)calloc(len+1,sizeof(char)); strcpy(version,GetNCLVersion()); sversion = (NrmQuark *)calloc(1,sizeof(NrmQuark)); *sversion = NrmStringToQuark(version); free(version); return(NclReturnValue((void *)sversion, 1, &ret_size, NULL, NCL_string, 0)); }
NclVar readNclFileVar(NclFile thefile, const char *var_name, NclSelectionRecord *sel_ptr) { NclFileClass fc = NULL; NclQuark varqname = NrmStringToQuark(var_name); if(NULL == thefile) return(NULL); fc = (NclFileClass)thefile->obj.class_ptr; while((NclObjClass)fc != nclObjClass) { if(fc->file_class.read_var_func != NULL) { return((*fc->file_class.read_var_func)(thefile, varqname, sel_ptr)); } else { fc = (NclFileClass)fc->obj_class.super_class; } } return(NULL); }
NhlErrorTypes ut_calendar_W( void ) { /* * Input array variables */ void *x; double *tmp_x; NrmQuark *sspec = NULL; char *cspec, *cspec_orig; int *option; int ndims_x; ng_size_t dsizes_x[NCL_MAX_DIMENSIONS]; int has_missing_x; NclScalar missing_x, missing_dx; NclBasicDataTypes type_x; /* * Variables for calculating fraction of year, if the option is 4. */ int doy, nsid, total_seconds_in_year, seconds_in_doy, seconds_in_hour; int seconds_in_minute; double current_seconds_in_year, fraction_of_year; /* * Variables for retrieving attributes from the first argument. */ NclAttList *attr_list; NclAtt attr_obj; NclStackEntry stack_entry; NrmQuark *scal; char *ccal = NULL; /* * Variables for Udunits package. */ ut_system *utopen_ncl(), *unit_system; ut_unit *utunit; /* * Output variables. */ int year, month, day, hour, minute; double second; void *date = NULL; int ndims_date = 0; ng_size_t *dsizes_date; NclScalar missing_date; NclBasicDataTypes type_date = NCL_none; NclObjClass type_date_t = NCL_none; /* * Variables for returning "calendar" attribute. */ int att_id; NclQuark *calendar; NclMultiDValData att_md, return_md; NclVar tmp_var; NclStackEntry return_data; /* * various */ int ret, return_missing; ng_size_t dsizes[1]; ng_size_t i, total_size_x; ng_size_t total_size_date = 0; ng_size_t index_date; int months_to_days_fix=0, years_to_days_fix=0; extern float truncf(float); /* * Before we do anything, initialize the Udunits package. */ unit_system = utopen_ncl(); /* * Retrieve parameters * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. */ x = (void*)NclGetArgValue( 0, 2, &ndims_x, dsizes_x, &missing_x, &has_missing_x, &type_x, DONT_CARE); /* * Get option. */ option = (int*)NclGetArgValue( 1, 2, NULL, NULL, NULL, NULL, NULL, 1); /* * The "units" attribute of "time" must be set, otherwise missing * values will be returned. * * The "calendar" option may optionally be set, but it must be equal to * one of the recognized calendars. */ return_missing = 0; stack_entry = _NclGetArg(0, 2, DONT_CARE); switch (stack_entry.kind) { case NclStk_VAR: if (stack_entry.u.data_var->var.att_id != -1) { attr_obj = (NclAtt) _NclGetObj(stack_entry.u.data_var->var.att_id); if (attr_obj == NULL) { return_missing = 1; break; } } else { /* * att_id == -1 ==> no attributes specified; return all missing. */ return_missing = 1; break; } /* * Check for attributes. If none are specified, then return missing values. */ if (attr_obj->att.n_atts == 0) { return_missing = 1; break; } else { /* * Get list of attributes. */ attr_list = attr_obj->att.att_list; /* * Loop through attributes and check them. */ while (attr_list != NULL) { if ((strcmp(attr_list->attname, "calendar")) == 0) { scal = (NrmQuark *) attr_list->attvalue->multidval.val; ccal = NrmQuarkToString(*scal); if(strcasecmp(ccal,"standard") && strcasecmp(ccal,"gregorian") && strcasecmp(ccal,"noleap") && strcasecmp(ccal,"365_day") && strcasecmp(ccal,"365") && strcasecmp(ccal,"360_day") && strcasecmp(ccal,"360") ) { NhlPError(NhlWARNING,NhlEUNKNOWN,"ut_calendar: the 'calendar' attribute is not equal to a recognized calendar. Returning all missing values."); return_missing = 1; } } if ((strcmp(attr_list->attname, "units")) == 0) { sspec = (NrmQuark *) attr_list->attvalue->multidval.val; } attr_list = attr_list->next; } } default: break; } /* * Convert sspec to character string. */ if(sspec == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ut_calendar: no 'units' attribute provided"); return(NhlFATAL); } cspec = NrmQuarkToString(*sspec); /* * There's a bug in utInvCalendar2_cal that doesn't handle the * 360-day calendar correctly if units are "years since" or * "months since". * * To fix this bug, we convert these units to "days since", do the * calculation as "days since", and then convert back to the original * "years since" or "months since" requested units. */ cspec_orig = (char*)calloc(strlen(cspec)+1,sizeof(char)); strcpy(cspec_orig,cspec); cspec = fix_units_for_360_bug(ccal,cspec,&months_to_days_fix, &years_to_days_fix); /* * Make sure cspec is a valid udunits string. */ utunit = ut_parse(unit_system, cspec, UT_ASCII); if(utunit == NULL) { NhlPError(NhlWARNING,NhlEUNKNOWN,"ut_calendar: Invalid specification string. Missing values will be returned."); return_missing = 1; } /* * Calculate size of input array. */ total_size_x = 1; for( i = 0; i < ndims_x; i++ ) total_size_x *= dsizes_x[i]; /* * Calculate size and dimensions for output array, and allocate * memory for output array. The output size will vary depending * on what option the user has specified. Only options -5 to 4 * are currently recognized. (option = -4 doesn't exist.) */ if(*option < -5 || *option > 4 || *option == -4) { NhlPError(NhlWARNING,NhlEUNKNOWN,"ut_calendar: Unknown option, defaulting to 0."); *option = 0; } if(*option == 0) { type_date = NCL_float; type_date_t = nclTypefloatClass; total_size_date = 6 * total_size_x; missing_date = ((NclTypeClass)nclTypefloatClass)->type_class.default_mis; ndims_date = ndims_x + 1; date = (float *)calloc(total_size_date,sizeof(float)); } else if(*option == -5) { /* identical to option=0, except returns ints */ type_date = NCL_int; type_date_t = nclTypeintClass; total_size_date = 6 * total_size_x; missing_date = ((NclTypeClass)nclTypeintClass)->type_class.default_mis; ndims_date = ndims_x + 1; date = (int *)calloc(total_size_date,sizeof(int)); } else if(*option >= 1 && *option <= 4) { type_date = NCL_double; type_date_t = nclTypedoubleClass; total_size_date = total_size_x; missing_date = ((NclTypeClass)nclTypedoubleClass)->type_class.default_mis; ndims_date = ndims_x; date = (double *)calloc(total_size_date,sizeof(double)); } else if(*option >= -3 && *option <= -1) { type_date = NCL_int; type_date_t = nclTypeintClass; total_size_date = total_size_x; missing_date = ((NclTypeClass)nclTypeintClass)->type_class.default_mis; ndims_date = ndims_x; date = (int *)calloc(total_size_date,sizeof(int)); } dsizes_date = (ng_size_t *)calloc(ndims_date,sizeof(ng_size_t)); /* * Make sure we have enough memory for output. */ if( date == NULL || dsizes_date == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ut_calendar: Unable to allocate memory for output arrays"); return(NhlFATAL); } /* * Calculate output dimension sizes. */ for( i = 0; i < ndims_x; i++ ) dsizes_date[i] = dsizes_x[i]; if(*option == 0 || *option == -5) { dsizes_date[ndims_x] = 6; } /* * Coerce missing values to double. */ coerce_missing(type_x,has_missing_x,&missing_x,&missing_dx,NULL); /* * If we reach this point and return_missing is not 0, then either * "units" was invalid or wasn't set, or "calendar" was not a * recoginized calendar. We return all missing values in this case. */ if(return_missing) { if(*option == 0) { for(i = 0; i < total_size_date; i++ ) { ((float*)date)[i] = missing_date.floatval; } } else if(*option == -5) { /* identical to option=0, except returns ints */ for(i = 0; i < total_size_date; i++ ) { ((int*)date)[i] = missing_date.intval; } } else if(*option >= 1 && *option <= 4) { for(i = 0; i < total_size_date; i++ ) { ((double*)date)[i] = missing_date.doubleval; } } else if(*option >= -3 && *option <= -1) { for(i = 0; i < total_size_date; i++ ) { ((int*)date)[i] = missing_date.intval; } } /* * Return all missing values. */ ret = NclReturnValue(date,ndims_date,dsizes_date, &missing_date,type_date,0); NclFree(dsizes_date); return(ret); } /* * Convert input to double if necessary. */ tmp_x = coerce_input_double(x,type_x,total_size_x,has_missing_x,&missing_x, &missing_dx); /* * This is the bug fix for 360 day calendars and a units * of "years since" or "months since". We have to convert * from "years since" or "months since" to "days since". * * See above for more information about the bug. */ if(years_to_days_fix == 1) { for(i = 0; i < total_size_x; i++ ) tmp_x[i] *= 360.; } if(months_to_days_fix == 1) { for(i = 0; i < total_size_x; i++ ) tmp_x[i] *= 30.; } /* * Loop through each element and get the 6 values. */ index_date = 0; for( i = 0; i < total_size_x; i++ ) { if(!has_missing_x || (has_missing_x && tmp_x[i] != missing_dx.doubleval)) { (void) utCalendar2_cal(tmp_x[i],utunit,&year,&month,&day, &hour,&minute,&second,ccal); /* * Calculate the return values, based on the input option. */ switch(*option) { case 0: ((float*)date)[index_date] = (float)year; ((float*)date)[index_date+1] = (float)month; ((float*)date)[index_date+2] = (float)day; ((float*)date)[index_date+3] = (float)hour; ((float*)date)[index_date+4] = (float)minute; ((float*)date)[index_date+5] = second; break; /* identical to option=0, except returns ints */ case -5: ((int*)date)[index_date] = year; ((int*)date)[index_date+1] = month; ((int*)date)[index_date+2] = day; ((int*)date)[index_date+3] = hour; ((int*)date)[index_date+4] = minute; ((int*)date)[index_date+5] = (int)truncf(second); break; /* * YYYYMM */ case -1: ((int*)date)[index_date] = (100*year) + month; break; case 1: ((double*)date)[index_date] = (double)(100*year) + (double)month; break; /* * YYYYMMDD */ case -2: ((int*)date)[index_date] = (10000*year) + (100*month) + day; break; case 2: ((double*)date)[index_date] = (double)(10000*year) + (double)(100*month) + (double)day; break; /* * YYYYMMDDHH */ case -3: ((int*)date)[index_date] = (1000000*year) + (10000*month) + (100*day) + hour; break; case 3: ((double*)date)[index_date] = (double)(1000000*year) + (double)(10000*month) + (double)(100*day) + (double)hour; break; /* * YYYY.fraction_of_year */ case 4: nsid = 86400; /* num seconds in a day */ if(ccal == NULL) { total_seconds_in_year = seconds_in_year(year,"standard"); doy = day_of_year(year,month,day,"standard"); } else { total_seconds_in_year = seconds_in_year(year,ccal); doy = day_of_year(year,month,day,ccal); } if(doy > 1) { seconds_in_doy = (doy-1) * nsid; } else { seconds_in_doy = 0; } if(hour > 1) { seconds_in_hour = (hour-1) * 3600; } else { seconds_in_hour = 0; } if(minute > 1) { seconds_in_minute = (minute-1) * 60; } else { seconds_in_minute = 0; } current_seconds_in_year = seconds_in_doy + seconds_in_hour + seconds_in_minute + second; fraction_of_year = current_seconds_in_year/(double)total_seconds_in_year; ((double*)date)[index_date] = (double)year + fraction_of_year; break; } } else { switch(*option) { case 0: ((float*)date)[index_date] = missing_date.floatval; ((float*)date)[index_date+1] = missing_date.floatval; ((float*)date)[index_date+2] = missing_date.floatval; ((float*)date)[index_date+3] = missing_date.floatval; ((float*)date)[index_date+4] = missing_date.floatval; ((float*)date)[index_date+5] = missing_date.floatval; break; /* identical to option=0, except returns ints */ case -5: ((int*)date)[index_date] = missing_date.intval; ((int*)date)[index_date+1] = missing_date.intval; ((int*)date)[index_date+2] = missing_date.intval; ((int*)date)[index_date+3] = missing_date.intval; ((int*)date)[index_date+4] = missing_date.intval; ((int*)date)[index_date+5] = missing_date.intval; break; case 1: case 2: case 3: case 4: ((double*)date)[index_date] = missing_date.doubleval; break; case -1: case -2: case -3: ((int*)date)[index_date] = missing_date.intval; break; } } if(*option == 0 || *option == -5) { index_date += 6; } else { index_date++; } } /* * Free the work arrays. */ if(type_x != NCL_double) NclFree(tmp_x); /* * Close up Udunits. */ utclose_ncl(unit_system); /* * Free extra units */ NclFree(cspec_orig); ut_free(utunit); /* * Set up variable to return. */ if(has_missing_x) { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, date, &missing_date, ndims_date, dsizes_date, TEMPORARY, NULL, type_date_t ); } else { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, date, NULL, ndims_date, dsizes_date, TEMPORARY, NULL, type_date_t ); } /* * Set up attributes to return. */ att_id = _NclAttCreate(NULL,NULL,Ncl_Att,0,NULL); dsizes[0] = 1; /* * Return "calendar" attribute. * * We can't just return "scal" here, because it's an NCL input * parameter and this seems to screw things up if we try to * return it as an attribute. */ calendar = (NclQuark*)NclMalloc(sizeof(NclQuark)); if(ccal != NULL) { *calendar = NrmStringToQuark(ccal); } else { *calendar = NrmStringToQuark("standard"); } att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, (void*)calendar, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)nclTypestringClass ); _NclAddAtt( att_id, "calendar", att_md, NULL ); tmp_var = _NclVarCreate( NULL, NULL, Ncl_Var, 0, NULL, return_md, NULL, att_id, NULL, RETURNVAR, NULL, TEMPORARY ); NclFree(dsizes_date); /* * Return output grid and attributes to NCL. */ return_data.kind = NclStk_VAR; return_data.u.data_var = tmp_var; _NclPlaceReturn(return_data); return(NhlNOERROR); }
NclAdvancedFile NclCreateAdvancedFile(const char *path) { NclQuark qpath = NrmStringToQuark(path); return (_NclCreateAdvancedFile(NULL,NULL,Ncl_File,0,TEMPORARY,qpath,-1)); }
NclQuark NclStringToQuark(const char *str) { return (NrmStringToQuark(str)); }
NhlErrorTypes ezfftb_W( void ) { /* * Input array variables */ void *cf; double *tmp_cf1 = NULL; double *tmp_cf2 = NULL; int ndims_cf; ng_size_t dsizes_cf[NCL_MAX_DIMENSIONS]; ng_size_t dsizes_xbar[1]; void *xbar; double *tmp_xbar = NULL; NclBasicDataTypes type_cf, type_xbar; NclScalar missing_cf, missing_dcf, missing_rcf, missing_x; int has_missing_cf; /* * Some variables we need to retrieve the "npts" atttribute (if it exists). */ NclAttList *att_list; NclAtt tmp_attobj; NclStackEntry data; /* * Output array variables */ void *x; double *tmp_x; int ndims_x; ng_size_t dsizes_x[NCL_MAX_DIMENSIONS]; NclBasicDataTypes type_x; /* * various */ double *work; ng_size_t index_cf, index_x; ng_size_t i, *tmp_npts, npts, npts2, lnpts2, size_x, size_leftmost; int found_missing1, found_missing2, any_missing, scalar_xbar; int inpts; /* * Retrieve parameters * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. */ cf = (void*)NclGetArgValue( 0, 2, &ndims_cf, dsizes_cf, &missing_cf, &has_missing_cf, &type_cf, DONT_CARE); xbar = (void*)NclGetArgValue( 1, 2, NULL, dsizes_xbar, NULL, NULL, &type_xbar, DONT_CARE); /* * Calculate number of leftmost elements. */ size_leftmost = 1; for( i = 1; i < ndims_cf-1; i++ ) size_leftmost *= dsizes_cf[i]; /* * Check xbar dimension sizes. */ scalar_xbar = is_scalar(1,dsizes_xbar); if(!scalar_xbar) { /* * If xbar is not a scalar, it must be an array of the same dimension * sizes as the leftmost dimensions of cf (except the first dimension * of '2'). */ if(dsizes_xbar[0] != size_leftmost) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: If xbar is not a scalar, then it must be a single vector of the length of the product of the leftmost dimensions of 'cf' (not including the '2' dimension)") ; return(NhlFATAL); } } /* * Coerce missing values. */ coerce_missing(type_cf,has_missing_cf,&missing_cf,&missing_dcf,&missing_rcf); /* * Okay, what follows here is some code for retrieving the "npts" * attribute if it exists. This attribute is one that should have been * set when "ezfftf" was called, and it indicates the length of the * original series. */ npts2 = dsizes_cf[ndims_cf-1]; /* Calculate the length in case */ /* it is not set explicitly. */ npts = 2*npts2; data = _NclGetArg(0,2,DONT_CARE); switch(data.kind) { case NclStk_VAR: if(data.u.data_var->var.att_id != -1) { tmp_attobj = (NclAtt)_NclGetObj(data.u.data_var->var.att_id); if(tmp_attobj == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: Bad attribute list, can't continue"); return(NhlFATAL); } if(tmp_attobj->att.n_atts == 0) { break; } att_list = tmp_attobj->att.att_list; i = 0; while(att_list != NULL) { if(att_list->quark == NrmStringToQuark("npts")) { tmp_npts = get_dimensions(att_list->attvalue->multidval.val,1, att_list->attvalue->multidval.data_type, "ezfftb"); npts = *tmp_npts; free(tmp_npts); if((npts % 2) == 0) { npts2 = npts/2; } else { npts2 = (npts-1)/2; } break; } att_list = att_list->next; } } break; default: NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: data.kind, can't continue"); return(NhlFATAL); } /* * Test input array size */ if(npts > INT_MAX) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: npts = %d is greater than INT_MAX", npts); return(NhlFATAL); } inpts = (int) npts; /* * Calculate size of output array. */ lnpts2 = npts2 * size_leftmost; size_x = size_leftmost * npts; ndims_x = ndims_cf - 1; for(i = 0; i < ndims_x-1; i++ ) dsizes_x[i] = dsizes_cf[i+1]; dsizes_x[ndims_x-1] = npts; /* * Create arrays to coerce input to double if necessary. */ if(type_cf != NCL_double) { tmp_cf1 = (double*)calloc(npts2,sizeof(double)); tmp_cf2 = (double*)calloc(npts2,sizeof(double)); if(tmp_cf1 == NULL || tmp_cf2 == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: Unable to allocate memory for coercing input array to double precision"); return(NhlFATAL); } } if(type_xbar != NCL_double) { tmp_xbar = (double*)calloc(1,sizeof(double)); if(tmp_xbar == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: Unable to allocate memory for coercing input array to double precision"); return(NhlFATAL); } } /* * Allocate memory for output array. */ tmp_x = (double *)calloc(npts,sizeof(double)); if (tmp_x == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: Cannot allocate memory for temporary output array" ); return(NhlFATAL); } if(type_cf == NCL_double) { type_x = NCL_double; x = (void*)calloc(size_x,sizeof(double)); if(has_missing_cf) missing_x = missing_dcf; } else { type_x = NCL_float; x = (void*)calloc(size_x,sizeof(float)); if(has_missing_cf) missing_x = missing_rcf; } if (x == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: Cannot allocate memory for output array" ); return(NhlFATAL); } /* * Allocate memory for work array */ work = (double*)calloc(4*npts+15,sizeof(double)); if ( work == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftb: Cannot allocate memory for work array" ); return(NhlFATAL); } /* * If xbar is a scalar, coerce it outside the loop. */ if(scalar_xbar) { if(type_xbar != NCL_double) { coerce_subset_input_double(xbar,tmp_xbar,0,type_xbar,1,0,NULL,NULL); } else { tmp_xbar = &((double*)xbar)[0]; } } /* * Call the f77 version of 'dezfftb' with the full argument list. */ index_x = index_cf = 0; any_missing = 0; for(i = 0; i < size_leftmost; i++) { if(type_cf != NCL_double) { coerce_subset_input_double(cf,tmp_cf1,index_cf,type_cf,npts2,0, NULL,NULL); coerce_subset_input_double(cf,tmp_cf2,lnpts2+index_cf,type_cf,npts2,0, NULL,NULL); } else { tmp_cf1 = &((double*)cf)[index_cf]; tmp_cf2 = &((double*)cf)[lnpts2+index_cf]; } /* * Check for missing values in cf. If any, then coerce that section of * the output to missing. */ found_missing1 = contains_missing(tmp_cf1,npts2,has_missing_cf, missing_dcf.doubleval); found_missing2 = contains_missing(tmp_cf2,npts2,has_missing_cf, missing_dcf.doubleval); if(found_missing1 || found_missing2) { any_missing++; set_subset_output_missing(x,index_x,type_x,npts,missing_dcf.doubleval); } else { /* * If xbar is not a scalar, then we need to coerce each element * to double or else just grab its value. */ if(!scalar_xbar) { if(type_xbar != NCL_double) { coerce_subset_input_double(xbar,tmp_xbar,i,type_xbar,1,0,NULL,NULL); } else { tmp_xbar = &((double*)xbar)[i]; } } NGCALLF(dezffti,DEZFFTI)(&inpts,work); NGCALLF(dezfftb,DEZFFTB)(&inpts,tmp_x,tmp_xbar,tmp_cf1,tmp_cf2,work); /* * Copy results back into x. */ coerce_output_float_or_double(x,tmp_x,type_cf,npts,index_x); } index_x += npts; index_cf += npts2; } /* * Free up memory. */ if(type_cf != NCL_double) { free(tmp_cf1); free(tmp_cf2); } if(type_xbar != NCL_double) free(tmp_xbar); free(tmp_x); free(work); if(any_missing) { NhlPError(NhlWARNING,NhlEUNKNOWN,"ezfftb: %d input arrays contained missing values. No calculations performed on these arrays.",any_missing); return(NclReturnValue(x,ndims_x,dsizes_x,&missing_x,type_x,0)); } else { return(NclReturnValue(x,ndims_x,dsizes_x,NULL,type_x,0)); } }
NhlErrorTypes ezfftf_W( void ) { /* * Input array variables */ void *x; int ndims_x; ng_size_t dsizes_x[NCL_MAX_DIMENSIONS]; NclBasicDataTypes type_x; NclScalar missing_x, missing_dx, missing_rx, missing_cf; int has_missing_x; double *tmp_x = NULL; /* * Output array variables */ void *cf, *xbar; int ndims_cf; ng_size_t dsizes_cf[NCL_MAX_DIMENSIONS]; double *tmp_cf1, *tmp_cf2, *tmp_xbar; NclBasicDataTypes type_cf; NclTypeClass type_cf_class; /* * Attribute variables */ void *N; int att_id; ng_size_t dsizes[1]; NclMultiDValData att_md, return_md; NclVar tmp_var; NclStackEntry return_data; /* * various */ double *work; ng_size_t index_x, index_cf1, index_cf2; ng_size_t i, npts, npts2, lnpts2, npts22; int found_missing, any_missing; ng_size_t size_leftmost, size_cf; int inpts; /* * Retrieve parameters * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. */ x = (void*)NclGetArgValue( 0, 1, &ndims_x, dsizes_x, &missing_x, &has_missing_x, &type_x, DONT_CARE); /* * Calculate number of leftmost elements. */ size_leftmost = 1; for( i = 0; i < ndims_x-1; i++ ) size_leftmost *= dsizes_x[i]; /* * Test input array size */ npts = dsizes_x[ndims_x-1]; if(npts > INT_MAX) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftf: npts = %d is greater than INT_MAX", npts); return(NhlFATAL); } inpts = (int) npts; /* * Calculate size of output array. */ if((npts % 2) == 0) { npts2 = npts/2; } else { npts2 = (npts-1)/2; } lnpts2 = npts2 * size_leftmost; npts22 = 2*npts2; size_cf = size_leftmost * npts22; ndims_cf = ndims_x + 1; dsizes_cf[0] = 2; for(i = 1; i < ndims_x; i++ ) dsizes_cf[i] = dsizes_x[i-1]; dsizes_cf[ndims_x] = npts2; /* * Coerce missing values. */ coerce_missing(type_x,has_missing_x,&missing_x,&missing_dx,&missing_rx); /* * Create space for temporary input array if necessary. */ if(type_x != NCL_double) { tmp_x = (double*)calloc(npts,sizeof(double)); if(tmp_x == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftf: Unable to allocate memory for coercing input array to double precision"); return(NhlFATAL); } } /* * Allocate space for output arrays. */ tmp_xbar = (double*)calloc(1,sizeof(double)); tmp_cf1 = (double*)calloc(npts2,sizeof(double)); tmp_cf2 = (double*)calloc(npts2,sizeof(double)); if ( tmp_cf1 == NULL || tmp_cf2 == NULL || tmp_xbar == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftf: Cannot allocate memory for temporary output arrays" ); return(NhlFATAL); } if(type_x == NCL_double) { cf = (void*)calloc(size_cf,sizeof(double)); xbar = (void*)calloc(size_leftmost,sizeof(double)); type_cf = NCL_double; if(has_missing_x) missing_cf = missing_dx; } else { cf = (void*)calloc(size_cf,sizeof(float)); xbar = (void*)calloc(size_leftmost,sizeof(float)); type_cf = NCL_float; if(has_missing_x) missing_cf = missing_rx; } N = (void*)calloc(1,sizeof(int)); if ( cf == NULL || xbar == NULL || N == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftf: Cannot allocate memory for output arrays" ); return(NhlFATAL); } /* * Allocate memory for work array */ work = (double*)calloc((4*npts+15),sizeof(double)); if ( work == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ezfftf: Cannot allocate memory for work array" ); return(NhlFATAL); } /* * Call the f77 version of 'dezfftf' with the full argument list. */ index_x = 0; index_cf1 = 0; index_cf2 = lnpts2; any_missing = 0; for(i = 0; i < size_leftmost; i++) { if(type_x != NCL_double) { coerce_subset_input_double(x,tmp_x,index_x,type_x,npts,0,NULL,NULL); } else { tmp_x = &((double*)x)[index_x]; } /* * Check for missing values in x. If any, then coerce that section of * the output to missing. */ found_missing = contains_missing(tmp_x,npts,has_missing_x, missing_dx.doubleval); if(found_missing) { any_missing++; set_subset_output_missing(xbar,i,type_cf,1,missing_dx.doubleval); set_subset_output_missing(cf,index_cf1,type_cf,npts2, missing_dx.doubleval); set_subset_output_missing(cf,index_cf2,type_cf,npts2, missing_dx.doubleval); } else { NGCALLF(dezffti,DEZFFTI)(&inpts,work); NGCALLF(dezfftf,DEZFFTF)(&inpts,tmp_x,tmp_xbar,tmp_cf1,tmp_cf2,work); /* * Copy results back into xbar and cf. */ coerce_output_float_or_double(xbar,tmp_xbar,type_cf,1,i); coerce_output_float_or_double(cf,tmp_cf1,type_cf,npts2,index_cf1); coerce_output_float_or_double(cf,tmp_cf2,type_cf,npts2,index_cf2); } index_x += npts; index_cf1 += npts2; index_cf2 += npts2; } /* * Free up memory. */ if(type_x != NCL_double) free(tmp_x); free(work); free(tmp_cf1); free(tmp_cf2); free(tmp_xbar); /* * Set up variable to return. */ type_cf_class = (NclTypeClass)_NclNameToTypeClass(NrmStringToQuark(_NclBasicDataTypeToName(type_cf))); /* * Set up return values. */ if(any_missing) { NhlPError(NhlWARNING,NhlEUNKNOWN,"ezfftf: %d input arrays contained missing values. No calculations performed on these arrays.",any_missing); return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, cf, &missing_cf, ndims_cf, dsizes_cf, TEMPORARY, NULL, (NclObjClass)type_cf_class ); } else { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, cf, NULL, ndims_cf, dsizes_cf, TEMPORARY, NULL, (NclObjClass)type_cf_class ); } /* * Attributes "xbar" and "npts". */ att_id = _NclAttCreate(NULL,NULL,Ncl_Att,0,NULL); dsizes[0] = size_leftmost; att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, xbar, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)type_cf_class ); _NclAddAtt( att_id, "xbar", att_md, NULL ); (*(int*)N) = npts; dsizes[0] = 1; att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, N, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)nclTypeintClass ); _NclAddAtt( att_id, "npts", att_md, NULL ); /* * Set up variable to hold return array and attributes. */ tmp_var = _NclVarCreate( NULL, NULL, Ncl_Var, 0, NULL, return_md, NULL, att_id, NULL, RETURNVAR, NULL, TEMPORARY ); /* * Return output grid and attributes to NCL. */ return_data.kind = NclStk_VAR; return_data.u.data_var = tmp_var; _NclPlaceReturn(return_data); return(NhlNOERROR); }
NhlErrorTypes covcorm_W( void ) { /* * Input array variables */ void *x, *trace; int *iopt; double *dx, *dtrace; ng_size_t dsizes_x[NCL_MAX_DIMENSIONS]; int ndims_x, has_missing_x; NclScalar missing_x, missing_dx; ng_size_t size_x, nvar, ntim, lvcm; int ier; NclBasicDataTypes type_x; /* * Output array variable */ void *vcm; double *dvcm; ng_size_t *dsizes_vcm; int ndims_vcm; ng_size_t size_vcm; NclBasicDataTypes type_vcm; NclTypeClass type_vcm_class; NclScalar missing_vcm; /* * Variables for returning attributes. */ int att_id; ng_size_t dsizes[1]; NclMultiDValData att_md, return_md; NclVar tmp_var; NclStackEntry return_data; int intim, invar, ilvcm; /* * Retrieve x. */ x = (void*)NclGetArgValue( 0, 2, &ndims_x, dsizes_x, &missing_x, &has_missing_x, &type_x, DONT_CARE); iopt = (int*)NclGetArgValue( 1, 2, NULL, NULL, NULL, NULL, NULL, DONT_CARE); nvar = dsizes_x[0]; ntim = dsizes_x[1]; size_x = nvar * ntim; lvcm = (nvar*(nvar+1))/2; /* * Test dimension sizes to make sure they are <= INT_MAX. */ if((ntim > INT_MAX) || (nvar > INT_MAX) || (lvcm > INT_MAX)) { NhlPError(NhlFATAL,NhlEUNKNOWN,"covcorm: one or more dimension sizes are greater than INT_MAX"); return(NhlFATAL); } intim = (int) ntim; invar = (int) nvar; ilvcm = (int) lvcm; /* * Coerce missing values, if any. */ coerce_missing(type_x,has_missing_x,&missing_x,&missing_dx,NULL); /* * Allocate space for input/output arrays. */ if(!iopt[1]) { size_vcm = lvcm; ndims_vcm = 1; dsizes_vcm = (ng_size_t*)malloc(sizeof(ng_size_t)); dsizes_vcm[0] = size_vcm; } else { size_vcm = nvar*nvar; ndims_vcm = 2; dsizes_vcm = (ng_size_t*)malloc(2*sizeof(ng_size_t)); dsizes_vcm[0] = nvar; dsizes_vcm[1] = nvar; } dx = coerce_input_double(x,type_x,size_x,0,NULL,NULL); if(type_x == NCL_double) { type_vcm = NCL_double; vcm = (void*)malloc(size_vcm*sizeof(double)); trace = (void*)malloc(sizeof(double)); if(vcm == NULL || trace == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"covcorm: Unable to allocate memory for output array"); return(NhlFATAL); } dvcm = &((double*)vcm)[0]; dtrace = &((double*)trace)[0]; missing_vcm.doubleval = missing_dx.doubleval; } else { type_vcm = NCL_float; vcm = (void*)malloc(size_vcm*sizeof(float)); trace = (void*)malloc(sizeof(float)); dvcm = (double*)malloc(size_vcm*sizeof(double)); dtrace = (double*)malloc(sizeof(double)); missing_vcm.floatval = (float)missing_dx.doubleval; if(vcm == NULL || trace == NULL || dvcm == NULL || dtrace == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"covcorm: Unable to allocate memory for output array"); return(NhlFATAL); } } /* * Depending on iopt[1], call one of two Fortran routines. * iopt[0]=0 --> covariance * iopt[0]=1 --> correlation * iopt[1]=0 --> 1D array (symmetric storage) * iopt[1]=1 --> 2D array */ if(!iopt[1]) { NGCALLF(dcovcormssm,DCOVCORMSSM)(&intim,&invar,dx,&missing_dx.doubleval, &iopt[0],dvcm,&ilvcm,dtrace,&ier); } else { NGCALLF(dcovcorm,DCOVCORM)(&intim,&invar,dx,&missing_dx.doubleval, &iopt[0],dvcm,&ilvcm,dtrace,&ier); } if(type_vcm == NCL_float) { /* * Need to coerce output array back to float before we return it. */ coerce_output_float_only(vcm,dvcm,size_vcm,0); coerce_output_float_only(trace,dtrace,1,0); NclFree(dx); if(type_x != NCL_double) NclFree(dvcm); NclFree(dtrace); } /* * Set up return value. */ type_vcm_class = (NclTypeClass)(_NclNameToTypeClass(NrmStringToQuark(_NclBasicDataTypeToName(type_vcm)))); return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, vcm, &missing_vcm, ndims_vcm, dsizes_vcm, TEMPORARY, NULL, (NclObjClass)type_vcm_class ); /* * Initialize att_id so we can return some attributes. */ att_id = _NclAttCreate(NULL,NULL,Ncl_Att,0,NULL); dsizes[0] = 1; att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, trace, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)type_vcm_class ); _NclAddAtt( att_id, "trace", att_md, NULL ); tmp_var = _NclVarCreate( NULL, NULL, Ncl_Var, 0, NULL, return_md, NULL, att_id, NULL, RETURNVAR, NULL, TEMPORARY ); /* * Return output grid and attributes to NCL. */ return_data.kind = NclStk_VAR; return_data.u.data_var = tmp_var; _NclPlaceReturn(return_data); return(NhlNOERROR); }
NhlErrorTypes cd_inv_calendar_W( void ) { /* * Input array variables */ int *year, *month, *day, *hour, *minute; void *second; double *tmp_second = NULL; NrmQuark *sspec; int *option; char *cspec; int ndims_year; ng_size_t dsizes_year[NCL_MAX_DIMENSIONS]; int has_missing_year; int ndims_month; ng_size_t dsizes_month[NCL_MAX_DIMENSIONS]; int has_missing_month; int ndims_day; ng_size_t dsizes_day[NCL_MAX_DIMENSIONS]; int has_missing_day; int ndims_hour; ng_size_t dsizes_hour[NCL_MAX_DIMENSIONS]; int has_missing_hour; int ndims_minute; ng_size_t dsizes_minute[NCL_MAX_DIMENSIONS]; int has_missing_minute; int ndims_second; ng_size_t dsizes_second[NCL_MAX_DIMENSIONS]; int has_missing_second; NclScalar missing_year; NclScalar missing_month; NclScalar missing_day; NclScalar missing_hour; NclScalar missing_minute; NclScalar missing_second; NclBasicDataTypes type_second; cdCompTime comptime; /* * Variables for retrieving attributes from last argument. */ NclAttList *attr_list; NclAtt attr_obj; NclStackEntry stack_entry; NrmQuark *scal; char *ccal = NULL; /* * Output variables. */ double *x; int has_missing_x; NclScalar missing_x; /* * Variables for returning "units" and "calendar" attributes. */ NclQuark *units, *calendar; int att_id; NclMultiDValData att_md, return_md; NclVar tmp_var; NclStackEntry return_data; /* * various */ int ret; ng_size_t i, total_size_input; ng_size_t dsizes[1], return_missing; cdCalenType ctype; double fraction; /* initialize error flag */ cuErrorOccurred = 0; /* * Retrieve parameters * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. * The first size input arrays must be the same dimension sizes. */ year = (int*)NclGetArgValue( 0, 8, &ndims_year, dsizes_year, &missing_year, &has_missing_year, NULL, DONT_CARE); month = (int*)NclGetArgValue( 1, 8, &ndims_month, dsizes_month, &missing_month, &has_missing_month, NULL, DONT_CARE); day = (int*)NclGetArgValue( 2, 8, &ndims_day, dsizes_day, &missing_day, &has_missing_day, NULL, DONT_CARE); hour = (int*)NclGetArgValue( 3, 8, &ndims_hour, dsizes_hour, &missing_hour, &has_missing_hour, NULL, DONT_CARE); minute = (int*)NclGetArgValue( 4, 8, &ndims_minute, dsizes_minute, &missing_minute, &has_missing_minute, NULL, DONT_CARE); second = (void*)NclGetArgValue( 5, 8, &ndims_second, dsizes_second, &missing_second, &has_missing_second, &type_second, DONT_CARE); if(ndims_year != ndims_month || ndims_year != ndims_day || ndims_year != ndims_hour || ndims_year != ndims_minute || ndims_year != ndims_second) { NhlPError(NhlFATAL,NhlEUNKNOWN,"cd_inv_calendar: The first six arguments must have the same dimensionality"); return(NhlFATAL); } for(i = 0; i < ndims_year; i++ ) { if(dsizes_year[i] != dsizes_month[i] || dsizes_year[i] != dsizes_day[i] || dsizes_year[i] != dsizes_hour[i] || dsizes_year[i] != dsizes_minute[i] || dsizes_year[i] != dsizes_second[i]) { NhlPError(NhlFATAL,NhlEUNKNOWN,"cd_inv_calendar: The first six arguments must have the same dimensionality"); return(NhlFATAL); } } /* * x will contain a _FillValue attribute if any of the input * has a _FillValue attribute set. */ if(has_missing_year || has_missing_month || has_missing_day || has_missing_hour || has_missing_minute || has_missing_second) { has_missing_x = 1; /* * Get the default missing value for a double type. */ missing_x = ((NclTypeClass)nclTypedoubleClass)->type_class.default_mis; } else { has_missing_x = 0; } /* * Get spec string. */ sspec = (NrmQuark *)NclGetArgValue( 6, 8, NULL, NULL, NULL, NULL, NULL, 1); /* * Get option. */ option = (int*)NclGetArgValue( 7, 8, NULL, NULL, NULL, NULL, NULL, 1); /* * Check the "option" variable to see if it contains a "calendar" * attribute. */ return_missing = 0; stack_entry = _NclGetArg(7, 8, DONT_CARE); switch (stack_entry.kind) { case NclStk_VAR: if (stack_entry.u.data_var->var.att_id != -1) { attr_obj = (NclAtt) _NclGetObj(stack_entry.u.data_var->var.att_id); if (attr_obj == NULL) { break; } } else { /* * att_id == -1 ==> no attributes specified args given. */ break; } /* * Get optional arguments. */ if (attr_obj->att.n_atts > 0) { /* * Get list of attributes. */ attr_list = attr_obj->att.att_list; /* * Loop through attributes and check them. */ while (attr_list != NULL) { if ((strcmp(attr_list->attname, "calendar")) == 0) { scal = (NrmQuark *) attr_list->attvalue->multidval.val; ccal = NrmQuarkToString(*scal); if(strcasecmp(ccal,"standard") && strcasecmp(ccal,"gregorian") && strcasecmp(ccal,"proleptic_gregorian") && strcasecmp(ccal,"noleap") && strcasecmp(ccal,"no_leap") && strcasecmp(ccal,"allleap") && strcasecmp(ccal,"all_leap") && strcasecmp(ccal,"365_day") && strcasecmp(ccal,"365") && strcasecmp(ccal,"366_day") && strcasecmp(ccal,"366") && strcasecmp(ccal,"360_day") && strcasecmp(ccal,"360") && strcasecmp(ccal,"julian") && strcasecmp(ccal,"none")) { NhlPError(NhlWARNING,NhlEUNKNOWN,"cd_inv_calendar: the 'calendar' attribute is not equal to a recognized calendar. Returning all missing values."); return_missing = has_missing_x = 1; } } attr_list = attr_list->next; } } default: break; } /* * If no calendar attribute set, or "none" was selected, then use * the default "standard". */ if(ccal == NULL || !strcasecmp(ccal,"none")) { ctype = calendar_type("standard"); } else { ctype = calendar_type(ccal); } /* * Convert sspec to character string. */ cspec = NrmQuarkToString(*sspec); /* * Calculate total size of input arrays, and size and dimensions for * output array, and alloc memory for output array. */ total_size_input = 1; for( i = 0; i < ndims_year; i++ ) total_size_input *= dsizes_year[i]; x = (double *)calloc(total_size_input,sizeof(double)); if( x == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"cd_inv_calendar: Unable to allocate memory for output array"); return(NhlFATAL); } /* * Create tmp array for coercing second to double if necessary. */ if(type_second != NCL_double) { tmp_second = (double*)calloc(1,sizeof(double)); if(tmp_second == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"cd_inv_calendar: Unable to allocate memory for coercing second array to double precision"); return(NhlFATAL); } } /* * Loop through each data value, and call Udunits routine. */ for( i = 0; i < total_size_input; i++ ) { /* * Coerce "second" to double, since this is what the original Udunits * routine is expecting. */ if(type_second != NCL_double) { coerce_subset_input_double(second,tmp_second,i,type_second,1, has_missing_second,&missing_second,NULL); } else { tmp_second = &((double*)second)[i]; } if(!return_missing && (!has_missing_year || (has_missing_year && year[i] != missing_year.intval)) && (!has_missing_month || (has_missing_month && month[i] != missing_month.intval)) && (!has_missing_day || (has_missing_day && day[i] != missing_day.intval)) && (!has_missing_hour || (has_missing_hour && hour[i] != missing_hour.intval)) && (!has_missing_minute || (has_missing_minute && minute[i] != missing_minute.intval)) && (!has_missing_second || (has_missing_second && *tmp_second != missing_second.doubleval)) ) { fraction = (double)minute[i]/60. + *tmp_second/3600.; comptime.year = (long)year[i]; comptime.month = (short)month[i]; comptime.day = (short)day[i]; comptime.hour = (double)hour[i] + fraction; (void)cdComp2Rel(ctype,comptime,cspec,&x[i]); /* * Return all missing values if we encounter a fatal error. */ if(i == 0 && (cuErrorOccurred && (cuErrOpts & CU_FATAL))) { set_all_missing(x, total_size_input, missing_x, 1); ret = NclReturnValue(x,ndims_year,dsizes_year,&missing_x, NCL_double,0); if(type_second != NCL_double) NclFree(tmp_second); return(ret); } } else { x[i] = missing_x.doubleval; } } if(type_second != NCL_double) NclFree(tmp_second); /* * Set up variable to return. */ if(has_missing_x) { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, x, &missing_x, ndims_year, dsizes_year, TEMPORARY, NULL, (NclObjClass)nclTypedoubleClass ); } else { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, x, NULL, ndims_year, dsizes_year, TEMPORARY, NULL, (NclObjClass)nclTypedoubleClass ); } /* * Set up attributes to return. */ att_id = _NclAttCreate(NULL,NULL,Ncl_Att,0,NULL); dsizes[0] = 1; /* * Return "units" attribute. * * We can't just return "sspec" here, because it's an NCL input * parameter and this seems to screw things up if we try to * return it as an attribute. */ units = (NclQuark*)NclMalloc(sizeof(NclQuark)); *units = NrmStringToQuark(cspec); att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, (void*)units, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)nclTypestringClass ); _NclAddAtt( att_id, "units", att_md, NULL ); /* * Return "calendar" attribute. * * We can't just return "sspec" here, because it's an NCL input * parameter and this seems to screw things up if we try to * return it as an attribute. */ calendar = (NclQuark*)NclMalloc(sizeof(NclQuark)); if(ccal != NULL) { *calendar = NrmStringToQuark(ccal); } else { *calendar = NrmStringToQuark("standard"); } att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, (void*)calendar, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)nclTypestringClass ); _NclAddAtt( att_id, "calendar", att_md, NULL ); tmp_var = _NclVarCreate( NULL, NULL, Ncl_Var, 0, NULL, return_md, NULL, att_id, NULL, RETURNVAR, NULL, TEMPORARY ); /* * Return output grid and attributes to NCL. */ return_data.kind = NclStk_VAR; return_data.u.data_var = tmp_var; _NclPlaceReturn(return_data); return(NhlNOERROR); }
NhlErrorTypes cd_calendar_W( void ) { /* * Input array variables */ void *x; double *tmp_x; NrmQuark *sspec = NULL; char *cspec; int *option; int ndims_x; ng_size_t dsizes_x[NCL_MAX_DIMENSIONS]; int has_missing_x; NclScalar missing_x, missing_dx; NclBasicDataTypes type_x; /* * Variables for calculating fraction of year, if the option is 4. */ int doy, nsid, total_seconds_in_year, seconds_in_doy, seconds_in_hour; int seconds_in_minute; double current_seconds_in_year, fraction_of_year; /* * Variables for retrieving attributes from the first argument. */ NclAttList *attr_list; NclAtt attr_obj; NclStackEntry stack_entry; NrmQuark *scal; const char *ccal = NULL; cdCalenType ctype; /* * Output variables. */ cdCompTime comptime; int year, month, day, hour, minute; double second; void *date = NULL; int ndims_date = 0; ng_size_t *dsizes_date; NclScalar missing_date; NclBasicDataTypes type_date = NCL_none; NclObjClass type_date_t = NCL_none; /* * Variables for returning "calendar" attribute. */ int att_id; NclQuark *calendar; NclMultiDValData att_md, return_md; NclVar tmp_var; NclStackEntry return_data; /* * various */ int ret, return_missing; ng_size_t dsizes[1]; ng_size_t i, total_size_x; ng_size_t total_size_date = 0; ng_size_t index_date; extern float truncf(float); /* initialize error flag */ cuErrorOccurred = 0; /* * Retrieve parameters * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. */ x = (void*)NclGetArgValue( 0, 2, &ndims_x, dsizes_x, &missing_x, &has_missing_x, &type_x, DONT_CARE); /* * Get option. */ option = (int*)NclGetArgValue( 1, 2, NULL, NULL, NULL, NULL, NULL, 1); /* * The "units" attribute of "time" must be set, otherwise missing * values will be returned. * * The "calendar" option may optionally be set, but it must be equal to * one of the recognized calendars. */ return_missing = 0; stack_entry = _NclGetArg(0, 2, DONT_CARE); switch (stack_entry.kind) { case NclStk_VAR: if (stack_entry.u.data_var->var.att_id != -1) { attr_obj = (NclAtt) _NclGetObj(stack_entry.u.data_var->var.att_id); if (attr_obj == NULL) { return_missing = 1; break; } } else { /* * att_id == -1 ==> no attributes specified; return all missing. */ return_missing = 1; break; } /* * Check for attributes. If none are specified, then return missing values. */ if (attr_obj->att.n_atts == 0) { return_missing = 1; break; } else { /* * Get list of attributes. */ attr_list = attr_obj->att.att_list; /* * Loop through attributes and check them. */ while (attr_list != NULL) { if ((strcmp(attr_list->attname, "calendar")) == 0) { scal = (NrmQuark *) attr_list->attvalue->multidval.val; ccal = NrmQuarkToString(*scal); if(strcasecmp(ccal,"standard") && strcasecmp(ccal,"gregorian") && strcasecmp(ccal,"proleptic_gregorian") && strcasecmp(ccal,"noleap") && strcasecmp(ccal,"no_leap") && strcasecmp(ccal,"allleap") && strcasecmp(ccal,"all_leap") && strcasecmp(ccal,"365_day") && strcasecmp(ccal,"365") && strcasecmp(ccal,"366_day") && strcasecmp(ccal,"366") && strcasecmp(ccal,"360_day") && strcasecmp(ccal,"360") && strcasecmp(ccal,"julian") && strcasecmp(ccal,"none")) { NhlPError(NhlWARNING,NhlEUNKNOWN,"cd_calendar: the 'calendar' attribute (%s) is not equal to a recognized calendar. Returning all missing values.",ccal); return_missing = 1; } } if ((strcmp(attr_list->attname, "units")) == 0) { sspec = (NrmQuark *) attr_list->attvalue->multidval.val; } attr_list = attr_list->next; } } default: break; } /* * If no calendar attribute set, or "none" was selected, then use * the default "standard". */ if(ccal == NULL || !strcasecmp(ccal,"none")) { ctype = calendar_type("standard"); } else { ctype = calendar_type(ccal); } /* * Convert sspec to character string. */ if(sspec == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"cd_calendar: no 'units' attribute provided"); return(NhlFATAL); } cspec = NrmQuarkToString(*sspec); /* * Calculate size of input array. */ total_size_x = 1; for( i = 0; i < ndims_x; i++ ) total_size_x *= dsizes_x[i]; /* * Calculate size and dimensions for output array, and allocate * memory for output array. The output size will vary depending * on what option the user has specified. Only options -5 to 4 * are currently recognized. (option = -4 doesn't exist.) */ if(*option < -5 || *option > 4 || *option == -4) { NhlPError(NhlWARNING,NhlEUNKNOWN,"cd_calendar: Unknown option, defaulting to 0."); *option = 0; } if(*option == 0) { type_date = NCL_float; type_date_t = nclTypefloatClass; total_size_date = 6 * total_size_x; missing_date = ((NclTypeClass)nclTypefloatClass)->type_class.default_mis; ndims_date = ndims_x + 1; date = (float *)calloc(total_size_date,sizeof(float)); } else if(*option == -5) { /* identical to option=0, except returns ints */ type_date = NCL_int; type_date_t = nclTypeintClass; total_size_date = 6 * total_size_x; missing_date = ((NclTypeClass)nclTypeintClass)->type_class.default_mis; ndims_date = ndims_x + 1; date = (int *)calloc(total_size_date,sizeof(int)); } else if(*option >= 1 && *option <= 4) { type_date = NCL_double; type_date_t = nclTypedoubleClass; total_size_date = total_size_x; missing_date = ((NclTypeClass)nclTypedoubleClass)->type_class.default_mis; ndims_date = ndims_x; date = (double *)calloc(total_size_date,sizeof(double)); } else if(*option >= -3 && *option <= -1) { type_date = NCL_int; type_date_t = nclTypeintClass; total_size_date = total_size_x; missing_date = ((NclTypeClass)nclTypeintClass)->type_class.default_mis; ndims_date = ndims_x; date = (int *)calloc(total_size_date,sizeof(int)); } dsizes_date = (ng_size_t *)calloc(ndims_date,sizeof(ng_size_t)); /* * Make sure we have enough memory for output. */ if( date == NULL || dsizes_date == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"cd_calendar: Unable to allocate memory for output arrays"); return(NhlFATAL); } /* * Calculate output dimension sizes. */ for( i = 0; i < ndims_x; i++ ) dsizes_date[i] = dsizes_x[i]; if(*option == 0 || *option == -5) { dsizes_date[ndims_x] = 6; } /* * Coerce missing values to double. */ coerce_missing(type_x,has_missing_x,&missing_x,&missing_dx,NULL); /* * If we reach this point and return_missing is not 0, then either * "units" was invalid or wasn't set, or "calendar" was not a * recoginized calendar. We return all missing values in this case. */ if(return_missing) { set_all_missing(date, total_size_date, missing_date, *option); ret = NclReturnValue(date,ndims_date,dsizes_date, &missing_date,type_date,0); NclFree(dsizes_date); return(ret); } /* * Convert input to double if necessary. */ tmp_x = coerce_input_double(x,type_x,total_size_x,has_missing_x,&missing_x, &missing_dx); /* * Loop through each element and get the 6 values. */ index_date = 0; for( i = 0; i < total_size_x; i++ ) { if(!has_missing_x || (has_missing_x && tmp_x[i] != missing_dx.doubleval)) { (void)cdRel2Iso_minsec(ctype,cspec,tmp_x[i],&comptime,&minute,&second); /* * Return all missing values if we encounter a fatal error. * Only check this once. */ if(i == 0 && (cuErrorOccurred && (cuErrOpts & CU_FATAL))) { set_all_missing(date, total_size_date, missing_date, *option); ret = NclReturnValue(date,ndims_date,dsizes_date, &missing_date,type_date,0); NclFree(dsizes_date); return(ret); } year = (int)comptime.year; month = (int)comptime.month; day = (int)comptime.day; /* * comptime.hour is a double, and fractional. The "minute" and "second" * above are calculated from the fractional part of the hour. */ hour = (int)comptime.hour; /* * Calculate the return values, based on the input option. */ switch(*option) { case 0: ((float*)date)[index_date] = (float)year; ((float*)date)[index_date+1] = (float)month; ((float*)date)[index_date+2] = (float)day; ((float*)date)[index_date+3] = (float)hour; ((float*)date)[index_date+4] = (float)minute; ((float*)date)[index_date+5] = second; break; /* identical to option=0, except returns ints */ case -5: ((int*)date)[index_date] = year; ((int*)date)[index_date+1] = month; ((int*)date)[index_date+2] = day; ((int*)date)[index_date+3] = hour; ((int*)date)[index_date+4] = minute; ((int*)date)[index_date+5] = (int)truncf(second); break; /* * YYYYMM */ case -1: ((int*)date)[index_date] = (100*year) + month; break; case 1: ((double*)date)[index_date] = (double)(100*year) + (double)month; break; /* * YYYYMMDD */ case -2: ((int*)date)[index_date] = (10000*year) + (100*month) + day; break; case 2: ((double*)date)[index_date] = (double)(10000*year) + (double)(100*month) + (double)day; break; /* * YYYYMMDDHH */ case -3: ((int*)date)[index_date] = (1000000*year) + (10000*month) + (100*day) + hour; break; case 3: ((double*)date)[index_date] = (double)(1000000*year) + (double)(10000*month) + (double)(100*day) + (double)hour; break; /* * YYYY.fraction_of_year */ case 4: nsid = 86400; /* num seconds in a day */ if(ccal == NULL) { total_seconds_in_year = seconds_in_year(year,"standard"); doy = day_of_year(year,month,day,"standard"); } else { total_seconds_in_year = seconds_in_year(year,ccal); doy = day_of_year(year,month,day,ccal); } if(doy > 1) { seconds_in_doy = (doy-1) * nsid; } else { seconds_in_doy = 0; } if(hour > 1) { seconds_in_hour = (hour-1) * 3600; } else { seconds_in_hour = 0; } if(minute > 1) { seconds_in_minute = (minute-1) * 60; } else { seconds_in_minute = 0; } current_seconds_in_year = seconds_in_doy + seconds_in_hour + seconds_in_minute + second; fraction_of_year = current_seconds_in_year/(double)total_seconds_in_year; ((double*)date)[index_date] = (double)year + fraction_of_year; break; } } else { switch(*option) { case 0: ((float*)date)[index_date] = missing_date.floatval; ((float*)date)[index_date+1] = missing_date.floatval; ((float*)date)[index_date+2] = missing_date.floatval; ((float*)date)[index_date+3] = missing_date.floatval; ((float*)date)[index_date+4] = missing_date.floatval; ((float*)date)[index_date+5] = missing_date.floatval; break; /* identical to option=0, except returns ints */ case -5: ((int*)date)[index_date] = missing_date.intval; ((int*)date)[index_date+1] = missing_date.intval; ((int*)date)[index_date+2] = missing_date.intval; ((int*)date)[index_date+3] = missing_date.intval; ((int*)date)[index_date+4] = missing_date.intval; ((int*)date)[index_date+5] = missing_date.intval; break; case 1: case 2: case 3: case 4: ((double*)date)[index_date] = missing_date.doubleval; break; case -1: case -2: case -3: ((int*)date)[index_date] = missing_date.intval; break; } } if(*option == 0 || *option == -5) { index_date += 6; } else { index_date++; } } /* * Free the work arrays. */ if(type_x != NCL_double) NclFree(tmp_x); /* * Set up variable to return. */ if(has_missing_x) { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, date, &missing_date, ndims_date, dsizes_date, TEMPORARY, NULL, type_date_t ); } else { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, date, NULL, ndims_date, dsizes_date, TEMPORARY, NULL, type_date_t ); } /* * Set up attributes to return. */ att_id = _NclAttCreate(NULL,NULL,Ncl_Att,0,NULL); dsizes[0] = 1; /* * Return "calendar" attribute. * * We can't just return "scal" here, because it's an NCL input * parameter and this seems to screw things up if we try to * return it as an attribute. */ calendar = (NclQuark*)NclMalloc(sizeof(NclQuark)); if(ccal != NULL) { *calendar = NrmStringToQuark(ccal); } else { *calendar = NrmStringToQuark("standard"); } att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, (void*)calendar, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)nclTypestringClass ); _NclAddAtt( att_id, "calendar", att_md, NULL ); tmp_var = _NclVarCreate( NULL, NULL, Ncl_Var, 0, NULL, return_md, NULL, att_id, NULL, RETURNVAR, NULL, TEMPORARY ); NclFree(dsizes_date); /* * Return output grid and attributes to NCL. */ return_data.kind = NclStk_VAR; return_data.u.data_var = tmp_var; _NclPlaceReturn(return_data); return(NhlNOERROR); }
NhlErrorTypes ut_inv_calendar_W( void ) { /* * Input array variables */ int *year, *month, *day, *hour, *minute; void *second; double *tmp_second = NULL; NrmQuark *sspec; int *option; char *cspec, *cspec_orig; int ndims_year; ng_size_t dsizes_year[NCL_MAX_DIMENSIONS]; int has_missing_year; int ndims_month; ng_size_t dsizes_month[NCL_MAX_DIMENSIONS]; int has_missing_month; int ndims_day; ng_size_t dsizes_day[NCL_MAX_DIMENSIONS]; int has_missing_day; int ndims_hour; ng_size_t dsizes_hour[NCL_MAX_DIMENSIONS]; int has_missing_hour; int ndims_minute; ng_size_t dsizes_minute[NCL_MAX_DIMENSIONS]; int has_missing_minute; int ndims_second; ng_size_t dsizes_second[NCL_MAX_DIMENSIONS]; int has_missing_second; NclScalar missing_year; NclScalar missing_month; NclScalar missing_day; NclScalar missing_hour; NclScalar missing_minute; NclScalar missing_second; NclBasicDataTypes type_second; /* * Variables for Udunits package. */ ut_system *utopen_ncl(), *unit_system; ut_unit *utunit; /* * Variables for retrieving attributes from last argument. */ NclAttList *attr_list; NclAtt attr_obj; NclStackEntry stack_entry; NrmQuark *scal; char *ccal = NULL; /* * Output variables. */ double *x; int has_missing_x; NclScalar missing_x; /* * Variables for returning "units" and "calendar" attributes. */ NclQuark *units, *calendar; int att_id; NclMultiDValData att_md, return_md; NclVar tmp_var; NclStackEntry return_data; /* * various */ ng_size_t i, total_size_input; ng_size_t dsizes[1], return_missing; int months_to_days_fix=0, years_to_days_fix=0; /* * Before we do anything, initialize the Udunits package. */ unit_system = utopen_ncl(); /* * Retrieve parameters * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. * The first size input arrays must be the same dimension sizes. */ year = (int*)NclGetArgValue( 0, 8, &ndims_year, dsizes_year, &missing_year, &has_missing_year, NULL, DONT_CARE); month = (int*)NclGetArgValue( 1, 8, &ndims_month, dsizes_month, &missing_month, &has_missing_month, NULL, DONT_CARE); day = (int*)NclGetArgValue( 2, 8, &ndims_day, dsizes_day, &missing_day, &has_missing_day, NULL, DONT_CARE); hour = (int*)NclGetArgValue( 3, 8, &ndims_hour, dsizes_hour, &missing_hour, &has_missing_hour, NULL, DONT_CARE); minute = (int*)NclGetArgValue( 4, 8, &ndims_minute, dsizes_minute, &missing_minute, &has_missing_minute, NULL, DONT_CARE); second = (void*)NclGetArgValue( 5, 8, &ndims_second, dsizes_second, &missing_second, &has_missing_second, &type_second, DONT_CARE); if(ndims_year != ndims_month || ndims_year != ndims_day || ndims_year != ndims_hour || ndims_year != ndims_minute || ndims_year != ndims_second) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ut_inv_calendar: The first six arguments must have the same dimensionality"); return(NhlFATAL); } for(i = 0; i < ndims_year; i++ ) { if(dsizes_year[i] != dsizes_month[i] || dsizes_year[i] != dsizes_day[i] || dsizes_year[i] != dsizes_hour[i] || dsizes_year[i] != dsizes_minute[i] || dsizes_year[i] != dsizes_second[i]) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ut_inv_calendar: The first six arguments must have the same dimensionality"); return(NhlFATAL); } } /* * x will contain a _FillValue attribute if any of the input * has a _FillValue attribute set. */ if(has_missing_year || has_missing_month || has_missing_day || has_missing_hour || has_missing_minute || has_missing_second) { has_missing_x = 1; /* * Get the default missing value for a double type. */ missing_x = ((NclTypeClass)nclTypedoubleClass)->type_class.default_mis; } else { has_missing_x = 0; } /* * Get spec string. */ sspec = (NrmQuark *)NclGetArgValue( 6, 8, NULL, NULL, NULL, NULL, NULL, 1); /* * Get option. */ option = (int*)NclGetArgValue( 7, 8, NULL, NULL, NULL, NULL, NULL, 1); /* * Check the "option" variable to see if it contains a "calendar" * attribute. */ return_missing = 0; stack_entry = _NclGetArg(7, 8, DONT_CARE); switch (stack_entry.kind) { case NclStk_VAR: if (stack_entry.u.data_var->var.att_id != -1) { attr_obj = (NclAtt) _NclGetObj(stack_entry.u.data_var->var.att_id); if (attr_obj == NULL) { break; } } else { /* * att_id == -1 ==> no attributes specified args given. */ break; } /* * Get optional arguments. */ if (attr_obj->att.n_atts > 0) { /* * Get list of attributes. */ attr_list = attr_obj->att.att_list; /* * Loop through attributes and check them. */ while (attr_list != NULL) { if ((strcmp(attr_list->attname, "calendar")) == 0) { scal = (NrmQuark *) attr_list->attvalue->multidval.val; ccal = NrmQuarkToString(*scal); if(strcasecmp(ccal,"standard") && strcasecmp(ccal,"gregorian") && strcasecmp(ccal,"noleap") && strcasecmp(ccal,"365_day") && strcasecmp(ccal,"365") && strcasecmp(ccal,"360_day") && strcasecmp(ccal,"360") ) { NhlPError(NhlWARNING,NhlEUNKNOWN,"ut_inv_calendar: the 'calendar' attribute is not equal to a recognized calendar. Returning all missing values."); return_missing = has_missing_x = 1; } } attr_list = attr_list->next; } } default: break; } /* * Convert sspec to character string. */ cspec = NrmQuarkToString(*sspec); /* * There's a bug in utInvCalendar2_cal that doesn't handle the * 360-day calendar correctly if units are "years since" or * "months since". * * To fix this bug, we convert these units to "days since", do the * calculation as "days since", and then convert back to the original * "years since" or "months since" requested units. */ cspec_orig = (char*)calloc(strlen(cspec)+1,sizeof(char)); strcpy(cspec_orig,cspec); cspec = fix_units_for_360_bug(ccal,cspec,&months_to_days_fix, &years_to_days_fix); /* * Make sure cspec is a valid udunits string. */ utunit = ut_parse(unit_system, cspec, UT_ASCII); if(utunit == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ut_inv_calendar: Invalid specification string"); return(NhlFATAL); } /* * Calculate total size of input arrays, and size and dimensions for * output array, and alloc memory for output array. */ total_size_input = 1; for( i = 0; i < ndims_year; i++ ) total_size_input *= dsizes_year[i]; x = (double *)calloc(total_size_input,sizeof(double)); if( x == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ut_inv_calendar: Unable to allocate memory for output array"); return(NhlFATAL); } /* * Create tmp array for coercing second to double if necessary. */ if(type_second != NCL_double) { tmp_second = (double*)calloc(1,sizeof(double)); if(tmp_second == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"ut_inv_calendar: Unable to allocate memory for coercing second array to double precision"); return(NhlFATAL); } } /* * Loop through each data value, and call Udunits routine. */ for( i = 0; i < total_size_input; i++ ) { /* * Coerce "second" to double, since this is what the original Udunits * routine is expecting. */ if(type_second != NCL_double) { coerce_subset_input_double(second,tmp_second,i,type_second,1, has_missing_second,&missing_second,NULL); } else { tmp_second = &((double*)second)[i]; } if(!return_missing && (!has_missing_year || (has_missing_year && year[i] != missing_year.intval)) && (!has_missing_month || (has_missing_month && month[i] != missing_month.intval)) && (!has_missing_day || (has_missing_day && day[i] != missing_day.intval)) && (!has_missing_hour || (has_missing_hour && hour[i] != missing_hour.intval)) && (!has_missing_minute || (has_missing_minute && minute[i] != missing_minute.intval)) && (!has_missing_second || (has_missing_second && *tmp_second != missing_second.doubleval)) ) { (void)utInvCalendar2_cal(year[i],month[i],day[i],hour[i], minute[i],*tmp_second,utunit,&x[i],ccal); /* * This is the bug fix for 360 day calendars and a units * of "years since" or "months since". We have to convert * from "days since" to the original requested units. * * See above for more information about the bug. */ if(years_to_days_fix == 1) x[i] /= 360.; if(months_to_days_fix == 1) x[i] /= 30.; } else { x[i] = missing_x.doubleval; } } /* * Close up Udunits. */ utclose_ncl(unit_system); /* * Set original units back if necessary. */ if(months_to_days_fix || years_to_days_fix) { cspec = cspec_orig; } else { NclFree(cspec_orig); } if(type_second != NCL_double) NclFree(tmp_second); /* * Set up variable to return. */ if(has_missing_x) { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, x, &missing_x, ndims_year, dsizes_year, TEMPORARY, NULL, (NclObjClass)nclTypedoubleClass ); } else { return_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, x, NULL, ndims_year, dsizes_year, TEMPORARY, NULL, (NclObjClass)nclTypedoubleClass ); } /* * Set up attributes to return. */ att_id = _NclAttCreate(NULL,NULL,Ncl_Att,0,NULL); dsizes[0] = 1; /* * Return "units" attribute. * * We can't just return "sspec" here, because it's an NCL input * parameter and this seems to screw things up if we try to * return it as an attribute. */ units = (NclQuark*)NclMalloc(sizeof(NclQuark)); *units = NrmStringToQuark(cspec); att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, (void*)units, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)nclTypestringClass ); _NclAddAtt( att_id, "units", att_md, NULL ); /* * Return "calendar" attribute. * * We can't just return "sspec" here, because it's an NCL input * parameter and this seems to screw things up if we try to * return it as an attribute. */ calendar = (NclQuark*)NclMalloc(sizeof(NclQuark)); if(ccal != NULL) { *calendar = NrmStringToQuark(ccal); } else { *calendar = NrmStringToQuark("standard"); } att_md = _NclCreateVal( NULL, NULL, Ncl_MultiDValData, 0, (void*)calendar, NULL, 1, dsizes, TEMPORARY, NULL, (NclObjClass)nclTypestringClass ); _NclAddAtt( att_id, "calendar", att_md, NULL ); tmp_var = _NclVarCreate( NULL, NULL, Ncl_Var, 0, NULL, return_md, NULL, att_id, NULL, RETURNVAR, NULL, TEMPORARY ); /* * Return output grid and attributes to NCL. */ return_data.kind = NclStk_VAR; return_data.u.data_var = tmp_var; _NclPlaceReturn(return_data); return(NhlNOERROR); }
int main(int argc, char **argv) { int errid = -1; int appid; int i, k = 0; int reset = 1; DIR *d; struct dirent *ent; #if defined(HPUX) shl_t so_handle; #else void *so_handle; #endif /* defined(HPUX) */ char buffer[4 * NCL_MAX_STRING]; void (*init_function) (void); char *libpath; char *scriptpath; char *pt; char *tmp = NULL; /* * Variables for command line options/arguments */ char *myName; /* argv[0]: program name (should be 'ncl') */ char **NCL_ARGV; int NCL_ARGC; /* local argv/argc -- future use for NCL scripts? */ int c; char **cargs = NULL; int nargs = 0; struct stat sbuf; int sr; FILE *tmpf = NULL; /* file variables for creating arguments */ char *tmpd = NULL; strcpy(buffer,(char *)GetNCARGPath("tmp")); sr = access(buffer,W_OK|X_OK|F_OK); if(sr != 0) { NhlPError(NhlWARNING,NhlEUNKNOWN, "\"%s\" tmp dir does not exist or is not writable: NCL functionality may be limited -- check TMPDIR environment variable", buffer); } #ifdef YYDEBUG extern int yydebug; yydebug = 1; #endif /* YYDEBUG */ error_fp = stderr; stdout_fp = stdout; stdin_fp = stdin; ncopts = NC_VERBOSE; cmd_line =isatty(fileno(stdin)); myName = NclMalloc(strlen(argv[0]) + 1); (void) strcpy(myName, argv[0]); /* * Save NCL argv, for command line processing later use */ NCL_ARGV = (char **) NclMalloc(argc * sizeof(char *)); for (i = 0; i < argc; i++) { NCL_ARGV[i] = (char *) NclMalloc((strlen(argv[i]) + 1) * sizeof(char *)); (void) strcpy(NCL_ARGV[i], argv[i]); } NCL_ARGC = argc; for(i = 0; i < _NclNumberOfFileFormats; ++i) NCLadvancedFileStructure[i] = 0; #ifdef NCLDEBUG for (i = 0; i < NCL_ARGC; i++, *NCL_ARGV++) (void) printf("NCL_ARGV[%d] = %s\n", i, *NCL_ARGV); #endif /* NCLDEBUG */ /* * Defined arguments * * -n element print: don't enumerate elements in print() * -x echo: turns on command echo * -V version: output NCARG/NCL version, exit * -o old behavior: retain former behavior for backwards incompatible changes * -h help: output options and exit * * -X override: echo every stmt regardless (unannounced option) * -Q override: don't echo copyright notice (unannounced option) */ opterr = 0; /* turn off getopt() msgs */ while ((c = getopt (argc, argv, "fhnoxVXQp")) != -1) { switch (c) { case 'p': NCLnoSysPager = 1; break; case 'n': NCLnoPrintElem = 1; break; case 'o': NCLoldBehavior = 1; break; case 'x': NCLecho = 1; break; /* NOT ADVERTISED! Will override "no echo" and print EVERYTHING! */ case 'X': NCLoverrideEcho = 1; break; /* NOT ADVERTISED! Will not echo copyright notice! */ case 'Q': NCLnoCopyright = 1; break; case 'V': (void) fprintf(stdout, "%s\n", GetNCLVersion()); exit(0); break; case 'f': for(i = 0; i < _NclNumberOfFileFormats; ++i) NCLadvancedFileStructure[i] = 1; break; case 'h': (void) fprintf(stdout, "Usage: ncl -fhnpxV <args> <file.ncl>\n"); (void) fprintf(stdout, "\t -f: Use New File Structure, and NetCDF4 features\n"); (void) fprintf(stdout, "\t -n: don't enumerate values in print()\n"); (void) fprintf(stdout, "\t -p: don't page output from the system() command\n"); (void) fprintf(stdout, "\t -o: retain former behavior for certain backwards-incompatible changes\n"); (void) fprintf(stdout, "\t -x: echo NCL commands\n"); (void) fprintf(stdout, "\t -V: print NCL version and exit\n"); (void) fprintf(stdout, "\t -h: print this message and exit\n"); exit(0); break; case '?': if (isprint(optopt)) (void) fprintf(stderr, "Unknown option `-%c'\n", optopt); else (void) fprintf(stderr, "Unknown option character `\\x%x'\n", optopt); break; default: break; } } /* * Announce NCL copyright notice, etc. */ if (!NCLnoCopyright) (void) fprintf(stdout, " Copyright (C) 1995-2013 - All Rights Reserved\n University Corporation for Atmospheric Research\n NCAR Command Language Version %s\n The use of this software is governed by a License Agreement.\n See http://www.ncl.ucar.edu/ for more details.\n", GetNCLVersion()); /* Process any user-defined arguments */ for (i = optind; i < argc; i++) { #ifdef NCLDEBUG (void) printf("Non-option argument %s\n", argv[i]); #endif /* NCLDEBUG */ /* * Is this a file of NCL commands? Can't assume ".ncl" tag, unfortunately. * Check for file's existence; the stat() call does not require access rights * but does require search path rights, so if this fails, the file could exist * but the user may not have permission to "see" it. */ sr = stat(argv[i], &sbuf); if (sr == 0) { #ifdef NCLDEBUG (void) printf("NCL commands file: %s\n", argv[i]); #endif /* NCLDEBUG */ nclf = argv[i]; continue; } if (sr < 0) { if (!strchr(argv[i], '=')) { /* argument is intended to be a file; can't locate it */ NhlPError(NhlFATAL, NhlEUNKNOWN, " can't find file \"%s\"\n", argv[i]); exit(NhlFATAL); } else { /* user-defined argument */ if (nargs == 0) cargs = (char **) NclMalloc(sizeof(char *)); else cargs = (char **) NclRealloc(cargs, (nargs + 1) * sizeof(char *)); cargs[nargs] = (char *) NclMalloc((strlen(argv[i]) + 2) * sizeof(char *)); (void) sprintf(cargs[nargs], "%s\n", argv[i]); nargs++; } } } if(nclf){ NCL_PROF_INIT(nclf); } else{ NCL_PROF_INIT("cmdline"); } error_fp = stderr; stdout_fp = stdout; stdin_fp = stdin; cur_line_text = NclMalloc((unsigned int) 512); cur_line_maxsize = 512; cur_line_text_pos = &(cur_line_text[0]); #ifdef NCLDEBUG thefptr = fopen("ncl.tree", "w"); theoptr = fopen("ncl.seq", "w"); #else thefptr = NULL; theoptr = NULL; #endif /* NCLDEBUG */ /* * Note: child processes should use _exit() instead of exit() to avoid calling the atexit() * functions prematurely */ NhlInitialize(); NhlVACreate(&appid, "ncl", NhlappClass, NhlDEFAULT_APP, NhlNappDefaultParent, 1, NhlNappUsrDir, "./", NULL); NhlPalLoadColormapFiles(NhlworkstationClass,False); errid = NhlErrGetID(); NhlVAGetValues(errid, NhlNerrFileName, &tmp, NULL); if ((tmp == NULL) || (!strcmp(tmp, "stderr"))) NhlVASetValues(errid, NhlNerrFilePtr, stdout, NULL); _NclInitMachine(); _NclInitSymbol(); _NclInitTypeClasses(); _NclInitDataClasses(); /* if the -o flag is specified do stuff to make NCL backwards compatible */ if (NCLoldBehavior) { _NclSetDefaultFillValues(NCL_5_DEFAULT_FILLVALUES); } /* Handle default directories */ if ((libpath = getenv("NCL_DEF_LIB_DIR")) != NULL) { d = opendir(_NGResolvePath(libpath)); if (d != NULL) { while((ent = readdir(d)) != NULL) { if (*ent->d_name != '.') { (void) sprintf(buffer, "%s/%s", _NGResolvePath(libpath), ent->d_name); #if defined (HPUX) so_handle = shl_load(buffer, BIND_IMMEDIATE, 0L); #else so_handle = dlopen(buffer, RTLD_NOW); if (so_handle == NULL) { NhlPError(NhlFATAL, NhlEUNKNOWN, "Could not open (%s): %s.", buffer, dlerror()); } #endif /* HPUX */ if (so_handle != NULL) { #if defined (HPUX) init_function = NULL; (void) shl_findsym(&so_handle, "Init", TYPE_UNDEFINED, (void *) &init_function); #else init_function = dlsym(so_handle, "Init"); #endif /* HPUX */ if (init_function != NULL) { (*init_function)(); } else { #if defined (HPUX) shl_unload(so_handle); #else dlclose(so_handle); #endif /* HPUX */ NhlPError(NhlWARNING, NhlEUNKNOWN, "Could not find Init() in external file %s, file not loaded.", buffer); } } } } } else { NhlPError(NhlWARNING, NhlEUNKNOWN, "Could not open default library path (%s), no libraries loaded.", libpath); } _NclResetNewSymStack(); } if (cmd_line == 1) { InitializeReadLine(1); /* * This next line is only to deal with an optimization bug with gcc * version 4.0.1 on MacOS 10.4. It apparently saw that "cmd_line" * was already of value 1 before it went into NclSetPromptFunc, so * when it optimized the code, it ignored the "cmd_line = 1" line * right after the NclSetPromptFunc call. Since NclSetPrompFunc * was setting cmd_line =2, this meant that the value of cmd_line * stayed 2, which is the wrong value. */ cmd_line = 0; NclSetPromptFunc(nclprompt, NULL); cmd_line = 1; cmd_line_is_set = 1; } else { InitializeReadLine(0); } /* Load default scripts */ /* These need to be loaded in alphabetical order to ensure that users can control * the order of loading. There is a BSD function scandir that would do it all but it * might not be standardized enough to be uniformly available on all systems, so for * now it must be coded just using readdir. */ if ((scriptpath = getenv("NCL_DEF_SCRIPTS_DIR")) != NULL) { d = opendir(_NGResolvePath(scriptpath)); if (d!= NULL) { int script_count = 0, alloc_count = 32; NrmQuark *qscript_names = NclMalloc(alloc_count * sizeof(NrmQuark)); while((ent = readdir(d)) != NULL) { if (*ent->d_name != '.') { (void) sprintf(buffer, "%s/%s", _NGResolvePath(scriptpath), ent->d_name); pt = strrchr(buffer, '.'); if (pt != NULL) { pt++; if (strncmp(pt, "ncl", 3) == 0) { if (script_count == alloc_count) { alloc_count *= 2; qscript_names = NclRealloc(qscript_names,alloc_count * sizeof(NrmQuark)); } qscript_names[script_count++] = NrmStringToQuark(ent->d_name); } } } } if (script_count == 0) { NhlPError(NhlWARNING, NhlEUNKNOWN, "No scripts found: scripts must have the \".ncl\" file extension."); } else { qsort(qscript_names,script_count,sizeof(NrmQuark),quark_comp); for (i = 0; i < script_count; i++) { (void) sprintf(buffer, "%s/%s", _NGResolvePath(scriptpath), NrmQuarkToString(qscript_names[i])); if (_NclPreLoadScript(buffer, 1) == NhlFATAL) { NhlPError(NhlFATAL, NhlEUNKNOWN, "Error loading default script."); } else { yyparse(reset); } } NclFree(qscript_names); } } else { NhlPError(NhlWARNING, NhlEUNKNOWN, " Could not open default script path (%s), no scripts loaded.", scriptpath); } } /* * Create the new args * * Ideally this would be done using calls to the parser/stack engine but there is * no clean interface to that process. Investigate _NclParseString() in the future. * * For now, create a temporary file with NCL commands and execute it. */ if (nargs) { cmd_line = 0; /* non-interactive */ tmpd = (char *) _NGGetNCARGEnv("tmp"); /* defaults to: /tmp */ (void) sprintf(buffer, "%s/ncl%d.ncl", tmpd, getpid()); tmpf = fopen(buffer, "w"); for (k = 0; k < nargs; k++) { if ((strstr(cargs[k], "=")) == (char *) NULL) NhlPError(NhlWARNING, NhlEUNKNOWN, " Improper assignment for variable %s", cargs[k]); else (void) fwrite(cargs[k], strlen(cargs[k]), 1, tmpf); } /* don't forget last newline; NCL requires it */ (void) fwrite("\n", 1, 1, tmpf); (void) fclose(tmpf); if (_NclPreLoadScript(buffer, 1) == NhlFATAL) { NhlPError(NhlFATAL, NhlEUNKNOWN, "Error initializing command line arguments."); (void) unlink(buffer); } else { yyparse(reset); } (void) unlink(buffer); cmd_line = 1; /* reset to default: interactive */ } /* Load utility script */ strcpy(buffer, _NGResolvePath("$NCARG_ROOT/lib/ncarg/nclscripts/utilities.ncl")); sr = stat(buffer, &sbuf); if(0 == sr) { if(_NclPreLoadScript(buffer, 1) == NhlFATAL) { NclReturnStatus = NclFileNotFound; NhlPError(NhlINFO, NhlEUNKNOWN, "Error loading NCL utility script."); } else yyparse(reset); } /* Load any provided script */ if (nclf != (char *) NULL) { (void) strcpy(buffer, _NGResolvePath(nclf)); if (_NclPreLoadScript(buffer, 0) == NhlFATAL) { NclReturnStatus = NclFileNotFound; NhlPError(NhlFATAL, NhlEUNKNOWN, "Error loading provided NCL script."); } else yyparse(reset); } else { yyparse(reset); } #ifdef NCLDEBUG (void) fclose(thefptr); (void) fprintf(stdout,"Number of unfreed objects %d\n",_NclNumObjs()); _NclObjsSize(stdout); _NclNumGetObjCals(stdout); _NclPrintUnfreedObjs(theoptr); (void) fprintf(stdout,"Number of constants used %d\n",number_of_constants); (void) fclose(theoptr); #endif /* NCLDEBUG */ NclFree(myName); _NclExit(NclReturnStatus); return NclReturnStatus; }
NhlErrorTypes AddNewGrp(void *rec, NclQuark grpname, size_t id) { NclFileGrpNode *rootgrpnode = (NclFileGrpNode *) rec; NhlErrorTypes ret = NhlNOERROR; NclFileGrpNode *grpnode; NclFileGrpRecord *grprec; int n = -1; char buffer[2 * NC_MAX_NAME + 1]; ret = _addNclGrpNodeToGrpNode(rootgrpnode, grpname); grprec = rootgrpnode->grp_rec; for(n = 0; n < grprec->n_grps; n++) { grpnode = grprec->grp_node[n]; if(grpname == grpnode->name) { break; } else grpnode = NULL; } if(NULL == grpnode) { NHLPERROR((NhlFATAL,NhlEUNKNOWN, "AddNewGrp: can not find group (%s)", NrmQuarkToString(grpname))); return (NhlFATAL); } grpnode->gid = id; grpnode->fid = id; grpnode->pid = rootgrpnode->gid; grpnode->pname = rootgrpnode->name; grpnode->path = rootgrpnode->path; grpnode->extension = rootgrpnode->extension; grpnode->file_format = rootgrpnode->file_format; grpnode->status = rootgrpnode->status; grpnode->open = rootgrpnode->open; grpnode->format = rootgrpnode->format; grpnode->define_mode = rootgrpnode->define_mode; grpnode->compress_level = rootgrpnode->compress_level; grpnode->is_chunked = rootgrpnode->is_chunked; grpnode->use_cache = rootgrpnode->use_cache; grpnode->cache_size = rootgrpnode->cache_size; grpnode->cache_nelems = rootgrpnode->cache_nelems; grpnode->cache_preemption = rootgrpnode->cache_preemption; if(strcmp("/", NrmQuarkToString(grpnode->pname))) { sprintf(buffer, "/%s", NrmQuarkToString(grpname)); } else { sprintf(buffer, "%s%s", NrmQuarkToString(rootgrpnode->real_name), NrmQuarkToString(grpname)); } grpnode->real_name = NrmStringToQuark(buffer); grpnode->n_options = rootgrpnode->n_options; grpnode->options = (NCLOptions *)NclCalloc(rootgrpnode->n_options, sizeof(NCLOptions)); assert(grpnode->options); memcpy(grpnode->options, rootgrpnode->options, rootgrpnode->n_options * sizeof(NCLOptions)); grpnode->chunk_dim_rec = NULL; grpnode->unlimit_dim_rec = NULL; grpnode->dim_rec = NULL; grpnode->att_rec = NULL; grpnode->var_rec = NULL; grpnode->coord_var_rec = NULL; grpnode->grp_rec = NULL; grpnode->udt_rec = NULL; grpnode->parent = rootgrpnode; return ret; }