public static void calcScaleOffset(GribData.Bean bean1, Formatter f) {
    float[] data;
    try {
      data = bean1.readData();
    } catch (IOException e) {
      f.format("IOException %s", e.getMessage());
      return;
    }
    int npoints = data.length;

    // we always use unsigned packed
    // "If the packed values are intended to be interpreted as signed/unsigned integers"
    // http://www.unidata.ucar.edu/software/netcdf/docs/BestPractices.html
    int nbits = bean1.getNBits();
    int width = (2 << nbits - 1) - 2;                // unsigned
    int missing_value = (2 << nbits - 1) - 1;       // all ones - reserved for missing value

    // int width2 = (2 << (nbits-1)) - 1;  // signed
    f.format(" nbits = %d%n", nbits);
    f.format(" npoints = %d%n", npoints);
    f.format(" width = %d (0x%s) %n", width, Long.toHexString(width));
    f.format(" scale = %g %n", bean1.getScale());
    f.format(" resolution = %g %n", bean1.getScale() / 2);
    f.format(" range = %f %n%n", bean1.getMaximum() - bean1.getMinimum());

    float dataMin = Float.MAX_VALUE;
    float dataMax = -Float.MAX_VALUE;
    for (float fd : data) {
      if (Float.isNaN(fd)) continue;
      dataMin = Math.min(dataMin, fd);
      dataMax = Math.max(dataMax, fd);
    }
    f.format("           actual    computed%n");
    f.format(" dataMin = %8f %8f%n", dataMin, bean1.getMinimum());
    f.format(" dataMax = %8f %8f%n", dataMax, bean1.getMaximum());

    f.format(" actual range = %f%n", (dataMax - dataMin));

    // scale_factor =(dataMax - dataMin) / (2^n - 1)
    // add_offset = dataMin + 2^(n-1) * scale_factor

    double scale_factor = (dataMax - dataMin) / width;
    // float add_offset = dataMin + width2 * scale_factor / 2; // signed
    double add_offset = dataMin;                             // unsigned

    f.format(" scale_factor = %g%n", scale_factor);
    f.format(" add_offset = %g%n", add_offset);

    // unpacked_data_value = packed_data_value * scale_factor + add_offset
    // packed_data_value = nint((unpacked_data_value - add_offset) / scale_factor)

    ByteBuffer bb = ByteBuffer.allocate(4 * npoints);
    IntBuffer intBuffer = bb.asIntBuffer();
    double diffMax = -Double.MAX_VALUE;
    double diffTotal = 0;
    double diffTotal2 = 0;
    for (float fd : data) {
      if (Float.isNaN(fd)) {
        intBuffer.put(missing_value);
        continue;
      }

      // otherwise pack it
      int packed_data = (int) Math.round((fd - add_offset) / scale_factor);   // nint((unpacked_data_value - add_offset) / scale_factor)
      double unpacked_data = packed_data * scale_factor + add_offset;
      double diff = Math.abs(fd - unpacked_data);
      if (diff > scale_factor / 2)
        f.format("***   org=%g, packed_data=%d unpacked=%g diff = %g%n", fd, packed_data, unpacked_data, diff);

      diffMax = Math.max(diffMax, diff);
      diffTotal += diff;
      diffTotal2 += diff * diff;
      intBuffer.put(packed_data);
    }

    f.format("%n max_diff = %g%n", diffMax);
    f.format(" avg_diff = %g%n", diffTotal / data.length);

    // Math.sqrt( sumsq/n - avg * avg)
    double mean = diffTotal / npoints;
    double var = (diffTotal2 / npoints - mean * mean);
    f.format(" std_diff = %g%n", Math.sqrt(var));

    f.format("%nCompression%n");
    f.format(" number of values = %d%n", npoints);
    f.format(" uncompressed as floats = %d%n", npoints * 4);
    int packedBitsLen = npoints * nbits / 8;
    f.format(" uncompressed packed bits = %d%n", packedBitsLen);
    f.format(" grib data length = %d%n", bean1.getDataLength());
    f.format(" grib msg length = %d%n", bean1.getMsgLength());

    byte[] bdata = convertToBytes(data);
    byte[] scaledData = bb.array();

    ////////////////////////////////////////////
    f.format("%ndeflate (float)%n");
    Deflater deflater = new Deflater();
    deflater.setInput(bdata);
    deflater.finish();
    int compressedSize = deflater.deflate(new byte[10 * npoints]);
    deflater.end();
    f.format(" compressedSize = %d%n", compressedSize);
    f.format(" ratio floats / size = %f%n", (float) (npoints * 4) / compressedSize);
    f.format(" ratio packed bits / size = %f%n", (float) packedBitsLen / compressedSize);
    f.format(" ratio size / grib = %f%n", (float) compressedSize / bean1.getMsgLength());

    /////////////////////////////////////////////////////////
    f.format("%ndeflate (scaled ints)%n");
    deflater = new Deflater();
    deflater.setInput(scaledData);
    deflater.finish();
    compressedSize = deflater.deflate(new byte[10 * npoints]);
    deflater.end();

    f.format(" compressedSize = %d%n", compressedSize);
    f.format(" ratio floats / size = %f%n", (float) (npoints * 4) / compressedSize);
    f.format(" ratio packed bits / size = %f%n", (float) packedBitsLen / compressedSize);
    f.format(" ratio size / grib = %f%n", (float) compressedSize / bean1.getMsgLength());
  }
