#include <stdio.h>#include <string.h>#include <netcdf.h>#include "nco_netcdf.h"#include "nco.h"#include "nco_cnf_typ.h"#include "nco_mmr.h"#include "nco_prn.h"#include "nco_sng_utl.h"Include dependency graph for nco_mss_val.h:

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

Go to the source code of this file.
Functions | |
| ptr_unn | nco_mss_val_mk (const nc_type type) |
| bool | nco_mss_val_cnf (var_sct *const var1, var_sct *const var2) |
| void | nco_mss_val_cp (const var_sct *const var1, var_sct *const var2) |
| int | nco_mss_val_get (const int nc_id, var_sct *const var) |
|
||||||||||||
|
Definition at line 44 of file nco_mss_val.c. References ptr_unn::bp, cast_nctype_void(), cast_void_nctype(), ptr_unn::cp, ptr_unn::dp, False, ptr_unn::fp, var_sct_tag::has_mss_val, long_CEWI, ptr_unn::lp, var_sct_tag::mss_val, NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_NAT, NC_SHORT, nco_dfl_case_nc_type_err(), NCO_MAX_LEN_FMT_SNG, nco_mss_val_cp(), nco_typ_fmt_sng(), nco_typ_sng(), var_sct_tag::nm, prg_nm_get(), ptr_unn::sp, and var_sct_tag::type. Referenced by main(), and VarOp< T >::var_var_op(). 00046 { 00047 /* Purpose: 00048 1. Change missing_value of var2 to missing_value of var1 when both exist 00049 2. Change missing_value of var1 to missing_value of var2 when only var2 has a missing_value 00050 3. Change missing_value of var2 to missing_value of var1 when only var1 has a missing_value 00051 4. Return false when neither operand has missing value */ 00052 int has_mss_val=False; /* [flg] One or both operands have missing value */ 00053 bool MSS_VAL_EQL=False; /* [flg] Missing values of input operands are identical */ 00054 long idx; 00055 long var_sz=long_CEWI; 00056 nc_type var_typ=NC_NAT; /* CEWI [enm] Type of input values */ 00057 ptr_unn var_val; 00058 00059 has_mss_val=var1->has_mss_val || var2->has_mss_val; 00060 00061 /* No missing values */ 00062 if(!var1->has_mss_val && !var2->has_mss_val) return has_mss_val; 00063 00064 if(var1->has_mss_val && var2->has_mss_val){ 00065 var_typ=var1->type; 00066 (void)cast_void_nctype(var_typ,&var1->mss_val); 00067 (void)cast_void_nctype(var_typ,&var2->mss_val); 00068 switch(var_typ){ 00069 case NC_FLOAT: MSS_VAL_EQL=(*var1->mss_val.fp == *var2->mss_val.fp); break; 00070 case NC_DOUBLE: MSS_VAL_EQL=(*var1->mss_val.dp == *var2->mss_val.dp); break; 00071 case NC_INT: MSS_VAL_EQL=(*var1->mss_val.lp == *var2->mss_val.lp); break; 00072 case NC_SHORT: MSS_VAL_EQL=(*var1->mss_val.sp == *var2->mss_val.sp); break; 00073 case NC_CHAR: MSS_VAL_EQL=(*var1->mss_val.cp == *var2->mss_val.cp); break; 00074 case NC_BYTE: MSS_VAL_EQL=(*var1->mss_val.bp == *var2->mss_val.bp); break; 00075 default: nco_dfl_case_nc_type_err(); break; 00076 } /* end switch */ 00077 if(!MSS_VAL_EQL){ 00078 /* World's most anally formatted warning message... */ 00079 char mss_val_1_sng[NCO_MAX_LEN_FMT_SNG]; 00080 char mss_val_2_sng[NCO_MAX_LEN_FMT_SNG]; 00081 char *fmt_sng; 00082 fmt_sng=nco_typ_fmt_sng(var1->type); 00083 switch(var1->type){ 00084 case NC_FLOAT: (void)sprintf(mss_val_1_sng,fmt_sng,var1->mss_val.fp[0]); break; 00085 case NC_DOUBLE: (void)sprintf(mss_val_1_sng,fmt_sng,var1->mss_val.dp[0]); break; 00086 case NC_SHORT: (void)sprintf(mss_val_1_sng,fmt_sng,var1->mss_val.sp[0]); break; 00087 case NC_INT: (void)sprintf(mss_val_1_sng,fmt_sng,var1->mss_val.lp[0]); break; 00088 case NC_CHAR: (void)sprintf(mss_val_1_sng,fmt_sng,var1->mss_val.cp[0]); break; 00089 case NC_BYTE: (void)sprintf(mss_val_1_sng,fmt_sng,var1->mss_val.bp[0]); break; 00090 default: nco_dfl_case_nc_type_err(); break; 00091 } /* end switch */ 00092 fmt_sng=nco_typ_fmt_sng(var2->type); 00093 switch(var2->type){ 00094 case NC_FLOAT: (void)sprintf(mss_val_2_sng,fmt_sng,var2->mss_val.fp[0]); break; 00095 case NC_DOUBLE: (void)sprintf(mss_val_2_sng,fmt_sng,var2->mss_val.dp[0]); break; 00096 case NC_SHORT: (void)sprintf(mss_val_2_sng,fmt_sng,var2->mss_val.sp[0]); break; 00097 case NC_INT: (void)sprintf(mss_val_2_sng,fmt_sng,var2->mss_val.lp[0]); break; 00098 case NC_CHAR: (void)sprintf(mss_val_2_sng,fmt_sng,var2->mss_val.cp[0]); break; 00099 case NC_BYTE: (void)sprintf(mss_val_2_sng,fmt_sng,var2->mss_val.bp[0]); break; 00100 default: nco_dfl_case_nc_type_err(); break; 00101 } /* end switch */ 00102 (void)fprintf(stderr,"%s: WARNING Input variables have different missing_value's:\nFile 1 variable %s has missing_value type = %s, value = %s\nFile 2 variable %s has missing_value type = %s, value = %s\nFile 3 variable %s will have missing_value type = %s, value = %s\nWill translate values of var2 equaling mss_val2 to mss_val1 before arithmetic operation\n",prg_nm_get(),var1->nm,nco_typ_sng(var1->type),mss_val_1_sng,var2->nm,nco_typ_sng(var2->type),mss_val_2_sng,var1->nm,nco_typ_sng(var1->type),mss_val_1_sng); 00103 } /* MSS_VAL_EQL */ 00104 (void)cast_nctype_void(var_typ,&var1->mss_val); 00105 (void)cast_nctype_void(var_typ,&var2->mss_val); 00106 00107 /* Missing values are already equal */ 00108 if(MSS_VAL_EQL) return has_mss_val; 00109 00110 /* If both files have missing_value's and they differ, 00111 must translate mss_val_2 in var2 to mss_val_1 before binary operation. 00112 Otherwise mss_val_2 would be treated as regular value in var_2 00113 Unfixable bug is when var1 has mss_val1 and var2 does not have a missing_value 00114 Then var2 values that happen to equal mss_val1 are treated as missing_values 00115 A generic, satisfactory solution to this problem does not exist 00116 Picking missing_values that are nearly out-of-range is best workaround 00117 The user must be smart enough to do this, NCO cannot help */ 00118 00119 /* Typecast pointer to values before access */ 00120 (void)cast_void_nctype(var_typ,&var1->mss_val); 00121 (void)cast_void_nctype(var_typ,&var2->mss_val); 00122 (void)cast_void_nctype(var_typ,&var2->val); 00123 00124 /* Shortcuts to avoid indirection */ 00125 var_val=var2->val; 00126 var_sz=var2->sz; 00127 switch(var_typ){ 00128 case NC_FLOAT: { 00129 const float mss_val_1_flt=*var1->mss_val.fp; 00130 const float mss_val_2_flt=*var2->mss_val.fp; 00131 for(idx=0L;idx<var_sz;idx++) if(var_val.fp[idx] == mss_val_2_flt) var_val.fp[idx]=mss_val_1_flt; 00132 } break; 00133 case NC_DOUBLE: { 00134 const double mss_val_1_dbl=*var1->mss_val.dp; 00135 const double mss_val_2_dbl=*var2->mss_val.dp; 00136 for(idx=0L;idx<var_sz;idx++) if(var_val.dp[idx] == mss_val_2_dbl) var_val.dp[idx]=mss_val_1_dbl; 00137 } break; 00138 case NC_INT: { 00139 const nco_int mss_val_1_lng=*var1->mss_val.lp; 00140 const nco_int mss_val_2_lng=*var2->mss_val.lp; 00141 for(idx=0L;idx<var_sz;idx++) if(var_val.lp[idx] == mss_val_2_lng) var_val.lp[idx]=mss_val_1_lng; 00142 } break; 00143 case NC_SHORT: { 00144 const short mss_val_1_sht=*var1->mss_val.sp; 00145 const short mss_val_2_sht=*var2->mss_val.sp; 00146 for(idx=0L;idx<var_sz;idx++) if(var_val.sp[idx] == mss_val_2_sht) var_val.sp[idx]=mss_val_1_sht; 00147 } break; 00148 case NC_CHAR: { 00149 const nco_char mss_val_1_chr=*var1->mss_val.cp; 00150 const nco_char mss_val_2_chr=*var2->mss_val.cp; 00151 for(idx=0L;idx<var_sz;idx++) if(var_val.cp[idx] == mss_val_2_chr) var_val.cp[idx]=mss_val_1_chr; 00152 } break; 00153 case NC_BYTE: { 00154 const nco_byte mss_val_1_byt=*var1->mss_val.bp; 00155 const nco_byte mss_val_2_byt=*var2->mss_val.bp; 00156 for(idx=0L;idx<var_sz;idx++) if(var_val.bp[idx] == mss_val_2_byt) var_val.bp[idx]=mss_val_1_byt; 00157 } break; 00158 default: nco_dfl_case_nc_type_err(); break; 00159 } /* end switch */ 00160 00161 /* Un-typecast the pointer to values after access */ 00162 (void)cast_nctype_void(var_typ,&var2->val); 00163 (void)cast_nctype_void(var_typ,&var1->mss_val); 00164 (void)cast_nctype_void(var_typ,&var2->mss_val); 00165 00166 } /* end if both variables have missing values */ 00167 00168 /* Handle cases where only one variable has missing value. 00169 First, if var2 has missing_value and var1 does not, 00170 then copy missing_value from var2 to var1 to ensure binary arithmetic 00171 (which uses var1's missing_value) handles missing_value's correctly 00172 Assume var1 and var2 already have same type */ 00173 if(!var1->has_mss_val && var2->has_mss_val) (void)nco_mss_val_cp(var2,var1); 00174 if(var1->has_mss_val && !var2->has_mss_val) (void)nco_mss_val_cp(var1,var2); 00175 00176 return has_mss_val; 00177 } /* end nco_mss_val_cnf() */
|
|
||||||||||||
|
Definition at line 181 of file nco_mss_val.c. References False, var_sct_tag::has_mss_val, var_sct_tag::mss_val, nco_realloc(), nco_typ_lng(), nco_val_cnf_typ(), True, and var_sct_tag::type. Referenced by main(), and nco_mss_val_cnf(). 00183 { 00184 /* Threads: Routine is thread safe and calls no unsafe routines */ 00185 /* Purpose: Copy missing value from var1 to var2 00186 On exit, var2 contains has_mss_val, and mss_val identical to var1 00187 Type of mss_val in var2 will agree with type of var2 00188 This maintains assumed consistency between type of variable and type of mss_val in all var_sct's */ 00189 00190 if(!var1->has_mss_val){ 00191 var2->has_mss_val=False; 00192 if(var2->mss_val.vp != NULL) free(var2->mss_val.vp); 00193 }else{ /* endif no mss_val in var1 */ 00194 var2->mss_val.vp=(void *)nco_realloc(var2->mss_val.vp,nco_typ_lng(var2->type)); 00195 (void)nco_val_cnf_typ(var1->type,var1->mss_val,var2->type,var2->mss_val); 00196 var2->has_mss_val=True; 00197 } /* endif var1 has mss_val */ 00198 00199 } /* end nco_mss_val_cp() */
|
|
||||||||||||
|
Definition at line 203 of file nco_mss_val.c. References cast_nctype_void(), ptr_unn::cp, False, NC_CHAR, NC_MAX_NAME, nco_free(), nco_get_att(), nco_inq_att(), nco_inq_attname(), nco_inq_varnatts(), nco_malloc(), nco_realloc(), nco_typ_lng(), nco_val_cnf_typ(), prg_nm_get(), True, and ptr_unn::vp. Referenced by nco_aed_prc(), nco_var_fll(), and nco_var_mtd_refresh(). 00205 { 00206 /* Purpose: Update number of attributes and missing_value attribute of variable 00207 No matter what type missing_value is on disk, this routine ensures that 00208 copy of mss_val in var_sct is stored as same type as host variable. 00209 Routine does not allow output missing_value to have more than one element */ 00210 00211 /* has_mss_val is typed as int not bool because it was sent to Fortran routines */ 00212 00213 char att_nm[NC_MAX_NAME]; 00214 00215 long att_sz; 00216 int idx; 00217 00218 size_t att_lng; 00219 00220 nc_type att_typ; 00221 00222 ptr_unn mss_tmp; 00223 00224 /* Refresh netCDF "mss_val" attribute for this variable */ 00225 var->has_mss_val=False; 00226 var->mss_val.vp=nco_free(var->mss_val.vp); 00227 00228 /* Refresh number of attributes for variable */ 00229 (void)nco_inq_varnatts(nc_id,var->id,&var->nbr_att); 00230 00231 for(idx=0;idx<var->nbr_att;idx++){ 00232 (void)nco_inq_attname(nc_id,var->id,idx,att_nm); 00233 if((int)strcasecmp(att_nm,"missing_value") != 0) continue; 00234 (void)nco_inq_att(nc_id,var->id,att_nm,&att_typ,&att_sz); 00235 if(att_sz != 1L && att_typ != NC_CHAR){ 00236 (void)fprintf(stderr,"%s: WARNING the \"%s\" attribute for %s has %li elements and so will not be used\n",prg_nm_get(),att_nm,var->nm,att_sz); 00237 continue; 00238 } /* end if */ 00239 /* if(att_typ != var->type) (void)fprintf(stderr,"%s: WARNING the \"%s\" attribute for %s will be typecast from %s to %s for arithmetic purposes\n",prg_nm_get(),att_nm,var->nm,nco_typ_sng(att_typ),nco_typ_sng(var->type)); */ 00240 /* If we got this far then try to retrieve attribute and make sure it conforms to variable's type */ 00241 var->has_mss_val=True; 00242 /* Oddly, ARM uses NC_CHAR for type of missing_value, so make allowances for this */ 00243 att_lng=att_sz*nco_typ_lng(att_typ); 00244 mss_tmp.vp=(void *)nco_malloc(att_lng); 00245 (void)nco_get_att(nc_id,var->id,att_nm,mss_tmp.vp,att_typ); 00246 if(att_typ == NC_CHAR){ 00247 /* NUL-terminate missing value string */ 00248 if(mss_tmp.cp[att_lng-1] != '\0'){ 00249 att_lng++; 00250 mss_tmp.vp=(void *)nco_realloc(mss_tmp.vp,att_lng); 00251 mss_tmp.cp[att_lng-1]='\0'; 00252 /* Un-typecast pointer to values after access */ 00253 (void)cast_nctype_void(att_typ,&mss_tmp); 00254 } /* end if */ 00255 } /* end if */ 00256 00257 /* Ensure mss_val in memory is stored as same type as variable */ 00258 var->mss_val.vp=(void *)nco_malloc(nco_typ_lng(var->type)); 00259 (void)nco_val_cnf_typ(att_typ,mss_tmp,var->type,var->mss_val); 00260 00261 /* Release temporary memory */ 00262 mss_tmp.vp=nco_free(mss_tmp.vp); 00263 break; 00264 } /* end loop over att */ 00265 00266 return var->has_mss_val; 00267 00268 } /* end nco_mss_val_get() */
|
|
|
Definition at line 13 of file nco_mss_val.c. References ptr_unn::bp, cast_nctype_void(), cast_void_nctype(), ptr_unn::cp, ptr_unn::dp, ptr_unn::fp, ptr_unn::lp, NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FILL_BYTE, NC_FILL_CHAR, NC_FILL_DOUBLE, NC_FILL_FLOAT, NC_FILL_INT, NC_FILL_SHORT, NC_FLOAT, NC_INT, NC_SHORT, nco_dfl_case_nc_type_err(), nco_malloc(), nco_typ_lng(), ptr_unn::sp, type, and ptr_unn::vp. Referenced by main(). 00014 { 00015 /* Threads: Routine is thread safe and makes no unsafe routines */ 00016 /* Purpose: Return pointer union containing default missing value for type type */ 00017 00018 ptr_unn mss_val; 00019 00020 mss_val.vp=(void *)nco_malloc(nco_typ_lng(type)); 00021 00022 /* Typecast pointer to values before access */ 00023 (void)cast_void_nctype(type,&mss_val); 00024 00025 switch(type){ 00026 case NC_FLOAT: *mss_val.fp=NC_FILL_FLOAT; break; 00027 case NC_DOUBLE: *mss_val.dp=NC_FILL_DOUBLE; break; 00028 case NC_INT: *mss_val.lp=NC_FILL_INT; break; 00029 case NC_SHORT: *mss_val.sp=NC_FILL_SHORT; break; 00030 case NC_CHAR: *mss_val.cp=NC_FILL_CHAR; break; 00031 case NC_BYTE: *mss_val.bp=NC_FILL_BYTE; break; 00032 default: nco_dfl_case_nc_type_err(); break; 00033 } /* end switch */ 00034 00035 /* Un-typecast pointer to values after access */ 00036 (void)cast_nctype_void(type,&mss_val); 00037 00038 return mss_val; 00039 00040 } /* end nco_mss_val_mk() */
|
1.4.4