nco++/ncap2.hh File Reference

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <string>
#include <netcdf.h>
#include "nco_netcdf.h"
#include "libnco.h"
#include "Ncap2.hh"
#include <vector>
#include "NcapVector.hh"
#include "NcapVarVector.hh"
#include "NcapVar.hh"
#include <antlr/AST.hpp>

Include dependency graph for ncap2.hh:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  sym_sct
struct  nm_lst_sct
struct  ast_lmt_sct
struct  prs_sct

Functions

var_sctncap_var_init (const char *const var_nm, prs_sct *prs_arg)
int ncap_var_write (var_sct *var, prs_sct *prs_arg)
var_sctncap_att_init (const char *const va_nm, prs_sct *prs_arg)
sym_sctncap_sym_init (const char *const sym_nm, double(*fnc_dbl)(double), float(*fnc_flt)(float))
var_sctncap_var_var_mod (var_sct *var_1, var_sct *var_2)
var_sctncap_var_var_pwr (var_sct *var_1, var_sct *var_2)
var_sctncap_var_fnc (var_sct *var_in, sym_sct *app)
var_sctncap_var_abs (var_sct *var)
nm_id_sctnco_var_lst_copy (nm_id_sct *xtr_lst, int lst_nbr)
nm_id_sctnco_var_lst_sub (nm_id_sct *xtr_lst, int *nbr_xtr, nm_id_sct *xtr_lst_b, int nbr_lst_b)
nm_id_sctnco_var_lst_add (nm_id_sct *xtr_lst, int *nbr_xtr, nm_id_sct *xtr_lst_a, int nbr_lst_a)
nm_id_sctnco_dmn_lst (const int nc_id, int *const nbr_dmn)
nm_id_sctnco_att_lst_mk (const int in_id, const int out_id, NcapVarVector &var_vtr, int *nbr_lst)
nco_bool ncap_var_stretch (var_sct **var_1, var_sct **var_2)
nco_bool ncap_att_stretch (var_sct *var, long nw_sz)
var_sctncap_var_var_op (var_sct *var1, var_sct *var2, int op)
bool ncap_var_lgcl (var_sct *var)
var_sctncap_mk_cst (char **sbs_lst, int lst_nbr, prs_sct *prs_arg)
var_sctncap_do_cst (var_sct *var, var_sct *var_cst, bool bntlscn)


Function Documentation

var_sct* ncap_att_init const char *const   va_nm,
prs_sct prs_arg
 

Definition at line 178 of file ncap2_utl.cc.

References var_sct_tag::id, prs_sct::in_id, var_sct_tag::nbr_dim, NC_ENOTATT, NC_GLOBAL, var_sct_tag::nc_id, NC_NOERR, nco_free(), nco_get_att(), nco_inq_att_flg(), nco_inq_varid_flg(), nco_malloc(), nco_typ_lng(), nco_var_free(), var_sct_tag::nm, var_sct_tag::sz, type, var_sct_tag::type, var_sct_tag::val, var_dfl_set(), and ptr_unn::vp.

00181 {
00182 int rcd;
00183 int var_id;
00184 long sz;
00185 nc_type type;
00186 
00187 char *var_nm;
00188 char *att_nm;
00189 
00190 
00191 var_sct *var_ret;
00192 
00193   var_nm=strdup(va_nm);
00194   att_nm=strchr(var_nm,'@');
00195   if (att_nm==NULL) return (var_sct*)NULL;
00196   *att_nm++='\0';
00197 
00198   if( !strcmp(var_nm,"global")){ 
00199     var_id=NC_GLOBAL;
00200   }else{
00201     rcd=nco_inq_varid_flg(prs_arg->in_id,var_nm,&var_id);
00202     if (rcd !=NC_NOERR) return (var_sct*)NULL;
00203   }
00204   rcd=nco_inq_att_flg(prs_arg->in_id,var_id,att_nm,&type,&sz);
00205   if (rcd == NC_ENOTATT) return (var_sct*)NULL;
00206 
00207 
00208   var_ret=(var_sct*)nco_malloc(sizeof(var_sct));
00209   (void)var_dfl_set(var_ret);
00210 
00211   var_ret->nm=strdup(va_nm);
00212   var_ret->id=var_id;
00213   var_ret->nc_id=prs_arg->in_id;
00214   var_ret->type=type;
00215   var_ret->sz=sz;
00216   // maybe needed ?
00217   var_ret->nbr_dim=0;
00218 
00219   var_ret->val.vp=(void *)nco_malloc(sz*nco_typ_lng(type));
00220 
00221 
00222   rcd=nco_get_att(prs_arg->in_id,var_id,att_nm,var_ret->val.vp,type);
00223   var_nm=(char*)nco_free(var_nm);
00224   if (rcd !=NC_NOERR) {
00225     var_ret=nco_var_free(var_ret);
00226     return (var_sct*)NULL;
00227   }
00228 
00229   return var_ret;
00230 }

nco_bool ncap_att_stretch var_sct var,
long  nw_sz
 

Definition at line 854 of file ncap2_utl.cc.

References nco_free(), nco_malloc(), nco_typ_lng(), var_sct_tag::sz, var_sct_tag::type, var_sct_tag::val, and ptr_unn::vp.

Referenced by ncap_var_var_op().

00856 {
00857 
00858   size_t idx;
00859   size_t var_typ_sz;  
00860   void* vp;
00861   char *cp;
00862 
00863   if(var->sz == 1L && nw_sz >1){
00864     
00865     var_typ_sz=nco_typ_lng(var->type);
00866     vp=(void*)nco_malloc(nw_sz*var_typ_sz);
00867     for(idx=0 ; idx < nw_sz ;idx++){
00868       cp=(char*)vp + (ptrdiff_t)(idx*var_typ_sz);
00869       memcpy(cp,var->val.vp ,var_typ_sz);
00870     }
00871   
00872     var->val.vp=(void*)nco_free(var->val.vp);
00873     var->sz=nw_sz;
00874     var->val.vp=vp;
00875     return true;
00876   }
00877   
00878     return false; 
00879 
00880 } /* end ncap_att_stretch */

var_sct* ncap_do_cst var_sct var,
var_sct var_cst,
bool  bntlscn
 

Definition at line 1195 of file ncap2_utl.cc.

References dbg_lvl_get(), False, var_sct_tag::id, var_sct_tag::nbr_dim, ncap_var_stretch(), nco_free(), nco_var_dpl(), nco_var_free(), var_sct_tag::nm, prg_nm_get(), var_sct_tag::sz, var_sct_tag::typ_dsk, var_sct_tag::type, var_sct_tag::undefined, var_sct_tag::val, and ptr_unn::vp.

01199 {
01200 
01201   var_sct* var_tmp;
01202 
01203   if(bntlscn) {
01204     var_tmp=nco_var_dpl(var_cst);
01205     var_tmp->id=var->id;
01206     var_tmp->nm=(char*)nco_free(var_tmp->nm);
01207     var_tmp->nm=strdup(var->nm);
01208     var_tmp->type=var->type;
01209     var_tmp->typ_dsk=var->typ_dsk;
01210     var_tmp->undefined=False;
01211     var_tmp->val.vp=(void*)NULL;
01212     var=nco_var_free(var);
01213     var=var_tmp;
01214   
01215   }else{
01216 
01217    /* User intends LHS to cast RHS to same dimensionality
01218       Stretch newly initialized variable to size of LHS template */
01219    var_tmp=var;
01220    (void)ncap_var_stretch(&var_tmp,&var_cst);
01221    if(var_tmp != var) { 
01222      var=nco_var_free(var); 
01223      var=var_tmp;
01224    }
01225   
01226   if(dbg_lvl_get() > 2) (void)fprintf(stderr,"%s: Stretching variable %s with LHS template: Template var->nm %s, var->nbr_dim %d, var->sz %li\n",prg_nm_get(),var->nm,var_cst->nm,var_cst->nbr_dim,var_cst->sz);
01227     
01228    var->undefined=False;
01229   }
01230 
01231 return var;
01232 
01233 }

var_sct* ncap_mk_cst char **  sbs_lst,
int  lst_nbr,
prs_sct prs_arg
 

