diff --git a/Dockerfile.dev b/Dockerfile.dev index 88679e4b35f39a404c3603013b0da2552e65628d..1a22f5603fd47ba7781ffecc8a55b8be125de118 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,9 +1,18 @@ FROM dawn/dawn-cli as base + RUN mkdir /app ADD . /app WORKDIR /app +RUN apt-get update && apt-get install -y python3 python3-dev python3-pip gfortran +RUN pip3 install numpy + +WORKDIR /app/lib/maize +RUN f2py mz.f -c -m mz + +WORKDIR /app + RUN go get -u gitlab.cs.umd.edu/dawn/dawn-go-common RUN go mod tidy diff --git a/Dockerfile.prod b/Dockerfile.prod index 5c955de463be712ba4d7a54b4e0d1adfee4bdd99..f2a633619bd5ec61b77457e7cbcdfda39b35b9b9 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -4,6 +4,14 @@ RUN mkdir /app ADD . /app WORKDIR /app +RUN apt-get update && apt-get install -y python3.9 python3.9-dev +RUN pip install numpy + +WORKDIR /app/lib/maize +RUN f2py mz.f -c -m mz + +WORKDIR /app + RUN go get gitlab.cs.umd.edu/dawn/dawn-go-common RUN curl -LJ -o swag.tar.gz https://github.com/swaggo/swag/releases/download/v1.7.4/swag_1.7.4_Linux_x86_64.tar.gz diff --git a/controllers/maturity_controller.go b/controllers/maturity_controller.go new file mode 100644 index 0000000000000000000000000000000000000000..c541c61073f236532ef5731a516e36635cd71959 --- /dev/null +++ b/controllers/maturity_controller.go @@ -0,0 +1,68 @@ +package controllers + +import ( + "github.com/gofiber/fiber/v2" + "gitlab.cs.umd.edu/dawn/dawn-go-common/common" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/services" +) + +type MaturityRequest struct { + PlantDate int `json:"plantdate"` + Tmins []float32 `json:"tmins"` + Tmaxs []float32 `json:"tmaxs"` + Srads []float32 `json:"srads"` + Rains []float32 `json:"rains"` + Units string `json:"units"` +} + +type ResponseTest struct { + Date int `json:"date"` +} + +// GetCultivars godoc +// @Summary Get all generic corn cultivars +// @Tags Maturity +// @Description Get all generic corn cultivars +// @Accept json +// @Produce json +// @Success 200 {object} models.CultivarResponse +// @Failure 400 {object} common.StandardError +// @Param name query string false "Name of cultivar to get" +// @Router /gdd/maturity/corn/cultivars [get] +func GetCultivars(c *fiber.Ctx) error { + ctx := common.DawnCtx{FiberCtx: c} + request := models.CultivarRequest{ + Name: c.Query("name", ""), + } + return c.Status(fiber.StatusOK).JSON(services.GetCultivars(ctx, request)) +} + +// GetMaturity godoc +// @Summary Get expected maturity date +// @Tags Maturity +// @Description Get expected maturity date +// @Accept json +// @Produce json +// @Success 200 {object} models.CultivarResponse +// @Failure 400 {object} common.StandardError +// @Param latitude query number true "Latitude to search for" +// @Param longitude query number true "Longitude to search for" +// @Param plant_month query number true "Platning month" +// @Param plant_date query number true "Platning date" +// @Param var_name query string true "Name of cultivar" +// @Param var_num query string true "ID# of cultivar" +// @Param eco_num query string true "Eco# of cultivar" +// @Param p1 query number true "P1 value of cultivar" +// @Param p2 query number true "P2 value of cultivar" +// @Param p5 query number true "P5 value of cultivar" +// @Param g2 query number true "G2 value of cultivar" +// @Param g3 query number true "G3 value of cultivar" +// @Param phint query number true "PHINT value of cultivar" +// @Router /gdd/maturity/corn [get] +func GetMaturity(c *fiber.Ctx) error { + ctx := common.DawnCtx{FiberCtx: c} + request := models.BuildCornMaturityRequest(ctx) + return c.Status(fiber.StatusOK).JSON(services.CalculateMaturity(ctx, request)) + +} diff --git a/controllers/routes.go b/controllers/routes.go index 727996df6ba7d9ae1b3160d6cd1756672d3ef86c..010a2b55b820fca8821019f920748ee2dbc704bc 100644 --- a/controllers/routes.go +++ b/controllers/routes.go @@ -16,6 +16,7 @@ func GddRoutes(route fiber.Router) { route.Get("gdd/csv", GetCSVFile) - route.Get("gdd/maturity/corn", GetCornSeedMaturityDate) - route.Get("gdd/seeds", GetSeedList) + route.Get("gdd/maturity/corn", GetMaturity) + route.Get("gdd/maturity/corn/cultivars", GetCultivars) + // route.Get("gdd/seeds", GetSeedList) } diff --git a/controllers/seed_controllers.go b/controllers/seed_controllers.go index c3ac845d89eaf73269dc98c3daa9a301d24ed2e9..d9dc4d4372d3554674a88148e6639cc8f6e2e6a7 100644 --- a/controllers/seed_controllers.go +++ b/controllers/seed_controllers.go @@ -1,38 +1,38 @@ package controllers -import ( - "gitlab.cs.umd.edu/dawn/dawn-go-common/common" - "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models" - "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/services" +// import ( +// "gitlab.cs.umd.edu/dawn/dawn-go-common/common" +// "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models" +// "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/services" - "github.com/gofiber/fiber/v2" -) +// "github.com/gofiber/fiber/v2" +// ) -func GetSeedList(c *fiber.Ctx) error { - request := models.SeedListRequest{Product: c.Query("product")} - return c.Status(fiber.StatusOK).JSON( - services.GetSeedList(c, request), - ) -} +// func GetSeedList(c *fiber.Ctx) error { +// request := models.SeedListRequest{Product: c.Query("product")} +// return c.Status(fiber.StatusOK).JSON( +// services.GetSeedList(c, request), +// ) +// } -// GetCornSeedMaturityDate godoc -// @Summary Get estimated maturity date from given gdd (uses CFS data if current GDUs are less than the crop maturity) -// @Tags GDD Maturity Data -// @Description Get estimated maturity date from given gdd -// @Accept json -// @Produce json -// @Success 200 {object} models.CornMaturityResponse -// @Failure 400 {object} common.StandardError -// @Param latitude query number true "Latitude to search for" -// @Param longitude query number true "Longitude to search for" -// @Param gdds query number true "number of gdds given" -// @Param month query number true "month planted" -// @Param date query number true "date planted" -// @Router /gdd/maturity/corn [get] -func GetCornSeedMaturityDate(c *fiber.Ctx) error { - ctx := common.DawnCtx{FiberCtx: c} - request := models.BuildCornMaturityRequest(c) - return c.Status(fiber.StatusOK).JSON( - services.GetCornMaturityDate(ctx, request), - ) -} +// // GetCornSeedMaturityDate godoc +// // @Summary Get estimated maturity date from given gdd (uses CFS data if current GDUs are less than the crop maturity) +// // @Tags GDD Maturity Data +// // @Description Get estimated maturity date from given gdd +// // @Accept json +// // @Produce json +// // @Success 200 {object} models.CornMaturityResponse +// // @Failure 400 {object} common.StandardError +// // @Param latitude query number true "Latitude to search for" +// // @Param longitude query number true "Longitude to search for" +// // @Param gdds query number true "number of gdds given" +// // @Param month query number true "month planted" +// // @Param date query number true "date planted" +// // @Router /gdd/maturity/corn [get] +// func GetCornSeedMaturityDate(c *fiber.Ctx) error { +// ctx := common.DawnCtx{FiberCtx: c} +// request := models.BuildCornMaturityRequest(c) +// return c.Status(fiber.StatusOK).JSON( +// services.GetCornMaturityDate(ctx, request), +// ) +// } diff --git a/docs/docs.go b/docs/docs.go index 2d3b55d3d428b5cf68a9bd9038ed22903023723b..bb298080e15f7dcc765ccee58a54f6d49d272826 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -235,6 +235,22 @@ var doc = `{ "in": "query", "required": true }, + { + "enum": [ + 80, + 85, + 90, + 95, + 99, + 99.5, + 99.9 + ], + "type": "number", + "description": "Interval values", + "name": "Interval", + "in": "query", + "required": true + }, { "type": "number", "description": "Latitude to search for", @@ -583,7 +599,7 @@ var doc = `{ }, "/gdd/maturity/corn": { "get": { - "description": "Get estimated maturity date from given gdd", + "description": "Get expected maturity date", "consumes": [ "application/json" ], @@ -591,9 +607,9 @@ var doc = `{ "application/json" ], "tags": [ - "GDD Maturity Data" + "Maturity" ], - "summary": "Get estimated maturity date from given gdd (uses CFS data if current GDUs are less than the crop maturity)", + "summary": "Get expected maturity date", "parameters": [ { "type": "number", @@ -611,22 +627,78 @@ var doc = `{ }, { "type": "number", - "description": "number of gdds given", - "name": "gdds", + "description": "Platning month", + "name": "plant_month", "in": "query", "required": true }, { "type": "number", - "description": "month planted", - "name": "month", + "description": "Platning date", + "name": "plant_date", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Name of cultivar", + "name": "var_name", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "ID# of cultivar", + "name": "var_num", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Eco# of cultivar", + "name": "eco_num", "in": "query", "required": true }, { "type": "number", - "description": "date planted", - "name": "date", + "description": "P1 value of cultivar", + "name": "p1", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "P2 value of cultivar", + "name": "p2", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "P5 value of cultivar", + "name": "p5", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "G2 value of cultivar", + "name": "g2", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "G3 value of cultivar", + "name": "g3", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "PHINT value of cultivar", + "name": "phint", "in": "query", "required": true } @@ -635,7 +707,44 @@ var doc = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.CornMaturityResponse" + "$ref": "#/definitions/models.CultivarResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/common.StandardError" + } + } + } + } + }, + "/gdd/maturity/corn/cultivars": { + "get": { + "description": "Get all generic corn cultivars", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maturity" + ], + "summary": "Get all generic corn cultivars", + "parameters": [ + { + "type": "string", + "description": "Name of cultivar to get", + "name": "name", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.CultivarResponse" } }, "400": { @@ -816,23 +925,46 @@ var doc = `{ } } }, - "models.CornMaturityResponse": { + "models.Cultivar": { "type": "object", "properties": { - "closest_gdd": { + "eco_num": { + "type": "string" + }, + "g2": { "type": "number" }, - "closest_latitude": { + "g3": { "type": "number" }, - "closest_longitude": { + "p1": { "type": "number" }, - "date": { - "type": "string" + "p2": { + "type": "number" + }, + "p5": { + "type": "number" }, - "gdd": { + "phint": { "type": "number" + }, + "var_name": { + "type": "string" + }, + "var_num": { + "type": "string" + } + } + }, + "models.CultivarResponse": { + "type": "object", + "properties": { + "cultivars": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Cultivar" + } } } }, @@ -988,5 +1120,5 @@ func (s *s) ReadDoc() string { } func init() { - swag.Register(swag.Name, &s{}) + swag.Register("swagger", &s{}) } diff --git a/docs/swagger.json b/docs/swagger.json index c124f4e120a186c64a68cb708253469e7be2c6df..1b8b582012e4ffa080a21350b145b386a88fafa6 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -218,6 +218,22 @@ "in": "query", "required": true }, + { + "enum": [ + 80, + 85, + 90, + 95, + 99, + 99.5, + 99.9 + ], + "type": "number", + "description": "Interval values", + "name": "Interval", + "in": "query", + "required": true + }, { "type": "number", "description": "Latitude to search for", @@ -566,7 +582,7 @@ }, "/gdd/maturity/corn": { "get": { - "description": "Get estimated maturity date from given gdd", + "description": "Get expected maturity date", "consumes": [ "application/json" ], @@ -574,9 +590,9 @@ "application/json" ], "tags": [ - "GDD Maturity Data" + "Maturity" ], - "summary": "Get estimated maturity date from given gdd (uses CFS data if current GDUs are less than the crop maturity)", + "summary": "Get expected maturity date", "parameters": [ { "type": "number", @@ -594,22 +610,78 @@ }, { "type": "number", - "description": "number of gdds given", - "name": "gdds", + "description": "Platning month", + "name": "plant_month", "in": "query", "required": true }, { "type": "number", - "description": "month planted", - "name": "month", + "description": "Platning date", + "name": "plant_date", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Name of cultivar", + "name": "var_name", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "ID# of cultivar", + "name": "var_num", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Eco# of cultivar", + "name": "eco_num", "in": "query", "required": true }, { "type": "number", - "description": "date planted", - "name": "date", + "description": "P1 value of cultivar", + "name": "p1", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "P2 value of cultivar", + "name": "p2", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "P5 value of cultivar", + "name": "p5", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "G2 value of cultivar", + "name": "g2", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "G3 value of cultivar", + "name": "g3", + "in": "query", + "required": true + }, + { + "type": "number", + "description": "PHINT value of cultivar", + "name": "phint", "in": "query", "required": true } @@ -618,7 +690,44 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.CornMaturityResponse" + "$ref": "#/definitions/models.CultivarResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/common.StandardError" + } + } + } + } + }, + "/gdd/maturity/corn/cultivars": { + "get": { + "description": "Get all generic corn cultivars", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maturity" + ], + "summary": "Get all generic corn cultivars", + "parameters": [ + { + "type": "string", + "description": "Name of cultivar to get", + "name": "name", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.CultivarResponse" } }, "400": { @@ -799,23 +908,46 @@ } } }, - "models.CornMaturityResponse": { + "models.Cultivar": { "type": "object", "properties": { - "closest_gdd": { + "eco_num": { + "type": "string" + }, + "g2": { "type": "number" }, - "closest_latitude": { + "g3": { "type": "number" }, - "closest_longitude": { + "p1": { "type": "number" }, - "date": { - "type": "string" + "p2": { + "type": "number" + }, + "p5": { + "type": "number" }, - "gdd": { + "phint": { "type": "number" + }, + "var_name": { + "type": "string" + }, + "var_num": { + "type": "string" + } + } + }, + "models.CultivarResponse": { + "type": "object", + "properties": { + "cultivars": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Cultivar" + } } } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b9e54da560d5e9fb843e4ea79ed56017b0817d88..497d78fedfa63afede88bd09bf23ae92d86fe406 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -59,18 +59,33 @@ definitions: type: number type: array type: object - models.CornMaturityResponse: + models.Cultivar: properties: - closest_gdd: + eco_num: + type: string + g2: type: number - closest_latitude: + g3: type: number - closest_longitude: + p1: type: number - date: - type: string - gdd: + p2: type: number + p5: + type: number + phint: + type: number + var_name: + type: string + var_num: + type: string + type: object + models.CultivarResponse: + properties: + cultivars: + items: + $ref: '#/definitions/models.Cultivar' + type: array type: object models.FreezingDateResponse: properties: @@ -289,6 +304,19 @@ paths: name: product required: true type: string + - description: Interval values + enum: + - 80 + - 85 + - 90 + - 95 + - 99 + - 99.5 + - 99.9 + in: query + name: Interval + required: true + type: number - description: Latitude to search for in: query name: latitude @@ -542,7 +570,7 @@ paths: get: consumes: - application/json - description: Get estimated maturity date from given gdd + description: Get expected maturity date parameters: - description: Latitude to search for in: query @@ -554,36 +582,99 @@ paths: name: longitude required: true type: number - - description: number of gdds given + - description: Platning month + in: query + name: plant_month + required: true + type: number + - description: Platning date in: query - name: gdds + name: plant_date required: true type: number - - description: month planted + - description: Name of cultivar + in: query + name: var_name + required: true + type: string + - description: ID# of cultivar in: query - name: month + name: var_num + required: true + type: string + - description: Eco# of cultivar + in: query + name: eco_num + required: true + type: string + - description: P1 value of cultivar + in: query + name: p1 required: true type: number - - description: date planted + - description: P2 value of cultivar in: query - name: date + name: p2 required: true type: number + - description: P5 value of cultivar + in: query + name: p5 + required: true + type: number + - description: G2 value of cultivar + in: query + name: g2 + required: true + type: number + - description: G3 value of cultivar + in: query + name: g3 + required: true + type: number + - description: PHINT value of cultivar + in: query + name: phint + required: true + type: number + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.CultivarResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/common.StandardError' + summary: Get expected maturity date + tags: + - Maturity + /gdd/maturity/corn/cultivars: + get: + consumes: + - application/json + description: Get all generic corn cultivars + parameters: + - description: Name of cultivar to get + in: query + name: name + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/models.CornMaturityResponse' + $ref: '#/definitions/models.CultivarResponse' "400": description: Bad Request schema: $ref: '#/definitions/common.StandardError' - summary: Get estimated maturity date from given gdd (uses CFS data if current - GDUs are less than the crop maturity) + summary: Get all generic corn cultivars tags: - - GDD Maturity Data + - Maturity /gdd/normals: get: consumes: diff --git a/go.mod b/go.mod index d5e0e03b5d49d0c060b800a8cb2475c72b1a0756..b85d374536a246fd8612b43938ae051dbbc80b81 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd go 1.16 require ( + github.com/DataDog/go-python3 v0.0.0-20211102160307-40adc605f1fe // indirect + github.com/Konstantin8105/f4go v0.0.0-20211017110926-3b02a09b3573 // indirect github.com/andybalholm/brotli v1.0.3 // indirect github.com/ansrivas/fiberprometheus/v2 v2.1.2 github.com/arsmn/fiber-swagger/v2 v2.15.0 diff --git a/go.sum b/go.sum index 066b7fc472411b27fd59e97d6ca9eae185dd7dc3..a2bfdc21231d750fb002b8f29e167b126de614d6 100644 --- a/go.sum +++ b/go.sum @@ -44,7 +44,11 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/go-python3 v0.0.0-20211102160307-40adc605f1fe h1:bNMi0HArOQY4899TKLi4RP7g9BZ2kwLOiVpoJHWxyFs= +github.com/DataDog/go-python3 v0.0.0-20211102160307-40adc605f1fe/go.mod h1:7ctnOCLiUlwKO9GvAjusUF68edSbiHqC18gVPQF0ojA= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Konstantin8105/f4go v0.0.0-20211017110926-3b02a09b3573 h1:brai4FFFTuoeMW97HzZMR5sKSporPtYLvYMl+naNQrI= +github.com/Konstantin8105/f4go v0.0.0-20211017110926-3b02a09b3573/go.mod h1:vZxW3sVrJfWNzLsO8EYioT8eWMzkdOVu8AqFqj+IWhs= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -89,6 +93,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 h1:/P9/RL0xgWE+ehnCUUN5h3RpG3dmoMCOONO1CCvq23Y= github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013/go.mod h1:pccXHIvs3TV/TUqSNyEvF99sxjX2r4FFRIyw6TZY9+w= +github.com/bradleyjkemp/cupaloy v2.3.0+incompatible/go.mod h1:Au1Xw1sgaJ5iSFktEhYsS0dbQiS1B0/XMXl+42y9Ilk= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/lib/__pycache__/mz.cpython-37.pyc b/lib/__pycache__/mz.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a6fd888b05ecc6b7d837d93e3963bc71aae9e45 Binary files /dev/null and b/lib/__pycache__/mz.cpython-37.pyc differ diff --git a/lib/maize/DSSAT.INP b/lib/maize/DSSAT.INP new file mode 100644 index 0000000000000000000000000000000000000000..d76651359cf65765f0fef13ee6c616856ef4e3d4 --- /dev/null +++ b/lib/maize/DSSAT.INP @@ -0,0 +1,111 @@ +*MODEL INPUT FILE A 8 1 8 8 0 +*FILES +MODEL MZCER047 +FILEX nml +FILEA nml . A +FILET nml . T +SPECIES MZCER047.SPE +ECOTYPE MZCER047.ECO +CULTIVAR MZCER047.CUL +PESTS MZCER047.PST ///glade/u/home/sunchao/model/dssat-csm-os/bin/Pest/ +SOILS SOIL.SOL +WEATHERW UFGA8201.WTH +OUTPUT OVERVIEW +*SIMULATION CONTROL + 1 1 S 1982056 2150 N X IRRIGATION, GAINESVI + Y Y N N N N N Y M + M M E R S R R 1 G S 2 D 0 + R R R N M + N Y Y 1 Y N Y Y N N Y N N +!AUTOMATIC MANAGEM + -99 -99 40. 100. 30. 40. 10. + 30. 50. 100. GS000 IR001 10.0 1.000 + 30. 50. 25. FE001 GS000 + 100. 1 20. + 0 -99 100. 0. +*EXP.DETAILS + 1nml NIT X IRR, GAINESVILLE 2N*3I +*TREATMENTS + 8 1 0 0 IRRIGATED HIGH NITROGENl +*CULTIVARS + MZ IB0006 McCurdy 84aa +*FIELDS + UFGA0002 UFGA8201 0.0 0. DR000 0. 100.0 00000 -99 180. IBMZ910014 + 29.63000 -82.37000 40.00 1.0 100. 1.0 0.0 -99 -99 +*INITIAL CONDITIONS + MZ 1982156 100 0 1.00 1.00 0.0 1000 0.80 0.00 100. 15. + 5. 0.086 0.500 0.100 + 15. 0.086 0.500 0.100 + 30. 0.086 0.500 0.100 + 45. 0.086 0.500 0.100 + 60. 0.086 0.500 0.100 + 90. 0.076 0.600 0.100 + 120. 0.076 0.500 0.100 + 150. 0.130 0.500 0.100 + 180. 0.258 0.500 0.100 +*PLANTING DETAILS + 1982157 -99 7.2 7.2 S R 61. 0. 7.0 -99. -99. -99.0 -99.0 0.0 +*IRRIGATION + 1.000 30. 75. -99. GS000 IR001 0.0 + 1982063 IR001 13.0 + 1982077 IR001 10.0 + 1982094 IR001 10.0 + 1982107 IR001 13.0 + 1982111 IR001 18.0 + 1982122 IR001 25.0 + 1982126 IR001 25.0 + 1982129 IR001 13.0 + 1982132 IR001 15.0 + 1982134 IR001 19.0 + 1982137 IR001 20.0 + 1982141 IR001 20.0 + 1982148 IR001 15.0 + 1982158 IR001 19.0 + 1982161 IR001 4.0 + 1982162 IR001 25.0 +*FERTILIZERS + 1982074 FE001 AP001 10. 56. 0. 0. 0. 0. -99 + 1982089 FE001 AP001 10. 52. 0. 0. 0. 0. -99 + 1982102 FE001 AP001 10. 75. 0. 0. 0. 0. -99 + 1982118 FE001 AP001 10. 37. 0. 0. 0. 0. -99 + 1982127 FE001 AP001 10. 55. 0. 0. 0. 0. -99 + 1982137 FE001 AP001 10. 126. 0. 0. 0. 0. -99 +*RESIDUES +*CHEMICALS +*TILLAGE +*ENVIRONMENT +*HARVEST +*SOIL + IBMZ910014 Gainesville -99 180. Millhopper Fine Sand + Gainesville USA 29.630 -82.370 Loamy,silic,hyperth Arenic Paleudult + -99 0.18 2.0 0.65 60. 1.00 0.92 IB001 IB001 IB001 -99 + 5. 0.026 0.096 0.230 1.000 -99. 1.30 2.000 -99.0 -99.0 -99.0 -9.0 7.00-99.00 20.00-99.00 + 15. 0.025 0.086 0.230 1.000 -99. 1.30 1.000 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + 30. 0.025 0.086 0.230 0.700 -99. 1.40 1.000 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + 45. 0.025 0.086 0.230 0.300 -99. 1.40 0.500 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + 60. 0.025 0.086 0.230 0.300 -99. 1.40 0.500 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + 90. 0.028 0.090 0.230 0.050 -99. 1.45 0.100 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + 120. 0.028 0.090 0.230 0.030 -99. 1.45 0.100 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + 150. 0.029 0.130 0.230 0.002 -99. 1.45 0.040 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + 180. 0.070 0.258 0.360 0.000 -99. 1.20 0.240 -99.0 -99.0 -99.0 -9.0 7.00-99.00-99.00-99.00 + + 5.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 15.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 30.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 45.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 60.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 90.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 120.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 150.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + 180.-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0 -99.0-99.00 -99.0 -99.0 -99.0 -99.0 -99.0 -99. + + 5.-99.00-99.00-99.00-99.00 + 15.-99.00-99.00-99.00-99.00 + 30.-99.00-99.00-99.00-99.00 + 45.-99.00-99.00-99.00-99.00 + 60.-99.00-99.00-99.00-99.00 + 90.-99.00-99.00-99.00-99.00 + 120.-99.00-99.00-99.00-99.00 + 150.-99.00-99.00-99.00-99.00 + 180.-99.00-99.00-99.00-99.00 +*CULTIVAR diff --git a/lib/maize/MZCER047.CUL b/lib/maize/MZCER047.CUL new file mode 100644 index 0000000000000000000000000000000000000000..7c65e59e22e47a9d424ecfd5b1a6a09c060fcf17 --- /dev/null +++ b/lib/maize/MZCER047.CUL @@ -0,0 +1,245 @@ +*MAIZE CULTIVAR COEFFICIENTS: MZCER047 MODEL +! +!The P1 values for the varieties used in experiments IBWA8301 and +!UFGA8201 were recalibrated to obtain a better fit for version 3 +!of the model. After converting from 2.1 to 3.0 the varieties +!IB0035, IB0060, and IB0063 showed an earlier simulated flowering +!date. To correct this, the P1 values were recalibrated. +!The reason for this is that there was an error in PHASEI in +!version 2.1 that had TLNO=IFIX(CUMDTT/21.+6.) rather than +!TLNO=IFIX(SUMDTT/21.+6.); see p. 74 of Jones & Kiniry. +!-Walter Bowen, 22 DEC 1994. +! +!All G2 values were increased by a factor of 1.1 for Ritchie's +!change to RUE -Walter, 28 DEC 1994 +! +! COEFF DEFINITIONS +! ======== =========== +! VAR# Identification code or number for a specific cultivar +! VAR-NAME Name of cultivar +! EXPNO Number of experiments used to estimate cultivar parameters +! ECO# Ecotype code of this cultivar, points to the Ecotype in the +! ECO file (currently not used). +! P1 Thermal time from seedling emergence to the end of the juvenile +! phase (expressed in degree days above a base temperature of 8 deg.C) +! during which the plant is not responsive to changes in +! photoperiod. +! P2 Extent to which development (expressed as days) is delayed for +! each hour increase in photoperiod above the longest photoperiod +! at which development proceeds at a maximum rate (which is +! considered to be 12.5 hours). +! P5 Thermal time from silking to physiological maturity (expressed +! in degree days above a base temperature of 8 deg.C). +! G2 Maximum possible number of kernels per plant. +! G3 Kernel filling rate during the linear grain filling stage and +! under optimum conditions (mg/day). +! PHINT Phylochron interval; the interval in thermal time (degree days) +! between successive leaf tip appearances. +! +! PIO Pioneer +! AS Asgrow (Monsanto) +! DK Dekalb (Monsanto) +! LH Holden (Monsanto) +! C/LOL Land of Lakes +! +@VAR# VRNAME.......... EXPNO ECO# P1 P2 P5 G2 G3 PHINT +! 1 2 3 4 5 6 +PC0001 2500-2600 GDD . IB0001 160.0 0.750 780.0 750.0 8.50 49.00 +PC0002 2600-2650 GDD . IB0001 185.0 0.750 850.0 800.0 8.50 49.00 +PC0003 2650-2700 GDD . IB0001 212.0 0.750 850.0 800.0 8.50 49.00 +PC0004 2700-2750 GDD . IB0001 240.0 0.750 850.0 800.0 8.50 49.00 +PC0005 2750-2800 GDD . IB0001 260.0 0.750 850.0 800.0 8.50 49.00 + +990001 LONG SEASON . IB0001 320.0 0.520 940.0 620.0 6.00 38.90 +990002 MEDIUM SEASON . IB0001 200.0 0.300 800.0 700.0 8.50 38.90 +990003 SHORT SEASON . IB0001 110.0 0.300 680.0 820.4 6.60 38.90 +990004 V.SHORT SEASON . IB0001 5.0 0.300 680.0 820.4 6.60 38.90 +! +IB0001 CORNL281 . IB0001 110.0 0.300 685.0 907.9 6.60 38.90 +IB0002 CP170 . IB0001 120.0 0.000 685.0 907.9 10.00 38.90 +IB0003 LG11 . IB0001 125.0 0.000 685.0 907.9 10.00 38.90 +IB0004 F7 X F2 . IB0001 125.0 0.000 685.0 907.9 10.00 38.90 +IB0005 PIO 3995 . IB0001 130.0 0.300 685.0 907.9 8.60 38.90 +IB0006 INRA . IB0001 135.0 0.000 685.0 907.9 10.00 38.90 +IB0007 EDO . IB0001 135.0 0.300 685.0 907.9 10.40 38.90 +IB0008 A654 X F2 . IB0001 135.0 0.000 685.0 907.9 10.00 38.90 +IB0009 DEKALB XL71 . IB0001 140.0 0.300 685.0 907.9 10.50 38.90 +IB0010 F478 X W705A . IB0001 140.0 0.000 685.0 907.9 10.00 38.90 +IB0011 DEKALBXL45 . IB0001 150.0 0.400 685.0 907.9 10.15 38.90 +IB0012 PIO 3382 . IB0001 160.0 0.700 950.0 845.0 8.40 38.90 +IB0013 B59*OH43 . IB0001 162.0 0.800 685.0 862.4 6.90 38.90 +IB0014 F16 X F19 . IB0001 165.0 0.000 685.0 907.9 10.00 38.90 +IB0015 WASHINGTON . IB0001 165.0 0.400 715.0 825.0 11.00 38.90 +IB0016 B14XOH43 . IB0001 172.0 0.300 685.0 907.9 8.50 38.90 +IB0017 R1*(N32*B14) . IB0001 172.0 0.800 685.0 907.9 10.15 38.90 +IB0018 B60*R71 . IB0001 172.0 0.800 685.0 781.4 7.70 38.90 +IB0019 WF9*B37 . IB0001 172.0 0.800 685.0 907.9 10.15 38.90 +IB0020 B59*C103 . IB0001 172.0 0.800 685.0 907.9 10.15 38.90 +IB0021 Garst 8702 . IB0001 175.0 0.200 960.0 855.8 6.00 38.90 +IB0022 B14*C103 . IB0001 180.0 0.500 685.0 907.9 10.15 38.90 +IB0023 B14*C131A . IB0001 180.0 0.500 685.0 907.9 10.15 38.90 +IB0024 PIO 3720 . IB0001 180.0 0.800 685.0 907.9 10.00 38.90 +IB0025 WASH/GRAIN-1 . IB0001 185.0 0.400 775.0 836.0 12.00 38.90 +IB0026 A632 X W117 . IB0001 187.0 0.000 685.0 907.9 10.00 38.90 +IB0027 Garst 8750 . IB0001 190.0 0.200 930.0 891.0 6.30 38.90 +IB0028 TAINAN-11 . IB0001 200.0 0.800 670.0 803.0 6.80 38.90 +IB0029 PIO 3541 . IB0001 200.0 0.300 800.0 770.0 8.50 38.90 +IB0030 PIO 3707 . IB0001 200.0 0.700 800.0 649.0 6.30 38.90 +IB0031 PIO 3475* . IB0001 200.0 0.700 800.0 797.5 8.60 38.90 +IB0032 PIO 3382* . IB0001 200.0 0.700 800.0 715.0 8.50 38.90 +IB0033 PIO 3780 . IB0001 200.0 0.760 685.0 660.0 9.60 38.90 +IB0034 PIO 3780* . IB0001 200.0 0.760 685.0 797.5 9.60 38.90 +IB0035 McCurdy 84aa . IB0001 265.0 0.300 920.0 920.0 8.00 43.00 +IB0036 C281 . IB0001 202.0 0.300 685.0 907.9 5.80 38.90 +IB0037 SWEET CORN . IB0001 210.0 0.520 625.0 907.5 10.00 38.90 +IB0038 Garst 8555 . IB0001 215.0 0.400 890.0 880.0 9.00 38.90 +IB0039 PIO 3901 . IB0001 215.0 0.760 600.0 616.0 9.00 38.90 +IB0040 B8*153R . IB0001 218.0 0.300 760.0 632.5 8.80 38.90 +IB0041 Garst 8808 . IB0001 220.0 0.400 780.0 858.0 8.50 38.90 +IB0042 B73 X MO17 . IB0001 220.0 0.520 880.0 803.0 10.00 38.90 +IB0043 PIO 511A . IB0001 220.0 0.300 685.0 709.5 10.50 38.90 +IB0044 W69A X F546 . IB0001 240.0 0.300 685.0 907.9 10.00 38.90 +IB0045 A632 X VA26 . IB0001 240.0 0.300 685.0 907.9 10.00 38.90 +IB0046 W64A X W117 . IB0001 245.0 0.000 685.0 907.9 8.00 38.90 +IB0047 PIO 3147 . IB0001 255.0 0.760 685.0 917.4 10.00 38.90 +IB0048 WF9*B37 . IB0001 260.0 0.800 710.0 907.9 6.50 38.90 +IB0049 NEB 611 . IB0001 260.0 0.300 720.0 907.5 9.00 38.90 +IB0050 PV82S . IB0001 260.0 0.500 750.0 660.0 8.50 38.90 +IB0051 PV76S . IB0001 260.0 0.500 750.0 660.0 8.50 38.90 +IB0052 PIO 3183 . IB0001 260.0 0.500 750.0 660.0 8.50 38.90 +IB0053 CESDA-28 . IB0001 260.0 0.500 669.0 858.0 7.10 38.90 +IB0054 B14*OH43 . IB0001 265.0 0.800 665.0 858.0 6.90 38.90 +IB0055 MCCURDY 6714 . IB0001 265.0 0.300 825.0 907.9 9.80 38.90 +IB0056 FM 6 . IB0001 276.0 0.520 867.0 677.6 10.70 38.90 +IB0057 TOCORON-3 . IB0001 276.0 0.520 867.0 660.0 8.12 38.90 +IB0058 NC+59 . IB0001 280.0 0.300 750.0 907.5 10.00 38.90 +IB0059 H6 . IB0001 310.0 0.300 685.0 907.9 10.00 38.90 +IB0060 H610(UH) . IB0001 365.0 0.520 850.0 680.0 6.50 38.90 +IB0061 PB 8 . IB0001 300.0 0.520 990.0 440.0 7.00 38.90 +IB0062 B56*C131A . IB0001 318.0 0.500 700.0 885.5 6.40 38.90 +IB0063 PIO X 304C . IB0001 365.0 0.520 920.0 780.0 5.70 38.90 +IB0064 H.OBREGON . IB0001 360.0 0.800 685.0 907.9 10.15 38.90 +IB0065 SUWAN-1 . IB0001 380.0 0.600 780.0 825.0 7.00 38.90 +IB0066 PIO 3165 . IB0001 320.0 0.520 940.0 625.0 6.00 38.90 +IB0067 PIO 3324 . IB0001 320.0 0.520 940.0 625.0 6.00 38.90 +IB0068 PIO 3475 . IB0001 200.0 0.700 750.0 907.0 9.00 38.90 +IB0168 PIO 3475 orig . IB0001 220.0 0.700 850.0 907.0 9.90 38.90 +IB0069 PIO 3790 . IB0001 212.4 0.520 792.8 625.0 6.00 38.90 +IB0070 CARGILL 111S . IB0001 290.0 0.500 1035. 580.0 5.50 47.00 +IB0071 PIO 31G98 . IB0003 165.0 0.750 680.0 820.4 6.60 48.00 +IB0089 GL 582 . IB0001 200.0 0.700 750.0 750.0 8.60 38.90 +IB0090 GL 482 . IB0001 240.0 0.700 990.0 907.0 8.80 38.90 +IB0091 GL 450 . IB0001 200.0 0.700 850.0 700.0 7.00 38.90 +IB0092 LAURENT 3733 . IB0001 200.0 0.700 680.0 725.0 9.00 38.90 +IB0093 GL 582 MOD KBS . IB0001 180.0 0.700 750.0 750.0 8.60 38.90 +IB0099 AGETI76 . IB0001 325.0 2.000 625.0 580.0 7.30 50.00 +IB0100 PARTAP1 . IB0001 450.0 2.000 580.0 600.0 16.50 50.00 + +IB1051 AS 740 . IB0001 215.0 0.750 850.0 700.0 5.00 48.00 +IB1053 LH198XLH185 . IB0001 205.0 0.750 850.0 731.0 5.00 48.00 +IB0154 PIO 3192 . IB0001 215.0 0.300 990.0 660.0 8.50 48.00 +IB0155 DEA . IB0001 165.0 0.100 476.0 442.0 5.35 40.00 + +IB1052 DK 611 . IB0001 260.0 0.100 800.0 980.0 5.70 48.00 + +!Brazil cultivars: +IB0171 AG9010 . IB0001 196.0 0.500 758.0 830.0 5.10 40.00 +IB0172 DAS CO32 . IB0001 220.0 0.500 747.8 1100. 5.40 45.00 +IB0173 DKB 333B . IB0001 250.0 0.500 842.0 920.0 4.80 45.00 +IB0174 EXCELER . IB0001 210.0 0.500 770.0 1170. 5.80 45.00 + +IB0185 JACKSON HYBRI . IB0001 200.0 0.300 950.0 980.0 7.15 43.00 + +IB1065 PIO 33Y09 . IB0001 245.0 0.500 905.0 780.0 6.00 48.00 +IB1066 PIO 3489 . IB0001 225.0 0.600 895.0 875.0 8.80 48.00 +IB1067 PIO 3394 . IB0001 240.0 0.500 900.0 820.0 8.50 48.00 +IB1069 PIO 3563 . IB0001 216.0 0.600 830.0 860.0 8.80 48.00 +IB1072 DEKALB 485 . IB0001 215.0 0.600 785.0 750.0 8.70 45.00 +IB1068 DEKALB 521 . IB0001 215.0 0.400 795.0 890.0 8.00 48.00 +IB1168 DEKALB 591 . IB0001 225.0 0.400 895.0 880.0 8.00 48.00 + +LL0499 C/LOL 499 . IB0001 182.0 0.500 650.0 750.0 8.70 46.00 +LL0564 C/LOL 564 . IB0001 210.0 0.500 670.0 880.0 11.25 46.00 +LL0581 C/LOL 581 . IB0001 200.0 0.500 668.0 850.0 8.80 45.00 +LL0599 C/LOL 599 . IB0001 200.0 0.500 670.0 850.0 8.80 45.00 +LL0542 C/LOL 542 . IB0001 185.0 0.500 700.0 835.0 8.70 46.00 +LL0661 C/LOL 661 . IB0001 200.0 0.500 670.0 850.0 9.00 45.00 +LL0674 C/LOL 674 . IB0001 200.0 0.500 670.0 800.0 8.90 45.00 + +ZA0001 Prisma (FAO 700) . IB0001 280.0 0.400 850.0 750.0 6.80 38.90 +ZA0002 Prisma GC Avg . IB0001 280.0 0.300 789.0 700.0 6.05 48.00 + +IF0001 OBA SUPER 2 . IB0001 270.0 0.600 780.0 840.0 7.80 45.00 +IF0002 EV8728-SR . IB0001 265.0 0.600 800.0 900.0 7.20 45.00 +IF0003 Mokwa 87TZPB-SR . IB0001 305.0 0.600 765.0 810.0 8.00 45.00 +IF0004 SPL (semi-prol) . IB0001 270.0 0.600 740.0 920.0 7.40 41.00 +IF0005 TZB-SR (open p) . IB0001 290.0 0.600 775.0 990.0 6.80 45.00 +IF0006 EV 8449-SR . IB0001 385.0 0.600 860.0 700.0 8.00 50.00 +IF0007 EV 8449-SRx . IB0001 385.0 0.600 860.0 945.4 7.20 50.00 +IF0008 AG-KADUNA . IB0001 220.0 0.600 780.0 845.0 8.00 40.00 +IF0009 OBA S2 Benin . IB0001 170.0 0.600 760.0 800.0 8.00 50.00 +IF0010 EV-8449_TG . IB0001 260.0 0.600 630.0 900.0 9.00 45.00 +IF0011 EV-8443_TG . IB0001 300.0 0.600 850.0 850.0 8.80 45.00 + +AC0001 TOHONO O'odham . IB0001 200.0 0.100 610.0 248.0 9.80 38.90 !Michael Pool, Austin Comm College + +! Vietnam sequencing +VI0001 LVN 10 . IB0001 350.0 1.000 980.0 760.0 9.20 38.90 + +!Coefficients calibrated by Jones and Boote in Mali +IM0001 SOTUBAKA . IB0001 300.0 0.520 930.0 500.0 6.00 38.90 +IM0002 NIELENI . IB0001 232.0 0.300 688.0 540.0 8.80 38.90 +IM0003 APPOLO . IB0001 216.0 0.300 530.0 455.0 11.00 38.90 + +!Coefficients calibrated by Dzotsi and Singh in Togo, 2002. +IF0018 TZE C0MP4C2 . IB0001 210.0 0.100 660.0 850.0 9.70 55.00 +IF0019 TZESRW X GUA 314 . IB0001 170.0 0.100 660.0 780.0 8.00 55.00 +IF0020 AB-11-TG . IB0001 250.0 0.100 620.0 920.0 8.50 55.00 +IF0021 TZEEY-SRBC5 . IB0001 130.0 0.100 600.0 850.0 8.00 55.00 +IF0022 IKENNE . IB0001 280.0 0.600 630.0 900.0 8.80 45.00 + +!Alagarswamy +IB0067 TEST . IB0001 130.0 0.500 720.0 380.0 7.50 75.00 +KA0001 H625 . IB0001 130.0 0.500 720.0 380.0 7.50 75.00 +EM0001 H512 . IB0001 130.0 0.500 720 0 550.0 7.50 75.00 +KY0001 H622 . IB0001 358.5 0.500 616.1 550.0 7.20 75.00 +KY0002 H511 . IB0001 317.6 0.500 530.4 550.0 7.50 75.00 +KY0003 CCOMP . IB0001 366.2 1.235 611.3 600.0 6.50 75.00 +KY0004 MAKUCOMP . IB0001 183.6 0.500 611.0 380.0 10.00 75.00 +KY0005 H625 . IB0001 341.1 0.500 612.0 700.0 8.50 75.00 +KY0006 KCB . IB0001 125.0 0.500 500.3 450.0 10.50 75.00 +KY0007 PWANI . IB0001 182.4 0.500 616.0 720.0 10.50 75.00 +KY0008 H613 . IB0001 182.4 0.500 616.0 825.0 10.15 75.00 +KY0009 CUZCO . IB0001 182.4 0.500 616.0 380.0 7.50 75.00 +KY0010 H512 . IB0001 332.9 0.500 601.6 550.0 7.50 75.00 +KY0011 H614 . IB0001 396.9 0.500 623.6 825.0 10.15 75.00 +KY0012 H5012 . IB0001 351.7 0.500 859.0 550.0 7.50 75.00 +KY0013 H626 . IB0001 458.0 0.500 429.0 450.0 10.50 75.00 +KY0014 KATUMANICOMPI . IB0001 238.6 0.500 654.0 450.0 10.50 75.00 +KY0015 PH 1 . IB0001 234.5 0.500 429.0 720.0 10.50 75.00 +KY0016 HAC . IB0001 245.0 0.500 825.0 750.0 10.50 75.00 +KY0017 H612 . IB0001 130.0 0.500 390.0 825.0 10.15 75.00 +KY0018 KATUMANICOMP-II . IB0001 125.0 0.500 660.0 450.0 10.50 75.00 + +!J.B.Naab data 2003-2006, re-calibrated by kjb 1/2/12 +GH0010 OBATAMPA . IB0001 280.0 0.000 750.0 540.0 7.50 40.00 + +!Four Global Futures maize cultivars (3 life cycle by 2 "yield levels") +!Composite: same maturity as Garst 8808 and WH403), but G2 and G3 mid-way. +!Those cultivars seemed most realistic compared with 5 other cultivars calibrated +!in DSSAT, not too early (Pio3382 too early), not too late (Pio 304C is late), +!not too high in yield(McCurdy 84aa not realistic), DK611 strange, and +!Obatanpa is low yielding (fertility constraints, or OPV) +!Yield "trait" is 5% higher RUE, 5% higher G2, 5% higher G3 + +GF0001 Base Garst808-wh403 . IB0001 250.0 0.500 730.0 800.0 7.80 38.90 +GF0101 Baseline 10%shorter . IB0001 215.0 0.500 650.0 800.0 7.80 38.90 +GF0201 Baseline 10%longer . IB0001 285.0 0.500 810.0 800.0 7.80 38.90 +GF0301 Yield norm cycle . IB0004 250.0 0.500 730.0 840.0 8.19 38.90 +GF0401 Yield 10%shorter . IB0004 215.0 0.500 650.0 840.0 8.19 38.90 +GF0501 Yield 10%longer . IB0004 285.0 0.500 810.0 840.0 8.19 38.90 + +CYMA01 wh403 . IB0001 265.0 0.760 685.0 760.0 7.60 38.90 + +! Added by Camilo Andrade from Embrapa Maize and Sorghum +EBSL06 BRS1030-SL2009 . IB0001 263.8 0.500 1034 700.0 5.20 44.22 !Single-cross hybrid from Embrapa diff --git a/lib/maize/MZCER047.ECO b/lib/maize/MZCER047.ECO new file mode 100644 index 0000000000000000000000000000000000000000..dbbf9654cfd4dedc5e59a1f6743809a8b085ef87 --- /dev/null +++ b/lib/maize/MZCER047.ECO @@ -0,0 +1,29 @@ +*MAIZE ECOTYPE COEFFICIENTS: MZCER047 MODEL +! +! COEFF DEFINITIONS +! ===== =========== +! ECO# Code for the ecotype to which a cultivar belongs (see *.cul +! file) +! ECONAME Name of the ecotype, which is referenced from *.CUL file +! TBASE Base temperature below which no development occurs, C +! TOPT Temperature at which maximum development rate occurs during vegetative stages, C +! ROPT Temperature at which maximum development rate occurs for reproductive stages, C +! P2O Daylength below which daylength does not affect development rate, hours +! DJTI Minimum days from end of juvenile stage to tassel initiation if the cultivar +! is not photoperiod sensitive, days +! GDDE Growing degree days per cm seed depth required for emergence, GDD/cm +! DSGFT GDD from silking to effective grain filling period, C +! RUE Radiation use efficiency, g plant dry matter/MJ PAR +! KCAN Canopy light extinction coefficient for daily PAR. +! TSEN Critical temperature below which leaf damage occurs (default 6°C) +! CDAY Number of cold days parameter (default 15.0 ) +@ECO# ECONAME......... TBASE TOPT ROPT P20 DJTI GDDE DSGFT RUE KCAN TSEN CDAY +! 1 2 3 4 5 6 7 8 9 10 11 +IB0001 GENERIC MIDWEST1 8.0 34.0 34.0 12.5 4.0 6.0 170. 4.2 0.85 +IB0002 GENERIC MIDWEST2 8.0 34.0 34.0 12.5 4.0 6.0 170. 4.5 0.85 +IB0003 GENERIC MIDWEST3 8.0 34.0 34.0 12.5 4.0 6.0 170. 2.0 0.85 +IB0004 +5% RUE MIDWEST1 8.0 34.0 34.0 12.5 4.0 6.0 170. 4.4 0.85 +DFAULT DEFAULT 8.0 34.0 34.0 12.5 4.0 6.0 170. 4.2 0.85 + + + diff --git a/lib/maize/MZCER047.SPE b/lib/maize/MZCER047.SPE new file mode 100644 index 0000000000000000000000000000000000000000..373ae0d691b7d8b3d05a0865998730c31f7f1da5 --- /dev/null +++ b/lib/maize/MZCER047.SPE @@ -0,0 +1,87 @@ +*MAIZE SPECIES COEFFICIENTS: MZCER047 MODEL + +*TEMPERATURE EFFECTS +! TBASE TOP1 TOP2 TMAX + PRFTC 6.2 16.5 33.0 44.0 !Effect of temperature on photosynthesis +! RGFIL 5.5 16.0 29.0 37.0 !Effect of temperature on relative grain filling rate (tolerant) + RGFIL 5.5 16.0 27.0 35.0 !Effect of temperature on relative grain filling rate (suscept) + +*PHOTOSYNTHESIS PARAMETERS + PARSR 0.50 !Conversion of solar radiation to PAR + CO2X 0 220 280 330 400 490 570 750 990 9999 + CO2Y 0.00 0.85 0.95 1.00 1.02 1.04 1.05 1.06 1.07 1.08 + +*STRESS RESPONSE + FSLFW 0.050 !Fraction of leaf area senesced under 100% water stress, 1/day + FSLFN 0.050 !Fraction of leaf area senesced under 100% nitrogen stress, 1/day + FSLFP 0.050 !Fraction of leaf area senesced under 100% phosphorus stress, 1/day + +*SEED GROWTH PARAMETERS + SDSZ .2750 !Maximum potential seed size, mg/sd + RSGR 0.1 !Relative seed growth rate below which plant may mature early + RSGRT 5.0 !Number of consecutive days relative seed growth rate is below RSGR that triggers early maturity + CARBOT 7.0 !Number of consecutive days CARBO is less than .001 before plant matures due to temperature, water or nitrogen stress + DSGT 21.0 !Maximum days from sowing to germination before seed dies. + DGET 150.0 !Growing degree days between germination and emergence after which the seed dies due to drought + SWCG 0.02 !Minimimum available soil water required for seed germination, cm3/cm3 + +*EMERGENCE INITIAL CONDITIONS + STMWTE 0.20 !Stem weight at emergence, g/plant + RTWTE 0.20 !Root weight at emergence, g/plant + LFWTE 0.20 !Leaf weight at emergence, g/plant + SEEDRVE 0.20 !Carbohydrate reserve in seed at emergence, g/plant + LEAFNOE 1.0 !Leaf number at emergence, #/plant + PLAE 1.0 !Leaf area at emergence, cm2/plant + +*NITROGEN PARAMETERS + TMNC 0.00450 !Plant top minimum N concentration g N/g dry matter (orig) + TANCE 0.0440 !Nitrogen content in above ground biomass at emergence, g N/g dry matter + RCNP 0.01060 !Root critical nitrogen concentration, g N/g root dry weight + RANCE 0.0220 !Root N content at emergence g N/g root + CTCNP1 1.52 !Maximum value for critical tissue N concentration (in developing seed embryo) + CTCNP2 0.160 !Coefficent for change in conc. with growth stage + +*ROOT PARAMETERS + PORM 0.05 !Minimum volume required for supplying oxygen to roots for optimum growth (1-1.0) + RWMX 0.03 !Not used in ceres, but passed through AltPlant for use elsewhere + RLWR 0.98 !Root length to weight ratio (cm/g * 1E-4) + RWUEP1 1.50 + +*PLANT COMPOSITION VALUES + PLIGLF 0.070 !Leaf lignin fraction + PLIGST 0.070 !Stem lignin fraction + PLIGRT 0.070 !Root lignin fraction + PLIGSH 0.280 !Shell lignin fraction + PLIGSD 0.020 !Seed lignin fraction + +*PHOSPHORUS CONTENT (g [P]/g [shoot]) + 0.0070 0.0025 0.0020 Optimum Shoot Conc (emerg, End L. Growth, p. mat) + -99.0 -99.0 -99.0 Optimum Leaf Conc ( " " " ) + -99.0 -99.0 -99.0 Optimum Stem Conc ( " " " ) + .00041 .00041 .00041 Optimum Root Conc ( " " " ) + 0.0050 0.0050 0.0005 Optimum Shell Conc ( " " " ) + 0.0035 0.0035 0.0035 Optimum Seed Conc ( " " " ) + + 0.0040 0.0015 0.0010 Minimum Shoot Conc (emerg, End L. Growth, p. mat) + -99.0 -99.0 -99.0 Minimum Leaf Conc ( " " " ) + -99.0 -99.0 -99.0 Minimum Stem Conc ( " " " ) + .00020 .00020 .00020 Minimum Root Conc ( " " " ) + 0.0025 0.0025 .00025 Minimum Shell Conc ( " " " ) + .00175 .00175 .00175 Minimum Seed Conc ( " " " ) + + 25.0 15.0 9.3 Maximum Veg N:P ratio (emergence, eff. grain fill, phys. mat) + 4.2 2.7 2.1 Minimum Veg N:P ratio (emergence, eff. grain fill, phys. mat) + + 0.80 1.00 SRATPHOTO, SRATPART + 0.10 FracPMobil - max fraction of P which can be mobilized from leaf & stem / day + 0.0028 ROOTRAD - radius of cylinder around roots from which soil P can be extracted (m) + +!At emergence and end of leaf growth: +!Optimum shoot P concentration (%) = 0.684 - 0.108X (Jones, 1983) +!At physiological maturity: +!Optimum shoot P concentration (%) = 0.238 - 0.0056X (Jones, 1983) +!Where: +!X is the growth stage. +!Emergence was defined as growth stage 0 (X = 0), end of leaf growth as growth stage 4, and +!physiological maturity as growth stage 10 (Jones, 1983). Minimum shoot P concentration was +!taken as 60% of the estimated optimum (Daroub et al., 2003). diff --git a/lib/maize/execute.py b/lib/maize/execute.py new file mode 100644 index 0000000000000000000000000000000000000000..11d91ebfeddd5f30aa21c13a4474891a562dfe7e --- /dev/null +++ b/lib/maize/execute.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python +from datetime import datetime, timedelta +from collections import defaultdict +import numpy as np +import mz, json, argparse + + +# def generate_DSSAT_config(var_num, var_name, eco_num, p1, p2, p5, g2, g3, phint): + + +#! DAYL Day length on day of simulation (from sunrise to sunset) (hr) +#! DLAYR(L) Soil thickness in layer L (cm) +#! LEAFNO Number of oldest leaf per plant +#! LL(NL) Soil water lower limit, cm3/cm3 +#! NLAYR Number of soil layers +#! PLTPOP Plant population, no./m2 +#! SDEPTH Sowing depth, cm +#! SI1(6) Water stress during a growth stage used for output +#! SI3(6) Water stress during a growth stage used for output +#! SNOW = Snow depth, mm +#! SRAD Daily solar radiation, MJ/m2/day +#! SUMP Cumulative plant growth during ISTAGE 4, g/plant +#! SW(NL) Soil water content in layer, cm3/cm3 +#! TMAX Daily maximum temperature, C +#! TMIN Daily minimum temperature, C +#! TWILEN Twilight definition of daylength +#! XN Number of oldest expanding leaf +#! YRDOY Year and day of year +#! YRSIM Year and day of year of first day of simulation + +def execute(config, json_parameter_file, output_csv_name): + refyear = "2021" + with open(json_parameter_file) as f: + params = json.load(f) + + plantdate = int(params["plantdate"]) + tmins = params["tmins"] + tmaxs = params["tmaxs"] + srads = params["srads"] + rains = params["rains"] + + freedom_units = params["units"] == "F" + + ##INIT + DAYL = 12. + DLAYR = 10. + LEAFNO = 20. + LL = 0.3 + NLAYR = 1. + PLTPOP = 5 + SDEPTH = 10. + SNOW = 0 + SUMP = 0 # we should use the plant growth value replace it + SW =2. + TWILEN =10 + TWILEN =8 + XN =20 + YRSIM = int(f"{refyear}001") + # output + EARS=0 + GPP=0 + ISDATE=0 + MDATE=0 + DTT = np.zeros(1) + CUMDTT = np.zeros(1) + SUMDTT = np.zeros(1) + P3 = np.zeros(1) + STGDOY = np.zeros(20,dtype=np.int32) + ISTAGE = np.zeros(1, dtype=np.int32) + ISTAGE[0] = 7 # begin with 7 + YREMRG = np.zeros(1, dtype=np.int32) + CDAY = np.zeros(1, dtype=np.int32) + + XNTI=0 + TLNO=0 + XSTAGE=0 + RUE=0 + KCAN=0 + KEP=0 + TSEN=0 + CDAY=0 + SeedFrac=0 + VegFrac=0 + + gdd=0 + + INIT = True + yrdoy = 1 + df_out = defaultdict(list) + + for tmin, tmax, srad, rain in zip(tmins, tmaxs, srads, rains): + doy = yrdoy + yrdoy += 1 + if doy<plantdate: + continue + if INIT: + dynamic = 1 + INIT = False + else: + dynamic = -1 + + YRDOY = f"{str(refyear)[-2:]}{str(yrdoy).rjust(3, '0')}" + SRAD = float(srad) + TMAX = float(tmax) + TMIN = float(tmin) + RAIN = float(rain) + + if freedom_units: + TMAX = (TMAX - 32) * (5/9) + TMIN = (TMIN - 32) * (5/9) + + + mz.mz_phenol(config, dynamic, # !C + DAYL,DLAYR,LEAFNO,LL,NLAYR, # !I + SNOW, SRAD,SUMP,SW,TMAX,TMIN, TWILEN, # !I + XN,YRDOY,YRSIM, # !I + CUMDTT,DTT,EARS,GPP,ISDATE, ISTAGE,MDATE,STGDOY,SUMDTT,# !O + XNTI,TLNO,XSTAGE,YREMRG,RUE,KCAN,KEP, P3, TSEN, CDAY, # !O + SeedFrac, VegFrac) + # !O + YRDOY = f"{refyear}{doy:03d}" + + df_out["DTT"].append(DTT[0]) + gdd = gdd+DTT[0] + df_out["GDD"].append(gdd) + df_out["SUMDTT"].append(SUMDTT[0]) + df_out["ISTAGE"].append(ISTAGE[0]) + df_out["YRDOY"].append(YRDOY) + + # df_out = pd.DataFrame.from_dict(df_out) + # df_out.set_index("YRDOY").to_csv(output_csv_name) + +def get_predicted_harvest(config, json_parameter_file): + refyear = "2021" + with open(json_parameter_file) as f: + params = json.load(f) + + plantdate = int(params["plant_date"]) + tmins = params["tmins"] + tmaxs = params["tmaxs"] + srads = params["srads"] + # rains = params["rains"] + + freedom_units = params["units"] == "F" + + ##INIT + DAYL = 12. + DLAYR = 10. + LEAFNO = 20. + LL = 0.3 + NLAYR = 1. + PLTPOP = 5 + SDEPTH = 10. + SNOW = 0 + SUMP = 0 # we should use the plant growth value replace it + SW =2. + TWILEN =10 + TWILEN =8 + XN =20 + YRSIM = int(f"{refyear}001") + # output + EARS=0 + GPP=0 + ISDATE=0 + MDATE=0 + DTT = np.zeros(1) + CUMDTT = np.zeros(1) + SUMDTT = np.zeros(1) + P3 = np.zeros(1) + STGDOY = np.zeros(20,dtype=np.int32) + ISTAGE = np.zeros(1, dtype=np.int32) + ISTAGE[0] = 7 # begin with 7 + YREMRG = np.zeros(1, dtype=np.int32) + CDAY = np.zeros(1, dtype=np.int32) + + XNTI=0 + TLNO=0 + XSTAGE=0 + RUE=0 + KCAN=0 + KEP=0 + TSEN=0 + CDAY=0 + SeedFrac=0 + VegFrac=0 + + gdd=0 + + INIT = True + yrdoy = 1 + df_out = defaultdict(list) + + for tmin, tmax, srad in zip(tmins, tmaxs, srads): + doy = yrdoy + yrdoy += 1 + if doy<plantdate: + continue + if INIT: + dynamic = 1 + INIT = False + else: + dynamic = -1 + + YRDOY = f"{str(refyear)[-2:]}{str(yrdoy).rjust(3, '0')}" + SRAD = float(srad) + TMAX = float(tmax) + TMIN = float(tmin) + # RAIN = float(rain) + + if freedom_units: + TMAX = (TMAX - 32) * (5/9) + TMIN = (TMIN - 32) * (5/9) + + + mz.mz_phenol(config, dynamic, # !C + DAYL,DLAYR,LEAFNO,LL,NLAYR, # !I + SNOW, SRAD,SUMP,SW,TMAX,TMIN, TWILEN, # !I + XN,YRDOY,YRSIM, # !I + CUMDTT,DTT,EARS,GPP,ISDATE, ISTAGE,MDATE,STGDOY,SUMDTT,# !O + XNTI,TLNO,XSTAGE,YREMRG,RUE,KCAN,KEP, P3, TSEN, CDAY, # !O + SeedFrac, VegFrac) + # !O + YRDOY = f"{refyear}{doy:03d}" + + if ISTAGE[0] == 6: + return YRDOY + + return -1 + + +# execute("test.json", "data.csv") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('--config', help='DSSAT config file') + parser.add_argument('--input', help='input json file') + parser.add_argument('--output', help='output csv file') + parser.add_argument('--predicted', action='store_true') + args = parser.parse_args() + if args.predicted: + print (get_predicted_harvest(int(args.config), args.input)) + else: + execute(int(args.config), args.input, args.output) \ No newline at end of file diff --git a/lib/maize/mz.cpython-38-x86_64-linux-gnu.so b/lib/maize/mz.cpython-38-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..6a4349edb938551a0e701aea2d0622ab1739e350 Binary files /dev/null and b/lib/maize/mz.cpython-38-x86_64-linux-gnu.so differ diff --git a/lib/maize/mz.f b/lib/maize/mz.f new file mode 100644 index 0000000000000000000000000000000000000000..f4e392224eba2f7a0fbae5f8975a254651274d0d --- /dev/null +++ b/lib/maize/mz.f @@ -0,0 +1,1209 @@ +!====================================================================== +! MZ_PHENOL, Subroutine +! +! Determines Phenological Stage and Growing Degree Days for Maize +!---------------------------------------------------------------------- +! Revision history +! +! Written +! 02/07/1993 PWW Header revision and minor changes +! 02/07/1993 PWW Added switch block, code cleanup +! 02/07/1993 PWW Modified TT calculations to reduce line #'s +! 05/ /1994 WTB Modified for MILLET model +! 03/29/2001 WDB Converted to modular format +! 12/01/2001 WDB Major restructuring for 2002 release +! 06/11/2002 GH Modified for Y2K +! 08/12/2003 CHP Added I/O error checking +! 10/12/2005 CHP/JIL Added optional temperature sensitivity parameter +! to ecotype file (TSEN) +! 07/13/2006 CHP Added P model +!---------------------------------------------------------------------- + +! DAYL Day length on day of simulation (from sunrise to sunset) (hr) +! DLAYR(L) Soil thickness in layer L (cm) +! LEAFNO Number of oldest leaf per plant +! LL(NL) Soil water lower limit, cm3/cm3 +! NLAYR Number of soil layers +! PLTPOP Plant population, no./m2 +! SDEPTH Sowing depth, cm +! SI1(6) Water stress during a growth stage used for output +! SI3(6) Water stress during a growth stage used for output +! SNOW = Snow depth, mm +! SRAD Daily solar radiation, MJ/m2/day +! SUMP Cumulative plant growth during ISTAGE 4, g/plant +! SW(NL) Soil water content in layer, cm3/cm3 +! TMAX Daily maximum temperature, C +! TMIN Daily minimum temperature, C +! TWILEN Twilight definition of daylength +! XN Number of oldest expanding leaf +! YRDOY Year and day of year +! YRSIM Year and day of year of first day of simulation + + CHARACTER*1 FUNCTION UPCASE (INCHAR) + + IMPLICIT NONE + + CHARACTER INCHAR*1 + INTEGER CHAVAL + + CHAVAL = ICHAR(INCHAR) + + IF ((CHAVAL .LE. 122) .AND. (CHAVAL .GE. 97)) THEN + UPCASE = CHAR(CHAVAL-32) + ELSE + UPCASE = INCHAR + ENDIF + + END FUNCTION UPCASE + + + + + SUBROUTINE IGNORE(LUN,LINEXP,ISECT,CHARTEST) + + CHARACTER BLANK*(80),CHARTEST*(*) + INTEGER LENGTH, LUN,LINEXP,ISECT + DATA BLANK/' '/ + + LENGTH = LEN(CHARTEST) + + ISECT = 1 + 30 READ(LUN,'(A)',ERR=70, END=70)CHARTEST + LINEXP = LINEXP + 1 + +! CHP 5/1/08 + IF (CHARTEST(1:1) == CHAR(26)) THEN + GO TO 70 + ENDIF + +C Check to see if all of this section has been read + IF(CHARTEST(1:1) .EQ. '*' .OR. CHARTEST(1:1) .EQ. '$') THEN +C End of section encountered + ISECT = 2 + RETURN + ENDIF +C +C Check for blank lines and comments (denoted by ! in column 1) + IF(CHARTEST(1:1).NE.'!' .AND. CHARTEST(1:1).NE.'@') THEN +! IF(CHARTEST(1:80).NE.BLANK)THEN + IF(CHARTEST(1:LENGTH).NE.BLANK)THEN +C FOUND A GOOD LINE TO READ + RETURN + ENDIF + ENDIF + + GO TO 30 +C To read the next line + + 70 ISECT = 0 + RETURN + END SUBROUTINE IGNORE + + + SUBROUTINE FIND(LUNUM,NAME,LNUM,FOUND) + + IMPLICIT NONE + INTEGER FOUND,I,LNUM,LUNUM + CHARACTER SECTION*6,NAME*6,UPCASE*1 +C +C Initialization. +C + FOUND = 0 + LNUM = 1 + DO I = 1, LEN(NAME) + NAME(I:I) = UPCASE(NAME(I:I)) + END DO +C +C Loop to read through data file. +C + 10 IF (.TRUE.) THEN + READ(LUNUM,'(A)',END=20) SECTION + DO I = 1,LEN(SECTION) + SECTION(I:I) = UPCASE(SECTION(I:I)) + END DO +C +C String found, set FOUND to 1, and exit loop. +C + IF (NAME .EQ. SECTION) then + FOUND = 1 + GOTO 20 +C +C String not found, set FOUND to 0. +C + ELSE + FOUND = 0 + ENDIF + + LNUM = LNUM + 1 + GOTO 10 + ENDIF + + 20 RETURN + END + + + SUBROUTINE MZ_PHENOL(FILEID, DYNAMIC, + & DAYL,DLAYR,LEAFNO,LL,NLAYR, + & SNOW, SRAD,SUMP,SW,TMAX,TMIN, TWILEN, + & XN,YRDOY,YRSIM, + & CUMDTT,DTT,EARS,GPP,ISDATE, ISTAGE,MDATE,STGDOY,SUMDTT, + & XNTI,TLNO,XSTAGE,YREMRG,RUE,KCAN,KEP, P3, TSEN, CDAY, + & SeedFrac, VegFrac) + + !USE ModuleDefs + IMPLICIT NONE + SAVE + INTEGER,PARAMETER :: NL=1 + CHARACTER*1,PARAMETER :: ISWWAT ="Y" + CHARACTER*30 :: FILEIO + CHARACTER*1,PARAMETER :: IDETO ="Y" + REAL,PARAMETER:: SI1(6) = (/0.1,0.1,0.1,0.1,0.1,0.1/) + REAL,PARAMETER:: SI3(6) = (/0.1,0.1,0.1,0.1,0.1,0.1/) +!---------------------------------------------------------------------- +! Define Variables +!---------------------------------------------------------------------- + INTEGER DYNAMIC + +! REAL ABSTRES + REAL ACOEF + REAL BARFAC + CHARACTER*1 BLANK + REAL C1 + REAL CUMDEP + REAL,intent(inout) :: P3 +Cf2py intent(inout) P3 + REAL,intent(inout) :: DTT +Cf2py intent(inout) DTT + REAL,intent(inout) :: CUMDTT +Cf2py intent(inout) CUMDTT + REAL,intent(inout) :: SUMDTT +Cf2py intent(inout) SUMDTT + INTEGER,intent(inout):: ISTAGE +Cf2py intent(inout) ISTAGE + INTEGER,intent(inout):: YREMRG +Cf2py intent(inout) YREMRG + INTEGER,intent(inout):: STGDOY(20) +Cf2py intent(inout) STGDOY + INTEGER,intent(inout):: CDAY +Cf2py intent(inout) CDAY + REAL DAYL + REAL DEC + REAL DGET + REAL DJTI + REAL DLAYR(NL) + REAL DLV + REAL DOPT + REAL DSGT + REAL DSGFT + REAL DUMMY + REAL EARS + CHARACTER*6 ECONO + INTEGER ERR + CHARACTER*6 ERRKEY + PARAMETER (ERRKEY='MZPHEN') + INTEGER ERRNUM + CHARACTER*12 FILEC + CHARACTER*12 FILES + CHARACTER*12 FILEE + INTEGER FILEID + CHARACTER*92 FILEGC + INTEGER FOUND + REAL G2 + REAL G3 + REAL GDDE + REAL GPP + INTEGER I + INTEGER IDURP + REAL KCAN + REAL KEP + INTEGER LEAFNO + INTEGER L + INTEGER L0 + INTEGER LINC + REAL LL(NL) + INTEGER LNUM + INTEGER LUNIO + INTEGER MDATE + INTEGER NDAS + INTEGER NLAYR + INTEGER NOUTDO + REAL P1 + REAL P2 + REAL P2O + REAL P5 + REAL P9 + CHARACTER*80 PATHCR + CHARACTER*80 PATHSR + CHARACTER*80 PATHER + REAL PDTT + REAL PHINT + REAL PLTPOP + REAL PSKER + REAL RATEIN + REAL ROPT + REAL RUE + REAL SDEPTH + CHARACTER*6 SECTION + REAL S1 + REAL SIND + REAL SNDN + REAL SNOW + REAL SNUP + REAL SRAD + REAL SUMDTT_2 !introduced for plant P routine + REAL SUMP + REAL SW(NL) + REAL SWCG + REAL SWSD + REAL TBASE + REAL TDSOIL + REAL TEMPCN + + REAL TEMPCR + REAL TEMPCX + REAL TH + REAL TLNO + REAL TMAX + REAL TMIN + REAL TMSOIL + REAL TNSOIL + REAL TOPT + REAL TSEN !10/12/2005 chp + REAL TWILEN + CHARACTER*6 VARNO + CHARACTER*16 VRNAME + REAL XN + REAL XNTI + REAL XS + REAL XSTAGE + INTEGER YRDOY + INTEGER YRSIM + INTEGER ISDATE + + INTEGER PATHL + PARAMETER (BLANK = ' ') + INTEGER LUNECO + + CHARACTER*6 ECOTYP + INTEGER ISECT + CHARACTER*255 C255 + CHARACTER*16 ECONAM + INTEGER LUNCRP + CHARACTER*92 FILECC + CHARACTER*80 C80 + CHARACTER*78 MESSAGE(10) + +! CHP added for P model + REAL SeedFrac, VegFrac + + INTEGER,PARAMETER :: RUNINIT=1 + WRITE (FILEIO, "(A5, I2,A4)") "DSSAT", FILEID, ".INP" +!---------------------------------------------------------------------- +! DYNAMIC = RUNINIT OR DYNAMIC = SEASINIT +! --------------------------------------------------------------------- +! IF (DYNAMIC.EQ.RUNINIT .OR. DYNAMIC.EQ.SEASINIT) THEN + IF (DYNAMIC.EQ.RUNINIT ) THEN + +! Do this just once in RUNINIT + IF (DYNAMIC .EQ. RUNINIT) THEN + !CALL GETLUN('OUTO', NOUTDO) + NOUTDO = 20 + + !------------------------------------------------------- + ! Read input file name (ie. DSSAT45.INP) and path + !------------------------------------------------------- + !CALL GETLUN('FILEIO', LUNIO) + LUNIO = 21 + + OPEN (LUNIO, FILE = FILEIO,STATUS = 'OLD',IOSTAT=ERR) + IF (ERR .NE. 0) THEN !CALL ERROR(ERRKEY,ERR,FILEIO,0) + print*,"A5" + STOP + endif + + READ(LUNIO,50,IOSTAT=ERR) FILES, PATHSR; LNUM = 7 + 50 FORMAT(//////,15X,A12,1X,A80) + IF (ERR .NE. 0) THEN !CALL ERROR(ERRKEY,ERR,FILEIO,LNUM) + print*,"A2" + STOP + endif + + READ(LUNIO,51,IOSTAT=ERR) FILEE, PATHER; LNUM = LNUM + 1 + IF (ERR .NE. 0) then !CALL ERROR(ERRKEY,ERR,FILEIO,LNUM) + print*,"A3" + STOP + endif + 51 FORMAT(15X,A12,1X,A80) + + READ(LUNIO,51,IOSTAT=ERR) FILEC, PATHCR; LNUM = LNUM + 1 + IF (ERR .NE. 0) THEN !CALL ERROR(ERRKEY,ERR,FILEIO,LNUM) + print*,"A4" + STOP + endif + + !------------------------------------------------------ + ! Read Planting Details Section + !------------------------------------------------------ + SECTION = '*PLANT' + CALL FIND(LUNIO, SECTION, LINC, FOUND) ; LNUM = LNUM + LINC + IF (FOUND .EQ. 0) THEN + !CALL ERROR(SECTION, 42, FILEIO, LNUM) + print*,"A2" + STOP + ELSE +! READ(LUNIO,60,IOSTAT=ERR) PLTPOP,SDEPTH + READ(LUNIO,60,IOSTAT=ERR) YREMRG,PLTPOP,SDEPTH + LNUM = LNUM + 1 +! 60 FORMAT(25X,F5.2,25X,F5.2) + 60 FORMAT(11X,I7,7X,F5.2,25X,F5.2) + IF (ERR .NE. 0) THEN!CALL ERROR(ERRKEY,ERR,FILEIO,LNUM) + print*,"A3" + STOP + endif + ENDIF +! ----------------------------------------------------------------- +! Read crop cultivar coefficients +! ----------------------------------------------------------------- + SECTION = '*CULTI' + CALL FIND(LUNIO, SECTION, LINC, FOUND) ; LNUM = LNUM + LINC + IF (FOUND .EQ. 0) THEN + !CALL ERROR(SECTION, 42, FILEIO, LNUM) + print*,"A5" + STOP + ELSE + READ (LUNIO,1800,IOSTAT=ERR) VARNO,VRNAME,ECONO, + % P1,P2,P5,G2,G3,PHINT ; LNUM = LNUM + 1 + IF (ERR .NE. 0) THEN !CALL ERROR(ERRKEY,ERR,FILEIO,LNUM) + print*,"A5" + STOP + endif +1800 FORMAT (A6,1X,A16,1X,A6,1X,6F6.0) + ENDIF + CLOSE(LUNIO) + +! ----------------------------------------------------------------- +! Read Species Coefficients +! ----------------------------------------------------------------- + + FILECC = TRIM(PATHSR) // FILES + !FILECC = "COGRO047.SPE" + !CALL GETLUN('FILEC', LUNCRP) + LUNCRP = 16 + OPEN (LUNCRP,FILE = FILECC, STATUS = 'OLD',IOSTAT=ERR) + IF (ERR .NE. 0) THEN!CALL ERROR(ERRKEY,ERR,FILECC,0) + print*,"A6" + STOP + endif + +! ---------------------------------------------------------------- +! Find and Read TEMPERATURE Section +! ---------------------------------------------------------------- + + SECTION = '*SEED ' + CALL FIND(LUNCRP, SECTION, LNUM, FOUND) + IF (FOUND .EQ. 0) THEN + !CALL ERROR(SECTION, 42, FILECC, LNUM) + print*,"b" + stop + ELSE + + CALL IGNORE(LUNCRP,LNUM,ISECT,C80) + CALL IGNORE(LUNCRP,LNUM,ISECT,C80) + CALL IGNORE(LUNCRP,LNUM,ISECT,C80) + CALL IGNORE(LUNCRP,LNUM,ISECT,C80) + CALL IGNORE(LUNCRP,LNUM,ISECT,C80) + READ(C80,'(9X,F7.3)',IOSTAT=ERR) DSGT + IF (ERR .NE. 0) THEN !CALL ERROR(ERRKEY,ERR,FILECC,LNUM) + print*,"A3" + STOP + endif + + CALL IGNORE(LUNCRP,LNUM,ISECT,C80) + READ(C80,'(9X,F7.3)',IOSTAT=ERR) DGET + IF (ERR .NE. 0) THEN!CALL ERROR(ERRKEY,ERR,FILECC,LNUM) + print*,"A3" + STOP + endif + + CALL IGNORE(LUNCRP,LNUM,ISECT,C80) + READ(C80,'(9X,F7.3)',IOSTAT=ERR) SWCG + IF (ERR .NE. 0) THEN !CALL ERROR(ERRKEY,ERR,FILECC,LNUM) + print*,"A3" + STOP + endif + ENDIF + + CLOSE(LUNCRP) + +!----------------------------------------------------------------------- +! Open Ecotype File FILEE +!----------------------------------------------------------------------- + LNUM = 0 + PATHL = INDEX(PATHER,BLANK) + IF (PATHL .LE. 1) THEN + FILEGC = FILEE + ELSE + FILEGC = PATHER(1:(PATHL-1)) // FILEE + ENDIF + +!----------------------------------------------------------------------- +! Read Ecotype Parameter File +!----------------------------------------------------------------------- + !CALL GETLUN('FILEE', LUNECO) + LUNECO = 10 + OPEN (LUNECO,FILE = FILEGC,STATUS = 'OLD',IOSTAT=ERRNUM) + IF (ERRNUM .NE. 0) THEN !CALL ERROR(ERRKEY,ERRNUM,FILEE,0) + print*,"A3" + STOP + endif + + ECOTYP = ' ' + LNUM = 0 + DO WHILE (ECOTYP .NE. ECONO) + CALL IGNORE(LUNECO, LNUM, ISECT, C255) + IF (ISECT .EQ. 1 .AND. C255(1:1) .NE. ' ' .AND. + & C255(1:1) .NE. '*') THEN + READ(C255,3100,IOSTAT=ERRNUM) ECOTYP,ECONAM,TBASE,TOPT, + & ROPT,P2O,DJTI,GDDE,DSGFT,RUE, KCAN +3100 FORMAT (A6,1X,A16,1X,9(1X,F5.1)) + IF (ERRNUM .NE. 0) THEN !CALL ERROR(ERRKEY,ERRNUM,FILEE,LNUM) + print*,"A3" + STOP + endif + + IF (ECOTYP .EQ. ECONO) THEN +! Read optional cold sensitivity paramter. +! Default to TSEN = 6.0 if no value given. + IF (C255(80:84) == ' ') THEN + TSEN = 6.0 + ELSE + READ(C255(80:84),'(F5.0)',IOSTAT=ERRNUM) TSEN + IF (ERRNUM .NE. 0 .OR. TSEN < 1.E-6) TSEN = 6.0 + ENDIF + +! Read optional number of cold days paramter. +! Default to CDAY = 15.0 if no value given. + IF (C255(86:90) == ' ') THEN + CDAY = 15 + ELSE + READ(C255(86:90),'(I5)',IOSTAT=ERRNUM) CDAY + IF (ERRNUM .NE. 0 .OR. CDAY < 0) CDAY = 15 + ENDIF + + EXIT + ENDIF + + ELSEIF (ISECT .EQ. 0) THEN + !CALL ERROR(ERRKEY,7,FILEE,LNUM) + print*,"A3" + STOP + +! CHP 1/4/2004 +! IMPLEMENT THIS SECTION OF CODE WHEN A DEFAULT ECOTYPE HAS BEEN ADDED +! TO THE ECOTYPE FILE. +! IF (ECONO .EQ. 'DFAULT') CALL ERROR(ERRKEY,35,FILEGC,LNUM) +! +!! Write message to WARNING.OUT file that default ecotype +!! will be used. +! WRITE(MESSAGE(1),5000) ECONO, FILEE +! WRITE(MESSAGE(2),5001) +! 5000 FORMAT('Ecotype ',A6,' not found in file: ',A12) +! 5001 FORMAT('Default ecotype parameters will be used.') +! +! ECONO = 'DFAULT' +! REWIND(LUNECO) +! LNUM = 0 + ENDIF + ENDDO + + CLOSE (LUNECO) + ENDIF + + KEP = KCAN/(1-0.07)*(1-0.25) + + DO I=1,20 + STGDOY(I) = 9999999 + ENDDO + STGDOY(14) = YRSIM +! YREMRG = 9999999 + YREMRG = -99 !CHP 5/19/2011 + + CUMDTT = 0.0 + SUMDTT = 0.0 + DTT = 0.0 + GPP = 0.0 + ISTAGE = 7 + XSTAGE = 0.1 + MDATE = -99 + DUMMY = 0 + + ISDATE = 0 + TNSOIL = 0.0 + TMSOIL = 0.0 + TH = 00.0 + TEMPCX = 0. + TEMPCR = 0.0 + TDSOIL = 0.0 + SWSD = 0.0 + SNUP = 0.0 + SNDN = 0.0 + S1 = 0.0 + RATEIN = 0.0 + PSKER = 0.0 + PDTT = 0.0 + P9 = 0.0 + P3 = 0.0 + NDAS = 0.0 + L0 = 0.0 + L = 0 + DLV = 0.0 + DEC = 0.0 + C1 = 0.0 + ACOEF = 0.0 + DOPT = 0.0 + +! CHP 9/10/2004 P model + SeedFrac = 0.0 + VegFrac = 0.0 + +!---------------------------------------------------------------------- +! DYNAMIC = RATE OR INTEGRATE +! --------------------------------------------------------------------- + + ELSE + +! ------------------------------------------------------------- +! Compute Crown Temperature under snow pack. +! Used in COLD.for +! ------------------------------------------------------------- + ! TEMPCN = crown temperature when snow is present and + ! TMIN < 0. This function computes crown temperature + ! as higher than TMIN, C. + ! TEMPCX = crown temp. for max. development rate, C + ! SNOW = Snow depth, mm + ! XS = temporary snow depth variable, mm + + TEMPCN = TMIN + TEMPCX = TMAX + XS = SNOW + XS = AMIN1 (XS,15.0) + !------------------------------------------------------------ + ! Calculate crown temperature based on temperature and + ! snow cover. Crown temperature is higher than TAVG due + ! to energy balance of snow pack. + !------------------------------------------------------------ + IF (TMIN .LT. 0.0) THEN + TEMPCN = 2.0 + TMIN*(0.4+0.0018*(XS-15.0)**2) + ENDIF + IF (TMAX .LT. 0.0) THEN + TEMPCX = 2.0 + TMAX*(0.4+0.0018*(XS-15.0)**2) + ENDIF + TEMPCR = (TEMPCX + TEMPCN)/2.0 + + + !------------------------------------------------------------ + ! Compute thermal time based on new method developed by J.T.R + ! at CYMMIT, 5/5/98. TBASE, TOPT, and ROPT are read in + ! from the species file. + !------------------------------------------------------------ + + ! DOPT, Devlopment optimum temperature, is set to TOPT + ! during vegetative growth and to ROPT after anthesis + + DOPT = TOPT + IF ((ISTAGE .GT. 3) .AND. (ISTAGE .LE. 6)) THEN + DOPT = ROPT + ENDIF + + ! Check basic temperature ranges and calculate DTT for + ! development based on PC with JTR + + IF (TMAX .LT. TBASE) THEN + DTT = 0.0 + ELSEIF (TMIN .GT. DOPT) THEN + ! ! + !This statement replaces DTT = TOPT .. GoL and LAH, CIMMYT, 1999 + ! ! + DTT = DOPT - TBASE + ! ! + !Now, modify TEMPCN, TEMPCX based on soil conditions or snow + ! ! If wheat and barley is before terminal spiklett stage + ! ! Or if corn and sorghum are before 10 leaves + ! ! + ELSEIF (LEAFNO.LE.10) THEN + !Check for snow (should following be GT.0 or GT.15 ?). + ! !Based on snow cover, calculate DTT for the day + ! ! + IF (XS .GT. 0.0) THEN + ! ! + ! ! Snow on the ground + ! ! + DTT = (TEMPCN + TEMPCX)/2.0 - TBASE + ELSE + ! ! + ! ! No snow, compute soil temperature + ! ! + ACOEF = 0.01061 * SRAD + 0.5902 + TDSOIL = ACOEF * TMAX + (1.0 - ACOEF) * TMIN + TNSOIL = 0.36354 * TMAX + 0.63646 * TMIN + IF (TDSOIL .LT. TBASE) THEN + DTT = 0.0 + ELSE + IF (TNSOIL .LT. TBASE) THEN + TNSOIL = TBASE + ENDIF + IF (TDSOIL .GT. DOPT) THEN + TDSOIL = DOPT + ENDIF + !Import DAYL from WEATHR module. chp 5-6-02 + TMSOIL = TDSOIL * (DAYL/24.) + + & TNSOIL * ((24.-DAYL)/24.) + IF (TMSOIL .LT. TBASE) THEN + DTT = (TBASE+TDSOIL)/2.0 - TBASE + ELSE + DTT = (TNSOIL+TDSOIL)/2.0 - TBASE + ENDIF + ! ! + ! ! Statement added ... GoL and LAH, CIMMYT, 1999 + ! ! + DTT = AMIN1 (DTT,DOPT-TBASE) + ENDIF + ENDIF + ! + ! Now, compute DTT for when Tmax or Tmin out of range + ! + ELSEIF (TMIN .LT. TBASE .OR. TMAX .GT. DOPT) THEN + DTT = 0.0 + DO I = 1, 24 + TH = (TMAX+TMIN)/2. + (TMAX-TMIN)/2. * SIN(3.14/12.*I) + IF (TH .LT. TBASE) THEN + TH = TBASE + ENDIF + IF (TH .GT. DOPT) THEN + TH = DOPT + ENDIF + DTT = DTT + (TH-TBASE)/24.0 + END DO + ELSE + DTT = (TMAX+TMIN)/2.0 - TBASE + ENDIF + + !print*,"DTT",tmax,tmin,tbase + DTT = AMAX1 (DTT,0.0) + SUMDTT = SUMDTT + DTT + CUMDTT = CUMDTT + DTT + + +! ------------------------------------------------------------------ +! ISTAGE Definitions +! +! 7 - Sowing date +! 8 - Germination +! 9 - Emergence +! 1 - End juvenile +! 2 - Pannicle initiation +! 3 - End leaf growth +! 4 - End pannicle growth +! 5 - Grain fill +! 6 - Maturity +! ---------------------------------------------------------- + + + !--------------------------------------------------------- + ! ISTAGE = 7 - Determine sowing date + !--------------------------------------------------------- + IF (ISTAGE .EQ. 7) THEN + STGDOY(ISTAGE) = YRDOY + NDAS = 0.0 + ISTAGE = 8 + SUMDTT = 0.0 + IF (ISWWAT .EQ. 'N') RETURN + + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + CUMDEP = 0.0 + DO L = 1, NLAYR + CUMDEP = CUMDEP + DLAYR(L) + IF (SDEPTH .LT. CUMDEP) GO TO 100 ! Was EXIT + END DO + 100 CONTINUE ! Sun Fix + L0 = L !L0 is layer that seed is in. + + RETURN + + + !----------------------------------------------------------------- + ! ISTAGE = 8 - Determine Germination Date + !----------------------------------------------------------------- + ELSEIF (ISTAGE .EQ. 8) THEN + IF (ISWWAT .NE. 'N') THEN + IF (SW(L0) .LE. LL(L0)) THEN + SWSD = (SW(L0)-LL(L0))*0.65 + + & (SW(L0+1)-LL(L0+1))*0.35 + NDAS = NDAS + 1 + + IF (NDAS .GE. DSGT) THEN + ISTAGE = 6 + PLTPOP = 0.00 + GPP = 1.0 + + WRITE(MESSAGE(1),3500) + !CALL WARNING(1,'MZPHEN',MESSAGE) + WRITE ( *,3500) + IF (IDETO .EQ. 'Y') THEN + WRITE (NOUTDO,3500) + ENDIF + MDATE = YRDOY + RETURN + ENDIF + !Germinate when soil water > 0.02 cm3/cm3 + + IF (SWSD .LT. SWCG) RETURN + ENDIF + ENDIF + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + STGDOY(ISTAGE) = YRDOY + ISTAGE = 9 + CUMDTT = 0.0 + SUMDTT = 0.0 + + P9 = 45.0 + GDDE*SDEPTH + RETURN + + + !----------------------------------------------------------------- + ! ISTAGE = 9 - Determine Seedling Emergence Date + !----------------------------------------------------------------- + ELSEIF (ISTAGE .EQ. 9) THEN + NDAS = NDAS + 1 + ! Emerge when P9 GDD's have been accumulated +! IF (SUMDTT .LT. P9) RETURN + IF (YREMRG .LE. 0) THEN + IF (SUMDTT .LT. P9) RETURN + ELSE + IF (YRDOY .LT. YREMRG) RETURN + ENDIF + ! If GDD's pass a threshold, terminate model run + + IF (P9 .GT. DGET) THEN + ISTAGE = 6 + PLTPOP = 0.00 + GPP = 1.0 + + WRITE(MESSAGE(1),1399) + !CALL WARNING(1,'MZPHEN',MESSAGE) + + WRITE ( *,1399) + IF (IDETO .EQ. 'Y') THEN + WRITE (NOUTDO,1399) + ENDIF + MDATE = YRDOY + RETURN + ENDIF + + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + STGDOY(ISTAGE) = YRDOY + ISTAGE = 1 + SUMDTT = SUMDTT - P9 + TLNO = 30.0 + YREMRG = STGDOY(9) !Passed back into water balance routi + RETURN + + !----------------------------------------------------------------- + ! ISTAGE = 1 - Emergence to End of Juvenile Stage + !----------------------------------------------------------------- + ELSEIF (ISTAGE .EQ. 1) THEN + NDAS = NDAS + 1 !NDAS - number of days after sowing + XSTAGE = SUMDTT/P1 !XSTAGE - noninteger growth stage (0-1 + ! Used to compute N demand + ! Stage occurs when GDD threshold reached + !Return if end of juvenile stage is not reached + +! chp 9/23/2004 +! For P model, we need to estimate the fraction of time completed +! between emergence and tassel initiation, VegFrac. Because stage 2 +! (end of juvenile stage to tassel initiation) completion is not +! based on physiological time, but rather on daylight hours, we +! will make the assumption that the physical duration of that phase +! is 5 days at optimum temperature. + +! CHP 5/11/2005 +! Extend VegFrac to include phases 3 & 4 (to beginning of effective +! grain filling). Reduce Seed Frac to phase 5. +! VegFrac = SUMDTT / (P1 + 5.0 * (DOPT - TBASE)) +! don't know value of P3 yet +! VegFrac = SUMDTT / (P1 + 5. * (DOPT - TBASE) + P3 + DSGFT) + +! CHP 5/25/2007 Move inflection point back to end of stage 3 +! VegFrac = SUMDTT / (P1 + 20. * (DOPT - TBASE) + DSGFT) +! VegFrac = SUMDTT / (P1 + 20. * (DOPT - TBASE)) +! 5/30/2007 CHP Estimate of total time is way off for EAAMOD runs, +! try using 25* instead of 20* + VegFrac = SUMDTT / (P1 + 25. * (DOPT - TBASE)) + + IF (SUMDTT .LT. P1) RETURN + + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + STGDOY(ISTAGE) = YRDOY + ISTAGE = 2 + SIND = 0.0 + + + !----------------------------------------------------------------- + ! ISTAGE = 2 - End of Juvenile Stage to Tassel Initiation + !----------------------------------------------------------------- + ELSEIF (ISTAGE .EQ. 2) THEN + !NDAS - number of days after sowing + NDAS = NDAS + 1 + !XSTAGE - noninteger growth stage (1-1.5) + XSTAGE = 1.0 + 0.5*SIND ! Used to compute N demand. + + PDTT = DTT + IF (ISWWAT .EQ. 'N') THEN + DUMMY = DUMMY + 1 + ENDIF + + IF (DUMMY .EQ. 1) THEN + PDTT = SUMDTT - P1 + ENDIF + +! chp 9/23/2004 +! See note for VegFrac under ISTAGE = 1, above +! VegFrac = SUMDTT / (P1 + 5.0 * (DOPT - TBASE)) +! don't know value of P3 yet +! VegFrac = SUMDTT / (P1 + 5. * (DOPT - TBASE) + P3 + DSGFT) + +! CHP 5/25/2007 Move inflection point back to end of stage 3 +! VegFrac = SUMDTT / (P1 + 20. * (DOPT - TBASE) + DSGFT) +! VegFrac = SUMDTT / (P1 + 20. * (DOPT - TBASE)) +! 5/30/2007 CHP Estimate of total time is way off for EAAMOD runs, +! try using 25* instead of 20* + VegFrac = MAX(VegFrac,SUMDTT / (P1 + 25. *(DOPT - TBASE))) + + !RATEIN - floral rate of development driven by daylength + ! and photoperiod sensitivity value for maize (different + ! for SG, ML + !TWILEN = AMAX1 (TWILEN,P2O) + + IF (TWILEN .GT. P2O) THEN + RATEIN = 1.0/(DJTI+P2*(TWILEN-P2O)) + ELSE + RATEIN = 1.0 / DJTI + ENDIF + PDTT = 1.0 + SIND = SIND + RATEIN*PDTT + !Return if panicle initiation has not been reached + IF (SIND .LT. 1.0) RETURN + + + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + STGDOY(ISTAGE) = YRDOY + ISTAGE = 3 + XNTI = SUMDTT/43.0 + !Next 2 lines: Change implemented at CIMMYT 1999 - JTR,US + TLNO = SUMDTT/(PHINT*0.5)+ 5.0 + P3 = ((TLNO + 0.5) * PHINT) - SUMDTT + XNTI = XN + +! chp 5/11/2005 + SUMDTT_2 = SUMDTT !SUMDTT_2 = P1 + P2 + VegFrac = MAX(VegFrac,SUMDTT_2 / (SUMDTT_2 + P3 + DSGFT)) + + SUMDTT = 0.0 + +! chp 9/23/2004, removed 5/11/2005 +! VegFrac = 1.0 + + !----------------------------------------------------------------- + ! ISTAGE = 3 - Tassel Initiation to End of Leaf Growth + !----------------------------------------------------------------- + ELSEIF (ISTAGE .EQ. 3) THEN + ! NDAS - number of days after sowing + NDAS = NDAS + 1 + ! XSTAGE - noninteger growth stage (1.5-4.5) + ! Used to compute N demand. + XSTAGE = 1.5 + 3.0*SUMDTT/P3 + +! chp 9/23/2004 +! For P model, we need to estimate the fraction of time +! completed between tassel initiation and physiological +! maturity, SeedFrac. +! CHP 5/11/2005 Extend VegFrac thru stage 4 +! SeedFrac = SUMDTT / (P3 + DSGFT + P5) + +! CHP 5/25/2007 Move inflection point back to end of stage 3 +! VegFrac = (SUMDTT + SUMDTT_2) / (SUMDTT_2 + P3 + DSGFT) + VegFrac = MAX(VegFrac,(SUMDTT + SUMDTT_2) / (SUMDTT_2+P3)) + + IF (SUMDTT .LT. P3) RETURN + + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + STGDOY(ISTAGE) = YRDOY + ISDATE = YRDOY + ISTAGE = 4 + SUMDTT = SUMDTT - P3 + IDURP = 0 + +! CHP 5/25/2007 Move inflection point back to end of stage 3 + VegFrac = 1.0 + + !----------------------------------------------------------------- + ! ISTAGE = 4 - End of Leaf Growth to Beginning Effective Gra + !----------------------------------------------------------------- + ELSEIF (ISTAGE .EQ. 4) THEN + NDAS = NDAS + 1 + IDURP = IDURP + 1 + ! Determine beginning of effective grain filling period fo + ! maize. Silking to beginning EFG is assumed to be 170 G + XSTAGE = 4.5+5.5*SUMDTT/(P5*0.95) + +! chp 9/23/2004, 5/11/2005 +! SeedFrac = (SUMDTT + P3) / (P3 + DSGFT + P5) +! VegFrac = (SUMDTT + SUMDTT_2 + P3) / (SUMDTT_2 + P3+DSGFT) +! VegFrac = AMIN1(VegFrac, 1.0) + +! CHP 5/25/2007 Move inflection point back to end of stage 3 + SeedFrac = SUMDTT / P5 + + IF (SUMDTT .LT. DSGFT) RETURN + + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + + ! When Silking phase ends and beginning of effective grain + ! filling begins. Compute grains per plant, ears per pla + ! and barrenness + + PSKER = SUMP*1000.0/IDURP*3.4/5.0 + GPP = G2*PSKER/7200.0 + 50.0 + GPP = AMIN1 (GPP, G2) + GPP = AMAX1 (GPP,0.0) + EARS = PLTPOP + + !Determine barrenness for maize + GPP = AMAX1 (GPP,51.0) + ! + ! Barreness (mod. US and PWW, 7-21-98) + ! Barreness function based on stress (PSKER f(SUMP)) + ! Smoothing function for ear number reduction + ! + IF (GPP .LT. G2*0.15) THEN + EARS = PLTPOP*(GPP/(G2*0.15))**0.33 + ELSE + ! + ! CIMMYT - US & JTR revised barreness function + ! + IF (PLTPOP .GT. 12.0) THEN + ! + ! Barreness from high population + ! + IF (GPP .LT. G2*0.5) THEN + ! ABSTRES = AMAX1 (SI1(3), SI3(3)) + ! + ! Barreness effect with min. N and H2O stress + ! + ! IF (ABSTRES .LT. 0.25) THEN + BARFAC = 0.0085*(1.0-GPP/G2)*PLTPOP**1.5 + EARS = PLTPOP*(GPP/(G2*0.50))**BARFAC + ! ENDIF + ENDIF + ENDIF + ENDIF + + EARS = AMAX1 (EARS,0.0) + STGDOY(ISTAGE) = YRDOY + ISTAGE = 5 + +! CHP 5/11/2005 +! CHP 5/25/2007 Move inflection point back to end of stage 3 +! VegFrac = 1.0 + + !----------------------------------------------------------------- + ! ISTAGE = 5 - Beginning to end of effective grain filling p + !----------------------------------------------------------------- + + ELSEIF (ISTAGE .EQ. 5) THEN + NDAS = NDAS + 1 + XSTAGE = 4.5 + 5.5*SUMDTT/P5 + +! chp 9/23/2004, 5/11/2005 +! SeedFrac = (SUMDTT + P3) / (P3 + DSGFT + P5) + +! CHP 5/25/2007 Move inflection point back to end of stage 3 +! SeedFrac = (SUMDTT - DSGFT) / (P5 - DSGFT) + SeedFrac = SUMDTT / P5 + + IF (SUMDTT .LT. P5*0.95) RETURN !End of EFP assumed to be 95% + !------------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Variables + !------------------------------------------------------------- + STGDOY (ISTAGE) = YRDOY + ISTAGE = 6 + + !----------------------------------------------------------------- + ! ISTAGE = 6 - End Effective Grain Filling to Physiological + !----------------------------------------------------------------- + ELSEIF (ISTAGE .EQ. 6) THEN + IF (DTT .LT. 2.0) SUMDTT = P5 + +! chp 9/23/2004, 5/11/2005 +! SeedFrac = (SUMDTT + P3) / (P3 + DSGFT + P5) + SeedFrac = (SUMDTT - DSGFT) / (P5 - DSGFT) + +! CHP 5/25/2007 Move inflection point back to end of stage 3 +! SeedFrac = (SUMDTT - DSGFT) / (P5 - DSGFT) + SeedFrac = SUMDTT / P5 + + IF (SUMDTT .LT. P5) RETURN + !--------------------------------------------------------- + ! New Growth Stage Occurred Today. Initialize Some Varia + !--------------------------------------------------------- + STGDOY(ISTAGE) = YRDOY + MDATE = YRDOY + !ISTAGE = 7 + ISTAGE = 10 !CHP - Prevents growth parameters from being + ! set back to initial values. 08/11/03 + CUMDTT = 0.0 + DTT = 0.0 + IF (PLTPOP .NE. 0.0) THEN + IF (GPP .LE. 0.0) THEN + GPP = 1.0 + ENDIF + ENDIF + +! chp 5/11/2005 + SeedFrac = 1.0 +! ---------------------------------------------------------------------- + ENDIF ! End ISTAGE Loop +! ---------------------------------------------------------------------- + + ENDIF ! End DYNAMIC STRUCTURE + RETURN + +!----------------------------------------------------------------------- +! Format Strings +!----------------------------------------------------------------------- + +1399 FORMAT (10X,'Seed ran out of metabolite due to deep planting') +3500 FORMAT ('Crop failure because of lack of germination ', + & 'within 15 days of sowing') + + END SUBROUTINE MZ_PHENOL + +! DYNAMIC Modular control +! ABSTRES Maximum of water stress stage 1 and 3 +! ACOEF Coefficient +! BARFAC Factor to reduce ears/plant under high populations (barrenn +! C1 Used to comptue daylength (computed in maize.for) +! CUMDEP Cumulative depth of soil, cm +! CUMDTT Cumulative daily thermal time after germination, C +! DAYL Daylength, hours +! DEC Used to compute daylength +! DGET Threshold defined as growing degree days between germination and emergence. +! If this threshold is exceeded, crop failure ocurrs. +! DJTI Minimum days from end of juvenile stage to tassel initiation if the cultivar +! is not photoperiod sensitive, DJTI +! DLAYR(L) Soil thickness in layer L (cm) +! DLV Used to compute daylength +! DOPT Development optimum temperature +! DSGFT GDD from silking to effective grain filling period, C +! DSGT Maximum number of days from sowing to germination before crop failure occurs. +! DTT Growing degree days today, C +! DUMMY Temporary variable +! EARS Ears per m2, computed here and used in grosub. +! ECONO Ecotype number for the variety (not really used in maize ye +! ERR Determines if error in reading file (0=ok, 1=error) +! ERRKEY Variable containing routine where error occurred +! (ERRKEY='MZ_PHENL') +! FILEC Filename of .SPE or species file +! FILEIO Filename containing model inputs (IBSNAT35.INP) +! FOUND Indicates if a section in a file is found +! G2 Potential kernel number, kernels/plant +! G3 Potential kernel growth rate mg/kernel/day +! GDDE Growing degree days per cm seed depth required for emergence, GDD/cm +! GPP Grain number per plant, grains/plant +! I Loop counter +! IDETO Screen output switch (Y/N) +! IDURP Duration of ISTAGE 4, calendar days +! ISTAGE Growth stage +! ISWWAT Water balance switch (Y/N) +! LEAFNO Number of oldest leaf per plant (same as XN) +! L Loop counter +! L0 Temporary soil layer number +! LINC Indicates if a line is a good line +! LL(NL) Soil water lower limit, cm3/cm3 +! LNUM Line number in an input file +! LUNIO Logical input number for model input file +! LUNIO Assign value to LUNIO for local use. +! MDATE Year and day of year of maturity +! NDAS Number of days after sowing +! NLAYR Number of soil layers +! NOUTDO Output file number +! P1 GDD from seedling emergence to end of juvenile phase, C +! P2 Photoperiod sensitivity coefficient, 1/hr +! P2O Minimum daylength below which daylength does not affect dev +! P3 Cumulative GDD required to complete ISTAGE 3, C +! P5 GDD from silking to physiological maturity, C +! P9 Growing degree days from germination to emergence, C +! PATHCR Pathname of species file +! DTT +! PHINT Phyllochron interval. Number of GDD required for new leaf e +! PLTPOP Plant population, no./m2 +! PSKER Average rate of photosynthesis during ISTAGE 4 +! RATEIN Rate of floral induction +! ROPT Second optimum temperature for development from species fil +! SDEPTH Sowing depth, cm +! SECTION Temporary variable used to identify section in a file +! S1 Used to compute daylength (computed in maize.for) +! SI1(6) Water stress during a growth stage used for output +! SI3(6) Water stress during a growth stage used for output +! SIND Summed photoperiod induction rate +! SNDN Sun down +! SNOW Snow, mm +! SNUP Sun up +! SRAD Daily solar radiation, MJ/m2/day +! STGDOY(20) Year and day of year that a growth stage occurred on +! SUMDTT Sum of GDD for a given stage, C +! SUMP Cumulative plant growth during ISTAGE 4, g/plant +! SW(NL) Soil water content in layer, cm3/cm3 +! SWCG Minimum soil water available required for germination to occur, cm3/cm3 +! SWSD Modified soil water content for computing emergence +! TBASE Base temperature for development from ecotype file, C +! TDSOIL Weighted average soil temperature, C +! TEMPCN Crown temperature when snow is present and TMIN < 0. This f +! computes crown temperature as higher than TMIN, C. +! TEMPCR Crown temperature, C +! TEMPCX Crown temperature for maximum development rate, C +! TH Intermedate variable for computing GDD today, C +! TLNO Total leaf numbers that will eventually develop +! TMAX Daily maximum temperature, C +! TMIN Daily minimum temperature, C +! TMSOIL Weighted average soil temperature, C +! TNSOIL Weighted average soil temperture, C +! TOPT Optimum temperature for development from species file, C +! TWILEN Twilight definition of daylength +! VARNO Variety identification number +! VRNAME Variety name +! WTHADJ(2,8)Note, used here, but not passed into maize.for from cropgro +! WMODB*1 Note, used here, but not passed into maize.for from cropgro +! XLAT Latitude +! XN Number of oldest expanding leaf +! XNTI Number of leaves at tassel initiation (used in grosub) +! XS Temporary snow depth variable +! XSTAGE Non-integer growth stage indicator +! YRDOY Year and day of year +! YREMRG Year and day of year of emergence (passed back to water bal +! YRSIM Year and day of year of first day of simulation + diff --git a/lib/maize/mz.o b/lib/maize/mz.o new file mode 100644 index 0000000000000000000000000000000000000000..b7bc856639eb3fa070c3515135f98f7f7732ac1a Binary files /dev/null and b/lib/maize/mz.o differ diff --git a/models/maturity.go b/models/maturity.go new file mode 100644 index 0000000000000000000000000000000000000000..bbf4c9862b4a9807ead564218e67eb697d1b9c36 --- /dev/null +++ b/models/maturity.go @@ -0,0 +1,114 @@ +package models + +import ( + "strconv" + "time" + + validation "github.com/go-ozzo/ozzo-validation" + + "gitlab.cs.umd.edu/dawn/dawn-go-common/common" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/config" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/persistence/entities" +) + +type CultivarRequest struct { + Name string `json:"name"` +} + +type Cultivar struct { + VarName string `json:"var_name"` + VarNum string `json:"var_num"` + EcoNum string `json:"eco_num"` + P1 float64 `json:"p1"` + P2 float64 `json:"p2"` + P5 float64 `json:"p5"` + G2 float64 `json:"g2"` + G3 float64 `json:"g3"` + PHINT float64 `json:"phint"` +} + +type CultivarResponse struct { + Cultivars []Cultivar `json:"cultivars"` +} + +func CreateCultivar(c entities.Cultivar) Cultivar { + return Cultivar{ + VarName: c.VarName, + VarNum: c.VarNum, + EcoNum: c.EcoNum, + P1: c.P1, + P2: c.P2, + P5: c.P5, + G2: c.P2, + G3: c.G3, + PHINT: c.PHINT, + } +} + +type CornMaturityRequest struct { + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` + PlantDate time.Time `json:"plant_date"` + VarName string `json:"var_name"` + VarNum string `json:"var_num"` + EcoNum string `json:"eco_num"` + P1 float64 `json:"p1"` + P2 float64 `json:"p2"` + P5 float64 `json:"p5"` + G2 float64 `json:"g2"` + G3 float64 `json:"g3"` + PHINT float64 `json:"phint"` +} + +type CornMaturityResponse struct { + HarvestDate time.Time `json:"harvest_date"` +} + +func (r CornMaturityRequest) Validate() error { + + return validation.ValidateStruct(&r, + validation.Field(&r.Latitude, validation.Required, validation.Min(-90.0), validation.Max(90.0)), + validation.Field(&r.Longitude, validation.Required, validation.Min(-180.0), validation.Max(180.0)), + ) +} + +func BuildCornMaturityRequest(ctx common.DawnCtx) CornMaturityRequest { + + latitude, _ := strconv.ParseFloat(ctx.FiberCtx.Query("latitude", "-100000.0"), 64) + longitude, _ := strconv.ParseFloat(ctx.FiberCtx.Query("longitude", "-100000.0"), 64) + + varName := ctx.FiberCtx.Query("var_name", "") + varNum := ctx.FiberCtx.Query("var_num", "") + ecoNum := ctx.FiberCtx.Query("eco_num", "") + plant_month, _ := strconv.Atoi(ctx.FiberCtx.Query("plant_month", "0")) + plant_day, _ := strconv.Atoi(ctx.FiberCtx.Query("plant_day", "0")) + + plant_date := time.Date(time.Now().Year(), time.Month(plant_month), plant_day, 0, 0, 0, 0, time.UTC) + + p1, _ := strconv.ParseFloat(ctx.FiberCtx.Query("p1", "0"), 64) + p2, _ := strconv.ParseFloat(ctx.FiberCtx.Query("p2", "0"), 64) + p5, _ := strconv.ParseFloat(ctx.FiberCtx.Query("p5", "0"), 64) + g2, _ := strconv.ParseFloat(ctx.FiberCtx.Query("g2", "0"), 64) + g3, _ := strconv.ParseFloat(ctx.FiberCtx.Query("g3", "0"), 64) + phint, _ := strconv.ParseFloat(ctx.FiberCtx.Query("phint", "0"), 64) + rNew := CornMaturityRequest{ + Latitude: latitude, + Longitude: longitude, + VarName: varName, + VarNum: varNum, + EcoNum: ecoNum, + P1: p1, + P2: p2, + P5: p5, + G2: g2, + G3: g3, + PHINT: phint, + PlantDate: plant_date, + } + + if rNew.Validate() != nil { + panic(config.BAD_REQUEST) + } + return rNew + +} diff --git a/models/seeds.go b/models/seeds.go index c837463c28e7a3590080ec163cf4fd36a2b7fe25..1b6817b7cabc1a55ca329774bf4a37ab6d198569 100644 --- a/models/seeds.go +++ b/models/seeds.go @@ -1,68 +1,27 @@ package models -import ( - "strconv" - "time" - - "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/config" - - validation "github.com/go-ozzo/ozzo-validation" - "github.com/gofiber/fiber/v2" -) - -type SeedListRequest struct { - Product string `json:"product"` -} - -type SeedListResponse struct { - Seeds []string `json:"seeds"` -} - -type CornMaturityRequest struct { - Latitude float64 `json:"latitude"` - Longitude float64 `json:"longitude"` - Gdds float64 `json:"gdds"` - Month int `json:"month"` - Date int `json:"date"` -} - -type CornMaturityResponse struct { - Date time.Time `json:"date"` - GDD float64 `json:"gdd"` - ClosestGDD float64 `json:"closest_gdd"` - ClosestLatitude float64 `json:"closest_latitude"` - ClosestLongitude float64 `json:"closest_longitude"` -} - -func (r CornMaturityRequest) Validate() error { - return validation.ValidateStruct(&r, - validation.Field(&r.Latitude, validation.Required, validation.Min(-90.0), validation.Max(90.0)), - validation.Field(&r.Longitude, validation.Required, validation.Min(-180.0), validation.Max(180.0)), - validation.Field(&r.Gdds, validation.Required, validation.Min(0.0), validation.Max(6000.0)), - validation.Field(&r.Month, validation.Required, validation.Min(1), validation.Max(12)), - validation.Field(&r.Date, validation.Required, validation.Min(1), validation.Max(31)), - ) -} - -func BuildCornMaturityRequest(c *fiber.Ctx) CornMaturityRequest { - - lat, _ := strconv.ParseFloat(c.Query("latitude", "-10000.0"), 64) - lon, _ := strconv.ParseFloat(c.Query("longitude", "-10000.0"), 64) - month, _ := strconv.Atoi(c.Query("month", "0")) - date, _ := strconv.Atoi(c.Query("date", "0")) - gdds, _ := strconv.ParseFloat(c.Query("gdds", "-10000.0"), 64) - - newRequest := CornMaturityRequest{ - Latitude: lat, - Longitude: lon, - Gdds: gdds, - Month: month, - Date: date, - } - - if e := newRequest.Validate(); e != nil { - panic(config.BAD_REQUEST.AddLogDetails(e.Error())) - } - - return newRequest -} +// type SeedListRequest struct { +// Product string `json:"product"` +// } + +// type SeedListResponse struct { +// Seeds []string `json:"seeds"` +// } + +// type CornMaturityRequest struct { +// Latitude float64 `json:"latitude"` +// Longitude float64 `json:"longitude"` +// Gdds float64 `json:"gdds"` +// Month int `json:"month"` +// Date int `json:"date"` +// } + +// func (r CornMaturityRequest) Validate() error { +// return validation.ValidateStruct(&r, +// validation.Field(&r.Latitude, validation.Required, validation.Min(-90.0), validation.Max(90.0)), +// validation.Field(&r.Longitude, validation.Required, validation.Min(-180.0), validation.Max(180.0)), +// validation.Field(&r.Gdds, validation.Required, validation.Min(0.0), validation.Max(6000.0)), +// validation.Field(&r.Month, validation.Required, validation.Min(1), validation.Max(12)), +// validation.Field(&r.Date, validation.Required, validation.Min(1), validation.Max(31)), +// ) +// } diff --git a/persistence/entities/gdd.go b/persistence/entities/gdd.go index f17aff3b98f8a0e27a5b6e32a6c07f68c4396530..62ba7c9dfdcc0c7e0dbe24d7590b16e439ad78be 100644 --- a/persistence/entities/gdd.go +++ b/persistence/entities/gdd.go @@ -18,6 +18,8 @@ type Gdd struct { Year int `bson:"year,omitempty"` MinTemps []float64 `bson:"min_temps,omitempty"` MaxTemps []float64 `bson:"max_temps,omitempty"` + SRAD []float64 `bson:"srad,omitempty"` + Precip []float64 `bson:"precip,omitempty"` Location Location `bson:"location,omitempty"` } @@ -38,5 +40,6 @@ type CfsGdd struct { MaxTemps []float64 `bson:"max_temps,omitempty"` VarMin []float64 `bson:"var_mins,omitempty"` VarMax []float64 `bson:"var_maxs,omitempty"` + Srad []float64 `bson:"srad,omitempty"` Date primitive.DateTime `bson:"date,omitempty"` } diff --git a/persistence/entities/maturity.go b/persistence/entities/maturity.go new file mode 100644 index 0000000000000000000000000000000000000000..c0eb8255f0ececb279d0b9b6c65a9fe48893a00c --- /dev/null +++ b/persistence/entities/maturity.go @@ -0,0 +1,13 @@ +package entities + +type Cultivar struct { + VarName string `bson:"var_name"` + VarNum string `bson:"var_num"` + EcoNum string `bson:"eco_num"` + P1 float64 `bson:"p1"` + P2 float64 `bson:"p2"` + P5 float64 `bson:"p5"` + G2 float64 `bson:"g2"` + G3 float64 `bson:"g3"` + PHINT float64 `bson:"phint"` +} diff --git a/persistence/mongodb.go b/persistence/mongodb.go index 0966ac4e583d97dca50978a9bd75b346e45746b9..da7034966148ff6613034d99b62311f253623cd3 100644 --- a/persistence/mongodb.go +++ b/persistence/mongodb.go @@ -11,6 +11,7 @@ import ( "github.com/bradfitz/slice" "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo/options" ) @@ -21,7 +22,7 @@ func buildLocationRequest(location entities.Location, year *int) bson.M { "location": bson.M{ "$nearSphere": bson.M{ "$geometry": location, - "$maxDistance": 5000, + "$maxDistance": 150000, }, }, "year": *year, @@ -31,7 +32,7 @@ func buildLocationRequest(location entities.Location, year *int) bson.M { "location": bson.M{ "$nearSphere": bson.M{ "$geometry": location, - "$maxDistance": 5000, + "$maxDistance": 150000, }, }, } @@ -148,6 +149,7 @@ func CfsFindAllByLocation(location entities.Location) entities.CfsGdd { var g entities.CfsGdd err := coll.FindOne(common.Ctx, filter).Decode(&g) + if err != nil { panic(config.NO_DATA_FOUND) } @@ -235,3 +237,48 @@ func FindSeeds(product string) []entities.Seed { return results } + +func FindCultivarByName(name string) entities.Cultivar { + coll := common.DB.Collection("dssat") + + filter := bson.M{ + "var_name": bson.M{ + "$regex": primitive.Regex{Pattern: name, Options: "i"}, + }, + } + + var results entities.Cultivar + + err := coll.FindOne(common.Ctx, filter).Decode(&results) + if err != nil { + panic(config.NO_DATA_FOUND) + } + + return results +} + +func FindCultivarsByName() []entities.Cultivar { + coll := common.DB.Collection("dssat") + + var results []entities.Cultivar + + options := options.Find() + + cursor, err := coll.Find(common.Ctx, bson.D{}, options) + if err != nil { + panic(config.NO_DATA_FOUND) + } + + for cursor.Next(context.TODO()) { + + var elem entities.Cultivar + err := cursor.Decode(&elem) + if err != nil { + panic(config.NO_DATA_FOUND) + } + + results = append(results, elem) + } + + return results +} diff --git a/services/maturity_service.go b/services/maturity_service.go new file mode 100644 index 0000000000000000000000000000000000000000..686b74144d16f80cfc589c55545032e0d99ad2fe --- /dev/null +++ b/services/maturity_service.go @@ -0,0 +1,147 @@ +package services + +import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" + "math/rand" + "os" + "os/exec" + "strconv" + "strings" + "time" + + "gitlab.cs.umd.edu/dawn/dawn-go-common/common" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/config" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/models" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/persistence" + "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/persistence/entities" +) + +type CornMaturityConfig struct { + PlantDate int `json:"plant_date"` + Tmins []float64 `json:"tmins"` + Tmaxs []float64 `json:"tmaxs"` + Srads []float64 `json:"srads"` + Units string `json:"units"` +} + +func GetCultivars(ctx common.DawnCtx, request models.CultivarRequest) models.CultivarResponse { + if request.Name != "" { + elem := persistence.FindCultivarByName(request.Name) + cultivar := models.CreateCultivar(elem) + return models.CultivarResponse{ + Cultivars: []models.Cultivar{cultivar}, + } + } else { + elems := persistence.FindCultivarsByName() + var cultivars []models.Cultivar + for _, e := range elems { + cultivars = append(cultivars, models.CreateCultivar(e)) + } + return models.CultivarResponse{ + Cultivars: cultivars, + } + } +} + +func getFullYearData(ctx common.DawnCtx, latitude float64, longitude float64, plantDate time.Time) CornMaturityConfig { + location := entities.Location{ + Type: "Point", + Coordinates: []float64{longitude, latitude}, + } + + observed := persistence.CurrentGddFindFirstByYearAndLocation(ctx, location) + predicted := persistence.CfsFindAllByLocation(location) + + tmins := append(observed.MaxTemps, predicted.MaxTemps...) + tmaxs := append(observed.MinTemps, predicted.MinTemps...) + srads := append(observed.SRAD, predicted.Srad...) + + pd := plantDate.YearDay() + + if plantDate.Year()%4 == 0 && plantDate.Year()%100 != 0 || plantDate.Year()%400 == 0 { + pd -= 1 + } + + return CornMaturityConfig{ + PlantDate: pd, + Tmins: tmins, + Tmaxs: tmaxs, + Srads: srads, + Units: "F", + } +} + +func CalculateMaturity(ctx common.DawnCtx, request models.CornMaturityRequest) models.CornMaturityResponse { + + cfg := getFullYearData(ctx, request.Latitude, request.Longitude, request.PlantDate) + fileId := rand.Intn(99-10) + 10 + + file, _ := json.MarshalIndent(cfg, "", " ") + + _ = ioutil.WriteFile("lib/maize/"+strconv.Itoa(fileId)+".json", file, 0644) + + original, err := os.Open("lib/maize/DSSAT.INP") + if err != nil { + panic(err) + } + new, err := os.Create("lib/maize/DSSAT" + strconv.Itoa(fileId) + ".INP") + if err != nil { + panic(err) + } + _, err = io.Copy(new, original) + if err != nil { + panic(err) + } + new.Close() + original.Close() + + f, err := os.OpenFile("lib/maize/DSSAT"+strconv.Itoa(fileId)+".INP", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + panic(err) + } + + cultivarLine := fmt.Sprintf("%s %s %s %s %s %s %s %s %s", + request.VarNum, + request.VarName, + request.EcoNum, + fmt.Sprintf("%f", request.P1)[:5], + fmt.Sprintf("%f", request.P2)[:5], + fmt.Sprintf("%f", request.P5)[:5], + fmt.Sprintf("%f", request.G2)[:5], + fmt.Sprintf("%f", request.G3)[:5], + fmt.Sprintf("%f", request.PHINT)[:5], + ) + + if _, err = f.WriteString(cultivarLine); err != nil { + panic(err) + } + f.Close() + + cmd := exec.Command("bash", "-c", "python3 execute.py --input "+strconv.Itoa(fileId)+".json --config "+strconv.Itoa(fileId)+" --predicted") + cmd.Dir = "./lib/maize" + out, _ := cmd.Output() + + value := strings.TrimSpace(string(out)) + if value == "-1" || strings.HasPrefix(value, "A") { + panic(config.BAD_REQUEST) + } + + year, _ := strconv.Atoi(value[:4]) + doy, _ := strconv.Atoi(value[4:]) + + date := time.Date(year, time.January, 1, 0, 0, 0, 0, time.UTC) + if year%4 == 0 && year%100 != 0 || year%400 == 0 { + doy -= 1 + } + date = date.AddDate(0, 0, doy) + + os.Remove("lib/maize/" + strconv.Itoa(fileId) + ".json") + os.Remove("lib/maize/DSSAT" + strconv.Itoa(fileId) + ".INP") + + return models.CornMaturityResponse{ + HarvestDate: date, + } +} diff --git a/services/seed_service.go b/services/seed_service.go index d1a9eedf80ced15a1cb0460db1987ef55a336dc1..c26b2590d9563315218af6f8b5ddf90a6827bd1e 100644 --- a/services/seed_service.go +++ b/services/seed_service.go @@ -1,69 +1,69 @@ package services -import ( - "math" - "time" +// import ( +// "math" +// "time" - "gitlab.cs.umd.edu/dawn/dawn-go-common/common" - "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/config" - "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/persistence" - "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/utils" +// "gitlab.cs.umd.edu/dawn/dawn-go-common/common" +// "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/config" +// "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/persistence" +// "gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/utils" - "github.com/gofiber/fiber/v2" -) +// "github.com/gofiber/fiber/v2" +// ) -func GetSeedList(c *fiber.Ctx, request models.SeedListRequest) models.SeedListResponse { - product := enums.GetProductFromString(request.Product) - if product.Name != enums.ProductType.CORN.Name && product.Name != enums.ProductType.SOYBEAN.Name { - panic(config.INVALID_PRODUCT(request.Product)) - } - seeds := persistence.FindSeeds(product.Name) - var results []string - for i := 0; i < len(seeds); i++ { - results = append(results, seeds[i].Seed) - } - return models.SeedListResponse{Seeds: results} -} +// func GetSeedList(c *fiber.Ctx, request models.SeedListRequest) models.SeedListResponse { +// product := enums.GetProductFromString(request.Product) +// if product.Name != enums.ProductType.CORN.Name && product.Name != enums.ProductType.SOYBEAN.Name { +// panic(config.INVALID_PRODUCT(request.Product)) +// } +// seeds := persistence.FindSeeds(product.Name) +// var results []string +// for i := 0; i < len(seeds); i++ { +// results = append(results, seeds[i].Seed) +// } +// return models.SeedListResponse{Seeds: results} +// } -func GetCornMaturityDate(ctx common.DawnCtx, request models.CornMaturityRequest) models.CornMaturityResponse { +// func GetCornMaturityDate(ctx common.DawnCtx, request models.CornMaturityRequest) models.CornMaturityResponse { - gddRequest := models.GddRequest{ - Year: time.Now().Year(), - Product: "corn", - Latitude: request.Latitude, - Longitude: request.Longitude, - Accumulate: false, - } +// gddRequest := models.GddRequest{ +// Year: time.Now().Year(), +// Product: "corn", +// Latitude: request.Latitude, +// Longitude: request.Longitude, +// Accumulate: false, +// } - gdds := GetFullYearGddValues(ctx, gddRequest) - closestValue := 0.0 - closestIdx := 0 - gdus := 0.0 +// gdds := GetFullYearGddValues(ctx, gddRequest) +// closestValue := 0.0 +// closestIdx := 0 +// gdus := 0.0 - startingDate := time.Date(time.Now().Year(), time.Month(request.Month), request.Date, 0, 0, 0, 0, time.UTC) - startingIdx := startingDate.Sub(time.Date(time.Now().Year(), time.January, 1, 0, 0, 0, 0, time.UTC)) - startingIdxVal := int(startingIdx.Hours() / 24) - if isLeapYear(time.Now().Year()) { - startingIdxVal -= 1 - } +// startingDate := time.Date(time.Now().Year(), time.Month(request.Month), request.Date, 0, 0, 0, 0, time.UTC) +// startingIdx := startingDate.Sub(time.Date(time.Now().Year(), time.January, 1, 0, 0, 0, 0, time.UTC)) +// startingIdxVal := int(startingIdx.Hours() / 24) +// if isLeapYear(time.Now().Year()) { +// startingIdxVal -= 1 +// } - for i := startingIdxVal; i < len(gdds.GddValues); i++ { - value := gdds.GddValues[i] - gdus += value - if math.Abs(gdus-request.Gdds) < math.Abs(closestValue-request.Gdds) { - closestValue = gdus - closestIdx = i - } - } - response := models.CornMaturityResponse{ - Date: utils.ConvertDateIdxToDate(closestIdx), - GDD: request.Gdds, - ClosestGDD: closestValue, - ClosestLatitude: gdds.ClosestLatitude, - ClosestLongitude: gdds.ClosestLongitude, - } - return response +// for i := startingIdxVal; i < len(gdds.GddValues); i++ { +// value := gdds.GddValues[i] +// gdus += value +// if math.Abs(gdus-request.Gdds) < math.Abs(closestValue-request.Gdds) { +// closestValue = gdus +// closestIdx = i +// } +// } +// response := models.CornMaturityResponse{ +// Date: utils.ConvertDateIdxToDate(closestIdx), +// GDD: request.Gdds, +// ClosestGDD: closestValue, +// ClosestLatitude: gdds.ClosestLatitude, +// ClosestLongitude: gdds.ClosestLongitude, +// } +// return response -} +// }