diff --git a/dashboards/solarplus-ui/main.py b/dashboards/solarplus-ui/main.py index e98182b6..5d000608 100644 --- a/dashboards/solarplus-ui/main.py +++ b/dashboards/solarplus-ui/main.py @@ -250,7 +250,7 @@ def cieeData(): ciee = pd.read_csv("./sample_data/ciee.csv") ciee.columns = ['TimeStamp', 'ciee', 's0', 's1', 's2', 's3'] - #limiting to 20 entries like prev demo + #limiting to 20 entries ciee = ciee[:20] return ciee.to_json(orient='records') @@ -259,6 +259,12 @@ def cieeData(): @main.route('/cieeData//') @crossdomain(origin="*") def extractData(startDate, endDate): + """ + + Not used in the project anymore + Extracts data using start date and end date + + """ cieeDF = pd.read_csv("./sample_data/ciee.csv") cieeDF.columns = ['TimeStamp', 'ciee', 's0', 's1', 's2', 's3'] @@ -281,16 +287,34 @@ def extractData(startDate, endDate): #fetching data in the specific timeframe dataInRange = cieeDF[startDateIndex:(endDateIndex+1)] - #print(dataInRange) return dataInRange.to_json(orient = 'records') -# This function takes in a file name, start and end date with the two features that -# the user wants plotted on the graph @main.route('/////') @crossdomain(origin="*") def extractData_plotTwoQueries(filename, startDate, endDate, feature1, feature2): + + """ + Not used in the project anymore + extractData_plotTwoQueries(filename, startDate, endDate, feature1, feature2) + + Parameters + ---------- + filename: str, + startDate: str (formatted as yyyy-mm-dd), + endDate: str (formatted as yyyy-mm-dd), + feature1: str, + feature2: str + + This function takes in a file name, start and end date with the two features that + the user wants plotted on the graph + + Returns + ------- + JSON object + pandas dataframe that is converted to JSON object to hold the data of dates and 2 features' values + """ filePathString = "./solarplus_sample_data/" + filename+".csv" print(filePathString) @@ -329,7 +353,28 @@ def extractData_plotTwoQueries(filename, startDate, endDate, feature1, feature2) @main.route('/analysis/MLModel///////') @crossdomain(origin="*") def MLPredictionModel(day1, day2, day3, day4, day5, day6, day7): - print(day1, day2, day3, day4, day5, day6, day7) + + """ + MLPredictionModel(day1, day2, day3, day4, day5, day6, day7) + + Parameters + ---------- + day1 : str + day2 : str + day3 : str + day4 : str + day5 : str + day6 : str + day7 : str + + The function predicts the solar power generated given the temperatures of different days + + Returns + ------- + JSON object + pandas dataframe that is converted to JSON object to hold the data of dates and predicted values + """ + filename = './solarplus-ui/trained_model.sav' loaded_model = pickle.load(open(filename, 'rb')) @@ -341,46 +386,122 @@ def MLPredictionModel(day1, day2, day3, day4, day5, day6, day7): X_pred=[float(day1), float(day2), float(day3), float(day4), float(day5), float(day6), float(day7)] dataset = pd.DataFrame({'X_pred': X_pred, 'Column1':Y_pred}) - #dataset = pd.DataFrame.from_records(Y_pred) - - #print(Y_pred[0]) - print(dataset) - #Y_pred0 = {'temperature': Y_pred[0]} - - #return make_response(dumps(Y_pred)) return dataset.to_json(orient = 'records') -# This function extracts data for any feature's data from Control.csv data -# of the solarplus sample data -> will be used for total power consumption -# values for dashboard + @main.route('/dashboard/access/') @crossdomain(origin="*") def extractData_oneFeature_Control2(feature1): + + """ + extractData_oneFeature_Control2(feature1) + + Parameters + ---------- + feature1 : str + + This function extracts data for any feature's data from Control.csv data + of the solarplus sample data -> will be used for total power consumption + values for dashboard + + Returns + ------- + JSON object + pandas dataframe that is converted to JSON object to hold the data of dates and feature1 values + """ filePathString = "./solarplus-ui/solarplus_sample_data/Control2.csv" readDF = pd.read_csv(filePathString) df = readDF.loc[:,['Time',feature1]] return df.to_json(orient = 'records') -# This function extracts data for any 2 features' data from Control.csv data -# of the solarplus sample data -> will be used for HVAC1 and HVAC2 -# values for dashboard + @main.route('/dashboard/access//') @crossdomain(origin="*") def extractData_twoFeatures_Control2(feature1, feature2): + """ + + Parameters + ---------- + feature1 : str + feature2 : str + + This function extracts data for any 2 features' data from Control.csv data + of the solarplus sample data -> will be used for HVAC1 and HVAC2 + values for dashboard + + Returns + ------- + JSON object + pandas dataframe that is converted to JSON object to hold the data of dates and feature1 and feature2 values + """ filePathString = "./solarplus-ui/solarplus_sample_data/Control2.csv" readDF = pd.read_csv(filePathString) df = readDF.loc[:,['Time',feature1,feature2]] return df.to_json(orient = 'records') -# This function extracts data for solar production values from @main.route('/dashboard/PVPowerGenData') @crossdomain(origin="*") def extractData_PVPowerGenData(): - filePathString = "./Historic_microgrid_data/PVPowerGenData.csv" + """ + extractData_PVPowerGenData() + + This function extracts data for solar production values from + + """ + filePathString = "./solarplus-ui/Historic_microgrid_data/PVPowerGenData.csv" readDF = pd.read_csv(filePathString) df = readDF.loc[:,['Date_PT','PVPower_kW']] return df.to_json(orient = 'records') + + +@main.route('/dashboard/access//average') +@crossdomain(origin="*") +def extractData_oneFeature_Control3(feature1): + """ + extractData_oneFeature_Control3(feature1) + + Parameters + ---------- + feature1 : str + + This function extracts data for any feature's data from Control.csv data + of the solarplus sample data -> will be used for average power consumption + values + + Returns + ------- + JSON object + pandas dataframe that is converted to JSON object to hold the data of dates and average values + """ + filePathString = "./solarplus-ui/solarplus_sample_data/Control2.csv" + readDF = pd.read_csv(filePathString) + + df = readDF.loc[:,['Time',feature1]] + + # loop here to go through the dataframe and calculate the average + nextEntryIndex = df.index[0] + df_model = pd.DataFrame() #creating an epty dataframe that feeds to model + df_model = pd.DataFrame(columns=['Time', feature1]) + + #having a while loop that runs till the power dataframe is empty since that is shorter + while not df.empty: + # getting the date of the entry we want to deal with + currDateEntry = df.iloc[nextEntryIndex].Time + currDate = (currDateEntry.split(' '))[0] + print(currDateEntry) + + #obtaining average power production of a day + currDateEntries_power = df[df['Time'].str.contains(currDate)].Building + currDateEntriesPowerAverage = sum(currDateEntries_power)/len(currDateEntries_power) + df_model.loc[len(df_model)] = [currDate, currDateEntriesPowerAverage] + + df = df[~df.Time.str.contains(currDate)] + # finding the next date to perform the same operations on, as long as the dataframe is not alraedy empty + if not df.empty: + nextEntryIndex_power = df.index[0] + + return df_model.to_json(orient = 'records') \ No newline at end of file diff --git a/dashboards/solarplus-ui/static/assets/js/analysis-mlgraph.js b/dashboards/solarplus-ui/static/assets/js/analysis-mlgraph.js index 548c63b0..72192f85 100644 --- a/dashboards/solarplus-ui/static/assets/js/analysis-mlgraph.js +++ b/dashboards/solarplus-ui/static/assets/js/analysis-mlgraph.js @@ -4,17 +4,24 @@ $(document).ready(function () { return (value); } + /* + * Graphs the temperature, days, and solar power + * + * @author: Raja Vyshnavi Sriramoju + * @param {Array of numbers} predictedSolarVals + * @param {Array of numbers} tempVals - the max temperatures for the following week + * @param {Array of Strings} daysArray - the days of the week starting from the next day + */ function renderChart(predictedSolarVals, tempVals, daysArray) { var highChart = new Highcharts.chart('predictionChart', { chart: { - //type: 'line', zoomType: "xy" }, title: { text: 'Predicted Solar production values' }, tooltip: { - valueSuffix: '\xB0C' + valueSuffix: '\xB0C' //the suffix when you hover over the graph for temperature }, xAxis: { categories: daysArray, @@ -22,10 +29,11 @@ $(document).ready(function () { }, yAxis: [ { + //creating the 2 y-axis elements in the array labels: { format: '{value}°C' }, - opposite: true, + opposite: true, //creating axis on the oppposite sides title: { text: 'Forecast Temperature' }, @@ -68,6 +76,13 @@ $(document).ready(function () { }); } + /* + * Request url and returns recieved data + * + * @author: Raja Vyshnavi Sriramoju + * @param {string} url for the flask server + * @return {JSON} The prediction values from flask. + */ function Get(yourUrl) { var Httpreq = new XMLHttpRequest(); // a new request Httpreq.open("GET", yourUrl, false); @@ -75,24 +90,31 @@ $(document).ready(function () { return Httpreq.responseText; } + /* + * Retrieves max temperature data from 'Weather' tab and predicts the predicted solar power generated in the next week + * Calls renderChart() to plot the values + * @author: Raja Vyshnavi Sriramoju + */ function graphData_MLModel() { - // TODO: have to extract daily values instead of static ones for now var forecast_TempVals = sessionStorage.getItem("temperatureVals"); forecast_TempVals = JSON.parse(forecast_TempVals); - console.log("Printing vals from weather tab"); - console.log(forecast_TempVals); + //console.log("Printing vals from weather tab"); + //console.log(forecast_TempVals); + + if (forecast_TempVals == null){ + document.getElementById("predictionChart").innerHTML = "Weather Values have not been obtained for prediction of solar power production. Please visit Weather tab first."; + } - //var tempVals = [14,19,18,17,18,20,22]; const uri_chart1 = `http://127.0.0.1:5000/analysis/MLModel/${forecast_TempVals[0]}/${forecast_TempVals[1]}/${forecast_TempVals[2]}/${forecast_TempVals[3]}/${forecast_TempVals[4]}/${forecast_TempVals[5]}/${forecast_TempVals[6]}`; var res_chart1 = JSON.parse(Get(uri_chart1)); - console.log(res_chart1); var d = new Date(); var today = d.getDay(); var days = []; + //This creates the array of days for the x-axis values for(let j = 0; j < 7; j++) { switch(today){ @@ -120,18 +142,18 @@ $(document).ready(function () { var predictedSolarVals = []; var labels = []; - //res_chart1.length for (let i = 0; i < 7; i++) { let singleElement = res_chart1[i]; for (let prop in singleElement) { if (prop == 'Column1') - predictedSolarVals.push(singleElement[prop]); + predictedSolarVals.push(singleElement[prop]); //will be y-values } } - renderChart(predictedSolarVals, forecast_TempVals, days); + renderChart(predictedSolarVals, forecast_TempVals, days); //x-values } + //making the function call so that call is made as soon as html page loads graphData_MLModel(); }); \ No newline at end of file diff --git a/dashboards/solarplus-ui/static/assets/js/index/dashboard-graphs.js b/dashboards/solarplus-ui/static/assets/js/index/dashboard-graphs.js index 9670e4e0..4699b423 100644 --- a/dashboards/solarplus-ui/static/assets/js/index/dashboard-graphs.js +++ b/dashboards/solarplus-ui/static/assets/js/index/dashboard-graphs.js @@ -4,6 +4,14 @@ $(document).ready(function () { return (value); } + /* + * Graphs the total power consumption vs time + * + * @author: Raja Vyshnavi Sriramoju + * @param {Array of numbers} yVals - the power consumption values + * @param {String} yValsTitle - the string for the y-axis title + * @param {Array of Strings} dates - the dates for the power consumption values + */ function renderChart1(yVals, yValsTitle, dates) { var highChart = new Highcharts.chart('chart1', { chart: { @@ -14,7 +22,7 @@ $(document).ready(function () { text: 'Total Power Consumption' }, tooltip: { - valueSuffix: '\xB0C' + valueSuffix: ' kWh' }, xAxis: { categories: dates @@ -25,7 +33,10 @@ $(document).ready(function () { }, plotLines: [{ value: 0 - }] + }], + labels: { + format: '{value} kWh' + } }, series: [{ name: yValsTitle, @@ -35,11 +46,20 @@ $(document).ready(function () { }); } + + /* + * Graphs the total power consumption vs time + * + * @author: Raja Vyshnavi Sriramoju + * @param {String} feature1 - the string for the y-axis title for 1st feature + * @param {String} feature2 - the string for the y-axis title for 2nd feature + * @param {Array of numbers} feature1Vals - the power consumption values for 1st feature + * @param {Array of numbers} feature2Vals - the power consumption values for 2nd feature + * @param {Array of Strings} dates - the dates for the power consumption values + */ function renderChart2(feature1, feature2, feature1Vals, feature2Vals, dates) { - //var ctx = document.getElementById("myChart").getContext('2d'); var highChart = new Highcharts.chart('chart2', { chart: { - //renderTo: "myChart", type: 'column', zoomType: "x" }, @@ -47,7 +67,7 @@ $(document).ready(function () { text: 'HVAC Power Consumption' }, tooltip: { - valueSuffix: '\xB0C' + valueSuffix: ' kWh' }, xAxis: { categories: dates @@ -58,8 +78,12 @@ $(document).ready(function () { }, plotLines: [{ value: 0 - }] + }], + labels: { + format: '{value} kWh' + } }, + //series consists of the 2 features with names that are to be plotted series: [{ name: feature1, data: feature1Vals @@ -72,81 +96,102 @@ $(document).ready(function () { }); } - function renderChart3(feature1, feature2, feature1Vals, feature2Vals, dates) { - //var ctx = document.getElementById("myChart").getContext('2d'); + + /* + * Graphs the average power consumption vs time + * + * @author: Raja Vyshnavi Sriramoju + * @param {Array of numbers} yVals - the average power consumption values + * @param {String} yValsTitle - the string for the y-axis title + * @param {Array of Strings} dates - the dates for the power consumption values + */ + function renderChart3(yVals, yValsTitle, dates) { var highChart = new Highcharts.chart('chart3', { chart: { - //renderTo: "myChart", type: 'line', zoomType: "x" }, title: { - text: 'Power Consumption' + text: 'Average Power Consumed' }, tooltip: { - valueSuffix: '\xB0C' + valueSuffix: ' kWh' }, xAxis: { categories: dates }, yAxis: { title: { - text: 'Consumption' + text: 'Power Consumed' }, plotLines: [{ value: 0 - }] + }], + labels: { + format: '{value} kWh' + } + }, series: [{ - name: feature1, - data: feature1Vals - }, - { - name: feature2, - data: feature2Vals + name: yValsTitle, + data: yVals } ] }); } - function renderChart4(feature1, feature2, feature1Vals, feature2Vals, dates) { - //var ctx = document.getElementById("myChart").getContext('2d'); + + /* + * Graphs the total power generation vs time + * + * @author: Raja Vyshnavi Sriramoju + * @param {Array of numbers} yVals - the power generated values + * @param {String} yValsTitle - the string for the y-axis title + * @param {Array of Strings} dates - the dates for the power consumption values + */ + function renderChart4(yVals, yValsTitle, dates) { var highChart = new Highcharts.chart('chart4', { chart: { - //renderTo: "myChart", type: 'line', zoomType: "x" }, title: { - text: 'Power Consumption' + text: 'Total Power Generated' }, tooltip: { - valueSuffix: '\xB0C' + valueSuffix: ' kWh' }, xAxis: { categories: dates }, yAxis: { title: { - text: 'Consumption' + text: 'Power Generated' }, plotLines: [{ value: 0 - }] + }], + labels: { + format: '{value} kWh' + } + }, series: [{ - name: feature1, - data: feature1Vals - }, - { - name: feature2, - data: feature2Vals + name: yValsTitle, + data: yVals } ] }); } + /* + * Request url and returns recieved data + * + * @author: Raja Vyshnavi Sriramoju + * @param {string} url for the flask server + * @return {JSON} The prediction values from flask. + */ function Get(yourUrl) { var Httpreq = new XMLHttpRequest(); // a new request Httpreq.open("GET", yourUrl, false); @@ -154,6 +199,10 @@ $(document).ready(function () { return Httpreq.responseText; } + /* + * Fetches total power consumption data of the building from flask server and calls respective renderChart function + * @author: Raja Vyshnavi Sriramoju + */ function graphDataCollection_Chart1() { // will have to include code here about fetching data from the @@ -176,17 +225,22 @@ $(document).ready(function () { { buildingVals.push(singleElement[prop]); } - labels.push(res_chart1[i].Time); + if(prop == 'Time') + { + labels.push(res_chart1[i].Time); + } } } renderChart1(buildingVals, 'Total Power Consumption Values', labels); } + + /* + * Fetches power consumption data for two features from flask server and calls respective renderChart function + * @author: Raja Vyshnavi Sriramoju + */ function graphDataCollection_Chart2() { - // will have to include code here about fetching data from the - // selected features for the specific features on dashboard - //const feature = 'Building' const uri_chart1 = `http://127.0.0.1:5000/dashboard/access/HVAC1/HVAC2`; var res_chart1 = JSON.parse(Get(uri_chart1)); @@ -194,7 +248,6 @@ $(document).ready(function () { var feature2Vals = [] var labels = []; - //res_chart1.length for (let i = 0; i < 500; i++) { let singleElement = res_chart1[i]; @@ -212,54 +265,73 @@ $(document).ready(function () { } - function render() { - - var startDate = '2018-06-01'; - var endDate = '2018-06-02'; + /* + * Fetches average power consumption from flask server and calls respective renderChart function + * @author: Raja Vyshnavi Sriramoju + */ + function graphDataCollection_Chart3() { - var filename = 'Control2'; - var feature1 = 'HVAC2'; - var feature2 = 'HVAC1'; - - console.log(startDate); - console.log(endDate); - console.log(filename); - console.log(feature1); - console.log(feature2); + const uri_chart1 = `http://127.0.0.1:5000/dashboard/access/Building/average`; + var res_chart1 = JSON.parse(Get(uri_chart1)); + + var avgPowerVals = []; + labels = []; - const uri = `http://127.0.0.1:5000/${filename}/${startDate}/${endDate}/${feature1}/${feature2}`; - //const uri = 'http://127.0.0.1:5000/dashboard/access/HVAC1/HVAC2'; - var res = JSON.parse(Get(uri)); - console.log(res); + //res_chart1.length + for (let i = 0; i < res_chart1.length; i++) { + + let singleElement = res_chart1[i]; + + for (let prop in singleElement) { + if (prop == 'Building') + { + avgPowerVals.push(singleElement[prop]); + } + if(prop == 'Time') + { + labels.push(res_chart1[i].Time); + } + + } + } + console.log(labels); + renderChart3(avgPowerVals, 'Average Power Consumed Values', labels); - var feature1Vals = []; - var feature2Vals = [] - var labels = []; + } + /* + * Fetches total power generated values from flask server and calls respective renderChart function + * @author: Raja Vyshnavi Sriramoju + */ + function graphDataCollection_Chart4() { + const uri_chart1 = `http://127.0.0.1:5000/dashboard/PVPowerGenData`; + var res_chart1 = JSON.parse(Get(uri_chart1)); + + var PVGenVals = []; + labels = []; + + //res_chart1.length for (let i = 0; i < 500; i++) { - - let singleElement = res[i]; - + + let singleElement = res_chart1[i]; + //console.log(singleElement); + for (let prop in singleElement) { - if (prop == feature1) - feature1Vals.push(singleElement[prop]); - if (prop == feature2) - feature2Vals.push(singleElement[prop]); - } - labels.push(res[i].Time); - + if (prop == 'PVPower_kW') + { + PVGenVals.push(singleElement[prop]); + } + labels.push(res_chart1[i].Date_PT); + } } + renderChart4(PVGenVals, 'Total Power Generated Values', labels); - console.log(labels); - console.log(feature1Vals); - console.log(feature2Vals) - //renderChart1(feature1, feature2, feature1Vals, feature2Vals, labels); - renderChart2(feature1, feature2, feature1Vals, feature2Vals, labels); - renderChart3(feature1, feature2, feature1Vals, feature2Vals, labels); - renderChart4(feature1, feature2, feature1Vals, feature2Vals, labels); - }; - //render(); + } + //making the function calls so that call is made as soon as html page loads graphDataCollection_Chart1(); graphDataCollection_Chart2(); + graphDataCollection_Chart3(); + graphDataCollection_Chart4(); + }); \ No newline at end of file diff --git a/dashboards/solarplus-ui/templates/analysis.html b/dashboards/solarplus-ui/templates/analysis.html index 9382eb67..0270e43a 100644 --- a/dashboards/solarplus-ui/templates/analysis.html +++ b/dashboards/solarplus-ui/templates/analysis.html @@ -73,6 +73,23 @@ +
+
+
+
+ About + +

