package grib import ( "encoding/binary" "math" "os" mmap "github.com/edsrzf/mmap-go" ) type cube struct { mm mmap.MMap t, p, lat, lon int bytesPerVar int64 file *os.File } func openCube(path string) (*cube, error) { f, err := os.Open(path) if err != nil { return nil, err } mm, err := mmap.Map(f, mmap.RDONLY, 0) if err != nil { f.Close() return nil, err } const ( nT = 33 // 0-96 hours with step 3 hours (33 time steps) nP = 47 // 47 pressure levels matching tawhiri nLat = 361 nLon = 720 ) return &cube{mm: mm, t: nT, p: nP, lat: nLat, lon: nLon, bytesPerVar: int64(nT * nP * nLat * nLon * 4), file: f}, nil } func (c *cube) val(varIdx, ti, pi, y, x int) float32 { idx := (((ti*c.p+pi)*c.lat + y) * c.lon) + x off := int64(varIdx)*c.bytesPerVar + int64(idx)*4 bits := binary.LittleEndian.Uint32(c.mm[off : off+4]) return math.Float32frombits(bits) } func (c *cube) Close() error { if c.mm != nil { c.mm.Unmap() } if c.file != nil { return c.file.Close() } return nil }