Commit 97281206 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

collgrid: added support for curvilinear grids

parent 9a8e1102
......@@ -3,9 +3,9 @@
* using CDI library version 1.7.0
* Version 1.7.0 released
2015-07-15 Uwe Schulzweida
2015-07-16 Uwe Schulzweida
* distgrid: added support for curvilinear grids
* collgrid: added support for curvilinear grids
2015-06-27 Uwe Schulzweida
......
......@@ -5,6 +5,7 @@ Version 1.7.0 (28 October 2015):
New features:
* distgrid: added support for curvilinear grids
* collgrid: added support for curvilinear grids
New operators:
* setmisstonn: Set missing value to nearest neightbour
* vertstd1: Vertical standard deviation [Divisor is (n-1)]
......
......@@ -11,19 +11,22 @@
@BeginOperator_collgrid
@Title = Collect horizontal grid
@Parameter = [names]
@Parameter = [nx] [names]
@BeginDescription
This operator collects the data of the input files to one output file.
All input files need to have the same variables and the same number of timesteps on a different
horizonal grid region. A source region must be a rectilinear longitude/latitude grid box.
horizonal grid region. A source region must be a structured longitude/latitude grid box.
The parameter @var{nx} needs to be specified only for curvilinear grids.
@EndDescription
@EndOperator
@BeginParameter names
@Item = nx
INTEGER Number of regions in x direction, only needed for curvilinear grids
@Item = names
STRING Comma separated list of variable names [default: all variables]
STRING Comma separated list of variable names [default: all variables]
@EndParameter
......
......@@ -15,10 +15,11 @@
@BeginDescription
This operator distributes a dataset into smaller pieces. Each output file contains a different region of the horizontal
source grid. A target grid region contains a regular longitude/latitude box of the source grid. Only rectilinear source
grids are supported by this operator. The number of different regions can be specified with the parameter @var{nx} and @var{ny}.
The output files will be named <obase><xxx><suffix> where suffix is the filename extension derived from the file format.
xxx will have five digits with the number of the target region.
source grid. A target grid region contains a structured longitude/latitude box of the source grid. Only rectilinear and
curvilinear source grids are supported by this operator.
The number of different regions can be specified with the parameter @var{nx} and @var{ny}. The output files will be named
<obase><xxx><suffix> where suffix is the filename extension derived from the file format. xxx will have five digits with
the number of the target region.
@EndDescription
@EndOperator
......
......@@ -15,6 +15,8 @@
GNU General Public License for more details.
*/
#include <ctype.h>
#include <cdi.h>
#include "cdo.h"
#include "cdo_int.h"
......@@ -48,7 +50,7 @@ int cmpx(const void *s1, const void *s2)
if ( xy1->x < xy2->x ) cmp = -1;
else if ( xy1->x > xy2->x ) cmp = 1;
return (cmp);
return cmp;
}
static
......@@ -61,7 +63,7 @@ int cmpxy_lt(const void *s1, const void *s2)
if ( xy1->y < xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x < xy2->x) ) cmp = -1;
else if ( xy1->y > xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x > xy2->x) ) cmp = 1;
return (cmp);
return cmp;
}
static
......@@ -74,28 +76,24 @@ int cmpxy_gt(const void *s1, const void *s2)
if ( xy1->y > xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x < xy2->x) ) cmp = -1;
else if ( xy1->y < xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x > xy2->x) ) cmp = 1;
return (cmp);
return cmp;
}
static
int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid, int nxblocks)
{
int lsouthnorth = TRUE;
int fileID;
int gridID;
int gridID2 = -1;
int gridtype = -1;
int *xoff, *yoff;
int xsize2, ysize2;
int idx;
int nx, ny, ix, iy, i, j, ij, offset;
int lregular = TRUE;
double *xvals2, *yvals2;
gridID = vlistGrid(ef[0].vlistID, igrid);
gridtype = gridInqType(gridID);
int gridID = vlistGrid(ef[0].vlistID, igrid);
int gridtype = gridInqType(gridID);
if ( gridtype == GRID_GENERIC && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
return (gridID2);
return gridID2;
int *xsize = (int*) malloc(nfiles*sizeof(int));
int *ysize = (int*) malloc(nfiles*sizeof(int));
......@@ -117,12 +115,7 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
xsize[fileID] = gridInqXsize(gridID);
ysize[fileID] = gridInqYsize(gridID);
/*
if ( xsize == 0 ) xsize = gridInqXsize(gridID);
if ( ysize == 0 ) ysize = gridInqYsize(gridID);
if ( xsize != gridInqXsize(gridID) ) cdoAbort("xsize differ!");
if ( ysize != gridInqYsize(gridID) ) cdoAbort("ysize differ!");
*/
if ( lregular )
{
xvals[fileID] = (double*) malloc(xsize[fileID]*sizeof(double));
......@@ -148,39 +141,47 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
if ( yvals[fileID][0] > yvals[fileID][ysize[fileID]-1] ) lsouthnorth = FALSE;
}
}
/*
if ( cdoVerbose )
for ( fileID = 0; fileID < nfiles; fileID++ )
printf("1 %d %g %g \n", xyinfo[fileID].id, xyinfo[fileID].x, xyinfo[fileID].y);
*/
qsort(xyinfo, nfiles, sizeof(xyinfo_t), cmpx);
/*
if ( cdoVerbose )
for ( fileID = 0; fileID < nfiles; fileID++ )
printf("2 %d %g %g \n", xyinfo[fileID].id, xyinfo[fileID].x, xyinfo[fileID].y);
*/
if ( lsouthnorth )
qsort(xyinfo, nfiles, sizeof(xyinfo_t), cmpxy_lt);
else
qsort(xyinfo, nfiles, sizeof(xyinfo_t), cmpxy_gt);
if ( cdoVerbose )
for ( fileID = 0; fileID < nfiles; fileID++ )
printf("3 %d %g %g \n", xyinfo[fileID].id, xyinfo[fileID].x, xyinfo[fileID].y);
if ( lregular )
{
qsort(xyinfo, nfiles, sizeof(xyinfo_t), cmpx);
nx = 1;
for ( fileID = 1; fileID < nfiles; fileID++ )
if ( cdoVerbose )
for ( fileID = 0; fileID < nfiles; fileID++ )
printf("2 %d %g %g \n", xyinfo[fileID].id, xyinfo[fileID].x, xyinfo[fileID].y);
if ( lsouthnorth )
qsort(xyinfo, nfiles, sizeof(xyinfo_t), cmpxy_lt);
else
qsort(xyinfo, nfiles, sizeof(xyinfo_t), cmpxy_gt);
if ( cdoVerbose )
for ( fileID = 0; fileID < nfiles; fileID++ )
printf("3 %d %g %g \n", xyinfo[fileID].id, xyinfo[fileID].x, xyinfo[fileID].y);
nx = 1;
for ( fileID = 1; fileID < nfiles; fileID++ )
{
if ( DBL_IS_EQUAL(xyinfo[0].y, xyinfo[fileID].y) ) nx++;
else break;
}
}
else
{
if ( DBL_IS_EQUAL(xyinfo[0].y, xyinfo[fileID].y) ) nx++;
else break;
nx = nxblocks;
if ( nx <= 0 ) cdoAbort("Parameter nxblocks missing!");
}
ny = nfiles/nx;
if ( cdoVerbose ) cdoPrint("nx %d ny %d", nx, ny);
if ( nx*ny != nfiles ) cdoAbort("Number of input files (%d) seems to be incomplete!", nfiles);
if ( nx*ny != nfiles ) cdoAbort("Number of input files (%d) and number of blocks (%dx%d) differ!", nfiles, nx, ny);
xsize2 = 0;
int xsize2 = 0;
for ( i = 0; i < nx; ++i ) xsize2 += xsize[xyinfo[i].id];
ysize2 = 0;
int ysize2 = 0;
for ( j = 0; j < ny; ++j ) ysize2 += ysize[xyinfo[j*nx].id];
if ( cdoVerbose ) cdoPrint("xsize2 %d ysize2 %d", xsize2, ysize2);
......@@ -195,8 +196,8 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
yvals2 = (double*) malloc(xsize2*ysize2*sizeof(double));
}
xoff = (int*) malloc((nx+1)*sizeof(int));
yoff = (int*) malloc((ny+1)*sizeof(int));
int *xoff = (int*) malloc((nx+1)*sizeof(int));
int *yoff = (int*) malloc((ny+1)*sizeof(int));
xoff[0] = 0;
for ( i = 0; i < nx; ++i )
......@@ -279,18 +280,19 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
free(yvals);
free(xyinfo);
return (gridID2);
return gridID2;
}
void *Collgrid(void *argument)
{
int nxblocks = 1;
int varID, recID;
int nrecs, nrecs0;
int levelID;
int nmiss;
double missval;
int fileID;
double missval;
cdoInitialize(argument);
......@@ -324,6 +326,19 @@ void *Collgrid(void *argument)
for ( varID = 0; varID < nvars; varID++ ) vars1[varID] = FALSE;
int nsel = operatorArgc();
if ( nsel > 0 )
{
int len = (int) strlen(operatorArgv()[0]);
while ( --len >= 0 && isdigit(operatorArgv()[0][len]) ) ;
if ( len == -1 )
{
nsel--;
nxblocks = parameter2int(operatorArgv()[0]);
}
}
if ( nsel == 0 )
{
for ( varID = 0; varID < nvars; varID++ ) vars1[varID] = TRUE;
......@@ -418,11 +433,11 @@ void *Collgrid(void *argument)
if ( ginit == FALSE )
{
gridIDs[i2] = genGrid(nfiles, ef, gridindex, i1);
gridIDs[i2] = genGrid(nfiles, ef, gridindex, i1, nxblocks);
if ( gridIDs[i2] != -1 ) ginit = TRUE;
}
else
gridIDs[i2] = genGrid(nfiles, ef, NULL, i1);
gridIDs[i2] = genGrid(nfiles, ef, NULL, i1, nxblocks);
}
......@@ -548,5 +563,5 @@ void *Collgrid(void *argument)
cdoFinish();
return (0);
return 0;
}
......@@ -20,7 +20,7 @@
#include "cdo_int.h"
#include "pstream.h"
#define MAX_BLOCKS 16384
#define MAX_BLOCKS 65536
static
void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, int nyblocks,
......@@ -131,9 +131,7 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
static
void window_cell(double *array1, double *array2, long gridsize2, int *cellidx)
{
long i;
for ( i = 0; i < gridsize2; ++i )
for ( long i = 0; i < gridsize2; ++i )
array2[i] = array1[cellidx[i]];
}
......@@ -148,44 +146,36 @@ typedef struct
void *Distgrid(void *argument)
{
int nchars;
int streamID1;
int *vlistIDs = NULL, *streamIDs = NULL;
int gridID1 = -1, varID;
int nrecs, ngrids;
int tsID, recID, levelID;
int vlistID1;
int gridID1;
int varID;
int nrecs;
int recID, levelID;
char filesuffix[32];
char filename[8192];
const char *refname;
int index;
int nsplit;
int xinc = 1, yinc = 1;
int gridsize, gridsize2max;
int gridtype = -1;
int nmiss;
int nxblocks = 1, nyblocks = 1;
int nx, ny, i;
int i;
double missval;
double *array1 = NULL, *array2 = NULL;
sgrid_t *grids;
cdoInitialize(argument);
operatorInputArg("nxblocks, [nyblocks]");
if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
nxblocks = parameter2int(operatorArgv()[0]);
int nxblocks = parameter2int(operatorArgv()[0]);
int nyblocks = 1;
if ( operatorArgc() == 2 ) nyblocks = parameter2int(operatorArgv()[1]);
if ( nxblocks <= 0 ) cdoAbort("nxblocks has to be greater than 0!");
if ( nyblocks <= 0 ) cdoAbort("nyblocks has to be greater than 0!");
streamID1 = streamOpenRead(cdoStreamName(0));
int streamID1 = streamOpenRead(cdoStreamName(0));
vlistID1 = streamInqVlist(streamID1);
int vlistID1 = streamInqVlist(streamID1);
ngrids = vlistNgrids(vlistID1);
int ngrids = vlistNgrids(vlistID1);
for ( index = 0; index < ngrids; index++ )
{
......@@ -200,9 +190,9 @@ void *Distgrid(void *argument)
cdoAbort("No Lon/Lat, Gaussian or Generic grid found (%s data unsupported)!", gridNamePtr(gridtype));
gridID1 = vlistGrid(vlistID1, 0);
gridsize = gridInqSize(gridID1);
nx = gridInqXsize(gridID1);
ny = gridInqYsize(gridID1);
int gridsize = gridInqSize(gridID1);
int nx = gridInqXsize(gridID1);
int ny = gridInqYsize(gridID1);
for ( i = 1; i < ngrids; i++ )
{
gridID1 = vlistGrid(vlistID1, i);
......@@ -221,21 +211,21 @@ void *Distgrid(void *argument)
nyblocks = ny;
}
xinc = nx/nxblocks;
yinc = ny/nyblocks;
int xinc = nx/nxblocks;
int yinc = ny/nyblocks;
if ( nx%xinc != 0 ) xinc++;
if ( ny%yinc != 0 ) yinc++;
nsplit = nxblocks*nyblocks;
int nsplit = nxblocks*nyblocks;
if ( nsplit > MAX_BLOCKS ) cdoAbort("Too many blocks (max = %d)!", MAX_BLOCKS);
array1 = (double*) malloc(gridsize*sizeof(double));
double *array1 = (double*) malloc(gridsize*sizeof(double));
vlistIDs = (int*) malloc(nsplit*sizeof(int));
streamIDs = (int*) malloc(nsplit*sizeof(int));
int *vlistIDs = (int*) malloc(nsplit*sizeof(int));
int *streamIDs = (int*) malloc(nsplit*sizeof(int));
grids = (sgrid_t*) malloc(ngrids*sizeof(sgrid_t));
sgrid_t *grids = (sgrid_t*) malloc(ngrids*sizeof(sgrid_t));
for ( i = 0; i < ngrids; i++ )
{
gridID1 = vlistGrid(vlistID1, i);
......@@ -265,14 +255,14 @@ void *Distgrid(void *argument)
vlistChangeGridIndex(vlistIDs[index], i, grids[i].gridIDs[index]);
}
gridsize2max = 0;
int gridsize2max = 0;
for ( index = 0; index < nsplit; index++ )
if ( grids[0].gridsize[index] > gridsize2max ) gridsize2max = grids[0].gridsize[index];
array2 = (double*) malloc(gridsize2max*sizeof(double));
double *array2 = (double*) malloc(gridsize2max*sizeof(double));
strcpy(filename, cdoStreamName(1)->args);
nchars = strlen(filename);
int nchars = strlen(filename);
refname = cdoStreamName(0)->argv[cdoStreamName(0)->argc-1];
filesuffix[0] = 0;
......@@ -292,7 +282,7 @@ void *Distgrid(void *argument)
}
if ( ngrids > 1 ) cdoPrint("Bausstelle: number of different grids > 1!");
tsID = 0;
int tsID = 0;
while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
{
for ( index = 0; index < nsplit; index++ )
......@@ -352,5 +342,5 @@ void *Distgrid(void *argument)
cdoFinish();
return (0);
return 0;
}
......@@ -1418,7 +1418,6 @@ int main(int argc, char *argv[])
fprintf(stderr, "OMP num procs = %d\n", omp_get_num_procs());
fprintf(stderr, "OMP max threads = %d\n", omp_get_max_threads());
fprintf(stderr, "OMP num threads = %d\n", omp_get_num_threads());
fprintf(stderr, "OMP num threads = %d\n", omp_get_num_threads());
fprintf(stderr, "OMP thread limit = %d\n", omp_get_thread_limit());
omp_sched_t kind;
int modifer;
......
......@@ -409,10 +409,11 @@ static char *DistgridHelp[] = {
"",
"DESCRIPTION",
" This operator distributes a dataset into smaller pieces. Each output file contains a different region of the horizontal ",
" source grid. A target grid region contains a regular longitude/latitude box of the source grid. Only rectilinear source ",
" grids are supported by this operator. The number of different regions can be specified with the parameter nx and ny.",
" The output files will be named <obase><xxx><suffix> where suffix is the filename extension derived from the file format. ",
" xxx will have five digits with the number of the target region.",
" source grid. A target grid region contains a structured longitude/latitude box of the source grid. Only rectilinear and",
" curvilinear source grids are supported by this operator.",
" The number of different regions can be specified with the parameter nx and ny. The output files will be named ",
" <obase><xxx><suffix> where suffix is the filename extension derived from the file format. xxx will have five digits with ",
" the number of the target region.",
"",
"PARAMETER",
" nx INTEGER Number of regions in x direction",
......@@ -429,15 +430,17 @@ static char *CollgridHelp[] = {
" collgrid - Collect horizontal grid",
"",
"SYNOPSIS",
" collgrid[,names] ifiles ofile",
" collgrid[,nx[,names]] ifiles ofile",
"",
"DESCRIPTION",
" This operator collects the data of the input files to one output file. ",
" All input files need to have the same variables and the same number of timesteps on a different",
" horizonal grid region. A source region must be a rectilinear longitude/latitude grid box.",
" horizonal grid region. A source region must be a structured longitude/latitude grid box.",
" The parameter nx needs to be specified only for curvilinear grids.",
"",
"PARAMETER",
" names STRING Comma separated list of variable names [default: all variables]",
" nx INTEGER Number of regions in x direction, only needed for curvilinear grids",
" names STRING Comma separated list of variable names [default: all variables]",
"",
"NOTE",
" This operator needs to open all input files simultaneously.",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment