Documentation
¶
Index ¶
- Constants
- Variables
- func CheckAtmosConversion(at AtmosByPoint, soa AtmosByPointSOA) error
- func CheckMETARSOA(soa METARSOA, orig []METAR) error
- func FetchRadarImage(center math.Point2LL, radius float32, resolution int) (image.Image, math.Extent2D, error)
- func FullDataDays(metar, precip, atmos []time.Time) []util.TimeInterval
- func IdFromLevelIndex(i int) string
- func LevelIndexFromId(b []byte) int
- func PressureFromLevelIndex(i int) float32
- func RadarImageToDBZ(img image.Image) []byte
- type AtmosByPoint
- type AtmosByPointSOA
- type AtmosByTime
- type AtmosByTimeSOA
- type AtmosGrid
- type AtmosLevelsSOA
- type AtmosResult
- type AtmosSample
- type AtmosSampleStack
- type METAR
- func DecodeMETARSOA(soa METARSOA) []METAR
- func METARForTime(metar []METAR, t time.Time) METAR
- func SampleMETAR(metar []METAR, intervals []util.TimeInterval, avgHdg float32) *METAR
- func SampleMETARWithSpec(metar []METAR, intervals []util.TimeInterval, spec *WindSpecifier, ...) *METAR
- func SampleMatchingMETAR(metar []METAR, intervals []util.TimeInterval, match func(METAR) bool) *METAR
- type METARSOA
- type Model
- type Precip
- type Provider
- type Sample
- type WindSample
- type WindSpecifier
Constants ¶
const NumSampleLevels = 40
This is fairly specialized to our needs we ingest from: at each lat-long, we store a vertical stack of 40 levels with samples from the source HRRR files (wind direction, speed, temperature, dewpoint, height). The vertical indexing of is low to high where LevelIndexFromId and IdFromLevelIndex perform the indexing and its inverse.
Variables ¶
var AtmosTRACONs = []string{
"A80", "A90", "AAC", "ABE", "ABQ", "AGS", "ALB", "ASE", "AUS", "AVL", "BGR",
"BHM", "BIL", "BNA", "BOI", "BTV", "BUF", "C90", "CHS", "CID", "CLE", "CLT", "COS",
"CPR", "D01", "D10", "D21", "DAB", "EWR", "F11", "GSO", "GSP", "GTF", "I90", "IND",
"JAX", "L30", "M98", "MCI", "MDT", "MIA", "MKE", "N90", "NCT", "OKC", "P31", "P50",
"P80", "PCT", "PHL", "PIT", "PVD", "PWM", "R90", "RDU", "S46", "S56", "SAV", "SBA",
"SBN", "SCT", "SDF", "SGF", "SYR", "TPA", "Y90",
}
NOTE: PANC (A11) is not included: we only process the conus dataset for now and giving that -small_grib with the PANC lat-longs generates a ~1.4GB grib file, for reasons unknown.
vice -listscenarios 2>/dev/null | cut -d / -f 1 | grep -v A11 | uniq
Functions ¶
func CheckAtmosConversion ¶ added in v0.13.0
func CheckAtmosConversion(at AtmosByPoint, soa AtmosByPointSOA) error
func CheckMETARSOA ¶ added in v0.13.0
func FetchRadarImage ¶
func FullDataDays ¶ added in v0.13.0
func FullDataDays(metar, precip, atmos []time.Time) []util.TimeInterval
func IdFromLevelIndex ¶ added in v0.13.0
func LevelIndexFromId ¶ added in v0.13.0
func PressureFromLevelIndex ¶ added in v0.13.0
PressureFromLevelIndex returns pressure in millibars at the level.
func RadarImageToDBZ ¶
Types ¶
type AtmosByPoint ¶ added in v0.13.0
type AtmosByPoint struct {
// Lat-longs to stack of levels
SampleStacks map[math.Point2LL]*AtmosSampleStack
}
func MakeAtmosByPoint ¶ added in v0.13.0
func MakeAtmosByPoint() AtmosByPoint
func (*AtmosByPoint) Average ¶ added in v0.13.0
func (ap *AtmosByPoint) Average() (math.Point2LL, *AtmosSampleStack)
Average returns the averaged location and atmospheric data across all sample stacks
func (AtmosByPoint) GetGrid ¶ added in v0.13.0
func (ap AtmosByPoint) GetGrid() *AtmosGrid
func (AtmosByPoint) ToSOA ¶ added in v0.13.0
func (ap AtmosByPoint) ToSOA() (AtmosByPointSOA, error)
type AtmosByPointSOA ¶ added in v0.13.0
type AtmosByPointSOA struct {
Lat, Long []float32
Levels [NumSampleLevels]AtmosLevelsSOA
}
For storage, this information is encoded in structure-of-arrays format, which makes it more compressible.
func (AtmosByPointSOA) ToAOS ¶ added in v0.13.0
func (atsoa AtmosByPointSOA) ToAOS() AtmosByPoint
type AtmosByTime ¶ added in v0.13.0
type AtmosByTime struct {
SampleStacks map[time.Time]*AtmosSampleStack
}
func (AtmosByTime) ToSOA ¶ added in v0.13.0
func (at AtmosByTime) ToSOA() (AtmosByTimeSOA, error)
type AtmosByTimeSOA ¶ added in v0.13.0
type AtmosByTimeSOA struct {
Times []int64 // Delta-encoded Unix timestamps
Levels [NumSampleLevels]AtmosLevelsSOA
}
AtmosByTimeSOA stores atmospheric data for multiple time points at a single location (used for offline weather packaging)
func (AtmosByTimeSOA) ToAOS ¶ added in v0.13.0
func (atsoa AtmosByTimeSOA) ToAOS() AtmosByTime
type AtmosGrid ¶ added in v0.13.0
func MakeAtmosGrid ¶ added in v0.13.0
func MakeAtmosGrid(sampleStacks map[math.Point2LL]*AtmosSampleStack) *AtmosGrid
func (*AtmosGrid) AltitudeForIndex ¶ added in v0.13.0
type AtmosLevelsSOA ¶ added in v0.13.0
type AtmosResult ¶ added in v0.13.0
type AtmosSample ¶ added in v0.13.0
type AtmosSample struct {
UComponent float32 // eastward velocity m/s
VComponent float32 // northward velocity m/s
Temperature float32 // Kelvin
Dewpoint float32 // Kelvin
Height float32 // geopotential height (meters)
}
AtmosSample stores wind as velocity vectors (direction the air mass is moving). UComponent is the eastward wind velocity in m/s (positive = moving east). VComponent is the northward wind velocity in m/s (positive = moving north). These match the standard GRIB2 UGRD/VGRD convention.
type AtmosSampleStack ¶ added in v0.13.0
type AtmosSampleStack struct {
Levels [NumSampleLevels]AtmosSample
}
type METAR ¶
type METAR struct {
ICAO string `json:"icaoId"`
Time time.Time
Temperature float32 `json:"temp"`
Dewpoint float32 `json:"dewp"`
Altimeter float32 `json:"altim"`
WindDir *int `json:"-"` // nil for variable winds, otherwise heading 0-360
WindSpeed int `json:"wspd"`
WindGust *int `json:"wgst"`
Raw string `json:"rawOb"`
// WindDirRaw and ReportTime are used for JSON unmarshaling only
WindDirRaw any `json:"wdir"` // nil or string "VRB" for variable, else number for heading
ReportTime string `json:"reportTime"`
}
This is as much of the METAR as we need at runtime.
func DecodeMETARSOA ¶ added in v0.13.0
func SampleMETAR ¶ added in v0.13.0
func SampleMETAR(metar []METAR, intervals []util.TimeInterval, avgHdg float32) *METAR
Given an average headings (e.g. runway directions) and a slice of valid time intervals, randomly sample a METAR entry with wind that is compatible with the headings.
func SampleMETARWithSpec ¶ added in v0.13.0
func SampleMETARWithSpec(metar []METAR, intervals []util.TimeInterval, spec *WindSpecifier, magVar float32) *METAR
SampleMETARWithSpec randomly samples a METAR that matches the wind specifier
func SampleMatchingMETAR ¶ added in v0.13.0
func SampleMatchingMETAR(metar []METAR, intervals []util.TimeInterval, match func(METAR) bool) *METAR
SampleMatchingMETAR randomly samples from METARs that match a predicate using reservoir sampling
func (METAR) Altimeter_inHg ¶
func (METAR) IsVMC ¶ added in v0.13.0
IsVMC returns true if Visual Meteorological Conditions apply VMC requires >= 3 miles visibility and >= 1000' ceiling AGL
func (*METAR) UnmarshalJSON ¶ added in v0.13.0
UnmarshalJSON handles converting WindDirRaw to WindDir
func (METAR) Visibility ¶ added in v0.13.0
Visibility extracts visibility in statute miles from the raw METAR
type METARSOA ¶ added in v0.13.0
type METARSOA struct {
// These are all delta coded
ReportTime [][]byte
Temperature []int16 // fixed point, one decimal digit
Dewpoint []int16 // fixed point, one decimal digit
Altimeter []int16 // fixed point, one decimal digit
WindDir []int16
WindSpeed []int16
WindGust []int16
// This is not; it's not worth delta encoding the raw METAR reports
// since there's generally not much character alignment between
// successive reports.
Raw []string
}
Structure-of-arrays representation of an array of METAR objects for better compressability.
func MakeMETARSOA ¶ added in v0.13.0
type Model ¶ added in v0.13.0
type Model struct {
// contains filtered or unexported fields
}
func (*Model) GetAtmosGrid ¶ added in v0.13.0
type Precip ¶ added in v0.13.0
Precip is the object type that is stored in GCS after wx ingest for precipitation.
type Provider ¶ added in v0.13.0
type Provider interface {
GetAvailableTimeIntervals() []util.TimeInterval
// Best effort, may not have it for all airports, but no error is returned for that.
GetMETAR(airports []string) (map[string]METARSOA, error)
// Returns the item at-or-before the given time
GetPrecipURL(tracon string, t time.Time) (string, time.Time, error)
// Returns atmos, it's time, the time for the next one in the series.
GetAtmosGrid(tracon string, t time.Time) (*AtmosByPointSOA, time.Time, time.Time, error)
}
type Sample ¶
type Sample struct {
WindSample
Temperature float32 // Celsius
Dewpoint float32 // Celsius
Pressure float32 // millibars
}
func LerpSample ¶ added in v0.13.0
func MakeStandardSampleForAltitude ¶ added in v0.13.0
func (Sample) RelativeHumidity ¶ added in v0.13.0
type WindSample ¶
type WindSample struct {
// WindVec is the wind velocity vector (direction air mass is moving) in nm/s.
// When added to aircraft velocity, it represents wind's effect on the aircraft.
WindVec [2]float32 // nm / s
}
func (WindSample) Component ¶ added in v0.13.0
func (s WindSample) Component(course float32) float32
Component calculates the wind component along a given course in knots. Positive values indicate tailwind, negative values indicate headwind.
func (WindSample) Deflection ¶ added in v0.13.0
func (s WindSample) Deflection(v [2]float32) float32
Deflection calculates the heading correction needed to compensate for wind. Given a velocity vector v, it returns the deflection angle that should be subtracted from the heading to fly into the wind.
func (WindSample) WindDirection ¶ added in v0.13.0
func (s WindSample) WindDirection() float32
func (WindSample) WindSpeed ¶ added in v0.13.0
func (s WindSample) WindSpeed() float32
type WindSpecifier ¶ added in v0.13.0
type WindSpecifier struct {
Direction string `json:"direction,omitempty"` // e.g., "30-90", "270", empty for any
Speed string `json:"speed,omitempty"` // e.g., "5+", "5-", "5-15", empty for any
FlightRules string `json:"flight_rules,omitempty"` // "VMC" or "IMC", empty defaults to "VMC"
}
WindSpecifier defines constraints for sampling weather data
func (*WindSpecifier) Matches ¶ added in v0.13.0
func (ws *WindSpecifier) Matches(metar METAR, magVar float32) bool
Matches checks if a METAR matches this wind specifier
func (*WindSpecifier) Validate ¶ added in v0.13.0
func (ws *WindSpecifier) Validate() error
Validate checks if the wind specifier is valid