void *Template2(void *argument) { int streamID1, streamID2 = CDI_UNDEFID; int nrecs; int tsID, recID, varID, levelID; int vlistID1, vlistID2; int gridsize; int nmiss; int taxisID1, taxisID2; double *array = NULL; cdoInitialize(argument); streamID1 = streamOpenRead(cdoStreamName(0)); vlistID1 = streamInqVlist(streamID1); vlistID2 = vlistDuplicate(vlistID1); taxisID1 = vlistInqTaxis(vlistID1); taxisID2 = taxisDuplicate(taxisID1); vlistDefTaxis(vlistID2, taxisID2); streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype()); streamDefVlist(streamID2, vlistID2); gridsize = vlistGridsizeMax(vlistID1); array = (double*) malloc(gridsize*sizeof(double)); tsID = 0; while ( (nrecs = streamInqTimestep(streamID1, tsID)) ) { taxisCopyTimestep(taxisID2, taxisID1); streamDefTimestep(streamID2, tsID); for ( recID = 0; recID < nrecs; recID++ ) { streamInqRecord(streamID1, &varID, &levelID); streamDefRecord(streamID2, varID, levelID); streamReadRecord(streamID1, array, &nmiss); streamWriteRecord(streamID2, array, nmiss); } tsID++; } streamClose(streamID1); streamClose(streamID2); vlistDestroy(vlistID2); if ( array ) free(array); cdoFinish(); return (0); }
int unloadSpreadsheetDialog(spreadStruct *spreadSheet) { vdialogDestroy(spreadSheet->spreadDialog); releaseSpreadsheet(spreadSheet); releaseRowLabels(spreadSheet); releaseColumnHeadings(spreadSheet); if (spreadSheet->spreadList != NULL) vlistDestroy(spreadSheet->spreadList); if (spreadSheet->rowList != NULL) vlistDestroy(spreadSheet->rowList); if (spreadSheet->columnList != NULL) vlistDestroy(spreadSheet->columnList); if (spreadSheet->editData != NULL) vtextDestroy(spreadSheet->editData); return TRUE; }
/* _lifeShutdownDialog -- destroy auxiliary memory consumed by the dialog. * * -> dialog -- the dialog to clean up after */ static void _lifeShutdownDialog (vdialog *dialog) { lifeRock *gibraltar; gibraltar = (lifeRock*)vdialogGetData (dialog); vtimerStop (gibraltar->timer); vtimerDestroy (gibraltar->timer); vmemFree (gibraltar->petri1); vmemFree (gibraltar->petri2); vpoolFree (primordialSoup, gibraltar); vlistDestroy (vlistviewGetList ((vlistview*) vdialogFindItem (dialog, TAG("Life Listview")))); } /* _lifeShutdownDialog */
void *Arith(void *argument) { int operatorID; int operfunc; enum {FILL_NONE, FILL_TS, FILL_VAR, FILL_VARTS, FILL_FILE}; int filltype = FILL_NONE; int streamIDx1, streamIDx2, streamID1, streamID2, streamID3; int gridsize; int nrecs, nrecs2, nvars = 0, nlev, recID; int nlevels2 = 1; int tsID, tsID2; int varID, levelID; int varID2, levelID2; int offset; int lfill1, lfill2; int ntsteps1, ntsteps2; int vlistIDx1, vlistIDx2, vlistID1, vlistID2, vlistID3; int taxisIDx1, taxisID1, taxisID2, taxisID3; field_t *fieldx1, *fieldx2, field1, field2; int *varnmiss2 = NULL; int **varnmiss = NULL; double *vardata2 = NULL; double **vardata = NULL; cdoInitialize(argument); cdoOperatorAdd("add", func_add, 0, NULL); cdoOperatorAdd("sub", func_sub, 0, NULL); cdoOperatorAdd("mul", func_mul, 0, NULL); cdoOperatorAdd("div", func_div, 0, NULL); cdoOperatorAdd("min", func_min, 0, NULL); cdoOperatorAdd("max", func_max, 0, NULL); cdoOperatorAdd("atan2", func_atan2, 0, NULL); operatorID = cdoOperatorID(); operfunc = cdoOperatorF1(operatorID); streamID1 = streamOpenRead(cdoStreamName(0)); streamID2 = streamOpenRead(cdoStreamName(1)); streamIDx1 = streamID1; streamIDx2 = streamID2; fieldx1 = &field1; fieldx2 = &field2; vlistID1 = streamInqVlist(streamID1); vlistID2 = streamInqVlist(streamID2); vlistIDx1 = vlistID1; vlistIDx2 = vlistID2; if ( cdoVerbose ) vlistPrint(vlistID1); if ( cdoVerbose ) vlistPrint(vlistID2); taxisID1 = vlistInqTaxis(vlistID1); taxisID2 = vlistInqTaxis(vlistID2); taxisIDx1 = taxisID1; ntsteps1 = vlistNtsteps(vlistID1); ntsteps2 = vlistNtsteps(vlistID2); if ( ntsteps1 == 0 ) ntsteps1 = 1; if ( ntsteps2 == 0 ) ntsteps2 = 1; if ( vlistNvars(vlistID1) == 1 && vlistNvars(vlistID2) == 1 ) { lfill2 = vlistNrecs(vlistID1) != 1 && vlistNrecs(vlistID2) == 1; lfill1 = vlistNrecs(vlistID1) == 1 && vlistNrecs(vlistID2) != 1; } else { lfill2 = vlistNvars(vlistID1) != 1 && vlistNvars(vlistID2) == 1; lfill1 = vlistNvars(vlistID1) == 1 && vlistNvars(vlistID2) != 1; } if ( lfill2 ) { nlevels2 = vlistCompareX(vlistID1, vlistID2, CMP_DIM); if ( ntsteps1 != 1 && ntsteps2 == 1 ) { filltype = FILL_VAR; cdoPrint("Filling up stream2 >%s< by copying the first variable.", cdoStreamName(1)->args); } else { filltype = FILL_VARTS; cdoPrint("Filling up stream2 >%s< by copying the first variable of each timestep.", cdoStreamName(1)->args); } } else if ( lfill1 ) { nlevels2 = vlistCompareX(vlistID2, vlistID1, CMP_DIM); if ( ntsteps1 == 1 && ntsteps2 != 1 ) { filltype = FILL_VAR; cdoPrint("Filling up stream1 >%s< by copying the first variable.", cdoStreamName(0)->args); } else { filltype = FILL_VARTS; cdoPrint("Filling up stream1 >%s< by copying the first variable of each timestep.", cdoStreamName(0)->args); } streamIDx1 = streamID2; streamIDx2 = streamID1; vlistIDx1 = vlistID2; vlistIDx2 = vlistID1; taxisIDx1 = taxisID2; fieldx1 = &field2; fieldx2 = &field1; } if ( filltype == FILL_NONE ) vlistCompare(vlistID1, vlistID2, CMP_ALL); gridsize = vlistGridsizeMax(vlistIDx1); field_init(&field1); field_init(&field2); field1.ptr = (double*) malloc(gridsize*sizeof(double)); field2.ptr = (double*) malloc(gridsize*sizeof(double)); if ( filltype == FILL_VAR || filltype == FILL_VARTS ) { vardata2 = (double*) malloc(gridsize*nlevels2*sizeof(double)); varnmiss2 = (int*) malloc(nlevels2*sizeof(int)); } if ( cdoVerbose ) cdoPrint("Number of timesteps: file1 %d, file2 %d", ntsteps1, ntsteps2); if ( filltype == FILL_NONE ) { if ( ntsteps1 != 1 && ntsteps2 == 1 ) { filltype = FILL_TS; cdoPrint("Filling up stream2 >%s< by copying the first timestep.", cdoStreamName(1)->args); } else if ( ntsteps1 == 1 && ntsteps2 != 1 ) { filltype = FILL_TS; cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0)->args); streamIDx1 = streamID2; streamIDx2 = streamID1; vlistIDx1 = vlistID2; vlistIDx2 = vlistID1; taxisIDx1 = taxisID2; fieldx1 = &field2; fieldx2 = &field1; } if ( filltype == FILL_TS ) { nvars = vlistNvars(vlistIDx2); vardata = (double **) malloc(nvars*sizeof(double *)); varnmiss = (int **) malloc(nvars*sizeof(int *)); for ( varID = 0; varID < nvars; varID++ ) { gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID)); nlev = zaxisInqSize(vlistInqVarZaxis(vlistIDx2, varID)); vardata[varID] = (double*) malloc(nlev*gridsize*sizeof(double)); varnmiss[varID] = (int*) malloc(nlev*sizeof(int)); } } } vlistID3 = vlistDuplicate(vlistIDx1); if ( filltype == FILL_TS && vlistIDx1 != vlistID1 ) { nvars = vlistNvars(vlistID1); for ( varID = 0; varID < nvars; varID++ ) vlistDefVarMissval(vlistID3, varID, vlistInqVarMissval(vlistID1, varID)); } taxisID3 = taxisDuplicate(taxisIDx1); vlistDefTaxis(vlistID3, taxisID3); streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype()); streamDefVlist(streamID3, vlistID3); tsID = 0; tsID2 = 0; while ( (nrecs = streamInqTimestep(streamIDx1, tsID)) ) { if ( tsID == 0 || filltype == FILL_NONE || filltype == FILL_FILE || filltype == FILL_VARTS ) { nrecs2 = streamInqTimestep(streamIDx2, tsID2); if ( nrecs2 == 0 ) { if ( filltype == FILL_NONE && streamIDx2 == streamID2 ) { filltype = FILL_FILE; cdoPrint("Filling up stream2 >%s< by copying all timesteps.", cdoStreamName(1)->args); } if ( filltype == FILL_FILE ) { tsID2 = 0; streamClose(streamID2); streamID2 = streamOpenRead(cdoStreamName(1)); streamIDx2 = streamID2; vlistID2 = streamInqVlist(streamID2); vlistIDx2 = vlistID2; vlistCompare(vlistID1, vlistID2, CMP_DIM); nrecs2 = streamInqTimestep(streamIDx2, tsID2); if ( nrecs2 == 0 ) cdoAbort("Empty input stream %s!", cdoStreamName(1)->args); } else cdoAbort("Input streams have different number of timesteps!"); } } taxisCopyTimestep(taxisID3, taxisIDx1); streamDefTimestep(streamID3, tsID); for ( recID = 0; recID < nrecs; recID++ ) { streamInqRecord(streamIDx1, &varID, &levelID); streamReadRecord(streamIDx1, fieldx1->ptr, &fieldx1->nmiss); if ( tsID == 0 || filltype == FILL_NONE || filltype == FILL_FILE || filltype == FILL_VARTS ) { int lstatus = nlevels2 > 1 ? varID == 0 : recID == 0; if ( lstatus || (filltype != FILL_VAR && filltype != FILL_VARTS) ) { streamInqRecord(streamIDx2, &varID2, &levelID2); streamReadRecord(streamIDx2, fieldx2->ptr, &fieldx2->nmiss); } if ( filltype == FILL_TS ) { gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID)); offset = gridsize*levelID; memcpy(vardata[varID]+offset, fieldx2->ptr, gridsize*sizeof(double)); varnmiss[varID][levelID] = fieldx2->nmiss; } else if ( lstatus && (filltype == FILL_VAR || filltype == FILL_VARTS) ) { gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, 0)); offset = gridsize*levelID2; memcpy(vardata2+offset, fieldx2->ptr, gridsize*sizeof(double)); varnmiss2[levelID2] = fieldx2->nmiss; } } else if ( filltype == FILL_TS ) { gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID2)); offset = gridsize*levelID; memcpy(fieldx2->ptr, vardata[varID]+offset, gridsize*sizeof(double)); fieldx2->nmiss = varnmiss[varID][levelID]; } fieldx1->grid = vlistInqVarGrid(vlistIDx1, varID); fieldx1->missval = vlistInqVarMissval(vlistIDx1, varID); if ( filltype == FILL_VAR || filltype == FILL_VARTS ) { gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, 0)); levelID2 = 0; if ( nlevels2 > 1 ) levelID2 = levelID; offset = gridsize*levelID2; memcpy(fieldx2->ptr, vardata2+offset, gridsize*sizeof(double)); fieldx2->nmiss = varnmiss2[levelID2]; fieldx2->grid = vlistInqVarGrid(vlistIDx2, 0); fieldx2->missval = vlistInqVarMissval(vlistIDx2, 0); } else { fieldx2->grid = vlistInqVarGrid(vlistIDx2, varID2); fieldx2->missval = vlistInqVarMissval(vlistIDx2, varID2); } farfun(&field1, field2, operfunc); streamDefRecord(streamID3, varID, levelID); streamWriteRecord(streamID3, field1.ptr, field1.nmiss); } tsID++; tsID2++; } streamClose(streamID3); streamClose(streamID2); streamClose(streamID1); vlistDestroy(vlistID3); if ( vardata ) { for ( varID = 0; varID < nvars; varID++ ) { free(vardata[varID]); free(varnmiss[varID]); } free(vardata); free(varnmiss); } if ( field1.ptr ) free(field1.ptr); if ( field2.ptr ) free(field2.ptr); if ( vardata2 ) free(vardata2); if ( varnmiss2 ) free(varnmiss2); cdoFinish(); return (0); }
void *Complextorect(void *argument) { // int COMPLEXTORECT; // int operatorID; int streamID1, streamID2, streamID3; int tsID, nrecs; int recID, varID, levelID; int vlistID1, vlistID2, vlistID3; int taxisID1, taxisID2, taxisID3; int i, gridsize; int datatype; int nmiss, nvars; double *array1 = NULL, *array2 = NULL, *array3 = NULL; cdoInitialize(argument); // COMPLEXTORECT = cdoOperatorAdd("complextorect", 0, 0, NULL); // operatorID = cdoOperatorID(); streamID1 = streamOpenRead(cdoStreamName(0)); vlistID1 = streamInqVlist(streamID1); vlistID2 = vlistDuplicate(vlistID1); vlistID3 = vlistDuplicate(vlistID1); nvars = vlistNvars(vlistID2); for ( varID = 0; varID < nvars; ++varID ) { datatype = vlistInqVarDatatype(vlistID2, varID); if ( datatype == DATATYPE_CPX64 ) datatype = DATATYPE_FLT64; else datatype = DATATYPE_FLT32; vlistDefVarDatatype(vlistID2, varID, datatype); vlistDefVarDatatype(vlistID3, varID, datatype); } taxisID1 = vlistInqTaxis(vlistID1); taxisID2 = taxisDuplicate(taxisID1); taxisID3 = taxisDuplicate(taxisID1); vlistDefTaxis(vlistID2, taxisID2); vlistDefTaxis(vlistID3, taxisID3); streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype()); streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype()); streamDefVlist(streamID2, vlistID2); streamDefVlist(streamID3, vlistID3); gridsize = vlistGridsizeMax(vlistID1); array1 = (double*) malloc(2*gridsize*sizeof(double)); array2 = (double*) malloc(gridsize*sizeof(double)); array3 = (double*) malloc(gridsize*sizeof(double)); tsID = 0; while ( (nrecs = streamInqTimestep(streamID1, tsID)) ) { taxisCopyTimestep(taxisID2, taxisID1); taxisCopyTimestep(taxisID3, taxisID1); streamDefTimestep(streamID2, tsID); streamDefTimestep(streamID3, tsID); for ( recID = 0; recID < nrecs; recID++ ) { streamInqRecord(streamID1, &varID, &levelID); streamDefRecord(streamID2, varID, levelID); streamDefRecord(streamID3, varID, levelID); gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID)); streamReadRecord(streamID1, array1, &nmiss); for ( i = 0; i < gridsize; ++i ) { array2[i] = array1[2*i]; array3[i] = array1[2*i+1]; } streamWriteRecord(streamID2, array2, nmiss); streamWriteRecord(streamID3, array3, nmiss); } tsID++; } streamClose(streamID3); streamClose(streamID2); streamClose(streamID1); if ( array1 ) free(array1); if ( array2 ) free(array2); if ( array3 ) free(array3); vlistDestroy(vlistID2); vlistDestroy(vlistID3); cdoFinish(); return (NULL); }
void *Importobs(void *argument) { int operatorID; char line[MAX_LINE_LEN]; int streamID; int tsID; int gridID, zaxisID, taxisID, vlistID; int i, j; int nvars = MAX_VARS; int vdate = 0, vtime = 0; int vdate0 = 0, vtime0 = 0; int gridsize, xsize, ysize; double *xvals = NULL, *yvals = NULL; double *data[MAX_VARS]; FILE *fp; char dummy[32], station[32], datetime[32]; float lat, lon, height1, pressure, height2, value; double latmin = 90, latmax = -90, lonmin = 360, lonmax = -360; int code; int index; double dx, dy; char *pstation; cdoInitialize(argument); cdoOperatorAdd("import_obs", 0, 0, "grid description file or name"); operatorID = cdoOperatorID(); operatorInputArg(cdoOperatorEnter(operatorID)); gridID = cdoDefineGrid(operatorArgv()[0]); if ( gridInqType(gridID) != GRID_LONLAT ) cdoAbort("Unsupported grid type: %s", gridNamePtr(gridInqType(gridID))); gridsize = gridInqSize(gridID); xsize = gridInqXsize(gridID); ysize = gridInqYsize(gridID); // printf("gridsize=%d, xsize=%d, ysize=%d\n", gridsize, xsize, ysize); xvals = (double*) malloc(gridsize*sizeof(double)); yvals = (double*) malloc(gridsize*sizeof(double)); gridInqXvals(gridID, xvals); gridInqYvals(gridID, yvals); /* Convert lat/lon units if required */ { char units[CDI_MAX_NAME]; gridInqXunits(gridID, units); grid_to_degree(units, gridsize, xvals, "grid center lon"); gridInqYunits(gridID, units); grid_to_degree(units, gridsize, yvals, "grid center lat"); } fp = fopen(cdoStreamName(0)->args, "r"); if ( fp == NULL ) { perror(cdoStreamName(0)->args); exit(EXIT_FAILURE); } vdate = getDate(cdoStreamName(0)->args); if ( vdate <= 999999 ) vdate = vdate*100 + 1; streamID = streamOpenWrite(cdoStreamName(1), cdoFiletype()); zaxisID = zaxisCreate(ZAXIS_SURFACE, 1); taxisID = taxisCreate(TAXIS_ABSOLUTE); vlistID = vlistCreate(); vlistDefTaxis(vlistID, taxisID); { for ( i = 0; i < nvars; ++i ) data[i] = (double*) malloc(gridsize*sizeof(double)); init_vars(vlistID, gridID, zaxisID, nvars); streamDefVlist(streamID, vlistID); vdate0 = 0; vtime0 = 0; //ntime = 0; tsID = 0; while ( readline(fp, line, MAX_LINE_LEN) ) { sscanf(line, "%s %s %s %g %g %g %d %g %g %g", dummy, station, datetime, &lat, &lon, &height1, &code, &pressure, &height2, &value); sscanf(datetime, "%d_%d", &vdate, &vtime); if ( vdate != vdate0 || vtime != vtime0 ) { if ( tsID > 0 ) write_data(streamID, vlistID, nvars, data); vdate0 = vdate; vtime0 = vtime; /* printf("%s %d %d %g %g %g %d %g %g %g\n", station, vdate, vtime, lat, lon, height1, code, pressure, height2, value); */ taxisDefVdate(taxisID, vdate); taxisDefVtime(taxisID, vtime); streamDefTimestep(streamID, tsID); init_data(vlistID, nvars, data); tsID++; } if ( lon < lonmin ) lonmin = lon; if ( lon > lonmax ) lonmax = lon; if ( lat < latmin ) latmin = lat; if ( lat > latmax ) latmax = lat; dy = yvals[1] - yvals[0]; for ( j = 0; j < ysize; ++j ) if ( lat >= (yvals[j]-dy/2) && lat < (yvals[j]+dy/2) ) break; dx = xvals[1] - xvals[0]; if ( lon < (xvals[0] - dx/2) && lon < 0 ) lon+=360; for ( i = 0; i < xsize; ++i ) if ( lon >= (xvals[i]-dx/2) && lon < (xvals[i]+dx/2) ) break; index = -1; if ( code == 11 ) index = 0; if ( code == 17 ) index = 1; if ( code == 33 ) index = 2; if ( code == 34 ) index = 3; //printf("%d %d %d %g %g %g %g\n", i, j, index, dx, dy, lon, lat); if ( i < xsize && j < ysize && index >= 0 ) { pstation = station; while (isalpha(*pstation)) pstation++; // printf("station %s %d\n", pstation, atoi(pstation)); data[index][j*xsize+i] = value; data[ 4][j*xsize+i] = height1; data[ 5][j*xsize+i] = pressure; // data[ 6][j*xsize+i] = atoi(pstation); } /* printf("%s %d %d %g %g %g %d %g %g %g\n", station, vdate, vtime, lat, lon, height1, code, pressure, height2, value); */ } write_data(streamID, vlistID, nvars, data); for ( i = 0; i < nvars; ++i ) free(data[i]); } printf("lonmin=%g, lonmax=%g, latmin=%g, latmax=%g\n", lonmin, lonmax, latmin, latmax); processDefVarNum(vlistNvars(vlistID), streamID); streamClose(streamID); fclose(fp); vlistDestroy(vlistID); gridDestroy(gridID); zaxisDestroy(zaxisID); taxisDestroy(taxisID); free(xvals); free(yvals); cdoFinish(); return (0); }
void *Setrcaname(void *argument) { int streamID1, streamID2 = CDI_UNDEFID; int nrecs; int tsID, recID, varID, levelID; int vlistID1, vlistID2; int taxisID1, taxisID2; char **rcsnames; FILE *fp; char line[MAX_LINE_LEN]; char sname[CDI_MAX_NAME], sdescription[CDI_MAX_NAME], sunits[CDI_MAX_NAME]; int scode, sltype, slevel; int nvars; int zaxisID, ltype, code, nlev; int level; int lcopy = FALSE; int gridsize, nmiss; double *array = NULL; cdoInitialize(argument); if ( UNCHANGED_RECORD ) lcopy = TRUE; operatorInputArg("file name with RCA names"); rcsnames = operatorArgv(); streamID1 = streamOpenRead(cdoStreamName(0)); vlistID1 = streamInqVlist(streamID1); vlistID2 = vlistDuplicate(vlistID1); nvars = vlistNvars(vlistID2); fp = fopen(rcsnames[0], "r"); if ( fp != NULL ) { while ( readline(fp, line, MAX_LINE_LEN) ) { sscanf(line, "%d\t%d\t%d\t%s\t%s\t%s", &scode, &sltype, &slevel, sname, sdescription, sunits); /* printf("%s\n", line); printf("%d:%d:%d:%s:%s:%s\n", scode, sltype, slevel, sname, sdescription, sunits); */ for ( varID = 0; varID < nvars; varID++ ) { code = vlistInqVarCode(vlistID2, varID); zaxisID = vlistInqVarZaxis(vlistID2, varID); nlev = zaxisInqSize(zaxisID); ltype = zaxis2ltype(zaxisID); if ( code == scode ) { if ( ltype == 105 ) { if ( nlev != 1 ) { cdoWarning("Number of levels should be 1 for level type 105!"); cdoWarning("Maybe environment variable SPLIT_LTYPE_105 is not set."); continue; } level = (int) zaxisInqLevel(zaxisID, 0); if ( sltype == 105 && slevel == level ) { vlistDefVarName(vlistID2, varID, sname); vlistDefVarLongname(vlistID2, varID, sdescription); vlistDefVarUnits(vlistID2, varID, sunits); break; } } else if ( sltype != 105 ) { vlistDefVarName(vlistID2, varID, sname); vlistDefVarLongname(vlistID2, varID, sdescription); vlistDefVarUnits(vlistID2, varID, sunits); break; } } } } fclose(fp); } else { perror(rcsnames[0]); } taxisID1 = vlistInqTaxis(vlistID1); taxisID2 = taxisDuplicate(taxisID1); vlistDefTaxis(vlistID2, taxisID2); streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype()); streamDefVlist(streamID2, vlistID2); if ( ! lcopy ) { gridsize = vlistGridsizeMax(vlistID1); array = (double*) malloc(gridsize*sizeof(double)); } tsID = 0; while ( (nrecs = streamInqTimestep(streamID1, tsID)) ) { taxisCopyTimestep(taxisID2, taxisID1); streamDefTimestep(streamID2, tsID); for ( recID = 0; recID < nrecs; recID++ ) { streamInqRecord(streamID1, &varID, &levelID); streamDefRecord(streamID2, varID, levelID); if ( lcopy ) { streamCopyRecord(streamID2, streamID1); } else { streamReadRecord(streamID1, array, &nmiss); streamWriteRecord(streamID2, array, nmiss); } } tsID++; } streamClose(streamID1); streamClose(streamID2); vlistDestroy(vlistID2); if ( ! lcopy ) if ( array ) free(array); cdoFinish(); 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); }
void *SSOpar(void *argument) { int GEOPOTHEIGHT; int operatorID; int streamID1, streamID2; int vlistID1, vlistID2; int recID, nrecs; int i, offset, iv; int tsID, varID, levelID; int nvars; int zaxisID2, zaxisIDh = -1, nzaxis, surfaceID; int zaxisID; int nlevel; int nvct; int geopID = -1, tempID = -1, humID = -1, psID = -1, lnpsID = -1, presID = -1, clwcID = -1, ciwcID = -1; int code; char varname[CDI_MAX_NAME]; double *single2; int taxisID1, taxisID2; int lhavevct; int nhlevf = 0; double *lev2; double *vct = NULL; double *geop = NULL, *ps = NULL, *temp = NULL, *hum = NULL, *lwater = NULL, *iwater = NULL; double *geopotheight = NULL; int nmiss, nmissout = 0; int ltq = FALSE; double *array = NULL; double *half_press = NULL; double minval, maxval; double missval = 0; double cconst = 1.E-6; const char *fname; cdoInitialize(argument); GEOPOTHEIGHT = cdoOperatorAdd("geopotheight", 0, 0, NULL); operatorID = cdoOperatorID(); streamID1 = streamOpenRead(cdoStreamName(0)); vlistID1 = streamInqVlist(streamID1); int gridID = vlistGrid(vlistID1, 0); if ( gridInqType(gridID) == GRID_SPECTRAL ) cdoAbort("Spectral data unsupported!"); int gridsize = vlist_check_gridsize(vlistID1); nzaxis = vlistNzaxis(vlistID1); lhavevct = FALSE; if ( cdoVerbose ) cdoPrint("nzaxis: %d", nzaxis); for ( i = 0; i < nzaxis; i++ ) { zaxisID = vlistZaxis(vlistID1, i); nlevel = zaxisInqSize(zaxisID); if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID ) { if ( nlevel > 1 ) { nvct = zaxisInqVctSize(zaxisID); if ( cdoVerbose ) cdoPrint("i: %d, vct size of zaxisID %d = %d", i, zaxisID, nvct); if ( nlevel == (nvct/2 - 1) ) { if ( lhavevct == FALSE ) { lhavevct = TRUE; zaxisIDh = zaxisID; nhlevf = nlevel; if ( cdoVerbose ) cdoPrint("lhavevct=TRUE zaxisIDh = %d, nhlevf = %d", zaxisIDh, nlevel); vct = (double*) malloc(nvct*sizeof(double)); zaxisInqVct(zaxisID, vct); if ( cdoVerbose ) for ( i = 0; i < nvct/2; ++i ) cdoPrint("vct: %5d %25.17f %25.17f", i, vct[i], vct[nvct/2+i]); } } else { if ( cdoVerbose ) cdoPrint("nlevel /= (nvct/2 - 1): nlevel = %d", nlevel); } } } } if ( zaxisIDh == -1 ) cdoAbort("No 3D variable with hybrid sigma pressure coordinate found!"); nvars = vlistNvars(vlistID1); for ( varID = 0; varID < nvars; varID++ ) { gridID = vlistInqVarGrid(vlistID1, varID); zaxisID = vlistInqVarZaxis(vlistID1, varID); nlevel = zaxisInqSize(zaxisID); code = vlistInqVarCode(vlistID1, varID); /* code = -1; */ if ( code <= 0 ) { vlistInqVarName(vlistID1, varID, varname); strtolower(varname); if ( nlevel == 1 ) { if ( strcmp(varname, "geosp") == 0 ) code = 129; else if ( strcmp(varname, "aps") == 0 ) code = 134; else if ( strcmp(varname, "ps") == 0 ) code = 134; else if ( strcmp(varname, "lsp") == 0 ) code = 152; } if ( nlevel == nhlevf ) { if ( strcmp(varname, "t") == 0 ) code = 130; else if ( strcmp(varname, "q") == 0 ) code = 133; else if ( strcmp(varname, "clwc") == 0 ) code = 246; else if ( strcmp(varname, "ciwc") == 0 ) code = 247; } } if ( code == 129 ) geopID = varID; else if ( code == 130 ) tempID = varID; else if ( code == 133 ) humID = varID; else if ( code == 134 ) psID = varID; else if ( code == 152 ) lnpsID = varID; else if ( code == 246 ) clwcID = varID; else if ( code == 247 ) ciwcID = varID; if ( gridInqType(gridID) == GRID_SPECTRAL && zaxisInqType(zaxisID) == ZAXIS_HYBRID ) cdoAbort("Spectral data on model level unsupported!"); if ( gridInqType(gridID) == GRID_SPECTRAL ) cdoAbort("Spectral data unsupported!"); if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && zaxisIDh != -1 && nlevel == nhlevf ) { } else { if ( code == 130 ) tempID = -1; if ( code == 133 ) humID = -1; if ( code == 246 ) clwcID = -1; if ( code == 247 ) ciwcID = -1; } } if ( tempID == -1 ) cdoAbort("Temperature not found!"); array = (double*) malloc(gridsize*sizeof(double)); geop = (double*) malloc(gridsize*sizeof(double)); ps = (double*) malloc(gridsize*sizeof(double)); temp = (double*) malloc(gridsize*nhlevf*sizeof(double)); hum = (double*) malloc(gridsize*nhlevf*sizeof(double)); lwater = (double*) malloc(gridsize*nhlevf*sizeof(double)); iwater = (double*) malloc(gridsize*nhlevf*sizeof(double)); half_press = (double*) malloc(gridsize*(nhlevf+1)*sizeof(double)); geopotheight = (double*) malloc(gridsize*(nhlevf+1)*sizeof(double)); if ( zaxisIDh != -1 && geopID == -1 ) { if ( ltq ) cdoWarning("Orography (surf. geopotential) not found - set to zero!"); memset(geop, 0, gridsize*sizeof(double)); } presID = lnpsID; if ( zaxisIDh != -1 && lnpsID == -1 ) { presID = psID; if ( psID != -1 ) cdoWarning("LOG surface pressure (lsp) not found - using surface pressure (asp)!"); else cdoAbort("Surface pressure not found!"); } vlistID2 = vlistCreate(); varID = vlistDefVar(vlistID2, gridID, zaxisIDh, TSTEP_INSTANT); vlistDefVarParam(vlistID2, varID, cdiEncodeParam(156, 128, 255)); vlistDefVarName(vlistID2, varID, "geopotheight"); vlistDefVarStdname(vlistID2, varID, "geopotential_height"); vlistDefVarUnits(vlistID2, varID, "m"); taxisID1 = vlistInqTaxis(vlistID1); taxisID2 = taxisDuplicate(taxisID1); vlistDefTaxis(vlistID2, taxisID2); streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype()); streamDefVlist(streamID2, vlistID2); tsID = 0; while ( (nrecs = streamInqTimestep(streamID1, tsID)) ) { taxisCopyTimestep(taxisID2, taxisID1); streamDefTimestep(streamID2, tsID); for ( recID = 0; recID < nrecs; recID++ ) { streamInqRecord(streamID1, &varID, &levelID); zaxisID = vlistInqVarZaxis(vlistID1, varID); nlevel = zaxisInqSize(zaxisID); offset = gridsize*levelID; streamReadRecord(streamID1, array, &nmiss); if ( zaxisIDh != -1 ) { if ( varID == geopID ) { memcpy(geop, array, gridsize*sizeof(double)); } else if ( varID == presID ) { if ( lnpsID != -1 ) for ( i = 0; i < gridsize; ++i ) ps[i] = exp(array[i]); else if ( psID != -1 ) memcpy(ps, array, gridsize*sizeof(double)); } else if ( varID == tempID ) memcpy(temp+offset, array, gridsize*sizeof(double)); else if ( varID == humID ) memcpy(hum+offset, array, gridsize*sizeof(double)); else if ( varID == clwcID ) memcpy(lwater+offset, array, gridsize*sizeof(double)); else if ( varID == ciwcID ) memcpy(iwater+offset, array, gridsize*sizeof(double)); } } if ( zaxisIDh != -1 ) { /* check range of ps_prog */ minmaxval(gridsize, ps, NULL, &minval, &maxval); if ( minval < MIN_PS || maxval > MAX_PS ) cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval); /* check range of geop */ minmaxval(gridsize, geop, NULL, &minval, &maxval); if ( minval < MIN_FIS || maxval > MAX_FIS ) cdoWarning("Orography out of range (min=%g max=%g)!", minval, maxval); } varID = tempID; nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID)); for ( levelID = 0; levelID < nlevel; levelID++ ) { offset = gridsize*levelID; single2 = temp + offset; minmaxval(gridsize, single2, NULL, &minval, &maxval); if ( minval < MIN_T || maxval > MAX_T ) cdoWarning("Input temperature at level %d out of range (min=%g max=%g)!", levelID+1, minval, maxval); } nmissout = 0; varID = 0; nlevel = nhlevf; for ( levelID = 0; levelID < nlevel; levelID++ ) { streamDefRecord(streamID2, varID, levelID); streamWriteRecord(streamID2, geopotheight+levelID*gridsize, nmissout); } tsID++; } streamClose(streamID2); streamClose(streamID1); vlistDestroy(vlistID2); free(ps); free(geop); free(temp); free(geopotheight); if ( hum ) free(hum); if ( half_press ) free(half_press); free(array); if ( vct ) free(vct); cdoFinish(); return (0); }
void *Merge(void *argument) { int streamID1 = -1, streamID2 = -1; int varID, varID2; int nrecs = 0; int recID, levelID, levelID2; int index; int vlistID1 = -1, vlistID2; int lcopy = FALSE; int gridsize; int nmiss; int taxisID1, taxisID2; //int skip_same_var = FALSE; double *array = NULL; cdoInitialize(argument); if ( UNCHANGED_RECORD ) lcopy = TRUE; /* { char *envstr; envstr = getenv("SKIP_SAME_VAR"); if ( envstr ) { int ival; ival = atoi(envstr); if ( ival == 1 ) { skip_same_var = TRUE; if ( cdoVerbose ) cdoPrint("Set SKIP_SAME_VAR to %d", ival); } } } */ int streamCnt = cdoStreamCnt(); int nmerge = streamCnt - 1; const char *ofilename = cdoStreamName(streamCnt-1)->args; if ( !cdoSilentMode && !cdoOverwriteMode ) if ( fileExists(ofilename) ) if ( !userFileOverwrite(ofilename) ) cdoAbort("Outputfile %s already exists!", ofilename); int *streamIDs = (int*) malloc(nmerge*sizeof(int)); int *vlistIDs = (int*) malloc(nmerge*sizeof(int)); int *numrecs = (int*) malloc(nmerge*sizeof(int)); int *numsteps = (int*) malloc(nmerge*sizeof(int)); for ( index = 0; index < nmerge; index++ ) { streamID1 = streamOpenRead(cdoStreamName(index)); streamIDs[index] = streamID1; vlistIDs[index] = streamInqVlist(streamID1); } vlistID1 = vlistIDs[0]; taxisID1 = vlistInqTaxis(vlistID1); taxisID2 = taxisDuplicate(taxisID1); vlistID2 = vlistCreate(); vlistCopy(vlistID2, vlistIDs[0]); for ( index = 1; index < nmerge; index++ ) { checkDupEntry(vlistID2, vlistIDs[index], cdoStreamName(index)->args); /* vlistCat(vlistID2, vlistIDs[index]); */ vlistMerge(vlistID2, vlistIDs[index]); } for ( index = 0; index < nmerge; index++ ) numsteps[index] = -1; int numconst = 0; for ( index = 0; index < nmerge; index++ ) { streamID1 = streamIDs[index]; vlistID1 = vlistIDs[index]; numsteps[index] = vlistNtsteps(vlistID1); if ( numsteps[index] == 0 ) numsteps[index] = 1; if ( numsteps[index] == 1 ) numconst++; } if ( numconst > 0 && numconst < nmerge ) for ( index = 0; index < nmerge; index++ ) { if ( numsteps[index] == 1 ) { vlistID1 = vlistIDs[index]; int nvars = vlistNvars(vlistID1); for ( int varID = 0; varID < nvars; ++varID ) { varID2 = vlistMergedVar(vlistID1, varID); vlistDefVarTsteptype(vlistID2, varID2, TSTEP_CONSTANT); } } } if ( cdoVerbose ) { for ( index = 0; index < nmerge; index++ ) vlistPrint(vlistIDs[index]); vlistPrint(vlistID2); } streamID2 = streamOpenWrite(cdoStreamName(streamCnt-1), cdoFiletype()); vlistDefTaxis(vlistID2, taxisID2); streamDefVlist(streamID2, vlistID2); if ( ! lcopy ) { gridsize = vlistGridsizeMax(vlistID2); array = (double*) malloc(gridsize*sizeof(double)); } int firstindex = 0; int tsID = 0; while ( tsID >= 0 ) { for ( index = 0; index < nmerge; index++ ) { streamID1 = streamIDs[index]; vlistID1 = vlistIDs[index]; if ( vlistID1 == -1 ) continue; numrecs[index] = streamInqTimestep(streamID1, tsID); } for ( index = 0; index < nmerge; index++ ) if ( numrecs[index] != 0 ) break; if ( index == nmerge ) break; // EOF on all input streams if ( tsID == 1 ) { for ( index = 0; index < nmerge; index++ ) if ( numrecs[index] == 0 && numsteps[index] == 1 ) vlistIDs[index] = -1; /* for ( index = 0; index < nmerge; index++ ) if ( vlistIDs[index] != -1 ) { firstindex = index; break; } */ } /* for ( index = 0; index < nmerge; index++ ) printf("tsID %d %d sID %d vID %d nrecs %d\n", tsID, index, streamIDs[index], vlistIDs[index], numrecs[index]); */ if ( numrecs[firstindex] == 0 ) { for ( index = 1; index < nmerge; index++ ) if ( vlistIDs[index] != -1 && numrecs[index] != 0 ) cdoWarning("Input stream %d has %d timestep%s. Stream %d has more timesteps, skipped!", firstindex+1, tsID, tsID==1?"":"s", index+1); break; } else { for ( index = 1; index < nmerge; index++ ) if ( vlistIDs[index] != -1 && numrecs[index] == 0 ) { cdoWarning("Input stream %d has %d timestep%s. Stream %d has more timesteps, skipped!", index+1, tsID, tsID==1?"":"s", firstindex+1); break; } if ( index < nmerge ) break; } for ( index = 0; index < nmerge; index++ ) { streamID1 = streamIDs[index]; vlistID1 = vlistIDs[index]; nrecs = numrecs[index]; if ( vlistID1 == -1 ) continue; if ( index == firstindex ) { taxisCopyTimestep(taxisID2, taxisID1); streamDefTimestep(streamID2, tsID); } for ( recID = 0; recID < nrecs; recID++ ) { streamInqRecord(streamID1, &varID, &levelID); varID2 = vlistMergedVar(vlistID1, varID); levelID2 = vlistMergedLevel(vlistID1, varID, levelID); if ( cdoVerbose ) cdoPrint("var %d %d %d %d", varID, levelID, varID2, levelID2); streamDefRecord(streamID2, varID2, levelID2); if ( lcopy ) { streamCopyRecord(streamID2, streamID1); } else { streamReadRecord(streamID1, array, &nmiss); streamWriteRecord(streamID2, array, nmiss); } } } tsID++; } for ( index = 0; index < nmerge; index++ ) streamClose(streamIDs[index]); streamClose(streamID2); vlistDestroy(vlistID2); if ( streamIDs ) free(streamIDs); if ( vlistIDs ) free(vlistIDs); if ( numrecs ) free(numrecs); if ( numsteps ) free(numsteps); if ( ! lcopy ) if ( array ) free(array); cdoFinish(); return (0); }