Wind.c 11.9 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
/*
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.

5
  Copyright (C) 2003-2010 Uwe Schulzweida, Uwe.Schulzweida@zmaw.de
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
9
10
11
12
13
14
15
16
17
  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.
*/

18
19
20
21
22
/*
   This module contains the following operators:

      Wind       uv2dv           U and V wind to divergence and vorticity
      Wind       dv2uv           Divergence and vorticity to U and V wind
23
24
      Wind       dv2ps           Divergence and vorticity to
                                 velocity potential and stream function
25
26
*/

Ralf Mueller's avatar
Ralf Mueller committed
27
#include <cdi.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
29
30
31
32
33
34
35
36
#include "cdo.h"
#include "cdo_int.h"
#include "pstream.h"
#include "specspace.h"
#include "list.h"


void *Wind(void *argument)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
37
  static const char *func = "Wind";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
38
  int UV2DV, UV2DVL, DV2UV, DV2UVL, DV2PS;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
40
41
42
  int operatorID;
  int streamID1, streamID2;
  int nrecs, nvars;
  int tsID, recID, varID, levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
43
  int nlev = 0, gridsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
44
45
46
47
48
49
50
51
  int index, ngrids;
  int vlistID1, vlistID2;
  int gridIDsp = -1, gridIDgp = -1;
  int gridID1 = -1, gridID2 = -1;
  int gridID;
  int nmiss;
  int lcopy = FALSE;
  int taxisID1, taxisID2;
52
  int nlon, nlat, ntr = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
53
54
55
  int code;
  int varID1 = -1, varID2 = -1;
  int offset;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
  SPTRANS *sptrans = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
58
  DVTRANS *dvtrans = NULL;
  char varname[128];
59
  double *array1 = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
60
  double *ivar1 = NULL, *ivar2 = NULL, *ovar1 = NULL, *ovar2 = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
62
63

  cdoInitialize(argument);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
65
66
67
68
  UV2DV  = cdoOperatorAdd("uv2dv",  0, 0, NULL);
  UV2DVL = cdoOperatorAdd("uv2dvl", 0, 0, NULL);
  DV2UV  = cdoOperatorAdd("dv2uv",  0, 0, NULL);
  DV2UVL = cdoOperatorAdd("dv2uvl", 0, 0, NULL);
  DV2PS  = cdoOperatorAdd("dv2ps",  0, 0, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

  operatorID = cdoOperatorID();

  if ( UNCHANGED_RECORD ) lcopy = TRUE;

  streamID1 = streamOpenRead(cdoStreamName(0));
  if ( streamID1 < 0 ) cdiError(streamID1, "Open failed on %s", cdoStreamName(0));

  vlistID1 = streamInqVlist(streamID1);
  vlistID2 = vlistDuplicate(vlistID1);

  taxisID1 = vlistInqTaxis(vlistID1);
  taxisID2 = taxisDuplicate(taxisID1);
  vlistDefTaxis(vlistID2, taxisID2);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
85
86
87
  /* find variables */
  nvars = vlistNvars(vlistID2);
  for ( varID = 0; varID < nvars; varID++ )
    {
Uwe Schulzweida's avatar
update    
Uwe Schulzweida committed
88
      if ( operatorID == UV2DV || operatorID == UV2DVL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
89
90
	{
	  /* search for u and v wind */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
91
92
93
94
95
96
97
98
99
100
101
102
	  code = vlistInqVarCode(vlistID1, varID);
	  if ( code <= 0 )
	    {
	      vlistInqVarName(vlistID1, varID, varname);
	      strtolower(varname);

	      if      ( strcmp(varname, "u") == 0 ) code = 131;
	      else if ( strcmp(varname, "v") == 0 ) code = 132;
	    }

	  if      ( code == 131 ) varID1 = varID;
	  else if ( code == 132 ) varID2 = varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
	}
Uwe Schulzweida's avatar
update    
Uwe Schulzweida committed
104
      else if ( operatorID == DV2UV || operatorID == DV2UVL || operatorID == DV2PS )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	{
	  /* search for divergence and vorticity */
	  code = vlistInqVarCode(vlistID1, varID);
	  if ( code <= 0 )
	    {
	      vlistInqVarName(vlistID1, varID, varname);
	      strtolower(varname);

	      if      ( strcmp(varname, "sd")  == 0 ) code = 155;
	      else if ( strcmp(varname, "svo") == 0 ) code = 138;
	    }

	  if      ( code == 155 ) varID1 = varID;
	  else if ( code == 138 ) varID2 = varID;
	}
120
121
      else
	cdoAbort("unexpected operatorID %d", operatorID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
122
123
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
124
  ngrids = vlistNgrids(vlistID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
125

Uwe Schulzweida's avatar
Uwe Schulzweida committed
126
127
128
129
130
131
132
133
134
135
  /* find first spectral grid */
  for ( index = 0; index < ngrids; index++ )
    {
      gridID = vlistGrid(vlistID1, index);
      if ( gridInqType(gridID) == GRID_SPECTRAL )
	{
	  gridIDsp = gridID;
	  break;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
136

Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
138
139
140
141
142
143
144
145
146
  /* find first gaussian grid */
  for ( index = 0; index < ngrids; index++ )
    {
      gridID = vlistGrid(vlistID1, index);
      if ( gridInqType(gridID) == GRID_GAUSSIAN )
	{
	  gridIDgp = gridID;
	  break;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
147

Uwe Schulzweida's avatar
Uwe Schulzweida committed
148
  /* define output grid */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149
  if ( operatorID == UV2DV || operatorID == UV2DVL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
150
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
151
152
      if ( varID1 == -1 ) cdoWarning("U-wind not found!");
      if ( varID2 == -1 ) cdoWarning("V-wind not found!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
153

Uwe Schulzweida's avatar
Uwe Schulzweida committed
154
      if ( varID1 != -1 && varID2 != -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
156
	  gridID1 = vlistInqVarGrid(vlistID1, varID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
157

Uwe Schulzweida's avatar
Uwe Schulzweida committed
158
159
	  if ( gridInqType(gridID1) != GRID_GAUSSIAN )
	    cdoAbort("U-wind is not on gaussian grid!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160

Uwe Schulzweida's avatar
Uwe Schulzweida committed
161
162
163
164
	  if ( gridID1 != vlistInqVarGrid(vlistID1, varID2) )
	    cdoAbort("U and V wind must have the same grid represention!");

	  if ( gridID1 != -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
165
	    {
Uwe Schulzweida's avatar
update    
Uwe Schulzweida committed
166
	      if ( operatorID == UV2DV )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
167
168
169
		ntr = nlat2ntr(gridInqYsize(gridID1));
	      else
		ntr = nlat2ntr_linear(gridInqYsize(gridID1));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
171
172
173
174
175

	      if ( gridIDsp != -1 )
		if ( ntr != gridInqTrunc(gridIDsp) ) gridIDsp = -1;

	      if ( gridIDsp == -1 )
		{
176
		  gridIDsp = gridCreate(GRID_SPECTRAL, (ntr+1)*(ntr+2));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
177
		  gridDefTrunc(gridIDsp, ntr);
178
		  gridDefComplexPacking(gridIDsp, 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
179
		}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180
181
	    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
182
183
	  if ( gridIDsp == -1 && gridInqType(vlistGrid(vlistID1, 0)) == GRID_GAUSSIAN_REDUCED )
	    cdoAbort("Gaussian reduced grid found. Use option -R to convert it to a regular grid!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184

Uwe Schulzweida's avatar
Uwe Schulzweida committed
185
	  if ( gridIDsp == -1 ) cdoAbort("No Gaussian grid data found!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
186

Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
	  gridID2 = gridIDsp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188

Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
190
191
192
	  vlistChangeVarGrid(vlistID2, varID1, gridID2);
	  vlistChangeVarGrid(vlistID2, varID2, gridID2);
	  vlistDefVarCode(vlistID2, varID1, 155);
	  vlistDefVarCode(vlistID2, varID2, 138);
193
194
195
196
197
198
	  vlistDefVarName(vlistID2, varID1, "sd");
	  vlistDefVarName(vlistID2, varID2, "svo");
	  vlistDefVarLongname(vlistID2, varID1, "divergence");
	  vlistDefVarLongname(vlistID2, varID2, "vorticity");
	  vlistDefVarUnits(vlistID2, varID1, "1/s");
	  vlistDefVarUnits(vlistID2, varID2, "1/s");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
199

Uwe Schulzweida's avatar
Uwe Schulzweida committed
200
201
202
203
204
205
	  nlon = gridInqXsize(gridID1);
	  nlat = gridInqYsize(gridID1);
	  ntr  = gridInqTrunc(gridID2);

	  sptrans = sptrans_new(nlon, nlat, ntr, 1);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
206
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
207
  else if ( operatorID == DV2UV || operatorID == DV2UVL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
    {   
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
210
      if ( varID1 == -1 ) cdoWarning("Divergence not found!");
      if ( varID2 == -1 ) cdoWarning("Vorticity not found!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
211

Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
213
214
      if ( varID1 != -1 && varID2 != -1 )
	{
	  gridID1 = vlistInqVarGrid(vlistID1, varID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215

Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
217
	  if ( gridInqType(gridID1) != GRID_SPECTRAL )
	    cdoAbort("Vorticity is not on spectral grid!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218

Uwe Schulzweida's avatar
Uwe Schulzweida committed
219
220
	  if ( gridID1 != vlistInqVarGrid(vlistID1, varID1) )
	    cdoAbort("Divergence and vorticity must have the same grid represention!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
221

Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
	  if ( gridIDgp != -1 )
	    {
Uwe Schulzweida's avatar
update    
Uwe Schulzweida committed
224
	      if ( operatorID == DV2UV )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
226
227
		ntr = nlat2ntr(gridInqYsize(gridIDgp));
	      else
		ntr = nlat2ntr_linear(gridInqYsize(gridIDgp));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
	      
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
230
	      if ( gridInqTrunc(gridIDsp) != ntr ) gridIDgp = -1;
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231

Uwe Schulzweida's avatar
Uwe Schulzweida committed
232
233
234
	  if ( gridIDgp == -1 )
	    {
	      char gridname[20];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
235

Uwe Schulzweida's avatar
update    
Uwe Schulzweida committed
236
237
238
239
	      if ( operatorID == DV2UV )
		sprintf(gridname, "t%dgrid", gridInqTrunc(gridIDsp));
	      else
		sprintf(gridname, "tl%dgrid", gridInqTrunc(gridIDsp));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
241
242
	  
	      gridIDgp = gridFromName(gridname);
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
243

Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
	  gridID2 = gridIDgp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245

Uwe Schulzweida's avatar
Uwe Schulzweida committed
246
247
248
249
	  vlistChangeVarGrid(vlistID2, varID1, gridID2);
	  vlistChangeVarGrid(vlistID2, varID2, gridID2);
	  vlistDefVarCode(vlistID2, varID1, 131);
	  vlistDefVarCode(vlistID2, varID2, 132);
250
251
252
253
254
255
	  vlistDefVarName(vlistID2, varID1, "u");
	  vlistDefVarName(vlistID2, varID2, "v");
	  vlistDefVarLongname(vlistID2, varID1, "u-velocity");
	  vlistDefVarLongname(vlistID2, varID2, "v-velocity");
	  vlistDefVarUnits(vlistID2, varID1, "m/s");
	  vlistDefVarUnits(vlistID2, varID2, "m/s");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256

Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
258
259
	  ntr  = gridInqTrunc(gridID1);
	  nlon = gridInqXsize(gridID2);
	  nlat = gridInqYsize(gridID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260
      
Uwe Schulzweida's avatar
Uwe Schulzweida committed
261
262
263
	  sptrans = sptrans_new(nlon, nlat, ntr, 0);
	  dvtrans = dvtrans_new(ntr);
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
    }
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
  else if ( operatorID == DV2PS )
    {   
      if ( varID1 == -1 ) cdoWarning("Divergence not found!");
      if ( varID2 == -1 ) cdoWarning("Vorticity not found!");

      if ( varID1 != -1 && varID2 != -1 )
	{
	  gridID1 = vlistInqVarGrid(vlistID1, varID2);

	  if ( gridInqType(gridID1) != GRID_SPECTRAL )
	    cdoAbort("Vorticity is not on spectral grid!");

	  if ( gridID1 != vlistInqVarGrid(vlistID1, varID1) )
	    cdoAbort("Divergence and vorticity must have the same grid represention!");

	  vlistDefVarCode(vlistID2, varID1, 149);
	  vlistDefVarCode(vlistID2, varID2, 148);
282
283
284
285
286
287
	  vlistDefVarName(vlistID2, varID1, "velopot");
	  vlistDefVarName(vlistID2, varID2, "stream");
	  vlistDefVarLongname(vlistID2, varID1, "velocity potential");
	  vlistDefVarLongname(vlistID2, varID2, "streamfunction");
	  vlistDefVarUnits(vlistID2, varID1, "m^2/s");
	  vlistDefVarUnits(vlistID2, varID2, "m^2/s");
288
289
290
291
292

	  ntr  = gridInqTrunc(gridID1);
	  gridID2 = gridID1;
	}
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
293
294
295
296
297
298
299
300
301

  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
  if ( streamID2 < 0 ) cdiError(streamID2, "Open failed on %s", cdoStreamName(1));

  streamDefVlist(streamID2, vlistID2);

  gridsize = vlistGridsizeMax(vlistID1);
  array1 = (double *) malloc(gridsize*sizeof(double));

Uwe Schulzweida's avatar
Uwe Schulzweida committed
302
303
304
  if ( varID1 != -1 && varID2 != -1 )
    {
      nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID1));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305

Uwe Schulzweida's avatar
Uwe Schulzweida committed
306
307
308
309
310
311
312
313
      gridsize = gridInqSize(gridID1);
      ivar1 = (double *) malloc(nlev*gridsize*sizeof(double));
      ivar2 = (double *) malloc(nlev*gridsize*sizeof(double));
  
      gridsize = gridInqSize(gridID2);
      ovar1 = (double *) malloc(nlev*gridsize*sizeof(double));
      ovar2 = (double *) malloc(nlev*gridsize*sizeof(double));
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314

Uwe Schulzweida's avatar
Uwe Schulzweida committed
315
316
317
318
319
320
321
322
323
324
325
  tsID = 0;
  while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
    {
      taxisCopyTimestep(taxisID2, taxisID1);

      streamDefTimestep(streamID2, tsID);
	       
      for ( recID = 0; recID < nrecs; recID++ )
	{
	  streamInqRecord(streamID1, &varID, &levelID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
326
	  if ( (varID1 != -1 && varID2 != -1) && (varID == varID1 || varID == varID2) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
327
328
329
330
	    {
	      streamReadRecord(streamID1, array1, &nmiss);
	      if ( nmiss ) cdoAbort("missing values unsupported for spectral data!");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
331
332
	      gridsize = gridInqSize(gridID1);
	      offset = gridsize*levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
333

Uwe Schulzweida's avatar
Uwe Schulzweida committed
334
335
336
337
	      if      ( varID == varID1 )
		memcpy(ivar1+offset, array1, gridsize*sizeof(double));
	      else if ( varID == varID2 )
	        memcpy(ivar2+offset, array1, gridsize*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
339
340
341
342
343
344
345
346
347
348
349
350
	    }   
	  else
	    {
	      streamDefRecord(streamID2, varID, levelID);
	      if ( lcopy )
		{
		  streamCopyRecord(streamID2, streamID1);
		}
	      else
		{
		  streamReadRecord(streamID1, array1, &nmiss);
		  streamWriteRecord(streamID2, array1, nmiss);
		}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351
352
353
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
354
      if ( varID1 != -1 && varID2 != -1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
	  if ( operatorID == UV2DV || operatorID == UV2DVL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
	    trans_uv2dv(sptrans, nlev, gridID1, ivar1, ivar2, gridID2, ovar1, ovar2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
	  else if ( operatorID == DV2UV || operatorID == DV2UVL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
359
	    trans_dv2uv(sptrans, dvtrans, nlev, gridID1, ivar1, ivar2, gridID2, ovar1, ovar2);
360
361
362
363
364
	  else if ( operatorID == DV2PS )
	    {
	      dv2ps(ivar1, ovar1, nlev, ntr);
	      dv2ps(ivar2, ovar2, nlev, ntr);
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365
366

	  gridsize = gridInqSize(gridID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
367
	  if ( operatorID == UV2DV || operatorID == UV2DVL || operatorID == DV2PS )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368
369
370
371
372
373
374
375
376
377
378
379
380
381
	    {
	      for ( levelID = 0; levelID < nlev; levelID++ )
		{
		  offset = gridsize*levelID;
		  streamDefRecord(streamID2, varID2, levelID);
		  streamWriteRecord(streamID2, ovar2+offset, 0);
		}
	      for ( levelID = 0; levelID < nlev; levelID++ )
		{
		  offset = gridsize*levelID;
		  streamDefRecord(streamID2, varID1, levelID);
		  streamWriteRecord(streamID2, ovar1+offset, 0);
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
382
	  else if ( operatorID == DV2UV || operatorID == DV2UVL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
383
384
385
386
387
388
389
390
391
392
393
394
395
396
	    {
	      for ( levelID = 0; levelID < nlev; levelID++ )
		{
		  offset = gridsize*levelID;
		  streamDefRecord(streamID2, varID1, levelID);
		  streamWriteRecord(streamID2, ovar1+offset, 0);
		}
	      for ( levelID = 0; levelID < nlev; levelID++ )
		{
		  offset = gridsize*levelID;
		  streamDefRecord(streamID2, varID2, levelID);
		  streamWriteRecord(streamID2, ovar2+offset, 0);
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398

Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
400
401
402
403
404
405
406
      tsID++;
    }

  streamClose(streamID2);
  streamClose(streamID1);

  if ( array1 ) free(array1);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
407
408
409
410
  if ( ivar1 ) free(ivar1);
  if ( ivar2 ) free(ivar2);
  if ( ovar1 ) free(ovar1);
  if ( ovar2 ) free(ovar2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
411
412

  sptrans_delete(sptrans);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
  if ( dvtrans ) dvtrans_delete(dvtrans);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
415
416
417
418

  cdoFinish();

  return (0);
}