Definition at line 1060 of file ncap2_utl.cc.

References var_sct_tag::cnt, dmn_sct_tag::cnt, dbg_lvl_get(), var_sct_tag::dim, var_sct_tag::dmn_id, var_sct_tag::end, dmn_sct_tag::end, EXIT_FAILURE, NcapVector< T >::find(), prs_sct::fl_out, dmn_sct_tag::id, dmn_sct_tag::is_rec_dmn, var_sct_tag::nbr_dim, NC_DOUBLE, ncap_err_sng, nco_dmn_dfn(), nco_dmn_dpl(), nco_dmn_xrf(), nco_enddef(), nco_exit(), nco_malloc(), nco_malloc_flg(), nco_redef(), nco_typ_lng(), var_sct_tag::nm, prs_sct::ntl_scn, prs_sct::out_id, prg_nm_get(), prs_sct::ptr_dmn_in_vtr, prs_sct::ptr_dmn_out_vtr, NcapVector< T >::push(), var_sct_tag::srd, dmn_sct_tag::srd, var_sct_tag::srt, dmn_sct_tag::srt, var_sct_tag::sz, var_sct_tag::type, var_sct_tag::val, var_dfl_set(), and ptr_unn::vp.

01064 {
01065 
01066   static const char * const tpl_nm="Internally generated template";
01067   
01068   
01069   int dmn_nbr; /* [nbr] Number of dimensions */
01070   int idx; /* [idx] Counter */
01071   
01072   double val=1.0; /* [frc] Value of template */
01073   
01074   var_sct *var; /* [sct] Variable */
01075   
01076   dmn_sct **dmn; /* [dmn] Dimension structure list */
01077   dmn_sct *dmn_item;
01078   dmn_sct *dmn_new;
01079   dmn_nbr = lst_nbr;
01080 
01081 
01082   //  sbs_lst=lst_prs_2D(sbs_sng,sbs_dlm,&dmn_nbr); 
01083 
01084   dmn=(dmn_sct **)nco_malloc(dmn_nbr*sizeof(dmn_sct *));
01085   (void)nco_redef(prs_arg->out_id);
01086   for(idx=0;idx<dmn_nbr;idx++){
01087     
01088     // Search dmn_out_vtr for dimension
01089     dmn_item=prs_arg->ptr_dmn_out_vtr->find(sbs_lst[idx]);
01090     if(dmn_item != NULL){ 
01091       dmn[idx]=dmn_item;
01092       continue;
01093     }
01094     // Search dmn_in_vtr for dimension
01095     dmn_item=prs_arg->ptr_dmn_in_vtr->find(sbs_lst[idx]);
01096     // die if not in list
01097     if(dmn_item == NULL) {
01098       (void)fprintf(stderr,"Warning: Unrecognized dimension \"%s\" in LHS subscripts",sbs_lst[idx]);
01099       exit(1);
01100     }  
01101     dmn_new=nco_dmn_dpl(dmn_item);
01102     // Define in output file 
01103     (void)nco_dmn_dfn(prs_arg->fl_out,prs_arg->out_id,&dmn_new,1);
01104     // add to out list
01105     (void)prs_arg->ptr_dmn_out_vtr->push(dmn_new);
01106     (void)nco_dmn_xrf(dmn_new,dmn_item);
01107     dmn[idx]=dmn_new;
01108   }
01109   (void)nco_enddef(prs_arg->out_id);
01110 
01111   /* Check that un-limited dimension is first dimension */
01112   for(idx=1;idx<dmn_nbr;idx++)
01113     if(dmn[idx]->is_rec_dmn){
01114       (void)sprintf(ncap_err_sng,"Warning:\"%s\" is the record dimension. It can only be the first dimension in a list",dmn[idx]->nm);
01115    (void)fprintf(stderr,ncap_err_sng);
01116       goto end_LHS_sbs;                     
01117     } /* endif */
01118 
01119   /* Create template variable to cast all RHS expressions */
01120   var=(var_sct *)nco_malloc(sizeof(var_sct));
01121   
01122   /* Set defaults */
01123   (void)var_dfl_set(var); /* [fnc] Set defaults for each member of variable structure */
01124   /* Overwrite with LHS information */
01125   /* fxm mmr: memory leak with var->nm */
01126   var->nm=(char *)strdup(tpl_nm);
01127   var->type=NC_DOUBLE;
01128   var->nbr_dim=dmn_nbr;
01129   var->dim=dmn;
01130   /* Allocate space for dimension structures */
01131   if(var->nbr_dim > 0) var->dmn_id=(int *)nco_malloc(var->nbr_dim*sizeof(int)); else var->dmn_id=(int *)NULL;
01132   if(var->nbr_dim > 0) var->cnt=(long *)nco_malloc(var->nbr_dim*sizeof(long)); else var->cnt=(long *)NULL;
01133   if(var->nbr_dim > 0) var->srt=(long *)nco_malloc(var->nbr_dim*sizeof(long)); else var->srt=(long *)NULL;
01134   if(var->nbr_dim > 0) var->end=(long *)nco_malloc(var->nbr_dim*sizeof(long)); else var->end=(long *)NULL;
01135   if(var->nbr_dim > 0) var->srd=(long *)nco_malloc(var->nbr_dim*sizeof(long)); else var->srd=(long *)NULL;
01136   
01137   /* Defensive programming */
01138   var->sz=1L; 
01139   /* Attach LHS dimensions to variable */
01140   for(idx=0;idx<dmn_nbr;idx++){
01141     var->dim[idx]=dmn[idx];
01142     var->dmn_id[idx]=dmn[idx]->id;
01143     var->cnt[idx]=dmn[idx]->cnt;
01144     var->srt[idx]=dmn[idx]->srt;
01145     var->end[idx]=dmn[idx]->end;
01146     var->srd[idx]=dmn[idx]->srd;
01147     var->sz*=var->cnt[idx];
01148   } /* end loop over dim */
01149 
01150 
01151   /* don't initalize val in intial scan  */
01152   if(prs_arg->ntl_scn) {
01153     var->val.vp=(void*)NULL;
01154     goto end_var;
01155   }
01156 
01157   /* Allocate space for variable values 
01158      fxm: more efficient and safer to use nco_calloc() and not fill with values? */
01159   if((var->val.vp=(void *)nco_malloc_flg(var->sz*nco_typ_lng(var->type))) == NULL){
01160     (void)fprintf(stderr,"%s: ERROR Unable to malloc() %ld*%lu bytes for var_LHS() in lexer\n",prg_nm_get(),var->sz,(unsigned long)nco_typ_lng(var->type));
01161     nco_exit(EXIT_FAILURE); 
01162   } /* end if */
01163   
01164   /* Copy arbitrary value into variable 
01165      Placing a uniform value in variable should be unnecessary since variable
01166      is intended for use solely as dimensional template for nco_var_cnf_dmn() 
01167      Nevertheless, copy 1.0 into value for safety */
01168   { /* Change scope to define convenience variables which reduce de-referencing */
01169     long var_sz; /* [nbr] Number of elements in variable */
01170     size_t var_typ_sz; /* [B] Size of single element of variable */
01171     char *var_val_cp; /* [ptr] Pointer to values */
01172     
01173     var_sz=var->sz; /* [nbr] Number of elements in variable */
01174     var_typ_sz=nco_typ_lng(var->type);
01175     var_val_cp=(char *)var->val.vp;
01176     for(idx=0;idx<var_sz;idx++) (void)memcpy(var_val_cp+idx,(void *)(&val),var_typ_sz);
01177   } /* end scope */
01178  end_var:
01179 
01180    
01181   if(dbg_lvl_get() > 2) (void)fprintf(stderr,"%s: Lexer creating LHS cast template: Template var->nm %s, var->nbr_dim %d, var->sz %li\n",prg_nm_get(),var->nm,var->nbr_dim,var->sz);
01182   
01183   /* Free dimension list memory */
01184 
01185    
01186  end_LHS_sbs: /* Errors encountered during LHS processing jump to here */
01187   /* Return to default state, known as INITIAL state or 0 state LMB92 p. 43 */    
01188 
01189   return var;
01190 
01191 } // end ncap_mk_cst

