gaint gagchk (struct gagrid *pgr1, struct gagrid *pgr2, gaint dim) { gadouble gmin1,gmax1,gmin2,gmax2,fuz1,fuz2,fuzz; gadouble (*conv1) (gadouble *, gadouble); gadouble (*conv2) (gadouble *, gadouble); gadouble *vals1, *vals2; gaint i1,i2,i,siz1,siz2; struct dt dtim1,dtim2; if (dim<0) return(0); if (dim==pgr1->idim) { conv1 = pgr1->igrab; vals1 = pgr1->ivals; i1 = pgr1->ilinr; siz1 = pgr1->isiz; } else if (dim==pgr1->jdim) { conv1 = pgr1->jgrab; vals1 = pgr1->jvals; i1 = pgr1->jlinr; siz1 = pgr1->jsiz; } else return (1); if (dim==pgr2->idim) { conv2 = pgr2->igrab; vals2 = pgr2->ivals; i2 = pgr2->ilinr; siz2 = pgr2->isiz; } else if (dim==pgr2->jdim) { conv2 = pgr2->jgrab; vals2 = pgr2->jvals; i2 = pgr2->jlinr; siz2 = pgr2->jsiz; } else return (1); if (siz1 != siz2) return(1); gmin1 = pgr1->dimmin[dim]; gmax1 = pgr1->dimmax[dim]; gmin2 = pgr2->dimmin[dim]; gmax2 = pgr2->dimmax[dim]; if (dim==3) { /* Dimension is time. */ gr2t (vals1, gmin1, &dtim1); gr2t (vals2, gmin2, &dtim2); if (dtim1.yr != dtim2.yr) return (1); if (dtim1.mo != dtim2.mo) return (1); if (dtim1.dy != dtim2.dy) return (1); if (dtim1.hr != dtim2.hr) return (1); if (dtim1.mn != dtim2.mn) return (1); gr2t (vals1, gmax1, &dtim1); gr2t (vals2, gmax2, &dtim2); if (dtim1.yr != dtim2.yr) return (1); if (dtim1.mo != dtim2.mo) return (1); if (dtim1.dy != dtim2.dy) return (1); if (dtim1.hr != dtim2.hr) return (1); if (dtim1.mn != dtim2.mn) return (1); return (0); } /* Check endpoints. If unequal, then automatic no match. */ fuz1=fabs(conv1(vals1,gmax1)-conv1(vals1,gmin1))*FUZZ_SCALE; fuz2=fabs(conv2(vals2,gmax2)-conv2(vals2,gmin2))*FUZZ_SCALE; fuzz=(fuz1+fuz2)*0.5; if ( fabs((conv1(vals1,gmin1)) - (conv2(vals2,gmin2))) > fuzz ) return (1); if ( fabs((conv1(vals1,gmax1)) - (conv2(vals2,gmax2))) > fuzz ) return (1); if (i1!=i2) return (1); if (i1) return (0); /* If linear then matches */ /* Nonlinear, but endpoints match. Check every grid point for a match. If any non-matches, then not a match. */ for (i=0; i<siz1; i++) { if (fabs((conv1(vals1,gmin1+(gadouble)i)) - (conv2(vals2,gmin2+(gadouble)i))) > fuzz ) { return (1); } } return (0); }
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); }