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 */
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 */
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 */
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-:";
126
cnk_dmn_sct **cnk_dmn=NULL_CEWI;
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 */
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,'?'},
275
301
}; /* end opt_lng */
276
302
int opt_idx=0; /* Index of current long option into opt_lng array */
299
325
/* Process long options without short option counterparts */
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);
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;
328
370
/* Process short options */
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);
513
/* Parse auxiliary coordinates */
516
aux=nco_aux_evl(in_id,aux_nbr,aux_arg,&aux_idx_nbr);
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;
521
for(int lmt_idx=lmt_nbr;lmt_idx<lmt_nbr_new;lmt_idx++) lmt[lmt_idx]=aux[aux_idx++];
524
} /* endif aux_nbr */
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
490
560
/* Fill-in dimension structure for all extracted dimensions */
491
561
dim=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *));
504
571
(void)nco_dmn_xrf(dim[idx],dmn_out[idx]);
505
572
} /* end loop over idx */
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);
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));
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);
575
645
CNV_CCM_CCSM_CF=nco_cnv_ccm_ccsm_cf_inq(in_id);
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);
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);
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);
606
676
(void)nco_fl_fmt_vet(fl_out_fmt,cnk_nbr,dfl_lvl);
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);
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);
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 */
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);
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);
815
885
/* Turn off default filling behavior to enhance efficiency */
816
886
nco_set_fill(out_id,NC_NOFILL,&fll_md_old);
818
888
/* Take output file out of define mode */
819
(void)nco_enddef(out_id);
890
(void)nco_enddef(out_id);
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);
820
895
#ifdef ENABLE_MPI
821
896
} /* prc_rnk != rnk_mgr */
829
904
#endif /* !ENABLE_MPI */
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);
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);
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);
862
937
#ifdef ENABLE_MPI
863
938
if(prc_rnk == rnk_mgr){ /* MPI manager code */
927
1002
#else /* !ENABLE_MPI */
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);
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]);
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 */
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);
984
1059
/* Turn off default filling behavior to enhance efficiency */
985
1060
nco_set_fill(out_id,NC_NOFILL,&fll_md_old);
1123
1199
} /* nco_pck_plc == nco_pck_plc_upk */
1124
1200
} /* nco_pck_plc == nco_pck_plc_nil */
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);
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);