sym_sct* ncap_sym_init const char *const   sym_nm,
double(*)(double)  fnc_dbl,
float(*)(float)  fnc_flt
 

Definition at line 234 of file ncap2_utl.cc.

Referenced by main().

00237 { 
00238   /* Purpose: Allocate space for sym_sct then initialize */
00239   sym_sct *symbol;
00240   symbol=(sym_sct *)nco_malloc(sizeof(sym_sct));
00241   symbol->nm=(char *)strdup(sym_nm);
00242   symbol->fnc_dbl=fnc_dbl;
00243   symbol->fnc_flt=fnc_flt;
00244   return symbol;
00245 } /* end ncap_sym_init() */

var_sct* ncap_var_abs var_sct var  ) 
 

Definition at line 381 of file ncap2_utl.cc.

00381                            : Find absolute value of each element of var */
00382 var_sct *var)    /* I/O [sct] input variable */
00383 {
00384 
00385   if(var->undefined) return var;
00386 
00387   /* deal with inital scan */
00388   if(var->val.vp==NULL) return var; 
00389 
00390   (void)nco_var_abs(var->type,var->sz,var->has_mss_val,var->mss_val,var->val);
00391   return var;
00392 } /* end ncap_var_abs */

var_sct* ncap_var_fnc var_sct var_in,
sym_sct app
 

Definition at line 323 of file ncap2_utl.cc.

00326 {
00327   /* Purpose: Evaluate fnc_dbl(var) or fnc_flt(var) for each value in variable
00328      Float and double functions are in app */
00329   long idx;
00330   long sz;
00331   ptr_unn op1;
00332 
00333   if(var_in->undefined) return var_in;
00334   
00335   
00336   /* Promote variable to NC_FLOAT */
00337   if(var_in->type < NC_FLOAT) var_in=nco_var_cnf_typ((nc_type)NC_FLOAT,var_in);
00338 
00339   /* deal with inital scan */
00340   if(var_in->val.vp==NULL) return var_in; 
00341   
00342 
00343   
00344   op1=var_in->val;
00345   sz=var_in->sz;
00346   (void)cast_void_nctype(var_in->type,&op1);
00347   if(var_in->has_mss_val) (void)cast_void_nctype(var_in->type,&(var_in->mss_val));
00348   
00349   switch(var_in->type){ 
00350   case NC_DOUBLE: {
00351     if(!var_in->has_mss_val){
00352       for(idx=0;idx<sz;idx++) op1.dp[idx]=(*(app->fnc_dbl))(op1.dp[idx]);
00353     }else{
00354       double mss_val_dbl=*(var_in->mss_val.dp); /* Temporary variable reduces de-referencing */
00355       for(idx=0;idx<sz;idx++){
00356         if(op1.dp[idx] != mss_val_dbl) op1.dp[idx]=(*(app->fnc_dbl))(op1.dp[idx]);
00357       } /* end for */
00358     } /* end else */
00359     break;
00360   }
00361   case NC_FLOAT: {
00362     if(!var_in->has_mss_val){
00363       for(idx=0;idx<sz;idx++) op1.fp[idx]=(*(app->fnc_flt))(op1.fp[idx]);
00364     }else{
00365       float mss_val_flt=*(var_in->mss_val.fp); /* Temporary variable reduces de-referencing */
00366       for(idx=0;idx<sz;idx++){
00367         if(op1.fp[idx] != mss_val_flt) op1.fp[idx]=(*(app->fnc_flt))(op1.fp[idx]);
00368       } /* end for */
00369     } /* end else */
00370     break;
00371   }
00372   default: nco_dfl_case_nc_type_err(); break;
00373   }/* end switch */
00374   
00375   if(var_in->has_mss_val) (void)cast_nctype_void(var_in->type,&(var_in->mss_val));
00376   return var_in;
00377 } /* end ncap_var_fnc() */

var_sct* ncap_var_init const char *const   var_nm,
prs_sct prs_arg
 

Definition at line 16 of file ncap2_utl.cc.

00019 {
00020   /* Purpose: Initialize variable structure, retrieve variable values from disk
00021      Parser calls ncap_var_init() when it encounters a new RHS variable */
00022   /* const char fnc_nm[]="ncap_var_init()"; *//* [sng] Function name */
00023 
00024   int idx;
00025   int nbr_dmn_var;
00026   int *dim_id=NULL;
00027   int var_id;
00028   int rcd;
00029   int fl_id;
00030 
00031   char dmn_nm[NC_MAX_NAME];
00032 
00033   dmn_sct *dmn_fd; 
00034   dmn_sct *dmn_nw;
00035   
00036   dmn_sct **dmn_out;  // dereferencing
00037   int nbr_dmn_out  ;  // dereferencing
00038   
00039   var_sct *var;
00040 
00041 
00042   /* Check output file for var */  
00043   rcd=nco_inq_varid_flg(prs_arg->out_id,var_nm,&var_id);
00044   if(rcd == NC_NOERR ){
00045     fl_id=prs_arg->out_id;
00046   }else{
00047     /* Check input file for ID */
00048     rcd=nco_inq_varid_flg(prs_arg->in_id,var_nm,&var_id);
00049     if(rcd != NC_NOERR){
00050       /* Return NULL if variable not in input or output file */
00051       (void)fprintf(stderr,"WARNING unable to find %s in %s or %s\n",var_nm,prs_arg->fl_in,prs_arg->fl_out);    
00052       return (var_sct *)NULL;
00053     } /* end if */
00054     
00055     /* Find dimensions used in var
00056        Learn which are not already in output list prs_arg->dmn_out and output file
00057        Add these to output list and output file */
00058     (void)nco_redef(prs_arg->out_id);
00059     fl_id=prs_arg->in_id;
00060     
00061     (void)nco_inq_varndims(fl_id,var_id,&nbr_dmn_var);
00062     if(nbr_dmn_var>0){
00063       dim_id=(int *)nco_malloc(nbr_dmn_var*sizeof(int));
00064       
00065       (void)nco_inq_vardimid(fl_id,var_id,dim_id);
00066       for(idx=0;idx<nbr_dmn_var;idx++){ 
00067         // get dim name
00068         (void)nco_inq_dimname(fl_id,dim_id[idx],dmn_nm);
00069         // check if dim is already in output
00070         if(prs_arg->ptr_dmn_out_vtr->find(dmn_nm) != NULL) continue; 
00071         // Get dim from input list
00072         dmn_fd= prs_arg->ptr_dmn_in_vtr->find(dmn_nm);
00073         // not in list -- crash out
00074         if(dmn_fd == (dmn_sct*)NULL){
00075           (void)fprintf(stderr,"%s: DEBUG New dimension %s not found in %s or %s\n",prg_nm_get(),dmn_nm ,prs_arg->fl_in, prs_arg->fl_out);
00076           exit(1);
00077         }
00078         dmn_nw=nco_dmn_dpl(dmn_fd);
00079         (void)nco_dmn_xrf(dmn_nw,dmn_fd);
00080         // write dim to output
00081         (void)nco_dmn_dfn(prs_arg->fl_out,prs_arg->out_id,&dmn_nw,1);          
00082         // Add new dim to output list
00083         (void)prs_arg->ptr_dmn_out_vtr->push(dmn_nw);
00084           if(dbg_lvl_get() > 2) (void)fprintf(stderr,"%s: DEBUG Found new dimension %s in input variable %s in file %s. Defining dimension %s in output file %s\n",prg_nm_get(),dmn_nm,var_nm,prs_arg->fl_in,dmn_nm,prs_arg->fl_out);
00085 
00086       }
00087       (void)nco_free(dim_id);
00088     }
00089     (void)nco_enddef(prs_arg->out_id); 
00090   } // end else  
00091   
00092   if(dbg_lvl_get() > 2) (void)fprintf(stderr,"%s: parser VAR action called ncap_var_init() to retrieve %s from disk\n",prg_nm_get(),var_nm);
00093 
00094   nbr_dmn_out=prs_arg->ptr_dmn_out_vtr->size();
00095   dmn_out=prs_arg->ptr_dmn_out_vtr->ptr(0);
00096 
00097   var=nco_var_fll(fl_id,var_id,var_nm,dmn_out,nbr_dmn_out);
00098   /*  var->nm=(char *)nco_malloc((strlen(var_nm)+1UL)*sizeof(char));
00099   (void)strcpy(var->nm,var_nm); */
00100 
00101   /* Tally is not required yet since ncap does not perform cross-file operations (yet) */
00102   /* var->tally=(long *)nco_malloc_dbg(var->sz*sizeof(long),"Unable to malloc() tally buffer in variable initialization",fnc_nm);
00103       (void)nco_zero_long(var->sz,var->tally); */
00104   var->tally=(long *)NULL;
00105 
00106   /* Retrieve variable values from disk into memory */
00107   (void)nco_var_get(fl_id,var); 
00108 
00109   return var;
00110 } /* end ncap_var_init() */

