private GRIB_Point[] SimpleUnpacking(FileStream fs, IGRIB2GridDefinitionSection gds, IGRIB2DataRepresentationSection drs, IGribBitMapSection bms) { // dataPoints are number of points encoded, it could be less than the // numberPoints in the grid record if bitMap is used, otherwise equal _bitPos = 0; _bitBuf = 0; int dataPoints = drs.DataPoints; float pmv = drs.PrimaryMissingValue; int nb = drs.NumberOfBits; int D = drs.DecimalScaleFactor; float DD = (float)System.Math.Pow((double)10, (double)D); float R = drs.ReferenceValue; int E = drs.BinaryScaleFactor; float EE = (float)System.Math.Pow((double)2.0, (double)E); int numberPoints = gds.PointsNumber; GRIB_Point[] data = new GRIB_Point[numberPoints]; bool[] bitmap = bms.Bitmap; // 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 ; if (bitmap == null) { for (int i = 0; i < numberPoints; i++) { data[i].Index = i; data[i].Value = (R + Bits2UInt(nb, fs) * EE) / DD; } } else { for (int i = 0; i < bitmap.Length; i++) { data[i].Index = i; if (bitmap[i]) { //data[ i ] = (R + ( X1 + X2) * EE)/DD ; data[i].Value = (R + Bits2UInt(nb, fs) * EE) / DD; } else { data[i].Value = pmv; } } } return(data); }
public void StatMinMax(GRIB_Point[] pts, out GRIB_Point minPoint, out GRIB_Point maxPoint) { throw new NotImplementedException(); }
private GRIB_Point[] ComplexUnpackingWithSpatial(FileStream fs, IGRIB2GridDefinitionSection gds, IGRIB2DataRepresentationSection drs) { int mvm = drs.MissingValueManagement; float pmv = drs.PrimaryMissingValue; int NG = drs.NumberOfGroups; int g1 = 0, gMin = 0, h1 = 0, h2 = 0, hMin = 0; // [6-ww] 1st values of undifferenced scaled values and minimums int os = drs.OrderSpatial; int ds = drs.DescriptorSpatial; _bitPos = 0; _bitBuf = 0; int sign; // ds is number of bytes, convert to bits -1 for sign bit ds = ds * 8 - 1; if (os == 1) { // first order spatial differencing g1 and gMin sign = Bits2UInt(1, fs); g1 = Bits2UInt(ds, fs); if (sign == 1) { g1 *= (-1); } sign = Bits2UInt(1, fs); gMin = Bits2UInt(ds, fs); if (sign == 1) { gMin *= (-1); } } else if (os == 2) { //second order spatial differencing h1, h2, hMin sign = Bits2UInt(1, fs); h1 = Bits2UInt(ds, fs); if (sign == 1) { h1 *= (-1); } sign = Bits2UInt(1, fs); h2 = Bits2UInt(ds, fs); if (sign == 1) { h2 *= (-1); } sign = Bits2UInt(1, fs); hMin = Bits2UInt(ds, fs); if (sign == 1) { hMin *= (-1); } } else { return(null); } // [ww +1]-xx Get reference values for groups (X1's) int[] X1 = new int[NG]; int nb = drs.NumberOfBits; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG; i++) { X1[i] = Bits2UInt(nb, fs); } // [xx +1 ]-yy Get number of bits used to encode each group int[] NB = new int[NG]; nb = drs.BitsGroupWidths; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG; i++) { NB[i] = Bits2UInt(nb, fs); } // [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 countL = 0; int ref_Renamed = drs.ReferenceGroupLength; int len_inc = drs.LengthIncrement; nb = drs.BitsScaledGroupLength; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG; i++) { // NG L[i] = ref_Renamed + (Bits2UInt(nb, fs) * len_inc); countL += L[i]; } // [zz +1 ]-nn get X2 values and add X1[ i ] + X2 GRIB_Point[] data = new GRIB_Point[countL]; // used to check missing values when X2 is packed with all 1's int[] bitsmv1 = new int[31]; for (int i = 0; i < 31; i++) { bitsmv1[i] = (int)System.Math.Pow((double)2, (double)i) - 1; } int count = 0; int X2; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG - 1; i++) { for (int j = 0; j < L[i]; j++) { data[count].Index = count; if (NB[i] == 0) { if (mvm == 0) { // X2 = 0 data[count++].Value = X1[i]; } else if (mvm == 1) { data[count++].Value = pmv; } } else { X2 = Bits2UInt(NB[i], fs); if (mvm == 0) { data[count++].Value = X1[i] + X2; } else if (mvm == 1) { // X2 is also set to missing value is all bits set to 1's if (X2 == bitsmv1[NB[i]]) { data[count++].Value = pmv; } else { data[count++].Value = X1[i] + X2; } } } } } // process last group int last = drs.LengthLastGroup; for (int j = 0; j < last; j++) { data[count].Index = count; // last group if (NB[NG - 1] == 0) { if (mvm == 0) { // X2 = 0 data[count++].Value = X1[NG - 1]; } else if (mvm == 1) { data[count++].Value = pmv; } } else { X2 = Bits2UInt(NB[NG - 1], fs); if (mvm == 0) { data[count++].Value = X1[NG - 1] + X2; } else if (mvm == 1) { // X2 is also set to missing value is all bits set to 1's if (X2 == bitsmv1[NB[NG - 1]]) { data[count++].Value = pmv; } else { data[count++].Value = X1[NG - 1] + X2; } } } } if (os == 1) { // g1 and gMin this coding is a sort of guess, no doc float sum = 0; if (mvm == 0) { // no missing values for (int i = 1; i < data.Length; i++) { data[i].Value += gMin; // add minimum back } data[0].Value = g1; for (int i = 1; i < data.Length; i++) { sum += data[i].Value; data[i].Value = data[i - 1].Value + sum; } } else { // contains missing values float lastOne = pmv; // add the minimum back and set g1 int idx = 0; for (int i = 0; i < data.Length; i++) { if (data[i].Value != pmv) { if (idx == 0) { // set g1 data[i].Value = g1; lastOne = data[i].Value; idx = i + 1; } else { data[i].Value += gMin; } } } if (lastOne == pmv) { return(data); } for (int i = idx; i < data.Length; i++) { if (data[i].Value != pmv) { sum += data[i].Value; data[i].Value = lastOne + sum; lastOne = data[i].Value; } } } } else if (os == 2) { //h1, h2, hMin float hDiff = h2 - h1; float sum = 0; if (mvm == 0) { // no missing values for (int i = 2; i < data.Length; i++) { data[i].Value += hMin; // add minimum back } data[0].Value = h1; data[1].Value = h2; sum = hDiff; for (int i = 2; i < data.Length; i++) { sum += data[i].Value; data[i].Value = data[i - 1].Value + sum; } } else { // contains missing values int idx = 0; float lastOne = pmv; // add the minimum back and set h1 and h2 for (int i = 0; i < data.Length; i++) { if (data[i].Value != pmv) { if (idx == 0) { // set h1 data[i].Value = h1; sum = 0; lastOne = data[i].Value; idx++; } else if (idx == 1) { // set h2 data[i].Value = h1 + hDiff; sum = hDiff; lastOne = data[i].Value; idx = i + 1; } else { data[i].Value += hMin; } } } if (lastOne == pmv) { return(data); } for (int i = idx; i < data.Length; i++) { if (data[i].Value != pmv) { sum += data[i].Value; data[i].Value = lastOne + sum; lastOne = data[i].Value; } } } } // end h1, h2, hMin // formula used to create values, Y * 10**D = R + (X1 + X2) * 2**E int D = drs.DecimalScaleFactor; float DD = (float)System.Math.Pow((double)10, (double)D); float R = drs.ReferenceValue; int E = drs.BinaryScaleFactor; float EE = (float)System.Math.Pow((double)2.0, (double)E); if (mvm == 0) { // no missing values for (int i = 0; i < data.Length; i++) { data[i].Value = (R + data[i].Value * EE) / DD; } } else { // missing value == 1 for (int i = 0; i < data.Length; i++) { if (data[i].Value != pmv) { data[i].Value = (R + data[i].Value * EE) / DD; } } } ScanningModeCheck(data, gds.ScanMode, gds.Nx); return(data); }
private GRIB_Point[] ComplexUnpacking(FileStream fs, IGRIB2GridDefinitionSection gds, IGRIB2DataRepresentationSection drs) { int mvm = drs.MissingValueManagement; float pmv = drs.PrimaryMissingValue; int NG = drs.NumberOfGroups; // 6-xx Get reference values for groups (X1's) int[] X1 = new int[NG]; int nb = drs.NumberOfBits; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG; i++) { X1[i] = Bits2UInt(nb, fs); } // [xx +1 ]-yy Get number of bits used to encode each group int[] NB = new int[NG]; nb = drs.BitsGroupWidths; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG; i++) { NB[i] = Bits2UInt(nb, fs); } // [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 countL = 0; int ref_Renamed = drs.ReferenceGroupLength; int len_inc = drs.LengthIncrement; nb = drs.BitsScaledGroupLength; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG; i++) { // NG L[i] = ref_Renamed + (Bits2UInt(nb, fs) * len_inc); countL += L[i]; } // [zz +1 ]-nn get X2 values and calculate the results Y using formula // Y * 10**D = R + (X1 + X2) * 2**E int D = drs.DecimalScaleFactor; float DD = (float)System.Math.Pow((double)10, (double)D); float R = drs.ReferenceValue; int E = drs.BinaryScaleFactor; float EE = (float)System.Math.Pow((double)2.0, (double)E); GRIB_Point[] data = new GRIB_Point[countL]; int count = 0; int[] bitsmv1 = new int[31]; for (int i = 0; i < 31; i++) { bitsmv1[i] = (int)System.Math.Pow((double)2, (double)i) - 1; } int X2; _bitPos = 0; _bitBuf = 0; for (int i = 0; i < NG - 1; i++) { for (int j = 0; j < L[i]; j++) { data[count].Index = count; if (NB[i] == 0) { if (mvm == 0) { // X2 = 0 data[count++].Value = (R + X1[i] * EE) / DD; } else if (mvm == 1) { data[count++].Value = pmv; } } else { X2 = Bits2UInt(NB[i], fs); if (mvm == 0) { data[count++].Value = (R + (X1[i] + X2) * EE) / DD; } else if (mvm == 1) { // X2 is also set to missing value is all bits set to 1's if (X2 == bitsmv1[NB[i]]) { data[count++].Value = pmv; } else { data[count++].Value = (R + (X1[i] + X2) * EE) / DD; } } } } } // process last group int last = drs.LengthLastGroup; for (int j = 0; j < last; j++) { data[count].Index = count; // last group if (NB[NG - 1] == 0) { if (mvm == 0) { // X2 = 0 data[count++].Value = (R + X1[NG - 1] * EE) / DD; } else if (mvm == 1) { data[count++].Value = pmv; } } else { X2 = Bits2UInt(NB[NG - 1], fs); if (mvm == 0) { data[count++].Value = (R + (X1[NG - 1] + X2) * EE) / DD; } else if (mvm == 1) { // X2 is also set to missing value is all bits set to 1's if (X2 == bitsmv1[NB[NG - 1]]) { data[count++].Value = pmv; } else { data[count++].Value = (R + (X1[NG - 1] + X2) * EE) / DD; } } } } // end for j ScanningModeCheck(data, gds.ScanMode, gds.Nx); return(data); }
public GRIB_Point[] Read() { try { if (_fs != null) { IGribBitMapSection bms = null; GRIB_Point[] points = null; bool isConstant = false; _fs.Seek(_dataOffset, SeekOrigin.Begin); if (_isBmsExist) { bms = new Grib1BitMapSection(_fs); } // octets 1-3 (section _length) int dataLength = GribNumberHelper.Uint3(_fs); // octet 4, 1st half (packing flag) int unusedbits = _fs.ReadByte(); if ((unusedbits & 192) != 0) { throw new NotSupportedException("BDS: (octet 4, 1st half) not grid point data and simple packing "); } // octet 4, 2nd half (number of unused bits at end of this section) unusedbits = unusedbits & 15; // octets 5-6 (binary scale factor) int binscale = GribNumberHelper.Int2(_fs); // octets 7-10 (reference point = minimum value) float refvalue = GribNumberHelper.Float4(_fs); // octet 11 (number of bits per value) int numbits = _fs.ReadByte(); if (numbits == 0) { isConstant = true; } float refRenamed = (float)(Math.Pow(10.0, -_decscale) * refvalue); float scale = (float)(System.Math.Pow(10.0, -_decscale) * System.Math.Pow(2.0, binscale)); if (_firstlat == 0 & _lastlat == 90) { if (bms != null) { bool[] bitmap = bms.Bitmap; points = new GRIB_Point[bitmap.Length]; for (int i = 0; i < bitmap.Length; i++) { int m = (_height - (int)(i / _width) - 1) * _width + (i % _width); if (bitmap[i]) { if (!isConstant) { points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } else { // rdg - added this to handle a constant valued parameter points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed; } } else { points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = -9999f; } } } else { if (!isConstant) { points = new GRIB_Point[((dataLength - 11) * 8 - unusedbits) / numbits]; for (int i = 0; i < points.Length; i++) { int m = (_height - (int)(i / _width) - 1) * _width + (i % _width); points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } } else { // constant valued - same min and max int x = 0, y = 0; _fs.Seek(_fs.Position - 53, SeekOrigin.Begin); // return to start of GDS dataLength = (int)GribNumberHelper.Uint3(_fs); if (dataLength == 42) { // Lambert/Mercator offset _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { _fs.Seek(7, SeekOrigin.Current); dataLength = GribNumberHelper.Uint3(_fs); if (dataLength == 32) { // Polar sterographic _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { x = y = 1; } } points = new GRIB_Point[x * y]; for (int i = 0; i < points.Length; i++) { int m = (_height - (int)(i / _width) - 1) * _width + (i % _width); points[m] = new GRIB_Point(); points[m].Index = i; points[m].Value = refRenamed; } } } } else { if (bms != null) { bool[] bitmap = bms.Bitmap; points = new GRIB_Point[bitmap.Length]; for (int i = 0; i < bitmap.Length; i++) { if (bitmap[i]) { if (!isConstant) { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } else { // rdg - added this to handle a constant valued parameter points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed; } } else { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = -9999f; } } } else { if (!isConstant) { points = new GRIB_Point[((dataLength - 11) * 8 - unusedbits) / numbits]; for (int i = 0; i < points.Length; i++) { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed + scale * Bits2UInt(numbits, _fs); } } else { // constant valued - same min and max int x = 0, y = 0; _fs.Seek(_fs.Position - 53, SeekOrigin.Begin); // return to start of GDS dataLength = (int)GribNumberHelper.Uint3(_fs); if (dataLength == 42) { // Lambert/Mercator offset _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { _fs.Seek(7, SeekOrigin.Current); dataLength = GribNumberHelper.Uint3(_fs); if (dataLength == 32) { // Polar sterographic _fs.Seek(3, SeekOrigin.Current); x = GribNumberHelper.Int2(_fs); y = GribNumberHelper.Int2(_fs); } else { x = y = 1; } } points = new GRIB_Point[x * y]; for (int i = 0; i < points.Length; i++) { points[i] = new GRIB_Point(); points[i].Index = i; points[i].Value = refRenamed; } } } } return(points); } return(null); } finally { _fs.Seek(0, SeekOrigin.Begin); } }