nilsmagnus / grib

Golang GRIB2 parser
Other
57 stars 19 forks source link
forecasts go golang grib grib2 library meteorological-data meteorology weather

Build

GRIB2 Golang parser application and library

Parser and library for the grib2 file format for meteorological data representations.

For a full presentation of the library, see https://github.com/nilsmagnus/what-is-griblib

Usage

Install by typing

go get -u github.com/nilsmagnus/grib

Library Usage:

Have a look at 'main.go' for main usage:

gribfile, err := os.Open("somegrib2file.grib2")
if err != nil {
    log.Fatalf("Could not open test-file %v", err)
}
messages, err := griblib.ReadMessages(gribfile)

for _, message := range messages {
    // do your thing
}

Read first n messages in a grib-file:

gribfile, err := os.Open("somegrib2file.grib2")
if err != nil { log.Fatalf("Could not open test-file %v", err) }
messages, err := griblib.ReadNMessages(gribfile, 2)

for _, message := range messages {
    // do your thing with the n first messages
}

Application Usage:

$ grib -h 

Usage of grib:
 -category int
    Filters on Category within discipline. -1 means all categories (default -1)
 -dataExport
    Export data values. (default true)
 -discipline int
    Filters on Discipline. -1 means all disciplines (default -1)
 -export int
    Export format. Valid types are 0 (none) 1(print discipline names) 2(print categories) 3(json) 
 -file string
    Grib filepath
 -latMax int
    Maximum latitude multiplied with 100000. (default 36000000)
 -latMin int
    Minimum latitude multiplied with 100000.
 -longMax int
    Maximum longitude multiplied with 100000. (default 9000000)
 -longMin int
    Minimum longitude multiplied with 100000. (default -9000000)
 -maxmsg int
    Maximum number of messages to parse. Does not work in combination with filters. (default 2147483647)
 -operation string
    Operation. Valid values: 'parse', 'reduce'. (default "parse")
 -reducefile string
    Destination for reduced file. (default "reduced.grib2")

Examples:

Reduce input file to default output-file with discipline 0 (Meteorology):

grib -operation reduce -file testdata/reduced.grib2 -discipline 0

Filter on area on size of norway+sweden, output to json:

grib -file testdata/gfs.t00z.pgrb2.2p50.f003  -latMin 57000000 -latMax 71000000 -longMin 4400000 -longMax 32000000 -export 3

Filter on temperature only:

grib -file testdata/gfs.t00z.pgrb2.2p50.f003 -discipline 0 -category 0 

What works?

Development

Dependencies

grib itself has no dependencies and wants to stay that way to keep it simple. Therefore, there is no dep/glide and no dependency-configuration-files.

Build

Grib uses make to build. You probably need go-lint installed in order to build.

To build, simply type

$ make

to test:

$ make test

TODOs

Contributors

Help appreciated

Feel free to fork and submit pull requests or simply create issues for improvements :)

Performance

to run a performance-test go to griblib/gribtest and run make benchmark.

CPU

Sample output:

