#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 ncra.c:

Go to the source code of this file.
Defines | |
| #define | gettext(foo) foo |
| #define | MAIN_PROGRAM_FILE |
Functions | |
| int | main (int argc, char **argv) |
|
|
|
|
|
|
|
||||||||||||
|
Definition at line 90 of file ncra.c. References arm_base_time_get(), arm_inq(), var_sct_tag::cnt, copyright_prn(), ptr_unn::dp, var_sct_tag::end, lmt_sct::end, EXIT_FAILURE, EXIT_SUCCESS, False, FILE, getopt_long, gettext, var_sct_tag::has_mss_val, int_CEWI, var_sct_tag::is_crd_var, lmt_sct::is_usr_spc_max, lmt_sct::is_usr_spc_min, lmt_dmn_idx, lmt_sct::lmt_typ, lst_prs_2D(), lmt_sct::max_idx, lmt_sct::min_idx, option::name, var_sct_tag::nbr_dim, NC_FORMAT_64BIT, NC_FORMAT_CLASSIC, NC_FORMAT_NETCDF4, NC_GLOBAL, NC_MAX_DIMS, NC_NOERR, NC_NOFILL, NC_NOWRITE, ncea, nco_arm_time_install(), nco_att_cpy(), nco_bool, nco_close(), nco_cmd_ln_sng(), nco_cnv_ccm_ccsm_cf_date(), nco_cnv_ccm_ccsm_cf_inq(), nco_cnv_mss_val_typ(), 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_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_int_CEWI, nco_lbr_vrs_prn(), nco_lmt_evl(), nco_lmt_free(), nco_lmt_lst_free(), nco_lmt_prs(), nco_lmt_sct_mk(), nco_lst_comma2hash(), nco_lst_srt_nm_id(), nco_malloc(), nco_nm_id_lst_free(), nco_op_avg, nco_op_avgsqr, nco_op_max, nco_op_min, nco_op_rms, nco_op_rmssdn, nco_op_sqravg, nco_op_sqrt, nco_op_ttl, nco_op_typ_get(), nco_open(), nco_openmp_ini(), nco_opr_drv(), nco_pck_map_nil, nco_pck_plc_all_new_att, nco_pck_plc_get(), nco_pck_plc_nil, nco_put_var1(), nco_put_var_pck(), nco_put_vara(), NCO_REC_DMN_UNDEFINED, nco_set_fill(), nco_sng_lst_free(), nco_thr_att_cat(), nco_typ_cnv_rth(), nco_typ_lng(), nco_usg_prn(), nco_var_cnf_typ(), 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_mlt(), nco_var_mtd_refresh(), nco_var_nrm(), nco_var_nrm_sdn(), nco_var_prc_crr_prn(), nco_var_sqrt(), nco_var_srt_zero(), nco_var_val_cpy(), nco_var_zero(), nco_xrf_dmn(), nco_xrf_var(), nco_zero_long(), ncra, ncrcat, no_argument, NULL_CEWI, omp_get_thread_num(), optarg, optind, prg_nm_get(), prg_prs(), rec_crd_chk(), required_argument, lmt_sct::srd, var_sct_tag::srt, lmt_sct::srt, var_sct_tag::sz, var_sct_tag::sz_rec, var_sct_tag::tally, True, var_sct_tag::typ_upk, var_sct_tag::type, type, option::val, var_sct_tag::val, and ptr_unn::vp. 00091 { 00092 nco_bool CNV_ARM=int_CEWI; 00093 nco_bool CNV_CCM_CCSM_CF=int_CEWI; 00094 nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */ 00095 nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */ 00096 nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */ 00097 nco_bool FILE_RETRIEVED_FROM_REMOTE_LOCATION; 00098 nco_bool FL_LST_IN_APPEND=True; /* Option H */ 00099 nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */ 00100 nco_bool FORCE_APPEND=False; /* Option A */ 00101 nco_bool FORCE_OVERWRITE=False; /* Option O */ 00102 nco_bool FORTRAN_IDX_CNV=False; /* Option F */ 00103 nco_bool HISTORY_APPEND=True; /* Option h */ 00104 nco_bool LAST_RECORD=False; 00105 nco_bool REMOVE_REMOTE_FILES_AFTER_PROCESSING=True; /* Option R */ 00106 00107 char **fl_lst_abb=NULL; /* Option n */ 00108 char **fl_lst_in; 00109 char **var_lst_in=NULL_CEWI; 00110 char *cmd_ln; 00111 char *fl_in=NULL; 00112 char *fl_out=NULL; /* Option o */ 00113 char *fl_out_tmp=NULL_CEWI; 00114 char *fl_pth=NULL; /* Option p */ 00115 char *fl_pth_lcl=NULL; /* Option l */ 00116 char *lmt_arg[NC_MAX_DIMS]; 00117 char *nco_op_typ_sng=NULL_CEWI; /* [sng] Operation type Option y */ 00118 char *nco_pck_plc_sng=NULL_CEWI; /* [sng] Packing policy Option P */ 00119 char *opt_crr=NULL; /* [sng] String representation of current long-option name */ 00120 char *optarg_lcl=NULL; /* [sng] Local copy of system optarg */ 00121 char *time_bfr_srt; 00122 00123 const char * const CVS_Id="$Id: ncra.c,v 1.176 2006/02/26 07:41:55 zender Exp $"; 00124 const char * const CVS_Revision="$Revision: 1.176 $"; 00125 const char * const opt_sht_lst="4ACcD:d:FHhl:n:Oo:p:P:rRt:v:xY:y:-:"; 00126 00127 dmn_sct **dim; 00128 dmn_sct **dmn_out; 00129 00130 extern char *optarg; 00131 extern int optind; 00132 00133 /* Using naked stdin/stdout/stderr in parallel region generates warning 00134 Copy appropriate filehandle to variable scoped shared in parallel clause */ 00135 FILE * const fp_stderr=stderr; /* [fl] stderr filehandle CEWI */ 00136 FILE * const fp_stdout=stdout; /* [fl] stdout filehandle CEWI */ 00137 00138 int *in_id_arr; 00139 00140 int abb_arg_nbr=0; 00141 int fl_idx; 00142 int fl_nbr=0; 00143 int fl_out_fmt=NC_FORMAT_CLASSIC; /* [enm] Output file format */ 00144 int fll_md_old; /* [enm] Old fill mode */ 00145 int idx=int_CEWI; 00146 int in_id; 00147 int lmt_nbr=0; /* Option d. NB: lmt_nbr gets incremented */ 00148 int nbr_dmn_fl; 00149 int nbr_dmn_xtr; 00150 int nbr_var_fix; /* nbr_var_fix gets incremented */ 00151 int nbr_var_fl; 00152 int nbr_var_prc; /* nbr_var_prc gets incremented */ 00153 int nbr_xtr=0; /* nbr_xtr won't otherwise be set for -c with no -v */ 00154 int nco_op_typ=nco_op_avg; /* [enm] Default operation is averaging */ 00155 int nco_pck_plc=nco_pck_plc_nil; /* [enm] Default packing is none */ 00156 int opt; 00157 int out_id; 00158 int rcd=NC_NOERR; /* [rcd] Return code */ 00159 int rec_dmn_id=NCO_REC_DMN_UNDEFINED; 00160 int thr_idx; /* [idx] Index of current thread */ 00161 int thr_nbr=int_CEWI; /* [nbr] Thread number Option t */ 00162 int var_lst_in_nbr=0; 00163 00164 lmt_sct **lmt=NULL_CEWI; 00165 lmt_sct *lmt_rec=NULL_CEWI; 00166 00167 long idx_rec; /* [idx] Index of current record in current input file */ 00168 long idx_rec_out=0L; /* [idx] Index of current record in output file (0 is first, ...) */ 00169 00170 nco_int base_time_srt=nco_int_CEWI; 00171 nco_int base_time_crr=nco_int_CEWI; 00172 00173 nm_id_sct *dmn_lst; 00174 nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */ 00175 00176 time_t time_crr_time_t; 00177 00178 var_sct **var; 00179 var_sct **var_fix; 00180 var_sct **var_fix_out; 00181 var_sct **var_out=NULL_CEWI; 00182 var_sct **var_prc; 00183 var_sct **var_prc_out; 00184 00185 static struct option opt_lng[]= 00186 { /* Structure ordered by short option key if possible */ 00187 /* Long options with no argument, no short option counterpart */ 00188 /* Long options with argument, no short option counterpart */ 00189 {"fl_fmt",required_argument,0,0}, 00190 {"file_format",required_argument,0,0}, 00191 /* Long options with short counterparts */ 00192 {"4",no_argument,0,'4'}, 00193 {"64bit",no_argument,0,'4'}, 00194 {"netcdf4",no_argument,0,'4'}, 00195 {"append",no_argument,0,'A'}, 00196 {"coords",no_argument,0,'c'}, 00197 {"crd",no_argument,0,'c'}, 00198 {"no-coords",no_argument,0,'C'}, 00199 {"no-crd",no_argument,0,'C'}, 00200 {"debug",required_argument,0,'D'}, 00201 {"dbg_lvl",required_argument,0,'D'}, 00202 {"dimension",required_argument,0,'d'}, 00203 {"dmn",required_argument,0,'d'}, 00204 {"fortran",no_argument,0,'F'}, 00205 {"ftn",no_argument,0,'F'}, 00206 {"fl_lst_in",no_argument,0,'H'}, 00207 {"file_list",no_argument,0,'H'}, 00208 {"history",no_argument,0,'h'}, 00209 {"hst",no_argument,0,'h'}, 00210 {"local",required_argument,0,'l'}, 00211 {"lcl",required_argument,0,'l'}, 00212 {"nintap",required_argument,0,'n'}, 00213 {"overwrite",no_argument,0,'O'}, 00214 {"ovr",no_argument,0,'O'}, 00215 {"output",required_argument,0,'o'}, 00216 {"fl_out",required_argument,0,'o'}, 00217 {"path",required_argument,0,'p'}, 00218 {"pack",required_argument,0,'P'}, 00219 {"retain",no_argument,0,'R'}, 00220 {"rtn",no_argument,0,'R'}, 00221 {"revision",no_argument,0,'r'}, 00222 {"thr_nbr",required_argument,0,'t'}, 00223 {"threads",required_argument,0,'t'}, 00224 {"omp_num_threads",required_argument,0,'t'}, 00225 {"variable",required_argument,0,'v'}, 00226 {"version",no_argument,0,'r'}, 00227 {"vrs",no_argument,0,'r'}, 00228 {"exclude",no_argument,0,'x'}, 00229 {"xcl",no_argument,0,'x'}, 00230 {"pseudonym",required_argument,0,'Y'}, 00231 {"program",required_argument,0,'Y'}, 00232 {"prg_nm",required_argument,0,'Y'}, 00233 {"math",required_argument,0,'y'}, 00234 {"help",no_argument,0,'?'}, 00235 {0,0,0,0} 00236 }; /* end opt_lng */ 00237 int opt_idx=0; /* Index of current long option into opt_lng array */ 00238 00239 #ifdef _LIBINTL_H 00240 setlocale(LC_ALL,""); /* LC_ALL sets all localization tokens to same value */ 00241 bindtextdomain("nco","/home/zender/share/locale"); /* ${LOCALEDIR} is e.g., /usr/share/locale */ 00242 /* MO files should be in ${LOCALEDIR}/es/LC_MESSAGES */ 00243 textdomain("nco"); /* PACKAGE is name of program */ 00244 #endif /* not _LIBINTL_H */ 00245 00246 /* Start clock and save command line */ 00247 cmd_ln=nco_cmd_ln_sng(argc,argv); 00248 time_crr_time_t=time((time_t *)NULL); 00249 time_bfr_srt=ctime(&time_crr_time_t); time_bfr_srt=time_bfr_srt; /* Avoid compiler warning until variable is used for something */ 00250 #if 0 /* Solaris version of ctime_r() requires three arguments */ 00251 ctime_r(&time_crr_time_t,time_bfr_srt); 00252 time_bfr_srt[24] = '\0'; /* Remove newline */ 00253 #endif /* !0 */ 00254 00255 /* Get program name and set program enum (e.g., prg=ncra) */ 00256 prg_nm=prg_prs(argv[0],&prg); 00257 00258 /* Parse command line arguments */ 00259 while(1){ 00260 /* getopt_long_only() allows one dash to prefix long options */ 00261 opt=getopt_long(argc,argv,opt_sht_lst,opt_lng,&opt_idx); 00262 /* NB: access to opt_crr is only valid when long_opt is detected */ 00263 if(opt == EOF) break; /* Parse positional arguments once getopt_long() returns EOF */ 00264 opt_crr=(char *)strdup(opt_lng[opt_idx].name); 00265 00266 /* Process long options without short option counterparts */ 00267 if(opt == 0){ 00268 if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt); 00269 } /* opt != 0 */ 00270 /* Process short options */ 00271 switch(opt){ 00272 case 0: /* Long options have already been processed, return */ 00273 break; 00274 case '4': /* [flg] Catch-all to prescribe output storage format */ 00275 if(!strcmp(opt_crr,"64bit")) fl_out_fmt=NC_FORMAT_64BIT; else fl_out_fmt=NC_FORMAT_NETCDF4; 00276 break; 00277 case 'A': /* Toggle FORCE_APPEND */ 00278 FORCE_APPEND=!FORCE_APPEND; 00279 break; 00280 case 'C': /* Extract all coordinates associated with extracted variables? */ 00281 EXTRACT_ASSOCIATED_COORDINATES=False; 00282 break; 00283 case 'c': 00284 EXTRACT_ALL_COORDINATES=True; 00285 break; 00286 case 'D': /* Debugging level. Default is 0. */ 00287 dbg_lvl=(unsigned short)strtol(optarg,(char **)NULL,10); 00288 break; 00289 case 'd': /* Copy argument for later processing */ 00290 lmt_arg[lmt_nbr]=(char *)strdup(optarg); 00291 lmt_nbr++; 00292 break; 00293 case 'F': /* Toggle index convention. Default is 0-based arrays (C-style). */ 00294 FORTRAN_IDX_CNV=!FORTRAN_IDX_CNV; 00295 break; 00296 case 'H': /* Toggle writing input file list attribute */ 00297 FL_LST_IN_APPEND=!FL_LST_IN_APPEND; 00298 break; 00299 case 'h': /* Toggle appending to history global attribute */ 00300 HISTORY_APPEND=!HISTORY_APPEND; 00301 break; 00302 case 'l': /* Local path prefix for files retrieved from remote file system */ 00303 fl_pth_lcl=(char *)strdup(optarg); 00304 break; 00305 case 'n': /* NINTAP-style abbreviation of files to average */ 00306 fl_lst_abb=lst_prs_2D(optarg,",",&abb_arg_nbr); 00307 if(abb_arg_nbr < 1 || abb_arg_nbr > 5){ 00308 (void)fprintf(stdout,gettext("%s: ERROR Incorrect abbreviation for file list\n"),prg_nm_get()); 00309 (void)nco_usg_prn(); 00310 nco_exit(EXIT_FAILURE); 00311 } /* end if */ 00312 break; 00313 case 'O': /* Toggle FORCE_OVERWRITE */ 00314 FORCE_OVERWRITE=!FORCE_OVERWRITE; 00315 break; 00316 case 'o': /* Name of output file */ 00317 fl_out=(char *)strdup(optarg); 00318 break; 00319 case 'p': /* Common file path */ 00320 fl_pth=(char *)strdup(optarg); 00321 break; 00322 case 'P': /* Packing policy */ 00323 nco_pck_plc_sng=(char *)strdup(optarg); 00324 nco_pck_plc=nco_pck_plc_get(nco_pck_plc_sng); 00325 break; 00326 case 'R': /* Toggle removal of remotely-retrieved-files. Default is True. */ 00327 REMOVE_REMOTE_FILES_AFTER_PROCESSING=!REMOVE_REMOTE_FILES_AFTER_PROCESSING; 00328 break; 00329 case 'r': /* Print CVS program information and copyright notice */ 00330 (void)copyright_prn(CVS_Id,CVS_Revision); 00331 (void)nco_lbr_vrs_prn(); 00332 nco_exit(EXIT_SUCCESS); 00333 break; 00334 case 't': /* Thread number */ 00335 thr_nbr=(int)strtol(optarg,(char **)NULL,10); 00336 break; 00337 case 'v': /* Variables to extract/exclude */ 00338 /* Replace commas with hashes when within braces (convert back later) */ 00339 optarg_lcl=(char *)strdup(optarg); 00340 (void)nco_lst_comma2hash(optarg_lcl); 00341 var_lst_in=lst_prs_2D(optarg_lcl,",",&var_lst_in_nbr); 00342 optarg_lcl=(char *)nco_free(optarg_lcl); 00343 nbr_xtr=var_lst_in_nbr; 00344 break; 00345 case 'x': /* Exclude rather than extract variables specified with -v */ 00346 EXCLUDE_INPUT_LIST=True; 00347 break; 00348 case 'Y': /* Pseudonym */ 00349 /* Call prg_prs to reset pseudonym */ 00350 optarg_lcl=(char *)strdup(optarg); 00351 if(prg_nm != NULL) prg_nm=(char *)nco_free(prg_nm); 00352 prg_nm=prg_prs(optarg_lcl,&prg); 00353 optarg_lcl=(char *)nco_free(optarg_lcl); 00354 break; 00355 case 'y': /* Operation type */ 00356 nco_op_typ_sng=(char *)strdup(optarg); 00357 if(prg == ncra || prg == ncea ) nco_op_typ=nco_op_typ_get(nco_op_typ_sng); 00358 break; 00359 case '?': /* Print proper usage */ 00360 (void)nco_usg_prn(); 00361 nco_exit(EXIT_SUCCESS); 00362 break; 00363 case '-': /* Long options are not allowed */ 00364 (void)fprintf(stderr,"%s: ERROR Long options are not available in this build. Use single letter options instead.\n",prg_nm_get()); 00365 nco_exit(EXIT_FAILURE); 00366 break; 00367 default: /* Print proper usage */ 00368 (void)nco_usg_prn(); 00369 nco_exit(EXIT_FAILURE); 00370 break; 00371 } /* end switch */ 00372 if(opt_crr != NULL) opt_crr=(char *)nco_free(opt_crr); 00373 } /* end while loop */ 00374 00375 /* Process positional arguments and fill in filenames */ 00376 fl_lst_in=nco_fl_lst_mk(argv,argc,optind,&fl_nbr,&fl_out,&FL_LST_IN_FROM_STDIN); 00377 00378 /* Make uniform list of user-specified dimension limits */ 00379 if(lmt_nbr > 0) lmt=nco_lmt_prs(lmt_nbr,lmt_arg); 00380 00381 /* Initialize thread information */ 00382 thr_nbr=nco_openmp_ini(thr_nbr); 00383 in_id_arr=(int *)nco_malloc(thr_nbr*sizeof(int)); 00384 00385 /* Parse filename */ 00386 fl_in=nco_fl_nm_prs(fl_in,0,&fl_nbr,fl_lst_in,abb_arg_nbr,fl_lst_abb,fl_pth); 00387 /* Make sure file is on local system and is readable or die trying */ 00388 fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FILE_RETRIEVED_FROM_REMOTE_LOCATION); 00389 /* Open file for reading */ 00390 rcd=nco_open(fl_in,NC_NOWRITE,&in_id); 00391 00392 /* Get number of variables, dimensions, and record dimension ID of input file */ 00393 (void)nco_inq(in_id,&nbr_dmn_fl,&nbr_var_fl,(int *)NULL,&rec_dmn_id); 00394 00395 /* Form initial extraction list which may include extended regular expressions */ 00396 xtr_lst=nco_var_lst_mk(in_id,nbr_var_fl,var_lst_in,EXTRACT_ALL_COORDINATES,&nbr_xtr); 00397 00398 /* Change included variables to excluded variables */ 00399 if(EXCLUDE_INPUT_LIST) xtr_lst=nco_var_lst_xcl(in_id,nbr_var_fl,xtr_lst,&nbr_xtr); 00400 00401 /* Add all coordinate variables to extraction list */ 00402 if(EXTRACT_ALL_COORDINATES) xtr_lst=nco_var_lst_add_crd(in_id,nbr_dmn_fl,xtr_lst,&nbr_xtr); 00403 00404 /* Make sure coordinates associated extracted variables are also on extraction list */ 00405 if(EXTRACT_ASSOCIATED_COORDINATES) xtr_lst=nco_var_lst_ass_crd_add(in_id,xtr_lst,&nbr_xtr); 00406 00407 /* Sort extraction list by variable ID for fastest I/O */ 00408 if(nbr_xtr > 1) xtr_lst=nco_lst_srt_nm_id(xtr_lst,nbr_xtr,False); 00409 00410 /* We now have final list of variables to extract. Phew. */ 00411 00412 /* Find coordinate/dimension values associated with user-specified limits 00413 NB: nco_lmt_evl() with same nc_id contains OpenMP critical region */ 00414 for(idx=0;idx<lmt_nbr;idx++) (void)nco_lmt_evl(in_id,lmt[idx],0L,FORTRAN_IDX_CNV); 00415 00416 /* Find dimensions associated with variables to be extracted */ 00417 dmn_lst=nco_dmn_lst_ass_var(in_id,xtr_lst,nbr_xtr,&nbr_dmn_xtr); 00418 00419 /* Fill in dimension structure for all extracted dimensions */ 00420 dim=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *)); 00421 for(idx=0;idx<nbr_dmn_xtr;idx++) dim[idx]=nco_dmn_fll(in_id,dmn_lst[idx].id,dmn_lst[idx].nm); 00422 /* Dimension list no longer needed */ 00423 dmn_lst=nco_nm_id_lst_free(dmn_lst,nbr_dmn_xtr); 00424 00425 /* Merge hyperslab limit information into dimension structures */ 00426 if(lmt_nbr > 0) (void)nco_dmn_lmt_mrg(dim,nbr_dmn_xtr,lmt,lmt_nbr); 00427 00428 /* Duplicate input dimension structures for output dimension structures */ 00429 dmn_out=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *)); 00430 for(idx=0;idx<nbr_dmn_xtr;idx++){ 00431 dmn_out[idx]=nco_dmn_dpl(dim[idx]); 00432 (void)nco_dmn_xrf(dim[idx],dmn_out[idx]); 00433 } /* end loop over idx */ 00434 00435 /* Create stand-alone limit structure just for record dimension */ 00436 if(prg == ncra || prg == ncrcat){ 00437 if(rec_dmn_id == NCO_REC_DMN_UNDEFINED){ 00438 (void)fprintf(stdout,gettext("%s: ERROR input file %s lacks a record dimension\n"),prg_nm_get(),fl_in); 00439 if(fl_nbr == 1)(void)fprintf(stdout,gettext("%s: HINT Use ncks instead of %s\n"),prg_nm_get(),prg_nm_get()); 00440 nco_exit(EXIT_FAILURE); 00441 } /* endif */ 00442 lmt_rec=nco_lmt_sct_mk(in_id,rec_dmn_id,lmt,lmt_nbr,FORTRAN_IDX_CNV); 00443 } /* endif */ 00444 00445 /* Is this an CCM/CCSM/CF-format history tape? */ 00446 CNV_CCM_CCSM_CF=nco_cnv_ccm_ccsm_cf_inq(in_id); 00447 00448 /* Is this an ARM-format data file? */ 00449 CNV_ARM=arm_inq(in_id); 00450 /* NB: arm_base_time_get() with same nc_id contains OpenMP critical region */ 00451 if(CNV_ARM) base_time_srt=arm_base_time_get(in_id); 00452 00453 /* Fill in variable structure list for all extracted variables */ 00454 var=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *)); 00455 var_out=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *)); 00456 for(idx=0;idx<nbr_xtr;idx++){ 00457 var[idx]=nco_var_fll(in_id,xtr_lst[idx].id,xtr_lst[idx].nm,dim,nbr_dmn_xtr); 00458 var_out[idx]=nco_var_dpl(var[idx]); 00459 (void)nco_xrf_var(var[idx],var_out[idx]); 00460 (void)nco_xrf_dmn(var_out[idx]); 00461 } /* end loop over idx */ 00462 /* Extraction list no longer needed */ 00463 xtr_lst=nco_nm_id_lst_free(xtr_lst,nbr_xtr); 00464 00465 /* Divide variable lists into lists of fixed variables and variables to be processed */ 00466 (void)nco_var_lst_dvd(var,var_out,nbr_xtr,CNV_CCM_CCSM_CF,nco_pck_plc_nil,nco_pck_map_nil,NULL,0,&var_fix,&var_fix_out,&nbr_var_fix,&var_prc,&var_prc_out,&nbr_var_prc); 00467 00468 /* Open output file */ 00469 fl_out_tmp=nco_fl_out_open(fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&out_id); 00470 00471 /* Copy global attributes */ 00472 (void)nco_att_cpy(in_id,out_id,NC_GLOBAL,NC_GLOBAL,True); 00473 00474 /* Catenate time-stamped command line to "history" global attribute */ 00475 if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln); 00476 00477 /* Add input file list global attribute */ 00478 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); 00479 00480 if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr); 00481 00482 /* Define dimensions in output file */ 00483 (void)nco_dmn_dfn(fl_out,out_id,dmn_out,nbr_dmn_xtr); 00484 00485 /* Define variables in output file, copy their attributes */ 00486 (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); 00487 00488 /* Turn off default filling behavior to enhance efficiency */ 00489 (void)nco_set_fill(out_id,NC_NOFILL,&fll_md_old); 00490 00491 /* Take output file out of define mode */ 00492 (void)nco_enddef(out_id); 00493 00494 /* Zero start vectors for all output variables */ 00495 (void)nco_var_srt_zero(var_out,nbr_xtr); 00496 00497 /* Copy variable data for non-processed variables */ 00498 (void)nco_var_val_cpy(in_id,out_id,var_fix,nbr_var_fix); 00499 00500 /* Close first input netCDF file */ 00501 (void)nco_close(in_id); 00502 00503 /* Allocate and, if necesssary, initialize accumulation space for processed variables */ 00504 for(idx=0;idx<nbr_var_prc;idx++){ 00505 if(prg == ncra || prg == ncrcat){ 00506 /* Allocate space for only one record */ 00507 var_prc_out[idx]->sz=var_prc[idx]->sz=var_prc[idx]->sz_rec; 00508 } /* endif */ 00509 if(prg == ncra || prg == ncea){ 00510 var_prc_out[idx]->tally=var_prc[idx]->tally=(long *)nco_malloc(var_prc_out[idx]->sz*sizeof(long)); 00511 (void)nco_zero_long(var_prc_out[idx]->sz,var_prc_out[idx]->tally); 00512 var_prc_out[idx]->val.vp=(void *)nco_malloc(var_prc_out[idx]->sz*nco_typ_lng(var_prc_out[idx]->type)); 00513 (void)nco_var_zero(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->val); 00514 } /* end if */ 00515 } /* end loop over idx */ 00516 00517 /* Loop over input files */ 00518 for(fl_idx=0;fl_idx<fl_nbr;fl_idx++){ 00519 /* Parse filename */ 00520 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); 00521 if(dbg_lvl > 0) (void)fprintf(stderr,gettext("\nInput file %d is %s; "),fl_idx,fl_in); 00522 /* Make sure file is on local system and is readable or die trying */ 00523 if(fl_idx != 0) fl_in=nco_fl_mk_lcl(fl_in,fl_pth_lcl,&FILE_RETRIEVED_FROM_REMOTE_LOCATION); 00524 if(dbg_lvl > 0) (void)fprintf(stderr,gettext("local file %s:\n"),fl_in); 00525 00526 /* Open file once per thread to improve caching */ 00527 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd=nco_open(fl_in,NC_NOWRITE,in_id_arr+thr_idx); 00528 in_id=in_id_arr[0]; 00529 00530 /* Variables may have different ID, missing_value, type, in each file */ 00531 for(idx=0;idx<nbr_var_prc;idx++) (void)nco_var_mtd_refresh(in_id,var_prc[idx]); 00532 00533 /* Each file can have a different number of records to process 00534 NB: nco_lmt_evl() with same nc_id contains OpenMP critical region */ 00535 if(prg == ncra || prg == ncrcat) (void)nco_lmt_evl(in_id,lmt_rec,idx_rec_out,FORTRAN_IDX_CNV); 00536 00537 /* NB: arm_base_time_get() with same nc_id contains OpenMP critical region */ 00538 if(CNV_ARM) base_time_crr=arm_base_time_get(in_id); 00539 00540 /* Perform various error-checks on input file */ 00541 if(False) (void)nco_fl_cmp_err_chk(); 00542 00543 if(prg == ncra || prg == ncrcat){ /* ncea jumps to else branch */ 00544 /* Loop over each record in current file */ 00545 00546 if(lmt_rec->srt > lmt_rec->end) (void)fprintf(fp_stdout,gettext("%s: WARNING %s (input file %d) is superfluous\n"),prg_nm_get(),fl_in,fl_idx); 00547 00548 for(idx_rec=lmt_rec->srt;idx_rec<=lmt_rec->end;idx_rec+=lmt_rec->srd){ 00549 if(fl_idx == fl_nbr-1 && idx_rec >= 1L+lmt_rec->end-lmt_rec->srd) LAST_RECORD=True; 00550 /* Process all variables in current record */ 00551 if(dbg_lvl > 1) (void)fprintf(fp_stderr,gettext("Record %ld of %s is input record %ld\n"),idx_rec,fl_in,idx_rec_out); 00552 #ifdef _OPENMP 00553 #pragma omp parallel for default(none) private(idx,in_id) shared(CNV_ARM,base_time_crr,base_time_srt,dbg_lvl,fl_in,fl_out,fp_stderr,idx_rec,idx_rec_out,in_id_arr,LAST_RECORD,nbr_var_prc,nco_op_typ,out_id,prg,rcd,var_prc,var_prc_out) 00554 #endif /* !_OPENMP */ 00555 for(idx=0;idx<nbr_var_prc;idx++){ 00556 in_id=in_id_arr[omp_get_thread_num()]; 00557 if(dbg_lvl > 2) rcd+=nco_var_prc_crr_prn(idx,var_prc[idx]->nm); 00558 if(dbg_lvl > 0) (void)fflush(fp_stderr); 00559 /* Update hyperslab start indices to current record for each variable */ 00560 var_prc[idx]->srt[0]=idx_rec; 00561 var_prc[idx]->end[0]=idx_rec; 00562 var_prc[idx]->cnt[0]=1L; 00563 /* Retrieve variable from disk into memory */ 00564 /* NB: nco_var_get() with same nc_id contains OpenMP critical region */ 00565 (void)nco_var_get(in_id,var_prc[idx]); 00566 00567 if(prg == ncra){ 00568 /* Convert char, short, long, int types to doubles before arithmetic 00569 Output variable type is "sticky" so only convert on first record */ 00570 if(idx_rec_out == 0) var_prc_out[idx]=nco_typ_cnv_rth(var_prc_out[idx],nco_op_typ); 00571 var_prc[idx]=nco_var_cnf_typ(var_prc_out[idx]->type,var_prc[idx]); 00572 /* Perform arithmetic operations: avg, min, max, ttl, ... */ 00573 nco_opr_drv(idx_rec_out,nco_op_typ,var_prc[idx],var_prc_out[idx]); 00574 } /* end if ncra */ 00575 00576 /* Append current record to output file */ 00577 if(prg == ncrcat){ 00578 var_prc_out[idx]->srt[0]=var_prc_out[idx]->end[0]=idx_rec_out; 00579 var_prc_out[idx]->cnt[0]=1L; 00580 /* Replace this time_offset value with time_offset from initial file base_time */ 00581 if(CNV_ARM && !strcmp(var_prc[idx]->nm,"time_offset")) var_prc[idx]->val.dp[0]+=(base_time_crr-base_time_srt); 00582 #ifdef _OPENMP 00583 #pragma omp critical 00584 #endif /* _OPENMP */ 00585 if(var_prc_out[idx]->sz_rec > 1) (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_out[idx]->type); else (void)nco_put_var1(out_id,var_prc_out[idx]->id,var_prc_out[idx]->srt,var_prc[idx]->val.vp,var_prc_out[idx]->type); 00586 } /* end if ncrcat */ 00587 00588 /* Warn if record coordinate, if any, is not monotonic */ 00589 if(prg == ncrcat && var_prc[idx]->is_crd_var) (void)rec_crd_chk(var_prc[idx],fl_in,fl_out,idx_rec,idx_rec_out); 00590 /* Convert missing_value, if any, back to unpacked type 00591 Otherwise missing_value will be double-promoted when next record read 00592 Do not convert after last record otherwise normalization fails 00593 due to wrong missing_value type (needs promoted type, not unpacked type) */ 00594 if(var_prc[idx]->has_mss_val && var_prc[idx]->type != var_prc[idx]->typ_upk && !LAST_RECORD) var_prc[idx]=nco_cnv_mss_val_typ(var_prc[idx],var_prc[idx]->typ_upk); 00595 /* Free current input buffer */ 00596 var_prc[idx]->val.vp=nco_free(var_prc[idx]->val.vp); 00597 } /* end (OpenMP parallel for) loop over variables */ 00598 idx_rec_out++; /* [idx] Index of current record in output file (0 is first, ...) */ 00599 if(dbg_lvl > 2) (void)fprintf(fp_stderr,"\n"); 00600 } /* end loop over idx_rec */ 00601 /* Warn if fewer than number of requested records were read and final file has been processed */ 00602 if(lmt_rec->lmt_typ == lmt_dmn_idx && lmt_rec->is_usr_spc_min && lmt_rec->is_usr_spc_max){ 00603 long rec_nbr_rqs; /* Number of records user requested */ 00604 rec_nbr_rqs=1L+(lmt_rec->max_idx-lmt_rec->min_idx)/lmt_rec->srd; 00605 if(fl_idx == fl_nbr-1 && rec_nbr_rqs != idx_rec_out) (void)fprintf(fp_stdout,gettext("%s: WARNING User requested %li records but only %li were found\n"),prg_nm_get(),rec_nbr_rqs,idx_rec_out); 00606 } /* end if */ 00607 /* Error if no records were read and final file has been processed */ 00608 if(idx_rec_out <= 0 && fl_idx == fl_nbr-1){ 00609 (void)fprintf(fp_stdout,gettext("%s: ERROR No records lay within specified hyperslab\n"),prg_nm_get()); 00610 nco_exit(EXIT_FAILURE); 00611 } /* end if */ 00612 /* End of ncra, ncrcat section */ 00613 }else{ /* ncea */ 00614 #ifdef _OPENMP 00615 #pragma omp parallel for default(none) private(idx,in_id) shared(dbg_lvl,fl_idx,fp_stderr,in_id_arr,nbr_var_prc,nco_op_typ,rcd,var_prc,var_prc_out) 00616 #endif /* !_OPENMP */ 00617 for(idx=0;idx<nbr_var_prc;idx++){ /* Process all variables in current file */ 00618 in_id=in_id_arr[omp_get_thread_num()]; 00619 if(dbg_lvl > 0) rcd+=nco_var_prc_crr_prn(idx,var_prc[idx]->nm); 00620 if(dbg_lvl > 0) (void)fflush(fp_stderr); 00621 /* Retrieve variable from disk into memory */ 00622 (void)nco_var_get(in_id,var_prc[idx]); 00623 00624 /* Convert char, short, long, int types to doubles before arithmetic 00625 Output variable type is "sticky" so only convert on first record */ 00626 if(fl_idx == 0) var_prc_out[idx]=nco_typ_cnv_rth(var_prc_out[idx],nco_op_typ); 00627 var_prc[idx]=nco_var_cnf_typ(var_prc_out[idx]->type,var_prc[idx]); 00628 /* Perform arithmetic operations: avg, min, max, ttl, ... */ /* Note: fl_idx not idx_rec_out! */ 00629 nco_opr_drv(fl_idx,nco_op_typ,var_prc[idx],var_prc_out[idx]); 00630 00631 /* Free current input buffer */ 00632 var_prc[idx]->val.vp=nco_free(var_prc[idx]->val.vp); 00633 } /* end (OpenMP parallel for) loop over idx */ 00634 } /* end else ncea */ 00635 00636 if(dbg_lvl > 1) (void)fprintf(fp_stderr,"\n"); 00637 00638 /* Close input netCDF file */ 00639 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) nco_close(in_id_arr[thr_idx]); 00640 00641 /* Dispose local copy of file */ 00642 if(FILE_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in); 00643 00644 } /* end loop over fl_idx */ 00645 00646 /* Normalize, multiply, etc where necessary */ 00647 if(prg == ncra || prg == ncea){ 00648 #ifdef _OPENMP 00649 #pragma omp parallel for default(none) private(idx) shared(nbr_var_prc,nco_op_typ,var_prc,var_prc_out) 00650 #endif /* !_OPENMP */ 00651 for(idx=0;idx<nbr_var_prc;idx++){ 00652 switch(nco_op_typ) { 00653 case nco_op_avg: /* Normalize sum by tally to create mean */ 00654 case nco_op_sqrt: /* Normalize sum by tally to create mean */ 00655 case nco_op_sqravg: /* Normalize sum by tally to create mean */ 00656 case nco_op_rms: /* Normalize sum of squares by tally to create mean square */ 00657 case nco_op_avgsqr: /* Normalize sum of squares by tally to create mean square */ 00658 (void)nco_var_nrm(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc[idx]->has_mss_val,var_prc[idx]->mss_val,var_prc[idx]->tally,var_prc_out[idx]->val); 00659 break; 00660 case nco_op_rmssdn: /* Normalize sum of squares by tally-1 to create mean square for sdn */ 00661 (void)nco_var_nrm_sdn(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc[idx]->has_mss_val,var_prc[idx]->mss_val,var_prc[idx]->tally,var_prc_out[idx]->val); 00662 break; 00663 case nco_op_min: /* Minimum is already in buffer, do nothing */ 00664 case nco_op_max: /* Maximum is already in buffer, do nothing */ 00665 case nco_op_ttl: /* Total is already in buffer, do nothing */ 00666 default: 00667 break; 00668 } /* end switch */ 00669 /* Some operations require additional processing */ 00670 switch(nco_op_typ) { 00671 case nco_op_rms: /* Take root of mean of sum of squares to create root mean square */ 00672 case nco_op_rmssdn: /* Take root of sdn mean of sum of squares to create root mean square for sdn */ 00673 case nco_op_sqrt: /* Take root of mean to create root mean */ 00674 (void)nco_var_sqrt(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc[idx]->has_mss_val,var_prc[idx]->mss_val,var_prc[idx]->tally,var_prc_out[idx]->val,var_prc_out[idx]->val); 00675 break; 00676 case nco_op_sqravg: /* Square mean to create square of the mean (for sdn) */ 00677 (void)nco_var_mlt(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->has_mss_val,var_prc_out[idx]->mss_val,var_prc_out[idx]->val,var_prc_out[idx]->val); 00678 break; 00679 default: 00680 break; 00681 } /* end switch */ 00682 var_prc_out[idx]->tally=var_prc[idx]->tally=(long *)nco_free(var_prc[idx]->tally); 00683 } /* end (OpenMP parallel for) loop over variables */ 00684 } /* end if */ 00685 00686 /* Manually fix YYMMDD date which was mangled by averaging */ 00687 if(CNV_CCM_CCSM_CF && prg == ncra) (void)nco_cnv_ccm_ccsm_cf_date(out_id,var_out,nbr_xtr); 00688 00689 /* Add time variable to output file 00690 NB: arm_time_install() contains OpenMP critical region */ 00691 if(CNV_ARM && prg == ncrcat) (void)nco_arm_time_install(out_id,base_time_srt); 00692 00693 /* Copy averages to output file and free averaging buffers */ 00694 if(prg == ncra || prg == ncea){ 00695 for(idx=0;idx<nbr_var_prc;idx++){ 00696 /* Revert any arithmetic promotion but leave unpacking (for now) */ 00697 var_prc_out[idx]=nco_var_cnf_typ(var_prc_out[idx]->typ_upk,var_prc_out[idx]); 00698 /* Packing/Unpacking */ 00699 if(nco_pck_plc == nco_pck_plc_all_new_att) var_prc_out[idx]=nco_put_var_pck(out_id,var_prc_out[idx],nco_pck_plc); 00700 if(var_prc_out[idx]->nbr_dim == 0){ 00701 (void)nco_put_var1(out_id,var_prc_out[idx]->id,var_prc_out[idx]->srt,var_prc_out[idx]->val.vp,var_prc_out[idx]->type); 00702 }else{ /* end if variable is a scalar */ 00703 /* Size of record dimension is 1 in output file */ 00704 if(prg == ncra) var_prc_out[idx]->cnt[0]=1L; 00705 (void)nco_put_vara(out_id,var_prc_out[idx]->id,var_prc_out[idx]->srt,var_prc_out[idx]->cnt,var_prc_out[idx]->val.vp,var_prc_out[idx]->type); 00706 } /* end if variable is an array */ 00707 var_prc_out[idx]->val.vp=nco_free(var_prc_out[idx]->val.vp); 00708 } /* end loop over idx */ 00709 } /* end if */ 00710 00711 /* Close output file and move it from temporary to permanent location */ 00712 (void)nco_fl_out_cls(fl_out,fl_out_tmp,out_id); 00713 00714 /* ncra-specific memory cleanup */ 00715 if(prg == ncra || prg == ncrcat) lmt_rec=nco_lmt_free(lmt_rec); 00716 00717 /* NCO-generic clean-up */ 00718 /* Free individual strings/arrays */ 00719 if(cmd_ln != NULL) cmd_ln=(char *)nco_free(cmd_ln); 00720 if(fl_in != NULL) fl_in=(char *)nco_free(fl_in); 00721 if(fl_out != NULL) fl_out=(char *)nco_free(fl_out); 00722 if(fl_out_tmp != NULL) fl_out_tmp=(char *)nco_free(fl_out_tmp); 00723 if(fl_pth != NULL) fl_pth=(char *)nco_free(fl_pth); 00724 if(fl_pth_lcl != NULL) fl_pth_lcl=(char *)nco_free(fl_pth_lcl); 00725 if(in_id_arr != NULL) in_id_arr=(int *)nco_free(in_id_arr); 00726 /* Free lists of strings */ 00727 if(fl_lst_in != NULL && fl_lst_abb == NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,fl_nbr); 00728 if(fl_lst_in != NULL && fl_lst_abb != NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,1); 00729 if(fl_lst_abb != NULL) fl_lst_abb=nco_sng_lst_free(fl_lst_abb,abb_arg_nbr); 00730 if(var_lst_in_nbr > 0) var_lst_in=nco_sng_lst_free(var_lst_in,var_lst_in_nbr); 00731 /* Free limits */ 00732 for(idx=0;idx<lmt_nbr;idx++) lmt_arg[idx]=(char *)nco_free(lmt_arg[idx]); 00733 if(lmt_nbr > 0) lmt=nco_lmt_lst_free(lmt,lmt_nbr); 00734 /* Free dimension lists */ 00735 if(nbr_dmn_xtr > 0) dim=nco_dmn_lst_free(dim,nbr_dmn_xtr); 00736 if(nbr_dmn_xtr > 0) dmn_out=nco_dmn_lst_free(dmn_out,nbr_dmn_xtr); 00737 /* Free variable lists */ 00738 if(nbr_xtr > 0) var=nco_var_lst_free(var,nbr_xtr); 00739 if(nbr_xtr > 0) var_out=nco_var_lst_free(var_out,nbr_xtr); 00740 var_prc=(var_sct **)nco_free(var_prc); 00741 var_prc_out=(var_sct **)nco_free(var_prc_out); 00742 var_fix=(var_sct **)nco_free(var_fix); 00743 var_fix_out=(var_sct **)nco_free(var_fix_out); 00744 00745 nco_exit_gracefully(); 00746 return EXIT_SUCCESS; 00747 } /* end main() */
|
1.4.4