~ubuntu-branches/ubuntu/trusty/nco/trusty

« back to all changes in this revision

Viewing changes to src/nco/mpncpdq.c

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2014-03-26 16:54:51 UTC
  • mfrom: (5.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20140326165451-u9erq1ez71r248lt
Tags: 4.4.2-1
* New upstream release.
  (closes: #611673)
* Added missing watch flle.
* Policy bumped to 3.9.5.
* Added build-dep on autotools-dev and update/clean step in debian/rules.
  (closes: #727470)
* Changed Vcs-* url to canonicali ones.
* Debhelper level set to 9.
* Now nco.html is a single file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Header: /cvsroot/nco/nco/src/nco/mpncpdq.c,v 1.85 2012/01/01 20:51:53 zender Exp $ */
 
1
/* $Header: /cvsroot/nco/nco/src/nco/mpncpdq.c,v 1.114 2014/01/06 06:46:04 zender Exp $ */
2
2
 
3
3
/* mpncpdq -- netCDF pack, re-dimension, query */
4
4
 
5
5
/* Purpose: Pack, re-dimension, query single netCDF file and output to a single file */
6
6
 
7
 
/* Copyright (C) 1995--2012 Charlie Zender
 
7
/* Copyright (C) 1995--2014 Charlie Zender
8
8
   
9
9
   License: GNU General Public License (GPL) Version 3
10
10
   The full license text is at http://www.gnu.org/copyleft/gpl.html 
46
46
#include <math.h> /* sin cos cos sin 3.14159 */
47
47
#include <stdio.h> /* stderr, FILE, NULL, etc. */
48
48
#include <stdlib.h> /* atof, atoi, malloc, getopt */
49
 
#include <string.h> /* strcmp. . . */
 
49
#include <string.h> /* strcmp() */
50
50
#include <time.h> /* machine time */
51
 
#include <unistd.h> /* all sorts of POSIX stuff */
 
51
#include <unistd.h> /* POSIX stuff */
52
52
#ifndef HAVE_GETOPT_LONG
53
53
# include "nco_getopt.h"
54
54
#else /* HAVE_GETOPT_LONG */ 
80
80
  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
81
81
  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
82
82
  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
83
 
  nco_bool FILE_RETRIEVED_FROM_REMOTE_LOCATION;
 
83
  nco_bool FL_RTR_RMT_LCN;
84
84
  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
85
85
  nco_bool FORCE_APPEND=False; /* Option A */
86
86
  nco_bool FORCE_OVERWRITE=False; /* Option O */
87
87
  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
88
88
  nco_bool HISTORY_APPEND=True; /* Option h */
89
89
  nco_bool REDEFINED_RECORD_DIMENSION=False; /* [flg] Re-defined record dimension */
90
 
  nco_bool REMOVE_REMOTE_FILES_AFTER_PROCESSING=True; /* Option R */
 
90
  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
 
91
  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
 
92
  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
 
93
  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
91
94
  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
92
95
  
93
96
  char **dmn_rdr_lst_in=NULL_CEWI; /* Option a */
111
114
  char *rec_dmn_nm_in=NULL; /* [sng] Record dimension name, original */
112
115
  char *rec_dmn_nm_out=NULL; /* [sng] Record dimension name, re-ordered */
113
116
  char *rec_dmn_nm_out_crr=NULL; /* [sng] Name of record dimension, if any, required by re-order */
114
 
  char *sng_cnv_rcd=char_CEWI; /* [sng] strtol()/strtoul() return code */
 
117
  char *sng_cnv_rcd=NULL_CEWI; /* [sng] strtol()/strtoul() return code */
115
118
  
116
119
  char add_fst_sng[]="add_offset"; /* [sng] Unidata standard string for add offset */
117
120
  char scl_fct_sng[]="scale_factor"; /* [sng] Unidata standard string for scale factor */
118
121
  
119
 
  const char * const CVS_Id="$Id: mpncpdq.c,v 1.85 2012/01/01 20:51:53 zender Exp $"; 
120
 
  const char * const CVS_Revision="$Revision: 1.85 $";
121
 
  const char * const opt_sht_lst="346Aa:CcD:d:FhL:l:M:Oo:P:p:RrSt:v:Ux-:";
 
122
  const char * const CVS_Id="$Id: mpncpdq.c,v 1.114 2014/01/06 06:46:04 zender Exp $"; 
 
123
  const char * const CVS_Revision="$Revision: 1.114 $";
 
124
  const char * const opt_sht_lst="3467Aa:CcD:d:FhL:l:M:Oo:P:p:RrSt:v:Ux-:";
122
125
  
 
126
  cnk_dmn_sct **cnk_dmn=NULL_CEWI;
 
127
 
123
128
  dmn_sct **dim=NULL_CEWI;
124
129
  dmn_sct **dmn_out;
125
130
  dmn_sct **dmn_rdr=NULL; /* [sct] Dimension structures to be re-ordered */
140
145
  int cnk_map=nco_cnk_map_nil; /* [enm] Chunking map */
141
146
  int cnk_nbr=0; /* [nbr] Number of chunk sizes */
142
147
  int cnk_plc=nco_cnk_plc_nil; /* [enm] Chunking policy */
143
 
  int dfl_lvl=0; /* [enm] Deflate level */
 
148
  int dfl_lvl=NCO_DFL_LVL_UNDEFINED; /* [enm] Deflate level */
144
149
  int dmn_out_idx; /* [idx] Index over output dimension list */
145
150
  int dmn_out_idx_rec_in=NCO_REC_DMN_UNDEFINED; /* [idx] Record dimension index in output dimension list, original */
146
151
  int dmn_rdr_nbr=0; /* [nbr] Number of dimension to re-order */
155
160
  int idx_rdr=int_CEWI;
156
161
  int in_id;  
157
162
  int lmt_nbr=0; /* Option d. NB: lmt_nbr gets incremented */
 
163
  int md_open; /* [enm] Mode flag for nc_open() call */
158
164
  int nbr_dmn_fl;
159
165
  int nbr_dmn_out;
160
166
  int nbr_dmn_xtr;
161
167
  int nbr_var_fix; /* nbr_var_fix gets incremented */
162
168
  int nbr_var_fl;
163
169
  int nbr_var_prc; /* nbr_var_prc gets incremented */
164
 
  int nbr_xtr=0; /* nbr_xtr won't otherwise be set for -c with no -v */
 
170
  int xtr_nbr=0; /* xtr_nbr won't otherwise be set for -c with no -v */
165
171
  int nco_pck_map=nco_pck_map_flt_sht; /* [enm] Packing map */
166
172
  int nco_pck_plc=nco_pck_plc_nil; /* [enm] Packing policy */
167
173
  int opt;
172
178
  int thr_nbr=int_CEWI; /* [nbr] Thread number Option t */
173
179
  int var_lst_in_nbr=0;
174
180
  
175
 
  lmt_sct **lmt;
 
181
  lmt_sct **aux=NULL_CEWI; /* Auxiliary coordinate limits */
 
182
  lmt_sct **lmt=NULL_CEWI;
 
183
  lmt_all_sct **lmt_all_lst=NULL_CEWI; /* List of *lmt_all structures */
176
184
  
177
185
  nm_id_sct *dmn_lst;
178
186
  nm_id_sct *dmn_rdr_lst;
179
187
  nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */
180
188
  
 
189
  size_t bfr_sz_hnt=NC_SIZEHINT_DEFAULT; /* [B] Buffer size hint */
 
190
  size_t cnk_sz_byt=0UL; /* [B] Chunk size in bytes */
181
191
  size_t cnk_sz_scl=0UL; /* [nbr] Chunk size scalar */
 
192
  size_t hdr_pad=0UL; /* [B] Pad at end of header section */
182
193
  
183
194
  var_sct **var;
184
195
  var_sct **var_fix;
211
222
  static struct option opt_lng[]=
212
223
    { /* Structure ordered by short option key if possible */
213
224
      /* Long options with no argument, no short option counterpart */
 
225
      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
 
226
      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
 
227
      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
 
228
      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
 
229
      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
 
230
      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
 
231
      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
214
232
      {"version",no_argument,0,0},
215
233
      {"vrs",no_argument,0,0},
216
234
      /* Long options with argument, no short option counterpart */
217
 
      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
 
235
      {"bfr_sz_hnt",required_argument,0,0}, /* [B] Buffer size hint */
 
236
      {"buffer_size_hint",required_argument,0,0}, /* [B] Buffer size hint */
218
237
      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
219
238
      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
220
239
      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
 
240
      {"cnk_byt",required_argument,0,0}, /* [B] Chunk size in bytes */
 
241
      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
221
242
      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
222
243
      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
223
244
      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
224
245
      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
225
 
      {"file_format",required_argument,0,0},
 
246
      {"fl_fmt",required_argument,0,0},
 
247
      {"hdr_pad",required_argument,0,0},
 
248
      {"header_pad",required_argument,0,0},
226
249
      /* Long options with short counterparts */
227
250
      {"3",no_argument,0,'3'},
228
251
      {"4",no_argument,0,'4'},
229
252
      {"64bit",no_argument,0,'4'},
230
253
      {"netcdf4",no_argument,0,'4'},
 
254
      {"7",no_argument,0,'7'},
231
255
      {"append",no_argument,0,'A'},
232
256
      {"arrange",required_argument,0,'a'},
233
257
      {"permute",required_argument,0,'a'},
238
262
      {"coords",no_argument,0,'c'},
239
263
      {"crd",no_argument,0,'c'},
240
264
      {"debug",required_argument,0,'D'},
241
 
      {"dbg_lvl",required_argument,0,'D'},
 
265
      {"nco_dbg_lvl",required_argument,0,'D'},
242
266
      {"dimension",required_argument,0,'d'},
243
267
      {"dmn",required_argument,0,'d'},
244
268
      {"fortran",no_argument,0,'F'},
268
292
      {"unpack",no_argument,0,'U'},
269
293
      {"upk",no_argument,0,'U'},
270
294
      {"variable",required_argument,0,'v'},
 
295
      {"auxiliary",required_argument,0,'X'},
271
296
      {"exclude",no_argument,0,'x'},
272
297
      {"xcl",no_argument,0,'x'},
273
298
      {"help",no_argument,0,'?'},
 
299
      {"hlp",no_argument,0,'?'},
274
300
      {0,0,0,0}
275
301
    }; /* end opt_lng */
276
302
  int opt_idx=0; /* Index of current long option into opt_lng array */
285
311
  /* Start clock and save command line */ 
286
312
  cmd_ln=nco_cmd_ln_sng(argc,argv);
287
313
  
288
 
  /* Get program name and set program enum (e.g., prg=ncra) */
289
 
  prg_nm=prg_prs(argv[0],&prg);
 
314
  /* Get program name and set program enum (e.g., nco_prg_id=ncra) */
 
315
  nco_prg_nm=nco_prg_prs(argv[0],&nco_prg_id);
290
316
  
291
317
  /* Parse command line arguments */
292
318
  while(1){
298
324
    
299
325
    /* Process long options without short option counterparts */
300
326
    if(opt == 0){
 
327
      if(!strcmp(opt_crr,"bfr_sz_hnt") || !strcmp(opt_crr,"buffer_size_hint")){
 
328
        bfr_sz_hnt=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
 
329
        if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
 
330
      } /* endif cnk */
 
331
      if(!strcmp(opt_crr,"cnk_byt") || !strcmp(opt_crr,"chunk_byte")){
 
332
        cnk_sz_byt=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
 
333
        if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
 
334
      } /* endif cnk_byt */
301
335
      if(!strcmp(opt_crr,"cnk_dmn") || !strcmp(opt_crr,"chunk_dimension")){
302
336
        /* Copy limit argument for later processing */
303
337
        cnk_arg[cnk_nbr]=(char *)strdup(optarg);
320
354
      if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
321
355
      if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
322
356
      if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
 
357
      if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
 
358
        hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
 
359
        if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
 
360
      } /* endif "hdr_pad" */
 
361
      if(!strcmp(opt_crr,"ram_all") || !strcmp(opt_crr,"create_ram") || !strcmp(opt_crr,"diskless_all")) RAM_CREATE=True; /* [flg] Open (netCDF3) file(s) in RAM */
 
362
      if(!strcmp(opt_crr,"ram_all") || !strcmp(opt_crr,"open_ram") || !strcmp(opt_crr,"diskless_all")) RAM_OPEN=True; /* [flg] Create file in RAM */
323
363
      if(!strcmp(opt_crr,"vrs") || !strcmp(opt_crr,"version")){
324
364
        (void)nco_vrs_prn(CVS_Id,CVS_Revision);
325
365
        nco_exit(EXIT_SUCCESS);
326
366
      } /* endif "vrs" */
 
367
      if(!strcmp(opt_crr,"wrt_tmp_fl") || !strcmp(opt_crr,"write_tmp_fl")) WRT_TMP_FL=True;
 
368
      if(!strcmp(opt_crr,"no_tmp_fl")) WRT_TMP_FL=False;
327
369
    } /* opt != 0 */
328
370
    /* Process short options */
329
371
    switch(opt){
338
380
    case '6': /* Request netCDF3 64-bit offset output storage format */
339
381
      fl_out_fmt=NC_FORMAT_64BIT;
340
382
      break;
 
383
    case '7': /* Request netCDF4-classic output storage format */
 
384
      fl_out_fmt=NC_FORMAT_NETCDF4_CLASSIC;
 
385
      break;
341
386
    case 'A': /* Toggle FORCE_APPEND */
342
387
      FORCE_APPEND=!FORCE_APPEND;
343
388
      break;
352
397
      EXTRACT_ALL_COORDINATES=True;
353
398
      break;
354
399
    case 'D': /* Debugging level. Default is 0. */
355
 
      dbg_lvl=(unsigned short int)strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
 
400
      nco_dbg_lvl=(unsigned short int)strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
356
401
      if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
357
402
      break;
358
403
    case 'd': /* Copy limit argument for later processing */
389
434
      fl_pth=(char *)strdup(optarg);
390
435
      break;
391
436
    case 'R': /* Toggle removal of remotely-retrieved-files. Default is True. */
392
 
      REMOVE_REMOTE_FILES_AFTER_PROCESSING=!REMOVE_REMOTE_FILES_AFTER_PROCESSING;
 
437
      RM_RMT_FL_PST_PRC=!RM_RMT_FL_PST_PRC;
393
438
      break;
394
439
    case 'r': /* Print CVS program information and copyright notice */
395
440
      (void)nco_vrs_prn(CVS_Id,CVS_Revision);
400
445
      break;
401
446
#ifdef ENABLE_MPI
402
447
    case 'S': /* Suspend with signal handler to facilitate debugging */
403
 
      if(signal(SIGUSR1,nco_cnt_run) == SIG_ERR) (void)fprintf(fp_stdout,"%s: ERROR Could not install suspend handler.\n",prg_nm);
 
448
      if(signal(SIGUSR1,nco_cnt_run) == SIG_ERR) (void)fprintf(fp_stdout,"%s: ERROR Could not install suspend handler.\n",nco_prg_nm);
404
449
      while(!nco_spn_lck_brk) usleep(nco_spn_lck_us); /* Spinlock. fxm: should probably insert a sched_yield */
405
450
      break;
406
451
#endif /* !ENABLE_MPI */
414
459
    case 'v': /* Variables to extract/exclude */
415
460
      /* Replace commas with hashes when within braces (convert back later) */
416
461
      optarg_lcl=(char *)strdup(optarg);
417
 
      (void)nco_lst_comma2hash(optarg_lcl);
 
462
      (void)nco_rx_comma2hash(optarg_lcl);
418
463
      var_lst_in=nco_lst_prs_2D(optarg_lcl,",",&var_lst_in_nbr);
419
464
      optarg_lcl=(char *)nco_free(optarg_lcl);
420
 
      nbr_xtr=var_lst_in_nbr;
 
465
      xtr_nbr=var_lst_in_nbr;
 
466
      break;
 
467
    case 'X': /* Copy auxiliary coordinate argument for later processing */
 
468
      aux_arg[aux_nbr]=(char *)strdup(optarg);
 
469
      aux_nbr++;
 
470
      MSA_USR_RDR=True; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */      
421
471
      break;
422
472
    case 'x': /* Exclude rather than extract variables specified with -v */
423
473
      EXCLUDE_INPUT_LIST=True;
427
477
      nco_exit(EXIT_SUCCESS);
428
478
      break;
429
479
    case '-': /* Long options are not allowed */
430
 
      (void)fprintf(stderr,"%s: ERROR Long options are not available in this build. Use single letter options instead.\n",prg_nm_get());
 
480
      (void)fprintf(stderr,"%s: ERROR Long options are not available in this build. Use single letter options instead.\n",nco_prg_nm_get());
431
481
      nco_exit(EXIT_FAILURE);
432
482
      break;
433
483
    default: /* Print proper usage */
 
484
      (void)fprintf(stdout,"%s ERROR in command-line syntax/options. Please reformulate command accordingly.\n",nco_prg_nm_get());
434
485
      (void)nco_usg_prn();
435
486
      nco_exit(EXIT_FAILURE);
436
487
      break;
442
493
  fl_lst_in=nco_fl_lst_mk(argv,argc,optind,&fl_nbr,&fl_out,&FL_LST_IN_FROM_STDIN);
443
494
  
444
495
  /* Make uniform list of user-specified chunksizes */
445
 
  if(cnk_nbr > 0) cnk=nco_cnk_prs(cnk_nbr,cnk_arg);
 
496
  if(cnk_nbr > 0) cnk_dmn=nco_cnk_prs(cnk_nbr,cnk_arg);
446
497
  
447
498
  /* Make uniform list of user-specified dimension limits */
448
499
  lmt=nco_lmt_prs(lmt_nbr,lmt_arg);
454
505
  /* Parse filename */
455
506
  fl_in=nco_fl_nm_prs(fl_in,0,&fl_nbr,fl_lst_in,abb_arg_nbr,fl_lst_abb,fl_pth);
456
507
  /* Make sure file is on local system and is readable or die trying */
457
 
  fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FILE_RETRIEVED_FROM_REMOTE_LOCATION);
458
 
  /* Open file for reading */
459
 
  rcd=nco_open(fl_in,NC_NOWRITE,&in_id);
 
508
  fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FL_RTR_RMT_LCN);
 
509
  /* Open file using appropriate buffer size hints and verbosity */
 
510
  if(RAM_OPEN) md_open=NC_NOWRITE|NC_DISKLESS; else md_open=NC_NOWRITE;
 
511
  rcd+=nco_fl_open(fl_in,md_open,&bfr_sz_hnt,&in_id);
 
512
  
 
513
  /* Parse auxiliary coordinates */
 
514
  if(aux_nbr > 0){
 
515
     int aux_idx_nbr;
 
516
     aux=nco_aux_evl(in_id,aux_nbr,aux_arg,&aux_idx_nbr);
 
517
     if(aux_idx_nbr > 0){
 
518
        lmt=(lmt_sct **)nco_realloc(lmt,(lmt_nbr+aux_idx_nbr)*sizeof(lmt_sct *));
 
519
        int lmt_nbr_new=lmt_nbr+aux_idx_nbr;
 
520
        int aux_idx=0;
 
521
        for(int lmt_idx=lmt_nbr;lmt_idx<lmt_nbr_new;lmt_idx++) lmt[lmt_idx]=aux[aux_idx++];
 
522
        lmt_nbr=lmt_nbr_new;
 
523
     } /* endif aux */
 
524
  } /* endif aux_nbr */
460
525
  
461
526
  /* Get number of variables, dimensions, and record dimension ID of input file */
462
527
  (void)nco_inq(in_id,&nbr_dmn_fl,&nbr_var_fl,(int *)NULL,&rec_dmn_id_in);
463
528
  (void)nco_inq_format(in_id,&fl_in_fmt);
464
529
  
465
530
  /* Form initial extraction list which may include extended regular expressions */
466
 
  xtr_lst=nco_var_lst_mk(in_id,nbr_var_fl,var_lst_in,EXCLUDE_INPUT_LIST,EXTRACT_ALL_COORDINATES,&nbr_xtr);
 
531
  xtr_lst=nco_var_lst_mk(in_id,nbr_var_fl,var_lst_in,EXCLUDE_INPUT_LIST,EXTRACT_ALL_COORDINATES,&xtr_nbr);
467
532
  
468
533
  /* Change included variables to excluded variables */
469
 
  if(EXCLUDE_INPUT_LIST) xtr_lst=nco_var_lst_xcl(in_id,nbr_var_fl,xtr_lst,&nbr_xtr);
 
534
  if(EXCLUDE_INPUT_LIST) xtr_lst=nco_var_lst_xcl(in_id,nbr_var_fl,xtr_lst,&xtr_nbr);
470
535
  
471
536
  /* Is this a CCM/CCSM/CF-format history tape? */
472
537
  CNV_CCM_CCSM_CF=nco_cnv_ccm_ccsm_cf_inq(in_id);
473
538
  
474
539
  /* Add all coordinate variables to extraction list */
475
 
  if(EXTRACT_ALL_COORDINATES) xtr_lst=nco_var_lst_crd_add(in_id,nbr_dmn_fl,nbr_var_fl,xtr_lst,&nbr_xtr,CNV_CCM_CCSM_CF);
 
540
  if(EXTRACT_ALL_COORDINATES) xtr_lst=nco_var_lst_crd_add(in_id,nbr_dmn_fl,nbr_var_fl,xtr_lst,&xtr_nbr,CNV_CCM_CCSM_CF);
476
541
  
477
542
  /* Extract coordinates associated with extracted variables */
478
 
  if(EXTRACT_ASSOCIATED_COORDINATES) xtr_lst=nco_var_lst_crd_ass_add(in_id,xtr_lst,&nbr_xtr,CNV_CCM_CCSM_CF);
 
543
  if(EXTRACT_ASSOCIATED_COORDINATES) xtr_lst=nco_var_lst_crd_ass_add(in_id,xtr_lst,&xtr_nbr,CNV_CCM_CCSM_CF);
479
544
  
480
545
  /* Sort extraction list by variable ID for fastest I/O */
481
 
  if(nbr_xtr > 1) xtr_lst=nco_lst_srt_nm_id(xtr_lst,nbr_xtr,False);
 
546
  if(xtr_nbr > 1) xtr_lst=nco_lst_srt_nm_id(xtr_lst,xtr_nbr,False);
482
547
  
483
548
  /* Find coordinate/dimension values associated with user-specified limits
484
549
     NB: nco_lmt_evl() with same nc_id contains OpenMP critical region */
485
550
  for(idx=0;idx<lmt_nbr;idx++) (void)nco_lmt_evl(in_id,lmt[idx],0L,FORTRAN_IDX_CNV);
486
551
  
 
552
  /* Place all dimensions in lmt_all_lst */
 
553
  lmt_all_lst=(lmt_all_sct **)nco_malloc(nbr_dmn_fl*sizeof(lmt_all_sct *));
 
554
  /* Initialize lmt_all_sct's */ 
 
555
  (void)nco_msa_lmt_all_ntl(in_id,MSA_USR_RDR,lmt_all_lst,nbr_dmn_fl,lmt,lmt_nbr);
 
556
 
487
557
  /* Find dimensions associated with variables to be extracted */
488
 
  dmn_lst=nco_dmn_lst_ass_var(in_id,xtr_lst,nbr_xtr,&nbr_dmn_xtr);
 
558
  dmn_lst=nco_dmn_lst_ass_var(in_id,xtr_lst,xtr_nbr,&nbr_dmn_xtr);
489
559
  
490
560
  /* Fill-in dimension structure for all extracted dimensions */
491
561
  dim=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *));
493
563
  /* Dimension list no longer needed */
494
564
  dmn_lst=nco_nm_id_lst_free(dmn_lst,nbr_dmn_xtr);
495
565
  
496
 
  /* Merge hyperslab limit information into dimension structures */
497
 
  if(lmt_nbr > 0) (void)nco_dmn_lmt_mrg(dim,nbr_dmn_xtr,lmt,lmt_nbr);
498
 
  
499
566
  /* Duplicate input dimension structures for output dimension structures */
500
567
  nbr_dmn_out=nbr_dmn_xtr;
501
568
  dmn_out=(dmn_sct **)nco_malloc(nbr_dmn_out*sizeof(dmn_sct *));
504
571
    (void)nco_dmn_xrf(dim[idx],dmn_out[idx]);
505
572
  } /* end loop over idx */
506
573
  
 
574
  /* Merge hyperslab limit information into dimension structures */
 
575
  if(nbr_dmn_fl > 0) (void)nco_dmn_lmt_all_mrg(dmn_out,nbr_dmn_xtr,lmt_all_lst,nbr_dmn_fl); 
 
576
  
507
577
  /* No re-order dimensions specified implies packing request */
508
578
  if(dmn_rdr_nbr == 0){
509
579
    if(nco_pck_plc == nco_pck_plc_nil) nco_pck_plc=nco_pck_plc_get(nco_pck_plc_sng);
510
 
    if(dbg_lvl >= nco_dbg_scl) (void)fprintf(stderr,"%s: DEBUG Packing map is %s and packing policy is %s\n",prg_nm_get(),nco_pck_map_sng_get(nco_pck_map),nco_pck_plc_sng_get(nco_pck_plc));
 
580
    if(nco_dbg_lvl >= nco_dbg_scl) (void)fprintf(stderr,"%s: DEBUG Packing map is %s and packing policy is %s\n",nco_prg_nm_get(),nco_pck_map_sng_get(nco_pck_map),nco_pck_plc_sng_get(nco_pck_plc));
511
581
  } /* endif */
512
582
  
513
583
  /* From this point forward, assume ncpdq operator packs or re-orders, not both */
