forked from gsn/predictor
56 lines
987 B
Go
56 lines
987 B
Go
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, dc *DatasetConfig) (*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
|
|
}
|
|
|
|
return &cube{
|
|
mm: mm,
|
|
t: dc.NT,
|
|
p: dc.NP,
|
|
lat: dc.NLat,
|
|
lon: dc.NLon,
|
|
bytesPerVar: dc.SizePerVar(),
|
|
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
|
|
}
|