Copy.cc 5.38 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.

Uwe Schulzweida's avatar
Uwe Schulzweida committed
5
  Copyright (C) 2003-2017 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.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
23
/*
   This module contains the following operators:

      Copy       copy            Copy datasets
*/

Ralf Mueller's avatar
Ralf Mueller committed
24
#include <cdi.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
25
26
#include "cdo.h"
#include "cdo_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
27
#include "par_io.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
29
30
#include "pstream.h"


31
32
33
34
35
36
37
38
#ifdef __cplusplus
extern "C" {
#endif
int streamGrbInqDataScanningMode(void);
#if defined (__cplusplus)
}
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
40
void *Copy(void *argument)
{
41
42
43
44
  bool lconstvars = true;
  int streamID2 = CDI_UNDEFID;
  int vlistID2 = CDI_UNDEFID;
  int taxisID2 = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
45
  int nrecs;
46
  int varID, levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
47
  int nmiss;
48
  int ntsteps, nvars;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
  double *array = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
  par_io_t parIO;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
51
52
53

  cdoInitialize(argument);

54
55
  bool lcopy = UNCHANGED_RECORD;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
  // clang-format off
57
58
59
                cdoOperatorAdd("copy",   0, 0, NULL);
  int SELALL  = cdoOperatorAdd("selall", 0, 0, NULL);
  int SZIP    = cdoOperatorAdd("szip",   0, 0, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
60
  // clang-format on
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61

62
63
64
65
66
67
68
69
#ifdef HIRLAM_EXTENSIONS
  // KEEP in mind the difference between copy and selall with respect to unpacking and repacking the GRIB information!
  // Especially when setting the DataScanningMode.
  printf("cdo copy/selall : UNCHANGED_RECORD=%d\n",UNCHANGED_RECORD);
  //if (cdiGribDataScanningMode != -1) lcopy = false;
  printf("cdo copy/selall : cdiGribDataScanningMode=%d; lcopy=%d\n", streamGrbInqDataScanningMode(), lcopy);
#endif //#ifdef HIRLAM_EXTENSIONS

70
  int operatorID = cdoOperatorID();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71

Uwe Schulzweida's avatar
Uwe Schulzweida committed
72
73
  if ( operatorID == SZIP )
    {
74
      cdoCompType  = CDI_COMPRESS_SZIP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
76
77
      cdoCompLevel = 0;
    }

78
79
  int streamCnt = cdoStreamCnt();
  int nfiles = streamCnt - 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80

81
82
  int tsID2 = 0;
  for ( int indf = 0; indf < nfiles; indf++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
83
    {
84
      if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf)->args);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85

86
      int streamID1 = pstreamOpenRead(cdoStreamName(indf));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
87

88
      int vlistID1 = pstreamInqVlist(streamID1);
89
      int taxisID1 = vlistInqTaxis(vlistID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
90
91
92

      if ( indf == 0 )
	{
93
	  streamID2 = pstreamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
95
96
97
98

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

99
	  ntsteps = vlistNtsteps(vlistID1);
100
101
102
	  nvars   = vlistNvars(vlistID1);

	  if ( ntsteps == 1 )
103
	    {
104
	      for ( varID = 0; varID < nvars; ++varID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
		if ( vlistInqVarTsteptype(vlistID1, varID) != TSTEP_CONSTANT ) break;
106
	      
107
108
109
110
111
	      if ( varID == nvars ) ntsteps = 0;
	    }

	  if ( ntsteps == 0 && nfiles > 1 )
	    {	      
112
              lconstvars = false;
113
	      for ( varID = 0; varID < nvars; ++varID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
		vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
115
116
	    }

117
	  pstreamDefVlist(streamID2, vlistID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
118

119
	  int gridsize = vlistGridsizeMax(vlistID1);
120
	  array = (double*) Malloc(gridsize*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
122
	  if ( cdoParIO )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
123
	      fprintf(stderr, "Parallel reading enabled!\n");
124
	      parIO.array = (double*) Malloc(gridsize*sizeof(double));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
125
126
	      parIO.array_size = gridsize;
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
127
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
128
129
      else
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130
	  vlistCompare(vlistID1, vlistID2, CMP_ALL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
131
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132

133
      int tsID1 = 0;
134
      while ( (nrecs = pstreamInqTimestep(streamID1, tsID1)) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
135
136
137
	{
	  taxisCopyTimestep(taxisID2, taxisID1);

138
	  pstreamDefTimestep(streamID2, tsID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
	       
140
	  for ( int recID = 0; recID < nrecs; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
141
	    { 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
	      if ( lcopy && (operatorID == SELALL || operatorID == SZIP) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
143
		{
144
		  pstreamInqRecord(streamID1, &varID, &levelID);
145

146
                  if ( lconstvars && tsID2 > 0 && tsID1 == 0 )
147
148
149
                    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
                      continue;
                  
150
151
		  pstreamDefRecord(streamID2,  varID,  levelID);
		  pstreamCopyRecord(streamID2, streamID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
152
153
154
		}
	      else
		{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
156
157
		  if ( cdoParIO )
		    {
		      parIO.recID = recID; parIO.nrecs = nrecs;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
158
		      /* fprintf(stderr, "in1 streamID %d varID %d levelID %d\n", streamID1, varID, levelID);*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
159
		      parReadRecord(streamID1, &varID, &levelID, array, &nmiss, &parIO);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
		      /* fprintf(stderr, "in2 streamID %d varID %d levelID %d\n", streamID1, varID, levelID);*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
161
162
163
		    }
		  else
		    {
164
		      pstreamInqRecord(streamID1, &varID, &levelID);
165

166
                      if ( lconstvars && tsID2 > 0 && tsID1 == 0 )
167
168
169
                        if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
                          continue;

170
		      pstreamReadRecord(streamID1, array, &nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
171
		    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
173
174
175
		  /*
		  if ( cdoParIO )
		    fprintf(stderr, "out1 %d %d %d\n", streamID2,  varID,  levelID);
		  */
176
177
		  pstreamDefRecord(streamID2,  varID,  levelID);
		  pstreamWriteRecord(streamID2, array, nmiss);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
179
180
181
		  /*
		  if ( cdoParIO )
		    fprintf(stderr, "out2 %d %d %d\n", streamID2,  varID,  levelID);
		  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
182
		}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183
	    }
184

Uwe Schulzweida's avatar
Uwe Schulzweida committed
185
186
187
	  tsID1++;
	  tsID2++;
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188

189
      pstreamClose(streamID1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
190
191
    }

192
  pstreamClose(streamID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
193

194
  if ( array ) Free(array);
195
  if ( vlistID2 != CDI_UNDEFID ) vlistDestroy(vlistID2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
196
197
198

  cdoFinish();

Uwe Schulzweida's avatar
Uwe Schulzweida committed
199
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
200
}