bool ncap_var_lgcl var_sct var  ) 
 

Definition at line 1022 of file ncap2_utl.cc.

References cast_nctype_void(), cast_void_nctype(), var_sct_tag::has_mss_val, var_sct_tag::mss_val, NC_SHORT, nco_var_cnf_typ(), ptr_unn::sp, var_sct_tag::sz, type, and var_sct_tag::val.

01023 {
01024   int idx;
01025   int sz;
01026   nc_type type;
01027   bool bret=true;
01028   ptr_unn op1;
01029   
01030   // Convert to type SHORT
01031   var=nco_var_cnf_typ((nc_type)NC_SHORT,var);  
01032 
01033   type=NC_SHORT;
01034   sz = var->sz;
01035   op1=var->val;
01036   /* Typecast pointer to values before access */
01037   (void)cast_void_nctype(type,&op1);
01038   if(var->has_mss_val) (void)cast_void_nctype(type,&var->mss_val);
01039 
01040 
01041     if(!var->has_mss_val){
01042       for(idx=0;idx<sz;idx++) 
01043         if(!op1.sp[idx]) break;
01044     }else{
01045       const short mss_val_sht=*(var->mss_val.sp);
01046       for(idx=0;idx<sz;idx++) 
01047         if( !op1.sp[idx] &&  op1.sp[idx] !=mss_val_sht ) break; 
01048     }
01049     
01050   if(idx <sz) bret=false;
01051 
01052   if(var->has_mss_val) (void)cast_nctype_void(type,&var->mss_val);
01053 
01054   return bret;
01055 }

nco_bool ncap_var_stretch var_sct **  var_1,
var_sct **  var_2
 

Definition at line 556 of file ncap2_utl.cc.

Referenced by ncap_do_cst().

