Skip to content
Snippets Groups Projects
Commit c717552d authored by Tucker Siegel's avatar Tucker Siegel
Browse files

update

parent e49c023a
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,7 @@ type StageRequest struct { ...@@ -19,6 +19,7 @@ type StageRequest struct {
Longitude float64 `json:"longitude"` Longitude float64 `json:"longitude"`
AnchorStage string `json:"anchor_stage"` AnchorStage string `json:"anchor_stage"`
AnchorDate time.Time `json:"anchor_date"` AnchorDate time.Time `json:"anchor_date"`
Comparison int `json:"comparison"`
} }
func BuildStageRequest(ctx common.DawnCtx) StageRequest { func BuildStageRequest(ctx common.DawnCtx) StageRequest {
...@@ -29,6 +30,7 @@ func BuildStageRequest(ctx common.DawnCtx) StageRequest { ...@@ -29,6 +30,7 @@ func BuildStageRequest(ctx common.DawnCtx) StageRequest {
longitude := ctx.FiberCtx.Query("longitude") longitude := ctx.FiberCtx.Query("longitude")
anchorStage := ctx.FiberCtx.Query("anchor_stage") anchorStage := ctx.FiberCtx.Query("anchor_stage")
anchorDateString := ctx.FiberCtx.Query("anchor_date") anchorDateString := ctx.FiberCtx.Query("anchor_date")
comparison := ctx.FiberCtx.Query("comparison", "-1")
pd, err := time.Parse(time.RFC3339, plantDate) pd, err := time.Parse(time.RFC3339, plantDate)
if err != nil { if err != nil {
...@@ -48,6 +50,11 @@ func BuildStageRequest(ctx common.DawnCtx) StageRequest { ...@@ -48,6 +50,11 @@ func BuildStageRequest(ctx common.DawnCtx) StageRequest {
panic(config.BAD_REQUEST.PutDetail("reason", "\""+mode+"\" is not valid")) panic(config.BAD_REQUEST.PutDetail("reason", "\""+mode+"\" is not valid"))
} }
comparisonInt, err := strconv.Atoi(comparison)
if err != nil {
panic(config.BAD_REQUEST.PutDetail("reason", err.Error()))
}
valueInt, err := strconv.Atoi(value) valueInt, err := strconv.Atoi(value)
if err != nil { if err != nil {
panic(config.BAD_REQUEST.PutDetail("reason", err.Error())) panic(config.BAD_REQUEST.PutDetail("reason", err.Error()))
...@@ -71,6 +78,7 @@ func BuildStageRequest(ctx common.DawnCtx) StageRequest { ...@@ -71,6 +78,7 @@ func BuildStageRequest(ctx common.DawnCtx) StageRequest {
Longitude: longitudeFloat, Longitude: longitudeFloat,
AnchorDate: anchorDate, AnchorDate: anchorDate,
AnchorStage: anchorStage, AnchorStage: anchorStage,
Comparison: comparisonInt,
} }
e := stageRequest.Validate() e := stageRequest.Validate()
...@@ -89,11 +97,11 @@ func (r StageRequest) Validate() error { ...@@ -89,11 +97,11 @@ func (r StageRequest) Validate() error {
} }
type StageData struct { type StageData struct {
AllGdds [][]float64 AllGdds [][]float64
NormalMean []float64 NormalMean []float64
Normal5th []float64 Normal5th []float64
NormalAll [][]float64 ComparisonAll [][]float64
Normal95th []float64 Normal95th []float64
} }
type Bin struct { type Bin struct {
...@@ -102,11 +110,9 @@ type Bin struct { ...@@ -102,11 +110,9 @@ type Bin struct {
} }
type Bins struct { type Bins struct {
Bins []Bin `json:"bins"` Bins []Bin `json:"bins"`
NormalMean time.Time `json:"normal_mean"` ComparisonMean time.Time `json:"comparison_mean"`
NormalMin time.Time `json:"normal_min"` Count int `json:"count"`
NormalMax time.Time `json:"normal_max"`
Count int `json:"count"`
} }
type StageMatches struct { type StageMatches struct {
......
...@@ -199,6 +199,27 @@ func CfsFindByLocation(location entities.Location) []entities.CfsGdd { ...@@ -199,6 +199,27 @@ func CfsFindByLocation(location entities.Location) []entities.CfsGdd {
return gs return gs
} }
func CfsFindByLocationMultiple(location entities.Location, mult int) []entities.CfsGdd {
cfs := CfsFindAllByLocation(location)
coll := Session.Collection("cfs")
filter := buildLocationRequestLarger(location, nil)
// cursor, err := coll.Find(Session.Ctx, filter, options.Find().SetLimit(int64(2)))
cursor, err := coll.Find(Session.Ctx, filter, options.Find().SetLimit(int64(cfs.Count)*int64(mult)))
if err != nil {
panic(config.NO_DATA_FOUND.PutDetail("reason", "cfs").AddLogDetails(err.Error()))
}
var gs []entities.CfsGdd
if err = cursor.All(Session.Ctx, &gs); err != nil {
panic(config.INTERNAL_SERVER_STANDARD_ERROR.AddLogDetails(err.Error()))
}
return gs
}
func FindAnalogYear(location entities.Location) models.AnalogResponse { func FindAnalogYear(location entities.Location) models.AnalogResponse {
coll := Session.Collection("gdd_current") coll := Session.Collection("gdd_current")
......
package services package services
import ( import (
"fmt"
"math" "math"
"sort" "sort"
"time" "time"
...@@ -11,20 +10,23 @@ import ( ...@@ -11,20 +10,23 @@ import (
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models" "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models"
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models/enums" "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models/enums"
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/persistence" "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/persistence"
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/persistence/entities"
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/utils" "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/utils"
) )
func GetStageYearData(ctx common.DawnCtx, request models.GddRequest) models.StageData { func GetStageYearData(ctx common.DawnCtx, request models.GddRequest, comparison int) models.StageData {
product := enums.GetProductFromString(request.Product) product := enums.GetProductFromString(request.Product)
gddData := persistence.CurrentGddFindFirstByYearAndLocation(ctx, request.BuildLocation()) gddData := persistence.CurrentGddFindFirstByYearAndLocation(ctx, request.BuildLocation())
gdds := utils.CalculateGddValues(gddData.MinTemps, gddData.MaxTemps, product, false) gdds := utils.CalculateGddValues(gddData.MinTemps, gddData.MaxTemps, product, false)
request.Year = gddData.AnalogYear request.Year = gddData.AnalogYear
gs := persistence.GetLastNormalsYearly(request.BuildLocation()) var gs []entities.Gdd
if comparison == -1 {
gs = persistence.GetLastNormalsYearly(request.BuildLocation())
} else {
gs = []entities.Gdd{persistence.GddFindFirstByYearAndLocation(comparison, request.BuildLocation())}
}
var normalMeanNonAcc []float64 var normalMeanNonAcc []float64
var normalMean []float64
var normal5th []float64
var normal95th []float64
rows := [][]float64{} rows := [][]float64{}
rowsAll := [][]float64{} rowsAll := [][]float64{}
for i := 0; i < len(gs[0].MinTemps); i++ { for i := 0; i < len(gs[0].MinTemps); i++ {
...@@ -43,7 +45,7 @@ func GetStageYearData(ctx common.DawnCtx, request models.GddRequest) models.Stag ...@@ -43,7 +45,7 @@ func GetStageYearData(ctx common.DawnCtx, request models.GddRequest) models.Stag
normalMeanNonAcc = append(normalMeanNonAcc, meanNoAcc) normalMeanNonAcc = append(normalMeanNonAcc, meanNoAcc)
} }
allCfs := persistence.CfsFindByLocation(request.BuildLocation()) allCfs := persistence.CfsFindByLocationMultiple(request.BuildLocation(), 4)
gddArr := [][]float64{} gddArr := [][]float64{}
for i, c := range allCfs { for i, c := range allCfs {
...@@ -53,11 +55,8 @@ func GetStageYearData(ctx common.DawnCtx, request models.GddRequest) models.Stag ...@@ -53,11 +55,8 @@ func GetStageYearData(ctx common.DawnCtx, request models.GddRequest) models.Stag
} }
returnData := models.StageData{ returnData := models.StageData{
AllGdds: gddArr, AllGdds: gddArr,
NormalMean: normalMean, ComparisonAll: rowsAll,
Normal5th: normal5th,
Normal95th: normal95th,
NormalAll: rowsAll,
} }
return returnData return returnData
} }
...@@ -70,7 +69,7 @@ func CalculateStages(ctx common.DawnCtx, request models.StageRequest) map[string ...@@ -70,7 +69,7 @@ func CalculateStages(ctx common.DawnCtx, request models.StageRequest) map[string
Accumulate: false, Accumulate: false,
Product: "CORN", Product: "CORN",
} }
fyData := GetStageYearData(ctx, gddReq) fyData := GetStageYearData(ctx, gddReq, request.Comparison)
start := request.PlantDate.YearDay() start := request.PlantDate.YearDay()
year := request.PlantDate.Year() year := request.PlantDate.Year()
...@@ -82,26 +81,20 @@ func CalculateStages(ctx common.DawnCtx, request models.StageRequest) map[string ...@@ -82,26 +81,20 @@ func CalculateStages(ctx common.DawnCtx, request models.StageRequest) map[string
stageMatches := models.BuildStageMatches(request.Mode, request.Value, start, fyData, request) stageMatches := models.BuildStageMatches(request.Mode, request.Value, start, fyData, request)
accs := make([]float64, len(fyData.AllGdds)) accs := make([]float64, len(fyData.AllGdds))
accs2 := make([]float64, len(fyData.NormalAll[0])) accs2 := make([]float64, len(fyData.ComparisonAll[0]))
accNormal := 0.0 accNormal := 0.0
acc5thNormal := 0.0
acc95thNormal := 0.0
for i := start; i < len(fyData.AllGdds[0]); i++ { for i := start; i < len(fyData.AllGdds[0]); i++ {
for r, v := range fyData.AllGdds { for r, v := range fyData.AllGdds {
accs[r] += v[i] accs[r] += v[i]
} }
for j := 0; j < len(fyData.NormalAll[0]); j++ { for j := 0; j < len(fyData.ComparisonAll[0]); j++ {
accs2[j] += fyData.NormalAll[i][j] accs2[j] += fyData.ComparisonAll[i][j]
} }
normal, _ := stats.Mean(accs2) normal, _ := stats.Mean(accs2)
min, _ := stats.PercentileNearestRank(accs2, 2.5)
max, _ := stats.PercentileNearestRank(accs2, 97.5)
accNormal = normal accNormal = normal
acc5thNormal = min
acc95thNormal = max
for stage, stageVal := range stageMatches { for stage, stageVal := range stageMatches {
dists := make([]float64, len(fyData.AllGdds)) dists := make([]float64, len(fyData.AllGdds))
...@@ -114,29 +107,15 @@ func CalculateStages(ctx common.DawnCtx, request models.StageRequest) map[string ...@@ -114,29 +107,15 @@ func CalculateStages(ctx common.DawnCtx, request models.StageRequest) map[string
Dists: dists, Dists: dists,
Hists: make([]int, len(fyData.AllGdds)), Hists: make([]int, len(fyData.AllGdds)),
NormalMeanDist: 1000000, NormalMeanDist: 1000000,
Normal5thDist: 1000000,
Normal95thDist: 1000000,
NormalMeanIdx: 0, NormalMeanIdx: 0,
Normal5thIdx: 0,
Normal95thIdx: 0,
} }
} else { } else {
normalMeanDist := math.Abs(stageVal - accNormal) normalMeanDist := math.Abs(stageVal - accNormal)
normal5thDist := math.Abs(stageVal - acc5thNormal)
normal95thDist := math.Abs(stageVal - acc95thNormal)
if normalMeanDist < val.NormalMeanDist { if normalMeanDist < val.NormalMeanDist {
val.NormalMeanDist = normalMeanDist val.NormalMeanDist = normalMeanDist
val.NormalMeanIdx = i val.NormalMeanIdx = i
} }
if normal5thDist < val.Normal5thDist {
val.Normal5thDist = normal5thDist
val.Normal5thIdx = i
}
if normal95thDist < val.Normal95thDist {
val.Normal95thDist = normal95thDist
val.Normal95thIdx = i
}
for r := range accs { for r := range accs {
if dists[r] < val.Dists[r] { if dists[r] < val.Dists[r] {
...@@ -212,78 +191,13 @@ func BinStageMatches(stageState map[string]models.StageStateInner, year int, sta ...@@ -212,78 +191,13 @@ func BinStageMatches(stageState map[string]models.StageStateInner, year int, sta
Value: smoothedVal, Value: smoothedVal,
}) })
} }
inner.NormalMin = plantDate.AddDate(0, 0, min-start) inner.ComparisonMean = plantDate.AddDate(0, 0, stateVal.NormalMeanIdx-start)
inner.NormalMax = plantDate.AddDate(0, 0, max-start)
inner.NormalMean = plantDate.AddDate(0, 0, stateVal.NormalMeanIdx-start)
inner.Count = total inner.Count = total
fmt.Println(state, rangeSize, stepSize, total)
response[state] = inner response[state] = inner
} }
return response return response
} }
// func BinStageMatches(stageState map[string]models.StageStateInner, year int, start int, plantDate time.Time) map[string]models.Bins {
// response := map[string]models.Bins{}
// alpha := 1.0
// add := 0
// if year%4 == 0 && year%100 != 0 || year%400 == 0 {
// add -= 1
// }
// for state, stateVal := range stageState {
// min := stateVal.Normal95thIdx
// max := stateVal.Normal5thIdx
// rangeSize := max - min
// if rangeSize%5 != 0 {
// target := math.Ceil(float64(rangeSize)/5) * 5
// dist := math.Abs((target - float64(rangeSize)))
// move := math.Ceil(dist / 2)
// max += int(move)
// min -= int(move)
// rangeSize = max - min
// if rangeSize%5 != 0 {
// min -= 1
// }
// rangeSize = max - min
// }
// arr := []float64{}
// idxs := []int{}
// stepSize := rangeSize / 5
// base := min
// total := 0
// for i := 0; i < 5; i++ {
// count := 0.0
// for _, h := range stateVal.Hists {
// if base <= h && h < base+stepSize {
// count += 1
// total += 1
// }
// }
// idxs = append(idxs, base)
// arr = append(arr, count)
// base += stepSize
// }
// inner := models.Bins{}
// inner.Bins = []models.Bin{}
// for i := 0; i < 5; i++ {
// idx := idxs[i] + add
// date := plantDate.AddDate(0, 0, idx-start)
// val := arr[i]
// smoothedVal := (val + alpha) / (float64(total) + 5*alpha) // modified version of laplace smoothing to remove 0%
// inner.Bins = append(inner.Bins, models.Bin{
// Date: date,
// Value: smoothedVal,
// })
// }
// inner.NormalMin = plantDate.AddDate(0, 0, min-start)
// inner.NormalMax = plantDate.AddDate(0, 0, max-start)
// inner.NormalMean = plantDate.AddDate(0, 0, stateVal.NormalMeanIdx-start)
// inner.Count = total
// response[state] = inner
// }
// return response
// }
func ForecastFirstLastFreeze(ctx common.DawnCtx, request models.FreezingForecastRequest) models.FreezingForecastResponse { func ForecastFirstLastFreeze(ctx common.DawnCtx, request models.FreezingForecastRequest) models.FreezingForecastResponse {
lastFreezeIdx := 0 lastFreezeIdx := 0
firstFreezeIdx := 0 firstFreezeIdx := 0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment