Skip to content

Instantly share code, notes, and snippets.

@zentrope
Created June 27, 2011 18:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zentrope/1049471 to your computer and use it in GitHub Desktop.
Save zentrope/1049471 to your computer and use it in GitHub Desktop.
Fragment: decoding weather strings in a weather.gov grib2 file
// convert a byte into a list of ones and zeros
def bits(num: Int): List[Int] = (for (i <- Range(0,8)) yield (((num << i) & 0xff) >>> 7)).toList
// given a list, take the first N bits
def next(bits: List[Int], numBits: Int) = {
val filler = List[Int](8 - numBits) map (_ => 0)
val bitList = filler ++ bits.take(numBits)
def convert (accumulator: Int, val_pos: Tuple2[Int, Int]) =
accumulator + (val_pos._1 << val_pos._2)
bitList.reverse.zipWithIndex.foldLeft(0) { convert }
}
def localStrings(len: Int, data: DataInputStream): List[String] = {
// Works for the NDFD data files as I've found them, but doesn't
// account for more than one group of data (say), or bits that
// might be stored as floating point numbers.
val numGroups = readInteger(2, data)
val numValues = readInteger(4, data)
val refValue = data.readFloat()
val scale = readInteger(2, data)
val recScale10 = 1 / math.pow(10, scale)
val numBits = data.readUnsignedByte()
val dataType = data.readUnsignedByte()
// TODO: This really needs to be "streamed" in some
// way so we don't have to keep such a massive list
// in memory. Okay for local WX strings, but is
// unusable on huge CONUS data sets.
// Convert the data into a list of ones and zeros
var packed: List[Int] = List()
for (i <- 1 to (len - 14))
packed = packed ++ bits(data.readUnsignedByte)
// Expand the packed bit list into bytes
var unpacked: List[Char] = List()
for (i <- 1 to numValues) {
unpacked = unpacked ++ List(((refValue + next(packed, numBits)) * recScale10).toChar)
packed = packed.drop(numBits)
}
// Convert the zero-delimited strings into a list of strings
unpacked.mkString.split(0.toChar.toString).toList
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment