Commit 982f5238 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

New operator selmulti: Select multiple fields (patch from Michal Koutek, KMNI).

parent d7e9760b
......@@ -3,15 +3,20 @@
* Using CDI library version 1.8.1
* Version 1.8.1 release
2017-03-06 Uwe Schulzweida
* New operator selmulti: Select multiple fields (patch from Michal Koutek, KMNI)
* New operator delmulti: Delete multiple fields (patch from Michal Koutek, KMNI)
* New operator changemulti: Change identication of multiple fields (patch from Michal Koutek, KMNI)
2017-03-03 Uwe Schulzweida
* New operator uvDestag: Destaggering of u-, v- wind components (patch from Michal Koutek, KMNI)
* New operator rotuvNorth: Rotate grid-relative wind(u,v) to North_pole-relative (patch from Michal Koutek, KMNI)
* New operator projuvLatLon: Cylindrical Equidistant projection (patch from Michal Koutek, KMNI)
2017-02-28 Uwe Schulzweida
* New operator uvDestag: destaggering of wind components (patch from Michal Koutek, KMNI)
* New operator uvDestag: Destaggering of wind components (patch from Michal Koutek, KMNI)
2017-02-27 Uwe Schulzweida
......
......@@ -69,6 +69,9 @@ Operator catalog:
-------------------------------------------------------------
Select select Select fields
Select delete Delete fields
Selmulti selmulti Select multiple fields
Selmulti delmulti Delete multiple fields
Selmulti changemulti Change identication of multiple fields
Selvar selparam Select parameters by identifier
Selvar delparam Delete parameters by identifier
Selvar selcode Select parameters by code number
......
......@@ -15,6 +15,7 @@ Splitsel File operations
Distgrid File operations
Collgrid File operations
Select Selection
Selmulti Selection
Selvar Selection
Seltime Selection
Selbox Selection
......
......@@ -188,7 +188,7 @@ keepaspectratio]{cdo_libdep.pdf}}%
\begin{titlepage}
\vspace*{50mm}
%\vspace*{25mm}
{\Huge{\CDO}} \ {\Huge \textbf{User's Guide}}
{\Huge{\CDO}} \ {\Huge \textbf{User Guide}}
\setlength{\unitlength}{1cm}
\begin{picture}(16,0.4)
......
@BeginModule
@NewPage
@Name = Selmulti
@Title = Select multiple fields via GRIB1 parameters
@Section = Selection
@Class = Selection
@Arguments = infile outfile
@Operators = selmulti delmulti changemulti
@BeginDescription
This module selects multiple fields from @file{infile} and writes them to @file{outfile}.
selection-specification is a filename or in-place string with the selection specification.
Each selection-specification has the following compact notation format:
@BeginVerbatim
<type>(parameters; leveltype(s); levels)
@EndVerbatim
@BeginList parameters
@Item = type
sel for select or del for delete (optional)
@Item = parameters
GRIB1 parameter code number
@Item = leveltype
GRIB1 level type
@Item = levels
value of each level
@EndList
Examples:
@BeginListing
(1; 103; 0)
(33,34; 105; 10)
(11,17; 105; 2)
(71,73,74,75,61,62,65,117,67,122,121,11,131,66,84,111,112; 105; 0)
@EndListing
The following descriptive notation can also be used for selection specification from a file:
@BeginVerbatim
SELECT/DELETE, PARAMETER=parameters, LEVTYPE=leveltye(s), LEVEL=levels
@EndVerbatim
Examples:
@BeginListing
SELECT, PARAMETER=1, LEVTYPE=103, LEVEL=0
SELECT, PARAMETER=33/34, LEVTYPE=105, LEVEL=10
SELECT, PARAMETER=11/17, LEVTYPE=105, LEVEL=2
SELECT, PARAMETER=71/73/74/75/61/62/65/117/67/122, LEVTYPE=105, LEVEL=0
DELETE, PARAMETER=128, LEVTYPE=109, LEVEL=*
@EndListing
The following will convert Pressure from Pa into hPa; Temp from Kelvin to Celsius:
@BeginListing
SELECT, PARAMETER=1, LEVTYPE= 103, LEVEL=0, SCALE=0.01
SELECT, PARAMETER=11, LEVTYPE=105, LEVEL=2, OFFSET=273.15
@EndListing
If SCALE and/or OFFSET are defined, then the data values are scaled as SCALE*(VALUE-OFFSET).
@EndDescription
@EndModule
@BeginOperator_selmulti
@Title = Select multiple fields
@Parameter = selection-specification
@BeginDescription
@EndDescription
@EndOperator
@BeginOperator_delmulti
@Title = Delete multiple fields
@Parameter = selection-specification
@BeginDescription
@EndDescription
@EndOperator
@BeginOperator_changemulti
@Title = Change identication of multiple fields
@Parameter = selection-specification
@BeginDescription
@EndDescription
@EndOperator
@BeginExample
Change ECMWF GRIB code of surface pressure to Hirlam notation:
@BeginVerbatim
cdo changemulti,'{(134;1;*|1;105;*)}' infile outfile
@EndVerbatim
@EndExample
......@@ -150,21 +150,14 @@ int multiSelectionParser(const char *filenameOrString);
void *Selmulti(void *argument)
{
int streamID1, streamID2 = CDI_UNDEFID;
int nrecs;
int tsID, recID, varID, levelID;
int vlistID1, vlistID2;
int taxisID1, taxisID2;
int varID, levelID;
double level;
int nvars, nlevs, code, zaxisID;
int nlevs, code, zaxisID;
int ltype = 0;
int varID2, levelID2;
int sellevel, selcode, selltype;
int lcopy = FALSE;
int gridsize, nmiss;
double *array = NULL;
int SELMULTI, DELMULTI, CHANGEMULTI;
int operatorID;
bool lcopy = false;
int nmiss;
int simpleMath=0; // 1: simple array arithmetics ( *,+), 0: do nothing
float scale = 1.0;
float offset = 0.0; // If SCALE and/or OFFSET are defined, then the data values are scaled as SCALE*(VALUE-OFFSET).
......@@ -173,11 +166,11 @@ void *Selmulti(void *argument)
cdoInitialize(argument);
SELMULTI = cdoOperatorAdd("selmulti", 0, 0, "filename/string with selection specification ");
DELMULTI = cdoOperatorAdd("delmulti", 0, 0, "filename/string with selection specification ");
CHANGEMULTI = cdoOperatorAdd("changemulti", 0, 0, "filename/string with selection specification ");
int SELMULTI = cdoOperatorAdd("selmulti", 0, 0, "filename/string with selection specification ");
int DELMULTI = cdoOperatorAdd("delmulti", 0, 0, "filename/string with selection specification ");
int CHANGEMULTI = cdoOperatorAdd("changemulti", 0, 0, "filename/string with selection specification ");
operatorID = cdoOperatorID();
int operatorID = cdoOperatorID();
operatorInputArg(cdoOperatorEnter(operatorID));
......@@ -207,12 +200,12 @@ void *Selmulti(void *argument)
if (getNumberOfSelectionTuples()==0)
cdoAbort("Error! You must provide at lease ONE selection tuple!\nNotations: 'CHANGE, .. or (/;;|;;;)'\nCheck the file: %s",filenameOrString);
streamID1 = streamOpenRead(cdoStreamName(0));
int streamID1 = streamOpenRead(cdoStreamName(0));
vlistID1 = streamInqVlist(streamID1);
int vlistID1 = streamInqVlist(streamID1);
vlistClearFlag(vlistID1);
nvars = vlistNvars(vlistID1);
int nvars = vlistNvars(vlistID1);
if ( cdoDebugExt ) cdoPrint(" Total number of variables: %d", nvars);
......@@ -325,7 +318,7 @@ void *Selmulti(void *argument)
if ( cdoDebugExt ) cdoPrint(" Writing the selected fields ...");
vlistID2 = vlistCreate();
int vlistID2 = vlistCreate();
vlistCopyFlag(vlistID2, vlistID1);
nvars = vlistNvars(vlistID2);
......@@ -333,27 +326,27 @@ void *Selmulti(void *argument)
if ( vlistInqVarTsteptype(vlistID2, varID) != TSTEP_CONSTANT ) break;
if ( varID == nvars ) vlistDefNtsteps(vlistID2, 0);
taxisID1 = vlistInqTaxis(vlistID1);
taxisID2 = taxisDuplicate(taxisID1);
int taxisID1 = vlistInqTaxis(vlistID1);
int taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
nrecs = vlistNrecs(vlistID2);
int nrecs = vlistNrecs(vlistID2);
streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
streamDefVlist(streamID2, vlistID2);
gridsize = vlistGridsizeMax(vlistID1);
int gridsize = vlistGridsizeMax(vlistID1);
if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
array = (double *) malloc(gridsize*sizeof(double));
double *array = (double *) malloc(gridsize*sizeof(double));
tsID = 0;
int tsID = 0;
while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
{
taxisCopyTimestep(taxisID2, taxisID1);
streamDefTimestep(streamID2, tsID);
for ( recID = 0; recID < nrecs; recID++ )
for ( int recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
missval = vlistInqVarMissval(vlistID1, varID);
......@@ -375,7 +368,7 @@ void *Selmulti(void *argument)
selcode = checkListContainsInt(code, tuplerec->codeLST, tuplerec->ncodes);
selltype = checkListContainsInt(ltype, tuplerec->levelTypeLST, tuplerec->nlevelTypes);
sellevel = checkListContainsInt((int)level, tuplerec->levelLST, tuplerec->nlevels);
lcopy = TRUE;
lcopy = true;
if ( selcode && selltype && sellevel )
{
if (operatorID == CHANGEMULTI)
......@@ -399,7 +392,7 @@ void *Selmulti(void *argument)
{
scale = tuplerec->scale;
offset = tuplerec->offset;
lcopy = FALSE;
lcopy = false;
}
break; // get out of this for loop
}
......@@ -469,8 +462,9 @@ void *Selmulti(void *argument)
cdoFinish();
cdoDebugExt =0;
return (0);
cdoDebugExt = 0;
return 0;
}
......@@ -496,7 +490,7 @@ TUPLEREC *TUPLERECNew()
tpl->changedLevelType = -1;
tpl->changedLevel = -1;
return (tpl);
return tpl;
}
void push_backSelTuple(TUPLEREC *tp)
......@@ -569,7 +563,7 @@ char *removeSpaces(char *pline)
{
if (pline==NULL) return NULL;
while ( isspace((int) *pline) ) pline++;
return (pline);
return pline;
}
......@@ -580,7 +574,7 @@ char *skipSeparator(char *pline)
while ( isspace((int) *pline) ) pline++;
if ( *pline == '=' || *pline == ':' || *pline == '/' || *pline == ',' ) pline++;
while ( isspace((int) *pline) ) pline++;
return (pline);
return pline;
}
......@@ -607,7 +601,7 @@ char *goToNextSeparator(char *pline)
if ( cdoDebugExt>=100 ) cdoPrint("goToNextSeparator(): pline= ('%s') ", pline);
//while ( isspace((int) *pline) ) pline++;
pline = removeSpaces(pline);
return (pline);
return pline;
}
......
......@@ -844,7 +844,7 @@ static modules_t Modules[] =
{ Maggraph, MaggraphHelp, MaggraphOperators, 1, CDI_REAL, -1, 1 },
// HIRLAM_EXTENSIONS
{ Samplegrid, SamplegridHelp, SamplegridOperators, 1, CDI_REAL, 1, 1 },
{ Selmulti, NULL, SelmultiOperators, 1, CDI_REAL, 1, 1 },
{ Selmulti, SelmultiHelp, SelmultiOperators, 1, CDI_REAL, 1, 1 },
{ WindTrans, WindTransHelp, WindTransOperators, 1, CDI_REAL, 1, 1 },
};
......
......@@ -513,6 +513,56 @@ static const char *SelectHelp[] = {
NULL
};
static const char *SelmultiHelp[] = {
"NAME",
" selmulti, delmulti, changemulti - Select multiple fields via GRIB1 parameters",
"",
"SYNOPSIS",
" <operator>,selection-specification infile outfile",
"",
"DESCRIPTION",
" This module selects multiple fields from infile and writes them to outfile.",
" selection-specification is a filename or in-place string with the selection specification.",
" Each selection-specification has the following compact notation format: ",
" ",
" <type>(parameters; leveltype(s); levels)",
" ",
" type " " sel for select or del for delete (optional)",
" parameters" " GRIB1 parameter code number",
" leveltype " " GRIB1 level type",
" levels " " value of each level",
" ",
" Examples:",
" ",
" (1; 103; 0) ",
" (33,34; 105; 10) ",
" (11,17; 105; 2) ",
" (71,73,74,75,61,62,65,117,67,122,121,11,131,66,84,111,112; 105; 0) ",
" ",
" The following descriptive notation can also be used for selection specification from a file:",
" ",
" SELECT/DELETE, PARAMETER=parameters, LEVTYPE=leveltye(s), LEVEL=levels",
" ",
" Examples:",
" ",
" SELECT, PARAMETER=1, LEVTYPE=103, LEVEL=0 ",
" SELECT, PARAMETER=33/34, LEVTYPE=105, LEVEL=10 ",
" SELECT, PARAMETER=11/17, LEVTYPE=105, LEVEL=2 ",
" SELECT, PARAMETER=71/73/74/75/61/62/65/117/67/122, LEVTYPE=105, LEVEL=0 ",
" DELETE, PARAMETER=128, LEVTYPE=109, LEVEL=* ",
" ",
" The following will convert Pressure from Pa into hPa; Temp from Kelvin to Celsius: ",
" SELECT, PARAMETER=1, LEVTYPE= 103, LEVEL=0, SCALE=0.01 ",
" SELECT, PARAMETER=11, LEVTYPE=105, LEVEL=2, OFFSET=273.15 ",
" If SCALE and/or OFFSET are defined, then the data values are scaled as SCALE*(VALUE-OFFSET).",
"",
"OPERATORS",
" selmulti Select multiple fields",
" delmulti Delete multiple fields",
" changemulti Change identication of multiple fields",
NULL
};
static const char *SelvarHelp[] = {
"NAME",
" selparam, delparam, selcode, delcode, selname, delname, selstdname, sellevel, ",
......
Markdown is supported
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