Commit 0e1773db authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Added operator selindex.

parent b7a94309
2016-07-29 Uwe Schulzweida
* New operator selindex - Select grid indices
2016-07-18 Uwe Schulzweida
* setgrid: added parameter regularnn
......
......@@ -281,6 +281,7 @@ cdo_SOURCES += Adisit.c \
Seaspctl.c \
Seasstat.c \
Selbox.c \
Selindex.c \
Select.c \
Seloperator.c \
Selrec.c \
......
......@@ -208,15 +208,16 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
cdo-Rhopot.$(OBJEXT) cdo-Rotuv.$(OBJEXT) cdo-Runpctl.$(OBJEXT) \
cdo-Runstat.$(OBJEXT) cdo-Seascount.$(OBJEXT) \
cdo-Seaspctl.$(OBJEXT) cdo-Seasstat.$(OBJEXT) \
cdo-Selbox.$(OBJEXT) cdo-Select.$(OBJEXT) \
cdo-Seloperator.$(OBJEXT) cdo-Selrec.$(OBJEXT) \
cdo-Seltime.$(OBJEXT) cdo-Selvar.$(OBJEXT) cdo-Set.$(OBJEXT) \
cdo-Setbox.$(OBJEXT) cdo-Setgatt.$(OBJEXT) \
cdo-Setgrid.$(OBJEXT) cdo-Sethalo.$(OBJEXT) \
cdo-Setmiss.$(OBJEXT) cdo-Setpartab.$(OBJEXT) \
cdo-Setrcaname.$(OBJEXT) cdo-Settime.$(OBJEXT) \
cdo-Setzaxis.$(OBJEXT) cdo-Showinfo.$(OBJEXT) \
cdo-Sinfo.$(OBJEXT) cdo-Smooth.$(OBJEXT) cdo-Sort.$(OBJEXT) \
cdo-Selbox.$(OBJEXT) cdo-Selindex.$(OBJEXT) \
cdo-Select.$(OBJEXT) cdo-Seloperator.$(OBJEXT) \
cdo-Selrec.$(OBJEXT) cdo-Seltime.$(OBJEXT) \
cdo-Selvar.$(OBJEXT) cdo-Set.$(OBJEXT) cdo-Setbox.$(OBJEXT) \
cdo-Setgatt.$(OBJEXT) cdo-Setgrid.$(OBJEXT) \
cdo-Sethalo.$(OBJEXT) cdo-Setmiss.$(OBJEXT) \
cdo-Setpartab.$(OBJEXT) cdo-Setrcaname.$(OBJEXT) \
cdo-Settime.$(OBJEXT) cdo-Setzaxis.$(OBJEXT) \
cdo-Showinfo.$(OBJEXT) cdo-Sinfo.$(OBJEXT) \
cdo-Smooth.$(OBJEXT) cdo-Sort.$(OBJEXT) \
cdo-Sorttimestamp.$(OBJEXT) cdo-Specinfo.$(OBJEXT) \
cdo-Spectral.$(OBJEXT) cdo-Spectrum.$(OBJEXT) \
cdo-Split.$(OBJEXT) cdo-Splitrec.$(OBJEXT) \
......@@ -563,7 +564,7 @@ cdo_SOURCES = cdo.c Adisit.c Afterburner.c Arith.c Arithc.c \
Nmltest.c Output.c Outputgmt.c Pack.c Pardup.c Pinfo.c \
Pressure.c Regres.c Remap.c Remapeta.c Replace.c \
Replacevalues.c Rhopot.c Rotuv.c Runpctl.c Runstat.c \
Seascount.c Seaspctl.c Seasstat.c Selbox.c Select.c \
Seascount.c Seaspctl.c Seasstat.c Selbox.c Selindex.c Select.c \
Seloperator.c Selrec.c Seltime.c Selvar.c Set.c Setbox.c \
Setgatt.c Setgrid.c Sethalo.c Setmiss.c Setpartab.c \
Setrcaname.c Settime.c Setzaxis.c Showinfo.c Sinfo.c Smooth.c \
......@@ -889,6 +890,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdo-Seasstat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdo-Selbox.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdo-Select.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdo-Selindex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdo-Seloperator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdo-Selrec.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdo-Seltime.Po@am__quote@
......@@ -3273,6 +3275,20 @@ cdo-Selbox.obj: Selbox.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Selbox.obj `if test -f 'Selbox.c'; then $(CYGPATH_W) 'Selbox.c'; else $(CYGPATH_W) '$(srcdir)/Selbox.c'; fi`
cdo-Selindex.o: Selindex.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Selindex.o -MD -MP -MF $(DEPDIR)/cdo-Selindex.Tpo -c -o cdo-Selindex.o `test -f 'Selindex.c' || echo '$(srcdir)/'`Selindex.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Selindex.Tpo $(DEPDIR)/cdo-Selindex.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Selindex.c' object='cdo-Selindex.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Selindex.o `test -f 'Selindex.c' || echo '$(srcdir)/'`Selindex.c
cdo-Selindex.obj: Selindex.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Selindex.obj -MD -MP -MF $(DEPDIR)/cdo-Selindex.Tpo -c -o cdo-Selindex.obj `if test -f 'Selindex.c'; then $(CYGPATH_W) 'Selindex.c'; else $(CYGPATH_W) '$(srcdir)/Selindex.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Selindex.Tpo $(DEPDIR)/cdo-Selindex.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Selindex.c' object='cdo-Selindex.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Selindex.obj `if test -f 'Selindex.c'; then $(CYGPATH_W) 'Selindex.c'; else $(CYGPATH_W) '$(srcdir)/Selindex.c'; fi`
cdo-Select.o: Select.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Select.o -MD -MP -MF $(DEPDIR)/cdo-Select.Tpo -c -o cdo-Select.o `test -f 'Select.c' || echo '$(srcdir)/'`Select.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Select.Tpo $(DEPDIR)/cdo-Select.Po
......
......@@ -232,7 +232,7 @@ int gengrid(int gridID1, int lat1, int lat2, int lon11, int lon12, int lon21, in
return gridID2;
}
static
int gengridcell(int gridID1, int gridsize2, int *cellidx)
{
char xname[CDI_MAX_NAME], xlongname[CDI_MAX_NAME], xunits[CDI_MAX_NAME];
......
/*
This file is part of CDO. CDO is a collection of Operators to
manipulate and analyse Climate model Data.
Copyright (C) 2003-2016 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
See COPYING file for copying and redistribution conditions.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/*
This module contains the following operators:
Selindex selindex Select grid indices
*/
#include <cdi.h>
#include "cdo.h"
#include "cdo_int.h"
#include "grid.h"
#include "list.h"
#include "pstream.h"
int gengridcell(int gridID1, int gridsize2, int *cellidx);
static
int genindexgrid(int gridID1, int gridsize2, int *cellidx)
{
int gridtype1 = gridInqType(gridID1);
int gridtype = (gridsize2 == 1) ? GRID_LONLAT : GRID_UNSTRUCTURED;
int gridID2 = -1;
if ( gridtype1 == GRID_UNSTRUCTURED ) gridID2 = gengridcell(gridID1, gridsize2, cellidx);
if ( gridID2 == -1 ) cdoAbort("Unsupported grid!");
return gridID2;
}
static
void sel_index(double *array1, double *array2, int nind, int *indarr)
{
for ( int i = 0; i < nind; ++i )
{
array2[i] = array1[indarr[i]];
}
}
void *Selindex(void *argument)
{
int nrecs;
int varID, levelID;
int gridID1 = -1, gridID2;
int index, gridtype = -1;
int nmiss;
double missval;
typedef struct {
int gridID1, gridID2;
} sindex_t;
LIST *ilist = listNew(INT_LIST);
cdoInitialize(argument);
cdoOperatorAdd("selindex", 0, 0, "grid cell indices (1-N)");
operatorInputArg(cdoOperatorEnter(0));
int nind = args2intlist(operatorArgc(), operatorArgv(), ilist);
int *indarr = (int*) listArrayPtr(ilist);
int indmin = indarr[0];
int indmax = indarr[0];
for ( int i = 1; i < nind; i++ )
{
if ( indmax < indarr[i] ) indmax = indarr[i];
if ( indmin > indarr[i] ) indmin = indarr[i];
}
if ( cdoVerbose )
for ( int i = 0; i < nind; i++ )
cdoPrint("int %d = %d", i+1, indarr[i]);
if ( indmin < 1 ) cdoAbort("Index < 1 not allowed!");
for ( int i = 0; i < nind; i++ ) indarr[i] -= 1;
int streamID1 = streamOpenRead(cdoStreamName(0));
int vlistID1 = streamInqVlist(streamID1);
int vlistID2 = vlistDuplicate(vlistID1);
int taxisID1 = vlistInqTaxis(vlistID1);
int taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
int nvars = vlistNvars(vlistID1);
bool *vars = (bool*) Malloc(nvars*sizeof(bool));
for ( varID = 0; varID < nvars; varID++ ) vars[varID] = false;
int ngrids = vlistNgrids(vlistID1);
sindex_t *sindex = (sindex_t *) Malloc(ngrids*sizeof(sindex_t));
for ( index = 0; index < ngrids; index++ )
{
gridID1 = vlistGrid(vlistID1, index);
gridtype = gridInqType(gridID1);
int gridsize = gridInqSize(gridID1);
if ( gridsize == 1 ) continue;
if ( indmax > gridsize )
{
cdoWarning("Max grid index is greater than grid size, skipped grid %d!", index+1);
continue;
}
gridID2 = genindexgrid(gridID1, nind, indarr);
sindex[index].gridID1 = gridID1;
sindex[index].gridID2 = gridID2;
vlistChangeGridIndex(vlistID2, index, gridID2);
for ( varID = 0; varID < nvars; varID++ )
if ( gridID1 == vlistInqVarGrid(vlistID1, varID) )
vars[varID] = true;
}
for ( varID = 0; varID < nvars; varID++ )
if ( vars[varID] ) break;
if ( varID >= nvars ) cdoAbort("No variables selected!");
int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
streamDefVlist(streamID2, vlistID2);
int gridsize = vlistGridsizeMax(vlistID1);
if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
double *array1 = (double*) Malloc(gridsize*sizeof(double));
int gridsize2 = vlistGridsizeMax(vlistID2);
if ( vlistNumber(vlistID2) != CDI_REAL ) gridsize2 *= 2;
double *array2 = (double*) Malloc(gridsize2*sizeof(double));
int tsID = 0;
while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
{
taxisCopyTimestep(taxisID2, taxisID1);
streamDefTimestep(streamID2, tsID);
for ( int recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
streamReadRecord(streamID1, array1, &nmiss);
streamDefRecord(streamID2, varID, levelID);
if ( vars[varID] )
{
gridID1 = vlistInqVarGrid(vlistID1, varID);
for ( index = 0; index < ngrids; index++ )
if ( gridID1 == sindex[index].gridID1 ) break;
if ( index == ngrids ) cdoAbort("Internal problem, grid not found!");
gridsize2 = gridInqSize(sindex[index].gridID2);
sel_index(array1, array2, nind, indarr);
if ( nmiss )
{
nmiss = 0;
missval = vlistInqVarMissval(vlistID2, varID);
for ( int i = 0; i < gridsize2; i++ )
if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
}
streamWriteRecord(streamID2, array2, nmiss);
}
else
{
streamWriteRecord(streamID2, array1, nmiss);
}
}
tsID++;
}
streamClose(streamID2);
streamClose(streamID1);
vlistDestroy(vlistID2);
if ( vars ) Free(vars);
if ( array2 ) Free(array2);
if ( array1 ) Free(array1);
if ( sindex ) Free(sindex);
listDelete(ilist);
cdoFinish();
return 0;
}
......@@ -146,6 +146,7 @@ void *Seascount(void *argument);
void *Seaspctl(void *argument);
void *Seasstat(void *argument);
void *Selbox(void *argument);
void *Selindex(void *argument);
void *Select(void *argument);
void *Selvar(void *argument);
void *Seloperator(void *argument);
......@@ -398,6 +399,7 @@ void *Maggraph(void *argument);
#define SeaspctlOperators {"seaspctl"}
#define SeasstatOperators {"seasmin", "seasmax", "seassum", "seasmean", "seasavg", "seasstd", "seasstd1", "seasvar", "seasvar1"}
#define SelboxOperators {"sellonlatbox", "selindexbox"}
#define SelindexOperators {"selindex"}
#define SelectOperators {"select", "delete"}
#define SelvarOperators {"selparam", "selcode", "selname", "selstdname", "sellevel", "sellevidx", "selgrid", \
"selzaxis", "selzaxisname", "seltabnum", "delparam", "delcode", "delname", "selltype"}
......@@ -679,6 +681,7 @@ static modules_t Modules[] =
{ Seaspctl, SeaspctlHelp, SeaspctlOperators, 1, CDI_REAL, 3, 1 },
{ Seasstat, SeasstatHelp, SeasstatOperators, 1, CDI_REAL, 1, 1 },
{ Selbox, SelboxHelp, SelboxOperators, 1, CDI_BOTH, 1, 1 },
{ Selindex, NULL, SelindexOperators, 1, CDI_BOTH, 1, 1 },
{ Select, SelectHelp, SelectOperators, 1, CDI_BOTH, -1, 1 },
{ Selvar, SelvarHelp, SelvarOperators, 1, CDI_BOTH, 1, 1 },
{ Selrec, SelvarHelp, SelrecOperators, 1, CDI_BOTH, 1, 1 },
......
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