update for 4 hour rain forecast
This commit is contained in:
+49
-19
@@ -51,11 +51,14 @@ type RainPredictionPoint struct {
|
||||
GeneratedAt time.Time `json:"generated_at"`
|
||||
ModelName string `json:"model_name"`
|
||||
ModelVersion string `json:"model_version"`
|
||||
HorizonHours int `json:"horizon_hours"`
|
||||
Threshold float64 `json:"threshold"`
|
||||
Probability float64 `json:"probability"`
|
||||
PredictRain bool `json:"predict_rain"`
|
||||
RainNext1hMM *float64 `json:"rain_next_1h_mm_actual,omitempty"`
|
||||
RainNext1hActual *bool `json:"rain_next_1h_actual,omitempty"`
|
||||
RainNextMM *float64 `json:"rain_next_mm_actual,omitempty"`
|
||||
RainNextActual *bool `json:"rain_next_actual,omitempty"`
|
||||
RainNext1hMM *float64 `json:"rain_next_1h_mm_actual,omitempty"` // backward-compatible alias
|
||||
RainNext1hActual *bool `json:"rain_next_1h_actual,omitempty"` // backward-compatible alias
|
||||
EvaluatedAt *time.Time `json:"evaluated_at,omitempty"`
|
||||
}
|
||||
|
||||
@@ -365,8 +368,24 @@ func (d *DB) ForecastSeriesRange(ctx context.Context, site, model string, start,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DB) LatestRainPrediction(ctx context.Context, site, modelName string) (*RainPredictionPoint, error) {
|
||||
query := `
|
||||
func predictionStorageForHorizon(horizonHours int) (table string, mmCol string, flagCol string, err error) {
|
||||
switch horizonHours {
|
||||
case 1:
|
||||
return "predictions_rain_1h", "rain_next_1h_mm_actual", "rain_next_1h_actual", nil
|
||||
case 4:
|
||||
return "predictions_rain_4h", "rain_next_4h_mm_actual", "rain_next_4h_actual", nil
|
||||
default:
|
||||
return "", "", "", fmt.Errorf("unsupported rain prediction horizon: %d", horizonHours)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DB) LatestRainPrediction(ctx context.Context, site, modelName string, horizonHours int) (*RainPredictionPoint, error) {
|
||||
table, mmCol, flagCol, err := predictionStorageForHorizon(horizonHours)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := fmt.Sprintf(`
|
||||
SELECT
|
||||
ts,
|
||||
generated_at,
|
||||
@@ -375,15 +394,15 @@ func (d *DB) LatestRainPrediction(ctx context.Context, site, modelName string) (
|
||||
threshold,
|
||||
probability,
|
||||
predict_rain,
|
||||
rain_next_1h_mm_actual,
|
||||
rain_next_1h_actual,
|
||||
%s,
|
||||
%s,
|
||||
evaluated_at
|
||||
FROM predictions_rain_1h
|
||||
FROM %s
|
||||
WHERE site = $1
|
||||
AND model_name = $2
|
||||
ORDER BY ts DESC, generated_at DESC
|
||||
LIMIT 1
|
||||
`
|
||||
`, mmCol, flagCol, table)
|
||||
|
||||
var (
|
||||
p RainPredictionPoint
|
||||
@@ -393,7 +412,7 @@ func (d *DB) LatestRainPrediction(ctx context.Context, site, modelName string) (
|
||||
predictRain sql.NullBool
|
||||
)
|
||||
|
||||
err := d.Pool.QueryRow(ctx, query, site, modelName).Scan(
|
||||
err = d.Pool.QueryRow(ctx, query, site, modelName).Scan(
|
||||
&p.TS,
|
||||
&p.GeneratedAt,
|
||||
&p.ModelName,
|
||||
@@ -421,14 +440,22 @@ func (d *DB) LatestRainPrediction(ctx context.Context, site, modelName string) (
|
||||
if predictRain.Valid {
|
||||
p.PredictRain = predictRain.Bool
|
||||
}
|
||||
p.RainNext1hMM = nullFloatPtr(rainMM)
|
||||
p.RainNext1hActual = nullBoolPtr(rainActual)
|
||||
p.HorizonHours = horizonHours
|
||||
p.RainNextMM = nullFloatPtr(rainMM)
|
||||
p.RainNextActual = nullBoolPtr(rainActual)
|
||||
p.RainNext1hMM = p.RainNextMM
|
||||
p.RainNext1hActual = p.RainNextActual
|
||||
p.EvaluatedAt = nullTimePtr(evaluatedAt)
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
func (d *DB) RainPredictionSeriesRange(ctx context.Context, site, modelName string, start, end time.Time) ([]RainPredictionPoint, error) {
|
||||
query := `
|
||||
func (d *DB) RainPredictionSeriesRange(ctx context.Context, site, modelName string, horizonHours int, start, end time.Time) ([]RainPredictionPoint, error) {
|
||||
table, mmCol, flagCol, err := predictionStorageForHorizon(horizonHours)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := fmt.Sprintf(`
|
||||
SELECT DISTINCT ON (ts)
|
||||
ts,
|
||||
generated_at,
|
||||
@@ -437,16 +464,16 @@ func (d *DB) RainPredictionSeriesRange(ctx context.Context, site, modelName stri
|
||||
threshold,
|
||||
probability,
|
||||
predict_rain,
|
||||
rain_next_1h_mm_actual,
|
||||
rain_next_1h_actual,
|
||||
%s,
|
||||
%s,
|
||||
evaluated_at
|
||||
FROM predictions_rain_1h
|
||||
FROM %s
|
||||
WHERE site = $1
|
||||
AND model_name = $2
|
||||
AND ts >= $3
|
||||
AND ts <= $4
|
||||
ORDER BY ts ASC, generated_at DESC
|
||||
`
|
||||
`, mmCol, flagCol, table)
|
||||
|
||||
rows, err := d.Pool.Query(ctx, query, site, modelName, start, end)
|
||||
if err != nil {
|
||||
@@ -486,8 +513,11 @@ func (d *DB) RainPredictionSeriesRange(ctx context.Context, site, modelName stri
|
||||
if predictRain.Valid {
|
||||
p.PredictRain = predictRain.Bool
|
||||
}
|
||||
p.RainNext1hMM = nullFloatPtr(rainMM)
|
||||
p.RainNext1hActual = nullBoolPtr(rainActual)
|
||||
p.HorizonHours = horizonHours
|
||||
p.RainNextMM = nullFloatPtr(rainMM)
|
||||
p.RainNextActual = nullBoolPtr(rainActual)
|
||||
p.RainNext1hMM = p.RainNextMM
|
||||
p.RainNext1hActual = p.RainNextActual
|
||||
p.EvaluatedAt = nullTimePtr(evaluatedAt)
|
||||
points = append(points, p)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user