00558 {
00559   /* Purpose: Make input variables conform or die
00560      var_1 and var_2 are considered completely symmetrically
00561      No assumption is made about var_1 relative to var_2
00562      Main difference betwee ncap_var_stretch() and nco_var_cnf_dmn() is
00563      If variables conform, then ncap_var_stretch() will broadcast
00564      If variables share no dimensions, then ncap_var_stretch() will convolve
00565      
00566      Terminology--- 
00567      Broadcast: Inflate smaller conforming variable to larger variable
00568      Conform: Dimensions of one variable are subset of other variable
00569      Convolve: Construct array whose rank is sum of non-duplicated dimensions
00570      Stretch: Union of broadcast and convolve
00571      
00572      Logic is pared down version of nco_var_cnf_dmn()
00573      1. USE_DUMMY_WGT has been eliminated: 
00574      ncap has no reason not to stretch input variables because grammar
00575      ensures only arithmetic variables will be stretched.
00576      
00577      2. wgt_crr has been eliminated:
00578      ncap never does anything multiple times so no equivalent to wgt_crr exists
00579      
00580      3. ncap_var_stretch(), unlike nco_var_cnf_dmn(), performs memory management
00581      Variables are var_free'd if they are superceded (replaced)
00582      
00583      4. Conformance logic is duplicated from nco_var_cnf_dmn()
00584      var_gtr plays role of var
00585      var_lsr plays role of wgt
00586      var_lsr_out plays role of wgt_out
00587      var_lsr_out=var_lsr only if variables already conform
00588      var_gtr_out is required since both variables may change
00589      var_gtr_out=var_gtr unless convolution is required */
00590   
00591   nco_bool CONFORMABLE=False; /* [flg] Whether var_lsr can be made to conform to var_gtr */
00592   nco_bool CONVOLVE=False; /* [flg] var_1 and var_2 had to be convolved */
00593   nco_bool DO_CONFORM; /* [flg] Did var_1 and var_2 conform? */
00594   nco_bool MUST_CONFORM=False; /* [flg] Must var_1 and var_2 conform? */
00595   
00596   int idx;
00597   int idx_dmn;
00598   int var_lsr_var_gtr_dmn_shr_nbr=0; /* [nbr] Number of dimensions shared by var_lsr and var_gtr */
00599   
00600   var_sct *var_gtr=NULL; /* [ptr] Pointer to variable structure of greater rank */
00601   var_sct *var_lsr=NULL; /* [ptr] Pointer to variable structure to lesser rank */
00602   var_sct *var_gtr_out=NULL; /* [ptr] Pointer to stretched version of greater rank variable */
00603   var_sct *var_lsr_out=NULL; /* [ptr] Pointer to stretched version of lesser rank variable */
00604   
00605   /* Initialize flag to false. Overwrite by true after successful conformance */
00606   DO_CONFORM=False;
00607   
00608   /* Determine which variable is greater and which lesser rank */
00609   if((*var_1)->nbr_dim >= (*var_2)->nbr_dim){
00610     var_gtr=*var_1;
00611     var_lsr=*var_2;
00612   }else{
00613     var_gtr=*var_2;
00614     var_lsr=*var_1;
00615   } /* endif */
00616   
00617   /* var_gtr_out=var_gtr unless convolution is required */
00618   var_gtr_out=var_gtr;
00619   
00620   /* Does lesser variable (var_lsr) conform to greater variable's dimensions? */
00621   if(var_lsr_out == NULL){
00622     if(var_gtr->nbr_dim > 0){
00623       /* Test that all dimensions in var_lsr appear in var_gtr */
00624       for(idx=0;idx<var_lsr->nbr_dim;idx++){
00625         for(idx_dmn=0;idx_dmn<var_gtr->nbr_dim;idx_dmn++){
00626           /* Compare names, not dimension IDs */
00627           if(!strcmp(var_lsr->dim[idx]->nm,var_gtr->dim[idx_dmn]->nm)){
00628             var_lsr_var_gtr_dmn_shr_nbr++; /* var_lsr and var_gtr share this dimension */
00629             break;
00630           } /* endif */
00631         } /* end loop over var_gtr dimensions */
00632       } /* end loop over var_lsr dimensions */
00633       /* Decide whether var_lsr and var_gtr dimensions conform, are mutually exclusive, or are partially exclusive */ 
00634       if(var_lsr_var_gtr_dmn_shr_nbr == var_lsr->nbr_dim){
00635         /* var_lsr and var_gtr conform */
00636         /* fxm: Variables do not conform when dimension list of one is subset of other if order of dimensions differs, i.e., a(lat,lev,lon) !~ b(lon,lev) */
00637         CONFORMABLE=True;
00638       }else if(var_lsr_var_gtr_dmn_shr_nbr == 0){
00639         /* Dimensions in var_lsr and var_gtr are mutually exclusive */
00640         CONFORMABLE=False;
00641         if(MUST_CONFORM){
00642           (void)fprintf(stdout,"%s: ERROR %s and template %s share no dimensions\n",prg_nm_get(),var_lsr->nm,var_gtr->nm);
00643           nco_exit(EXIT_FAILURE);
00644         }else{
00645           if(dbg_lvl_get() >= 1) (void)fprintf(stdout,"\n%s: DEBUG %s and %s share no dimensions: Attempting to convolve...\n",prg_nm_get(),var_lsr->nm,var_gtr->nm);
00646           CONVOLVE=True;
00647         } /* endif */
00648       }else if(var_lsr_var_gtr_dmn_shr_nbr > 0 && var_lsr_var_gtr_dmn_shr_nbr < var_lsr->nbr_dim){
00649         /* Some, but not all, of var_lsr dimensions are in var_gtr */
00650         CONFORMABLE=False;
00651         if(MUST_CONFORM){
00652           (void)fprintf(stdout,"%s: ERROR %d dimensions of %s belong to template %s but %d dimensions do not\n",prg_nm_get(),var_lsr_var_gtr_dmn_shr_nbr,var_lsr->nm,var_gtr->nm,var_lsr->nbr_dim-var_lsr_var_gtr_dmn_shr_nbr);
00653           nco_exit(EXIT_FAILURE);
00654         }else{
00655           if(dbg_lvl_get() >= 1) (void)fprintf(stdout,"\n%s: DEBUG %d dimensions of %s belong to template %s but %d dimensions do not: Not broadcasting %s to %s, could attempt stretching???\n",prg_nm_get(),var_lsr_var_gtr_dmn_shr_nbr,var_lsr->nm,var_gtr->nm,var_lsr->nbr_dim-var_lsr_var_gtr_dmn_shr_nbr,var_lsr->nm,var_gtr->nm);
00656           CONVOLVE=True;
00657         } /* endif */
00658       } /* end if */
00659       if(CONFORMABLE){
00660         if(var_gtr->nbr_dim == var_lsr->nbr_dim){
00661           /* var_gtr and var_lsr conform and are same rank */
00662           /* Test whether all var_lsr and var_gtr dimensions match in sequence */
00663           for(idx=0;idx<var_gtr->nbr_dim;idx++){
00664             if(strcmp(var_lsr->dim[idx]->nm,var_gtr->dim[idx]->nm)) break;
00665           } /* end loop over dimensions */
00666           /* If so, take shortcut and copy var_lsr to var_lsr_out */
00667           if(idx == var_gtr->nbr_dim) DO_CONFORM=True;
00668         }else{
00669           /* var_gtr and var_lsr conform but are not same rank, set flag to proceed to generic conform routine */
00670           DO_CONFORM=False;
00671         } /* end else */
00672       } /* endif CONFORMABLE */
00673     }else{ /* nbr_dmn == 0 */
00674       /* var_gtr is scalar, if var_lsr is also then set flag to copy var_lsr to var_lsr_out else proceed to generic conform routine */
00675       if(var_lsr->nbr_dim == 0) DO_CONFORM=True; else DO_CONFORM=False;
00676     } /* end else nbr_dmn == 0 */
00677     if(CONFORMABLE && DO_CONFORM){
00678       var_lsr_out=nco_var_dpl(var_lsr);
00679       (void)nco_xrf_var(var_lsr,var_lsr_out);
00680     } /* end if */
00681   } /* endif var_lsr_out == NULL */
00682   
00683   if(var_lsr_out == NULL && CONVOLVE){
00684     /* Convolve variables by returned stretched variables with minimum possible number of dimensions */
00685     int dmn_nbr; /* Number of dimensions in convolution */
00686     if(dbg_lvl_get() >= 1) (void)fprintf(stdout,"\n%s: WARNING Convolution not yet implemented, results of operation between %s and %s are unpredictable\n",prg_nm_get(),var_lsr->nm,var_gtr->nm);
00687     /* Dimensions in convolution are union of dimensions in variables */
00688     dmn_nbr=var_lsr->nbr_dim+var_gtr->nbr_dim-var_lsr_var_gtr_dmn_shr_nbr; /* Number of dimensions in convolution */
00689     dmn_nbr=dmn_nbr; /* CEWI: Avert compiler warning that variable is set but never used */
00690     /* fxm: these should go away soon */
00691     var_lsr_out=nco_var_dpl(var_lsr);
00692     var_gtr_out=nco_var_dpl(var_gtr);
00693 
00694     /* for(idx_dmn=0;idx_dmn<var_gtr->nbr_dim;idx_dmn++){;}
00695        if(var_lsr_var_gtr_dmn_shr_nbr == 0); else; */
00696     
00697     /* Free calling variables */
00698     var_lsr=nco_var_free(var_lsr);
00699     var_gtr=nco_var_free(var_gtr);
00700   } /* endif STRETCH */
00701   
00702   if(var_lsr_out == NULL){
00703     /* Expand lesser variable (var_lsr) to match size of greater variable */
00704     const char fnc_nm[]="ncap_var_stretch()"; /* [sng] Function name */
00705     char *var_lsr_cp;
00706     char *var_lsr_out_cp;
00707     
00708     int idx_var_lsr_var_gtr[NC_MAX_DIMS];
00709     int var_lsr_nbr_dim;
00710     int var_gtr_nbr_dmn_m1;
00711     
00712     long *var_gtr_cnt;
00713     long dmn_ss[NC_MAX_DIMS];
00714     long dmn_var_gtr_map[NC_MAX_DIMS];
00715     long dmn_var_lsr_map[NC_MAX_DIMS];
00716     long var_gtr_lmn;
00717     long var_lsr_lmn;
00718     long var_gtr_sz;
00719     
00720     size_t var_lsr_typ_sz;
00721     
00722     /* Copy main attributes of greater variable into lesser variable */
00723     var_lsr_out=nco_var_dpl(var_gtr);
00724     (void)nco_xrf_var(var_lsr,var_lsr_out);
00725     
00726     /* Modify elements of lesser variable array */
00727     var_lsr_out->nm=(char *)nco_free(var_lsr_out->nm);
00728     var_lsr_out->nm=(char *)strdup(var_lsr->nm);
00729     var_lsr_out->id=var_lsr->id;
00730     var_lsr_out->type=var_lsr->type;
00731     /* Added 20050323: 
00732        Not quite sure why, but var->val.vp may already have values here when LHS-casting
00733        Perform safety free to guard against memory leaks */
00734     var_lsr_out->val.vp=nco_free(var_lsr_out->val.vp);
00735     var_lsr_out->val.vp=(void *)nco_malloc_dbg(var_lsr_out->sz*nco_typ_lng(var_lsr_out->type),"Unable to malloc() value buffer in variable stretching",fnc_nm);
00736     var_lsr_cp=(char *)var_lsr->val.vp;
00737     var_lsr_out_cp=(char *)var_lsr_out->val.vp;
00738     var_lsr_typ_sz=nco_typ_lng(var_lsr_out->type);
00739     
00740     if(var_lsr_out->nbr_dim == 0){
00741       /* Variables are scalars, not arrays */
00742       (void)memcpy(var_lsr_out_cp,var_lsr_cp,var_lsr_typ_sz);
00743     }else if(var_lsr->nbr_dim == 0){
00744       /* Lesser-ranked input variable is scalar 
00745          Expansion in this degenerate case needs no index juggling (reverse-mapping)
00746          Code as special case to speed-up important applications of ncap
00747          for synthetic file creation */
00748       var_gtr_sz=var_gtr->sz;
00749       for(var_gtr_lmn=0;var_gtr_lmn<var_gtr_sz;var_gtr_lmn++){
00750         (void)memcpy(var_lsr_out_cp+var_gtr_lmn*var_lsr_typ_sz,var_lsr_cp,var_lsr_typ_sz);
00751       } /* end loop over var_gtr_lmn */
00752     }else{
00753       /* Variables are arrays, not scalars */
00754       
00755       /* Create forward and reverse mappings from greater variable's dimensions to lesser variable's dimensions:
00756          
00757       dmn_var_gtr_map[i] is number of elements between one value of i_th 
00758       dimension of greater variable and next value of i_th dimension, i.e., 
00759       number of elements in memory between indicial increments in i_th dimension. 
00760       This is computed as product of one (1) times size of all dimensions (if any) after i_th 
00761       dimension in greater variable.
00762       
00763       dmn_var_lsr_map[i] contains analogous information, except for lesser variable
00764       
00765       idx_var_lsr_var_gtr[i] contains index into greater variable's dimensions of i_th dimension of lesser variable
00766       idx_var_gtr_var_lsr[i] contains index into lesser variable's dimensions of i_th dimension of greater variable 
00767       
00768       Since lesser variable is a subset of greater variable, some elements of idx_var_gtr_var_lsr may be "empty", or unused
00769       
00770       Since mapping arrays (dmn_var_gtr_map and dmn_var_lsr_map) are ultimately used for a
00771       memcpy() operation, they could (read: should) be computed as byte offsets, not type offsets.
00772       This is why netCDF generic hyperslab routines (ncvarputg(), ncvargetg())
00773       request imap vector to specify offset (imap) vector in bytes. */
00774       for(idx=0;idx<var_lsr->nbr_dim;idx++){
00775         for(idx_dmn=0;idx_dmn<var_gtr->nbr_dim;idx_dmn++){
00776           /* Compare names, not dimension IDs */
00777           if(!strcmp(var_gtr->dim[idx_dmn]->nm,var_lsr->dim[idx]->nm)){
00778             idx_var_lsr_var_gtr[idx]=idx_dmn;
00779             /*      idx_var_gtr_var_lsr[idx_dmn]=idx;*/
00780             break;
00781           } /* end if */
00782           /* Sanity check */
00783           if(idx_dmn == var_gtr->nbr_dim-1){
00784             (void)fprintf(stdout,"%s: ERROR var_lsr %s has dimension %s but var_gtr %s does not deep in ncap_var_stretch()\n",prg_nm_get(),var_lsr->nm,var_lsr->dim[idx]->nm,var_gtr->nm);
00785             nco_exit(EXIT_FAILURE);
00786           } /* end if err */
00787         } /* end loop over greater variable dimensions */
00788       } /* end loop over lesser variable dimensions */
00789       
00790       /* Figure out map for each dimension of greater variable */
00791       for(idx=0;idx<var_gtr->nbr_dim;idx++) dmn_var_gtr_map[idx]=1L;
00792       for(idx=0;idx<var_gtr->nbr_dim-1;idx++)
00793         for(idx_dmn=idx+1;idx_dmn<var_gtr->nbr_dim;idx_dmn++)
00794           dmn_var_gtr_map[idx]*=var_gtr->cnt[idx_dmn];
00795       
00796       /* Figure out map for each dimension of lesser variable */
00797       for(idx=0;idx<var_lsr->nbr_dim;idx++) dmn_var_lsr_map[idx]=1L;
00798       for(idx=0;idx<var_lsr->nbr_dim-1;idx++)
00799         for(idx_dmn=idx+1;idx_dmn<var_lsr->nbr_dim;idx_dmn++)
00800           dmn_var_lsr_map[idx]*=var_lsr->cnt[idx_dmn];
00801       
00802       /* Define convenience variables to avoid repetitive indirect addressing */
00803       var_lsr_nbr_dim=var_lsr->nbr_dim;
00804       var_gtr_sz=var_gtr->sz;
00805       var_gtr_cnt=var_gtr->cnt;
00806       var_gtr_nbr_dmn_m1=var_gtr->nbr_dim-1;
00807       
00808       /* var_gtr_lmn is offset into 1-D array corresponding to N-D indices dmn_ss */
00809       for(var_gtr_lmn=0;var_gtr_lmn<var_gtr_sz;var_gtr_lmn++){
00810         dmn_ss[var_gtr_nbr_dmn_m1]=var_gtr_lmn%var_gtr_cnt[var_gtr_nbr_dmn_m1];
00811         for(idx=0;idx<var_gtr_nbr_dmn_m1;idx++){
00812           dmn_ss[idx]=(long)(var_gtr_lmn/dmn_var_gtr_map[idx]);
00813           dmn_ss[idx]%=var_gtr_cnt[idx];
00814         } /* end loop over dimensions */
00815         
00816         /* Map (shared) N-D array indices into 1-D index into original lesser variable data */
00817         var_lsr_lmn=0L;
00818         for(idx=0;idx<var_lsr_nbr_dim;idx++) var_lsr_lmn+=dmn_ss[idx_var_lsr_var_gtr[idx]]*dmn_var_lsr_map[idx];
00819         
00820         (void)memcpy(var_lsr_out_cp+var_gtr_lmn*var_lsr_typ_sz,var_lsr_cp+var_lsr_lmn*var_lsr_typ_sz,var_lsr_typ_sz);
00821         
00822       } /* end loop over var_gtr_lmn */
00823       
00824     } /* end if greater variable (and lesser variable) are arrays, not scalars */
00825     
00826     DO_CONFORM=True;
00827   } /* end if we had to broadcast lesser variable to fit greater variable */
00828   
00829   /* Place variables in original order
00830      Not necessary if variables are used in binary operations that are associative
00831      But do not want to require that assumption of calling routines */
00832   if((*var_1)->nbr_dim >= (*var_2)->nbr_dim){
00833     *var_1=var_gtr_out; /* [ptr] First variable */
00834     *var_2=var_lsr_out; /* [ptr] Second variable */
00835   }else{
00836     *var_1=var_lsr_out; /* [ptr] First variable */
00837     *var_2=var_gtr_out; /* [ptr] Second variable */
00838   } /* endif */
00839   
00840   /* Variables now conform */
00841   return DO_CONFORM;
00842 } /* end ncap_var_stretch() */

