nco/mpncflint.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 mpncflint.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 67 of file mpncflint.c.


Function Documentation

int main int  argc,
char **  argv
 

Definition at line 71 of file mpncflint.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, var_sct_tag::id, idx_all_wrk_ass, int_CEWI, lst_prs_2D(), msg_bfr_lng, msg_tag_tkn_wrt_rqs, msg_tag_tkn_wrt_rsp, msg_tag_wrk_rqs, msg_tag_wrk_rsp, 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, NC_SHARE, NC_WRITE, nco_att_cpy(), nco_bool, nco_close(), nco_cmd_ln_sng(), nco_cnt_run(), 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_mv(), 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_mpi_att_cat(), 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_spn_lck_brk, nco_spn_lck_us, 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, rnk_mgr, scl_mk_var(), var_sct_tag::sz, var_sct_tag::tally, tkn_wrt_rqs_dny, tkn_wrt_rqs_ntv, tkn_wrt_rqs_xcp, True, type, var_sct_tag::type, option::val, var_sct_tag::val, and wrk_id_bfr_lng.

00072 {
00073   nco_bool CMD_LN_NTP_VAR=False; /* Option i */
00074   nco_bool CMD_LN_NTP_WGT=True; /* Option w */
00075   nco_bool DO_CONFORM=False; /* Did nco_var_cnf_dmn() find truly conforming variables? */
00076   nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
00077   nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
00078   nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
00079   nco_bool FILE_1_RETRIEVED_FROM_REMOTE_LOCATION;
00080   nco_bool FILE_2_RETRIEVED_FROM_REMOTE_LOCATION;
00081   nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
00082   nco_bool FORCE_APPEND=False; /* Option A */
00083   nco_bool FORCE_OVERWRITE=False; /* Option O */
00084   nco_bool FORTRAN_IDX_CNV=False; /* Option F */
00085   nco_bool HISTORY_APPEND=True; /* Option h */
00086   nco_bool MUST_CONFORM=False; /* Must nco_var_cnf_dmn() find truly conforming variables? */
00087   nco_bool CNV_CCM_CCSM_CF;
00088   nco_bool REMOVE_REMOTE_FILES_AFTER_PROCESSING=True; /* Option R */
00089   
00090   char **fl_lst_abb=NULL; /* Option a */
00091   char **fl_lst_in;
00092   char **ntp_lst_in;
00093   char **var_lst_in=NULL_CEWI;
00094   char *cmd_ln;
00095   char *fl_in_1=NULL; /* fl_in_1 is nco_realloc'd when not NULL */;
00096   char *fl_in_2=NULL; /* fl_in_2 is nco_realloc'd when not NULL */;
00097   char *fl_out=NULL; /* Option o */
00098   char *fl_out_tmp=NULL; /* MPI CEWI */
00099   char *fl_pth=NULL; /* Option p */
00100   char *fl_pth_lcl=NULL; /* Option l */
00101   char *lmt_arg[NC_MAX_DIMS];
00102   char *ntp_nm=NULL; /* Option i */
00103   char *opt_crr=NULL; /* [sng] String representation of current long-option name */
00104   char *optarg_lcl=NULL; /* [sng] Local copy of system optarg */
00105   char *time_bfr_srt;
00106   
00107   const char * const CVS_Id="$Id: mpncflint.c,v 1.35 2006/02/26 07:41:55 zender Exp $"; 
00108   const char * const CVS_Revision="$Revision: 1.35 $";
00109   const char * const opt_sht_lst="4ACcD:d:Fhi:l:Oo:p:rRSt:v:xw:-:";
00110   
00111   dmn_sct **dim;
00112   dmn_sct **dmn_out;
00113   
00114   double ntp_val_out=double_CEWI; /* Option i */
00115   double wgt_val_1=0.5; /* Option w */
00116   double wgt_val_2=0.5; /* Option w */
00117   
00118   extern char *optarg;
00119   extern int optind;
00120   
00121   /* Using naked stdin/stdout/stderr in parallel region generates warning
00122      Copy appropriate filehandle to variable scoped shared in parallel clause */
00123   FILE * const fp_stderr=stderr; /* [fl] stderr filehandle CEWI */
00124   FILE * const fp_stdout=stdout; /* [fl] stdout filehandle CEWI */
00125   
00126   int *in_id_1_arr;
00127   int *in_id_2_arr;
00128 
00129   int abb_arg_nbr=0;
00130   int fl_idx;
00131   int fl_nbr=0;
00132   int fl_out_fmt=NC_FORMAT_CLASSIC; /* [enm] Output file format */
00133   int fll_md_old; /* [enm] Old fill mode */
00134   int has_mss_val=False;
00135   int idx;
00136   int in_id_1;  
00137   int in_id_2;  
00138   int lmt_nbr=0; /* Option d. NB: lmt_nbr gets incremented */
00139   int nbr_dmn_fl;
00140   int nbr_dmn_xtr;
00141   int nbr_ntp;
00142   int nbr_var_fix; /* nbr_var_fix gets incremented */
00143   int nbr_var_fl;
00144   int nbr_var_prc; /* nbr_var_prc gets incremented */
00145   int nbr_xtr=0; /* nbr_xtr won't otherwise be set for -c with no -v */
00146   int opt;
00147   int out_id;
00148   int rcd=NC_NOERR; /* [rcd] Return code */
00149   int thr_idx; /* [idx] Index of current thread */
00150   int thr_nbr=int_CEWI; /* [nbr] Thread number Option t */
00151   int var_lst_in_nbr=0;
00152   
00153   lmt_sct **lmt;
00154   
00155   nm_id_sct *dmn_lst;
00156   nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */
00157   
00158   time_t time_crr_time_t;
00159   
00160   val_unn val_gnr_unn; /* Generic container for arrival point or weight */
00161   
00162   var_sct *wgt_1=NULL_CEWI;
00163   var_sct *wgt_2=NULL_CEWI;
00164   var_sct *wgt_out_1=NULL;
00165   var_sct *wgt_out_2=NULL;
00166   var_sct **var;
00167   var_sct **var_fix;
00168   var_sct **var_fix_out;
00169   var_sct **var_out;
00170   var_sct **var_prc_1;
00171   var_sct **var_prc_2;
00172   var_sct **var_prc_out;
00173   
00174 #ifdef ENABLE_MPI
00175   /* Declare all MPI-specific variables here */
00176   MPI_Status mpi_stt; /* [enm] Status check to decode msg_tag_typ */
00177 
00178   bool TKN_WRT_FREE=True; /* [flg] Write-access to output file is available */
00179   
00180   const double tkn_wrt_rqs_ntv=0.04; /* [s] Token request interval */
00181   
00182   const int msg_bfr_lng=3; /* [nbr] Number of elements in msg_bfr */
00183   const int wrk_id_bfr_lng=1; /* [nbr] Number of elements in wrk_id_bfr */
00184 
00185   int fl_nm_lng; /* [nbr] Output file name length */
00186   int msg_bfr[msg_bfr_lng]; /* [bfr] Buffer containing var, idx, tkn_wrt_rsp */
00187   int msg_tag_typ; /* [enm] MPI message tag type */
00188   int prc_rnk; /* [idx] Process rank */
00189   int prc_nbr=0; /* [nbr] Number of MPI processes */
00190   int tkn_wrt_rsp; /* [enm] Response to request for write token */
00191   int var_wrt_nbr=0; /* [nbr] Variables written to output file until now */
00192   int rnk_wrk; /* [idx] Worker rank */
00193   int wrk_id_bfr[wrk_id_bfr_lng]; /* [bfr] Buffer for rnk_wrk */
00194 #endif /* !ENABLE_MPI */
00195 
00196   static struct option opt_lng[]=
00197     { /* Structure ordered by short option key if possible */
00198       /* Long options with no argument, no short option counterpart */
00199       /* Long options with argument, no short option counterpart */
00200       {"fl_fmt",required_argument,0,0},
00201       {"file_format",required_argument,0,0},
00202       /* Long options with short counterparts */
00203       {"4",no_argument,0,'4'},
00204       {"64bit",no_argument,0,'4'},
00205       {"netcdf4",no_argument,0,'4'},
00206       {"append",no_argument,0,'A'},
00207       {"coords",no_argument,0,'c'},
00208       {"crd",no_argument,0,'c'},
00209       {"no-coords",no_argument,0,'C'},
00210       {"no-crd",no_argument,0,'C'},
00211       {"debug",required_argument,0,'D'},
00212       {"dbg_lvl",required_argument,0,'D'},
00213       {"dimension",required_argument,0,'d'},
00214       {"dmn",required_argument,0,'d'},
00215       {"fortran",no_argument,0,'F'},
00216       {"ftn",no_argument,0,'F'},
00217       {"history",no_argument,0,'h'},
00218       {"hst",no_argument,0,'h'},
00219       {"interpolate",required_argument,0,'i'},
00220       {"ntp",required_argument,0,'i'},
00221       {"local",required_argument,0,'l'},
00222       {"lcl",required_argument,0,'l'},
00223       {"overwrite",no_argument,0,'O'},
00224       {"ovr",no_argument,0,'O'},
00225       {"output",required_argument,0,'o'},
00226       {"fl_out",required_argument,0,'o'},
00227       {"path",required_argument,0,'p'},
00228       {"retain",no_argument,0,'R'},
00229       {"rtn",no_argument,0,'R'},
00230       {"revision",no_argument,0,'r'},
00231       {"suspend", no_argument,0,'S'},
00232       {"thr_nbr",required_argument,0,'t'},
00233       {"variable",required_argument,0,'v'},
00234       {"version",no_argument,0,'r'},
00235       {"vrs",no_argument,0,'r'},
00236       {"weight",required_argument,0,'w'},
00237       {"wgt_var",no_argument,0,'w'},
00238       {"help",no_argument,0,'?'},
00239       {0,0,0,0}
00240     }; /* end opt_lng */
00241   int opt_idx=0; /* Index of current long option into opt_lng array */
00242   
00243 #ifdef ENABLE_MPI
00244   /* MPI Initialization */
00245   MPI_Init(&argc,&argv);
00246   MPI_Comm_size(MPI_COMM_WORLD,&prc_nbr);
00247   MPI_Comm_rank(MPI_COMM_WORLD,&prc_rnk);
00248 #endif /* !ENABLE_MPI */
00249   
00250   /* Start clock and save command line */ 
00251   cmd_ln=nco_cmd_ln_sng(argc,argv);
00252   time_crr_time_t=time((time_t *)NULL);
00253   time_bfr_srt=ctime(&time_crr_time_t); time_bfr_srt=time_bfr_srt; /* Avoid compiler warning until variable is used for something */
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': /* The 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 appending to history global attribute */
00297       HISTORY_APPEND=!HISTORY_APPEND;
00298       break;
00299     case 'i':
00300       /* Name of variable to guide interpolation. Default is none */
00301       ntp_lst_in=lst_prs_2D(optarg,",",&nbr_ntp);
00302       if(nbr_ntp > 2){
00303         (void)fprintf(stdout,"%s: ERROR too many arguments to -i\n",prg_nm_get());
00304         (void)nco_usg_prn();
00305         nco_exit(EXIT_FAILURE);
00306       } /* end if */
00307       ntp_nm=ntp_lst_in[0];
00308       ntp_val_out=strtod(ntp_lst_in[1],(char **)NULL);
00309       CMD_LN_NTP_VAR=True;
00310       CMD_LN_NTP_WGT=False;
00311       break;
00312     case 'l': /* Local path prefix for files retrieved from remote file system */
00313       fl_pth_lcl=(char *)strdup(optarg);
00314       break;
00315     case 'O': /* Toggle FORCE_OVERWRITE */
00316       FORCE_OVERWRITE=!FORCE_OVERWRITE;
00317       break;
00318     case 'o': /* Name of output file */
00319       fl_out=(char *)strdup(optarg);
00320       break;
00321     case 'p': /* Common file path */
00322       fl_pth=(char *)strdup(optarg);
00323       break;
00324     case 'R': /* Toggle removal of remotely-retrieved-files. Default is True. */
00325       REMOVE_REMOTE_FILES_AFTER_PROCESSING=!REMOVE_REMOTE_FILES_AFTER_PROCESSING;
00326       break;
00327     case 'r': /* Print CVS program information and copyright notice */
00328       (void)copyright_prn(CVS_Id,CVS_Revision);
00329       (void)nco_lbr_vrs_prn();
00330       nco_exit(EXIT_SUCCESS);
00331       break;
00332 #ifdef ENABLE_MPI
00333     case 'S': /* Suspend with signal handler to facilitate debugging */
00334       if(signal(SIGUSR1,nco_cnt_run) == SIG_ERR) (void)fprintf(fp_stdout,"%s: ERROR Could not install suspend handler.\n",prg_nm);
00335       while(!nco_spn_lck_brk) usleep(nco_spn_lck_us); /* Spinlock. fxm: should probably insert a sched_yield */
00336       break;
00337 #endif /* !ENABLE_MPI */
00338     case 't': /* Thread number */
00339       thr_nbr=(int)strtol(optarg,(char **)NULL,10);
00340       break;
00341     case 'v': /* Variables to extract/exclude */
00342       /* Replace commas with hashes when within braces (convert back later) */
00343       optarg_lcl=(char *)strdup(optarg);
00344       (void)nco_lst_comma2hash(optarg_lcl);
00345       var_lst_in=lst_prs_2D(optarg_lcl,",",&var_lst_in_nbr);
00346       optarg_lcl=(char *)nco_free(optarg_lcl);
00347       nbr_xtr=var_lst_in_nbr;
00348       break;
00349     case 'w':
00350       /* Weight(s) for interpolation.  Default is wgt_val_1=wgt_val_2=0.5 */
00351       ntp_lst_in=lst_prs_2D(optarg,",",&nbr_ntp);
00352       if(nbr_ntp > 2){
00353         (void)fprintf(stdout,"%s: ERROR too many arguments to -w\n",prg_nm_get());
00354         (void)nco_usg_prn();
00355         nco_exit(EXIT_FAILURE);
00356       }else if(nbr_ntp == 2){
00357         wgt_val_1=strtod(ntp_lst_in[0],(char **)NULL);
00358         wgt_val_2=strtod(ntp_lst_in[1],(char **)NULL);
00359       }else if(nbr_ntp == 1){
00360         wgt_val_1=strtod(ntp_lst_in[0],(char **)NULL);
00361         wgt_val_2=1.0-wgt_val_1;
00362       } /* end else */
00363       CMD_LN_NTP_WGT=True;
00364       break;
00365     case 'x': /* Exclude rather than extract variables specified with -v */
00366       EXCLUDE_INPUT_LIST=True;
00367       break;
00368     case '?': /* Print proper usage */
00369       (void)nco_usg_prn();
00370       nco_exit(EXIT_SUCCESS);
00371       break;
00372     case '-': /* Long options are not allowed */
00373       (void)fprintf(stderr,"%s: ERROR Long options are not available in this build. Use single letter options instead.\n",prg_nm_get());
00374       nco_exit(EXIT_FAILURE);
00375       break;
00376     default: /* Print proper usage */
00377       (void)nco_usg_prn();
00378       nco_exit(EXIT_FAILURE);
00379       break;
00380     } /* end switch */
00381     if(opt_crr != NULL) opt_crr=(char *)nco_free(opt_crr);
00382   } /* end while loop */
00383   
00384   if(CMD_LN_NTP_VAR && CMD_LN_NTP_WGT){
00385     (void)fprintf(stdout,"%s: ERROR interpolating variable (-i) and fixed weight(s) (-w) both set\n",prg_nm_get());
00386     nco_exit(EXIT_FAILURE);
00387   }else if(!CMD_LN_NTP_VAR && !CMD_LN_NTP_WGT){
00388     (void)fprintf(stdout,"%s: ERROR interpolating variable (-i) or fixed weight(s) (-w) must be set\n",prg_nm_get());
00389     nco_exit(EXIT_FAILURE);
00390   } /* end else */
00391   
00392   /* Process positional arguments and fill in filenames */
00393   fl_lst_in=nco_fl_lst_mk(argv,argc,optind,&fl_nbr,&fl_out,&FL_LST_IN_FROM_STDIN);
00394   
00395   /* Make uniform list of user-specified dimension limits */
00396   lmt=nco_lmt_prs(lmt_nbr,lmt_arg);
00397     
00398   /* Initialize thread information */
00399   thr_nbr=nco_openmp_ini(thr_nbr);
00400   in_id_1_arr=(int *)nco_malloc(thr_nbr*sizeof(int));
00401   in_id_2_arr=(int *)nco_malloc(thr_nbr*sizeof(int));
00402 
00403   /* Parse filenames */
00404   fl_idx=0; /* Input file _1 */
00405   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);
00406   if(dbg_lvl > 0) (void)fprintf(stderr,"\nInput file %d is %s; ",fl_idx,fl_in_1);
00407   /* Make sure file is on local system and is readable or die trying */
00408   fl_in_1=nco_fl_mk_lcl(fl_in_1,fl_pth_lcl,&FILE_1_RETRIEVED_FROM_REMOTE_LOCATION);
00409   if(dbg_lvl > 0) (void)fprintf(stderr,"local file %s:\n",fl_in_1);
00410   /* Open file once per thread to improve caching */
00411   for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd=nco_open(fl_in_1,NC_NOWRITE,in_id_1_arr+thr_idx);
00412   in_id_1=in_id_1_arr[0];
00413 
00414   fl_idx=1; /* Input file _2 */
00415   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);
00416   if(dbg_lvl > 0) (void)fprintf(stderr,"\nInput file %d is %s; ",fl_idx,fl_in_2);
00417   /* Make sure file is on local system and is readable or die trying */
00418   fl_in_2=nco_fl_mk_lcl(fl_in_2,fl_pth_lcl,&FILE_2_RETRIEVED_FROM_REMOTE_LOCATION);
00419   if(dbg_lvl > 0) (void)fprintf(stderr,"local file %s:\n",fl_in_2);
00420   /* Open file once per thread to improve caching */
00421   for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) rcd=nco_open(fl_in_2,NC_NOWRITE,in_id_2_arr+thr_idx);
00422   in_id_2=in_id_2_arr[0];
00423   
00424   /* Get number of variables and dimensions in file */
00425   (void)nco_inq(in_id_1,&nbr_dmn_fl,&nbr_var_fl,(int *)NULL,(int *)NULL);
00426   
00427   /* Form initial extraction list which may include extended regular expressions */
00428   xtr_lst=nco_var_lst_mk(in_id_1,nbr_var_fl,var_lst_in,EXTRACT_ALL_COORDINATES,&nbr_xtr);
00429   
00430   /* Change included variables to excluded variables */
00431   if(EXCLUDE_INPUT_LIST) xtr_lst=nco_var_lst_xcl(in_id_1,nbr_var_fl,xtr_lst,&nbr_xtr);
00432   
00433   /* Add all coordinate variables to extraction list */
00434   if(EXTRACT_ALL_COORDINATES) xtr_lst=nco_var_lst_add_crd(in_id_1,nbr_dmn_fl,xtr_lst,&nbr_xtr);
00435   
00436   /* Make sure coordinates associated extracted variables are also on extraction list */
00437   if(EXTRACT_ASSOCIATED_COORDINATES) xtr_lst=nco_var_lst_ass_crd_add(in_id_1,xtr_lst,&nbr_xtr);
00438   
00439   /* Sort extraction list by variable ID for fastest I/O */
00440   if(nbr_xtr > 1) xtr_lst=nco_lst_srt_nm_id(xtr_lst,nbr_xtr,False);
00441   
00442   /* We now have final list of variables to extract. Phew. */
00443   
00444   /* Find coordinate/dimension values associated with user-specified limits
00445      NB: nco_lmt_evl() with same nc_id contains OpenMP critical region */
00446   for(idx=0;idx<lmt_nbr;idx++) (void)nco_lmt_evl(in_id_1,lmt[idx],0L,FORTRAN_IDX_CNV);
00447   
00448   /* Find dimensions associated with variables to be extracted */
00449   dmn_lst=nco_dmn_lst_ass_var(in_id_1,xtr_lst,nbr_xtr,&nbr_dmn_xtr);
00450   
00451   /* Fill in dimension structure for all extracted dimensions */
00452   dim=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *));
00453   for(idx=0;idx<nbr_dmn_xtr;idx++) dim[idx]=nco_dmn_fll(in_id_1,dmn_lst[idx].id,dmn_lst[idx].nm);
00454   /* Dimension list no longer needed */
00455   dmn_lst=nco_nm_id_lst_free(dmn_lst,nbr_dmn_xtr);
00456   
00457   /* Merge hyperslab limit information into dimension structures */
00458   if(lmt_nbr > 0) (void)nco_dmn_lmt_mrg(dim,nbr_dmn_xtr,lmt,lmt_nbr);
00459   
00460   /* Duplicate input dimension structures for output dimension structures */
00461   dmn_out=(dmn_sct **)nco_malloc(nbr_dmn_xtr*sizeof(dmn_sct *));
00462   for(idx=0;idx<nbr_dmn_xtr;idx++){
00463     dmn_out[idx]=nco_dmn_dpl(dim[idx]);
00464     (void)nco_dmn_xrf(dim[idx],dmn_out[idx]); 
00465   } /* end loop over idx */
00466   
00467   /* Is this an CCM/CCSM/CF-format history tape? */
00468   CNV_CCM_CCSM_CF=nco_cnv_ccm_ccsm_cf_inq(in_id_1);
00469   
00470   /* Fill in variable structure list for all extracted variables */
00471   var=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *));
00472   var_out=(var_sct **)nco_malloc(nbr_xtr*sizeof(var_sct *));
00473   for(idx=0;idx<nbr_xtr;idx++){
00474     var[idx]=nco_var_fll(in_id_1,xtr_lst[idx].id,xtr_lst[idx].nm,dim,nbr_dmn_xtr);
00475     var_out[idx]=nco_var_dpl(var[idx]);
00476     (void)nco_xrf_var(var[idx],var_out[idx]);
00477     (void)nco_xrf_dmn(var_out[idx]);
00478   } /* end loop over idx */
00479   /* Extraction list no longer needed */
00480   xtr_lst=nco_nm_id_lst_free(xtr_lst,nbr_xtr);
00481   
00482   /* Divide variable lists into lists of fixed variables and variables to be processed */
00483   (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);
00484   
00485   /* Zero start vectors for all output variables */
00486   (void)nco_var_srt_zero(var_out,nbr_xtr);
00487   
00488 #ifdef ENABLE_MPI
00489   if(prc_rnk == rnk_mgr){ /* MPI manager code */
00490 #endif /* !ENABLE_MPI */
00491     /* Open output file */
00492     fl_out_tmp=nco_fl_out_open(fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&out_id);
00493     
00494     /* Copy global attributes */
00495     (void)nco_att_cpy(in_id_1,out_id,NC_GLOBAL,NC_GLOBAL,True);
00496     
00497     /* Catenate time-stamped command line to "history" global attribute */
00498     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
00499     
00500     if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
00501     
00502 #ifdef ENABLE_MPI
00503     /* Initialize MPI task information */
00504     if(prc_nbr > 0 && HISTORY_APPEND) (void)nco_mpi_att_cat(out_id,prc_nbr);
00505 #endif /* !ENABLE_MPI */
00506     
00507     /* Define dimensions in output file */
00508     (void)nco_dmn_dfn(fl_out,out_id,dmn_out,nbr_dmn_xtr);
00509     
00510     /* Define variables in output file, copy their attributes */
00511     (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);
00512     
00513     /* Turn off default filling behavior to enhance efficiency */
00514     rcd=nco_set_fill(out_id,NC_NOFILL,&fll_md_old);
00515     
00516     /* Take output file out of define mode */
00517     (void)nco_enddef(out_id);
00518     
00519 #ifdef ENABLE_MPI
00520   } /* prc_rnk != rnk_mgr */
00521   
00522   /* Manager obtains output filename and broadcasts to workers */
00523   if(prc_rnk == rnk_mgr) fl_nm_lng=(int)strlen(fl_out_tmp); 
00524   MPI_Bcast(&fl_nm_lng,1,MPI_INT,0,MPI_COMM_WORLD);
00525   if(prc_rnk != rnk_mgr) fl_out_tmp=(char *)malloc((fl_nm_lng+1)*sizeof(char));
00526   MPI_Bcast(fl_out_tmp,fl_nm_lng+1,MPI_CHAR,0,MPI_COMM_WORLD);
00527   
00528   if(prc_rnk == rnk_mgr){ /* MPI manager code */
00529     TKN_WRT_FREE=False;
00530 #endif /* !ENABLE_MPI */
00531     /* Copy variable data for non-processed variables */
00532     (void)nco_var_val_cpy(in_id_1,out_id,var_fix,nbr_var_fix);
00533 #ifdef ENABLE_MPI
00534     /* Close output file so workers can open it */
00535     nco_close(out_id);
00536     TKN_WRT_FREE=True;
00537   } /* prc_rnk != rnk_mgr */
00538 #endif /* !ENABLE_MPI */
00539   
00540   /* Perform various error-checks on input file */
00541   if(False) (void)nco_fl_cmp_err_chk();
00542   
00543   /* ncflint-specific stuff: */
00544   /* Find the weighting variable in input file */
00545   if(CMD_LN_NTP_VAR){
00546     int ntp_id_1;
00547     int ntp_id_2;
00548     
00549     var_sct *ntp_1;
00550     var_sct *ntp_2;
00551     var_sct *ntp_var_out;
00552     
00553     /* Turn arrival point into pseudo-variable */
00554     val_gnr_unn.d=ntp_val_out; /* Generic container for arrival point or weight */
00555     ntp_var_out=scl_mk_var(val_gnr_unn,NC_DOUBLE);
00556     
00557     rcd=nco_inq_varid(in_id_1,ntp_nm,&ntp_id_1);
00558     rcd=nco_inq_varid(in_id_2,ntp_nm,&ntp_id_2);
00559     
00560     ntp_1=nco_var_fll(in_id_1,ntp_id_1,ntp_nm,dim,nbr_dmn_xtr);
00561     ntp_2=nco_var_fll(in_id_2,ntp_id_2,ntp_nm,dim,nbr_dmn_xtr);
00562     
00563     /* Currently, only support scalar variables */
00564     if(ntp_1->sz > 1 || ntp_2->sz > 1){
00565       (void)fprintf(stdout,"%s: ERROR interpolation variable %s must be scalar\n",prg_nm_get(),ntp_nm);
00566       nco_exit(EXIT_FAILURE);
00567     } /* end if */
00568     
00569     /* Retrieve interpolation variable */
00570     /* NB: nco_var_get() with same nc_id contains OpenMP critical region */
00571     (void)nco_var_get(in_id_1,ntp_1);
00572     (void)nco_var_get(in_id_2,ntp_2);
00573     
00574     /* Weights must be NC_DOUBLE */
00575     ntp_1=nco_var_cnf_typ((nc_type)NC_DOUBLE,ntp_1);
00576     ntp_2=nco_var_cnf_typ((nc_type)NC_DOUBLE,ntp_2);
00577     
00578     /* Check for degenerate case */
00579     if(ntp_1->val.dp[0] == ntp_2->val.dp[0]){
00580       (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]);
00581       nco_exit(EXIT_FAILURE);
00582     } /* end if */
00583     
00584     /* Turn weights into pseudo-variables */
00585     wgt_1=nco_var_dpl(ntp_2);
00586     wgt_2=nco_var_dpl(ntp_var_out);
00587     
00588     /* Subtract to find interpolation distances */
00589     (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);
00590     (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);
00591     (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);
00592     
00593     /* Normalize to obtain final interpolation weights */
00594     (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);
00595     (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);
00596     
00597     if(ntp_1 != NULL) ntp_1=nco_var_free(ntp_1);
00598     if(ntp_2 != NULL) ntp_2=nco_var_free(ntp_2);
00599     if(ntp_var_out != NULL) ntp_var_out=nco_var_free(ntp_var_out);
00600   } /* end if CMD_LN_NTP_VAR */
00601   
00602   if(CMD_LN_NTP_WGT){
00603     val_gnr_unn.d=wgt_val_1; /* Generic container for arrival point or weight */
00604     wgt_1=scl_mk_var(val_gnr_unn,NC_DOUBLE);
00605     val_gnr_unn.d=wgt_val_2; /* Generic container for arrival point or weight */
00606     wgt_2=scl_mk_var(val_gnr_unn,NC_DOUBLE);
00607   } /* end if CMD_LN_NTP_WGT */
00608   
00609   if(dbg_lvl > 1) (void)fprintf(stderr,"wgt_1 = %g, wgt_2 = %g\n",wgt_1->val.dp[0],wgt_2->val.dp[0]);
00610   
00611   /* Create structure list for second file */
00612   var_prc_2=(var_sct **)nco_malloc(nbr_var_prc*sizeof(var_sct *));
00613   
00614   /* Loop over each interpolated variable */
00615 #ifdef ENABLE_MPI
00616   if(prc_rnk == rnk_mgr){ /* MPI manager code */
00617     /* Compensate for incrementing on each worker's first message */
00618     var_wrt_nbr=-prc_nbr+1;
00619     idx=0;
00620     /* While variables remain to be processed or written... */
00621     while(var_wrt_nbr < nbr_var_prc){
00622       /* Receive message from any worker */
00623       MPI_Recv(wrk_id_bfr,wrk_id_bfr_lng,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&mpi_stt);
00624       /* Obtain MPI message tag type */
00625       msg_tag_typ=mpi_stt.MPI_TAG;
00626       /* Get sender's prc_rnk */
00627       rnk_wrk=wrk_id_bfr[0];
00628       
00629       /* Allocate next variable, if any, to worker */
00630       if(msg_tag_typ == msg_tag_wrk_rqs){
00631         var_wrt_nbr++; /* [nbr] Number of variables written */
00632         /* Worker closed output file before sending msg_tag_wrk_rqs */
00633         TKN_WRT_FREE=True;
00634         
00635         if(idx > nbr_var_prc-1){
00636           msg_bfr[0]=idx_all_wrk_ass; /* [enm] All variables already assigned */
00637           msg_bfr[1]=out_id; /* Output file ID */
00638         }else{
00639           /* Tell requesting worker to allocate space for next variable */
00640           msg_bfr[0]=idx; /* [idx] Variable to be processed */
00641           msg_bfr[1]=out_id; /* Output file ID */
00642           msg_bfr[2]=var_prc_out[idx]->id; /* [id] Variable ID in output file */
00643           /* Point to next variable on list */
00644           idx++;
00645         } /* endif idx */
00646         MPI_Send(msg_bfr,msg_bfr_lng,MPI_INT,rnk_wrk,msg_tag_wrk_rsp,MPI_COMM_WORLD);
00647         /* msg_tag_typ != msg_tag_wrk_rqs */
00648       }else if(msg_tag_typ == msg_tag_tkn_wrt_rqs){
00649         /* Allocate token if free, else ask worker to try later */
00650         if(TKN_WRT_FREE){
00651           TKN_WRT_FREE=False;
00652           msg_bfr[0]=tkn_wrt_rqs_xcp; /* Accept request for write token */
00653         }else{
00654           msg_bfr[0]=tkn_wrt_rqs_dny; /* Deny request for write token */
00655         } /* !TKN_WRT_FREE */
00656         MPI_Send(msg_bfr,msg_bfr_lng,MPI_INT,rnk_wrk,msg_tag_tkn_wrt_rsp,MPI_COMM_WORLD);
00657       } /* msg_tag_typ != msg_tag_tkn_wrt_rqs */
00658     } /* end while var_wrt_nbr < nbr_var_prc */
00659   }else{ /* prc_rnk != rnk_mgr, end Manager code begin Worker code */
00660     wrk_id_bfr[0]=prc_rnk;
00661     while(1){ /* While work remains... */
00662       /* Send msg_tag_wrk_rqs */
00663       wrk_id_bfr[0]=prc_rnk;
00664       MPI_Send(wrk_id_bfr,wrk_id_bfr_lng,MPI_INT,rnk_mgr,msg_tag_wrk_rqs,MPI_COMM_WORLD);
00665       /* Receive msg_tag_wrk_rsp */
00666       MPI_Recv(msg_bfr,msg_bfr_lng,MPI_INT,0,msg_tag_wrk_rsp,MPI_COMM_WORLD,&mpi_stt);
00667       idx=msg_bfr[0];
00668       out_id=msg_bfr[1];
00669       if(idx == idx_all_wrk_ass) break;
00670       else{
00671         var_prc_out[idx]->id=msg_bfr[2];
00672         /* Process this variable same as UP code */
00673 #else /* !ENABLE_MPI */
00674 #ifdef _OPENMP
00675         /* OpenMP notes:
00676            shared(): msk and wgt are not altered within loop
00677            private(): wgt_avg does not need initialization */
00678 #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)
00679 #endif /* !_OPENMP */
00680         /* UP and SMP codes main loop over variables */
00681         for(idx=0;idx<nbr_var_prc;idx++){
00682 #endif /* !ENABLE_MPI */
00683           if(dbg_lvl > 0) (void)fprintf(fp_stderr,"%s, ",var_prc_1[idx]->nm);
00684           if(dbg_lvl > 0) (void)fflush(fp_stderr);
00685           
00686           in_id_1=in_id_1_arr[omp_get_thread_num()];
00687           in_id_2=in_id_2_arr[omp_get_thread_num()];
00688 
00689           var_prc_2[idx]=nco_var_dpl(var_prc_1[idx]);
00690           (void)nco_var_mtd_refresh(in_id_2,var_prc_2[idx]);
00691           
00692           /* NB: nco_var_get() with same nc_id contains OpenMP critical region */
00693           (void)nco_var_get(in_id_1,var_prc_1[idx]);
00694           (void)nco_var_get(in_id_2,var_prc_2[idx]);
00695           
00696           wgt_out_1=nco_var_cnf_dmn(var_prc_1[idx],wgt_1,wgt_out_1,MUST_CONFORM,&DO_CONFORM);
00697           wgt_out_2=nco_var_cnf_dmn(var_prc_2[idx],wgt_2,wgt_out_2,MUST_CONFORM,&DO_CONFORM);
00698           
00699           var_prc_1[idx]=nco_var_cnf_typ((nc_type)NC_DOUBLE,var_prc_1[idx]);
00700           var_prc_2[idx]=nco_var_cnf_typ((nc_type)NC_DOUBLE,var_prc_2[idx]);
00701           
00702           /* Allocate and, if necesssary, initialize space for processed variable */
00703           var_prc_out[idx]->sz=var_prc_1[idx]->sz;
00704           /* NB: must not try to free() same tally buffer twice */
00705           /*    var_prc_out[idx]->tally=var_prc_1[idx]->tally=(long *)nco_malloc(var_prc_out[idx]->sz*sizeof(long));*/
00706           var_prc_out[idx]->tally=(long *)nco_malloc(var_prc_out[idx]->sz*sizeof(long));
00707           (void)nco_zero_long(var_prc_out[idx]->sz,var_prc_out[idx]->tally);
00708           
00709           /* Weight variable by taking product of weight with variable */
00710           (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);
00711           (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);
00712           /* Change missing_value of var_prc_2, if any, to missing_value of var_prc_1, if any */
00713           has_mss_val=nco_mss_val_cnf(var_prc_1[idx],var_prc_2[idx]);
00714           /* NB: fxm: use tally to determine when to "unweight" answer? TODO  */
00715           (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);
00716           
00717           /* Re-cast output variable to original type */
00718           var_prc_2[idx]=nco_var_cnf_typ(var_prc_out[idx]->type,var_prc_2[idx]);
00719           
00720 #ifdef ENABLE_MPI
00721           /* Obtain token and prepare to write */
00722           while(1){ /* Send msg_tag_tkn_wrt_rqs repeatedly until token obtained */
00723             wrk_id_bfr[0]=prc_rnk;
00724             MPI_Send(wrk_id_bfr,wrk_id_bfr_lng,MPI_INT,rnk_mgr,msg_tag_tkn_wrt_rqs,MPI_COMM_WORLD);
00725             MPI_Recv(msg_bfr,msg_bfr_lng,MPI_INT,rnk_mgr,msg_tag_tkn_wrt_rsp,MPI_COMM_WORLD,&mpi_stt);
00726             tkn_wrt_rsp=msg_bfr[0];
00727             /* Wait then re-send request */
00728             if(tkn_wrt_rsp == tkn_wrt_rqs_dny) sleep(tkn_wrt_rqs_ntv); else break;
00729           } /* end while loop waiting for write token */
00730           
00731           /* Worker has token---prepare to write */
00732           if(tkn_wrt_rsp == tkn_wrt_rqs_xcp){
00733             rcd=nco_open(fl_out_tmp,NC_WRITE|NC_SHARE,&out_id);
00734             /* Turn off default filling behavior to enhance efficiency */
00735             rcd=nco_set_fill(out_id,NC_NOFILL,&fll_md_old);
00736 #else /* !ENABLE_MPI */
00737 #ifdef _OPENMP
00738 #pragma omp critical
00739 #endif /* _OPENMP */
00740 #endif /* !ENABLE_MPI */
00741             /* Common code for UP, SMP, and MPI */
00742             { /* begin OpenMP critical */
00743               /* Copy interpolations to output file */
00744               if(var_prc_out[idx]->nbr_dim == 0){
00745                 (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);
00746               }else{ /* end if variable is a scalar */
00747                 (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);
00748               } /* end else */
00749             } /* end OpenMP critical */
00750             
00751             /* Free dynamically allocated buffers */
00752             if(var_prc_1[idx] != NULL) var_prc_1[idx]=nco_var_free(var_prc_1[idx]);
00753             if(var_prc_2[idx] != NULL) var_prc_2[idx]=nco_var_free(var_prc_2[idx]);
00754             if(var_prc_out[idx] != NULL) var_prc_out[idx]=nco_var_free(var_prc_out[idx]);
00755             
00756 #ifdef ENABLE_MPI
00757             /* Close output file and increment written counter */
00758             nco_close(out_id);
00759             var_wrt_nbr++;
00760           } /* endif tkn_wrt_rqs_xcp */
00761         } /* end else !idx_all_wrk_ass */
00762       } /* end while loop requesting work/token */
00763     } /* endif Worker */
00764 #else /* !ENABLE_MPI */
00765   } /* end (OpenMP parallel for) loop over idx */
00766 #endif /* !ENABLE_MPI */
00767   
00768   if(dbg_lvl > 0) (void)fprintf(stderr,"\n");
00769   
00770   /* Close input netCDF files */
00771   for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) nco_close(in_id_1_arr[thr_idx]);
00772   for(thr_idx=0;thr_idx<thr_nbr;thr_idx++) nco_close(in_id_2_arr[thr_idx]);
00773   
00774 #ifdef ENABLE_MPI
00775   /* Manager moves output file (closed by workers) from temporary to permanent location */
00776   if(prc_rnk == rnk_mgr) (void)nco_fl_mv(fl_out_tmp,fl_out);
00777 #else /* !ENABLE_MPI */
00778   /* Close output file and move it from temporary to permanent location */
00779   (void)nco_fl_out_cls(fl_out,fl_out_tmp,out_id);
00780 #endif /* end !ENABLE_MPI */
00781   
00782   /* Remove local copy of file */
00783   if(FILE_1_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in_1);
00784   if(FILE_2_RETRIEVED_FROM_REMOTE_LOCATION && REMOVE_REMOTE_FILES_AFTER_PROCESSING) (void)nco_fl_rm(fl_in_2);
00785   
00786   /* ncflint-unique memory */
00787   if(fl_in_1 != NULL) fl_in_1=(char *)nco_free(fl_in_1);
00788   if(fl_in_2 != NULL) fl_in_2=(char *)nco_free(fl_in_2);
00789   var_prc_1=(var_sct **)nco_free(var_prc_1);
00790   var_prc_2=(var_sct **)nco_free(var_prc_2);
00791   if(wgt_1 != NULL) wgt_1=(var_sct *)nco_var_free(wgt_1);
00792   if(wgt_2 != NULL) wgt_2=(var_sct *)nco_var_free(wgt_2);
00793   if(wgt_out_1 != NULL) wgt_out_1=(var_sct *)nco_var_free(wgt_out_1);
00794   if(wgt_out_2 != NULL) wgt_out_2=(var_sct *)nco_var_free(wgt_out_2);
00795   
00796   /* NCO-generic clean-up */
00797   /* Free individual strings/arrays */
00798   if(cmd_ln != NULL) cmd_ln=(char *)nco_free(cmd_ln);
00799   if(fl_out != NULL) fl_out=(char *)nco_free(fl_out);
00800   if(fl_out_tmp != NULL) fl_out_tmp=(char *)nco_free(fl_out_tmp);
00801   if(fl_pth != NULL) fl_pth=(char *)nco_free(fl_pth);
00802   if(fl_pth_lcl != NULL) fl_pth_lcl=(char *)nco_free(fl_pth_lcl);
00803 
00804   /* Free lists of strings */
00805   if(fl_lst_in != NULL && fl_lst_abb == NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,fl_nbr); 
00806   if(fl_lst_in != NULL && fl_lst_abb != NULL) fl_lst_in=nco_sng_lst_free(fl_lst_in,1);
00807   if(fl_lst_abb != NULL) fl_lst_abb=nco_sng_lst_free(fl_lst_abb,abb_arg_nbr);
00808   if(var_lst_in_nbr > 0) var_lst_in=nco_sng_lst_free(var_lst_in,var_lst_in_nbr);
00809   /* Free limits */
00810   for(idx=0;idx<lmt_nbr;idx++) lmt_arg[idx]=(char *)nco_free(lmt_arg[idx]);
00811   if(lmt_nbr > 0) lmt=nco_lmt_lst_free(lmt,lmt_nbr);
00812   /* Free dimension lists */
00813   if(nbr_dmn_xtr > 0) dim=nco_dmn_lst_free(dim,nbr_dmn_xtr);
00814   if(nbr_dmn_xtr > 0) dmn_out=nco_dmn_lst_free(dmn_out,nbr_dmn_xtr);
00815   /* Free variable lists */
00816   /* ncflint free()s _prc variables at end of main loop */
00817   var=(var_sct **)nco_free(var);
00818   var_out=(var_sct **)nco_free(var_out);
00819   var_prc_out=(var_sct **)nco_free(var_prc_out);
00820   if(nbr_var_fix > 0) var_fix=nco_var_lst_free(var_fix,nbr_var_fix);
00821   if(nbr_var_fix > 0) var_fix_out=nco_var_lst_free(var_fix_out,nbr_var_fix);
00822   
00823 #ifdef ENABLE_MPI
00824   MPI_Finalize();
00825 #endif /* !ENABLE_MPI */
00826   
00827   if(rcd != NC_NOERR) nco_err_exit(rcd,"main");
00828   nco_exit_gracefully();
00829   return EXIT_SUCCESS;
00830 } /* end main() */


Generated on Thu Mar 16 18:13:51 2006 for nco by  doxygen 1.4.4