514
584
  if(dmn_rdr_nbr > 0 && nco_pck_plc != nco_pck_plc_nil){
515
 
    (void)fprintf(fp_stdout,"%s: ERROR %s does not support simultaneous dimension re-ordering  (-a switch) and packing (-P switch).\nHINT: Invoke %s twice, once to re-order (with -a), and once to pack (with -P).\n",prg_nm,prg_nm,prg_nm);
 
585
    (void)fprintf(fp_stdout,"%s: ERROR %s does not support simultaneous dimension re-ordering  (-a switch) and packing (-P switch).\nHINT: Invoke %s twice, once to re-order (with -a), and once to pack (with -P).\n",nco_prg_nm,nco_prg_nm,nco_prg_nm);
516
586
    nco_exit(EXIT_FAILURE);
517
587
  } /* end if */
518
588
  
544
614
      for(idx=0;idx<nbr_dmn_xtr;idx++){
545
615
        if(!strcmp(dmn_rdr_lst[idx_rdr].nm,dim[idx]->nm)) break;
546
616
      } /* end loop over idx_rdr */
547
 
      if(idx != nbr_dmn_xtr) dmn_rdr[dmn_rdr_nbr_utl++]=dim[idx]; else if(dbg_lvl >= nco_dbg_std) (void)fprintf(stderr,"%s: WARNING re-ordering dimension \"%s\" is not contained in any variable in extraction list\n",prg_nm,dmn_rdr_lst[idx_rdr].nm);
 
617
      if(idx != nbr_dmn_xtr) dmn_rdr[dmn_rdr_nbr_utl++]=dim[idx]; else if(nco_dbg_lvl >= nco_dbg_std) (void)fprintf(stderr,"%s: WARNING re-ordering dimension \"%s\" is not contained in any variable in extraction list\n",nco_prg_nm,dmn_rdr_lst[idx_rdr].nm);
548
618
    } /* end loop over idx_rdr */
549
619
    dmn_rdr_nbr=dmn_rdr_nbr_utl;
550
620
    /* Collapse extra dimension structure space to prevent accidentally using it */
557
627
      for(idx_rdr=0;idx_rdr<dmn_rdr_nbr;idx_rdr++){
558
628
        if(idx_rdr != idx){
559
629
          if(dmn_rdr[idx]->id == dmn_rdr[idx_rdr]->id){
560
 
            (void)fprintf(fp_stdout,"%s: ERROR %s specified more than once in reducing list\n",prg_nm,dmn_rdr[idx]->nm);
 
630
            (void)fprintf(fp_stdout,"%s: ERROR %s specified more than once in reducing list\n",nco_prg_nm,dmn_rdr[idx]->nm);
561
631
            nco_exit(EXIT_FAILURE);
562
632
          } /* end if */
563
633
        } /* end if */
565
635
    } /* end loop over idx */