var_sct* ncap_var_var_mod var_sct var_1,
var_sct var_2
 

Definition at line 250 of file ncap2_utl.cc.

00252 {
00253   /* Purpose: Remainder (modulo) operation of two variables (var_1%var_2) */
00254   /* Store result in var_2 */
00255   if(var_1->undefined) var_2->undefined=True;
00256     if(var_2->undefined) {
00257     var_1=nco_var_free(var_1);
00258     return var_2;
00259   }
00260   (void)ncap_var_retype(var_1,var_2);
00261    
00262   /* Handle initial scan */
00263   if(var_1->val.vp==(void*)NULL ) {
00264     if(var_1->nbr_dim > var_2->nbr_dim) {
00265       var_2=nco_var_free(var_2);
00266       return var_1;
00267     }else{
00268       var_1=nco_var_free(var_1);
00269       return var_2;
00270     }
00271   } 
00272 
00273 
00274  
00275   (void)ncap_var_cnf_dmn(&var_1,&var_2);
00276   if(var_1->has_mss_val){
00277     (void)nco_var_mod(var_1->type,var_1->sz,var_1->has_mss_val,var_1->mss_val,var_1->val,var_2->val);
00278   }else{
00279     (void)nco_var_mod(var_1->type,var_1->sz,var_2->has_mss_val,var_2->mss_val,var_1->val,var_2->val);
00280   } /* end else */
00281    
00282    var_1=nco_var_free(var_1);
00283    return var_2;
00284 } /* end ncap_var_var_mod() */

var_sct* ncap_var_var_op var_sct var1,
var_sct var2,
int  op
 

Definition at line 887 of file ncap2_utl.cc.

References EXIT_FAILURE, NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT, ncap_att_stretch(), ncap_var_cnf_dmn(), ncap_var_is_att(), ncap_var_retype(), nco_bool, nco_exit(), nco_var_cnf_typ(), nco_var_free(), var_sct_tag::nm, prg_nm_get(), var_sct_tag::sz, var_sct_tag::type, var_sct_tag::val, VarOp< T >::var_op(), and VarOp< T >::var_var_op().

