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

Go to the source code of this file.
Defines | |
| #define | MAIN_PROGRAM_FILE |
Functions | |
| int | main (int argc, char **argv) |
|
|
|
|
||||||||||||
|
Definition at line 68 of file ncflint.c. References copyright_prn(), val_unn::d, double_CEWI, ptr_unn::dp, EXIT_FAILURE, EXIT_SUCCESS, False, FILE, getopt_long, var_sct_tag::has_mss_val, int_CEWI, lst_prs_2D(), var_sct_tag::mss_val, option::name, var_sct_tag::nbr_dim, NC_DOUBLE, NC_FORMAT_64BIT, NC_FORMAT_CLASSIC, NC_FORMAT_NETCDF4, NC_GLOBAL, 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_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_inq_varid(), 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_mss_val_cnf(), 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_set_fill(), nco_sng_lst_free(), nco_thr_att_cat(), nco_usg_prn(), nco_var_add_tll_ncflint(), nco_var_cnf_dmn(), nco_var_cnf_typ(), nco_var_dfn(), nco_var_dpl(), nco_var_dvd(), nco_var_fll(), nco_var_free(), 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_sbt(), nco_var_srt_zero(), nco_var_val_cpy(), nco_xrf_dmn(), nco_xrf_var(), nco_zero_long(), no_argument, NULL_CEWI, omp_get_thread_num(), optarg, optind, prg_nm_get(), prg_prs(), required_argument, scl_mk_var(), var_sct_tag::sz, var_sct_tag::tally, True, type, var_sct_tag::type, option::val, and var_sct_tag::val. 00069 { 00070 nco_bool CMD_LN_NTP_VAR=False; /* Option i */ 00071 nco_bool CMD_LN_NTP_WGT=True; /* Option w */ 00072 nco_bool DO_CONFORM=False; /* Did nco_var_cnf_dmn() find truly conforming variables? */ 00073 nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */ 00074 nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */ 00075 nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */ 00076 nco_bool FILE_1_RETRIEVED_FROM_REMOTE_LOCATION; 00077 nco_bool FILE_2_RETRIEVED_FROM_REMOTE_LOCATION; 00078 nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */ 00079 nco_bool FORCE_APPEND=False; /* Option A */ 00080 nco_bool FORCE_OVERWRITE=False; /* Option O */ 00081 nco_bool FORTRAN_IDX_CNV=False; /* Option F */ 00082 nco_bool HISTORY_APPEND=True; /* Option h */ 00083 nco_bool MUST_CONFORM=False; /* Must nco_var_cnf_dmn() find truly conforming variables? */ 00084 nco_bool CNV_CCM_CCSM_CF; 00085 nco_bool REMOVE_REMOTE_FILES_AFTER_PROCESSING=True; /* Option R */ 00086 00087 char **fl_lst_abb=NULL; /* Option a */ 00088 char **fl_lst_in; 00089 char **ntp_lst_in; 00090 char **var_lst_in=NULL_CEWI; 00091 char *cmd_ln; 00092 char *fl_in_1=NULL; /* fl_in_1 is nco_realloc'd when not NULL */; 00093 char *fl_in_2=NULL; /* fl_in_2 is nco_realloc'd when not NULL */; 00094 char *fl_out=NULL; /* Option o */ 00095 char *fl_out_tmp; 00096 char *fl_pth=NULL; /* Option p */ 00097 char *fl_pth_lcl=NULL; /* Option l */ 00098 char *lmt_arg[NC_MAX_DIMS]; 00099 char *ntp_nm=NULL; /* Option i */ 00100 char *opt_crr=NULL; /* [sng] String representation of current long-option name */ 00101 char *optarg_lcl=NULL; /* [sng] Local copy of system optarg */ 00102 char *time_bfr_srt; 00103 00104 const char * const CVS_Id="$Id: ncflint.c,v 1.118 2006/02/26 07:41:55 zender Exp $"; 00105 const char * const CVS_Revision="$Revision: 1.118 $"; 00106 const char * const opt_sht_lst="4ACcD:d:Fhi:l:Oo:p:rRt:v:xw:-:"; 00107 00108 dmn_sct **dim; 00109 dmn_sct **dmn_out; 00110 00111 double ntp_val_out=double_CEWI; /* Option i */ 00112 double wgt_val_1=0.5; /* Option w */ 00113 double wgt_val_2=0.5; /* Option w */ 00114 00115 extern char *optarg; 00116 extern int optind; 00117 00118 /* Using naked stdin/stdout/stderr in parallel region generates warning 00119 Copy appropriate filehandle to variable scoped shared in parallel clause */ 00120 FILE * const fp_stderr=stderr; /* [fl] stderr filehandle CEWI */ 00121 00122 int *in_id_1_arr; 00123 int *in_id_2_arr; 00124 00125 int abb_arg_nbr=0; 00126 int fl_idx; 00127 int fl_nbr=0; 00128 int fl_out_fmt=NC_FORMAT_CLASSIC; /* [enm] Output file format */ 00129 int fll_md_old; /* [enm] Old fill mode */ 00130 int has_mss_val=False; 00131 int idx; 00132 int in_id_1; 00133 int in_id_2; 00134 int lmt_nbr=0; /* Option d. NB: lmt_nbr gets incremented */ 00135 int nbr_dmn_fl; 00136 int nbr_dmn_xtr; 00137 int nbr_ntp; 00138 int nbr_var_fix; /* nbr_var_fix gets incremented */ 00139 int nbr_var_fl; 00140 int nbr_var_prc; /* nbr_var_prc gets incremented */ 00141 int nbr_xtr=0; /* nbr_xtr won't otherwise be set for -c with no -v */ 00142 int opt; 00143 int out_id; 00144 int rcd=NC_NOERR; /* [rcd] Return code */ 00145 int thr_idx; /* [idx] Index of current thread */ 00146 int thr_nbr=int_CEWI; /* [nbr] Thread number Option t */ 00147 int var_lst_in_nbr=0; 00148 00149 lmt_sct **lmt; 00150 00151 nm_id_sct *dmn_lst; 00152 nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */ 00153 00154 time_t time_crr_time_t; 00155 00156 val_unn val_gnr_unn; /* Generic container for arrival point or weight */ 00157 00158 var_sct *wgt_1=NULL_CEWI; 00159 var_sct *wgt_2=NULL_CEWI; 00160 var_sct *wgt_out_1=NULL; 00161 var_sct *wgt_out_2=NULL; 00162 var_sct **var; 00163 var_sct **var_fix; 00164 var_sct **var_fix_out; 00165 var_sct **var_out; 00166 var_sct **var_prc_1; 00167 var_sct **var_prc_2; 00168 var_sct **var_prc_out; 00169 00170 static struct option opt_lng[]= 00171 { /* Structure ordered by short option key if possible */ 00172 /* Long options with no argument, no short option counterpart */ 00173 /* Long options with argument, no short option counterpart */ 00174 {"fl_fmt",required_argument,0,0}, 00175 {"file_format",required_argument,0,0}, 00176 /* Long options with short counterparts */ 00177 {"4",no_argument,0,'4'}, 00178 {"64bit",no_argument,0,'4'}, 00179 {"netcdf4",no_argument,0,'4'}, 00180 {"append",no_argument,0,'A'}, 00181 {"coords",no_argument,0,'c'}, 00182 {"crd",no_argument,0,'c'}, 00183 {"no-coords",no_argument,0,'C'}, 00184 {"no-crd",no_argument,0,'C'}, 00185 {"debug",required_argument,0,'D'}, 00186 {"dbg_lvl",required_argument,0,'D'}, 00187 {"dimension",required_argument,0,'d'}, 00188 {"dmn",required_argument,0,'d'}, 00189 {"fortran",no_argument,0,'F'}, 00190 {"ftn",no_argument,0,'F'}, 00191 {"history",no_argument,0,'h'}, 00192 {"hst",no_argument,0,'h'}, 00193 {"interpolate",required_argument,0,'i'}, 00194 {"ntp",required_argument,0,'i'}, 00195 {"local",required_argument,0,'l'}, 00196 {"lcl",required_argument,0,'l'}, 00197 {"overwrite",no_argument,0,'O'}, 00198 {"ovr",no_argument,0,'O'}, 00199 {"output",required_argument,0,'o'}, 00200 {"fl_out",required_argument,0,'o'}, 00201 {"path",required_argument,0,'p'}, 00202 {"retain",no_argument,0,'R'}, 00203 {"rtn",no_argument,0,'R'}, 00204 {"revision",no_argument,0,'r'}, 00205 {"thr_nbr",required_argument,0,'t'}, 00206 {"variable",required_argument,0,'v'}, 00207 {"version",no_argument,0,'r'}, 00208 {"vrs",no_argument,0,'r'}, 00209 {"weight",required_argument,0,'w'}, 00210 {"wgt_var",no_argument,0,'w'}, 00211 {"help",no_argument,0,'?'}, 00212 {0,0,0,0} 00213 }; /* end opt_lng */ 00214 int opt_idx=0; /* Index of current long option into opt_lng array */ 00215 00216 /* Start clock and save command line */ 00217 cmd_ln=nco_cmd_ln_sng(argc,argv); 00218 time_crr_time_t=time((time_t *)NULL); 00219 time_bfr_srt=ctime(&time_crr_time_t); time_bfr_srt=time_bfr_srt; /* Avoid compiler warning until variable is used for something */ 00220 00221 /* Get program name and set program enum (e.g., prg=ncra) */ 00222 prg_nm=prg_prs(argv[0],&prg); 00223 00224 /* Parse command line arguments */ 00225 while(1){ 00226 /* getopt_long_only() allows one dash to prefix long options */ 00227 opt=getopt_long(argc,argv,opt_sht_lst,opt_lng,&opt_idx); 00228 /* NB: access to opt_crr is only valid when long_opt is detected */ 00229 if(opt == EOF) break; /* Parse positional arguments once getopt_long() returns EOF */ 00230 opt_crr=(char *)strdup(opt_lng[opt_idx].name); 00231 00232 /* Process long options without short option counterparts */ 00233 if(opt == 0){ 00234 if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt); 00235 } /* opt != 0 */ 00236 /* Process short options */ 00237 switch(opt){ 00238 case 0: /* Long options have already been processed, return */ 00239 break; 00240 case '4': /* [flg] Catch-all to prescribe output storage format */ 00241 if(!strcmp(opt_crr,"64bit")) fl_out_fmt=NC_FORMAT_64BIT; else fl_out_fmt=NC_FORMAT_NETCDF4; 00242 break; 00243 case 'A': /* Toggle FORCE_APPEND */ 00244 FORCE_APPEND=!FORCE_APPEND; 00245 break; 00246 case 'C': /* Extract all coordinates associated with extracted variables? */ 00247 EXTRACT_ASSOCIATED_COORDINATES=False; 00248 break; 00249 case 'c': 00250 EXTRACT_ALL_COORDINATES=True; 00251 break; 00252 case 'D': /* The debugging level. Default is 0. */ 00253 dbg_lvl=(unsigned short)strtol(optarg,(char **)NULL,10); 00254 break; 00255 case 'd': /* Copy argument for later processing */ 00256 lmt_arg[lmt_nbr]=(char *)strdup(optarg); 00257 lmt_nbr++; 00258 break; 00259 case 'F': /* Toggle index convention. Default is 0-based arrays (C-style). */ 00260 FORTRAN_IDX_CNV=!FORTRAN_IDX_CNV; 00261 break; 00262 case 'h': /* Toggle appending to history global attribute */ 00263 HISTORY_APPEND=!HISTORY_APPEND; 00264 break; 00265 case 'i': 00266 /* Name of variable to guide interpolation. Default is none */ 00267 ntp_lst_in=lst_prs_2D(optarg,",",&nbr_ntp); 00268 if(nbr_ntp > 2){ 00269 (void)fprintf(stdout,"%s: ERROR too many arguments to -i\n",prg_nm_get()); 00270 (void)nco_usg_prn(); 00271 nco_exit(EXIT_FAILURE); 00272 } /* end if */ 00273 ntp_nm=ntp_lst_in[0]; 00274 ntp_val_out=strtod(ntp_lst_in[1],(char **)NULL); 00275 CMD_LN_NTP_VAR=True; 00276 CMD_LN_NTP_WGT=False; 00277 break; 00278 case 'l': /* Local path prefix for files retrieved from remote file system */ 00279 fl_pth_lcl=(char *)strdup(optarg); 00280 break; 00281 case 'O': /* Toggle FORCE_OVERWRITE */ 00282 FORCE_OVERWRITE=!FORCE_OVERWRITE; 00283 break; 00284 case 'o': /* Name of output file */ 00285 fl_out=(char *)strdup(optarg); 00286 break; 00287 case 'p': /* Common file path */ 00288 fl_pth=(char *)strdup(optarg); 00289 break; 00290 case 'R': /* Toggle removal of remotely-retrieved-files. Default is True. */ 00291 REMOVE_REMOTE_FILES_AFTER_PROCESSING=!REMOVE_REMOTE_FILES_AFTER_PROCESSING; 00292 break; 00293 case 'r': /* Print CVS program information and copyright notice */ 00294 (void)copyright_prn(CVS_Id,CVS_Revision); 00295 (void)nco_lbr_vrs_prn(); 00296 nco_exit(EXIT_SUCCESS); 00297 break; 00298 case 't': /* Thread number */ 00299 thr_nbr=(int)strtol(optarg,(char **)NULL,10); 00300 break; 00301 case 'v': /* Variables to extract/exclude */ 00302 /* Replace commas with hashes when within braces (convert back later) */ 00303 optarg_lcl=(char *)strdup(optarg); 00304 (void)nco_lst_comma2hash(optarg_lcl); 00305 var_lst_in=lst_prs_2D(optarg_lcl,",",&var_lst_in_nbr); 00306 optarg_lcl=(char *)nco_free(optarg_lcl); 00307 nbr_xtr=var_lst_in_nbr; 00308 break; 00309 case 'w': 00310 /* Weight(s) for interpolation. Default is wgt_val_1=wgt_val_2=0.5 */ 00311 ntp_lst_in=lst_prs_2D(optarg,",",&nbr_ntp); 00312 if(nbr_ntp > 2){ 00313 (void)fprintf(stdout,"%s: ERROR too many arguments to -w\n",prg_nm_get()); 00314 (void)nco_usg_prn(); 00315 nco_exit(EXIT_FAILURE); 00316 }else if(nbr_ntp == 2){ 00317 wgt_val_1=strtod(ntp_lst_in[0],(char **)NULL); 00318 wgt_val_2=strtod(ntp_lst_in[1],(char **)NULL); 00319 }else if(nbr_ntp == 1){ 00320 wgt_val_1=strtod(ntp_lst_in[0],(char **)NULL); 00321 wgt_val_2=1.0-wgt_val_1; 00322 } /* end else */ 00323 CMD_LN_NTP_WGT=True; 00324 break; 00325 case 'x': /* Exclude rather than extract variables specified with -v */ 00326 EXCLUDE_INPUT_LIST=True; 00327 break; 00328 case '?': /* Print proper usage */ 00329 (void)nco_usg_prn(); 00330 nco_exit(EXIT_SUCCESS); 00331 break; 00332 case '-': /* Long options are not allowed */ 00333 (void)fprintf(stderr,"%s: ERROR Long options are not available in this build. Use single letter options instead.\n",prg_nm_get()); 00334 nco_exit(EXIT_FAILURE); 00335 break; 00336 default: /* Print proper usage */ 00337 (void)nco_usg_prn(); 00338 nco_exit(EXIT_FAILURE); 00339 break; 00340 } /* end switch */ 00341 if(opt_crr != NULL) opt_crr=(char *)nco_free(opt_crr); 00342 } /* end while loop */ 00343 00344 if(CMD_LN_NTP_VAR && CMD_LN_NTP_WGT){ 00345 (void)fprintf(stdout,"%s: ERROR interpolating variable (-i) and fixed weight(s) (-w) both set\n",prg_nm_get()); 00346 nco_exit(EXIT_FAILURE); 00347 }else if(!CMD_LN_NTP_VAR && !CMD_LN_NTP_WGT){ 00348 (void)fprintf(stdout,"%s: ERROR interpolating variable (-i) or fixed weight(s) (-w) must be set\n",prg_nm_get()); 00349 nco_exit(EXIT_FAILURE); 00350 } /* end else */ 00351 00352 /* Process positional arguments and fill in filenames */ 00353 fl_lst_in=nco_fl_lst_mk(argv,argc,optind,&fl_nbr,&fl_out,&FL_LST_IN_FROM_STDIN); 00354 00355 /* Make uniform list of user-specified dimension limits */ 00356 lmt=nco_lmt_prs(lmt_nbr,lmt_arg); 00357 00358 /* Initialize thread information */ 00359 thr_nbr=nco_openmp_ini(thr_nbr); 00360 in_id_1_arr=(int *)nco_malloc(thr_nbr*sizeof(int)); 00361 in_id_2_arr=(int *)nco_malloc(thr_nbr*sizeof(int)); 00362 00363 /* Parse filenames */ 00364 fl_idx=0; /* Input file _1 */ 00365 fl_in_1=nco_fl_nm_prs(fl_in_1,fl_idx,&fl_nbr,fl_lst_in,abb_arg_nbr,fl_lst_abb,fl_pth); 00366 if(dbg_lvl > 0) (void)fprintf(stderr,"\nInput file %d is %s; ",fl_idx,fl_in_1); 00367 /* Make sure file is on local system and is readable or die trying */ 00368 fl_in_1=nco_fl_mk_lcl(fl_in_1,fl_pth_lcl,&FILE_1_RETRIEVED_FROM_REMOTE_LOCATION); 00369 if(dbg_lvl > 0) (void)fprintf(stderr,"local file %s:\n",fl_in_1); 00370 /* Open file once per thread to improve caching */ 00371 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd=nco_open(fl_in_1,NC_NOWRITE,in_id_1_arr+thr_idx); 00372 in_id_1=in_id_1_arr[0]; 00373 00374 fl_idx=1; /* Input file _2 */ 00375 fl_in_2=nco_fl_nm_prs(fl_in_2,fl_idx,&fl_nbr,fl_lst_in,abb_arg_nbr,fl_lst_abb,fl_pth); 00376 if(dbg_lvl > 0) (void)fprintf(stderr,"\nInput file %d is %s; ",fl_idx,fl_in_2); 00377 /* Make sure file is on local system and is readable or die trying */ 00378 fl_in_2=nco_fl_mk_lcl(fl_in_2,fl_pth_lcl,&FILE_2_RETRIEVED_FROM_REMOTE_LOCATION); 00379 if(dbg_lvl > 0) (void)fprintf(stderr,"local file %s:\n",fl_in_2); 00380 /* Open file once per thread to improve caching */ 00381 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd=nco_open(fl_in_2,NC_NOWRITE,in_id_2_arr+thr_idx); 00382 in_id_2=in_id_2_arr[0]; 00383 00384 /* Get number of variables and dimensions in file */ 00385 (void)nco_inq(in_id_1,&nbr_dmn_fl,&nbr_var_fl,(int *)NULL,(int *)NULL); 00386 00387 /* Form initial extraction list which may include extended regular expressions */ 00388 xtr_lst=nco_var_lst_mk(in_id_1,nbr_var_fl,var_lst_in,EXTRACT_ALL_COORDINATES,&nbr_xtr); 00389 00390 /* Change included variables to excluded variables */ 00391 if(EXCLUDE_INPUT_LIST) xtr_lst=nco_var_lst_xcl(in_id_1,nbr_var_fl,xtr_lst,&nbr_xtr); 00392 00393 /* Add all coordinate variables to extraction list */ 00394 if(EXTRACT_ALL_COORDINATES) xtr_lst=nco_var_lst_add_crd(in_id_1,nbr_dmn_fl,xtr_lst,&nbr_xtr); 00395 00396 /* Make sure coordinates associated extracted variables are also on extraction list */ 00397 if(EXTRACT_ASSOCIATED_COORDINATES) xtr_lst=nco_var_lst_ass_crd_add(in_id_1,xtr_lst,&nbr_xtr); 00398 00399 /* Sort extraction list by variable ID for fastest I/O */ 00400 if(nbr_xtr > 1) xtr_lst=nco_lst_srt_nm_id(xtr_lst,nbr_xtr,False); 00401 00402 /* We now have final list of variables to extract. Phew. */ 00403 00404 /* Find coordinate/dimension values associated with user-specified limits 00405 NB: nco_lmt_evl() with same nc_id contains OpenMP critical region */ 00406 for(idx=0;idx<lmt_nbr;idx++) (void)nco_lmt_evl(in_id_1,lmt[idx],0L,FORTRAN_IDX_CNV); 00407 00408 /* Find dimensions associated with variables to be extracted */ 00409 dmn_lst=nco_dmn_lst_ass_var(in_id_1,xtr_lst,nbr_xtr,&nbr_dmn_xtr); 00410 00411 /* Fill in dimension structure for all extracted dimensions */ 00412 dim=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *)); 00413 for(idx=0;idx<nbr_dmn_xtr;idx++) dim[idx]=nco_dmn_fll(in_id_1,dmn_lst[idx].id,dmn_lst[idx].nm); 00414 /* Dimension list no longer needed */ 00415 dmn_lst=nco_nm_id_lst_free(dmn_lst,nbr_dmn_xtr); 00416 00417 /* Merge hyperslab limit information into dimension structures */ 00418 if(lmt_nbr > 0) (void)nco_dmn_lmt_mrg(dim,nbr_dmn_xtr,lmt,lmt_nbr); 00419 00420 /* Duplicate input dimension structures for output dimension structures */ 00421 dmn_out=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *)); 00422 for(idx=0;idx<nbr_dmn_xtr;idx++){ 00423 dmn_out[idx]=nco_dmn_dpl(dim[idx]); 00424 (void)nco_dmn_xrf(dim[idx],dmn_out[idx]); 00425 } /* end loop over idx */ 00426 00427 /* Is this an CCM/CCSM/CF-format history tape? */ 00428 CNV_CCM_CCSM_CF=nco_cnv_ccm_ccsm_cf_inq(in_id_1); 00429 00430 /* Fill in variable structure list for all extracted variables */ 00431 var=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *)); 00432 var_out=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *)); 00433 for(idx=0;idx<nbr_xtr;idx++){ 00434 var[idx]=nco_var_fll(in_id_1,xtr_lst[idx].id,xtr_lst[idx].nm,dim,nbr_dmn_xtr); 00435 var_out[idx]=nco_var_dpl(var[idx]); 00436 (void)nco_xrf_var(var[idx],var_out[idx]); 00437 (void)nco_xrf_dmn(var_out[idx]); 00438 } /* end loop over idx */ 00439 /* Extraction list no longer needed */ 00440 xtr_lst=nco_nm_id_lst_free(xtr_lst,nbr_xtr); 00441 00442 /* Divide variable lists into lists of fixed variables and variables to be processed */ 00443 (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_1,&var_prc_out,&nbr_var_prc); 00444 00445 /* Open output file */ 00446 fl_out_tmp=nco_fl_out_open(fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&out_id); 00447 00448 /* Copy global attributes */ 00449 (void)nco_att_cpy(in_id_1,out_id,NC_GLOBAL,NC_GLOBAL,True); 00450 00451 /* Catenate time-stamped command line to "history" global attribute */ 00452 if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln); 00453 00454 if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr); 00455 00456 /* Define dimensions in output file */ 00457 (void)nco_dmn_dfn(fl_out,out_id,dmn_out,nbr_dmn_xtr); 00458 00459 /* Define variables in output file, copy their attributes */ 00460 (void)nco_var_dfn(in_id_1,fl_out,out_id,var_out,nbr_xtr,(dmn_sct **)NULL,(int)0,nco_pck_plc_nil,nco_pck_map_nil); 00461 00462 /* Turn off default filling behavior to enhance efficiency */ 00463 rcd=nco_set_fill(out_id,NC_NOFILL,&fll_md_old); 00464 00465 /* Take output file out of define mode */ 00466 (void)nco_enddef(out_id); 00467 00468 /* Zero start vectors for all output variables */ 00469 (void)nco_var_srt_zero(var_out,nbr_xtr); 00470 00471 /* Copy variable data for non-processed variables */ 00472 (void)nco_var_val_cpy(in_id_1,out_id,var_fix,nbr_var_fix); 00473 00474 /* Perform various error-checks on input file */ 00475 if(False) (void)nco_fl_cmp_err_chk(); 00476 00477 /* ncflint-specific stuff: */ 00478 /* Find the weighting variable in input file */ 00479 if(CMD_LN_NTP_VAR){ 00480 int ntp_id_1; 00481 int ntp_id_2; 00482 00483 var_sct *ntp_1; 00484 var_sct *ntp_2; 00485 var_sct *ntp_var_out; 00486 00487 /* Turn arrival point into pseudo-variable */ 00488 val_gnr_unn.d=ntp_val_out; /* Generic container for arrival point or weight */ 00489 ntp_var_out=scl_mk_var(val_gnr_unn,NC_DOUBLE); 00490 00491 rcd=nco_inq_varid(in_id_1,ntp_nm,&ntp_id_1); 00492 rcd=nco_inq_varid(in_id_2,ntp_nm,&ntp_id_2); 00493 00494 ntp_1=nco_var_fll(in_id_1,ntp_id_1,ntp_nm,dim,nbr_dmn_xtr); 00495 ntp_2=nco_var_fll(in_id_2,ntp_id_2,ntp_nm,dim,nbr_dmn_xtr); 00496 00497 /* Currently, only support scalar variables */ 00498 if(ntp_1->sz > 1 || ntp_2->sz > 1){ 00499 (void)fprintf(stdout,"%s: ERROR interpolation variable %s must be scalar\n",prg_nm_get(),ntp_nm); 00500 nco_exit(EXIT_FAILURE); 00501 } /* end if */ 00502 00503 /* Retrieve interpolation variable */ 00504 /* NB: nco_var_get() with same nc_id contains OpenMP critical region */ 00505 (void)nco_var_get(in_id_1,ntp_1); 00506 (void)nco_var_get(in_id_2,ntp_2); 00507 00508 /* Weights must be NC_DOUBLE */ 00509 ntp_1=nco_var_cnf_typ((nc_type)NC_DOUBLE,ntp_1); 00510 ntp_2=nco_var_cnf_typ((nc_type)NC_DOUBLE,ntp_2); 00511 00512 /* Check for degenerate case */ 00513 if(ntp_1->val.dp[0] == ntp_2->val.dp[0]){ 00514 (void)fprintf(stdout,"%s: ERROR Interpolation variable %s is identical (%g) in input files, therefore unable to interpolate.\n",prg_nm_get(),ntp_nm,ntp_1->val.dp[0]); 00515 nco_exit(EXIT_FAILURE); 00516 } /* end if */ 00517 00518 /* Turn weights into pseudo-variables */ 00519 wgt_1=nco_var_dpl(ntp_2); 00520 wgt_2=nco_var_dpl(ntp_var_out); 00521 00522 /* Subtract to find interpolation distances */ 00523 (void)nco_var_sbt(ntp_1->type,ntp_1->sz,ntp_1->has_mss_val,ntp_1->mss_val,ntp_var_out->val,wgt_1->val); 00524 (void)nco_var_sbt(ntp_1->type,ntp_1->sz,ntp_1->has_mss_val,ntp_1->mss_val,ntp_1->val,wgt_2->val); 00525 (void)nco_var_sbt(ntp_1->type,ntp_1->sz,ntp_1->has_mss_val,ntp_1->mss_val,ntp_1->val,ntp_2->val); 00526 00527 /* Normalize to obtain final interpolation weights */ 00528 (void)nco_var_dvd(wgt_1->type,wgt_1->sz,wgt_1->has_mss_val,wgt_1->mss_val,ntp_2->val,wgt_1->val); 00529 (void)nco_var_dvd(wgt_2->type,wgt_2->sz,wgt_2->has_mss_val,wgt_2->mss_val,ntp_2->val,wgt_2->val); 00530 00531 if(ntp_1 != NULL) ntp_1=nco_var_free(ntp_1); 00532 if(ntp_2 != NULL) ntp_2=nco_var_free(ntp_2); 00533 if(ntp_var_out != NULL) ntp_var_out=nco_var_free(ntp_var_out); 00534 } /* end if CMD_LN_NTP_VAR */ 00535 00536 if(CMD_LN_NTP_WGT){ 00537 val_gnr_unn.d=wgt_val_1; /* Generic container for arrival point or weight */ 00538 wgt_1=scl_mk_var(val_gnr_unn,NC_DOUBLE); 00539 val_gnr_unn.d=wgt_val_2; /* Generic container for arrival point or weight */ 00540 wgt_2=scl_mk_var(val_gnr_unn,NC_DOUBLE); 00541 } /* end if CMD_LN_NTP_WGT */ 00542 00543 if(dbg_lvl > 1) (void)fprintf(stderr,"wgt_1 = %g, wgt_2 = %g\n",wgt_1->val.dp[0],wgt_2->val.dp[0]); 00544 00545 /* Create structure list for second file */ 00546 var_prc_2=(var_sct **)nco_malloc(nbr_var_prc*sizeof(var_sct *)); 00547 00548 /* Loop over each interpolated variable */ 00549 #ifdef _OPENMP 00550 /* OpenMP notes: 00551 shared(): msk and wgt are not altered within loop 00552 private(): wgt_avg does not need initialization */ 00553 #pragma omp parallel for default(none) firstprivate(wgt_1,wgt_2,wgt_out_1,wgt_out_2) private(DO_CONFORM,MUST_CONFORM,idx,in_id_1,in_id_2,has_mss_val) shared(dbg_lvl,dim,fl_in_1,fl_in_2,fl_out,fp_stderr,in_id_1_arr,in_id_2_arr,nbr_dmn_xtr,nbr_var_prc,out_id,prg_nm,var_prc_1,var_prc_2,var_prc_out) 00554 #endif /* !_OPENMP */ 00555 for(idx=0;idx<nbr_var_prc;idx++){ 00556 if(dbg_lvl > 0) (void)fprintf(fp_stderr,"%s, ",var_prc_1[idx]->nm); 00557 if(dbg_lvl > 0) (void)fflush(fp_stderr); 00558 00559 in_id_1=in_id_1_arr[omp_get_thread_num()]; 00560 in_id_2=in_id_2_arr[omp_get_thread_num()]; 00561 00562 var_prc_2[idx]=nco_var_dpl(var_prc_1[idx]); 00563 (void)nco_var_mtd_refresh(in_id_2,var_prc_2[idx]); 00564 00565 /* NB: nco_var_get() with same nc_id contains OpenMP critical region */ 00566 (void)nco_var_get(in_id_1,var_prc_1[idx]); 00567 (void)nco_var_get(in_id_2,var_prc_2[idx]); 00568 00569 wgt_out_1=nco_var_cnf_dmn(var_prc_1[idx],wgt_1,wgt_out_1,MUST_CONFORM,&DO_CONFORM); 00570 wgt_out_2=nco_var_cnf_dmn(var_prc_2[idx],wgt_2,wgt_out_2,MUST_CONFORM,&DO_CONFORM); 00571 00572 var_prc_1[idx]=nco_var_cnf_typ((nc_type)NC_DOUBLE,var_prc_1[idx]); 00573 var_prc_2[idx]=nco_var_cnf_typ((nc_type)NC_DOUBLE,var_prc_2[idx]); 00574 00575 /* Allocate and, if necesssary, initialize space for processed variable */ 00576 var_prc_out[idx]->sz=var_prc_1[idx]->sz; 00577 /* NB: must not try to free() same tally buffer twice */ 00578 /* var_prc_out[idx]->tally=var_prc_1[idx]->tally=(long *)nco_malloc(var_prc_out[idx]->sz*sizeof(long));*/ 00579 var_prc_out[idx]->tally=(long *)nco_malloc(var_prc_out[idx]->sz*sizeof(long)); 00580 (void)nco_zero_long(var_prc_out[idx]->sz,var_prc_out[idx]->tally); 00581 00582 /* Weight variable by taking product of weight with variable */ 00583 (void)nco_var_mlt(var_prc_1[idx]->type,var_prc_1[idx]->sz,var_prc_1[idx]->has_mss_val,var_prc_1[idx]->mss_val,wgt_out_1->val,var_prc_1[idx]->val); 00584 (void)nco_var_mlt(var_prc_2[idx]->type,var_prc_2[idx]->sz,var_prc_2[idx]->has_mss_val,var_prc_2[idx]->mss_val,wgt_out_2->val,var_prc_2[idx]->val); 00585 /* Change missing_value of var_prc_2, if any, to missing_value of var_prc_1, if any */ 00586 has_mss_val=nco_mss_val_cnf(var_prc_1[idx],var_prc_2[idx]); 00587 /* NB: fxm: use tally to determine when to "unweight" answer? TODO */ 00588 (void)nco_var_add_tll_ncflint(var_prc_1[idx]->type,var_prc_1[idx]->sz,has_mss_val,var_prc_1[idx]->mss_val,var_prc_out[idx]->tally,var_prc_1[idx]->val,var_prc_2[idx]->val); 00589 00590 /* Re-cast output variable to original type */ 00591 var_prc_2[idx]=nco_var_cnf_typ(var_prc_out[idx]->type,var_prc_2[idx]); 00592 00593 #ifdef _OPENMP 00594 #pragma omp critical 00595 #endif /* _OPENMP */ 00596 { /* begin OpenMP critical */ 00597 /* Copy interpolations to output file */ 00598 if(var_prc_out[idx]->nbr_dim == 0){ 00599 (void)nco_put_var1(out_id,var_prc_out[idx]->id,var_prc_out[idx]->srt,var_prc_2[idx]->val.vp,var_prc_out[idx]->type); 00600 }else{ /* end if variable is a scalar */ 00601 (void)nco_put_vara(out_id,var_prc_out[idx]->id,var_prc_out[idx]->srt,var_prc_out[idx]->cnt,var_prc_2[idx]->val.vp,var_prc_out[idx]->type); 00602 } /* end else */ 00603 } /* end OpenMP critical */ 00604 00605 /* Free dynamically allocated buffers */ 00606 if(var_prc_1[idx] != NULL) var_prc_1[idx]=nco_var_free(var_prc_1[idx]); 00607 if(var_prc_2[idx] != NULL) var_prc_2[idx]=nco_var_free(var_prc_2[idx]); 00608 if(var_prc_out[idx] != NULL) var_prc_out[idx]=nco_var_free(var_prc_out[idx]); 00609 00610 } /* end (OpenMP parallel for) loop over idx */ 00611 if(dbg_lvl > 0) (void)fprintf(stderr,"\n"); 00612 00613 /* Close input netCDF files */ 00614 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) nco_close(in_id_1_arr[thr_idx]); 00615 for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) nco_close(in_id_2_arr[thr_idx]); 00616 00617 /* Close output file and move it from temporary to permanent location */ 00618 (void)nco_fl_out_cls(fl_out,fl_out_tmp,out_id); 00619 00620 /* Remove local copy of file */ 00621 if(FILE_1_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in_1); 00622 if(FILE_2_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in_2); 00623 00624 /* ncflint-unique memory */ 00625 if(fl_in_1 != NULL) fl_in_1=(char *)nco_free(fl_in_1); 00626 if(fl_in_2 != NULL) fl_in_2=(char *)nco_free(fl_in_2); 00627 var_prc_1=(var_sct **)nco_free(var_prc_1); 00628 var_prc_2=(var_sct **)nco_free(var_prc_2); 00629 if(wgt_1 != NULL) wgt_1=(var_sct *)nco_var_free(wgt_1); 00630 if(wgt_2 != NULL) wgt_2=(var_sct *)nco_var_free(wgt_2); 00631 if(wgt_out_1 != NULL) wgt_out_1=(var_sct *)nco_var_free(wgt_out_1); 00632 if(wgt_out_2 != NULL) wgt_out_2=(var_sct *)nco_var_free(wgt_out_2); 00633 00634 /* NCO-generic clean-up */ 00635 /* Free individual strings/arrays */ 00636 if(cmd_ln != NULL) cmd_ln=(char *)nco_free(cmd_ln); 00637 if(fl_out != NULL) fl_out=(char *)nco_free(fl_out); 00638 if(fl_out_tmp != NULL) fl_out_tmp=(char *)nco_free(fl_out_tmp); 00639 if(fl_pth != NULL) fl_pth=(char *)nco_free(fl_pth); 00640 if(fl_pth_lcl != NULL) fl_pth_lcl=(char *)nco_free(fl_pth_lcl); 00641 if(in_id_1_arr != NULL) in_id_1_arr=(int *)nco_free(in_id_1_arr); 00642 if(in_id_2_arr != NULL) in_id_2_arr=(int *)nco_free(in_id_2_arr); 00643 /* Free lists of strings */ 00644 if(fl_lst_in != NULL && fl_lst_abb == NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,fl_nbr); 00645 if(fl_lst_in != NULL && fl_lst_abb != NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,1); 00646 if(fl_lst_abb != NULL) fl_lst_abb=nco_sng_lst_free(fl_lst_abb,abb_arg_nbr); 00647 if(var_lst_in_nbr > 0) var_lst_in=nco_sng_lst_free(var_lst_in,var_lst_in_nbr); 00648 /* Free limits */ 00649 for(idx=0;idx<lmt_nbr;idx++) lmt_arg[idx]=(char *)nco_free(lmt_arg[idx]); 00650 if(lmt_nbr > 0) lmt=nco_lmt_lst_free(lmt,lmt_nbr); 00651 /* Free dimension lists */ 00652 if(nbr_dmn_xtr > 0) dim=nco_dmn_lst_free(dim,nbr_dmn_xtr); 00653 if(nbr_dmn_xtr > 0) dmn_out=nco_dmn_lst_free(dmn_out,nbr_dmn_xtr); 00654 /* Free variable lists */ 00655 /* ncflint free()s _prc variables at end of main loop */ 00656 var=(var_sct **)nco_free(var); 00657 var_out=(var_sct **)nco_free(var_out); 00658 var_prc_out=(var_sct **)nco_free(var_prc_out); 00659 if(nbr_var_fix > 0) var_fix=nco_var_lst_free(var_fix,nbr_var_fix); 00660 if(nbr_var_fix > 0) var_fix_out=nco_var_lst_free(var_fix_out,nbr_var_fix); 00661 00662 if(rcd != NC_NOERR) nco_err_exit(rcd,"main"); 00663 nco_exit_gracefully(); 00664 return EXIT_SUCCESS; 00665 } /* end main() */
|
1.4.4