/* addthis.c This is a sample user defined plug-in function for use with GrADS. It does a very basic task: it adds a number to all the non-missing values in a GrADS expression, which may be for gridded or station data. The function takes two arguments: the first is the GrADS expression and the second is the number to add to the result of the expression. Example: 'define tempf=addthis(tempc*9/5,32)' ************************************************************************ Instructions for compiling this sample program are in the documentation: http://cola.gmu.edu/grads/gadoc/udp.html#compile ************************************************************************ GrADS plug-in functions are passed pointers to three data structures : 1. gafunc -- contains info about the function call including the number of arguments and pointers to the argument strings 2. gastat -- the GrADS status structure contains pointers to file structures and defined variables, the current dimension environment, and results from expression evaluations 3. gaudpinfo -- used for keeping track of plug-in compatibility These structures are defined in the main GrADS include file, grads.h, which is why that file must be included here. ************************************************************************ This plug-in also uses some internal GrADS functions: 1. gaprnt -- prints messages that can be captured by the scripting language 2. getdbl -- parses a string and converts it to a double-precision number 3. gaexpr -- evaluates the GrADS expression and does the required I/O ************************************************************************/ #include "grads.h" gaint addthis (struct gafunc *pfc, struct gastat *pst, struct gaudpinfo *pinfo) { gaint i,rc; struct gagrid *pgr; struct gastn *stn; struct garpt *rpt; gadouble *val,addend; char *valu; /* Check if this plug-in is still compatible with the GrADS interface */ if (pinfo->version != UDPVERS) printf("Error: version mismatch. Recompile this plug-in\n"); /* Check for the proper number of arguments */ if (pfc->argnum!=2) { gaprnt (0,"Error from ADDTHIS: Two arguments expected. \n"); return (1); } /* Parse the second argument, which should be a number */ if (getdbl(pfc->argpnt[1],&addend) == NULL) { gaprnt (0,"Error from ADDTHIS: the user-provided addend is not a number\n"); return (1); } /* Invoke gaexpr to evaluate the first argument, which should be a GrADS expression. The reuslt gets stored in the gastat structure 'pst' */ rc = gaexpr(pfc->argpnt[0],pst); if (rc) return (rc); /* If the expression is a grid ... */ if (pst->type==1) { /* Set up pointers to the gridded data structure, the grid of data, and the undef mask */ pgr = pst->result.pgr; val = pgr->grid; valu = pgr->umask; /* Loop over all grid points */ for (i=0; iisiz*pgr->jsiz; i++) { /* Add the user-provided number to the non-missing grid values */ if (*valu!=0) *val = addend+(*val); val++; valu++; } } /* ...the expression is station data */ else { /* Set up pointers to the station data structure and the report chain */ stn = pst->result.stn; rpt = stn->rpt; /* Loop over all reports */ while (rpt!=NULL) { /* Add the user-provided number to the non-missing station values */ if (rpt->umask!=0) rpt->val = addend+(rpt->val); rpt=rpt->rpt; } } /* finish without errors */ return (0); }