go version go1.11.2 linux/amd64
go test -bench=. -benchmem -memprofile memprofile.out -cpuprofile profile.out
category number 0,parameter number 0,surface type 1, surface value 0 max: 329.500000 min: 197.900000
goos: linux
goarch: amd64
pkg: github.com/nilsmagnus/grib/griblib/gribtest
BenchmarkReadMessages-4          100      11681028 ns/op     6587281 B/op       9344 allocs/op
PASS
ok      github.com/nilsmagnus/grib/griblib/gribtest 5.456s
go tool pprof -top profile.out
File: gribtest.test
Type: cpu
Time: Feb 9, 2019 at 6:44pm (CET)
Duration: 5.41s, Total samples = 5.34s (98.77%)
Showing nodes accounting for 5.12s, 95.88% of 5.34s total
Dropped 69 nodes (cum <= 0.03s)
      flat  flat%   sum%        cum   cum%
     1.58s 29.59% 29.59%      1.78s 33.33%  github.com/nilsmagnus/grib/griblib.(*BitReader).readBit
     1.07s 20.04% 49.63%      2.85s 53.37%  github.com/nilsmagnus/grib/griblib.(*BitReader).readUint
     0.53s  9.93% 59.55%      0.53s  9.93%  runtime.memclrNoHeapPointers
     0.36s  6.74% 66.29%      0.85s 15.92%  encoding/binary.(*decoder).value
     0.15s  2.81% 69.10%      2.78s 52.06%  github.com/nilsmagnus/grib/griblib.(*BitReader).readIntsBlock
     0.15s  2.81% 71.91%      0.15s  2.81%  github.com/nilsmagnus/grib/griblib.(*Data3).applySpacialDifferencing
     0.14s  2.62% 74.53%      0.26s  4.87%  reflect.Value.Index
     0.13s  2.43% 76.97%      0.20s  3.75%  bytes.(*Buffer).ReadByte
     0.11s  2.06% 79.03%      0.28s  5.24%  github.com/nilsmagnus/grib/griblib.(*Data2).scaleValues
     0.11s  2.06% 81.09%      0.19s  3.56%  reflect.Value.SetUint
     0.08s  1.50% 82.58%      0.08s  1.50%  github.com/nilsmagnus/grib/griblib.Data0.scaleFunc.func1
     0.08s  1.50% 84.08%      0.08s  1.50%  reflect.(*rtype).Kind (inline)
     0.07s  1.31% 85.39%      0.07s  1.31%  bytes.(*Buffer).empty (inline)
     0.06s  1.12% 86.52%      0.68s 12.73%  runtime.mallocgc
     0.06s  1.12% 87.64%      0.06s  1.12%  runtime.memmove
     0.05s  0.94% 88.58%      0.05s  0.94%  reflect.flag.mustBeAssignable
     0.05s  0.94% 89.51%      0.05s  0.94%  runtime.nextFreeFast (inline)
     0.04s  0.75% 90.26%      0.04s  0.75%  encoding/binary.(*decoder).uint8 (inline)

Memory

go tool pprof -top memprofile.out
File: gribtest.test
Type: alloc_space
Time: Feb 12, 2019 at 8:19pm (CET)
Showing nodes accounting for 3.39GB, 99.31% of 3.41GB total
Dropped 43 nodes (cum <= 0.02GB)
      flat  flat%   sum%        cum   cum%
    1.52GB 44.71% 44.71%     2.05GB 60.09%  github.com/nilsmagnus/grib/griblib.(*Data2).extractData
    0.76GB 22.19% 66.90%     0.76GB 22.19%  github.com/nilsmagnus/grib/griblib.(*Data2).scaleValues
    0.48GB 14.09% 80.99%     0.48GB 14.09%  github.com/nilsmagnus/grib/griblib.(*BitReader).readIntsBlock
    0.26GB  7.68% 88.67%     0.34GB 10.01%  github.com/nilsmagnus/grib/griblib.(*Data2).extractBitGroupParameters
    0.08GB  2.38% 91.05%     0.08GB  2.38%  github.com/nilsmagnus/grib/griblib.(*BitReader).readUintsBlock
    0.06GB  1.90% 92.95%     3.34GB 97.93%  github.com/nilsmagnus/grib/griblib.readMessage
    0.06GB  1.76% 94.70%     0.06GB  1.77%  encoding/binary.Read
    0.06GB  1.70% 96.40%     3.40GB 99.64%  github.com/nilsmagnus/grib/griblib.ReadMessage
    0.06GB  1.62% 98.02%     0.06GB  1.62%  github.com/nilsmagnus/grib/griblib.makeBitReader
    0.04GB  1.29% 99.31%     0.04GB  1.29%  github.com/nilsmagnus/grib/griblib.(*bitGroupParameter).zeroGroup (inline)

Grib Documentation

Grib specification:

https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/

Documentation from noaa.gov :

http://www.nco.ncep.noaa.gov/pmb/docs/on388/

Daily grib2 files from NOAA can be found at

http://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/