#include <stdio.h>#include <netcdf.h>#include "nco_netcdf.h"#include "nco.h"#include "nco_cnf_typ.h"#include "nco_ctl.h"#include "nco_mmr.h"#include "nco_scl_utl.h"#include "nco_rth_utl.h"#include "nco_var_avg.h"#include "nco_var_rth.h"#include "nco_var_scv.h"#include "nco_var_utl.h"Include dependency graph for nco_pck.h:

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

Go to the source code of this file.
|
|
Definition at line 45 of file nco_pck.h. 00045 { /* [enm] Packing conversion map */ 00046 /* NB: Packing to NC_CHAR is implemented but not advertised or supported because 00047 (char)0 == NUL, a special value with difficult implicit conversion rules. 00048 We recommend always packing to type NC_BYTE rather than NC_CHAR */ 00049 nco_pck_map_nil, /* 0 [enm] Do not convert anything, i.e., all types remain unchanged */ 00050 nco_pck_map_hgh_sht, /* 1 [enm] Pack higher precision types to NC_SHORT, pack nothing else 00051 [NC_DOUBLE,NC_FLOAT,NC_INT]->NC_SHORT, [NC_SHORT,NC_CHAR,NC_BYTE]->unaltered */ 00052 nco_pck_map_hgh_chr, /* 2 [enm] Pack higher precision types to NC_CHAR, pack nothing else 00053 [NC_DOUBLE,NC_FLOAT,NC_INT,NC_SHORT]->NC_CHAR, [NC_CHAR,NC_BYTE]->unaltered */ 00054 nco_pck_map_hgh_byt, /* 3 [enm] Pack higher precision types to NC_BYTE, pack nothing else 00055 [NC_DOUBLE,NC_FLOAT,NC_INT,NC_SHORT]->NC_BYTE, [NC_CHAR,NC_BYTE]->unaltered */ 00056 nco_pck_map_nxt_lsr, /* 4 [enm] Convert each type of each size to type of next size down 00057 NC_DOUBLE->NC_INT, [NC_FLOAT,NC_INT]->NC_SHORT, NC_SHORT->NC_BYTE, [NC_CHAR,NC_BYTE]->unaltered */ 00058 nco_pck_map_flt_sht, /* 5 [enm] Pack floating precision types to NC_SHORT, pack nothing else 00059 [NC_DOUBLE,NC_FLOAT]->NC_SHORT, [NC_INT,NC_SHORT,NC_CHAR,NC_BYTE]->unaltered */ 00060 nco_pck_map_flt_chr, /* 6 [enm] Pack floating precision types to NC_CHAR, pack nothing else 00061 [NC_DOUBLE,NC_FLOAT]->NC_CHAR, [NC_INT,NC_SHORT,NC_CHAR,NC_BYTE]->unaltered */ 00062 nco_pck_map_flt_byt /* 7 [enm] Pack floating precision types to NC_BYTE, pack nothing else 00063 [NC_DOUBLE,NC_FLOAT]->NC_BYTE, [NC_INT,NC_SHORT,NC_CHAR,NC_BYTE]->unaltered */ 00064 }; /* end nco_pck_map enum */
|
|
|
Definition at line 36 of file nco_pck.h. 00036 { /* [enm] Packing policy */ 00037 nco_pck_plc_nil, /* 0 [enm] Do not think about packing */ 00038 nco_pck_plc_all_xst_att, /* 1 [enm] Pack all variables, keep existing packing attributes if any */ 00039 nco_pck_plc_all_new_att, /* 2 [enm] Pack all variables, always generate new packing attributes */ 00040 nco_pck_plc_xst_new_att, /* 3 [enm] Pack existing packed variables, always generate new packing attributes */ 00041 nco_pck_plc_upk /* 4 [enm] Unpack all packed variables */ 00042 }; /* end nco_pck_plc enum */
|
|
|
Definition at line 74 of file nco_pck.c. References nco_err_exit(). Referenced by nco_pck_map_sng_get(). 00075 { 00076 /* Purpose: Convenience routine for printing error and exiting when 00077 switch(pck_map) statement receives an illegal default case 00078 00079 Placing this in its own routine also has the virtue of saving many lines 00080 of code since this function is used in many many switch() statements. */ 00081 const char fnc_nm[]="nco_dfl_case_pck_map_err()"; 00082 (void)fprintf(stdout,"%s: ERROR switch(pck_map) statement fell through to default case, which is unsafe. This catch-all error handler ensures all switch(pck_map) statements are fully enumerated. Exiting...\n",fnc_nm); 00083 nco_err_exit(0,fnc_nm); 00084 } /* end nco_dfl_case_pck_map_err() */
|
|
|
Definition at line 87 of file nco_pck.c. References nco_err_exit(). Referenced by nco_pck_mtd(), nco_pck_plc_sng_get(), nco_pck_val(), and nco_put_var_pck(). 00088 { 00089 /* Purpose: Convenience routine for printing error and exiting when 00090 switch(pck_plc) statement receives an illegal default case 00091 00092 Placing this in its own routine also has the virtue of saving many lines 00093 of code since this function is used in many many switch() statements. */ 00094 const char fnc_nm[]="nco_dfl_case_pck_plc_err()"; 00095 (void)fprintf(stdout,"%s: ERROR switch(pck_plc) statement fell through to default case, which is unsafe. This catch-all error handler ensures all switch(pck_plc) statements are fully enumerated. Exiting...\n",fnc_nm); 00096 nco_err_exit(0,fnc_nm); 00097 } /* end nco_dfl_case_pck_plc_err() */
|
|
|
Definition at line 101 of file nco_pck.c. References EXIT_FAILURE, False, NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT, nco_dfl_case_nc_type_err(), nco_exit(), prg_nm_get(), and True. 00102 { 00103 /* Purpose: Determine whether NCO should attempt to pack a given type 00104 Packing certain variable types is not recommended, e.g., packing NC_CHAR 00105 and NC_BYTE makes no sense, because precision would needlessly be lost. 00106 Routine should be consistent with nco_pck_plc_typ_get() 00107 NB: Routine is deprecated in favor of more flexible nco_pck_plc_typ_get() */ 00108 const char fnc_nm[]="nco_is_packable()"; /* [sng] Function name */ 00109 00110 (void)fprintf(stdout,"%s: ERROR deprecated routine %s should not be called\n",prg_nm_get(),fnc_nm); 00111 nco_exit(EXIT_FAILURE); 00112 00113 switch(nc_typ_in){ 00114 case NC_FLOAT: 00115 case NC_DOUBLE: 00116 case NC_INT: 00117 return True; 00118 break; 00119 case NC_SHORT: 00120 case NC_CHAR: 00121 case NC_BYTE: 00122 return False; 00123 break; 00124 default: nco_dfl_case_nc_type_err(); break; 00125 } /* end switch */ 00126 00127 /* Some compilers, e.g., SGI cc, need return statement to end non-void functions */ 00128 return False; 00129 } /* end nco_is_packable() */
|
|
||||||||||||
|
Definition at line 335 of file nco_pck.c. References dbg_lvl_get(), False, NC_BYTE, NC_CHAR, NC_ENOTATT, nco_inq_att_flg(), nco_is_rth_opr(), nco_typ_sng(), prg_get(), prg_nm_get(), and True. Referenced by nco_var_fll(), and nco_var_get(). 00337 { 00338 /* Purpose: Check whether variable is packed on disk and set variable members 00339 pck_dsk, has_scl_fct, has_add_fst, and typ_upk accordingly 00340 nco_pck_dsk_inq() should be called early in application, e.g., in nco_var_fll() 00341 Call nco_pck_dsk_inq() before copying input list to output list 00342 Multi-file operators which handle packing must call this routine prior 00343 to each read of a variable, in case that variable has been unpacked. */ 00344 /* ncea -O -D 3 -v pck ~/nco/data/in.nc ~/nco/data/foo.nc */ 00345 00346 const char add_fst_sng[]="add_offset"; /* [sng] Unidata standard string for add offset */ 00347 const char scl_fct_sng[]="scale_factor"; /* [sng] Unidata standard string for scale factor */ 00348 00349 int rcd; /* [rcd] Return success code */ 00350 00351 long add_fst_lng; /* [idx] Number of elements in add_offset attribute */ 00352 long scl_fct_lng; /* [idx] Number of elements in scale_factor attribute */ 00353 00354 nc_type add_fst_typ; /* [idx] Type of add_offset attribute */ 00355 nc_type scl_fct_typ; /* [idx] Type of scale_factor attribute */ 00356 00357 /* Set some defaults in variable structure for safety in case of early return 00358 Flags for variables without valid scaling information should appear 00359 same as flags for variables with _no_ scaling information 00360 Set has_scl_fct, has_add_fst in var_dfl_set() 00361 typ_upk: 00362 1. is required by ncra nco_cnv_mss_val_typ() 00363 2. depends on var->type and so should not be set in var_dfl_set() 00364 3. is therefore set to default here */ 00365 var->typ_upk=var->type; /* [enm] Type of variable when unpacked (expanded) (in memory) */ 00366 00367 /* Vet scale_factor */ 00368 rcd=nco_inq_att_flg(nc_id,var->id,scl_fct_sng,&scl_fct_typ,&scl_fct_lng); 00369 if(rcd != NC_ENOTATT){ 00370 if(scl_fct_typ == NC_BYTE || scl_fct_typ == NC_CHAR){ 00371 (void)fprintf(stdout,"%s: WARNING nco_pck_dsk_inq() reports scale_factor for %s is NC_BYTE or NC_CHAR. Will not attempt to unpack using scale_factor.\n",prg_nm_get(),var->nm); 00372 return False; 00373 } /* endif */ 00374 if(scl_fct_lng != 1){ 00375 (void)fprintf(stdout,"%s: WARNING nco_pck_dsk_inq() reports %s has scale_factor of length %li. Will not attempt to unpack using scale_factor\n",prg_nm_get(),var->nm,scl_fct_lng); 00376 return False; 00377 } /* endif */ 00378 var->has_scl_fct=True; /* [flg] Valid scale_factor attribute exists */ 00379 var->typ_upk=scl_fct_typ; /* [enm] Type of variable when unpacked (expanded) (in memory) */ 00380 } /* endif */ 00381 00382 /* Vet add_offset */ 00383 rcd=nco_inq_att_flg(nc_id,var->id,add_fst_sng,&add_fst_typ,&add_fst_lng); 00384 if(rcd != NC_ENOTATT){ 00385 if(add_fst_typ == NC_BYTE || add_fst_typ == NC_CHAR){ 00386 (void)fprintf(stdout,"%s: WARNING nco_pck_dsk_inq() reports add_offset for %s is NC_BYTE or NC_CHAR. Will not attempt to unpack using add_offset.\n",prg_nm_get(),var->nm); 00387 return False; 00388 } /* endif */ 00389 if(add_fst_lng != 1){ 00390 (void)fprintf(stdout,"%s: WARNING nco_pck_dsk_inq() reports %s has add_offset of length %li. Will not attempt to unpack.\n",prg_nm_get(),var->nm,add_fst_lng); 00391 return False; 00392 } /* endif */ 00393 var->has_add_fst=True; /* [flg] Valid add_offset attribute exists */ 00394 var->typ_upk=add_fst_typ; /* [enm] Type of variable when unpacked (expanded) (in memory) */ 00395 } /* endif */ 00396 00397 if(var->has_scl_fct && var->has_add_fst){ 00398 if(scl_fct_typ != add_fst_typ){ 00399 (void)fprintf(stdout,"%s: WARNING nco_pck_dsk_inq() reports type of scale_factor does not equal type of add_offset. Will not attempt to unpack.\n",prg_nm_get()); 00400 return False; 00401 } /* endif */ 00402 } /* endif */ 00403 00404 if(var->has_scl_fct || var->has_add_fst){ 00405 /* Variable is considered packed iff either or both valid scale_factor or add_offset exist */ 00406 var->pck_dsk=True; /* [flg] Variable is packed on disk */ 00407 /* If variable is packed on disk and is in memory then variable is packed in memory */ 00408 var->pck_ram=True; /* [flg] Variable is packed in memory */ 00409 var->typ_upk=(var->has_scl_fct) ? scl_fct_typ : add_fst_typ; /* [enm] Type of variable when unpacked (expanded) (in memory) */ 00410 if(nco_is_rth_opr(prg_get()) && dbg_lvl_get() > 2){ 00411 (void)fprintf(stdout,"%s: PACKING Variable %s is type %s packed into type %s\n",prg_nm_get(),var->nm,nco_typ_sng(var->typ_upk),nco_typ_sng(var->typ_dsk)); 00412 (void)fprintf(stdout,"%s: DEBUG Packed variables processed by all arithmetic operators are unpacked automatically, and then stored unpacked in the output file. If you wish to repack them in the output file, use, e.g., ncap -O -s \"foo=pack(foo);\" out.nc out.nc. If you wish to pack all variables in a file, use, e.g., ncpdq -P all_new in.nc out.nc.\n",prg_nm_get()); 00413 } /* endif print packing information */ 00414 }else{ 00415 /* Variable is not packed since neither scale factor nor add_offset exist 00416 Insert hooks which depend on variable not being packed here 00417 Currently this is no-op */ 00418 ; 00419 } /* end else */ 00420 00421 return var->pck_dsk; /* [flg] Variable is packed on disk (valid scale_factor, add_offset, or both attributes exist) */ 00422 00423 } /* end nco_pck_dsk_inq() */
|
|
|
Definition at line 133 of file nco_pck.c. References EXIT_FAILURE, nco_exit(), nco_pck_map_flt_byt, nco_pck_map_flt_chr, nco_pck_map_flt_sht, nco_pck_map_hgh_byt, nco_pck_map_hgh_chr, nco_pck_map_hgh_sht, nco_pck_map_nil, nco_pck_map_nxt_lsr, and prg_nm_get(). Referenced by main(). 00134 { 00135 /* Purpose: Process ncpdq '-P' command line argument 00136 Convert user-specified string to packing map 00137 Return nco_pck_map_nil by default */ 00138 const char fnc_nm[]="nco_pck_map_get()"; /* [sng] Function name */ 00139 char *prg_nm; /* [sng] Program name */ 00140 prg_nm=prg_nm_get(); /* [sng] Program name */ 00141 00142 if(nco_pck_map_sng == NULL){ 00143 (void)fprintf(stderr,"%s: ERROR %s reports empty user-specified packing map string %s\n",prg_nm,fnc_nm,nco_pck_map_sng); 00144 nco_exit(EXIT_FAILURE); 00145 } /* endif */ 00146 00147 if(!strcmp(nco_pck_map_sng,"hgh_sht")) return nco_pck_map_hgh_sht; 00148 if(!strcmp(nco_pck_map_sng,"pck_map_hgh_sht")) return nco_pck_map_hgh_sht; 00149 if(!strcmp(nco_pck_map_sng,"hgh_chr")) return nco_pck_map_hgh_chr; 00150 if(!strcmp(nco_pck_map_sng,"pck_map_hgh_chr")) return nco_pck_map_hgh_chr; 00151 if(!strcmp(nco_pck_map_sng,"hgh_byt")) return nco_pck_map_hgh_byt; 00152 if(!strcmp(nco_pck_map_sng,"pck_map_hgh_byt")) return nco_pck_map_hgh_byt; 00153 if(!strcmp(nco_pck_map_sng,"nxt_lsr")) return nco_pck_map_nxt_lsr; 00154 if(!strcmp(nco_pck_map_sng,"pck_map_nxt_lsr")) return nco_pck_map_nxt_lsr; 00155 if(!strcmp(nco_pck_map_sng,"flt_sht")) return nco_pck_map_flt_sht; 00156 if(!strcmp(nco_pck_map_sng,"pck_map_flt_sht")) return nco_pck_map_flt_sht; 00157 if(!strcmp(nco_pck_map_sng,"flt_chr")) return nco_pck_map_flt_chr; 00158 if(!strcmp(nco_pck_map_sng,"pck_map_flt_chr")) return nco_pck_map_flt_chr; 00159 if(!strcmp(nco_pck_map_sng,"flt_byt")) return nco_pck_map_flt_byt; 00160 if(!strcmp(nco_pck_map_sng,"pck_map_flt_byt")) return nco_pck_map_flt_byt; 00161 00162 (void)fprintf(stderr,"%s: ERROR %s reports unknown user-specified packing policy %s\n",prg_nm_get(),fnc_nm,nco_pck_map_sng); 00163 nco_exit(EXIT_FAILURE); 00164 return nco_pck_map_nil; /* Statement should not be reached */ 00165 } /* end nco_pck_map_get() */
|
|
|
Definition at line 25 of file nco_pck.c. References nco_dfl_case_pck_map_err(), nco_pck_map_flt_byt, nco_pck_map_flt_chr, nco_pck_map_flt_sht, nco_pck_map_hgh_byt, nco_pck_map_hgh_chr, nco_pck_map_hgh_sht, nco_pck_map_nil, and nco_pck_map_nxt_lsr. Referenced by main(), nco_pck_mtd(), and nco_pck_val(). 00026 { 00027 /* Purpose: Convert packing map enum to string */ 00028 switch(nco_pck_map){ 00029 case nco_pck_map_nil: 00030 return "nil"; 00031 case nco_pck_map_hgh_sht: 00032 return "hgh_sht"; 00033 case nco_pck_map_hgh_chr: 00034 return "hgh_chr"; 00035 case nco_pck_map_hgh_byt: 00036 return "hgh_byt"; 00037 case nco_pck_map_nxt_lsr: 00038 return "nxt_lsr"; 00039 case nco_pck_map_flt_sht: 00040 return "flt_sht"; 00041 case nco_pck_map_flt_chr: 00042 return "flt_chr"; 00043 case nco_pck_map_flt_byt: 00044 return "flt_byt"; 00045 default: nco_dfl_case_pck_map_err(); break; 00046 } /* end switch */ 00047 /* Some compilers, e.g., SGI cc, need return statement to end non-void functions */ 00048 return (char *)NULL; 00049 } /* end nco_pck_map_sng_get() */
|
|
||||||||||||||||||||
|
Definition at line 427 of file nco_pck.c. References dbg_lvl_get(), nco_dfl_case_pck_plc_err(), nco_pck_map_sng_get(), nco_pck_plc_all_new_att, nco_pck_plc_all_xst_att, nco_pck_plc_nil, nco_pck_plc_sng_get(), nco_pck_plc_typ_get(), nco_pck_plc_upk, nco_pck_plc_xst_new_att, nco_typ_sng(), var_sct_tag::nm, var_sct_tag::pck_ram, prg_nm_get(), var_sct_tag::typ_upk, and var_sct_tag::type. Referenced by main(). 00431 { 00432 /* Purpose: Alter metadata according to packing specification */ 00433 const char fnc_nm[]="nco_pck_mtd()"; /* [sng] Function name */ 00434 nc_type nc_typ_pck_out; /* [enm] Type to pack to */ 00435 bool nco_pck_plc_alw; /* [flg] Packing policy allows packing nc_typ_in */ 00436 00437 switch(nco_pck_plc){ 00438 case nco_pck_plc_all_xst_att: 00439 /* If variable is already packed do nothing otherwise pack to default type */ 00440 if(var_in->pck_ram){ 00441 if(dbg_lvl_get() > 2) (void)fprintf(stdout,"%s: DEBUG %s keeping existing packing parameters and type (%s) for %s\n",prg_nm_get(),fnc_nm,nco_typ_sng(var_in->type),var_in->nm); 00442 }else{ 00443 goto var_upk_try_to_pck; 00444 } /* endif */ 00445 break; 00446 case nco_pck_plc_xst_new_att: 00447 /* If variable is already packed then re-pack otherwise do nothing */ 00448 if(var_in->pck_ram){ 00449 goto var_pck_try_to_rpk; 00450 }else{ 00451 /* Variable is not packed so do nothing */ 00452 if(dbg_lvl_get() > 2) (void)fprintf(stdout,"%s: INFO %s leaving variable %s of type %s as unpacked\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_out->typ_upk)); 00453 } /* endelse */ 00454 break; 00455 case nco_pck_plc_all_new_att: 00456 if(var_in->pck_ram){ 00457 goto var_pck_try_to_rpk; 00458 }else{ 00459 goto var_upk_try_to_pck; 00460 } /* endif */ 00461 break; 00462 case nco_pck_plc_upk: 00463 var_out->type=var_in->typ_upk; 00464 if(dbg_lvl_get() > 3){ 00465 if(var_in->pck_ram) (void)fprintf(stdout,"%s: DEBUG %s will unpack variable %s from %s to %s\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_in->type),nco_typ_sng(var_out->type)); else (void)fprintf(stdout,"%s: DEBUG %s variable %s is already unpacked and of type %s\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_in->type)); 00466 } /* endif dbg */ 00467 break; 00468 case nco_pck_plc_nil: 00469 default: nco_dfl_case_pck_plc_err(); break; 00470 } /* end case */ 00471 00472 /* Return after finishing switch() statement and before falling through 00473 to code-saving goto branches */ 00474 return; 00475 00476 var_upk_try_to_pck: /* end goto */ 00477 /* Variable is not yet packed---try to pack it */ 00478 if((nco_pck_plc_alw=nco_pck_plc_typ_get(nco_pck_map,var_in->type,&nc_typ_pck_out))){ 00479 var_out->type=nc_typ_pck_out; 00480 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: DEBUG %s will pack variable %s from %s to %s\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_in->type),nco_typ_sng(var_out->type)); 00481 }else{ 00482 if(dbg_lvl_get() > 2) (void)fprintf(stdout,"%s: INFO %s packing policy %s with packing map %s does not allow packing variable %s of type %s, skipping...\n",prg_nm_get(),fnc_nm,nco_pck_plc_sng_get(nco_pck_plc),nco_pck_map_sng_get(nco_pck_map),var_in->nm,nco_typ_sng(var_in->type)); 00483 } /* endif nco_pck_plc_alw */ 00484 return; 00485 00486 var_pck_try_to_rpk: /* end goto */ 00487 /* Variable is already packed---try to re-pack it 00488 Final packed variable type may differ from original */ 00489 if((nco_pck_plc_alw=nco_pck_plc_typ_get(nco_pck_map,var_in->typ_upk,&nc_typ_pck_out))){ 00490 var_out->type=nc_typ_pck_out; 00491 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: DEBUG %s will re-pack variable %s of expanded type %s from current packing (type %s) into new packing of type %s\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_in->typ_upk),nco_typ_sng(var_in->type),nco_typ_sng(var_out->type)); 00492 }else{ 00493 if(dbg_lvl_get() > 2) (void)fprintf(stdout,"%s: WARNING %s variable %s of expanded type %s is already packed into type %s and re-packing is requested but packing policy %s and packing map %s does not allow re-packing variables of type %s\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_in->typ_upk),nco_typ_sng(var_in->type),nco_pck_plc_sng_get(nco_pck_plc),nco_pck_map_sng_get(nco_pck_map),nco_typ_sng(var_in->typ_upk)); 00494 } /* endif nco_pck_plc_alw */ 00495 return; 00496 00497 } /* end nco_pck_mtd() */
|
|
|
Definition at line 169 of file nco_pck.c. References EXIT_FAILURE, nco_exit(), nco_pck_plc_all_new_att, nco_pck_plc_all_xst_att, nco_pck_plc_nil, nco_pck_plc_upk, nco_pck_plc_xst_new_att, and prg_nm_get(). Referenced by main(). 00170 { 00171 /* Purpose: Process ncpdq '-P' command line argument 00172 Convert user-specified string to packing operation type 00173 Return nco_pck_plc_nil by default */ 00174 const char fnc_nm[]="nco_pck_plc_get()"; /* [sng] Function name */ 00175 char *prg_nm; /* [sng] Program name */ 00176 prg_nm=prg_nm_get(); /* [sng] Program name */ 00177 00178 if(nco_pck_plc_sng == NULL){ 00179 if(strstr(prg_nm,"ncpdq")){ 00180 (void)fprintf(stdout,"%s: INFO %s reports %s invoked without explicit packing or dimension permutation options. Defaulting to packing policy \"all_new\".\n",prg_nm,fnc_nm,prg_nm); 00181 return nco_pck_plc_all_new_att; 00182 } /* endif */ 00183 if(strstr(prg_nm,"ncpack")) return nco_pck_plc_all_new_att; 00184 if(strstr(prg_nm,"ncunpack")) return nco_pck_plc_upk; 00185 (void)fprintf(stderr,"%s: ERROR %s reports empty user-specified packing string in conjunction with unknown or ambiguous executable name %s\n",prg_nm,fnc_nm,prg_nm); 00186 nco_exit(EXIT_FAILURE); 00187 } /* endif */ 00188 00189 if(!strcmp(nco_pck_plc_sng,"all_xst")) return nco_pck_plc_all_xst_att; 00190 if(!strcmp(nco_pck_plc_sng,"pck_all_xst_att")) return nco_pck_plc_all_xst_att; 00191 if(!strcmp(nco_pck_plc_sng,"all_new")) return nco_pck_plc_all_new_att; 00192 if(!strcmp(nco_pck_plc_sng,"pck_all_new_att")) return nco_pck_plc_all_new_att; 00193 if(!strcmp(nco_pck_plc_sng,"xst_new")) return nco_pck_plc_xst_new_att; 00194 if(!strcmp(nco_pck_plc_sng,"pck_xst_new_att")) return nco_pck_plc_xst_new_att; 00195 if(!strcmp(nco_pck_plc_sng,"upk")) return nco_pck_plc_upk; 00196 if(!strcmp(nco_pck_plc_sng,"unpack")) return nco_pck_plc_upk; 00197 if(!strcmp(nco_pck_plc_sng,"pck_upk")) return nco_pck_plc_upk; 00198 00199 (void)fprintf(stderr,"%s: ERROR %s reports unknown user-specified packing policy %s\n",prg_nm_get(),fnc_nm,nco_pck_plc_sng); 00200 nco_exit(EXIT_FAILURE); 00201 return nco_pck_plc_nil; /* Statement should not be reached */ 00202 } /* end nco_pck_plc_get() */
|
|
|
Definition at line 53 of file nco_pck.c. References nco_dfl_case_pck_plc_err(), nco_pck_plc_all_new_att, nco_pck_plc_all_xst_att, nco_pck_plc_nil, nco_pck_plc_upk, and nco_pck_plc_xst_new_att. Referenced by main(), nco_pck_mtd(), and nco_pck_val(). 00054 { 00055 /* Purpose: Convert packing policy enum to string */ 00056 switch(nco_pck_plc){ 00057 case nco_pck_plc_nil: 00058 return "nil"; 00059 case nco_pck_plc_all_xst_att: 00060 return "all_xst"; 00061 case nco_pck_plc_all_new_att: 00062 return "all_new"; 00063 case nco_pck_plc_xst_new_att: 00064 return "xst_new"; 00065 case nco_pck_plc_upk: 00066 return "upk"; 00067 default: nco_dfl_case_pck_plc_err(); break; 00068 } /* end switch */ 00069 /* Some compilers, e.g., SGI cc, need return statement to end non-void functions */ 00070 return (char *)NULL; 00071 } /* end nco_pck_plc_sng_get() */
|
|
||||||||||||||||
|
Definition at line 206 of file nco_pck.c. References False, NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_NAT, NC_SHORT, nco_dfl_case_nc_type_err(), nco_err_exit(), nco_pck_map_flt_byt, nco_pck_map_flt_chr, nco_pck_map_flt_sht, nco_pck_map_hgh_byt, nco_pck_map_hgh_chr, nco_pck_map_hgh_sht, nco_pck_map_nil, nco_pck_map_nxt_lsr, prg_nm_get(), and True. Referenced by main(), nco_pck_mtd(), nco_pck_val(), nco_var_dfn(), and nco_var_lst_dvd(). 00209 { 00210 /* Purpose: Determine type, if any, to pack input type to 00211 Routine enforces policy specified by nco_pck_map 00212 Replacement for simple deprecated routine nco_is_packable() 00213 There are two cases: 00214 1. nco_pck_map allows packing nc_typ_in: 00215 Routine returns true and sets nc_typ_pck_out accordingly 00216 2. nco_pck_map does not allow packing nc_typ_in: 00217 Routine returns false and sets nc_typ_pck_out=nc_typ_in 00218 In both cases, nc_typ_pck_out is only set if it is non-NULL */ 00219 00220 const char fnc_nm[]="nco_pck_plc_typ_get()"; /* [sng] Function name */ 00221 bool nco_pck_plc_alw; /* O [flg] Packing policy allows packing nc_typ_in */ 00222 nc_type nc_typ_pck_out_tmp; /* O [enm] Type to pack variable to */ 00223 00224 /* Initialize output type to NAT and pack allow to False to help catch errors */ 00225 nc_typ_pck_out_tmp=NC_NAT; 00226 nco_pck_plc_alw=False; 00227 switch(nco_pck_map){ 00228 case nco_pck_map_nil: 00229 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00230 case nco_pck_map_hgh_sht: 00231 switch(nc_typ_in){ 00232 case NC_DOUBLE: 00233 case NC_FLOAT: 00234 case NC_INT: 00235 nc_typ_pck_out_tmp=NC_SHORT; nco_pck_plc_alw=True; break; 00236 case NC_SHORT: 00237 case NC_CHAR: 00238 case NC_BYTE: 00239 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00240 default: nco_dfl_case_nc_type_err(); break; 00241 } /* end nc_type switch */ 00242 break; 00243 case nco_pck_map_hgh_chr: 00244 switch(nc_typ_in){ 00245 case NC_DOUBLE: 00246 case NC_FLOAT: 00247 case NC_INT: 00248 case NC_SHORT: 00249 nc_typ_pck_out_tmp=NC_CHAR; nco_pck_plc_alw=True; break; 00250 case NC_CHAR: 00251 case NC_BYTE: 00252 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00253 default: nco_dfl_case_nc_type_err(); break; 00254 } /* end nc_type switch */ 00255 break; 00256 case nco_pck_map_hgh_byt: 00257 switch(nc_typ_in){ 00258 case NC_DOUBLE: 00259 case NC_FLOAT: 00260 case NC_INT: 00261 case NC_SHORT: 00262 nc_typ_pck_out_tmp=NC_BYTE; nco_pck_plc_alw=True; break; 00263 case NC_CHAR: 00264 case NC_BYTE: 00265 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00266 default: nco_dfl_case_nc_type_err(); break; 00267 } /* end nc_type switch */ 00268 break; 00269 case nco_pck_map_nxt_lsr: 00270 switch(nc_typ_in){ 00271 case NC_DOUBLE: nc_typ_pck_out_tmp=NC_INT; nco_pck_plc_alw=True; break; 00272 case NC_FLOAT: 00273 case NC_INT: 00274 nc_typ_pck_out_tmp=NC_SHORT; nco_pck_plc_alw=True; break; 00275 case NC_SHORT: nc_typ_pck_out_tmp=NC_BYTE; nco_pck_plc_alw=True; break; 00276 case NC_CHAR: 00277 case NC_BYTE: 00278 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00279 default: nco_dfl_case_nc_type_err(); break; 00280 } /* end nc_type switch */ 00281 break; 00282 case nco_pck_map_flt_sht: 00283 switch(nc_typ_in){ 00284 case NC_DOUBLE: 00285 case NC_FLOAT: 00286 nc_typ_pck_out_tmp=NC_SHORT; nco_pck_plc_alw=True; break; 00287 case NC_INT: 00288 case NC_SHORT: 00289 case NC_CHAR: 00290 case NC_BYTE: 00291 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00292 default: nco_dfl_case_nc_type_err(); break; 00293 } /* end nc_type switch */ 00294 break; 00295 case nco_pck_map_flt_chr: 00296 switch(nc_typ_in){ 00297 case NC_DOUBLE: 00298 case NC_FLOAT: 00299 nc_typ_pck_out_tmp=NC_CHAR; nco_pck_plc_alw=True; break; 00300 case NC_INT: 00301 case NC_SHORT: 00302 case NC_CHAR: 00303 case NC_BYTE: 00304 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00305 default: nco_dfl_case_nc_type_err(); break; 00306 } /* end nc_type switch */ 00307 break; 00308 case nco_pck_map_flt_byt: 00309 switch(nc_typ_in){ 00310 case NC_DOUBLE: 00311 case NC_FLOAT: 00312 nc_typ_pck_out_tmp=NC_BYTE; nco_pck_plc_alw=True; break; 00313 case NC_INT: 00314 case NC_SHORT: 00315 case NC_CHAR: 00316 case NC_BYTE: 00317 nc_typ_pck_out_tmp=nc_typ_in; nco_pck_plc_alw=False; break; 00318 default: nco_dfl_case_nc_type_err(); break; 00319 } /* end nc_type switch */ 00320 break; 00321 default: 00322 (void)fprintf(stdout,"%s: ERROR %s reports switch(nco_pck_map) statement fell through to default case\n",prg_nm_get(),fnc_nm); 00323 nco_err_exit(0,fnc_nm); 00324 break; 00325 } /* end nco_pck_map switch */ 00326 00327 /* Only fill in nc_typ_pck_out if it is non-NULL */ 00328 if(nc_typ_pck_out != NULL) *nc_typ_pck_out=nc_typ_pck_out_tmp; 00329 00330 return nco_pck_plc_alw; /* O [flg] Packing policy allows packing nc_typ_in */ 00331 } /* end nco_pck_plc_typ_get() */
|
|
||||||||||||||||||||||||||||
|
Definition at line 501 of file nco_pck.c. References aed_delete, aed_overwrite, dbg_lvl_get(), False, nco_dfl_case_pck_plc_err(), nco_pck_map_sng_get(), nco_pck_plc_all_new_att, nco_pck_plc_all_xst_att, nco_pck_plc_nil, nco_pck_plc_sng_get(), nco_pck_plc_typ_get(), nco_pck_plc_upk, nco_pck_plc_xst_new_att, nco_typ_sng(), nco_var_pck(), nco_var_upk_swp(), var_sct_tag::nm, var_sct_tag::pck_ram, prg_nm_get(), var_sct_tag::typ_dsk, var_sct_tag::val, and ptr_unn::vp. Referenced by main(). 00507 { 00508 /* Purpose: Alter metadata according to packing specification */ 00509 const char fnc_nm[]="nco_pck_val()"; /* [sng] Function name */ 00510 bool PCK_VAR_WITH_NEW_PCK_ATT=False; /* [flg] Insert new scale_factor and add_offset into lists */ 00511 nc_type typ_out; /* [enm] Type in output file */ 00512 bool nco_pck_plc_alw; /* [flg] Packing policy allows packing nc_typ_in */ 00513 00514 /* typ_out contains type of variable defined in output file 00515 as defined by var_out->type which was set in var_pck_mtd() 00516 We will temporarily set var_out->type to RAM type of variable 00517 Packing routine will re-set var_out->type to typ_out if necessary */ 00518 typ_out=var_out->type; /* [enm] Type in output file */ 00519 00520 switch(nco_pck_plc){ 00521 case nco_pck_plc_all_xst_att: 00522 /* nco_var_pck() expects to alter var_out->type itself, if necessary */ 00523 var_out->type=var_in->typ_dsk; 00524 if(var_in->pck_ram){ 00525 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: INFO %s keeping existing packing attributes for variable %s\n",prg_nm_get(),fnc_nm,var_in->nm); 00526 /* Warn if packing attribute values are in memory for pre-packed variables */ 00527 if(var_out->scl_fct.vp != NULL || var_out->add_fst.vp != NULL) (void)fprintf(stdout,"%s: WARNING %s reports variable %s has packing attribute values in memory. This is not supposed to happen through known code paths, but is not necessarily dangerous.\n",prg_nm_get(),fnc_nm,var_in->nm); 00528 /* Remove dangling pointer, see explanation below */ 00529 var_in->val.vp=NULL; 00530 }else{ 00531 goto var_upk_try_to_pck; /* end goto */ 00532 } /* endif input variable was not packed */ 00533 break; 00534 case nco_pck_plc_xst_new_att: 00535 if(var_in->pck_ram){ 00536 nco_var_upk_swp(var_in,var_out); 00537 goto var_upk_try_to_pck; 00538 }else{ 00539 /* Remove dangling pointer, see explanation below */ 00540 var_in->val.vp=NULL; 00541 } /* endif */ 00542 break; 00543 case nco_pck_plc_all_new_att: 00544 if(var_in->pck_ram){ 00545 /* Variable is already packed---unpack it before re-packing it */ 00546 nco_var_upk_swp(var_in,var_out); 00547 }else{ 00548 /* nco_var_pck() expects to alter var_out->type itself, if necessary */ 00549 var_out->type=var_in->typ_dsk; 00550 } /* endif */ 00551 goto var_upk_try_to_pck; 00552 break; 00553 case nco_pck_plc_upk: 00554 /* Unpack if possible, otherwise remove dangling pointer (explanation below) */ 00555 if(var_in->pck_ram) nco_var_upk_swp(var_in,var_out); else var_in->val.vp=NULL; 00556 break; 00557 case nco_pck_plc_nil: 00558 default: nco_dfl_case_pck_plc_err(); break; 00559 } /* end case */ 00560 00561 /* Ensure code goes to final block before falling through to next goto */ 00562 goto put_new_pck_att_in_lst; 00563 00564 var_upk_try_to_pck: /* end goto */ 00565 /* Variable is not yet packed---try to pack it */ 00566 if((nco_pck_plc_alw=nco_pck_plc_typ_get(nco_pck_map,var_out->type,(nc_type *)NULL))){ 00567 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: INFO %s packing variable %s values from %s to %s\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_out->typ_upk),nco_typ_sng(typ_out)); 00568 var_out=nco_var_pck(var_out,typ_out,&PCK_VAR_WITH_NEW_PCK_ATT); 00569 }else{ 00570 if(dbg_lvl_get() > 2) (void)fprintf(stdout,"%s: INFO %s packing policy %s with packing map %s does not allow packing variable %s of type %s, skipping...\n",prg_nm_get(),fnc_nm,nco_pck_plc_sng_get(nco_pck_plc),nco_pck_map_sng_get(nco_pck_map),var_in->nm,nco_typ_sng(var_out->typ_upk)); 00571 } /* endif nco_pck_plc_alw */ 00572 /* Packing function nco_var_pck() usually free()'s var_out->val.vp 00573 Hence var_in->val.vp is left with a dangling pointer 00574 In ncpdq, var_in->val.vp and var_out->val.vp point to same buffer 00575 This reduces peak memory consumption by ~50%, but is dangerous */ 00576 var_in->val.vp=NULL; 00577 /* Ensure code goes to final block before falling through to next goto */ 00578 goto put_new_pck_att_in_lst; 00579 00580 put_new_pck_att_in_lst: /* end goto */ 00581 /* Fill attribute edit structures 00582 Use values directly from variable structures rather than copying 00583 Attribute structure dynamic memory will be free()'d in nco_var_free() call */ 00584 if(PCK_VAR_WITH_NEW_PCK_ATT){ 00585 aed_lst_add_fst->var_nm=aed_lst_scl_fct->var_nm=var_out->nm; 00586 aed_lst_add_fst->id=aed_lst_scl_fct->id=var_out->id; 00587 aed_lst_add_fst->sz=aed_lst_scl_fct->sz=1L; 00588 aed_lst_add_fst->type=aed_lst_scl_fct->type=var_out->typ_upk; 00589 /* Packing generates at least one of scale_factor or add_offset, 00590 but not necessarily both. 00591 Delete pre-defined attributes for those which were not created */ 00592 if(var_out->has_add_fst) aed_lst_add_fst->mode=aed_overwrite; else aed_lst_add_fst->mode=aed_delete; 00593 if(var_out->has_scl_fct) aed_lst_scl_fct->mode=aed_overwrite; else aed_lst_scl_fct->mode=aed_delete; 00594 /* Insert values into attribute structures */ 00595 aed_lst_add_fst->val=var_out->add_fst; 00596 aed_lst_scl_fct->val=var_out->scl_fct; 00597 } /* endif */ 00598 00599 } /* end nco_pck_val() */
|
|
||||||||||||||||
|
Definition at line 603 of file nco_pck.c. References False, nco_dfl_case_pck_plc_err(), nco_pck_plc_all_new_att, nco_pck_plc_all_xst_att, nco_pck_plc_nil, nco_pck_plc_upk, nco_pck_plc_xst_new_att, nco_put_att(), and nco_var_pck(). Referenced by main(). 00606 { 00607 /* Purpose: Pack variable in memory and write packing attributes to disk 00608 NB: Routine is not complete, debugged, or currently used 00609 ncpdq breaks up writing packed variables into multiple tasks, i.e., 00610 ncpdq separates variable value writes from packing attribute value writes. 00611 This routine is intended to write a packed variable in one routine */ 00612 bool PCK_VAR_WITH_NEW_PCK_ATT=False; /* [flg] Insert new scale_factor and add_offset into lists */ 00613 00614 switch(nco_pck_plc){ 00615 case nco_pck_plc_all_xst_att: 00616 break; 00617 case nco_pck_plc_xst_new_att: 00618 break; 00619 case nco_pck_plc_all_new_att: 00620 break; 00621 case nco_pck_plc_upk: 00622 break; 00623 case nco_pck_plc_nil: 00624 default: nco_dfl_case_pck_plc_err(); break; 00625 } /* end switch */ 00626 00627 /* Pack variable */ 00628 if(var->xrf->pck_dsk && !var->xrf->pck_ram) var=nco_var_pck(var,var->typ_pck,&PCK_VAR_WITH_NEW_PCK_ATT); 00629 00630 /* Write/overwrite scale_factor and add_offset attributes */ 00631 if(var->pck_ram){ /* [flg] Variable is packed in memory */ 00632 if(var->has_scl_fct){ /* [flg] Valid scale_factor attribute exists */ 00633 (void)nco_put_att(out_id,var->id,"scale_factor",var->typ_upk,1,var->scl_fct.vp); 00634 } /* endif has_scl_fct */ 00635 if(var->has_add_fst){ /* [flg] Valid add_offset attribute exists */ 00636 (void)nco_put_att(out_id,var->id,"add_offset",var->typ_upk,1,var->add_fst.vp); 00637 } /* endif has_add_fst */ 00638 } /* endif pck_ram */ 00639 00640 return var; 00641 00642 } /* end nco_put_var_pck() */
|
|
||||||||||||||||
|
Definition at line 646 of file nco_pck.c. References var_sct_tag::add_fst, val_unn::d, dbg_lvl_get(), double_CEWI, ptr_unn::dp, EXIT_FAILURE, False, var_sct_tag::has_add_fst, var_sct_tag::has_mss_val, var_sct_tag::has_scl_fct, var_sct_tag::mss_val, 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_exit(), nco_free(), nco_malloc(), nco_scv_cnf_typ(), nco_typ_lng(), nco_typ_sng(), nco_val_cnf_typ(), nco_var_add(), nco_var_avg_reduce_max(), nco_var_avg_reduce_min(), nco_var_cnf_typ(), nco_var_dpl(), nco_var_dvd(), nco_var_free(), nco_var_mlt(), nco_var_sbt(), var_sct_tag::nm, var_sct_tag::pck_ram, prg_nm_get(), ptr_unn_2_scl_dbl(), var_sct_tag::scl_fct, scl_mk_var(), scl_ptr_mk_var(), var_sct_tag::sz, True, var_sct_tag::typ_pck, var_sct_tag::typ_upk, scv_sct::type, var_sct_tag::type, scv_sct::val, var_sct_tag::val, var_scv_dvd(), var_scv_sub(), and ptr_unn::vp. Referenced by nco_pck_val(), and nco_put_var_pck(). 00649 { 00650 /* Purpose: Pack variable 00651 Routine is inverse of nco_var_upk(): nco_var_pck[nco_var_upk(var)]=var 00652 Currently routine outputs same variable structure as given on input 00653 In other words, output structure may be neglected as all changes are made 00654 to input structure. 00655 NB: Value buffer var->val.vp is usually free()'d here 00656 Variables in calling routine which point to var->val.vp will be left dangling */ 00657 00658 bool PURE_MSS_VAL_FLD=False; /* [flg] Field is pure missing_value, i.e., no valid values */ 00659 const char fnc_nm[]="nco_var_pck()"; /* [sng] Function name */ 00660 double scl_fct_dbl=double_CEWI; /* [sct] Double precision value of scale_factor */ 00661 double add_fst_dbl=double_CEWI; /* [sct] Double precision value of add_offset */ 00662 00663 /* Set flag true once new scale_factor/add_offset generated */ 00664 *PCK_VAR_WITH_NEW_PCK_ATT=False; 00665 00666 /* Return if variable in memory is currently packed and should not be re-packed */ 00667 if(var->pck_ram) return var; 00668 00669 /* Routine should be called with variable already in memory */ 00670 if(var->val.vp == NULL) (void)fprintf(stdout,"%s: ERROR %s called with empty var->val.vp\n",prg_nm_get(),fnc_nm); 00671 00672 /* Packed type must be NC_BYTE, NC_CHAR, NC_SHORT, or NC_INT */ 00673 if(nc_typ_pck == NC_FLOAT || nc_typ_pck == NC_DOUBLE){ 00674 (void)fprintf(stdout,"%s: ERROR %s called to pack variable %s with invalid packed type nc_typ_pck = %s\n",prg_nm_get(),fnc_nm,var->nm,nco_typ_sng(nc_typ_pck)); 00675 nco_exit(EXIT_FAILURE); 00676 } /* endif */ 00677 00678 /* Variable must be packable (usually NC_INT, NC_FLOAT, or NC_DOUBLE) 00679 Definition of "packable" determined by nco_pck_plc_typ_get() 00680 Prefer not to make nco_var_pck() rely directly on nco_pck_plc_typ_get() 00681 However, certain types are never packable */ 00682 if(var->type == NC_CHAR || var->type == NC_BYTE){ 00683 (void)fprintf(stdout,"%s: ERROR %s is asked to pack variable %s of type %s\n",prg_nm_get(),fnc_nm,var->nm,nco_typ_sng(var->type)); 00684 nco_exit(EXIT_FAILURE); 00685 } /* endif */ 00686 00687 if(True){ /* Keep in own scope for eventual functionalization of core packing algorithm */ 00688 /* Compute packing parameters to apply to var 00689 00690 Linear packing in a nutshell: 00691 scale_factor = (max-min)/ndrv <--> (max-min)/scale_factor = ndrv <--> scale_factor*ndrv = max-min 00692 add_offset = 0.5*(min+max) 00693 pck = (upk-add_offset)/scale_factor = (upk-0.5*(min+max))*ndrv/(max-min) 00694 upk = scale_factor*pck + add_offset = (max-min)*pck/ndrv + 0.5*(min+max) 00695 00696 where 00697 00698 ndrv = number of discrete representable values for given type of packed variable and 00699 ndrv = 256 iff var->typ_pck == NC_CHAR 00700 ndrv = 256*256 iff var->typ_pck == NC_SHORT 00701 ndrv = 256*256*256*256 = 2^32 iff var->typ_pck == NC_INT */ 00702 00703 const double max_mns_min_dbl_wrn=1.0e10; /* [frc] Threshold value for warning */ 00704 double ndrv_dbl=double_CEWI; /* [frc] Double precision value of number of discrete representable values */ 00705 double max_mns_min_dbl; /* [frc] Maximum value minus minimum value */ 00706 00707 ptr_unn ptr_unn_min; /* [ptr] Pointer union to minimum value of variable */ 00708 ptr_unn ptr_unn_max; /* [ptr] Pointer union to maximum value of variable */ 00709 ptr_unn ptr_unn_mss_val_dbl; /* [ptr] Pointer union to missing value of variable */ 00710 00711 var_sct *min_var; /* [sct] Minimum value of variable */ 00712 var_sct *max_var; /* [sct] Maximum value of variable */ 00713 var_sct *max_var_dpl; /* [sct] Copy of Maximum value of variable */ 00714 var_sct *hlf_var; /* [sct] NCO variable for value 0.5 */ 00715 var_sct *zero_var; /* [sct] NCO variable for value 0.0 */ 00716 var_sct *ndrv_var; /* [sct] NCO variable for number of discrete representable values */ 00717 00718 val_unn hlf_unn; /* [frc] Generic container for value 0.5 */ 00719 val_unn zero_unn; /* [frc] Generic container for value 0.0 */ 00720 val_unn ndrv_unn; /* [nbr] Generic container for number of discrete representable values */ 00721 00722 /* Initialize data */ 00723 hlf_unn.d=0.5; /* Generic container for value 0.5 */ 00724 zero_unn.d=0.0; /* Generic container for value 0.0 */ 00725 00726 /* Derive scalar values for scale_factor and add_offset */ 00727 var->scl_fct.vp=nco_free(var->scl_fct.vp); 00728 var->add_fst.vp=nco_free(var->add_fst.vp); 00729 var->scl_fct.vp=(void *)nco_malloc(nco_typ_lng(var->type)); 00730 var->add_fst.vp=(void *)nco_malloc(nco_typ_lng(var->type)); 00731 ptr_unn_min.vp=(void *)nco_malloc(nco_typ_lng(var->type)); 00732 ptr_unn_max.vp=(void *)nco_malloc(nco_typ_lng(var->type)); 00733 00734 /* Create double precision missing_value for use in min/max arithmetic */ 00735 if(var->has_mss_val){ 00736 ptr_unn_mss_val_dbl.vp=(void *)nco_malloc(nco_typ_lng((nc_type)NC_DOUBLE)); 00737 (void)nco_val_cnf_typ(var->type,var->mss_val,(nc_type)NC_DOUBLE,ptr_unn_mss_val_dbl); 00738 } /* endif has_mss_val */ 00739 00740 /* Find minimum and maximum values in data */ 00741 (void)nco_var_avg_reduce_max(var->type,var->sz,1L,var->has_mss_val,var->mss_val,var->val,ptr_unn_min); 00742 (void)nco_var_avg_reduce_min(var->type,var->sz,1L,var->has_mss_val,var->mss_val,var->val,ptr_unn_max); 00743 00744 /* Convert to NC_DOUBLE before 0.5*(min+max) operation */ 00745 min_var=scl_ptr_mk_var(ptr_unn_min,var->type); 00746 min_var=nco_var_cnf_typ((nc_type)NC_DOUBLE,min_var); 00747 max_var=scl_ptr_mk_var(ptr_unn_max,var->type); 00748 max_var=nco_var_cnf_typ((nc_type)NC_DOUBLE,max_var); 00749 /* Copy max_var for use in scale_factor computation */ 00750 max_var_dpl=nco_var_dpl(max_var); 00751 hlf_var=scl_mk_var(hlf_unn,NC_DOUBLE); /* [sct] NCO variable for value one half */ 00752 00753 /* Field is pure missing_value iff either extrema is missing_value */ 00754 if(var->has_mss_val) 00755 if(min_var->val.dp[0] == ptr_unn_mss_val_dbl.dp[0]) 00756 PURE_MSS_VAL_FLD=True; 00757 00758 /* Change value of missing value iff necessary to fit inside packed type */ 00759 if(var->has_mss_val && !PURE_MSS_VAL_FLD){ 00760 double mss_val_dfl_dbl=0.0; /* CEWI */ 00761 switch(nc_typ_pck){ 00762 case NC_FLOAT: mss_val_dfl_dbl=NC_FILL_FLOAT; break; 00763 case NC_DOUBLE: mss_val_dfl_dbl=NC_FILL_DOUBLE; break; 00764 case NC_INT: mss_val_dfl_dbl=NC_FILL_INT; break; 00765 case NC_SHORT: mss_val_dfl_dbl=NC_FILL_SHORT; break; 00766 case NC_CHAR: mss_val_dfl_dbl=NC_FILL_CHAR; break; 00767 case NC_BYTE: mss_val_dfl_dbl=NC_FILL_BYTE; break; 00768 default: nco_dfl_case_nc_type_err(); break; 00769 } /* end switch */ 00770 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: %s mss_val_dfl = %g\n",prg_nm_get(),fnc_nm,mss_val_dfl_dbl); 00771 } /* endif */ 00772 00773 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: %s: min_var = %g, max_var = %g\n",prg_nm_get(),var->nm,min_var->val.dp[0],max_var->val.dp[0]); 00774 00775 /* add_offset is 0.5*(min+max) */ 00776 /* max_var->val is overridden with add_offset answers, no longer valid as max_var */ 00777 (void)nco_var_add((nc_type)NC_DOUBLE,1L,var->has_mss_val,ptr_unn_mss_val_dbl,min_var->val,max_var->val); 00778 (void)nco_var_mlt((nc_type)NC_DOUBLE,1L,var->has_mss_val,ptr_unn_mss_val_dbl,hlf_var->val,max_var->val); 00779 /* Contents of max_var are actually add_offset */ 00780 (void)nco_val_cnf_typ((nc_type)NC_DOUBLE,max_var->val,var->type,var->add_fst); 00781 00782 /* ndrv is 2^{bits per packed value} where bppv = 8 for NC_CHAR and bppv = 16 for NC_SHORT 00783 Subtract one to leave slop for rounding errors 00784 Subtract two to leave room for missing_value? */ 00785 if(nc_typ_pck == NC_BYTE || nc_typ_pck == NC_CHAR){ 00786 ndrv_dbl=256.0-1.0; /* [sct] Double precision value of number of discrete representable values */ 00787 }else if(nc_typ_pck == NC_SHORT){ 00788 ndrv_dbl=65536.0-1.0; /* [sct] Double precision value of number of discrete representable values */ 00789 }else if(nc_typ_pck == NC_INT){ 00790 ndrv_dbl=4294967295.0-1.0; /* [sct] Double precision value of number of discrete representable values */ 00791 } /* end else */ 00792 ndrv_unn.d=ndrv_dbl; /* Generic container for number of discrete representable values */ 00793 ndrv_var=scl_mk_var(ndrv_unn,NC_DOUBLE); /* [sct] Variable structure for number of discrete representable values */ 00794 00795 /* scale_factor is (max-min)/ndrv 00796 If max-min = 0 then variable is constant value so scale_factor=0.0 and add_offset=var 00797 If max-min > ndrv then precision is worse than 1.0 00798 If max-min < ndrv then precision is better than 1.0 */ 00799 (void)nco_var_sbt((nc_type)NC_DOUBLE,1L,var->has_mss_val,ptr_unn_mss_val_dbl,min_var->val,max_var_dpl->val); 00800 /* max-min is currently stored in max_var_dpl */ 00801 max_mns_min_dbl=ptr_unn_2_scl_dbl(max_var_dpl->val,max_var_dpl->type); 00802 00803 /* Manually set max-min=0.0 for pure missing_value fields to set add_offset correctly */ 00804 if(PURE_MSS_VAL_FLD) max_mns_min_dbl=0.0; 00805 00806 if(max_mns_min_dbl != 0.0){ 00807 (void)nco_var_dvd((nc_type)NC_DOUBLE,1L,var->has_mss_val,ptr_unn_mss_val_dbl,ndrv_var->val,max_var_dpl->val); 00808 /* Contents of max_var_dpl are actually scale_factor */ 00809 (void)nco_val_cnf_typ((nc_type)NC_DOUBLE,max_var_dpl->val,var->type,var->scl_fct); 00810 }else{ 00811 /* Variable is constant, i.e., equal values everywhere */ 00812 zero_var=scl_mk_var(zero_unn,var->type); /* [sct] NCO variable for value 0.0 */ 00813 /* Set scale_factor to 0.0 */ 00814 (void)memcpy(var->scl_fct.vp,zero_var->val.vp,nco_typ_lng(var->type)); 00815 if(zero_var != NULL) zero_var=nco_var_free(zero_var); 00816 /* Set add_offset to first variable value 00817 Variable is constant everywhere so particular value copied is unimportant */ 00818 (void)memcpy(var->add_fst.vp,var->val.vp,nco_typ_lng(var->type)); 00819 } /* end else */ 00820 00821 if(max_mns_min_dbl > max_mns_min_dbl_wrn){ 00822 (void)fprintf(stdout,"%s: WARNING %s reports data range of variable %s is = %g. The linear data packing technique defined by netCDF's packing convention and implemented by NCO result in significant precision loss over such a great range.\n",prg_nm_get(),fnc_nm,var->nm,max_mns_min_dbl); 00823 if(var->has_mss_val) (void)fprintf(stdout,"%s: HINT variable %s has missing_value = %g. Consider specifying new missing_value to reduce range of data needing packing. See http://nco.sf.net/nco.html#ncatted for examples of how to change the missing_value attribute.\n",prg_nm_get(),fnc_nm,ptr_unn_mss_val_dbl.dp[0]); 00824 } /* endif large data range */ 00825 00826 /* Free minimum and maximum values */ 00827 ptr_unn_min.vp=nco_free(ptr_unn_min.vp); 00828 ptr_unn_max.vp=nco_free(ptr_unn_max.vp); 00829 00830 /* Free temporary double missing_value */ 00831 if(var->has_mss_val) ptr_unn_mss_val_dbl.vp=nco_free(ptr_unn_mss_val_dbl.vp); 00832 00833 /* Free variables */ 00834 if(min_var != NULL) min_var=nco_var_free(min_var); 00835 if(max_var != NULL) max_var=nco_var_free(max_var); 00836 if(max_var_dpl != NULL) max_var_dpl=nco_var_free(max_var_dpl); 00837 if(hlf_var != NULL) hlf_var=nco_var_free(hlf_var); 00838 if(ndrv_var != NULL) ndrv_var=nco_var_free(ndrv_var); 00839 00840 /* Do not bother creating superfluous scale_factor (0.0 or 1.0) or add_offset (0.0) */ 00841 scl_fct_dbl=ptr_unn_2_scl_dbl(var->scl_fct,var->type); 00842 add_fst_dbl=ptr_unn_2_scl_dbl(var->add_fst,var->type); 00843 00844 if(scl_fct_dbl != 0.0 && scl_fct_dbl != 1.0) var->has_scl_fct=True; /* [flg] Valid scale_factor attribute exists */ 00845 if(add_fst_dbl != 0.0) var->has_add_fst=True; /* [flg] Valid add_offset attribute exists */ 00846 00847 /* However, must create either scale_factor or add_offset 00848 Otherwise, routine fails to pack field uniformly equal to zero (0.0) 00849 In zero corner case, create add_offset (avoids division by zero problems) */ 00850 if(scl_fct_dbl == 0.0 && add_fst_dbl == 0.0) var->has_add_fst=True; 00851 00852 } /* endif True */ 00853 00854 /* Create double precision value of scale_factor for diagnostics */ 00855 if(var->has_scl_fct){ /* [flg] Valid scale_factor attribute exists */ 00856 scl_fct_dbl=ptr_unn_2_scl_dbl(var->scl_fct,var->type); 00857 if(scl_fct_dbl == 0.0) (void)fprintf(stdout,"%s: WARNING %s reports scl_fct_dbl = 0.0\n",prg_nm_get(),fnc_nm); 00858 } /* endif */ 00859 00860 /* Create double precision value of add_offset for diagnostics */ 00861 if(var->has_add_fst){ /* [flg] Valid add_offset attribute exists */ 00862 add_fst_dbl=ptr_unn_2_scl_dbl(var->add_fst,var->type); 00863 } /* endif */ 00864 00865 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: %s reports variable %s has scl_fct_dbl = %g, add_fst_dbl = %g\n",prg_nm_get(),fnc_nm,var->nm,scl_fct_dbl,add_fst_dbl); 00866 00867 /* Packing attributes now exist and are same type as variable in memory */ 00868 00869 /* Apply scale_factor and add_offset to reduce variable size 00870 add_offset and scale_factor are always scalars so use var_scv_* functions 00871 var_scv_[sub,multiply] functions avoid cost of broadcasting attributes and doing element-by-element operations 00872 Using var_scv_[sub,multiply] instead of ncap_var_scv_[sub,multiply] avoids cost of deep copies 00873 Moreover, this keeps variable structure from changing (because ncap_var_scv_* functions all do deep copies before operations) and thus complicating memory management */ 00874 if(var->has_add_fst){ /* [flg] Valid add_offset attribute exists */ 00875 bool has_mss_val_tmp; /* [flg] Temporary missing_value flag */ 00876 00877 /* Subtract add_offset from var */ 00878 scv_sct add_fst_scv; 00879 add_fst_scv.type=NC_DOUBLE; 00880 add_fst_scv.val.d=add_fst_dbl; 00881 (void)nco_scv_cnf_typ(var->type,&add_fst_scv); 00882 /* Pass temporary missing_value flag to accomodate pure missing_value fields */ 00883 has_mss_val_tmp=var->has_mss_val; 00884 /* Dupe var_scv_sub() into subtracting missing values when all values are missing */ 00885 if(PURE_MSS_VAL_FLD){ 00886 has_mss_val_tmp=False; 00887 (void)fprintf(stdout,"%s: INFO %s reports variable %s is completely missing_value = %g. Why do you store variables with no valid values?\n",prg_nm_get(),fnc_nm,var->nm,add_fst_dbl); 00888 } /* !PURE_MSS_VAL_FLD */ 00889 (void)var_scv_sub(var->type,var->sz,has_mss_val_tmp,var->mss_val,var->val,&add_fst_scv); 00890 } /* endif */ 00891 00892 if(var->has_scl_fct){ /* [flg] Valid scale_factor attribute exists */ 00893 /* Divide var by scale_factor */ 00894 scv_sct scl_fct_scv; 00895 scl_fct_scv.type=NC_DOUBLE; 00896 scl_fct_scv.val.d=scl_fct_dbl; 00897 (void)nco_scv_cnf_typ(var->type,&scl_fct_scv); 00898 if(scl_fct_dbl != 0.0) (void)var_scv_dvd(var->type,var->sz,var->has_mss_val,var->mss_val,var->val,&scl_fct_scv); 00899 } /* endif */ 00900 00901 if(!var->has_scl_fct && !var->has_add_fst){ 00902 (void)fprintf(stderr,"%s: ERROR Reached end of %s without packing variable\n",prg_nm_get(),fnc_nm); 00903 nco_exit(EXIT_FAILURE); 00904 }else{ 00905 *PCK_VAR_WITH_NEW_PCK_ATT=True; /* O [flg] Routine generated new scale_factor/add_offset */ 00906 } /* endif */ 00907 00908 /* Tell the world we packed the variable 00909 This is true if input variable satisfied nco_pck_plc_typ_get() criteria 00910 Variables that fail nco_pck_plc_typ_get() (e.g., type == NC_CHAR) are not packed 00911 and should not have their packing attributes set */ 00912 var->pck_ram=True; /* [flg] Variable is packed in memory */ 00913 var->typ_pck=nc_typ_pck; /* [enm] Type of variable when packed (on disk). This should be same as typ_dsk except in cases where variable is packed in input file and unpacked in output file. */ 00914 var->typ_upk=var->type; /* [enm] Type of variable when unpacked (expanded) (in memory) */ 00915 00916 /* Convert variable to user-specified packed type 00917 This is where var->type is changed from original to packed type */ 00918 var=nco_var_cnf_typ(nc_typ_pck,var); 00919 00920 if(dbg_lvl_get() >= 3) (void)fprintf(stdout,"%s: PACKING %s packed %s into %s\n",prg_nm_get(),fnc_nm,var->nm,nco_typ_sng(var->type)); 00921 00922 return var; 00923 } /* end nco_var_pck() */
|
|
|
Definition at line 927 of file nco_pck.c. References var_sct_tag::add_fst, dbg_lvl_get(), False, var_sct_tag::has_add_fst, var_sct_tag::has_mss_val, var_sct_tag::has_scl_fct, var_sct_tag::id, var_sct_tag::mss_val, var_sct_tag::nc_id, nco_cnv_mss_val_typ(), nco_free(), nco_get_att(), nco_malloc(), nco_typ_lng(), nco_typ_sng(), nco_var_cnf_typ(), var_sct_tag::nm, var_sct_tag::pck_ram, prg_nm_get(), ptr_unn_2_scv(), var_sct_tag::scl_fct, var_sct_tag::sz, var_sct_tag::typ_upk, var_sct_tag::type, scv_sct::type, var_sct_tag::val, var_scv_add(), var_scv_mlt(), and ptr_unn::vp. Referenced by nco_var_get(), and nco_var_upk_swp(). 00928 { 00929 /* Threads: Routine is thread-safe */ 00930 /* Purpose: Unpack variable 00931 Routine is inverse of nco_var_pck(): nco_var_upk[nco_var_pck(var)]=var 00932 Routine handles missing_value's implicitly: 00933 nco_var_cnf_typ() automatically converts missing_value, if any, to unpacked type 00934 This may need to change when nco427 is addressed */ 00935 00936 const char fnc_nm[]="nco_var_upk()"; 00937 const char scl_fct_sng[]="scale_factor"; /* [sng] Unidata standard string for scale factor */ 00938 const char add_fst_sng[]="add_offset"; /* [sng] Unidata standard string for add offset */ 00939 00940 /* Return if variable in memory is not currently packed */ 00941 if(!var->pck_ram) return var; 00942 00943 /* Routine should be called with variable already in memory */ 00944 if(var->val.vp == NULL) (void)fprintf(stdout,"%s: ERROR nco_var_upk() called with empty var->val.vp\n",prg_nm_get()); 00945 00946 /* Packed variables are not guaranteed to have both scale_factor and add_offset 00947 scale_factor is guaranteed to be of type NC_FLOAT or NC_DOUBLE and of size 1 (a scalar) */ 00948 00949 /* Create scalar value structures from values of scale_factor, add_offset */ 00950 if(var->has_scl_fct){ /* [flg] Valid scale_factor attribute exists */ 00951 scv_sct scl_fct_scv; 00952 var->scl_fct.vp=(void *)nco_malloc(nco_typ_lng(var->typ_upk)); 00953 (void)nco_get_att(var->nc_id,var->id,scl_fct_sng,var->scl_fct.vp,var->typ_upk); 00954 scl_fct_scv=ptr_unn_2_scv(var->typ_upk,var->scl_fct); 00955 /* Convert var to type of scale_factor for expansion */ 00956 var=nco_var_cnf_typ(scl_fct_scv.type,var); 00957 /* Multiply var by scale_factor */ 00958 (void)var_scv_mlt(var->type,var->sz,var->has_mss_val,var->mss_val,var->val,&scl_fct_scv); 00959 } /* endif has_scl_fct */ 00960 00961 if(var->has_add_fst){ /* [flg] Valid add_offset attribute exists */ 00962 scv_sct add_fst_scv; 00963 var->add_fst.vp=(void *)nco_malloc(nco_typ_lng(var->typ_upk)); 00964 /* fxm TODO nco638 */ 00965 (void)nco_get_att(var->nc_id,var->id,add_fst_sng,var->add_fst.vp,var->typ_upk); 00966 add_fst_scv=ptr_unn_2_scv(var->typ_upk,var->add_fst); 00967 /* Convert var to type of scale_factor for expansion */ 00968 var=nco_var_cnf_typ(add_fst_scv.type,var); 00969 /* Add add_offset to var */ 00970 (void)var_scv_add(var->type,var->sz,var->has_mss_val,var->mss_val,var->val,&add_fst_scv); 00971 } /* endif has_add_fst */ 00972 00973 if(var->has_mss_val) var=nco_cnv_mss_val_typ(var,var->type); 00974 00975 /* Tell the world */ 00976 var->pck_ram=False; 00977 00978 /* Clean up tell-tale signs that variable was ever packed */ 00979 var->has_scl_fct=False; /* [flg] Valid scale_factor attribute exists */ 00980 var->has_add_fst=False; /* [flg] Valid add_offset attribute exists */ 00981 var->scl_fct.vp=nco_free(var->scl_fct.vp); 00982 var->add_fst.vp=nco_free(var->add_fst.vp); 00983 00984 if(dbg_lvl_get() > 2) (void)fprintf(stdout,"%s: PACKING %s unpacked %s into %s\n",prg_nm_get(),fnc_nm,var->nm,nco_typ_sng(var->type)); 00985 00986 return var; 00987 } /* end nco_var_upk() */
|
|
||||||||||||
|
Definition at line 991 of file nco_pck.c. References dbg_lvl_get(), EXIT_FAILURE, var_sct_tag::has_add_fst, var_sct_tag::has_scl_fct, var_sct_tag::mss_val, nco_exit(), nco_free(), nco_typ_sng(), nco_var_dpl(), nco_var_free(), nco_var_upk(), var_sct_tag::nm, var_sct_tag::pck_ram, prg_nm_get(), var_sct_tag::type, var_sct_tag::val, and ptr_unn::vp. Referenced by nco_pck_val(). 00993 { 00994 /* Purpose: Unpack var_in into var_out 00995 Information flow in ncpdq prevents ncpdq from calling nco_var_upk() 00996 directly with either var_in or var_out. 00997 Need combination of var_in (for correct file and variable IDs) 00998 and var_out (so unpacked variable ends up in correct place) 00999 Accomplish this by unpacking into temporary variable and copying 01000 needed information from temporary (swap) variable to var_out. 01001 Routine hides gory details of swapped unpacking 01002 var_in is untouched except var_in->val buffer is free()'d 01003 01004 nco_pck_val() uses this routine for two purposes: 01005 1. Unpack already packed variable prior to re-packing them 01006 2. Unpack already packed variables permanently */ 01007 const char fnc_nm[]="nco_var_upk_swp()"; 01008 var_sct *var_tmp; /* [sct] Temporary variable to be unpacked */ 01009 01010 if(var_in->pck_ram){ 01011 if(dbg_lvl_get() > 3) (void)fprintf(stdout,"%s: DEBUG %s unpacking variable %s values from %s to %s\n",prg_nm_get(),fnc_nm,var_in->nm,nco_typ_sng(var_out->typ_pck),nco_typ_sng(var_out->typ_upk)); 01012 }else{ 01013 (void)fprintf(stderr,"%s: ERROR %s variable %s is already unpacked\n",prg_nm_get(),fnc_nm,var_in->nm); 01014 nco_exit(EXIT_FAILURE); 01015 } /* endif not already packed */ 01016 01017 /* Output file does not contain packing attributes yet 01018 Hence unpacking var_out directly is impossible 01019 Instead, make var_tmp a copy of var_in and unpack var_tmp 01020 Then copy needed elements of var_tmp to var_out 01021 Then delete the rest of var_tmp 01022 Fields modified in nco_var_upk() must be explicitly updated in var_out */ 01023 var_tmp=nco_var_dpl(var_in); 01024 /* Free current input buffer */ 01025 var_in->val.vp=nco_free(var_in->val.vp); 01026 /* Unpack temporary variable */ 01027 var_tmp=nco_var_upk(var_tmp); 01028 /* Save relevent parts of temporary variable into output variable */ 01029 var_out->type=var_tmp->type; 01030 var_out->val=var_tmp->val; 01031 var_out->pck_ram=var_tmp->pck_ram; 01032 /* nco_var_cnf_typ() in nco_var_upk() automatically converts missing_value, if any, to unpacked type */ 01033 if(var_out->has_mss_val){ 01034 /* Free current missing value before obtaining new one */ 01035 var_out->mss_val.vp=(void *)nco_free(var_out->mss_val.vp); 01036 var_out->mss_val=var_tmp->mss_val; 01037 /* var_out now owns mss_val, make sure nco_var_free(var_tmp) ignores it */ 01038 var_tmp->mss_val.vp=NULL; 01039 } /* endif */ 01040 var_out->has_scl_fct=var_tmp->has_scl_fct; 01041 var_out->has_add_fst=var_tmp->has_add_fst; 01042 var_out->scl_fct.vp=nco_free(var_out->scl_fct.vp); 01043 var_out->add_fst.vp=nco_free(var_out->add_fst.vp); 01044 /* var_tmp->val buffer now doubles as var_out->val buffer 01045 Prevent nco_var_free() from free()'ing var_tmp->val 01046 Setting var_tmp->val.vp=NULL accomplishes this 01047 Use var_out->val.vp to free() this buffer later with nco_var_free() */ 01048 var_tmp->val.vp=NULL; 01049 if(var_tmp != NULL) var_tmp=nco_var_free(var_tmp); 01050 } /* end nco_var_upk_swp() */
|
1.4.4