<div dir="ltr">Hauss,<div><br></div><div>Thanks to Kevin for a thorough description of scale/offset packing and its issues.  NCL is also easily capable of creating Netcdf-4 compressed files from scratch.  I recommend this modern approach in preference to scale/offset, because of simplicity for data users, and avoidance of possible numeric problems.</div><div><br></div><div>Netcdf-4 compressed requires a few extra set-up steps when you first create the initial file in NCL.  Set the file format to "NetCDF4Classic", and the compression level to a low value 1-3 initially.  For large arrays, set medium chunk sizes in the range of 10,000 to 500,000 bytes per chunk.   For low and medium resolution gridded data, one grid per chunk is a common scheme.  More details and examples of writing netcdf-4 are found here:</div><div><br></div><div>   <a href="https://www.ncl.ucar.edu/Applications/write_netcdf.shtml">https://www.ncl.ucar.edu/Applications/write_netcdf.shtml</a></div><div><br></div><div><div>Netcdf-4 compression works well in general, but it also responds to reduced number of decimal places on input, resulting in slightly improved compression.</div><div><br></div><div>--Dave</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 26, 2018 at 12:53 PM, Kevin Hallock <span dir="ltr"><<a href="mailto:hallock@ucar.edu" target="_blank">hallock@ucar.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word">Hi Hauss,<div><br></div><div>That is correct, NCL uses a consistent data type for all elements of an array without considering whether individual values in the array actually require that level of precision. If an array contained a mix of data types, then in order to access a specific index it would be necessary to determine the size of every element before it; in a single-data-type array (let’s say “float”), the memory address of a particular index is easily determined as an offset from the beginning of the array equal to “<font face="Menlo">sizeof(float) * index</font>”, where the size of a float variable is 4 bytes. Just determining the memory address of an index in a mixed-type array is difficult enough, so trying to perform an actual computation across a multi-dimensional array of mixed types would likely be very slow compared to a homogeneous array.</div><div><br></div><div><br></div><div>If you’re certain that losing several decimal places of precision is alright, then you could try using NCL’s <a href="http://www.ncl.ucar.edu/Document/Functions/Contributed/pack_values.shtml" target="_blank">pack_values</a> function. pack_values can “pack” a float (4 bytes per value) or double (8 bytes per value) type array into either “short” (2 bytes) or “byte” (1 byte) arrays, using a multiplier and an offset value to “unpack” an approximation of the original float/double data.</div><div><br></div><div>Please note that “packing” data into a smaller data type is a form of “lossy” compression, meaning it may not be possible to recover the exact original data from the compressed data.</div><div><br></div><div>If you have a float array “a_float” that you want to compress by a factor of 2, you could pack_values() it into a short array:</div><div><font face="Menlo">a_short = pack_values(a_float, "short", False)</font></div><div><font face="Menlo">a_unpacked = short2flt(a_short)<span class="gmail-m_-1790059104186181233Apple-tab-span" style="white-space:pre-wrap">  </span><span class="gmail-m_-1790059104186181233Apple-tab-span" style="white-space:pre-wrap">           </span>; This is essentially the same as "(a_short * a_short@scale_factor) + a_short@add_offset"</font></div><div><br></div><div>You will likely want to compare your original array with the new packed-then-unpacked array to evaluate whether the lost precision is acceptable for your use case.</div><div><br></div><div>It is also possible to pack values into a “byte” array (4 bytes to 1 byte compression in this case), although the loss of precision will be even more apparent:</div><div><div><font face="Menlo">a_byte = pack_values(a_float, "byte", False)</font></div><div><font face="Menlo">a_unpacked = byte2flt(a_byte)</font></div></div><div><font face="Menlo"><br></font></div><div>Alternatively, there is a way to do this outside of NCL for a netcdf file that already exists using a software package called <a href="http://nco.sourceforge.net/" target="_blank">NetCDF Operators</a>. In particular, the <a href="http://nco.sourceforge.net/nco.html#ncpdq" target="_blank">ncpdq</a> operator can be used to pack data as follows:</div><div><font face="Menlo">ncpdq <a href="http://infile.nc" target="_blank">infile.nc</a> <a href="http://outfile.nc" target="_blank">outfile.nc</a></font></div><div><br></div><div>I hope this helps,</div><div>Kevin</div><div><br><div><blockquote type="cite"><div>On Jun 25, 2018, at 7:47 PM, Hauss Reinbold <<a href="mailto:Hauss.Reinbold@dri.edu" target="_blank">Hauss.Reinbold@dri.edu</a>> wrote:</div><br class="gmail-m_-1790059104186181233Apple-interchange-newline"><div><div>Hi all,<br><br>I’m creating a large netcdf dataset via NCL and I was looking to reduce the file size by reducing the number of decimal places the float values were holding, but it doesn’t look like it worked. In looking into it further, it seems like NCL allocates space in the file by data type, regardless of what value each individual index of an array might have. Is that correct?<br><br>I did some looking and couldn’t see a way to reduce file size explicitly other than by changing data type, which I don’t think I can do. Is there a way to reduce the file size of the netcdf file by limiting the number of decimal places? Or is compression or changing the data type my only alternative here?<br><br>Thanks for any help on this.<br><br>Hauss Reinbold</div></div></blockquote></div></div></div></blockquote></div></div></div></div>