diff --git a/.gitignore b/.gitignore
index 8ab2149e584fa00e61611fc7e781d576cc7e048c..75ffdd60fa16c59dac9d3680f19dbfd06467902e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@
 /node_modules
 /.vs
 *.png
-*.npy
\ No newline at end of file
+*.npy
+*.csv
\ No newline at end of file
diff --git a/controllers/cfsController.js b/controllers/cfsController.js
new file mode 100644
index 0000000000000000000000000000000000000000..c51015f1183e1d0bc63a94f2f802aa63f1710c19
--- /dev/null
+++ b/controllers/cfsController.js
@@ -0,0 +1,112 @@
+cfs = require('../models/cfs.js');
+current_year = require('../models/gdd_current.js');
+utils = require('../lib/utils');
+
+function find(collection, query, projection, t_base, res, product) {
+    current_year.find(query).limit(1).then(function(cy) {
+        var min_temps = cy[0]["min_temps"]
+        var max_temps = cy[0]["max_temps"]
+  
+        var gdd_sum_cy = 0;
+        
+        for (var i = 0; i < min_temps.length; i++) {
+            gdd_value = utils.calculate_gdd(min_temps[i], max_temps[i], t_base, product);
+            gdd_sum_cy += gdd_value
+        }
+
+        collection.find(query).limit(200).then(function(data) {
+            // console.log(data);
+            var base_date = data[0]["time"]
+            var lat = data[0]["location"]["coordinates"][1]
+            var lon = data[0]["location"]["coordinates"][0]
+            var gdds = []
+            var i = 0;
+            while (data[i] !== undefined) {
+                if (lat != data[i]["location"]["coordinates"][1] ||
+                lon != data[i]["location"]["coordinates"][0]) {
+                    break;
+                }
+                gdd_value = utils.calculate_gdd(data[i].min_temp, data[i].max_temp, t_base, product);
+                gdd_sum_cy += gdd_value
+                gdds.push(gdd_sum_cy)
+                i += 1
+            }
+            // for (var i = 0; i < 10; i++) {
+            //     
+            // }
+        
+            res.json({
+                message: "CFS GDD",
+                data: gdds,
+                base_date: base_date,
+                closest_lon: data[0]["location"]["coordinates"][0],
+                closest_lat: data[0]["location"]["coordinates"][1]
+            })
+        }, function(err) {
+            res.status(500).send({"internal error": err})
+        })
+
+    }, function(err) {
+        res.status(500).send({"internal error": err})
+    })
+    
+}
+
+
+exports.cfs = function (req, res) {
+    var product = req.params.product;
+
+    var latitude = parseFloat(req.body.latitude)
+    var longitude = parseFloat(req.body.longitude)
+    
+    var query = {
+        location: { 
+            "$near": {
+                "$geometry": {
+                    "type": "Point", 
+                    "coordinates": [longitude, latitude]
+                },
+            },
+        },
+    }
+
+    var projection = {
+        min_temp: 1,
+        max_temp: 1,
+        location: 1,
+    }
+    
+    var t_base = 50
+
+    errors = []
+
+    if (latitude < 24.083334 || latitude > 49.916668) {
+        errors.push({
+            parameter_error: "latitude",
+            message: latitude.toString() + " is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668"
+        });
+    }
+
+    if (req.body.hasOwnProperty("t_base")) {
+        t_base = parseFloat(req.body.t_base);
+    } else {
+        out = utils.product_base_switch(product, errors, t_base);
+        t_base = out.t_base;
+        errors = out.errors;
+    }
+
+    if (longitude < -125 || longitude > -66.5) {
+        errors.push({
+            parameter_error: "longitude",
+            message: longitude.toString() + " is out of bounds for GDD calculations. Must be between -125.0 - -66.5"
+        });
+    }
+
+    if (errors.length > 0) {
+        res.status(400).send({
+            errors: errors
+        })
+    }
+
+    find(cfs, query, projection, t_base, res, product);
+};
\ No newline at end of file
diff --git a/models/cfs.js b/models/cfs.js
new file mode 100644
index 0000000000000000000000000000000000000000..48453757acf8be1aa1f945b22c812cbc1a313e23
--- /dev/null
+++ b/models/cfs.js
@@ -0,0 +1,30 @@
+var mongoose = require('mongoose');
+//schema
+var coordinatesSchema = mongoose.Schema({
+    id_: {
+        type: String,
+        required: true
+    },
+    location: {
+        type: {
+            type: String,
+            enum: ['Point', 'Polygon']
+        },
+        coordinates: [Number],
+    },
+    max_temp: {
+        type: Number,
+        required: true
+    },
+    min_temp: {
+        type: Number,
+        required: true
+    },
+    time: {
+        type: Date,
+        default: Date.now
+    },
+});
+
+var Model = module.exports = mongoose.model('cfs', coordinatesSchema, "gefs");
+
diff --git a/routes.js b/routes.js
index 1d5d4495146ab68de3d4d982ae7c6efed4d3b964..cf3fda3d7dea52ab95dfb7072eee80b6ee5653f0 100644
--- a/routes.js
+++ b/routes.js
@@ -5,10 +5,12 @@ const normController = require("./controllers/gddNormalController")
 const freezingDatesController = require("./controllers/freezingDatesController")
 const confidenceIntervalController = require("./controllers/gddConfidenceInterval")
 const gefsController = require("./controllers/gefsController")