+ The following prediction chart takes the maximum temperatures of the upcoming week from the Weather tab, and uses them to + give a chart that shows the predicted solar power production from the solar panels at the facility for that + day. The predictions are made using Artificial Intelligence tools that predict based on past data from the facility. +

+
+
+
+ +
+
diff --git a/dashboards/solarplus-ui/weather_regression_model_train.py b/dashboards/solarplus-ui/weather_regression_model_train.py index ed00c6b7..6867248a 100644 --- a/dashboards/solarplus-ui/weather_regression_model_train.py +++ b/dashboards/solarplus-ui/weather_regression_model_train.py @@ -5,8 +5,18 @@ import pickle def createDataTable(): - df_temperature =pd.read_csv('./Historic_microgrid_data/AirTemperatureData.csv') - df_PVPower = pd.read_csv('./Historic_microgrid_data/PVPowerGenData.csv') + """ + createDataTable() + + Creates data table by parsing the csv files for Air temperature and power generated data + + Returns + ------- + pandas dataframe + The dataframe required to train the regression model. + """ + df_temperature =pd.read_csv('./solarplus-ui/Historic_microgrid_data/AirTemperatureData.csv') + df_PVPower = pd.read_csv('./solarplus-ui/Historic_microgrid_data/PVPowerGenData.csv') # eliminating all entries except for the ones in the time range # we are looking from 14th march to 24th april 2018 @@ -36,17 +46,12 @@ def createDataTable(): nextEntryIndex_power = df_PVPower.index[0] df_model = pd.DataFrame() #creating an epty dataframe that feeds to model - #df_model = pd.DataFrame(columns=['date', 'AirTemp_degC_Max', 'PVPower_kW_Sum']) df_model = pd.DataFrame(columns=['AirTemp_degC_Max', 'PVPower_kW_Sum']) - #print(dataInRange_temperature) - #print(dataInRange_power) - #having a while loop that runs till the power dataframe is empty since that is shorter + #having a while loop that runs till the power dataframe is empty while not dataInRange_power.empty: - #for x in range(4): # getting the date of the entry we want to deal with - #print(df_PVPower.iloc[df_PVPower.index[0]]) #[nextEntryIndex_power]) currDateEntry = dataInRange_power.iloc[nextEntryIndex_power].Date_PT currDate = (currDateEntry.split(' '))[0] print(currDateEntry) @@ -59,7 +64,6 @@ def createDataTable(): currDateEntries_power = dataInRange_power[dataInRange_power['Date_PT'].str.contains(currDate)].PVPower_kW currDateEntriesPowerSum = sum(currDateEntries_power) - #df_model.loc[len(df_model)] = [currDate, currDateEntriesTempMax, currDateEntriesPowerSum] df_model.loc[len(df_model)] = [currDateEntriesTempMax, currDateEntriesPowerSum] dataInRange_power = dataInRange_power[~dataInRange_power.Date_PT.str.contains(currDate)] @@ -76,6 +80,13 @@ def createDataTable(): return df_model def regression_model(): + """ + regression_model() + + Creates the regression model, trains it, and saves the model + + """ + #fetching the data table df_temperature_power = createDataTable() @@ -84,8 +95,6 @@ def regression_model(): temperature_xvals = np.array(df_temperature_power['AirTemp_degC_Max']).reshape((-1, 1)) power_yvals = np.array(df_temperature_power['PVPower_kW_Sum']) - print(df_temperature_power) - # Performing a train-test split to predict accuracy seed = 7 X_train, X_test, Y_train, Y_test = model_selection.train_test_split(temperature_xvals, power_yvals, @@ -103,16 +112,18 @@ def regression_model(): print('intercept:', linear_model.intercept_) print('slope:', linear_model.coef_) + # saving the trained model filename = 'trained_model.sav' pickle.dump(linear_model, open(filename, 'wb')) + # small test value x_pred = [[17]] y_pred = linear_model.predict(x_pred) print("y-values = ", y_pred) -#this will have to go into app.py +#test function def test(): filename = 'trained_model.sav' @@ -124,5 +135,5 @@ def test(): print(X_pred) print(Y_pred) -#regression_model() +#quick test test()