#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <time.h>#include <unistd.h>#include "nco_getopt.h"#include <netcdf.h>#include "libnco.h"Include dependency graph for ncecat.c:

Go to the source code of this file.
Defines | |
| #define | MAIN_PROGRAM_FILE |
Functions | |
| int | main (int argc, char **argv) |
|
|
|
|
||||||||||||
|
Definition at line 61 of file ncecat.c. References var_sct_tag::cnt, dmn_sct_tag::cnt, copyright_prn(), var_sct_tag::dim, var_sct_tag::dmn_id, var_sct_tag::end, dmn_sct_tag::end, EXIT_FAILURE, EXIT_SUCCESS, False, FILE, getopt_long, dmn_sct_tag::id, int_CEWI, dmn_sct_tag::is_crd_dmn, dmn_sct_tag::is_rec_dmn, var_sct_tag::is_rec_var, lst_prs_2D(), option::name, var_sct_tag::nbr_dim, NC_FORMAT_64BIT, NC_FORMAT_CLASSIC, NC_FORMAT_NETCDF4, NC_GLOBAL, dmn_sct_tag::nc_id, NC_MAX_DIMS, NC_NOERR, NC_NOFILL, NC_NOWRITE, nco_att_cpy(), nco_bool, nco_close(), nco_cmd_ln_sng(), nco_cnv_ccm_ccsm_cf_inq(), nco_create_mode_prs(), nco_dmn_dfn(), nco_dmn_dpl(), nco_dmn_fll(), nco_dmn_lmt_mrg(), nco_dmn_lst_ass_var(), nco_dmn_lst_free(), nco_dmn_xrf(), nco_enddef(), nco_err_exit(), nco_exit(), nco_exit_gracefully(), nco_fl_cmp_err_chk(), nco_fl_lst_att_cat(), nco_fl_lst_mk(), nco_fl_mk_lcl(), nco_fl_nm_prs(), nco_fl_out_cls(), nco_fl_out_open(), nco_fl_rm(), nco_free(), nco_hst_att_cat(), nco_inq(), nco_lbr_vrs_prn(), nco_lmt_evl(), nco_lmt_lst_free(), nco_lmt_prs(), nco_lst_comma2hash(), nco_lst_srt_nm_id(), nco_malloc(), nco_nm_id_lst_free(), nco_open(), nco_openmp_ini(), nco_pck_map_nil, nco_pck_plc_nil, nco_put_var1(), nco_put_vara(), nco_realloc(), NCO_REC_DMN_UNDEFINED, nco_set_fill(), nco_sng_lst_free(), nco_thr_att_cat(), nco_usg_prn(), nco_var_dfn(), nco_var_dpl(), nco_var_fll(), nco_var_get(), nco_var_lst_add_crd(), nco_var_lst_ass_crd_add(), nco_var_lst_dvd(), nco_var_lst_free(), nco_var_lst_mk(), nco_var_lst_xcl(), nco_var_mtd_refresh(), nco_var_srt_zero(), nco_var_val_cpy(), nco_xrf_dmn(), nco_xrf_var(), dmn_sct_tag::nm, no_argument, NULL_CEWI, omp_get_thread_num(), optarg, optind, prg_nm_get(), prg_prs(), required_argument, var_sct_tag::srt, dmn_sct_tag::srt, var_sct_tag::sz, dmn_sct_tag::sz, var_sct_tag::sz_rec, True, var_sct_tag::type, var_sct_tag::val, option::val, dmn_sct_tag::val, ptr_unn::vp, and dmn_sct_tag::xrf. 00062 { 00063 nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */ 00064 nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */ 00065 nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */ 00066 nco_bool FILE_RETRIEVED_FROM_REMOTE_LOCATION; 00067 nco_bool FL_LST_IN_APPEND=True; /* Option H */ 00068 nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */ 00069 nco_bool FORCE_APPEND=False; /* Option A */ 00070 nco_bool FORCE_OVERWRITE=False; /* Option O */ 00071 nco_bool FORTRAN_IDX_CNV=False; /* Option F */ 00072 nco_bool HISTORY_APPEND=True; /* Option h */ 00073 nco_bool CNV_CCM_CCSM_CF; 00074 nco_bool REMOVE_REMOTE_FILES_AFTER_PROCESSING=True; /* Option R */ 00075 00076 char **fl_lst_abb=NULL; /* Option a */ 00077 char **fl_lst_in; 00078 char **var_lst_in=NULL_CEWI; 00079 char *cmd_ln; 00080 char *fl_in=NULL; 00081 char *fl_out=NULL; /* Option o */ 00082 char *fl_out_tmp; 00083 char *fl_pth=NULL; /* Option p */ 00084 char *fl_pth_lcl=NULL; /* Option l */ 00085 char *lmt_arg[NC_MAX_DIMS]; 00086 char *opt_crr=NULL; /* [sng] String representation of current long-option name */ 00087 char *optarg_lcl=NULL; /* [sng] Local copy of system optarg */ 00088 char *time_bfr_srt; 00089 00090 const char * const CVS_Id="$Id: ncecat.c,v 1.117 2006/02/19 00:42:34 zender Exp $"; 00091 const char * const CVS_Revision="$Revision: 1.117 $"; 00092 const char * const opt_sht_lst="4ACcD:d:FHhl:n:Oo:p:rRt:v:x-:"; 00093 00094 dmn_sct *rec_dmn; 00095 dmn_sct **dim; 00096 dmn_sct **dmn_out; 00097 00098 extern char *optarg; 00099 extern int optind; 00100 00101 /* Using naked stdin/stdout/stderr in parallel region generates warning 00102 Copy appropriate filehandle to variable scoped shared in parallel clause */ 00103 FILE * const fp_stderr=stderr; /* [fl] stderr filehandle CEWI */ 00104 00105 int *in_id_arr; 00106 00107 int abb_arg_nbr=0; 00108 int fl_idx; 00109 int fl_nbr=0; 00110 int fl_out_fmt=NC_FORMAT_CLASSIC; /* [enm] Output file format */ 00111 int fll_md_old; /* [enm] Old fill mode */ 00112 int idx; 00113 int in_id; 00114 int lmt_nbr=0; /* Option d. NB: lmt_nbr gets incremented */ 00115 int nbr_dmn_fl; 00116 int nbr_dmn_xtr; 00117 int nbr_var_fix; /* nbr_var_fix gets incremented */ 00118 int nbr_var_fl; 00119 int nbr_var_prc; /* nbr_var_prc gets incremented */ 00120 int nbr_xtr=0; /* nbr_xtr won't otherwise be set for -c with no -v */ 00121 int opt; 00122 int out_id; 00123 int rcd=NC_NOERR; /* [rcd] Return code */ 00124 int rec_dmn_id=NCO_REC_DMN_UNDEFINED; 00125 int thr_idx; /* [idx] Index of current thread */ 00126 int thr_nbr=int_CEWI; /* [nbr] Thread number Option t */ 00127 int var_lst_in_nbr=0; 00128 00129 lmt_sct **lmt; 00130 00131 long idx_rec_out=0L; /* idx_rec_out gets incremented */ 00132 00133 nm_id_sct *dmn_lst; 00134 nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */ 00135 00136 time_t time_crr_time_t; 00137 00138 var_sct **var; 00139 var_sct **var_fix; 00140 var_sct **var_fix_out; 00141 var_sct **var_out; 00142 var_sct **var_prc; 00143 var_sct **var_prc_out; 00144 00145 static struct option opt_lng[]= 00146 { /* Structure ordered by short option key if possible */ 00147 /* Long options with no argument, no short option counterpart */ 00148 /* Long options with argument, no short option counterpart */ 00149 {"fl_fmt",required_argument,0,0}, 00150 {"file_format",required_argument,0,0}, 00151 /* Long options with short counterparts */ 00152 {"4",no_argument,0,'4'}, 00153 {"64bit",no_argument,0,'4'}, 00154 {"netcdf4",no_argument,0,'4'}, 00155 {"append",no_argument,0,'A'}, 00156 {"coords",no_argument,0,'c'}, 00157 {"crd",no_argument,0,'c'}, 00158 {"no-coords",no_argument,0,'C'}, 00159 {"no-crd",no_argument,0,'C'}, 00160 {"debug",required_argument,0,'D'}, 00161 {"dbg_lvl",required_argument,0,'D'}, 00162 {"dimension",required_argument,0,'d'}, 00163 {"dmn",required_argument,0,'d'}, 00164 {"fortran",no_argument,0,'F'}, 00165 {"ftn",no_argument,0,'F'}, 00166 {"fl_lst_in",no_argument,0,'H'}, 00167 {"file_list",no_argument,0,'H'}, 00168 {"history",no_argument,0,'h'}, 00169 {"hst",no_argument,0,'h'}, 00170 {"local",required_argument,0,'l'}, 00171 {"lcl",required_argument,0,'l'}, 00172 {"nintap",required_argument,0,'n'}, 00173 {"overwrite",no_argument,0,'O'}, 00174 {"ovr",no_argument,0,'O'}, 00175 {"output",required_argument,0,'o'}, 00176 {"fl_out",required_argument,0,'o'}, 00177 {"path",required_argument,0,'p'}, 00178 {"retain",no_argument,0,'R'}, 00179 {"rtn",no_argument,0,'R'}, 00180 {"revision",no_argument,0,'r'}, 00181 {"thr_nbr",required_argument,0,'t'}, 00182 {"threads",required_argument,0,'t'}, 00183 {"omp_num_threads",required_argument,0,'t'}, 00184 {"variable",required_argument,0,'v'}, 00185 {"version",no_argument,0,'r'}, 00186 {"vrs",no_argument,0,'r'}, 00187 {"exclude",no_argument,0,'x'}, 00188 {"xcl",no_argument,0,'x'}, 00189 {"help",no_argument,0,'?'}, 00190 {0,0,0,0} 00191 }; /* end opt_lng */ 00192 int opt_idx=0; /* Index of current long option into opt_lng array */ 00193 00194 /* Start clock and save command line */ 00195 cmd_ln=nco_cmd_ln_sng(argc,argv); 00196 time_crr_time_t=time((time_t *)NULL); 00197 time_bfr_srt=ctime(&time_crr_time_t); time_bfr_srt=time_bfr_srt; /* Avoid compiler warning until variable is used for something */ 00198 00199 /* Get program name and set program enum (e.g., prg=ncra) */ 00200 prg_nm=prg_prs(argv[0],&prg); 00201 00202 /* Parse command line arguments */ 00203 while(1){ 00204 /* getopt_long_only() allows one dash to prefix long options */ 00205 opt=getopt_long(argc,argv,opt_sht_lst,opt_lng,&opt_idx); 00206 /* NB: access to opt_crr is only valid when long_opt is detected */ 00207 if(opt == EOF) break; /* Parse positional arguments once getopt_long() returns EOF */ 00208 opt_crr=(char *)strdup(opt_lng[opt_idx].name); 00209 00210 /* Process long options without short option counterparts */ 00211 if(opt == 0){ 00212 if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt); 00213 } /* opt != 0 */ 00214 /* Process short options */ 00215 switch(opt){ 00216 case 0: /* Long options have already been processed, return */ 00217 break; 00218 case '4': /* [flg] Catch-all to prescribe output storage format */ 00219 if(!strcmp(opt_crr,"64bit")) fl_out_fmt=NC_FORMAT_64BIT; else fl_out_fmt=NC_FORMAT_NETCDF4; 00220 break; 00221 case 'A': /* Toggle FORCE_APPEND */ 00222 FORCE_APPEND=!FORCE_APPEND; 00223 break; 00224 case 'C': /* Extract all coordinates associated with extracted variables? */ 00225 EXTRACT_ASSOCIATED_COORDINATES=False; 00226 break; 00227 case 'c': 00228 EXTRACT_ALL_COORDINATES=True; 00229 break; 00230 case 'D': /* Debugging level. Default is 0. */ 00231 dbg_lvl=(unsigned short)strtol(optarg,(char **)NULL,10); 00232 break; 00233 case 'd': /* Copy argument for later processing */ 00234 lmt_arg[lmt_nbr]=(char *)strdup(optarg); 00235 lmt_nbr++; 00236 break; 00237 case 'F': /* Toggle index convention. Default is 0-based arrays (C-style). */ 00238 FORTRAN_IDX_CNV=!FORTRAN_IDX_CNV; 00239 break; 00240 case 'H': /* Toggle writing input file list attribute */ 00241 FL_LST_IN_APPEND=!FL_LST_IN_APPEND; 00242 break; 00243 case 'h': /* Toggle appending to history global attribute */ 00244 HISTORY_APPEND=!HISTORY_APPEND; 00245 break; 00246 case 'l': /* Local path prefix for files retrieved from remote file system */ 00247 fl_pth_lcl=(char *)strdup(optarg); 00248 break; 00249 case 'n': /* NINTAP-style abbreviation of files to process */ 00250 fl_lst_abb=lst_prs_2D(optarg,",",&abb_arg_nbr); 00251 if(abb_arg_nbr < 1 || abb_arg_nbr > 5){ 00252 (void)fprintf(stdout,"%s: ERROR Incorrect abbreviation for file list\n",prg_nm); 00253 (void)nco_usg_prn(); 00254 nco_exit(EXIT_FAILURE); 00255 } /* end if */ 00256 break; 00257 case 'O': /* Toggle FORCE_OVERWRITE */ 00258 FORCE_OVERWRITE=!FORCE_OVERWRITE; 00259 break; 00260 case 'o': /* Name of output file */ 00261 fl_out=(char *)strdup(optarg); 00262 break; 00263 case 'p': /* Common file path */ 00264 fl_pth=(char *)strdup(optarg); 00265 break; 00266 case 'R': /* Toggle removal of remotely-retrieved-files. Default is True. */ 00267 REMOVE_REMOTE_FILES_AFTER_PROCESSING=!REMOVE_REMOTE_FILES_AFTER_PROCESSING; 00268 break; 00269 case 'r': /* Print CVS program information and copyright notice */ 00270 (void)copyright_prn(CVS_Id,CVS_Revision); 00271 (void)nco_lbr_vrs_prn(); 00272 nco_exit(EXIT_SUCCESS); 00273 break; 00274 case 't': /* Thread number */ 00275 thr_nbr=(int)strtol(optarg,(char **)NULL,10); 00276 break; 00277 case 'v': /* Variables to extract/exclude */ 00278 /* Replace commas with hashes when within braces (convert back later) */ 00279 optarg_lcl=(char *)strdup(optarg); 00280 (void)nco_lst_comma2hash(optarg_lcl); 00281 var_lst_in=lst_prs_2D(optarg_lcl,",",&var_lst_in_nbr); 00282 optarg_lcl=(char *)nco_free(optarg_lcl); 00283 nbr_xtr=var_lst_in_nbr; 00284 break; 00285 case 'x': /* Exclude rather than extract variables specified with -v */ 00286 EXCLUDE_INPUT_LIST=True; 00287 break; 00288 case '?': /* Print proper usage */ 00289 (void)nco_usg_prn(); 00290 nco_exit(EXIT_SUCCESS); 00291 break; 00292 case '-': /* Long options are not allowed */ 00293 (void)fprintf(stderr,"%s: ERROR Long options are not available in this build. Use single letter options instead.\n",prg_nm_get()); 00294 nco_exit(EXIT_FAILURE); 00295 break; 00296 default: /* Print proper usage */ 00297 (void)nco_usg_prn(); 00298 nco_exit(EXIT_FAILURE); 00299 break; 00300 } /* end switch */ 00301 if(opt_crr != NULL) opt_crr=(char *)nco_free(opt_crr); 00302 } /* end while loop */ 00303 00304 /* Process positional arguments and fill in filenames */ 00305 fl_lst_in=nco_fl_lst_mk(argv,argc,optind,&fl_nbr,&fl_out,&FL_LST_IN_FROM_STDIN); 00306 00307 /* Make uniform list of user-specified dimension limits */ 00308 lmt=nco_lmt_prs(lmt_nbr,lmt_arg); 00309 00310 /* Initialize thread information */ 00311 thr_nbr=nco_openmp_ini(thr_nbr); 00312 in_id_arr=(int *)nco_malloc(thr_nbr*sizeof(int)); 00313 00314 /* Parse filename */ 00315 fl_in=nco_fl_nm_prs(fl_in,0,&fl_nbr,fl_lst_in,abb_arg_nbr,fl_lst_abb,fl_pth); 00316 /* Make sure file is on local system and is readable or die trying */ 00317 fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FILE_RETRIEVED_FROM_REMOTE_LOCATION); 00318 /* Open file for reading */ 00319 rcd=nco_open(fl_in,NC_NOWRITE,&in_id); 00320 00321 /* Get number of variables, dimensions, and record dimension ID of input file */ 00322 (void)nco_inq(in_id,&nbr_dmn_fl,&nbr_var_fl,(int *)NULL,&rec_dmn_id); 00323 00324 /* Form initial extraction list which may include extended regular expressions */ 00325 xtr_lst=nco_var_lst_mk(in_id,nbr_var_fl,var_lst_in,EXTRACT_ALL_COORDINATES,&nbr_xtr); 00326 00327 /* Change included variables to excluded variables */ 00328 if(EXCLUDE_INPUT_LIST) xtr_lst=nco_var_lst_xcl(in_id,nbr_var_fl,xtr_lst,&nbr_xtr); 00329 00330 /* Add all coordinate variables to extraction list */ 00331 if(EXTRACT_ALL_COORDINATES) xtr_lst=nco_var_lst_add_crd(in_id,nbr_dmn_fl,xtr_lst,&nbr_xtr); 00332 00333 /* Make sure coordinates associated extracted variables are also on extraction list */ 00334 if(EXTRACT_ASSOCIATED_COORDINATES) xtr_lst=nco_var_lst_ass_crd_add(in_id,xtr_lst,&nbr_xtr); 00335 00336 /* Sort extraction list by variable ID for fastest I/O */ 00337 if(nbr_xtr > 1) xtr_lst=nco_lst_srt_nm_id(xtr_lst,nbr_xtr,False); 00338 00339 /* We now have final list of variables to extract. Phew. */ 00340 00341 /* Find coordinate/dimension values associated with user-specified limits 00342 NB: nco_lmt_evl() with same nc_id contains OpenMP critical region */ 00343 for(idx=0;idx<lmt_nbr;idx++) (void)nco_lmt_evl(in_id,lmt[idx],0L,FORTRAN_IDX_CNV); 00344 00345 /* Find dimensions associated with variables to be extracted */ 00346 dmn_lst=nco_dmn_lst_ass_var(in_id,xtr_lst,nbr_xtr,&nbr_dmn_xtr); 00347 00348 /* Fill in dimension structure for all extracted dimensions */ 00349 dim=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *)); 00350 for(idx=0;idx<nbr_dmn_xtr;idx++) dim[idx]=nco_dmn_fll(in_id,dmn_lst[idx].id,dmn_lst[idx].nm); 00351 /* Dimension list no longer needed */ 00352 dmn_lst=nco_nm_id_lst_free(dmn_lst,nbr_dmn_xtr); 00353 00354 /* Merge hyperslab limit information into dimension structures */ 00355 if(lmt_nbr > 0) (void)nco_dmn_lmt_mrg(dim,nbr_dmn_xtr,lmt,lmt_nbr); 00356 00357 /* Duplicate input dimension structures for output dimension structures */ 00358 dmn_out=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *)); 00359 for(idx=0;idx<nbr_dmn_xtr;idx++){ 00360 dmn_out[idx]=nco_dmn_dpl(dim[idx]); 00361 (void)nco_dmn_xrf(dim[idx],dmn_out[idx]); 00362 } /* end loop over idx */ 00363 00364 /* Is this an CCM/CCSM/CF-format history tape? */ 00365 CNV_CCM_CCSM_CF=nco_cnv_ccm_ccsm_cf_inq(in_id); 00366 00367 /* Fill in variable structure list for all extracted variables */ 00368 var=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *)); 00369 var_out=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *)); 00370 for(idx=0;idx<nbr_xtr;idx++){ 00371 var[idx]=nco_var_fll(in_id,xtr_lst[idx].id,xtr_lst[idx].nm,dim,nbr_dmn_xtr); 00372 var_out[idx]=nco_var_dpl(var[idx]); 00373 (void)nco_xrf_var(var[idx],var_out[idx]); 00374 (void)nco_xrf_dmn(var_out[idx]); 00375 } /* end loop over idx */ 00376 /* Extraction list no longer needed */ 00377 xtr_lst=nco_nm_id_lst_free(xtr_lst,nbr_xtr); 00378 00379 /* Divide variable lists into lists of fixed variables and variables to be processed */ 00380 (void)nco_var_lst_dvd(var,var_out,nbr_xtr,CNV_CCM_CCSM_CF,nco_pck_plc_nil,nco_pck_map_nil,(dmn_sct **)NULL,0,&var_fix,&var_fix_out,&nbr_var_fix,&var_prc,&var_prc_out,&nbr_var_prc); 00381 00382 /* Open output file */ 00383 fl_out_tmp=nco_fl_out_open(fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&out_id); 00384 00385 /* Copy global attributes */ 00386 (void)nco_att_cpy(in_id,out_id,NC_GLOBAL,NC_GLOBAL,True); 00387 00388 /* Catenate time-stamped command line to "history" global attribute */ 00389 if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln); 00390 00391 /* Add input file list global attribute */ 00392 if(FL_LST_IN_APPEND && HISTORY_APPEND && FL_LST_IN_FROM_STDIN) (void)nco_fl_lst_att_cat(out_id,fl_lst_in,fl_nbr); 00393 00394 /* ncecat-specific operations */ 00395 if(True){ 00396 00397 /* Always construct new "record" dimension from scratch */ 00398 rec_dmn=(dmn_sct *)nco_malloc(sizeof(dmn_sct)); 00399 rec_dmn->nm=(char *)strdup("record"); 00400 rec_dmn->id=-1; 00401 rec_dmn->nc_id=-1; 00402 rec_dmn->xrf=NULL; 00403 rec_dmn->val.vp=NULL; 00404 rec_dmn->is_crd_dmn=False; 00405 rec_dmn->is_rec_dmn=True; 00406 rec_dmn->sz=0L; 00407 rec_dmn->cnt=0L; 00408 rec_dmn->srt=0L; 00409 rec_dmn->end=rec_dmn->sz-1L; 00410 00411 /* Change existing record dimension, if any, to regular dimension */ 00412 for(idx=0;idx<nbr_dmn_xtr;idx++){ 00413 /* Is any input dimension a record dimension? */ 00414 if(dmn_out[idx]->is_rec_dmn){ 00415 dmn_out[idx]->is_rec_dmn=False; 00416 break; 00417 } /* end if */ 00418 } /* end loop over idx */ 00419 00420 /* Add record dimension to end of dimension list */ 00421 nbr_dmn_xtr++; 00422 dmn_out=(dmn_sct **)nco_realloc(dmn_out,nbr_dmn_xtr*sizeof(dmn_sct **)); 00423 dmn_out[nbr_dmn_xtr-1]=rec_dmn; 00424 00425 } /* end if */ 00426 00427 if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr); 00428 00429 /* Define dimensions in output file */ 00430 (void)nco_dmn_dfn(fl_out,out_id,dmn_out,nbr_dmn_xtr); 00431 00432 if(True){ 00433 /* Prepend record dimension to beginning of all vectors for processed variables */ 00434 for(idx=0;idx<nbr_var_prc;idx++){ 00435 var_prc_out[idx]->nbr_dim++; 00436 var_prc_out[idx]->is_rec_var=True; 00437 var_prc_out[idx]->sz_rec=var_prc_out[idx]->sz; 00438 00439 /* Allocate space to hold dimension IDs */ 00440 var_prc_out[idx]->dim=(dmn_sct **)nco_realloc(var_prc_out[idx]->dim,var_prc_out[idx]->nbr_dim*sizeof(dmn_sct *)); 00441 var_prc_out[idx]->dmn_id=(int *)nco_realloc(var_prc_out[idx]->dmn_id,var_prc_out[idx]->nbr_dim*sizeof(int)); 00442 var_prc_out[idx]->cnt=(long *)nco_realloc(var_prc_out[idx]->cnt,var_prc_out[idx]->nbr_dim*sizeof(long)); 00443 var_prc_out[idx]->srt=(long *)nco_realloc(var_prc_out[idx]->srt,var_prc_out[idx]->nbr_dim*sizeof(long)); 00444 var_prc_out[idx]->end=(long *)nco_realloc(var_prc_out[idx]->end,var_prc_out[idx]->nbr_dim*sizeof(long)); 00445 00446 /* Move current array by one to make room for new record dimension info */ 00447 (void)memmove((void *)(var_prc_out[idx]->dim+1),(void *)(var_prc_out[idx]->dim),(var_prc_out[idx]->nbr_dim-1)*sizeof(dmn_sct *)); 00448 (void)memmove((void *)(var_prc_out[idx]->dmn_id+1),(void *)(var_prc_out[idx]->dmn_id),(var_prc_out[idx]->nbr_dim-1)*sizeof(int)); 00449 (void)memmove((void *)(var_prc_out[idx]->cnt+1),(void *)(var_prc_out[idx]->cnt),(var_prc_out[idx]->nbr_dim-1)*sizeof(long)); 00450 (void)memmove((void *)(var_prc_out[idx]->srt+1),(void *)(var_prc_out[idx]->srt),(var_prc_out[idx]->nbr_dim-1)*sizeof(long)); 00451 (void)memmove((void *)(var_prc_out[idx]->end+1),(void *)(var_prc_out[idx]->end),(var_prc_out[idx]->nbr_dim-1)*sizeof(long)); 00452 00453 /* Insert value for new record dimension */ 00454 var_prc_out[idx]->dim[0]=rec_dmn; 00455 var_prc_out[idx]->dmn_id[0]=rec_dmn->id; 00456 var_prc_out[idx]->cnt[0]=1L; 00457 var_prc_out[idx]->srt[0]=-1L; 00458 var_prc_out[idx]->end[0]=-1L; 00459 00460 } /* end loop over idx */ 00461 00462 } /* end if */ 00463 00464 /* Define variables in output file, copy their attributes */ 00465 (void)nco_var_dfn(in_id,fl_out,out_id,var_out,nbr_xtr,(dmn_sct **)NULL,(int)0,nco_pck_plc_nil,nco_pck_map_nil); 00466 00467 /* Turn off default filling behavior to enhance efficiency */ 00468 rcd=nco_set_fill(out_id,NC_NOFILL,&fll_md_old); 00469 00470 /* Take output file out of define mode */ 00471 (void)nco_enddef(out_id); 00472 00473 /* Zero start vectors for all output variables */ 00474 (void)nco_var_srt_zero(var_out,nbr_xtr); 00475 00476 /* Copy variable data for non-processed variables */ 00477 (void)nco_var_val_cpy(in_id,out_id,var_fix,nbr_var_fix); 00478 00479 /* Close first input netCDF file */ 00480 (void)nco_close(in_id); 00481 00482 /* Loop over input files */ 00483 for(fl_idx=0;fl_idx<fl_nbr;fl_idx++){ 00484 /* Parse filename */ 00485 if(fl_idx != 0) fl_in=nco_fl_nm_prs(fl_in,fl_idx,(int *)NULL,fl_lst_in,abb_arg_nbr, fl_lst_abb,fl_pth); 00486 if(dbg_lvl > 0) (void)fprintf(fp_stderr,"\nInput file %d is %s; ",fl_idx,fl_in); 00487 /* Make sure file is on local system and is readable or die trying */ 00488 if(fl_idx != 0) fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FILE_RETRIEVED_FROM_REMOTE_LOCATION); 00489 if(dbg_lvl > 0) (void)fprintf(fp_stderr,"local file %s:\n",fl_in); 00490 00491 /* Open file once per thread to improve caching */ 00492 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd=nco_open(fl_in,NC_NOWRITE,in_id_arr+thr_idx); 00493 00494 /* Perform various error-checks on input file */ 00495 if(False) (void)nco_fl_cmp_err_chk(); 00496 00497 /* OpenMP with threading over variables, not files */ 00498 #ifdef _OPENMP 00499 #pragma omp parallel for default(none) private(idx,in_id) shared(dbg_lvl,fl_nbr,idx_rec_out,in_id_arr,nbr_var_prc,out_id,var_prc,var_prc_out) 00500 #endif /* !_OPENMP */ 00501 /* Process all variables in current file */ 00502 for(idx=0;idx<nbr_var_prc;idx++){ 00503 in_id=in_id_arr[omp_get_thread_num()]; 00504 if(dbg_lvl > 1) (void)fprintf(fp_stderr,"%s, ",var_prc[idx]->nm); 00505 if(dbg_lvl > 0) (void)fflush(fp_stderr); 00506 /* Variables may have different ID, missing_value, type, in each file */ 00507 (void)nco_var_mtd_refresh(in_id,var_prc[idx]); 00508 /* Retrieve variable from disk into memory */ 00509 /* NB: nco_var_get() with same nc_id contains OpenMP critical region */ 00510 (void)nco_var_get(in_id,var_prc[idx]); 00511 /* Size of record dimension is 1 in output file */ 00512 var_prc_out[idx]->cnt[0]=1L; 00513 var_prc_out[idx]->srt[0]=idx_rec_out; 00514 /* Write variable into current record in output file */ 00515 #ifdef _OPENMP 00516 #pragma omp critical 00517 #endif /* _OPENMP */ 00518 { /* begin OpenMP critical */ 00519 if(var_prc[idx]->nbr_dim == 0){ 00520 (void)nco_put_var1(out_id,var_prc_out[idx]->id,var_prc_out[idx]->srt,var_prc[idx]->val.vp,var_prc[idx]->type); 00521 }else{ /* end if variable is a scalar */ 00522 (void)nco_put_vara(out_id,var_prc_out[idx]->id,var_prc_out[idx]->srt,var_prc_out[idx]->cnt,var_prc[idx]->val.vp,var_prc[idx]->type); 00523 } /* end if variable is array */ 00524 /* Free current input buffer */ 00525 var_prc[idx]->val.vp=nco_free(var_prc[idx]->val.vp); 00526 } /* end OpenMP critical */ 00527 00528 } /* end (OpenMP parallel for) loop over idx */ 00529 if(dbg_lvl > 1) (void)fprintf(stderr,"\n"); 00530 00531 idx_rec_out++; /* [idx] Index of current record in output file (0 is first, ...) */ 00532 00533 /* Close input netCDF file */ 00534 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) nco_close(in_id_arr[thr_idx]); 00535 00536 /* Remove local copy of file */ 00537 if(FILE_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in); 00538 00539 } /* end loop over fl_idx */ 00540 00541 /* Close output file and move it from temporary to permanent location */ 00542 (void)nco_fl_out_cls(fl_out,fl_out_tmp,out_id); 00543 00544 /* ncecat-specific memory cleanup */ 00545 00546 /* NCO-generic clean-up */ 00547 /* Free individual strings/arrays */ 00548 if(cmd_ln != NULL) cmd_ln=(char *)nco_free(cmd_ln); 00549 if(fl_in != NULL) fl_in=(char *)nco_free(fl_in); 00550 if(fl_out != NULL) fl_out=(char *)nco_free(fl_out); 00551 if(fl_out_tmp != NULL) fl_out_tmp=(char *)nco_free(fl_out_tmp); 00552 if(fl_pth != NULL) fl_pth=(char *)nco_free(fl_pth); 00553 if(fl_pth_lcl != NULL) fl_pth_lcl=(char *)nco_free(fl_pth_lcl); 00554 if(in_id_arr != NULL) in_id_arr=(int *)nco_free(in_id_arr); 00555 /* Free lists of strings */ 00556 if(fl_lst_in != NULL && fl_lst_abb == NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,fl_nbr); 00557 if(fl_lst_in != NULL && fl_lst_abb != NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,1); 00558 if(fl_lst_abb != NULL) fl_lst_abb=nco_sng_lst_free(fl_lst_abb,abb_arg_nbr); 00559 if(var_lst_in_nbr > 0) var_lst_in=nco_sng_lst_free(var_lst_in,var_lst_in_nbr); 00560 /* Free limits */ 00561 for(idx=0;idx<lmt_nbr;idx++) lmt_arg[idx]=(char *)nco_free(lmt_arg[idx]); 00562 if(lmt_nbr > 0) lmt=nco_lmt_lst_free(lmt,lmt_nbr); 00563 /* Free dimension lists */ 00564 if(nbr_dmn_xtr > 0) dim=nco_dmn_lst_free(dim,nbr_dmn_xtr-1); /* NB: ncecat has one fewer input than output dimension */ 00565 if(nbr_dmn_xtr > 0) dmn_out=nco_dmn_lst_free(dmn_out,nbr_dmn_xtr); 00566 /* Free variable lists */ 00567 if(nbr_xtr > 0) var=nco_var_lst_free(var,nbr_xtr); 00568 if(nbr_xtr > 0) var_out=nco_var_lst_free(var_out,nbr_xtr); 00569 var_prc=(var_sct **)nco_free(var_prc); 00570 var_prc_out=(var_sct **)nco_free(var_prc_out); 00571 var_fix=(var_sct **)nco_free(var_fix); 00572 var_fix_out=(var_sct **)nco_free(var_fix_out); 00573 00574 if(rcd != NC_NOERR) nco_err_exit(rcd,"main"); 00575 nco_exit_gracefully(); 00576 return EXIT_SUCCESS; 00577 } /* end main() */
|
1.4.4