Created
June 27, 2011 18:40
-
-
Save zentrope/1049471 to your computer and use it in GitHub Desktop.
Fragment: decoding weather strings in a weather.gov grib2 file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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