char *stnvar (char *ch, char *vnam, struct gafile *pfi, struct gavar *pvar, struct gastat *pst) { struct gastn *stn; gadouble dmin[5],dmax[5],d,radius; gaint id[6],dim,size,i,rc,rflag,sflag; char *pos; char stid[10]; rflag = 0; sflag = 0; radius = 0; /* We want to finish parsing the variable name by looking at any dimension settings by the user. First initialize the request environment to that found in the pst. */ for (i=0;i<3;i++) { dmin[i] = pst->dmin[i]; dmax[i] = pst->dmax[i]; } dmin[3] = t2gr(pfi->abvals[3],&(pst->tmin)); dmax[3] = t2gr(pfi->abvals[3],&(pst->tmax)); /* Check for user provided dimension expressions */ if (*ch=='(') { ch++; for (i=0;i<6;i++) id[i] = 0; while (*ch!=')') { if (!cmpch(ch,"stid=",5)) { /* special stid= arg */ for (i=0; i<8; i++) stid[i] = ' '; stid[8] = '\0'; pos = ch+5; i=0; while (*pos!=',' && *pos!=')' && i<8) { stid[i] = *pos; pos++; i++; } if (i==0) { gaprnt (0,"Dimension Expression Error: No stid provided\n"); pos=NULL; } if (i>8) { gaprnt (0,"Dimension Expression Error: stid too long\n"); pos=NULL; } dim=11; } else { pos = dimprs(ch, pst, pfi, &dim, &d, 0, &rc); } if (pos==NULL) { sprintf (pout," Variable name = %s\n",vnam); gaprnt (0,pout); return (NULL); } if (dim<6 && id[dim]>1) { gaprnt (0,"Syntax Error: Invalid dimension expression\n"); gaprnt (0," Same dimension specified more than twice "); sprintf (pout,"for variable = %s\n",vnam); gaprnt (0,pout); return (NULL); } if ( dim==pst->idim || dim==pst->jdim || ( dim>3 && (pst->idim==0 || pst->idim==1 || pst->jdim==1))) { gaprnt (0,"Data Request Error: Invalid dimension expression\n"); gaprnt (0," Attempt to set or modify varying dimension\n"); sprintf (pout," Variable = %s, Dimension = %i \n",vnam,dim); gaprnt (0,pout); return (NULL); } if (dim==10) { rflag = 1; radius = d; } else if (dim==11) { sflag = 1; } else { if (id[dim]==0) dmin[dim] = d; dmax[dim] = d; } ch = pos; if (*ch == ',') ch++; id[dim]++; } ch++; } /* Verify that dmin is less than or equal to dmax for all our dims */ for (i=0; i<4; i++) { if ((i!=2 && dmin[i]>dmax[i]) || (i==2 && dmax[i]>dmin[i])) { gaprnt (0,"Data Request Error: Invalid grid coordinates\n"); sprintf (pout," Varying dimension %i decreases: %g to %g \n",i,dmin[i],dmax[i]); gaprnt (0,pout); sprintf (pout," Error ocurred getting variable '%s'\n",vnam); gaprnt (0,pout); return (NULL); } } /* Looks like the user specified good stuff, and we are ready to try to get some data. Allocate and fill in a gastn block. */ size = sizeof(struct gastn); stn = (struct gastn *)galloc(size,"stn"); if (stn==NULL) { gaprnt (0,"Memory Allocation Error: Station Request Block \n"); return (NULL); } stn->rnum = 0; stn->rpt = NULL; stn->pfi = pfi; stn->idim = pst->idim; stn->jdim = pst->jdim; stn->undef = pfi->undef; stn->tmin = dmin[3]; stn->tmax = dmax[3]; stn->ftmin = dmin[3]; stn->ftmax = dmax[3]; stn->pvar = pvar; for (i=0; i<3; i++) { stn->dmin[i] = dmin[i]; stn->dmax[i] = dmax[i]; } stn->rflag = rflag; stn->radius = radius; stn->sflag = sflag; if (sflag) { for (i=0; i<8; i++) stn->stid[i] = stid[i]; } stn->tvals = (gadouble *)galloc(sizeof(gadouble)*8,"stntvals"); if (stn->tvals==NULL) { gree(stn,"f170"); gaprnt (0,"Memory Allocation Error: Station Request Block \n"); return (NULL); } for (i=0; i<8; i++) *(stn->tvals+i) = *(pfi->grvals[3]+i); rc = gagstn (stn); if (rc) { sprintf (pout,"Data Request Error: Variable is '%s'\n",vnam); gaprnt (0,pout); gree(stn,"f171"); return (NULL); } pst->result.stn = stn; pst->type = 0; return (ch); }
struct gastn *gastop (struct gastn *stn1, struct gastn *stn2, gaint op, gaint rel) { struct gastn *stn; struct garpt *rpt1,*rpt2; gaint swap,i,j,flag,dimtyp; /* Verify dimension environment */ if (stn1->idim==0 && stn1->jdim==1 && stn2->idim==0 && stn2->jdim==1) dimtyp = 1; /* X and Y are varying */ else if (stn1->idim==2 && stn1->jdim==-1 && stn2->idim==2 && stn2->jdim==-1) dimtyp = 2; /* Z is varying */ else if (stn1->idim==3 && stn1->jdim==-1 && stn2->idim==3 && stn2->jdim==-1) dimtyp = 3; /* T is varying */ else { gaprnt (0,"Invalid dimension environment for station data"); gaprnt (0," operation\n"); return (NULL); } /* Set it up so first stn set has fewer stations */ swap=0; if (stn1->rnum > stn2->rnum) { stn=stn1; stn1=stn2; stn2=stn; swap=1; } /* Loop through stations of 1st station set. Find matching stations in 2nd station set. If a match, perform operation. Any duplicates in the 2nd station set get ignored. */ rpt1 = stn1->rpt; for (i=0; i<stn1->rnum; i++,rpt1=rpt1->rpt) { if (rpt1->umask == 0) continue; flag = 0; rpt2 = stn2->rpt; for (j=0; j<stn2->rnum; j++,rpt2=rpt2->rpt) { if (rpt2->umask == 0) continue; if (dimtyp==1 && dequal(rpt1->lat,rpt2->lat,1e-08)!=0) continue; if (dimtyp==1 && dequal(rpt1->lon,rpt2->lon,1e-08)!=0) continue; if (dimtyp==2 && dequal(rpt1->lev,rpt2->lev,1e-08)!=0) continue; if (dimtyp==3 && dequal(rpt1->tim,rpt2->tim,1e-08)!=0) continue; if (op==2) rpt1->val = rpt1->val + rpt2->val; else if (op==0) rpt1->val = rpt1->val * rpt2->val; else if (op==1) { if (swap) { if (dequal(rpt1->val,0.0,1e-08)==0) rpt1->umask = 0; else rpt1->val = rpt2->val / rpt1->val; } else { if (dequal(rpt2->val,0.0,1e-08)==0) rpt1->umask = 0; else rpt1->val = rpt1->val / rpt2->val; } } else if (op==10) { if (swap) rpt1->val = pow(rpt2->val,rpt1->val); else rpt1->val = pow(rpt1->val,rpt2->val); } else if (op==11) rpt1->val = hypot(rpt1->val,rpt2->val); else if (op==12) { if ((dequal(rpt1->val,0.0,1e-08)==0) && (dequal(rpt2->val,0.0,1e-08)==0)) rpt1->val = 0.0; else rpt1->val = atan2(rpt1->val,rpt2->val); } else if (op==13) { if (swap) { if (rpt1->val<0.0) rpt1->umask = 0; else rpt1->val = rpt2->val; } else { if (rpt2->val<0.0) rpt1->umask = 0; } } else { gaprnt (0,"Internal logic check 57: invalid oper value\n"); return (NULL); } flag=1; break; } if (!flag) rpt1->umask = 0; } /* Release storage if requested then return */ if (rel) { for (i=0; i<BLKNUM; i++) { if (stn2->blks[i] != NULL) gree(stn2->blks[i],"f168"); } gree(stn2,"f169"); } return (stn1); }
void *Importbinary(void *argument) { int streamID; int gridID = -1, zaxisID, zaxisIDsfc, taxisID, vlistID; int i; int nmiss = 0, n_nan; int ivar; int varID = -1, levelID, tsID; int gridsize; int status; int datatype; dsets_t pfi; int vdate, vtime; int tcur, told,fnum; int tmin=0,tmax=0; char *ch = NULL; int nvars, nlevels, nrecs; int recID; int e, flag; size_t rc, recsize; int recoffset; char *rec = NULL; struct gavar *pvar; struct dt dtim, dtimi; double missval; double fmin, fmax; double *array; double sfclevel = 0; int *recVarID, *recLevelID; int *var_zaxisID; int *var_dfrm = NULL; char vdatestr[32], vtimestr[32]; cdoInitialize(argument); dsets_init(&pfi); status = read_gradsdes(cdoStreamName(0)->args, &pfi); if ( cdoVerbose ) fprintf(stderr, "status %d\n", status); //if ( status ) cdoAbort("Open failed on %s!", pfi.name); if ( status ) cdoAbort("Open failed!"); nrecs = pfi.trecs; nvars = pfi.vnum; pvar = pfi.pvar1; if ( nvars == 0 ) cdoAbort("No variables found!"); gridID = define_grid(&pfi); if ( cdoVerbose ) gridPrint(gridID, gridID, 1); zaxisID = define_level(&pfi, 0); if ( cdoVerbose ) zaxisPrint(zaxisID, zaxisID); zaxisIDsfc = zaxisCreate(ZAXIS_SURFACE, 1); zaxisDefLevels(zaxisIDsfc, &sfclevel); vlistID = vlistCreate(); var_zaxisID = (int*) malloc(nvars*sizeof(int)); recVarID = (int*) malloc(nrecs*sizeof(int)); recLevelID = (int*) malloc(nrecs*sizeof(int)); var_dfrm = (int*) malloc(nrecs*sizeof(int)); recID = 0; for ( ivar = 0; ivar < nvars; ++ivar ) { /* if ( cdoVerbose ) fprintf(stderr, "1:%s 2:%s %d %d %d %d 3:%s %d \n", pvar->abbrv, pvar->longnm, pvar->offset, pvar->recoff, pvar->levels, pvar->nvardims, pvar->varnm, pvar->var_t); */ nlevels = pvar->levels; if ( nlevels == 0 ) { nlevels = 1; varID = vlistDefVar(vlistID, gridID, zaxisIDsfc, TSTEP_INSTANT); } else { if ( nlevels > zaxisInqSize(zaxisID) ) cdoAbort("Variable %s has too many number of levels!", pvar->abbrv); else if ( nlevels < zaxisInqSize(zaxisID) ) { int vid, zid = -1, nlev; for ( vid = 0; vid < ivar; ++vid ) { zid = var_zaxisID[vid]; nlev = zaxisInqSize(zid); if ( nlev == nlevels ) break; } if ( vid == ivar ) zid = define_level(&pfi, nlevels); varID = vlistDefVar(vlistID, gridID, zid, TSTEP_INSTANT); } else varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT); } var_zaxisID[varID] = vlistInqVarZaxis(vlistID, varID); vlistDefVarName(vlistID, varID, pvar->abbrv); { size_t len = strlen(pvar->varnm); char *longname = pvar->varnm; if ( longname[0] == '\'' && longname[len-1] == '\'' ) { longname[len-1] = 0; longname++; } vlistDefVarLongname(vlistID, varID, longname); } missval = pfi.undef; datatype = DATATYPE_FLT32; if ( pvar->dfrm == 1 ) { datatype = DATATYPE_UINT8; if ( missval < 0 || missval > 255 ) missval = 255; } else if ( pvar->dfrm == 2 ) { datatype = DATATYPE_UINT16; if ( missval < 0 || missval > 65535 ) missval = 65535; } else if ( pvar->dfrm == -2 ) { datatype = DATATYPE_INT16; if ( missval < -32768 || missval > 32767 ) missval = -32768; } else if ( pvar->dfrm == 4 ) { datatype = DATATYPE_INT32; if ( missval < -2147483648 || missval > 2147483647 ) missval = -2147483646; } else if ( pfi.flt64 ) datatype = DATATYPE_FLT64; vlistDefVarDatatype(vlistID, varID, datatype); vlistDefVarMissval(vlistID, varID, missval); for ( levelID = 0; levelID < nlevels; ++levelID ) { if ( recID >= nrecs ) cdoAbort("Internal problem with number of records!"); recVarID[recID] = varID; recLevelID[recID] = levelID; var_dfrm[recID] = pvar->dfrm; recID++; } pvar++; } taxisID = taxisCreate(TAXIS_RELATIVE); taxisDefCalendar(taxisID, CALENDAR_STANDARD); vlistDefTaxis(vlistID, taxisID); streamID = streamOpenWrite(cdoStreamName(1), cdoFiletype()); streamDefVlist(streamID, vlistID); gridsize = pfi.dnum[0]*pfi.dnum[1]; if ( pfi.flt64 ) recoffset = pfi.xyhdr*8; else recoffset = pfi.xyhdr*4; if ( pfi.seqflg ) recoffset += 4; //recsize = pfi.gsiz*4; recsize = pfi.gsiz*8; rec = (char*) malloc(recsize); array = (double*) malloc(gridsize*sizeof(double)); /* if (pfi.tmplat) for ( i = 0; i < pfi.dnum[3]; ++i ) printf("%d %d\n", i, pfi.fnums[i]); */ pfi.infile = NULL; tcur = 0; e = 1; while (1) { /* loop over all times for this ensemble */ if (pfi.tmplat) { /* make sure no file is open */ if (pfi.infile!=NULL) { fclose(pfi.infile); pfi.infile=NULL; } /* advance to first valid time step for this ensemble */ if (tcur==0) { told = 0; tcur = 1; while (pfi.fnums[tcur-1] == -1) tcur++; } else { /* tcur!=0 */ told = pfi.fnums[tcur-1]; /* increment time step until fnums changes */ while (told==pfi.fnums[tcur-1] && tcur<=pfi.dnum[3]) { tcur++; if ( tcur > pfi.dnum[3] ) break; } } /* make sure we haven't advanced past end of time axis */ if (tcur>pfi.dnum[3]) break; /* check if we're past all valid time steps for this ensemble */ if ((told != -1) && (pfi.fnums[tcur-1] == -1)) break; /* Find the range of t indexes that have the same fnums value. These are the times that are contained in this particular file */ tmin = tcur; tmax = tcur-1; fnum = pfi.fnums[tcur-1]; if (fnum != -1) { while (fnum == pfi.fnums[tmax]) { tmax++; if (tmax == pfi.dnum[3]) break; } gr2t(pfi.grvals[3], (gadouble)tcur, &dtim); gr2t(pfi.grvals[3], (gadouble)1, &dtimi); ch = gafndt(pfi.name, &dtim, &dtimi, pfi.abvals[3], pfi.pchsub1, NULL,tcur,e,&flag); if (ch==NULL) cdoAbort("Couldn't determine data file name for e=%d t=%d!",e,tcur); } } else { /* Data set is not templated */ ch = pfi.name; tmin = 1; tmax = pfi.dnum[3]; } /* Open this file and position to start of first record */ if ( cdoVerbose) cdoPrint("Opening file: %s", ch); pfi.infile = fopen(ch,"rb"); if (pfi.infile==NULL) { if (pfi.tmplat) { cdoWarning("Could not open file: %s",ch); break; } else { cdoAbort("Could not open file: %s",ch); } } if (pfi.tmplat) gree(ch,"312"); /* file header */ if (pfi.fhdr > 0) fseeko(pfi.infile, pfi.fhdr, SEEK_SET); /* Get file size */ /* fseeko(pfi.infile,0L,2); flen = ftello(pfi.infile); printf("flen %d tsiz %d\n", flen, pfi.tsiz); fseeko (pfi.infile,0,0); */ for ( tsID = tmin-1; tsID < tmax; ++tsID ) { gr2t(pfi.grvals[3], (gadouble)(tsID+1), &dtim); vdate = cdiEncodeDate(dtim.yr, dtim.mo, dtim.dy); vtime = cdiEncodeTime(dtim.hr, dtim.mn, 0); date2str(vdate, vdatestr, sizeof(vdatestr)); time2str(vtime, vtimestr, sizeof(vtimestr)); if ( cdoVerbose ) cdoPrint(" Reading timestep: %3d %s %s", tsID+1, vdatestr, vtimestr); taxisDefVdate(taxisID, vdate); taxisDefVtime(taxisID, vtime); streamDefTimestep(streamID, tsID); for ( recID = 0; recID < nrecs; ++recID ) { /* record size depends on data type */ if (var_dfrm[recID] == 1) { recsize = pfi.gsiz; } else if ((var_dfrm[recID] == 2) || (var_dfrm[recID] == -2)) { recsize = pfi.gsiz*2; } else { if ( pfi.flt64 ) recsize = pfi.gsiz*8; else recsize = pfi.gsiz*4; } rc = fread (rec, 1, recsize, pfi.infile); if ( rc < recsize ) cdoAbort("I/O error reading record=%d of timestep=%d!", recID+1, tsID+1); /* convert */ if (var_dfrm[recID] == 1) { unsigned char *carray = (void*)(rec + recoffset); for (i = 0; i < gridsize; ++i) array[i] = (double) carray[i]; } else if (var_dfrm[recID] == 2) { unsigned short *sarray = (void*)(rec + recoffset); if (pfi.bswap) gabswp2(sarray, gridsize); for (i = 0; i < gridsize; ++i) array[i] = (double) sarray[i]; } else if (var_dfrm[recID] == -2) { short *sarray = (void*)(rec + recoffset); if (pfi.bswap) gabswp2(sarray, gridsize); for (i = 0; i < gridsize; ++i) array[i] = (double) sarray[i]; } else if (var_dfrm[recID] == 4) { int *iarray = (void*)(rec + recoffset); if (pfi.bswap) gabswp(iarray, gridsize); for (i = 0; i < gridsize; ++i) array[i] = (double) iarray[i]; } else { if ( pfi.flt64 ) { double *darray = (double *) (rec + recoffset); if (pfi.bswap) gabswp(darray, gridsize); for ( i = 0; i < gridsize; ++i ) array[i] = darray[i]; } else { float *farray = (float *) (rec + recoffset); if (pfi.bswap) gabswp(farray, gridsize); for ( i = 0; i < gridsize; ++i ) array[i] = (double) farray[i]; } } fmin = 1.e99; fmax = -1.e99; nmiss = 0; n_nan = 0; for ( i = 0; i < gridsize; ++i ) { if ( array[i] > pfi.ulow && array[i] < pfi.uhi ) { array[i] = pfi.undef; nmiss++; } else if ( DBL_IS_NAN(array[i]) ) { array[i] = pfi.undef; nmiss++; n_nan++; } else { if ( array[i] < fmin ) fmin = array[i]; if ( array[i] > fmax ) fmax = array[i]; } } /* if ( cdoVerbose ) printf("%3d %4d %3d %6d %6d %12.5g %12.5g\n", tsID, recID, recoffset, nmiss, n_nan, fmin, fmax); */ varID = recVarID[recID]; levelID = recLevelID[recID]; streamDefRecord(streamID, varID, levelID); streamWriteRecord(streamID, array, nmiss); } } /* break out if not templating */ if (!pfi.tmplat) break; } /* end of while (1) loop */ processDefVarNum(vlistNvars(vlistID), streamID); streamClose(streamID); vlistDestroy(vlistID); gridDestroy(gridID); zaxisDestroy(zaxisID); taxisDestroy(taxisID); free(array); free(rec); if ( var_zaxisID ) free(var_zaxisID); if ( recVarID ) free(recVarID); if ( recLevelID ) free(recLevelID); if ( var_dfrm ) free(var_dfrm); cdoFinish(); return (0); }