nco/ncflint.c File Reference

#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)


Define Documentation

#define MAIN_PROGRAM_FILE
 

Definition at line 64 of file ncflint.c.


Function Documentation

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() */


Generated on Thu Mar 16 18:14:59 2006 for nco by  doxygen 1.4.4