public static void calcScaleOffset(GribData.Bean bean1, Formatter f) {
    float[] data;
    try {
      data = bean1.readData();
    } catch (IOException e) {
      f.format("IOException %s", e.getMessage());
      return;
    }
    int npoints = data.length;

    
    
    
    int nbits = bean1.getNBits();
    int width = (2 << nbits - 1) - 2;                
    int missing_value = (2 << nbits - 1) - 1;       

    
    f.format(" nbits = %d%n", nbits);
    f.format(" npoints = %d%n", npoints);
    f.format(" width = %d (0x%s) %n", width, Long.toHexString(width));
    f.format(" scale = %g %n", bean1.getScale());
    f.format(" resolution = %g %n", bean1.getScale() / 2);
    f.format(" range = %f %n%n", bean1.getMaximum() - bean1.getMinimum());

    float dataMin = Float.MAX_VALUE;
    float dataMax = -Float.MAX_VALUE;
    for (float fd : data) {
      if (Float.isNaN(fd)) continue;
      dataMin = Math.min(dataMin, fd);
      dataMax = Math.max(dataMax, fd);
    }
    f.format("           actual    computed%n");
    f.format(" dataMin = %8f %8f%n", dataMin, bean1.getMinimum());
    f.format(" dataMax = %8f %8f%n", dataMax, bean1.getMaximum());

    f.format(" actual range = %f%n", (dataMax - dataMin));

    
    

    double scale_factor = (dataMax - dataMin) / width;
    
    double add_offset = dataMin;                             

    f.format(" scale_factor = %g%n", scale_factor);
    f.format(" add_offset = %g%n", add_offset);

    
    

    ByteBuffer bb = ByteBuffer.allocate(4 * npoints);
    IntBuffer intBuffer = bb.asIntBuffer();
    double diffMax = -Double.MAX_VALUE;
    double diffTotal = 0;
    double diffTotal2 = 0;
    for (float fd : data) {
      if (Float.isNaN(fd)) {
        intBuffer.put(missing_value);
        continue;
      }

      
      int packed_data = (int) Math.round((fd - add_offset) / scale_factor);   
      double unpacked_data = packed_data * scale_factor + add_offset;
      double diff = Math.abs(fd - unpacked_data);
      if (diff > scale_factor / 2)
        f.format("***   org=%g, packed_data=%d unpacked=%g diff = %g%n", fd, packed_data, unpacked_data, diff);

      diffMax = Math.max(diffMax, diff);
      diffTotal += diff;
      diffTotal2 += diff * diff;
      intBuffer.put(packed_data);
    }

    f.format("%n max_diff = %g%n", diffMax);
    f.format(" avg_diff = %g%n", diffTotal / data.length);

    
    double mean = diffTotal / npoints;
    double var = (diffTotal2 / npoints - mean * mean);
    f.format(" std_diff = %g%n", Math.sqrt(var));

    f.format("%nCompression%n");
    f.format(" number of values = %d%n", npoints);
    f.format(" uncompressed as floats = %d%n", npoints * 4);
    int packedBitsLen = npoints * nbits / 8;
    f.format(" uncompressed packed bits = %d%n", packedBitsLen);
    f.format(" grib data length = %d%n", bean1.getDataLength());
    f.format(" grib msg length = %d%n", bean1.getMsgLength());

    byte[] bdata = convertToBytes(data);
    byte[] scaledData = bb.array();

    
    f.format("%ndeflate (float)%n");
    Deflater deflater = new Deflater();
    deflater.setInput(bdata);
    deflater.finish();
    int compressedSize = deflater.deflate(new byte[10 * npoints]);
    deflater.end();
    f.format(" compressedSize = %d%n", compressedSize);
    f.format(" ratio floats / size = %f%n", (float) (npoints * 4) / compressedSize);
    f.format(" ratio packed bits / size = %f%n", (float) packedBitsLen / compressedSize);
    f.format(" ratio size / grib = %f%n", (float) compressedSize / bean1.getMsgLength());

    
    f.format("%ndeflate (scaled ints)%n");
    deflater = new Deflater();
    deflater.setInput(scaledData);
    deflater.finish();
    compressedSize = deflater.deflate(new byte[10 * npoints]);
    deflater.end();

    f.format(" compressedSize = %d%n", compressedSize);
    f.format(" ratio floats / size = %f%n", (float) (npoints * 4) / compressedSize);
    f.format(" ratio packed bits / size = %f%n", (float) packedBitsLen / compressedSize);
    f.format(" ratio size / grib = %f%n", (float) compressedSize / bean1.getMsgLength());
  }
