/* setup the column headings and fill them with text */ void setupColumnHeadings(spreadStruct *spreadSheet) { vstr *string; int c; spreadData *cellData; /* create the list for the column headings */ spreadSheet->columnList = vlistCreate(); /* assoicate the list with the listview */ vlistviewSetList(spreadSheet->columnView, spreadSheet->columnList); /* set the heights and widths for the cells */ vlistviewSetRowHeight(spreadSheet->columnView, vlistviewALL_ROWS, spreadSheet->rowHeight); vlistviewSetColumnWidth(spreadSheet->columnView, vlistviewALL_COLUMNS, spreadSheet->columnWidth); /* set the column headings */ for (c = 0; c < spreadSheet->numColumns; c++) { string = vstrCloneScribed(vnumScribeInt((1990 + c))); cellData = (spreadData *) vmemAlloc(sizeof(spreadData)); cellData->type = SPREAD_STRING; cellData->data.string = string; vlistSetCellValue(spreadSheet->columnList, 0, c, cellData); } }
/* set up the row labels and fill them with text */ void setupRowLabels(spreadStruct *spreadSheet) { vstr *string; int r; spreadData *cellData; /* create the list for the row labels */ spreadSheet->rowList = vlistCreate(); /* associate the list with the listview */ vlistviewSetList(spreadSheet->rowView, spreadSheet->rowList); /* set the heights and widths for the cells */ vlistviewSetRowHeight(spreadSheet->rowView, vlistviewALL_ROWS, spreadSheet->rowHeight); vlistviewSetColumnWidth(spreadSheet->rowView, vlistviewALL_COLUMNS, spreadSheet->rowLabelWidth); /* set row labels, currently faked */ for (r = 0; r < spreadSheet->numRows; r++) { string = vstrCloneScribed(vnumScribeInt(r)); cellData = (spreadData *) vmemAlloc(sizeof(spreadData)); cellData->type = SPREAD_STRING; cellData->data.string = string; vlistSetCellValue(spreadSheet->rowList, r, 0, cellData); } }
/* _lifeSetupListview -- sets up various attributes of the life listview. * * -> listview -- bork's listview o' death. */ static void _lifeSetupListview (vlistview *listview) { vlist *list; /* create a new vlist and attach it to the view */ list = vlistCreate (); vlistviewSetList (listview, list); /* only use ONE_ONLY_SELECTION -- that makes it easy to do "fatbits" * style editing of cells. */ vlistSetSelectMethod (list, vlistviewGetSelection (listview), vlistONE_ONLY_SELECTION); /* attach our selection-change notification */ vlistviewSetSelectNotify (listview, _lifeListviewSelectNotify); /* attach our custom cell-drawing routine */ vlistviewSetCellContentProc (listview, _lifeCellContentProc); /* set the cell sizes */ vlistviewSetRowHeight (listview, vlistviewALL_ROWS, lifeCELL_SIZE); vlistviewSetColumnWidth (listview, vlistviewALL_COLUMNS, lifeCELL_SIZE); /* set the size of our petridishen */ vlistSetRowCount (list, lifeNUM_DOWN); vlistSetColumnCount (list, lifeNUM_ACROSS); /* turn on the scroll bars */ vlistviewSetHorzBar (listview, TRUE); vlistviewSetVertBar (listview, TRUE); /* we don't need no steenkin' keyboard */ vlistviewSetUseKeyboardSelection (listview, FALSE); vlistviewSetUseKeyboardTraversal (listview, FALSE); } /* _lifeSetupListview */
/* setup the spreadsheet and fill it with data */ void setupSpreadsheet(spreadStruct *spreadSheet) { register int r, c; int i; double doubleValue; double rd, cd; vstr *string; spreadData *cellData; char format; /* create the list to be used for the spreadsheet */ spreadSheet->spreadList = vlistCreate(); /* associate the list with the listview */ vlistviewSetList(spreadSheet->spreadView, spreadSheet->spreadList); /* set the heights and widths for the cells */ vlistviewSetRowHeight(spreadSheet->spreadView, vlistviewALL_ROWS, spreadSheet->rowHeight); vlistviewSetColumnWidth(spreadSheet->spreadView, vlistviewALL_COLUMNS, spreadSheet->columnWidth); /* allocate memory for the row format */ spreadSheet->rowFormat = (char *) vmemAlloc(sizeof(char) * spreadSheet->numRows); /* fill in values, currently faked */ i = 0; for (r = 0; r < spreadSheet->numRows; r++) { /* faked formats for testing */ if (r % 4) format = (SPREAD_RIGHT_JUSTIFY | SPREAD_COMMAS | SPREAD_DOLLARS | 0x02); else format = (SPREAD_RIGHT_JUSTIFY | SPREAD_COMMAS | 0x03); spreadSheet->rowFormat[r] = format; for (c = 0; c < spreadSheet->numColumns; c++) { /* fake some strings and floats */ if (c % 3) { rd = (double) r; cd = (double) c; doubleValue = (double) (rd * cd) + ((rd + 1.0) / (cd + 1.0)); cellData = (spreadData *) vmemAlloc(sizeof(spreadData)); cellData->type = (SPREAD_DOUBLE | SPREAD_CLEAN); cellData->data.value = doubleValue; } else { /* faked text strings */ switch (i) { case 0 : string = vstrCloneScribed(vcharScribeLiteral("Visix")); break; case 1 : string = vstrCloneScribed(vcharScribeLiteral("Spam")); break; case 2 : string = vstrCloneScribed(vcharScribeLiteral("Galaxy")); break; case 3 : string = vstrCloneScribed(vcharScribeLiteral("Bork")); break; default : string = vstrCloneScribed(vcharScribeLiteral("Fnord")); break; } cellData = (spreadData *) vmemAlloc(sizeof(spreadData)); cellData->type = (SPREAD_STRING | SPREAD_CLEAN); cellData->data.string = string; if (++i > 4) i = 0; } vlistSetCellValue(spreadSheet->spreadList, r, c, cellData); } } }
void *Pressure(void *argument) { int mode; enum {ECHAM_MODE, WMO_MODE}; int geop_code = 0, temp_code = 0, ps_code = 0, lsp_code = 0; int streamID2; int vlistID2; int recID, nrecs; int i, k, offset; int tsID, varID, levelID; int nvars; int zaxisIDp, zaxisIDh = -1, nzaxis; int ngrids, gridID, zaxisID; int nhlev = 0, nhlevf = 0, nhlevh = 0, nlevel; int nvct; int geopID = -1, tempID = -1, psID = -1, lnpsID = -1, pvarID = -1; int code, param; char paramstr[32]; char varname[CDI_MAX_NAME]; double minval, maxval; double *vct = NULL; double *ps_prog = NULL, *full_press = NULL, *half_press = NULL, *deltap = NULL; double *pout = NULL; double *pdata = NULL; int taxisID1, taxisID2; int lhavevct; int nmiss; int mono_level; int instNum, tableNum; int useTable; cdoInitialize(argument); int PRESSURE_FL = cdoOperatorAdd("pressure_fl", 0, 0, NULL); int PRESSURE_HL = cdoOperatorAdd("pressure_hl", 0, 0, NULL); int DELTAP = cdoOperatorAdd("deltap", 0, 0, NULL); int operatorID = cdoOperatorID(); int streamID1 = streamOpenRead(cdoStreamName(0)); int vlistID1 = streamInqVlist(streamID1); int gridsize = vlist_check_gridsize(vlistID1); nzaxis = vlistNzaxis(vlistID1); lhavevct = FALSE; for ( i = 0; i < nzaxis; i++ ) { mono_level = FALSE; mono_level = TRUE; zaxisID = vlistZaxis(vlistID1, i); nlevel = zaxisInqSize(zaxisID); if ( (zaxisInqType(zaxisID) == ZAXIS_HYBRID || zaxisInqType(zaxisID) == ZAXIS_HYBRID_HALF) && nlevel > 1 ) { double *level; int l; level = (double*) malloc(nlevel*sizeof(double)); zaxisInqLevels(zaxisID, level); for ( l = 0; l < nlevel; l++ ) { if ( (l+1) != (int) (level[l]+0.5) ) break; } if ( l == nlevel ) mono_level = TRUE; free(level); } if ( (zaxisInqType(zaxisID) == ZAXIS_HYBRID || zaxisInqType(zaxisID) == ZAXIS_HYBRID_HALF) && nlevel > 1 && mono_level ) { nvct = zaxisInqVctSize(zaxisID); if ( nlevel == (nvct/2 - 1) ) { if ( lhavevct == FALSE ) { lhavevct = TRUE; zaxisIDh = zaxisID; nhlev = nlevel; nhlevf = nhlev; nhlevh = nhlevf + 1; vct = (double*) malloc(nvct*sizeof(double)); zaxisInqVct(zaxisID, vct); } } else if ( nlevel == (nvct/2) ) { if ( lhavevct == FALSE ) { lhavevct = TRUE; zaxisIDh = zaxisID; nhlev = nlevel; nhlevf = nhlev - 1; nhlevh = nhlev; vct = (double*) malloc(nvct*sizeof(double)); zaxisInqVct(zaxisID, vct); } } else if ( nlevel == (nvct - 4 - 1) ) { if ( lhavevct == FALSE ) { int vctsize; int voff = 4; double *rvct = NULL; rvct = (double*) malloc(nvct*sizeof(double)); zaxisInqVct(zaxisID,rvct); if ( (int)(rvct[0]+0.5) == 100000 && rvct[voff] < rvct[voff+1] ) { lhavevct = TRUE; zaxisIDh = zaxisID; nhlev = nlevel; nhlevf = nhlev; nhlevh = nhlev + 1; vctsize = 2*nhlevh; vct = (double*) malloc(vctsize*sizeof(double)); /* calculate VCT for LM */ for ( i = 0; i < vctsize/2; i++ ) { if ( rvct[voff+i] >= rvct[voff] && rvct[voff+i] <= rvct[3] ) { vct[i] = rvct[0]*rvct[voff+i]; vct[vctsize/2+i] = 0; } else { vct[i] = (rvct[0]*rvct[3]*(1-rvct[voff+i]))/(1-rvct[3]); vct[vctsize/2+i] = (rvct[voff+i]-rvct[3])/(1-rvct[3]); } } if ( cdoVerbose ) { for ( i = 0; i < vctsize/2; i++ ) fprintf(stdout, "%5d %25.17f %25.17f\n", i, vct[i], vct[vctsize/2+i]); } } free(rvct); } } } } nvars = vlistNvars(vlistID1); if ( zaxisIDh != -1 && gridsize > 0 ) { ps_prog = (double*) malloc(gridsize*sizeof(double)); deltap = (double*) malloc(gridsize*nhlevf*sizeof(double)); full_press = (double*) malloc(gridsize*nhlevf*sizeof(double)); half_press = (double*) malloc(gridsize*nhlevh*sizeof(double)); } else cdoAbort("No 3D variable with hybrid sigma pressure coordinate found!"); if ( operatorID == PRESSURE_FL || operatorID == DELTAP ) zaxisIDp = zaxisCreate(ZAXIS_HYBRID, nhlevf); else zaxisIDp = zaxisCreate(ZAXIS_HYBRID_HALF, nhlevh); { double *level; int l; level = (double*) malloc(nhlevh*sizeof(double)); for ( l = 0; l < nhlevh; l++ ) level[l] = l+1; zaxisDefLevels(zaxisIDp, level); free(level); } zaxisDefVct(zaxisIDp, 2*nhlevh, vct); useTable = FALSE; for ( varID = 0; varID < nvars; varID++ ) { tableNum = tableInqNum(vlistInqVarTable(vlistID1, varID)); if ( tableNum > 0 && tableNum != 255 ) { useTable = TRUE; break; } } if ( cdoVerbose && useTable ) cdoPrint("Use code tables!"); for ( varID = 0; varID < nvars; varID++ ) { gridID = vlistInqVarGrid(vlistID1, varID); zaxisID = vlistInqVarZaxis(vlistID1, varID); nlevel = zaxisInqSize(zaxisID); instNum = institutInqCenter(vlistInqVarInstitut(vlistID1, varID)); tableNum = tableInqNum(vlistInqVarTable(vlistID1, varID)); code = vlistInqVarCode(vlistID1, varID); param = vlistInqVarParam(vlistID1, varID); cdiParamToString(param, paramstr, sizeof(paramstr)); if ( useTable ) { if ( tableNum == 2 ) { mode = WMO_MODE; geop_code = 6; temp_code = 11; ps_code = 1; } else if ( tableNum == 128 ) { mode = ECHAM_MODE; geop_code = 129; temp_code = 130; ps_code = 134; lsp_code = 152; } else mode = -1; } else { mode = ECHAM_MODE; geop_code = 129; temp_code = 130; ps_code = 134; lsp_code = 152; } if ( cdoVerbose ) cdoPrint("Mode = %d Center = %d Param = %s", mode, instNum, paramstr); if ( code <= 0 ) { vlistInqVarName(vlistID1, varID, varname); strtolower(varname); /* ECHAM ECMWF */ if ( strcmp(varname, "geosp") == 0 || strcmp(varname, "z") == 0 ) code = 129; else if ( strcmp(varname, "st") == 0 || strcmp(varname, "t") == 0 ) code = 130; else if ( strcmp(varname, "aps") == 0 || strcmp(varname, "sp" ) == 0 ) code = 134; else if ( strcmp(varname, "ps") == 0 ) code = 134; else if ( strcmp(varname, "lsp") == 0 || strcmp(varname, "lnsp") == 0 ) code = 152; /* else if ( strcmp(varname, "geopoth") == 0 ) code = 156; */ } if ( mode == ECHAM_MODE ) { if ( code == geop_code && nlevel == 1 ) geopID = varID; else if ( code == temp_code && nlevel == nhlev ) tempID = varID; else if ( code == ps_code && nlevel == 1 ) psID = varID; else if ( code == lsp_code && nlevel == 1 ) lnpsID = varID; /* else if ( code == 156 ) gheightID = varID; */ } else if ( mode == WMO_MODE ) { if ( code == geop_code && nlevel == 1 ) geopID = varID; else if ( code == temp_code && nlevel == nhlev ) tempID = varID; else if ( code == ps_code && nlevel == 1 ) psID = varID; } } pvarID = lnpsID; if ( zaxisIDh != -1 && lnpsID != -1 ) { gridID = vlistInqVarGrid(vlistID1, lnpsID); if ( gridInqType(gridID) == GRID_SPECTRAL ) { lnpsID = -1; cdoWarning("Spectral LOG(%s) not supported - using %s!", var_stdname(surface_air_pressure), var_stdname(surface_air_pressure)); } } if ( zaxisIDh != -1 && lnpsID == -1 ) { pvarID = psID; if ( psID == -1 ) cdoAbort("%s not found!", var_stdname(surface_air_pressure)); } gridID = vlistInqVarGrid(vlistID1, pvarID); if ( gridInqType(gridID) == GRID_SPECTRAL ) cdoAbort("%s on spectral representation not supported!", var_stdname(surface_air_pressure)); pdata = (double*) malloc(gridsize*sizeof(double)); vlistID2 = vlistCreate(); varID = vlistDefVar(vlistID2, gridID, zaxisIDp, TSTEP_INSTANT); vlistDefVarCode(vlistID2, varID, 1); vlistDefVarName(vlistID2, varID, "pressure"); vlistDefVarStdname(vlistID2, varID, "air_pressure"); vlistDefVarUnits(vlistID2, varID, "Pa"); 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); if ( varID == pvarID ) { streamReadRecord(streamID1, pdata, &nmiss); if ( nmiss > 0 ) cdoAbort("Missing valus unsupported!"); } } if ( zaxisIDh != -1 ) { if ( lnpsID != -1 ) for ( i = 0; i < gridsize; i++ ) ps_prog[i] = exp(pdata[i]); else if ( psID != -1 ) memcpy(ps_prog, pdata, gridsize*sizeof(double)); /* check range of ps_prog */ minmaxval(gridsize, ps_prog, NULL, &minval, &maxval); if ( minval < MIN_PS || maxval > MAX_PS ) cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval); presh(full_press, half_press, vct, ps_prog, nhlevf, gridsize); } if ( operatorID == PRESSURE_FL ) { nlevel = nhlevf; pout = full_press; } else if ( operatorID == DELTAP ) { nlevel = nhlevf; for ( k = 0; k < nhlevf; ++k ) for ( i = 0; i < gridsize; ++i ) { deltap[k*gridsize+i] = half_press[(k+1)*gridsize+i] - half_press[k*gridsize+i]; } pout = deltap; } else { nlevel = nhlevh; pout = half_press; } varID = 0; for ( levelID = 0; levelID < nlevel; levelID++ ) { streamDefRecord(streamID2, varID, levelID); offset = levelID*gridsize; streamWriteRecord(streamID2, pout+offset, 0); } tsID++; } streamClose(streamID2); streamClose(streamID1); if ( pdata ) free(pdata); if ( ps_prog ) free(ps_prog); if ( deltap ) free(deltap); if ( full_press ) free(full_press); if ( half_press ) free(half_press); if ( vct ) free(vct); cdoFinish(); return (0); }
int main() { char fname[] = "test.grb"; int filetype = FILETYPE_GRB; enum { nlat = 18, nlon = 2*nlat, }; double *data = NULL; int nlevel; int varID; int streamID1, streamID2; int gridID, zaxisID; int nrecs, nvars; int tsID; int levelID; int vlistID, taxisID; int nmiss; size_t datasize = (size_t)nlon * (size_t)nlat; data = (double *)xmalloc(datasize * sizeof (double)); memset(data, 0, datasize * sizeof (double)); gridID = gridCreate(GRID_GAUSSIAN, (int)datasize); gridDefXsize(gridID, nlon); gridDefYsize(gridID, nlat); zaxisID = zaxisCreate(ZAXIS_SURFACE, 1); vlistID = vlistCreate(); vlistDefVar(vlistID, gridID, zaxisID, TIME_VARIABLE); taxisID = taxisCreate(TAXIS_ABSOLUTE); vlistDefTaxis(vlistID, taxisID); streamID1 = streamOpenWrite(fname, filetype); if ( streamID1 < 0 ) { fprintf(stderr, "Open failed on %s\n", fname); fprintf(stderr, "%s\n", cdiStringError(streamID1)); return (-1); } streamDefVlist(streamID1, vlistID); (void) streamDefTimestep(streamID1, 0); streamWriteVar(streamID1, 0, data, 0); return (0); vlistID = streamInqVlist(streamID1); filetype = streamInqFiletype(streamID1); streamID2 = streamOpenWrite(fname, filetype); if ( streamID2 < 0 ) { fprintf(stderr, "Open failed on %s\n", fname); fprintf(stderr, "%s\n", cdiStringError(streamID2)); return (-1); } streamDefVlist(streamID2, vlistID); nvars = vlistNvars(vlistID); for ( varID = 0; varID < nvars; varID++ ) { int gridID = vlistInqVarGrid(vlistID, varID); int zaxisID = vlistInqVarZaxis(vlistID, varID); size_t gridsize = (size_t)gridInqSize(gridID); size_t nlevel = (size_t)zaxisInqSize(zaxisID); if ( gridsize*nlevel > datasize ) datasize = gridsize*nlevel; } data = (double *)xrealloc(data, datasize*sizeof(double)); memset(data, 0, datasize*sizeof(double)); taxisID = vlistInqTaxis(vlistID); tsID = 0; while ( (nrecs = streamInqTimestep(streamID1, tsID)) ) { /* int vdate = */taxisInqVdate(taxisID); /* int vtime = */taxisInqVtime(taxisID); streamDefTimestep(streamID2, tsID); for ( varID = 0; varID < nvars; varID++ ) { streamReadVar(streamID1, varID, data, &nmiss); /* int code = */vlistInqVarCode(vlistID, varID); gridID = vlistInqVarGrid(vlistID, varID); zaxisID = vlistInqVarZaxis(vlistID, varID); /* int gridtype = */gridInqType(gridID); /* int gridsize = */gridInqSize(gridID); nlevel = zaxisInqSize(zaxisID); /* double missval = */vlistInqVarMissval(vlistID, varID); for ( levelID = 0; levelID < nlevel; levelID++ ) { /* int level = (int) */ zaxisInqLevel(zaxisID, levelID); /* int offset = gridsize*levelID; */ } streamWriteVar(streamID2, varID, data, nmiss); } tsID++; } free(data); streamClose(streamID2); streamClose(streamID1); return (0); }
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 *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); }