00890 { 
00891   nco_bool vb1;
00892   nco_bool vb2;
00893 
00894 
00895   static VarOp<short> Vs;
00896   static VarOp<nco_int> Vl;
00897   static VarOp<float> Vf;
00898   static VarOp<double> Vd;
00899   
00900   struct ncoParserTokenTypes TT;
00901   var_sct *var_ret;
00902 
00903   //If var2 is null then we are dealing with a unary function
00904   if( var2 == NULL) {
00905 
00906    switch (var1->type) {
00907     case NC_BYTE:
00908     /* Do nothing */
00909       break;
00910     case NC_CHAR:
00911     /* Do nothing */
00912       break;
00913     case NC_SHORT:
00914       var_ret=Vs.var_op(var1,op);
00915       break;
00916     case NC_INT:
00917       var_ret=Vl.var_op(var1,op);
00918       break;            
00919     case NC_FLOAT:
00920       var_ret=Vf.var_op(var1 ,op);
00921       break;
00922   case NC_DOUBLE:
00923       var_ret=Vd.var_op(var1, op);
00924       break;
00925 
00926   default:
00927     break;
00928 
00929    }
00930    return var_ret;
00931   }
00932   
00933   
00934   vb1 = ncap_var_is_att(var1);
00935   vb2 = ncap_var_is_att(var2);
00936 
00937   // var & var
00938   if( !vb1 && !vb2 ) { 
00939     (void)ncap_var_retype(var1,var2);
00940     (void)ncap_var_cnf_dmn(&var1,&var2);
00941     // var & att
00942   }else  if( !vb1 && vb2 ){ 
00943     var2=nco_var_cnf_typ(var1->type,var2);
00944     if(var1->sz > 1 && var2->sz==1)
00945       (void)ncap_var_cnf_dmn(&var1,&var2);
00946       
00947     if(var1->sz != var2->sz) {
00948        (void)fprintf(stderr,"%s: Cannot make variable:%s and attribute:%s conform. So connot perform atrithmetic operation\n",prg_nm_get(),var1->nm,var2->nm);
00949        nco_exit(EXIT_FAILURE);
00950         }
00951        
00952     // att & var
00953     }else if( vb1 && !vb2){
00954       var_sct *var_swp;
00955       ptr_unn val_swp;  // Used to swap values around
00956 
00957       var1=nco_var_cnf_typ(var2->type,var1);
00958      if(var2->sz > 1 && var1->sz==1)
00959       (void)ncap_var_cnf_dmn(&var1,&var2);
00960       
00961      if(var1->sz != var2->sz) {
00962        (void)fprintf(stderr,"%s: Cannot make variable:%s and attribute:%s conform. So connot perform atrithmetic operation\n",prg_nm_get(),var2->nm,var1->nm);
00963        nco_exit(EXIT_FAILURE);
00964      }
00965      // Swap values around in var1 and var2;   
00966      val_swp=var1->val;
00967      var1->val=var2->val;
00968      var2->val=val_swp;;
00969      // Swap names about 
00970      var_swp=var1;
00971      var1=var2;
00972      var2=var_swp;
00973 
00974      // att && att
00975     } else if (vb1 && vb2) {
00976       (void)ncap_var_retype(var1,var2);
00977      
00978       if( var1->sz ==1 && var2->sz >1) 
00979         (void)ncap_att_stretch(var1,var2->sz);
00980       else if(var1->sz >1 && var2->sz==1)
00981         (void)ncap_att_stretch(var2,var1->sz);
00982 
00983       // Crash out if atts not equal size
00984       if(var1->sz != var2->sz) {
00985        (void)fprintf(stderr,"%s: Cannot make attribute:%s and attribute:%s conform. So connot perform atrithmetic operation\n",prg_nm_get(),var2->nm,var1->nm);
00986        nco_exit(EXIT_FAILURE);
00987       }
00988              
00989     }
00990 
00991   switch (var1->type) {
00992     case NC_BYTE:
00993     /* Do nothing */
00994       break;
00995     case NC_CHAR:
00996     /* Do nothing */
00997       break;
00998     case NC_SHORT:
00999       var_ret=Vs.var_var_op(var1, var2,op);
01000       break;
01001     case NC_INT:
01002       var_ret=Vl.var_var_op(var1, var2,op);
01003       break;            
01004     case NC_FLOAT:
01005       var_ret=Vf.var_var_op(var1, var2,op);
01006       break;
01007   case NC_DOUBLE:
01008       var_ret=Vd.var_var_op(var1, var2,op);
01009       break;
01010 
01011   default:
01012     break;
01013 
01014   } 
01015 
01016   var2=nco_var_free(var2);
01017   return var_ret;
01018 }

var_sct* ncap_var_var_pwr var_sct var_1,
var_sct var_2
 

Definition at line 288 of file ncap2_utl.cc.

00290 {
00291   /* Purpose: Empower two variables (var_1^var_2) */
00292 
00293   if(var_1->undefined) var_2->undefined=True;
00294     if(var_2->undefined) {
00295     var_1=nco_var_free(var_1);
00296     return var_2;
00297   }
00298   /* make sure vars are at least float */
00299 
00300   (void)ncap_var_retype(var_1,var_2);   
00301 
00302   /* Handle initial scan */
00303   if(var_1->val.vp==(void*)NULL ) {
00304     if(var_1->nbr_dim > var_2->nbr_dim) {
00305       var_2=nco_var_free(var_2);
00306       return var_1;
00307     }else{
00308       var_1=nco_var_free(var_1);
00309       return var_2;
00310     }
00311   } 
00312 
00313   (void)ncap_var_cnf_dmn(&var_1,&var_2);
00314   if(var_1->has_mss_val){
00315     (void)nco_var_pwr(var_1->type,var_1->sz,var_1->has_mss_val,var_1->mss_val,var_1->val,var_2->val);
00316   }else{
00317     (void)nco_var_pwr(var_1->type,var_1->sz,var_2->has_mss_val,var_2->mss_val,var_1->val,var_2->val);
00318   } /* end else */
00319    return var_2;
00320 } /* end ncap_var_var_pwr() */

int ncap_var_write var_sct var,
prs_sct prs_arg
 

Definition at line 115 of file ncap2_utl.cc.

00117 {
00118 
00119   /* Purpose: Define variable in output file and write variable */
00120   const char mss_val_sng[]="missing_value"; /* [sng] Unidata standard string for missing value */
00121   const char add_fst_sng[]="add_offset"; /* [sng] Unidata standard string for add offset */
00122   const char scl_fct_sng[]="scale_factor"; /* [sng] Unidata standard string for scale factor */
00123   int rcd; /* [rcd] Return code */
00124   int var_out_id;
00125 
00126 #ifdef NCO_RUSAGE_DBG
00127   long maxrss; /* [B] Maximum resident set size */
00128 #endif /* !NCO_RUSAGE_DBG */
00129 
00130 
00131   rcd=nco_inq_varid_flg(prs_arg->out_id,var->nm,&var_out_id);
00132 
00133   if(rcd == NC_NOERR){
00134     (void)fprintf(stdout,"Warning: Variable %s has aleady been saved in %s",var->nm,prs_arg->fl_out);
00135     var = nco_var_free(var);
00136     return False;
00137   }
00138   
00139   /* Put file in define mode to allow metadata writing */
00140   (void)nco_redef(prs_arg->out_id);
00141   
00142   /* Define variable */   
00143   (void)nco_def_var(prs_arg->out_id,var->nm,var->type,var->nbr_dim,var->dmn_id,&var_out_id);
00144   /* Put missing value */  
00145   if(var->has_mss_val) (void)nco_put_att(prs_arg->out_id,var_out_id,mss_val_sng,var->type,1,var->mss_val.vp);
00146   
00147       /* Write/overwrite scale_factor and add_offset attributes */
00148   if(var->pck_ram){ /* Variable is packed in memory */
00149   if(var->has_scl_fct) (void)nco_put_att(prs_arg->out_id,var_out_id,scl_fct_sng,var->typ_upk,1,var->scl_fct.vp);
00150   if(var->has_add_fst) (void)nco_put_att(prs_arg->out_id,var_out_id,add_fst_sng,var->typ_upk,1,var->add_fst.vp);
00151       } /* endif pck_ram */
00152 
00153   /* Take output file out of define mode */
00154   (void)nco_enddef(prs_arg->out_id);
00155   
00156   /* Write variable */ 
00157   if(var->nbr_dim == 0){
00158     (void)nco_put_var1(prs_arg->out_id,var_out_id,0L,var->val.vp,var->type);
00159   }else{
00160     (void)nco_put_vara(prs_arg->out_id,var_out_id,var->srt,var->cnt,var->val.vp,var->type);
00161   } /* end else */
00162   
00163 #ifdef NCO_RUSAGE_DBG
00164   /* Compile: cd ~/nco/bld;make 'USR_TKN=-DNCO_RUSAGE_DBG';cd - */
00165   /* Print rusage memory usage statistics */
00166   if(dbg_lvl_get() >= 0) (void)fprintf(stdout,"%s: INFO ncap_var_write() writing variable %s\n",prg_nm_get(),var->nm);
00167   maxrss=nco_mmr_rusage_prn((int)0);
00168 #endif /* !NCO_RUSAGE_DBG */
00169 
00170   /* Free varible */
00171   var=nco_var_free(var);
00172 
00173   return True;
00174 } /* end ncap_var_write() */

