void copyAttributes(NclFileAttInfoList **out, NclFileAttInfoList *in) { NclFileAttInfoList *att_list; NclFileAttInfoList *new_list; *out = NULL; att_list = in; while(att_list) { new_list = (NclFileAttInfoList *) NclMalloc(sizeof(NclFileAttInfoList)); new_list->the_att = (struct _NclFAttRec *) NclMalloc(sizeof(struct _NclFAttRec)); new_list->the_att->att_name_quark = att_list->the_att->att_name_quark; new_list->the_att->data_type = att_list->the_att->data_type; new_list->the_att->num_elements = att_list->the_att->num_elements; /* *fprintf(stdout, "\tnew_list->the_att->att_name_quark: <%s>\n", * NrmQuarkToString(new_list->the_att->att_name_quark)); */ new_list->next = *out; *out = new_list; att_list = att_list->next; } }
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; }
struct _FileCallBackRec *getFileCallBack(struct _FileCallBackRec *in_fcb) { struct _FileCallBackRec *out_fcb = NULL; if(in_fcb != NULL) { out_fcb = (struct _FileCallBackRec *)NclMalloc(sizeof(struct _FileCallBackRec)); out_fcb->thefileid = in_fcb->thefileid; out_fcb->theattid = in_fcb->theattid; out_fcb->thevar = in_fcb->thevar; } return (out_fcb); }
struct _NclFGrpRec *getGrpRec(struct _NclFGrpRec *in_grp_info) { int n = 0; struct _NclFGrpRec *out_grp_info; out_grp_info = (struct _NclFGrpRec *)NclMalloc(sizeof(struct _NclFGrpRec)); out_grp_info->grp_name_quark = in_grp_info->grp_name_quark; out_grp_info->grp_real_name_quark = in_grp_info->grp_real_name_quark; out_grp_info->grp_full_name_quark = in_grp_info->grp_full_name_quark; out_grp_info->data_type = in_grp_info->data_type; out_grp_info->num_dimensions = in_grp_info->num_dimensions; for(n = 0; n < in_grp_info->num_dimensions; n++) out_grp_info->file_dim_num[n] = in_grp_info->file_dim_num[n]; return (out_grp_info); }
struct _NclFVarRec *getVarRec(struct _NclFVarRec *in_var_info) { int n = 0; struct _NclFVarRec *out_var_info; out_var_info = (struct _NclFVarRec *)NclMalloc(sizeof(struct _NclFVarRec)); out_var_info->var_name_quark = in_var_info->var_name_quark; out_var_info->var_real_name_quark = in_var_info->var_real_name_quark; out_var_info->var_full_name_quark = in_var_info->var_full_name_quark; out_var_info->data_type = in_var_info->data_type; out_var_info->num_dimensions = in_var_info->num_dimensions; out_var_info->num_compounds = in_var_info->num_compounds; for(n = 0; n < in_var_info->num_dimensions; n++) out_var_info->file_dim_num[n] = in_var_info->file_dim_num[n]; for(n = 0; n < in_var_info->num_compounds; n++) { out_var_info->component_name[n] = in_var_info->component_name[n]; out_var_info->component_type[n] = in_var_info->component_type[n]; } return (out_var_info); }
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); }
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); }
void getNclFileVarInfo(NclFile thefile, int *ndims, int **dimsizes, char ***dimnames, long *type) { int i,j; if(NULL == thefile) return; if(thefile->file.advanced_file_structure) { NclAdvancedFile thenewfile = (NclAdvancedFile) thefile; NclFileVarNode *varnode = NULL; if(NULL != thenewfile->advancedfile.grpnode->var_rec) { for(i = 0; i < thenewfile->advancedfile.grpnode->var_rec->n_vars; ++i) { varnode = &(thenewfile->advancedfile.grpnode->var_rec->var_node[i]); ndims[i] = 0; type[i] = (long) varnode->type; if(NULL != varnode->dim_rec) { ndims[i] = varnode->dim_rec->n_dims; for(j = 0 ; j < ndims[i]; ++j) { strcpy(dimnames[i][j], NrmQuarkToString(varnode->dim_rec->dim_node[j].name)); dimsizes[i][j] = varnode->dim_rec->dim_node[j].size; } } #if 0 if(NULL != varnode->att_rec) { tmp->u.var->n_atts = varnode->att_rec->n_atts; tmp->u.var->attnames = (NclQuark*)NclMalloc(tmp->u.var->n_atts * sizeof(NclQuark)); for(j = 0; j < tmp->u.var->n_atts; ++j) { tmp->u.var->attnames[j] = varnode->att_rec->att_node[j].name; } } #endif } } } else { /* *fprintf(stderr, "file %s, line: %d\n", __FILE__, __LINE__); *fprintf(stderr, "\tnumber of vars = %d\n", thefile->file.n_vars); */ for(i = 0; i < thefile->file.n_vars; ++i) { type[i] = (long) thefile->file.var_info[i]->data_type; ndims[i] = thefile->file.var_info[i]->num_dimensions; for(j = 0; j < ndims[i]; ++j) { strcpy(dimnames[i][j], NrmQuarkToString(thefile->file.file_dim_info[thefile->file.var_info[i]->file_dim_num[j]]->dim_name_quark)); dimsizes[i][j] = thefile->file.file_dim_info[thefile->file.var_info[i]->file_dim_num[j]]->dim_size; /* *if(NULL != thefile->file.coord_vars[thefile->file.var_info[i]->file_dim_num[j]]) *{ * tmp->u.var->coordnames[j] = thefile->file.file_dim_info[thefile->file.var_info[i]->file_dim_num[j]]->dim_name_quark; *} *else *{ * tmp->u.var->coordnames[j] = -1; *} */ } #if 0 if(NULL != thefile->file.var_att_info[i]) { j = 0; step = thefile->file.var_att_info[i]; while(NULL != step) { step = step->next; j++; } tmp->u.var->n_atts = j; tmp->u.var->attnames = (NclQuark*)NclMalloc(sizeof(NclQuark)*j); step = thefile->file.var_att_info[i]; j = 0; while(NULL != step) { tmp->u.var->attnames[j]= step->the_att->att_name_quark; j++; step = step->next; } } #endif } } }
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 dim_gamfit_n_W( void ) { /* * Input variables */ /* * Argument # 0 */ void *x; double *tmp_x; int ndims_x; ng_size_t dsizes_x[NCL_MAX_DIMENSIONS]; int has_missing_x; NclScalar missing_x, missing_flt_x, missing_dbl_x; NclBasicDataTypes type_x; /* * Argument # 1 */ logical *optgam; /* * Argument # 2 */ int *dims; ng_size_t dsizes_dims; /* * Return variable */ void *xpar; int ndims_xpar; ng_size_t *dsizes_xpar; NclScalar missing_xpar; NclBasicDataTypes type_xpar; /* * Variables for retrieving attributes from "optgam"; */ NclAttList *attr_list; NclAtt attr_obj; NclStackEntry stack_entry; /* * Various */ ng_size_t npts; int inpts; ng_size_t index_x, index_xpar, index_nrx, index_nr; double *pcrit = NULL; logical set_pcrit; double alpha, scale, shape, pzero; int inv_scale, ier, ret; ng_size_t i, j, nrnx, total_nr, total_nl, total_nlnr, size_output; /* * Retrieve parameters. * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. */ /* * Get argument # 0 */ x = (void*)NclGetArgValue( 0, 3, &ndims_x, dsizes_x, &missing_x, &has_missing_x, &type_x, DONT_CARE); /* * Get argument # 1 */ optgam = (logical*)NclGetArgValue( 1, 3, NULL, NULL, NULL, NULL, NULL, DONT_CARE); /* * Get dimension(s) to do computation on. */ dims = (int*)NclGetArgValue( 2, 3, NULL, &dsizes_dims, NULL, NULL, NULL, DONT_CARE); /* * Some error checking. Make sure input dimensions are valid. */ for(i = 0; i < dsizes_dims; i++ ) { if(dims[i] < 0 || dims[i] >= ndims_x) { NhlPError(NhlFATAL,NhlEUNKNOWN,"dim_gamfit_n: Invalid dimension sizes to do calculations across, can't continue"); return(NhlFATAL); } if(i > 0 && dims[i] != (dims[i-1]+1)) { NhlPError(NhlFATAL,NhlEUNKNOWN,"dim_gamfit_n: Input dimension sizes must be monotonically increasing, can't continue"); return(NhlFATAL); } } /* * Calculate size of leftmost dimensions (nl) up to the dims[0]-th * dimensions. * * Calculate number of points that will be passed to Fortran * routine (npts). * * Calculate size of rightmost dimensions (nr) from the * ndims[ndims-1]-th dimension. * * The dimension(s) to do the calculations across are "dims". */ total_nl = total_nr = npts = 1; if(ndims_x > 1) { ndims_xpar = ndims_x-dsizes_dims+1; dsizes_xpar = NclMalloc(ndims_xpar * sizeof(ng_size_t)); dsizes_xpar[0] = 3; for(i = 0; i < dims[0] ; i++) { total_nl = total_nl*dsizes_x[i]; dsizes_xpar[i+1] = dsizes_x[i]; } for(i = 0; i < dsizes_dims ; i++) { npts = npts*dsizes_x[dims[i]]; } for(i = dims[dsizes_dims-1]+1; i < ndims_x; i++) { total_nr = total_nr*dsizes_x[i]; dsizes_xpar[i-dsizes_dims+1] = dsizes_x[i]; } } else { dsizes_xpar = NclMalloc(sizeof(ng_size_t)); *dsizes_xpar = 3; ndims_xpar = 1; npts = dsizes_x[dims[0]]; } total_nlnr = total_nl * total_nr; size_output = 3 * total_nlnr; if( npts > INT_MAX) { NhlPError(NhlFATAL,NhlEUNKNOWN,"dim_gamfit_n: npts is greater than INT_MAX"); return(NhlFATAL); } inpts = (int) npts; /* * Allocate space for tmp_x. */ tmp_x = (double *)calloc(npts,sizeof(double)); if(tmp_x == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"dim_gamfit_n: Unable to allocate memory for coercing input array to double"); return(NhlFATAL); } /* * Coerce missing value to double if necessary. */ coerce_missing(type_x,has_missing_x,&missing_x, &missing_dbl_x,&missing_flt_x); /* * Allocate space for output array. */ if(type_x != NCL_double) { type_xpar = NCL_float; xpar = (void *)calloc(size_output, sizeof(float)); } else { type_xpar = NCL_double; xpar = (void *)calloc(size_output, sizeof(double)); } if(xpar == NULL) { NhlPError(NhlFATAL,NhlEUNKNOWN,"dim_gamfit_n: Unable to allocate memory for output array"); return(NhlFATAL); } if(has_missing_x) { if(type_xpar == NCL_double) missing_xpar = missing_dbl_x; else missing_xpar = missing_flt_x; } /* * Retrieve attributes from optgam, if any. */ set_pcrit = False; inv_scale = 0; if(*optgam) { stack_entry = _NclGetArg(1, 3, 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. */ break; } /* * Check for attributes. If none are set, then use default values. */ if (attr_obj->att.n_atts == 0) { break; } else { /* * Get list of attributes. */ attr_list = attr_obj->att.att_list; /* * Loop through attributes and check them. */ while (attr_list != NULL) { /* * pcrit */ if ((strcmp(attr_list->attname, "pcrit")) == 0) { pcrit = coerce_input_double(attr_list->attvalue->multidval.val, attr_list->attvalue->multidval.data_type, 1,0,NULL,NULL); set_pcrit = True; } /* * inv_scale */ if ((strcmp(attr_list->attname, "inv_scale")) == 0) { if(attr_list->attvalue->multidval.data_type != NCL_logical) { NhlPError(NhlWARNING,NhlEUNKNOWN,"dim_gamfit_n: the 'inv_scale' attribute must be a logical, defaulting to False."); } else if(*(logical*)attr_list->attvalue->multidval.val) { inv_scale = 1; } } attr_list = attr_list->next; } } default: break; } } if(!set_pcrit) { pcrit = (double *)calloc(1,sizeof(double)); *pcrit = 0.0; } /* * Loop across leftmost dimensions and call the Fortran routine for each * subsection of the input arrays. */ nrnx = total_nr * npts; for(i = 0; i < total_nl; i++) { index_nrx = i*nrnx; index_nr = i*total_nr; for(j = 0; j < total_nr; j++) { index_x = index_nrx + j; index_xpar = index_nr + j; /* * Coerce subsection of x (tmp_x) to double. */ coerce_subset_input_double_step(x,tmp_x,index_x,total_nr,type_x, npts,0,NULL,NULL); /* * Call the Fortran routine. */ NGCALLF(gamfitd3,GAMFITD3)(tmp_x, &inpts, &missing_dbl_x.doubleval, pcrit, &inv_scale, &alpha, &scale, &shape, &pzero, &ier); /* * Coerce output back to float or double */ coerce_output_float_or_double(xpar,&shape,type_xpar,1,index_xpar); coerce_output_float_or_double(xpar,&scale,type_xpar,1, index_xpar+total_nlnr); coerce_output_float_or_double(xpar,&pzero,type_xpar,1, index_xpar+(2*total_nlnr)); } } /* * Free unneeded memory. */ NclFree(tmp_x); /* * Return value back to NCL script. */ if(has_missing_x) { ret = NclReturnValue(xpar,ndims_xpar,dsizes_xpar,&missing_xpar, type_xpar,0); } else { ret = NclReturnValue(xpar,ndims_xpar,dsizes_xpar,NULL,type_xpar,0); } NclFree(dsizes_xpar); return(ret); }
NhlErrorTypes rdsstoi_W( void ) { /* * Input array variables */ int *nyrstrt, *nyrlast, *mlon, *nlat, *info; /* * Output array variables */ float *sstoi; int ndims_sstoi = 2; ng_size_t dsizes_sstoi[2] = {180,360}; /* * Retrieve parameters * * Note any of the pointer parameters can be set to NULL, which * implies you don't care about its value. */ nyrstrt = (int*)NclGetArgValue( 0, 5, NULL, NULL, NULL, NULL, NULL, DONT_CARE); nyrlast = (int*)NclGetArgValue( 1, 5, NULL, NULL, NULL, NULL, NULL, DONT_CARE); mlon= (int*)NclGetArgValue( 2, 5, NULL, NULL, NULL, NULL, NULL, DONT_CARE); nlat= (int*)NclGetArgValue( 3, 5, NULL, NULL, NULL, NULL, NULL, DONT_CARE); info = (int*)NclGetArgValue( 4, 5, NULL, NULL, NULL, NULL, NULL, 1); /* * Allocate space for output array. */ sstoi = (float*)NclMalloc(360*180*sizeof(float)); if( sstoi == NULL ) { NhlPError(NhlFATAL,NhlEUNKNOWN,"rdsstoi: Unable to allocate memory for output array"); return(NhlFATAL); } NGCALLF(rdsstoi,RDSSTOI)(nyrstrt,nyrlast,mlon,nlat,info,sstoi); return(NclReturnValue((void*)sstoi,ndims_sstoi,dsizes_sstoi,NULL,NCL_float,0)); }
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); }