+const cfsController = require("./controllers/cfsController")
 
 router.route("/:product/daily/:year/accumulated").post(accController.accumulated_gdd)
 router.route("/:product/daily/:year").post(controller.year_gdd)
 router.route("/:product/gefs/accumulated").post(gefsController.gefs)
+router.route("/:product/cfs/accumulated").post(cfsController.cfs)
 router.route("/:product/normal").post(normController.normal)
 router.route("/:product/confidence").post(confidenceIntervalController.confidence_interval)
 router.route("/:product/normal/accumulated").post(accController.accumulated_normal_gdd)
diff --git a/swagger_definition.yaml b/swagger_definition.yaml
index 0456d5ee50287d1031473e7300748135e41be78b..6085b65e80870eddc944157a9918bdd2073c2853 100644
--- a/swagger_definition.yaml
+++ b/swagger_definition.yaml
@@ -614,6 +614,94 @@ paths:
                                     minimum: -125.0
                                     maximum: -66.5
                                     example: -76.94
+            400:
+                description: Bad Request
+                content:
+                    application/json:
+                        schema:
+                            type: object
+                            properties:
+                                errors:
+                                    type: array
+                                    items:
+                                        type: object
+                                        properties:
+                                            parameter_error:
+                                                type: string
+                                                example: latitude
+                                            message:
+                                                type: string
+                                                example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668
+    /api/{product}/cfs/accumulated:
+      post:
+        summary: Returns CFS forecast GDD data
+        description: Returns accumulated CFS forecast GDD data for a specific product, lat, and lon
+        produces:
+            - application/json
+        consumes:
+            - application/json
+        parameters:
+          - in: path
+            name: product
+            required: true
+            description: Agricultural product to calculate gdd for
+            schema:
+                type: string
+                enum: [corn, cotton, oat, peanut, pea, potato, rice, soybean, sorghum, spring_wheat, sugar_beet, sunflower, tomato, wheat]
+        requestBody:
+            content:
+                application/json:
+                    schema:
+                        type: object
+                        required:
+                            - longitude
+                            - latitude
+                        properties:
+                            latitude:
+                                description: latitude to calculate gdd on
+                                type: number
+                                minimum: 24.083334
+                                maximum: 49.916668
+                                example: 38.99
+                            longitude:
+                                description: longitude to calculate gdd on
+                                type: number
+                                minimum: -125.0
+                                maximum: -66.5
+                                example: -76.94
+                            t_base:
+                                description: Base temperature to calculate gdd on, in fahrenheit. NOT REQUIRED
+                                type: number
+                                example: 50
+                
+        responses:
+            200:
+                description: Success
+                content:
+                    application/json:
+                        schema:
+                            type: object
+                            properties:
+                                message:
+                                    type: string
+                                    example: CFS GDD
+                                base_date:
+                                    type: string
+                                    format: date
+                                data:
+                                    type: array
+                                    items:
+                                        type: number
+                                closest_lat:
+                                    type: number
+                                    minimum: 24.083334
+                                    maximum: 49.916668
+                                    example: 38.99
+                                closest_lon:
+                                    type: number
+                                    minimum: -125.0
+                                    maximum: -66.5
+                                    example: -76.94
             400:
                 description: Bad Request
                 content:
diff --git a/test_server.py b/test_server.py
index e2919ad89d497cd8c1240d6f373753cf02ba9912..bfa6ac23319f5aced48864a43e1ecc4396249b7a 100644
--- a/test_server.py
+++ b/test_server.py
@@ -3,54 +3,97 @@ import os
 import time 
 import matplotlib.pyplot as plt
 import numpy as np
-
+from pymongo import MongoClient
+import pandas as pd 
 data = {
     "latitude": 38.98567,
     "longitude": -76.94146
 }
-
 t = time.time()