nm_id_sct* nco_att_lst_mk const int  in_id,
const int  out_id,
NcapVarVector var_vtr,
int *  nbr_lst
 

Definition at line 517 of file ncap2_utl.cc.

Referenced by main().

00521 {
00522   int idx;
00523   int jdx;
00524   int rcd;
00525   int var_id;
00526   int size=0;
00527   char var_nm[NC_MAX_NAME];
00528   nm_id_sct *xtr_lst=NULL;  
00529   for(idx=0;idx<var_vtr.size();idx++){
00530     // Check for attribute
00531     if( var_vtr[idx]->type !=ncap_att) continue;
00532     (void)strcpy(var_nm, var_vtr[idx]->getVar().c_str());
00533 
00534     rcd=nco_inq_varid_flg(out_id,var_nm,&var_id);
00535     if(rcd== NC_NOERR) continue;   
00536     rcd=nco_inq_varid_flg(in_id,var_nm,&var_id);   
00537     if(rcd == NC_NOERR){
00538       /* eliminate any duplicates from list */
00539       for(jdx=0;jdx<size;jdx++)
00540         if(!strcmp(xtr_lst[jdx].nm,var_nm)) break;
00541       if(jdx!=size) continue;
00542       /* fxm mmr TODO 491: memory leak xtr_lst */
00543       xtr_lst=(nm_id_sct *)nco_realloc(xtr_lst,(size+1)*sizeof(nm_id_sct));
00544       xtr_lst[size].id=var_id;
00545       xtr_lst[size++].nm=(char *)strdup(var_nm);
00546     } /* end if */
00547   } /* end loop over att */
00548   
00549   *nbr_lst=size;
00550   
00551   return xtr_lst;
00552 } /* end nco_att_lst_mk() */

nm_id_sct* nco_dmn_lst const int  nc_id,
int *const   nbr_dmn
 

Definition at line 493 of file ncap2_utl.cc.

Referenced by main().

00495 {
00496   int idx;
00497   int nbr_dmn_in;
00498   char dmn_nm[NC_MAX_NAME];
00499   nm_id_sct *dmn;
00500   /* Get number of dimensions */
00501   (void)nco_inq(nc_id,&nbr_dmn_in,(int *)NULL,(int *)NULL,(int *)NULL);
00502   
00503   dmn=(nm_id_sct *)nco_malloc(nbr_dmn_in*sizeof(nm_id_sct));
00504   
00505   for(idx=0;idx<nbr_dmn_in;idx++){
00506     (void)nco_inq_dimname(nc_id,idx,dmn_nm);
00507     dmn[idx].id=idx;
00508     dmn[idx].nm=(char *)strdup(dmn_nm);
00509   } /* end loop over dmn */
00510   
00511   *nbr_dmn=nbr_dmn_in;
00512   return dmn;
00513 } /* end nco_dmn_lst() */

nm_id_sct* nco_var_lst_add nm_id_sct xtr_lst,
int *  nbr_xtr,
nm_id_sct xtr_lst_a,
int  nbr_lst_a
 

Definition at line 450 of file ncap2_utl.cc.

00455 {
00456   /* Purpose: Add to xtr_lst any elements from xtr_lst_a not already present and return new list */
00457   int idx;
00458   int xtr_idx;
00459   int nbr_xtr_crr;
00460   
00461   nm_id_sct *xtr_new_lst;
00462   
00463   nco_bool match;
00464   
00465   nbr_xtr_crr=*nbr_xtr;
00466   if(nbr_xtr_crr > 0){
00467     xtr_new_lst=(nm_id_sct*)nco_malloc((size_t)(*nbr_xtr)*sizeof(nm_id_sct));
00468     for(idx=0;idx<nbr_xtr_crr;idx++){
00469       xtr_new_lst[idx].nm=(char *)strdup(xtr_lst[idx].nm);
00470       xtr_new_lst[idx].id=xtr_lst[idx].id;
00471     } /* end loop over variables */
00472   }else{
00473     *nbr_xtr=nbr_lst_a;
00474     return nco_var_lst_copy(xtr_lst_a,nbr_lst_a);
00475   }/* end if */
00476   
00477   for(idx=0;idx<nbr_lst_a;idx++){
00478     match=False;
00479     for(xtr_idx=0;xtr_idx<*nbr_xtr;xtr_idx++)
00480       if(!strcmp(xtr_lst[xtr_idx].nm,xtr_lst_a[idx].nm)){match=True;break;}
00481     if(match) continue;
00482     xtr_new_lst=(nm_id_sct *)nco_realloc(xtr_new_lst,(size_t)(nbr_xtr_crr+1)*sizeof(nm_id_sct));
00483     xtr_new_lst[nbr_xtr_crr].nm=(char *)strdup(xtr_lst_a[idx].nm);
00484     xtr_new_lst[nbr_xtr_crr++].id=xtr_lst_a[idx].id;
00485   } /* end for */
00486   *nbr_xtr=nbr_xtr_crr;
00487   return xtr_new_lst;           
00488 } /* end nco_var_lst_add */

nm_id_sct* nco_var_lst_copy nm_id_sct xtr_lst,
int  lst_nbr
 

Definition at line 396 of file ncap2_utl.cc.

Referenced by nco_var_lst_add().

00396                                          : Copy xtr_lst and return new list */
00397 nm_id_sct *xtr_lst,    /* I  [sct] input list */ 
00398 int lst_nbr)           /* I  [nbr] number of elements in list */
00399 {
00400   int idx;
00401   nm_id_sct *xtr_new_lst;
00402   
00403   if(lst_nbr == 0) return NULL;
00404   xtr_new_lst=(nm_id_sct *)nco_malloc(lst_nbr*sizeof(nm_id_sct));
00405   for(idx=0;idx<lst_nbr;idx++){
00406     xtr_new_lst[idx].nm=(char *)strdup(xtr_lst[idx].nm);
00407     xtr_new_lst[idx].id=xtr_lst[idx].id;
00408   } /* end loop over variable */
00409   return xtr_new_lst;           
00410 } /* end nco_var_lst_copy() */

nm_id_sct* nco_var_lst_sub nm_id_sct xtr_lst,
int *  nbr_xtr,
nm_id_sct xtr_lst_b,
int  nbr_lst_b
 

Definition at line 414 of file ncap2_utl.cc.

Referenced by main().

00419 {
00420   /* Purpose: Subtract from xtr_lst any elements from xtr_lst_b which are present and return new list */
00421   int idx;
00422   int xtr_idx;
00423   int xtr_nbr_new=0;
00424   
00425   nco_bool match;
00426   
00427   nm_id_sct *xtr_new_lst=NULL;
00428   
00429   if(*nbr_xtr == 0) return xtr_lst;
00430   
00431   xtr_new_lst=(nm_id_sct*)nco_malloc((size_t)(*nbr_xtr)*sizeof(nm_id_sct)); 
00432   for(idx=0;idx<*nbr_xtr;idx++){
00433     match=False;
00434     for(xtr_idx=0;xtr_idx<nbr_lst_b;xtr_idx++)
00435       if(!strcmp(xtr_lst[idx].nm,xtr_lst_b[xtr_idx].nm)){match=True;break;}
00436     if(match) continue;
00437     xtr_new_lst[xtr_nbr_new].nm=(char *)strdup(xtr_lst[idx].nm);
00438     xtr_new_lst[xtr_nbr_new++].id=xtr_lst[idx].id;
00439   } /* end loop over idx */
00440   /* realloc to actual size */
00441   xtr_new_lst=(nm_id_sct*)nco_realloc(xtr_new_lst,xtr_nbr_new*sizeof(nm_id_sct)); 
00442   /* free old list */
00443   xtr_lst=nco_nm_id_lst_free(xtr_lst,*nbr_xtr);
00444 
00445   *nbr_xtr=xtr_nbr_new;
00446   return xtr_new_lst;     
00447 }/* end nco_var_lst_sub */


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