// Grid point data - simple packing private float[] getData0(RandomAccessFile raf, Grib2Drs.Type0 gdrs) throws IOException { int nb = gdrs.numberOfBits; int D = gdrs.decimalScaleFactor; float DD = (float) java.lang.Math.pow((double) 10, (double) D); float R = gdrs.referenceValue; int E = gdrs.binaryScaleFactor; float EE = (float) java.lang.Math.pow((double) 2.0, (double) E); // LOOK: can # datapoints differ from bitmap and data ? // dataPoints are number of points encoded, it could be less than the // totalNPoints in the grid record if bitMap is used, otherwise equal float[] data = new float[totalNPoints]; // Y * 10**D = R + (X1 + X2) * 2**E // E = binary scale factor // D = decimal scale factor // R = reference value // X1 = 0 // X2 = scaled encoded value // data[ i ] = (R + ( X1 + X2) * EE)/DD ; BitReader reader = new BitReader(raf, startPos + 5); if (bitmap == null) { for (int i = 0; i < totalNPoints; i++) { // data[ i ] = (R + ( X1 + X2) * EE)/DD ; data[i] = (R + reader.bits2UInt(nb) * EE) / DD; } } else { for (int i = 0; i < totalNPoints; i++) { if ((bitmap[i / 8] & GribNumbers.bitmask[i % 8]) != 0) { data[i] = (R + reader.bits2UInt(nb) * EE) / DD; } else { data[i] = staticMissingValue; // LOOK ?? // data[i] = R / DD; } } } return data; }
// Grid point data - complex packing and spatial differencing private float[] getData3(RandomAccessFile raf, Grib2Drs.Type3 gdrs) throws IOException { int mvm = gdrs.missingValueManagement; float mv = getMissingValue(gdrs); BitReader reader = new BitReader(raf, startPos + 5); int ival1 = 0; int ival2 = 0; int minsd = 0; // [6-ww] 1st values of undifferenced scaled values and minimums int os = gdrs.orderSpatial; int nbitsd = gdrs.descriptorSpatial; int sign; // ds is number of bytes, convert to bits -1 for sign bit nbitsd = nbitsd * 8; if (nbitsd > 0) { // first order spatial differencing g1 and gMin sign = (int) reader.bits2UInt(1); ival1 = (int) reader.bits2UInt(nbitsd - 1); if (sign == 1) { ival1 = -ival1; } if (os == 2) { // second order spatial differencing h1, h2, hMin sign = (int) reader.bits2UInt(1); ival2 = (int) reader.bits2UInt(nbitsd - 1); if (sign == 1) { ival2 = -ival2; } } sign = (int) reader.bits2UInt(1); minsd = (int) reader.bits2UInt(nbitsd - 1); if (sign == 1) { minsd = -minsd; } } else { float[] data = new float[totalNPoints]; for (int i = 0; i < totalNPoints; i++) data[i] = mv; return data; } int NG = gdrs.numberOfGroups; if (NG == 0) { float[] data = new float[totalNPoints]; for (int i = 0; i < totalNPoints; i++) data[i] = mv; return data; } // [ww +1]-xx Get reference values for groups (X1's) // X1 == gref int[] X1 = new int[NG]; // initialized to zero int nb = gdrs.numberOfBits; if (nb != 0) { reader.incrByte(); for (int i = 0; i < NG; i++) { X1[i] = (int) reader.bits2UInt(nb); } } // [xx +1 ]-yy Get number of bits used to encode each group // NB == gwidth int[] NB = new int[NG]; // initialized to zero nb = gdrs.bitsGroupWidths; if (nb != 0) { reader.incrByte(); for (int i = 0; i < NG; i++) { NB[i] = (int) reader.bits2UInt(nb); } } int referenceGroupWidths = gdrs.referenceGroupWidths; for (int i = 0; i < NG; i++) { NB[i] += referenceGroupWidths; } // [yy +1 ]-zz Get the scaled group lengths using formula // Ln = ref + Kn * len_inc, where n = 1-NG, // ref = referenceGroupLength, and len_inc = lengthIncrement int[] L = new int[NG]; // initialized to zero int referenceGroupLength = gdrs.referenceGroupLength; nb = gdrs.bitsScaledGroupLength; int len_inc = gdrs.lengthIncrement; if (nb != 0) { reader.incrByte(); for (int i = 0; i < NG; i++) { L[i] = (int) reader.bits2UInt(nb); } } int totalL = 0; for (int i = 0; i < NG; i++) { L[i] = L[i] * len_inc + referenceGroupLength; totalL += L[i]; } totalL -= L[NG - 1]; totalL += gdrs.lengthLastGroup; // enter Length of Last Group L[NG - 1] = gdrs.lengthLastGroup; // test if (mvm != 0) { if (totalL != totalNPoints) { log.warn("NPoints != gds.nPts: " + totalL + "!=" + totalNPoints); float[] data = new float[totalNPoints]; for (int i = 0; i < totalNPoints; i++) data[i] = mv; return data; } } else { if (totalL != dataNPoints) { log.warn("NPoints != drs.nPts: " + totalL + "!=" + totalNPoints); float[] data = new float[totalNPoints]; for (int i = 0; i < totalNPoints; i++) data[i] = mv; return data; } } int D = gdrs.decimalScaleFactor; float DD = (float) java.lang.Math.pow((double) 10, (double) D); float R = gdrs.referenceValue; int E = gdrs.binaryScaleFactor; float EE = (float) java.lang.Math.pow((double) 2.0, (double) E); float[] data = new float[totalNPoints]; // [zz +1 ]-nn get X2 values and calculate the results Y using formula // formula used to create values, Y * 10**D = R + (X1 + X2) * 2**E // Y = (R + (X1 + X2) * (2 ** E) ) / (10 ** D)] // WHERE: // Y = THE VALUE WE ARE UNPACKING // R = THE REFERENCE VALUE (FIRST ORDER MINIMA) // X1 = THE PACKED VALUE // X2 = THE SECOND ORDER MINIMA // E = THE BINARY SCALE FACTOR // D = THE DECIMAL SCALE FACTOR int count = 0; reader.incrByte(); int dataSize = 0; boolean[] dataBitMap = null; if (mvm == 0) { for (int i = 0; i < NG; i++) { if (NB[i] != 0) { for (int j = 0; j < L[i]; j++) data[count++] = (int) reader.bits2UInt(NB[i]) + X1[i]; } else { for (int j = 0; j < L[i]; j++) data[count++] = X1[i]; } } // end for i } else if (mvm == 1 || mvm == 2) { // don't add missing values into data but keep track of them in dataBitMap dataBitMap = new boolean[totalNPoints]; dataSize = 0; for (int i = 0; i < NG; i++) { if (NB[i] != 0) { int msng1 = bitsmv1[NB[i]]; int msng2 = msng1 - 1; for (int j = 0; j < L[i]; j++) { data[count] = (int) reader.bits2UInt(NB[i]); if (data[count] == msng1 || mvm == 2 && data[count] == msng2) { dataBitMap[count] = false; } else { dataBitMap[count] = true; data[dataSize++] = data[count] + X1[i]; } count++; } } else { // (NB[i] == 0 int msng1 = bitsmv1[gdrs.numberOfBits]; int msng2 = msng1 - 1; if (X1[i] == msng1) { for (int j = 0; j < L[i]; j++) dataBitMap[count++] = false; // data[count++] = X1[i]; } else if (mvm == 2 && X1[i] == msng2) { for (int j = 0; j < L[i]; j++) dataBitMap[count++] = false; } else { for (int j = 0; j < L[i]; j++) { dataBitMap[count] = true; data[dataSize++] = X1[i]; count++; } } } } // end for i } // first order spatial differencing if (os == 1) { // g1 and gMin // encoded by G(n) = F(n) - F(n -1 ) // decoded by F(n) = G(n) + F(n -1 ) // data[] at this point contains G0, G1, G2, .... data[0] = ival1; int itemp; if (mvm == 0) { // no missing values itemp = totalNPoints; } else { itemp = dataSize; } for (int i = 1; i < itemp; i++) { data[i] += minsd; data[i] = data[i] + data[i - 1]; } } else if (os == 2) { // 2nd order data[0] = ival1; data[1] = ival2; int itemp; if (mvm == 0) { // no missing values itemp = totalNPoints; } else { itemp = dataSize; } for (int i = 2; i < itemp; i++) { data[i] += minsd; data[i] = data[i] + (2 * data[i - 1]) - data[i - 2]; } } // formula used to create values, Y * 10**D = R + (X1 + X2) * 2**E // Y = (R + (X1 + X2) * (2 ** E) ) / (10 ** D)] // WHERE: // Y = THE VALUE WE ARE UNPACKING // R = THE REFERENCE VALUE (FIRST ORDER MINIMA) // X1 = THE PACKED VALUE // X2 = THE SECOND ORDER MINIMA // E = THE BINARY SCALE FACTOR // D = THE DECIMAL SCALE FACTOR if (mvm == 0) { // no missing values for (int i = 0; i < data.length; i++) { data[i] = (R + (data[i] * EE)) / DD; } } else { // missing value == 1 || missing value == 2 int count2 = 0; float[] tmp = new float[totalNPoints]; for (int i = 0; i < data.length; i++) { if (dataBitMap[i]) { tmp[i] = (R + (data[count2++] * EE)) / DD; } else { // mvm = 1 or 2 tmp[i] = mv; } } data = tmp; } // bit map is used if (bitmap != null) { int idx = 0; float[] tmp = new float[totalNPoints]; for (int i = 0; i < totalNPoints; i++) { if ((bitmap[i / 8] & GribNumbers.bitmask[i % 8]) != 0) { tmp[i] = data[idx++]; } else { tmp[i] = mv; } } data = tmp; } return data; }
// Grid point data - complex packing private float[] getData2(RandomAccessFile raf, Grib2Drs.Type2 gdrs) throws IOException { int mvm = gdrs.missingValueManagement; float mv = getMissingValue(gdrs); int NG = gdrs.numberOfGroups; if (NG == 0) { float[] data = new float[totalNPoints]; for (int i = 0; i < totalNPoints; i++) data[i] = mv; return data; } BitReader reader = new BitReader(raf, startPos + 5); // 6-xx Get reference values for groups (X1's) int[] X1 = new int[NG]; int nb = gdrs.numberOfBits; if (nb != 0) { for (int i = 0; i < NG; i++) X1[i] = (int) reader.bits2UInt(nb); } // [xx +1 ]-yy Get number of bits used to encode each group int[] NB = new int[NG]; nb = gdrs.bitsGroupWidths; if (nb != 0) { reader.incrByte(); for (int i = 0; i < NG; i++) NB[i] = (int) reader.bits2UInt(nb); } // [yy +1 ]-zz Get the scaled group lengths using formula // Ln = ref + Kn * len_inc, where n = 1-NG, // ref = referenceGroupLength, and len_inc = lengthIncrement int[] L = new int[NG]; int ref = gdrs.referenceGroupLength; int len_inc = gdrs.lengthIncrement; nb = gdrs.bitsScaledGroupLength; reader.incrByte(); for (int i = 0; i < NG; i++) L[i] = ref + (int) reader.bits2UInt(nb) * len_inc; L[NG - 1] = gdrs.lengthLastGroup; // enter Length of Last Group int D = gdrs.decimalScaleFactor; float DD = (float) java.lang.Math.pow((double) 10, (double) D); float R = gdrs.referenceValue; int E = gdrs.binaryScaleFactor; float EE = (float) java.lang.Math.pow((double) 2.0, (double) E); float[] data = new float[totalNPoints]; // [zz +1 ]-nn get X2 values and calculate the results Y using formula // Y = R + [(X1 + X2) * (2 ** E) * (10 ** D)] // WHERE: // Y = THE VALUE WE ARE UNPACKING // R = THE REFERENCE VALUE (FIRST ORDER MINIMA) // X1 = THE PACKED VALUE // X2 = THE SECOND ORDER MINIMA // E = THE BINARY SCALE FACTOR // D = THE DECIMAL SCALE FACTOR int count = 0; reader.incrByte(); for (int i = 0; i < NG; i++) { for (int j = 0; j < L[i]; j++) { if (NB[i] == 0) { if (mvm == 0) { // X2 = 0 data[count++] = (R + X1[i] * EE) / DD; } else { // if (mvm == 1) || (mvm == 2 ) data[count++] = mv; } } else { int X2 = (int) reader.bits2UInt(NB[i]); if (mvm == 0) { data[count++] = (R + (X1[i] + X2) * EE) / DD; } else { // if (mvm == 1) || (mvm == 2 ) // X2 is also set to missing value if all bits set to 1's if (X2 == bitsmv1[NB[i]]) { data[count++] = mv; } else { data[count++] = (R + (X1[i] + X2) * EE) / DD; } } } } // end for j } // end for i if (bitmap != null) { int idx = 0; float[] tmp = new float[totalNPoints]; for (int i = 0; i < totalNPoints; i++) { if ((bitmap[i / 8] & GribNumbers.bitmask[i % 8]) != 0) { tmp[i] = data[idx++]; } else { tmp[i] = mv; } } data = tmp; } return data; }