566
636
    
567
637
    if(dmn_rdr_nbr > nbr_dmn_xtr){
568
 
      (void)fprintf(fp_stdout,"%s: ERROR More re-ordering dimensions than extracted dimensions\n",prg_nm);
 
638
      (void)fprintf(fp_stdout,"%s: ERROR More re-ordering dimensions than extracted dimensions\n",nco_prg_nm);
569
639
      nco_exit(EXIT_FAILURE);
570
640
    } /* end if */
571
641
    
575
645
  CNV_CCM_CCSM_CF=nco_cnv_ccm_ccsm_cf_inq(in_id);
576
646
  
577
647
  /* Fill-in variable structure list for all extracted variables */
578
 
  var=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *));
579
 
  var_out=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *));
580
 
  for(idx=0;idx<nbr_xtr;idx++){
 
648
  var=(var_sct **)nco_malloc(xtr_nbr*sizeof(var_sct *));
 
649
  var_out=(var_sct **)nco_malloc(xtr_nbr*sizeof(var_sct *));
 
650
  for(idx=0;idx<xtr_nbr;idx++){
581
651
    var[idx]=nco_var_fll(in_id,xtr_lst[idx].id,xtr_lst[idx].nm,dim,nbr_dmn_xtr);
582
652
    var_out[idx]=nco_var_dpl(var[idx]);
583
653
    (void)nco_xrf_var(var[idx],var_out[idx]);
584
654
    (void)nco_xrf_dmn(var_out[idx]);
585
655
  } /* end loop over idx */
586
656
  /* Extraction list no longer needed */
587
 
  xtr_lst=nco_nm_id_lst_free(xtr_lst,nbr_xtr);
 
657
  xtr_lst=nco_nm_id_lst_free(xtr_lst,xtr_nbr);
588
658
  
589
659
  /* Divide variable lists into lists of fixed variables and variables to be processed */
590
 
  (void)nco_var_lst_dvd(var,var_out,nbr_xtr,CNV_CCM_CCSM_CF,nco_pck_map,nco_pck_plc,dmn_rdr,dmn_rdr_nbr,&var_fix,&var_fix_out,&nbr_var_fix,&var_prc,&var_prc_out,&nbr_var_prc);
 
660
  (void)nco_var_lst_dvd(var,var_out,xtr_nbr,CNV_CCM_CCSM_CF,True,nco_pck_map,nco_pck_plc,dmn_rdr,dmn_rdr_nbr,&var_fix,&var_fix_out,&nbr_var_fix,&var_prc,&var_prc_out,&nbr_var_prc);
591
661
  
592
662
  /* We now have final list of variables to extract. Phew. */
593
 
  if(dbg_lvl >= nco_dbg_var){
594
 
    for(idx=0;idx<nbr_xtr;idx++) (void)fprintf(stderr,"var[%d]->nm = %s, ->id=[%d]\n",idx,var[idx]->nm,var[idx]->id);
 
663
  if(nco_dbg_lvl >= nco_dbg_var){
 
664
    for(idx=0;idx<xtr_nbr;idx++) (void)fprintf(stderr,"var[%d]->nm = %s, ->id=[%d]\n",idx,var[idx]->nm,var[idx]->id);
595
665
    for(idx=0;idx<nbr_var_fix;idx++) (void)fprintf(stderr,"var_fix[%d]->nm = %s, ->id=[%d]\n",idx,var_fix[idx]->nm,var_fix[idx]->id);
596
666
    for(idx=0;idx<nbr_var_prc;idx++) (void)fprintf(stderr,"var_prc[%d]->nm = %s, ->id=[%d]\n",idx,var_prc[idx]->nm,var_prc[idx]->id);
597
667
  } /* end if */
606
676
    (void)nco_fl_fmt_vet(fl_out_fmt,cnk_nbr,dfl_lvl);
607
677
    
608
678
    /* Open output file */
609
 
    fl_out_tmp=nco_fl_out_open(fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&out_id);
610
 
    if(dbg_lvl >= nco_dbg_sbr) (void)fprintf(stderr,"Input, output file IDs = %d, %d\n",in_id,out_id);
 
679
    fl_out_tmp=nco_fl_out_open(fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&bfr_sz_hnt,RAM_CREATE,RAM_OPEN,WRT_TMP_FL,&out_id);
 
680
    if(nco_dbg_lvl >= nco_dbg_sbr) (void)fprintf(stderr,"Input, output file IDs = %d, %d\n",in_id,out_id);
611
681
    
612
682
    /* Copy global attributes */
613
683
    (void)nco_att_cpy(in_id,out_id,NC_GLOBAL,NC_GLOBAL,(nco_bool)True);
655
725
          /* ...and current output record dimension already differs from input record dimension... */
656
726
          if(REDEFINED_RECORD_DIMENSION){
657
727
            /* ...then requested re-order requires multiple record dimensions... */
658
 
            if(dbg_lvl >= nco_dbg_std) (void)fprintf(fp_stdout,"%s: WARNING Re-order requests multiple record dimensions\n. Only first request will be honored (netCDF allows only one record dimension). Record dimensions involved [original,first change request (honored),latest change request (made by variable %s)]=[%s,%s,%s]\n",prg_nm,var_prc[idx]->nm,rec_dmn_nm_in,rec_dmn_nm_out,rec_dmn_nm_out_crr);
 
728
            if(nco_dbg_lvl >= nco_dbg_std) (void)fprintf(fp_stdout,"%s: WARNING Re-order requests multiple record dimensions\n. Only first request will be honored (netCDF allows only one record dimension). Record dimensions involved [original,first change request (honored),latest change request (made by variable %s)]=[%s,%s,%s]\n",nco_prg_nm,var_prc[idx]->nm,rec_dmn_nm_in,rec_dmn_nm_out,rec_dmn_nm_out_crr);
659
729
            break;
660
730
          }else{ /* !REDEFINED_RECORD_DIMENSION */
661
731
            /* ...otherwise, update output record dimension name... */
676
746
     Hence making following logic prettier or funcionalizing is not high priority.
677
747
     Logic may need to be simplified/re-written once netCDF4 is released. */
678
748
  if(REDEFINED_RECORD_DIMENSION){
679
 
    if(dbg_lvl >= nco_dbg_std) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change record dimension from %s to %s. netCDF allows only one record dimension. Hence %s will make %s record (least rapidly varying) dimension in all variables that contain it.\n",prg_nm,rec_dmn_nm_in,rec_dmn_nm_out,prg_nm,rec_dmn_nm_out);
 
749
    if(nco_dbg_lvl >= nco_dbg_std) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change record dimension from %s to %s. netCDF allows only one record dimension. Hence %s will make %s record (least rapidly varying) dimension in all variables that contain it.\n",nco_prg_nm,rec_dmn_nm_in,rec_dmn_nm_out,nco_prg_nm,rec_dmn_nm_out);
680
750
    /* Changing record dimension may invalidate is_rec_var flag
681
751
       Updating is_rec_var flag to correct value, even if value is ignored,
682
752
       helps keep user appraised of unexpected dimension re-orders.
694
764
      /* ...Will variable be record variable in output file?... */
695
765
      if(dmn_out_idx == var_fix[idx]->nbr_dim){
696
766
        /* ...No. Variable will be non-record---does this change its status?... */
697
 
        if(dbg_lvl >= nco_dbg_var) if(var_fix[idx]->is_rec_var == True) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from record to non-record variable\n",prg_nm,var_fix[idx]->nm);
 
767
        if(nco_dbg_lvl >= nco_dbg_var) if(var_fix[idx]->is_rec_var == True) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from record to non-record variable\n",nco_prg_nm,var_fix[idx]->nm);
698
768
        /* Assign record flag dictated by re-order */
699
769
        var_fix[idx]->is_rec_var=False; 
700
770
      }else{ /* ...otherwise variable will be record variable... */
701
771
        /* ...Yes. Variable will be record... */
702
772
        /* ...Will becoming record variable change its status?... */
703
773
        if(var_fix[idx]->is_rec_var == False){
704
 
          if(dbg_lvl >= nco_dbg_var) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from non-record to record variable\n",prg_nm,var_fix[idx]->nm);
 
774
          if(nco_dbg_lvl >= nco_dbg_var) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from non-record to record variable\n",nco_prg_nm,var_fix[idx]->nm);
705
775
          /* Change record flag to status dictated by re-order */
706
776
          var_fix[idx]->is_rec_var=True;
707
777
        } /* endif status changing from non-record to record */
716
786
      /* ...Will variable be record variable in output file?... */
717
787
      if(dmn_out_idx == var_prc_out[idx]->nbr_dim){
718
788
        /* ...No. Variable will be non-record---does this change its status?... */
719
 
        if(dbg_lvl >= nco_dbg_var) if(var_prc_out[idx]->is_rec_var == True) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from record to non-record variable\n",prg_nm,var_prc_out[idx]->nm);
 
789
        if(nco_dbg_lvl >= nco_dbg_var) if(var_prc_out[idx]->is_rec_var == True) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from record to non-record variable\n",nco_prg_nm,var_prc_out[idx]->nm);
720
790
        /* Assign record flag dictated by re-order */
721
791
        var_prc_out[idx]->is_rec_var=False; 
722
792
      }else{ /* ...otherwise variable will be record variable... */
726
796
          int dmn_dpl_idx;
727
797
          for(dmn_dpl_idx=1;dmn_dpl_idx<var_prc_out[idx]->nbr_dim;dmn_dpl_idx++){ /* NB: loop starts from 1 */
728
798
            if(var_prc_out[idx]->dmn_id[0] == var_prc_out[idx]->dmn_id[dmn_dpl_idx]){
729
 
              (void)fprintf(stdout,"%s: ERROR Requested re-order turns duplicate non-record dimension %s in variable %s into output record dimension. netCDF does not support duplicate record dimensions in a single variable.\n%s: HINT: Exclude variable %s from extraction list with \"-x -v %s\".\n",prg_nm_get(),rec_dmn_nm_out,var_prc_out[idx]->nm,prg_nm_get(),var_prc_out[idx]->nm,var_prc_out[idx]->nm);
 
799
              (void)fprintf(stdout,"%s: ERROR Requested re-order turns duplicate non-record dimension %s in variable %s into output record dimension. netCDF does not support duplicate record dimensions in a single variable.\n%s: HINT: Exclude variable %s from extraction list with \"-x -v %s\".\n",nco_prg_nm_get(),rec_dmn_nm_out,var_prc_out[idx]->nm,nco_prg_nm_get(),var_prc_out[idx]->nm,var_prc_out[idx]->nm);
730
800
              nco_exit(EXIT_FAILURE);
731
801
            } /* endif err */
732
802
          } /* end loop over dmn_out */
733
803
        } /* endif has_dpl_dmn */
734
804
        /* ...Will becoming record variable change its status?... */
735
805
        if(var_prc_out[idx]->is_rec_var == False){
736
 
          if(dbg_lvl >= nco_dbg_var) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from non-record to record variable\n",prg_nm,var_prc_out[idx]->nm);
 
806
          if(nco_dbg_lvl >= nco_dbg_var) (void)fprintf(fp_stdout,"%s: INFO Requested re-order will change variable %s from non-record to record variable\n",nco_prg_nm,var_prc_out[idx]->nm);
737
807
          /* Change record flag to status dictated by re-order */
738
808
          var_prc_out[idx]->is_rec_var=True;
739
809
          /* ...Swap dimension information for multi-dimensional variables... */
807
877
  if(prc_rnk == rnk_mgr){ /* MPI manager code */
808
878
#endif /* !ENABLE_MPI */
809
879
    /* Define variables in output file, copy their attributes */
810
 
    (void)nco_var_dfn(in_id,fl_out,out_id,var_out,nbr_xtr,(dmn_sct **)NULL,(int)0,nco_pck_map,nco_pck_plc,dfl_lvl);
 
880
    (void)nco_var_dfn(in_id,fl_out,out_id,var_out,xtr_nbr,(dmn_sct **)NULL,(int)0,nco_pck_map,nco_pck_plc,dfl_lvl);
811
881
    
812
882
    /* Set chunksize parameters */
813
 
    if(fl_out_fmt == NC_FORMAT_NETCDF4 || fl_out_fmt == NC_FORMAT_NETCDF4_CLASSIC) (void)nco_cnk_sz_set(out_id,lmt_all_lst,nbr_dmn_fl,&cnk_map,&cnk_plc,cnk_sz_scl,cnk,cnk_nbr);
 
883
    if(fl_out_fmt == NC_FORMAT_NETCDF4 || fl_out_fmt == NC_FORMAT_NETCDF4_CLASSIC) (void)nco_cnk_sz_set(out_id,lmt_all_lst,nbr_dmn_fl,&cnk_map,&cnk_plc,cnk_sz_scl,cnk_dmn,cnk_nbr);
814
884
    
815
885
    /* Turn off default filling behavior to enhance efficiency */
816
886
    nco_set_fill(out_id,NC_NOFILL,&fll_md_old);
817
887
    
818
888
    /* Take output file out of define mode */
819
 
    (void)nco_enddef(out_id);
 
889
    if(hdr_pad == 0UL){
 
890
      (void)nco_enddef(out_id);
 
891
    }else{
 
892
      (void)nco__enddef(out_id,hdr_pad);
 
893
      if(nco_dbg_lvl >= nco_dbg_scl) (void)fprintf(stderr,"%s: INFO Padding header with %lu extra bytes\n",nco_prg_nm_get(),(unsigned long)hdr_pad);
 
894
    } /* hdr_pad */
820
895
#ifdef ENABLE_MPI
821
896
  } /* prc_rnk != rnk_mgr */
822
897
  
828
903
  
829
904
#endif /* !ENABLE_MPI */
830
905
  
831
 
  /* Assign zero-start and unity-stride vectors to output variables */
832
 
  (void)nco_var_srd_srt_set(var_out,nbr_xtr);
 
906
  /* Assign zero to start and unity to stride vectors in output variables */
 
907
  (void)nco_var_srd_srt_set(var_out,xtr_nbr);
833
908
  
834
909
#ifdef ENABLE_MPI
835
910
  if(prc_rnk == rnk_mgr){ /* MPI manager code */
836
911
    TKN_WRT_FREE=False;
837
912
#endif /* !ENABLE_MPI */
838
913
    /* Copy variable data for non-processed variables */
839
 
    (void)nco_var_val_cpy(in_id,out_id,var_fix,nbr_var_fix);
 
914
    (void)nco_msa_var_val_cpy(in_id,out_id,var_fix,nbr_var_fix,lmt_all_lst,nbr_dmn_fl);
840
915
#ifdef ENABLE_MPI
841
916
    /* Close output file so workers can open it */
842
917
    nco_close(out_id);
851
926
  for(fl_idx=0;fl_idx<fl_nbr;fl_idx++){
852
927
    /* Parse filename */
853
928
    if(fl_idx != 0) fl_in=nco_fl_nm_prs(fl_in,fl_idx,&fl_nbr,fl_lst_in,abb_arg_nbr,fl_lst_abb,fl_pth);
854
 
    if(dbg_lvl >= nco_dbg_fl) (void)fprintf(stderr,"\nInput file %d is %s; ",fl_idx,fl_in);
 
929
    if(nco_dbg_lvl >= nco_dbg_fl) (void)fprintf(stderr,"\nInput file %d is %s; ",fl_idx,fl_in);
855
930
    /* Make sure file is on local system and is readable or die trying */
856
 
    if(fl_idx != 0) fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FILE_RETRIEVED_FROM_REMOTE_LOCATION);
857
 
    if(dbg_lvl >= nco_dbg_fl) (void)fprintf(stderr,"local file %s:\n",fl_in);
 
931
    if(fl_idx != 0) fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FL_RTR_RMT_LCN);
 
932
    if(nco_dbg_lvl >= nco_dbg_fl) (void)fprintf(stderr,"local file %s:\n",fl_in);
858
933
    
859
934
    /* Open file once per thread to improve caching */
860
 
    for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd=nco_open(fl_in,NC_NOWRITE,in_id_arr+thr_idx);
 
935
    for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd+=nco_fl_open(fl_in,md_open,&bfr_sz_hnt,in_id_arr+thr_idx);
861
936
    
862
937
#ifdef ENABLE_MPI
863
938
    if(prc_rnk == rnk_mgr){ /* MPI manager code */
926
1001
#endif /* !0 */
927
1002
#else /* !ENABLE_MPI */
928
1003
#ifdef _OPENMP
929
 
#pragma omp parallel for default(none) private(idx,in_id) shared(aed_lst_add_fst,aed_lst_scl_fct,dbg_lvl,dmn_idx_out_in,dmn_rdr_nbr,dmn_rvr_in,in_id_arr,nbr_var_prc,nco_pck_map,nco_pck_plc,out_id,prg_nm,rcd,var_prc,var_prc_out)
 
1004
#pragma omp parallel for default(none) private(idx,in_id) shared(aed_lst_add_fst,aed_lst_scl_fct,nco_dbg_lvl,dmn_idx_out_in,dmn_rdr_nbr,dmn_rvr_in,in_id_arr,nbr_var_prc,nco_pck_map,nco_pck_plc,out_id,nco_prg_nm,rcd,var_prc,var_prc_out)
930
1005
#endif /* !_OPENMP */
931
1006
        /* UP and SMP codes main loop over variables */
932
1007
        for(idx=0;idx<nbr_var_prc;idx++){ /* Process all variables in current file */
934
1009
          in_id=in_id_arr[omp_get_thread_num()];
935
1010
          /* fxm TODO nco638 temporary fix? */
936
1011
          var_prc[idx]->nc_id=in_id; 
937
 
          if(dbg_lvl >= nco_dbg_var) rcd+=nco_var_prc_crr_prn(idx,var_prc[idx]->nm);
938
 
          if(dbg_lvl >= nco_dbg_var) (void)fflush(fp_stderr);
 
1012
          if(nco_dbg_lvl >= nco_dbg_var) rcd+=nco_var_prc_crr_prn(idx,var_prc[idx]->nm);
 
1013
          if(nco_dbg_lvl >= nco_dbg_var) (void)fflush(fp_stderr);
939
1014
          
940
1015
          /* Retrieve variable from disk into memory */
941
1016
          /* NB: nco_var_get() with same nc_id contains OpenMP critical region */
942
 
          (void)nco_var_get(in_id,var_prc[idx]);
943
 
          
 
1017
          (void)nco_msa_var_get(in_id,var_prc[idx],lmt_all_lst,nbr_dmn_fl);
944
1018
          if(dmn_rdr_nbr > 0){
945
1019
            if((var_prc_out[idx]->val.vp=(void *)nco_malloc_flg(var_prc_out[idx]->sz*nco_typ_lng(var_prc_out[idx]->type))) == NULL){
946
 
              (void)fprintf(fp_stdout,"%s: ERROR Unable to malloc() %ld*%lu bytes for value buffer for variable %s in main()\n",prg_nm_get(),var_prc_out[idx]->sz,(unsigned long)nco_typ_lng(var_prc_out[idx]->type),var_prc_out[idx]->nm);
 
1020
              (void)fprintf(fp_stdout,"%s: ERROR Unable to malloc() %ld*%lu bytes for value buffer for variable %s in main()\n",nco_prg_nm_get(),var_prc_out[idx]->sz,(unsigned long)nco_typ_lng(var_prc_out[idx]->type),var_prc_out[idx]->nm);
947
1021
              nco_exit(EXIT_FAILURE); 
948
1022
            } /* endif err */
949
1023
            
977
1051
          
978
1052
            /* Worker has token---prepare to write */
979
1053
          if(tkn_wrt_rsp == tkn_wrt_rqs_xcp){
980
 
            rcd=nco_open(fl_out_tmp,NC_WRITE|NC_SHARE,&out_id);
 
1054
            if(RAM_OPEN) md_open=NC_WRITE|NC_SHARE|NC_DISKLESS; else md_open=NC_WRITE|NC_SHARE;
 
1055
            rcd=nco_fl_open(fl_out_tmp,md_open,&bfr_sz_hnt,&out_id);
981
1056
            /* Set chunksize parameters */
982
 
            if(fl_out_fmt == NC_FORMAT_NETCDF4 || fl_out_fmt == NC_FORMAT_NETCDF4_CLASSIC) (void)nco_cnk_sz_set(out_id,lmt_all_lst,nbr_dmn_fl,&cnk_map,&cnk_plc,cnk_sz_scl,cnk,cnk_nbr);
 
1057
            if(fl_out_fmt == NC_FORMAT_NETCDF4 || fl_out_fmt == NC_FORMAT_NETCDF4_CLASSIC) (void)nco_cnk_sz_set(out_id,lmt_all_lst,nbr_dmn_fl,&cnk_map,&cnk_plc,cnk_sz_scl,cnk_dmn,cnk_nbr);
983
1058
            
984
1059
            /* Turn off default filling behavior to enhance efficiency */
985
1060
            nco_set_fill(out_id,NC_NOFILL,&fll_md_old);
1012
1087
  }  /* end (OpenMP parallel for) loop over idx */
1013
1088
#endif /* !ENABLE_MPI */
1014
1089
  
1015
 
  if(dbg_lvl >= nco_dbg_fl) (void)fprintf(fp_stderr,"\n");
 
1090
  if(nco_dbg_lvl >= nco_dbg_fl) (void)fprintf(fp_stderr,"\n");
1016
1091
  
1017
1092
#ifdef ENABLE_MPI
1018
1093
  MPI_Barrier(MPI_COMM_WORLD);
1028
1103
    if(nco_pck_plc != nco_pck_plc_nil && nco_pck_plc != nco_pck_plc_upk){
1029
1104
      nco_bool nco_pck_plc_alw; /* [flg] Packing policy allows packing nc_typ_in */
1030
1105
      /* ...put file in define mode to allow metadata writing... */
1031
 
      rcd=nco_open(fl_out_tmp,NC_WRITE,&out_id);
 
1106
      if(RAM_OPEN) md_open=NC_WRITE|NC_DISKLESS; else md_open=NC_WRITE;
 
1107
      rcd=nco_fl_open(fl_out_tmp,md_open,&bfr_sz_hnt,&out_id);
1032
1108
      (void)nco_redef(out_id);
1033
1109
      /* ...loop through all variables that may have been packed... */
1034
1110
#ifdef ENABLE_MPI
1054
1130
               (nco_pck_plc == nco_pck_plc_xst_new_att && var_prc[idx]->pck_ram)
1055
1131
               ){
1056
1132
              /* Replace dummy packing attributes with final values, or delete them */
1057
 
              if(dbg_lvl >= nco_dbg_io) (void)fprintf(stderr,"%s: main() replacing dummy packing attribute values for variable %s\n",prg_nm,var_prc[idx]->nm);
 
1133
              if(nco_dbg_lvl >= nco_dbg_io) (void)fprintf(stderr,"%s: main() replacing dummy packing attribute values for variable %s\n",nco_prg_nm,var_prc[idx]->nm);
1058
1134
              (void)nco_aed_prc(out_id,aed_lst_add_fst[idx].id,aed_lst_add_fst[idx]);
1059
1135
              (void)nco_aed_prc(out_id,aed_lst_scl_fct[idx].id,aed_lst_scl_fct[idx]);
1060
1136
            } /* endif variable is newly packed by this operator */
1081
1157
    for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) nco_close(in_id_arr[thr_idx]);
1082
1158
    
1083
1159
    /* Remove local copy of file */
1084
 
    if(FILE_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in);
 
1160
    if(FL_RTR_RMT_LCN && RM_RMT_FL_PST_PRC) (void)nco_fl_rm(fl_in);
1085
1161
    
1086
1162
  } /* end loop over fl_idx */
1087
1163
  
1123
1199
      } /* nco_pck_plc == nco_pck_plc_upk */
1124
1200
    } /* nco_pck_plc == nco_pck_plc_nil */
1125
1201
    
 
1202
    /* NB: lmt now referenced within lmt_all_lst[idx]  */
 
1203
    for(idx=0;idx<nbr_dmn_fl;idx++)
 
1204
      for(jdx=0;jdx< lmt_all_lst[idx]->lmt_dmn_nbr;jdx++)
 
1205
        lmt_all_lst[idx]->lmt_dmn[jdx]=nco_lmt_free(lmt_all_lst[idx]->lmt_dmn[jdx]);
 
1206
    if(nbr_dmn_fl > 0) lmt_all_lst=nco_lmt_all_lst_free(lmt_all_lst,nbr_dmn_fl);   
 
1207
    lmt=(lmt_sct**)nco_free(lmt); 
 
1208
        
1126
1209
    /* NCO-generic clean-up */
1127
1210
    /* Free individual strings/arrays */
1128
1211
    if(cmd_ln) cmd_ln=(char *)nco_free(cmd_ln);
1129
 
    if(cnk_map_sng) cnk_map_sng=(char *)strdup(cnk_map_sng);
1130
 
    if(cnk_plc_sng) cnk_plc_sng=(char *)strdup(cnk_plc_sng);
 
1212
    if(cnk_map_sng) cnk_map_sng=(char *)nco_free(cnk_map_sng);
 
1213
    if(cnk_plc_sng) cnk_plc_sng=(char *)nco_free(cnk_plc_sng);
1131
1214
    if(fl_in) fl_in=(char *)nco_free(fl_in);
1132
1215
    if(fl_out) fl_out=(char *)nco_free(fl_out);
1133
1216
    if(fl_out_tmp) fl_out_tmp=(char *)nco_free(fl_out_tmp);
1141
1224
    if(var_lst_in_nbr > 0) var_lst_in=nco_sng_lst_free(var_lst_in,var_lst_in_nbr);
1142
1225
    /* Free limits */
1143
1226
    for(idx=0;idx<lmt_nbr;idx++) lmt_arg[idx]=(char *)nco_free(lmt_arg[idx]);
1144
 
    if(lmt_nbr > 0) lmt=nco_lmt_lst_free(lmt,lmt_nbr);
 
1227
    for(idx=0;idx<aux_nbr;idx++) aux_arg[idx]=(char *)nco_free(aux_arg[idx]);
 
1228
    if(aux_nbr > 0) aux=(lmt_sct **)nco_free(aux);
1145
1229
    /* Free chunking information */
1146
1230
    for(idx=0;idx<cnk_nbr;idx++) cnk_arg[idx]=(char *)nco_free(cnk_arg[idx]);
1147
 
    if(cnk_nbr > 0) cnk=nco_cnk_lst_free(cnk,cnk_nbr);
 
1231
    if(cnk_nbr > 0) cnk_dmn=nco_cnk_lst_free(cnk_dmn,cnk_nbr);
1148
1232
    /* Free dimension lists */
1149
1233
    if(nbr_dmn_xtr > 0) dim=nco_dmn_lst_free(dim,nbr_dmn_xtr);
1150
1234
    if(nbr_dmn_xtr > 0) dmn_out=nco_dmn_lst_free(dmn_out,nbr_dmn_xtr);
1151
1235
    /* Free variable lists */
1152
 
    if(nbr_xtr > 0) var=nco_var_lst_free(var,nbr_xtr);
1153
 
    if(nbr_xtr > 0) var_out=nco_var_lst_free(var_out,nbr_xtr);
 
1236
    if(xtr_nbr > 0) var=nco_var_lst_free(var,xtr_nbr);
 
1237
    if(xtr_nbr > 0) var_out=nco_var_lst_free(var_out,xtr_nbr);
1154
1238
    var_prc=(var_sct **)nco_free(var_prc);
1155
1239
    var_prc_out=(var_sct **)nco_free(var_prc_out);
1156
1240
    var_fix=(var_sct **)nco_free(var_fix);