public static void calcScaleOffset ( GribData . Bean bean1 , Formatter f ) { float [ ] data ; try { data = bean1 . readData ( ) ; } catch ( IOException e ) { f . format ( "IOException %s" , e . getMessage ( ) ) ; return ; } int npoints = data . length ; // we always use unsigned packed // "If the packed values are intended to be interpreted as signed/unsigned integers" // http://www.unidata.ucar.edu/software/netcdf/docs/BestPractices.html int nbits = bean1 . getNBits ( ) ; int width = ( 2 << nbits - 1 ) - 2 ; // unsigned int missing_value = ( 2 << nbits - 1 ) - 1 ; // all ones - reserved for missing value // int width2 = (2 << (nbits-1)) - 1;  // signed f . format ( " nbits = %d%n" , nbits ) ; f . format ( " npoints = %d%n" , npoints ) ; f . format ( " width = %d (0x%s) %n" , width , Long . toHexString ( width ) ) ; f . format ( " scale = %g %n" , bean1 . getScale ( ) ) ; f . format ( " resolution = %g %n" , bean1 . getScale ( ) / 2 ) ; f . format ( " range = %f %n%n" , bean1 . getMaximum ( ) - bean1 . getMinimum ( ) ) ; float dataMin = Float . MAX_VALUE ; float dataMax = - Float . MAX_VALUE ; for ( float fd : data ) { if ( Float . isNaN ( fd ) ) continue ; dataMin = Math . min ( dataMin , fd ) ; dataMax = Math . max ( dataMax , fd ) ; } f . format ( "           actual    computed%n" ) ; f . format ( " dataMin = %8f %8f%n" , dataMin , bean1 . getMinimum ( ) ) ; f . format ( " dataMax = %8f %8f%n" , dataMax , bean1 . getMaximum ( ) ) ; f . format ( " actual range = %f%n" , ( dataMax - dataMin ) ) ; // scale_factor =(dataMax - dataMin) / (2^n - 1) // add_offset = dataMin + 2^(n-1) * scale_factor double scale_factor = ( dataMax - dataMin ) / width ; // float add_offset = dataMin + width2 * scale_factor / 2; // signed double add_offset = dataMin ; // unsigned f . format ( " scale_factor = %g%n" , scale_factor ) ; f . format ( " add_offset = %g%n" , add_offset ) ; // unpacked_data_value = packed_data_value * scale_factor + add_offset // packed_data_value = nint((unpacked_data_value - add_offset) / scale_factor) ByteBuffer bb = ByteBuffer . allocate ( 4 * npoints ) ; IntBuffer intBuffer = bb . asIntBuffer ( ) ; double diffMax = - Double . MAX_VALUE ; double diffTotal = 0 ; double diffTotal2 = 0 ; for ( float fd : data ) { if ( Float . isNaN ( fd ) ) { intBuffer . put ( missing_value ) ; continue ; } // otherwise pack it int packed_data = ( int ) Math . round ( ( fd - add_offset ) / scale_factor ) ; // nint((unpacked_data_value - add_offset) / scale_factor) double unpacked_data = packed_data * scale_factor + add_offset ; double diff = Math . abs ( fd - unpacked_data ) ; if ( diff > scale_factor / 2 ) f . format ( "***   org=%g, packed_data=%d unpacked=%g diff = %g%n" , fd , packed_data , unpacked_data , diff ) ; diffMax = Math . max ( diffMax , diff ) ; diffTotal += diff ; diffTotal2 += diff * diff ; intBuffer . put ( packed_data ) ; } f . format ( "%n max_diff = %g%n" , diffMax ) ; f . format ( " avg_diff = %g%n" , diffTotal / data . length ) ; // Math.sqrt( sumsq/n - avg * avg) double mean = diffTotal / npoints ; double var = ( diffTotal2 / npoints - mean * mean ) ; f . format ( " std_diff = %g%n" , Math . sqrt ( var ) ) ; f . format ( "%nCompression%n" ) ; f . format ( " number of values = %d%n" , npoints ) ; f . format ( " uncompressed as floats = %d%n" , npoints * 4 ) ; int packedBitsLen = npoints * nbits / 8 ; f . format ( " uncompressed packed bits = %d%n" , packedBitsLen ) ; f . format ( " grib data length = %d%n" , bean1 . getDataLength ( ) ) ; f . format ( " grib msg length = %d%n" , bean1 . getMsgLength ( ) ) ; byte [ ] bdata = convertToBytes ( data ) ; byte [ ] scaledData = bb . array ( ) ; //////////////////////////////////////////// f . format ( "%ndeflate (float)%n" ) ; Deflater deflater = new Deflater ( ) ; deflater . setInput ( bdata ) ; deflater . finish ( ) ; int compressedSize = deflater . deflate ( new byte [ 10 * npoints ] ) ; deflater . end ( ) ; f . format ( " compressedSize = %d%n" , compressedSize ) ; f . format ( " ratio floats / size = %f%n" , ( float ) ( npoints * 4 ) / compressedSize ) ; f . format ( " ratio packed bits / size = %f%n" , ( float ) packedBitsLen / compressedSize ) ; f . format ( " ratio size / grib = %f%n" , ( float ) compressedSize / bean1 . getMsgLength ( ) ) ; ///////////////////////////////////////////////////////// f . format ( "%ndeflate (scaled ints)%n" ) ; deflater = new Deflater ( ) ; deflater . setInput ( scaledData ) ; deflater . finish ( ) ; compressedSize = deflater . deflate ( new byte [ 10 * npoints ] ) ; deflater . end ( ) ; f . format ( " compressedSize = %d%n" , compressedSize ) ; f . format ( " ratio floats / size = %f%n" , ( float ) ( npoints * 4 ) / compressedSize ) ; f . format ( " ratio packed bits / size = %f%n" , ( float ) packedBitsLen / compressedSize ) ; f . format ( " ratio size / grib = %f%n" , ( float ) compressedSize / bean1 . getMsgLength ( ) ) ; }
This reports how well different compression schemes would work on the specific data.
Should be renamed
This reports how well different compression schemes would work on the specific data . Should be renamed