+
+client = MongoClient("mongodb+srv://gdd-server:u8i3icLAJXjZEhTs@cluster0.wdxf4.mongodb.net")
+
+db = client["gdd_database"]
+gdd = db["gdd_current"]
+
+query = {
+        "location": { 
+            "$near": {
+                "$geometry": {
+                    "type": "Point", 
+                    "coordinates": [float(data["longitude"]), float(data["latitude"])]
+                },
+            },
+        },
+    }
+
+min_temps = []
+max_temps = []
+for loc_data in gdd.find(query).limit(1):
+    min_temps = loc_data["min_temps"]
+    max_temps = loc_data["max_temps"]
+
+
+
+crops = ["corn", "soybean", "cotton", "wheat", "oat", "potato", "rice", "pea"]
+
+crop_data = {}
+temps = []
+
+for c in crops:
+    print (c)
+    df = pd.DataFrame(columns=("min_temp", "max_temp", "gdd"))
+
+    r = requests.post("http://localhost:4000/api/%s/daily/2021/accumulated" % c, data=data)
+    print (r.json())
+    crop_gdd = r.json()["data"]
+    for mt, mat, gd in zip(min_temps, max_temps, crop_gdd):
+        da = {"min_temp": mt, "max_temp": mat, "gdd": gd}
+        df = df.append(da, ignore_index=True)
+    
+    df.to_csv("2021_%s.csv" % c)
+
 # r = requests.post("http://localhost:4000/api/soybean/daily/1981", data=data)
+# # print (r.status_code)
+# # print (r.json())
+# # print (time.time() - t)
+# # print ()
+# # r = requests.post("http://localhost:4000/api/soybean/daily/2016", data=data)
+# # print (r.status_code)
+# # print (r.json())
+# # print (time.time() - t)
+# # print ()
+# r = requests.post("http://localhost:4000/api/soybean/normal", data=data)
 # print (r.status_code)
 # print (r.json())
 # print (time.time() - t)
 # print ()
-# r = requests.post("http://localhost:4000/api/soybean/daily/2016", data=data)
+# r = requests.post("http://localhost:4000/api/soybean/gefs", data=data)
 # print (r.status_code)
 # print (r.json())
 # print (time.time() - t)
-# print ()
-r = requests.post("http://localhost:4000/api/soybean/normal", data=data)
-print (r.status_code)
-print (r.json())
-print (time.time() - t)
-print ()
-r = requests.post("http://localhost:4000/api/soybean/gefs", data=data)
-print (r.status_code)
-print (r.json())
-print (time.time() - t)
-# r = requests.post("http://localhost:4000/api/freezing/28.2", data=data)
-# print (r.status_code)
-# print (r.json())
-# r = requests.post("http://localhost:4000/api/corn/confidence", data=data)
-# print (r.status_code)
-# print (r.json())
+# # r = requests.post("http://localhost:4000/api/freezing/28.2", data=data)
+# # print (r.status_code)
+# # print (r.json())
+# # r = requests.post("http://localhost:4000/api/corn/confidence", data=data)
+# # print (r.status_code)
+# # print (r.json())
 
-# min_gdds = r.json()["minimum"]
-# max_gdds = r.json()["maximum"]
+# # min_gdds = r.json()["minimum"]
+# # max_gdds = r.json()["maximum"]
 
-# r = requests.post("http://localhost:4000/api/corn/normal/accumulated", data=data)
-# print (r.status_code)
-# print (r.json())
+# # r = requests.post("http://localhost:4000/api/corn/normal/accumulated", data=data)
+# # print (r.status_code)
+# # print (r.json())
 
-# normals = r.json()["data"]
+# # normals = r.json()["data"]
 
-# # max_gdds = np.array(max_gdds) + np.array(normals)
-# # max_gdds /= 2
-# # min_gdds = np.array(min_gdds) + np.array(normals)
-# # min_gdds /= 2
+# # # max_gdds = np.array(max_gdds) + np.array(normals)
+# # # max_gdds /= 2
+# # # min_gdds = np.array(min_gdds) + np.array(normals)
+# # # min_gdds /= 2
 
-# plt.plot(list(range(len(normals))), normals, color="black")
-# plt.plot(list(range(len(normals))), max_gdds, color="orange")
-# plt.plot(list(range(len(normals))), min_gdds, color="blue")
-# plt.savefig("test.png", dpi=600)
\ No newline at end of file
+# # plt.plot(list(range(len(normals))), normals, color="black")
+# # plt.plot(list(range(len(normals))), max_gdds, color="orange")
+# # plt.plot(list(range(len(normals))), min_gdds, color="blue")
+# # plt.savefig("test.png", dpi=600)
\ No newline at end of file