using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using DotSpatial.Data;

namespace SMAT_CE
{
    class BenMAPOzoneCommonClass
    {
        public static DateTime _beginTime;
        public static DateTime _endTime;

        public static string _resultFilePath = "";

        

        public static bool BenMapOzoneAnalysis(BaseScenario baseScenario, SMAT_CE mats)
        {
            if (!(baseScenario.configuration is BenMAPOzoneAnalysisConfiguration))
            {
                return false;
            }
            try
            {
                BenMAPOzoneAnalysisConfiguration ozoneAnalysisConfiguration = (baseScenario.configuration) as BenMAPOzoneAnalysisConfiguration;
                string sFirstLine = "";
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Begin loading Ozone monitor data...");
                //CommonClass.CurrentLog = "Begin loading Ozone monitor data...";
                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read monitor data \"" + Path.GetFileName(ozoneAnalysisConfiguration.monitorInput.ozoneMonitorDataFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                bool errorOccur = false;
                DataTable dtMonitor = CommonClass.getDataSetFromCSVAndFirstLine(ozoneAnalysisConfiguration.monitorInput.ozoneMonitorDataFile, ref sFirstLine, ref errorOccur);
                if (dtMonitor == null || errorOccur)
                {
                    CommonClass.CurrentLog = "Fail to read monitor data \"" + Path.GetFileName(ozoneAnalysisConfiguration.monitorInput.ozoneMonitorDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }
                //if (errorOccur)
                //{
                //    CommonClass.CurrentLog = "Skip some abnormal data.";
                //    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                //}
                string startYear = ozoneAnalysisConfiguration.monitorInput.ozoneStartYear.Split('-')[1];
                string endYear = ozoneAnalysisConfiguration.monitorInput.ozoneEndYear.Split('-')[1];
                List<string> lstMonitorYear = new List<string>();
                for (int i = Convert.ToInt16(startYear); i <= Convert.ToInt16(endYear); i++)
                {
                    lstMonitorYear.Add(i.ToString());
                }
                string lastYear = "";
                #region Read Monitor from csv
                Dictionary<string, OzoneMonitor> dicOzoneMonitor = new Dictionary<string, OzoneMonitor>();
                //-------首先得到各个字段的index-------
                int iID = -1, iType = -1, iLat = -1, iLong = -1, iPOC = -1, iDVYear = -1, iO3 = -1, iStateName = -1, iCountyName = -1;
                try
                {
                    for (int i = 0; i < dtMonitor.Columns.Count; i++)
                    {
                        DataColumn dc = dtMonitor.Columns[i];
                        switch (dc.ColumnName.ToLower().Trim())
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_type":
                                iType = i;
                                break;
                            case "lat":
                                iLat = i;
                                break;
                            case "long":
                                iLong = i;
                                break;
                            case "poc":
                                iPOC = i;
                                break;
                            case "dvyear":
                                iDVYear = i;
                                break;
                            case "_state_name":
                                iStateName = i;
                                break;
                            case "_county_name":
                                iCountyName = i;
                                break;
                            case "o3":
                                iO3 = i;
                                break;
                        }
                    }
                    //bool isOK = true;
                    foreach (DataRow dr in dtMonitor.Rows)
                    {
                        //try
                        //{
                        //----------解析Monitor 首先去掉=-9的值，然后根据StartYear 求出 StartYear,StartYear+1,StartYear+2的均值*10 -> int /10 最后仍然是int 值。如果都没有Ozone="."
                        //if ((dr[iDVYear].ToString() == ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0,4) ||
                        //    dr[iDVYear].ToString() == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 1).ToString() ||
                        //    dr[iDVYear].ToString() == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 2).ToString()))
                        //{
                        if (dicOzoneMonitor.ContainsKey(dr[iID].ToString()))
                        {
                            dicOzoneMonitor[dr[iID].ToString()].dicOzone.Add(dr[iDVYear].ToString(), Convert.ToDouble(dr[iO3]));

                        }
                        else
                        {
                            dicOzoneMonitor.Add(dr[iID].ToString(), new OzoneMonitor());
                            dicOzoneMonitor[dr[iID].ToString()].dicOzone = new Dictionary<string, double>();
                            dicOzoneMonitor[dr[iID].ToString()].dicOzone.Add(dr[iDVYear].ToString(), Convert.ToDouble(dr[iO3]));
                            dicOzoneMonitor[dr[iID].ToString()].id = dr[iID].ToString();
                            dicOzoneMonitor[dr[iID].ToString()].lat = Convert.ToDouble(dr[iLat]);
                            dicOzoneMonitor[dr[iID].ToString()].longitude = Convert.ToDouble(dr[iLong]);
                            dicOzoneMonitor[dr[iID].ToString()].county = dr[iCountyName].ToString();
                            dicOzoneMonitor[dr[iID].ToString()].state = dr[iStateName].ToString();
                        }
                        //}
                        //}
                        //catch
                        //{
                        //    isOK = false;
                        //}
                    }
                    //if (!errorOccur && !isOK)
                    //{
                    //    CommonClass.CurrentLog = "Skip some abnormal data.";
                    //    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    //}
                }
                catch
                {
                    CommonClass.CurrentLog = "Fail to read monitor data \"" + Path.GetFileName(ozoneAnalysisConfiguration.monitorInput.ozoneMonitorDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }
                dtMonitor.Dispose();
                GC.Collect();

                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentLog = "Finish reading monitor data: " + CommonClass.TotalTime + " s.";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                #region
                //--------------修正dicOzoneMonitor的坐标系！-------------------
                double[] dConvertArrayMonitor = null;
                List<double> lstConvertArrayMonitor = new List<double>();
                List<string> lstKeyMonitor = dicOzoneMonitor.Keys.ToList();
                for (int iLstKey = 0; iLstKey < dicOzoneMonitor.Keys.Count; iLstKey++)
                {
                    lstConvertArrayMonitor.Add(dicOzoneMonitor[lstKeyMonitor[iLstKey]].longitude);
                    lstConvertArrayMonitor.Add(dicOzoneMonitor[lstKeyMonitor[iLstKey]].lat);
                }
                dConvertArrayMonitor = lstConvertArrayMonitor.ToArray();
                DotSpatial.Projections.Reproject.ReprojectPoints(dConvertArrayMonitor, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984,
                   DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ), 0, dConvertArrayMonitor.Length / 2);
                for (int iLstKey = 0; iLstKey < dicOzoneMonitor.Keys.Count; iLstKey++)
                {
                    dicOzoneMonitor[lstKeyMonitor[iLstKey]].longitudeLamber = dConvertArrayMonitor[2 * iLstKey] / 100.00;
                    dicOzoneMonitor[lstKeyMonitor[iLstKey]].latitudeLamber = dConvertArrayMonitor[2 * iLstKey + 1] / 100.00;
                }
                #endregion
                List<string> lstrequiredDVPeriods = new List<string>();
                //if (ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods != "None selected")
                //{
                //    string[] s = ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Split(',');
                //    for (int i = 0; i < s.Count(); i++)
                //    {
                //        lstrequiredDVPeriods.Add(s[i].Substring(s[i].Length - 4, 4));
                //    }
                //}
                //ozoneAnalysisConfiguration.filteringInterpolationO.minNumDV = ozoneAnalysisConfiguration.filteringInterpolationO.minNumDV > lstMonitorYear.Count ? lstMonitorYear.Count : ozoneAnalysisConfiguration.filteringInterpolationO.minNumDV;
                foreach (KeyValuePair<string, OzoneMonitor> k in dicOzoneMonitor)
                {
                    //dicOzoneMonitor[k.Key].dicOzone = dicOzoneMonitor[k.Key].dicOzone.Where(p => p.Value != -9).ToList();
                    if (k.Key == "011210003")
                    {

                    }
                    List<double> lstTemp = new List<double>();
                    bool isValid = true;
                    int iValid = 0;
                    //if (ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods == "None Selected")
                    //{
                    //    foreach (KeyValuePair<string, double> kin in dicOzoneMonitor[k.Key].dicOzone)
                    //    {
                    //        if(lstMonitorYear.Contains(kin.Key))
                    //        //if ((kin.Key == ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4) ||
                    //        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + 1).ToString() ||
                    //        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + 2).ToString()))
                    //        {
                    //            if (kin.Value > -9)
                    //            {
                    //                lstTemp.Add(kin.Value);
                    //                iValid++;
                    //            }
                    //        }
                    //    }
                    //}
                    //else
                    //{
                    foreach (KeyValuePair<string, double> kin in dicOzoneMonitor[k.Key].dicOzone)
                    {
                        if (lstMonitorYear.Contains(kin.Key))
                        //if ((kin.Key == ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4) ||
                        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + 1).ToString() ||
                        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + 2).ToString()))
                        {
                            if (kin.Value >= 0)
                            {
                                lstTemp.Add(kin.Value);
                                iValid++;
                            }
                            else if (lstrequiredDVPeriods.Contains(kin.Key))
                            {
                                isValid = false;
                                break;
                            }

                        }
                    }
                    //}
                    if (iValid < 1)//ozoneAnalysisConfiguration.filteringInterpolationO.minNumDV)
                        isValid = false;
                    if (lstTemp.Count > 0 && isValid)
                    {
                        //if (lstTemp.Count <= 2)
                        //{
                        //    dicOzoneMonitor[k.Key].ozone = -7;
                        //}
                        //else
                        //{
                        dicOzoneMonitor[k.Key].ozone = Math.Round(lstTemp.Average(), 1);// Convert.ToInt32((dicOzoneMonitor[k.Key].lstOzone.Average() * 10)) / 10;
                        dicOzoneMonitor[k.Key].datacount = lstTemp.Count;
                        //}
                    }
                    else
                        dicOzoneMonitor[k.Key].ozone = -7;
                }
                //_endTime = DateTime.Now;
                //CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish reading monitor data: " + CommonClass.TotalTime + " s.");
                //CommonClass.CurrentLog = "Finish reading monitor data: " + CommonClass.TotalTime + " s.";
                //CommonClass.CurrentProgressBar++;
                #endregion
                //----------解析Monitor 首先去掉=-9的值，然后根据StartYear 求出 StartYear,StartYear+1,StartYear+2的均值*10 -> int /10 最后仍然是int 值。如果都没有Ozone="."

                // DataSet dsModelBase = CommonClass.getDataSetFromCSV(ozoneAnalysisConfiguration.dataInputO.baselineFile);//-------太大了。
                #region Read OzoneModel Base from csv
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Begin loading Baseline Model Data...");
                //CommonClass.CurrentLog = "Begin loading Baseline Model Data...";
                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read model data \"" + Path.GetFileName(ozoneAnalysisConfiguration.modelInput.baselineModelDataFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                iID = -1; iType = -1; iLat = -1; iLong = -1; iO3 = -1;
                int iDate = -1;
                Dictionary<string, OzoneModel> dicOzoneModel = new Dictionary<string, OzoneModel>();
                //读ModelBase
                // 要与只读方式打开csv文件，可以防止excel文档被占用问题
                FileStream fs = new FileStream(ozoneAnalysisConfiguration.modelInput.baselineModelDataFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                try
                {
                    using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                    {
                        //int fieldCount = csv.FieldCount;

                        //string[] headers = csv.GetFieldHeaders();
                        //csv.ReadNextRecord(false,true);
                        string strLine = csv.ReadLine();
                        string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                        int i = 0;
                        while (i < strLineArray.Length)
                        {
                            string s = strLineArray[i];
                            switch (s.Trim().ToLower())
                            {
                                case "_id":
                                    iID = i;
                                    break;
                                case "_type":
                                    iType = i;
                                    break;
                                case "lat":
                                    iLat = i;
                                    break;
                                case "long":
                                    iLong = i;
                                    break;
                                case "date":
                                    iDate = i;
                                    break;
                                case "o3":
                                    iO3 = i;
                                    break;

                            }
                            i++;
                        }
                        while (strLine != null)
                        {
                            strLine = csv.ReadLine();
                            if (strLine == null) break;
                            strLineArray = strLine.Split(new char[] { ',' });
                            //if (strLineArray[iDate].Substring(0, 4) != startYear) continue;
                            if (dicOzoneModel.ContainsKey(strLineArray[iID].ToString().Trim()))//strLineArray[iDate].Substring(0, 4)))
                            {
                                //try
                                //{
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzone.Add(strLineArray[iDate].Substring(4), new float[2] { Convert.ToSingle(strLineArray[iO3]), -9 });
                                //}
                                //catch
                                //{
                                //}
                            }
                            else
                            {
                                dicOzoneModel.Add(strLineArray[iID].ToString().Trim(), new OzoneModel()
                                {
                                    Date = strLineArray[iDate].Substring(0, 4),
                                    id = strLineArray[iID],
                                    lat = Convert.ToDouble(strLineArray[iLat]),
                                    longitude = Convert.ToDouble(strLineArray[iLong]),
                                    type = strLineArray[iType],
                                    lstOzone = new Dictionary<string, float[]>(),
                                    // lstOzoneForecast = new Dictionary<string, float>(),
                                });
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzone.Add(strLineArray[iDate].Substring(4), new float[2] { Convert.ToSingle(strLineArray[iO3]), -9 });
                            }

                        }
                        csv.Dispose(); fs.Dispose();
                        GC.Collect();
                    }
                }
                catch
                {
                    CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(ozoneAnalysisConfiguration.modelInput.baselineModelDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }
                //_endTime = DateTime.Now;
                //CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish reading baseline model data: " + CommonClass.TotalTime + " s");
                //CommonClass.CurrentLog = "Finish reading baseline model data: " + CommonClass.TotalTime + " s";
                //CommonClass.CurrentProgressBar++;
                #endregion
                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentLog = "Finish reading model data: " + CommonClass.TotalTime + " s.";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read model data \"" + Path.GetFileName(ozoneAnalysisConfiguration.modelInput.forecastModelDataFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                #region Read Ozone Model Forcast from csv
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Begin loading forecast model data...");
                //CommonClass.CurrentLog = "Begin loading forecast model data...";
                _beginTime = DateTime.Now;
                //要与只读方式打开csv文件，可以防止excel文档被占用问题
                fs = new FileStream(ozoneAnalysisConfiguration.modelInput.forecastModelDataFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                try
                {
                    using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                    {
                        //int fieldCount = csv.FieldCount;

                        //string[] headers = csv.GetFieldHeaders();
                        //csv.ReadNextRecord(false,true);
                        string strLine = csv.ReadLine();
                        string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                        int i = 0;
                        while (i < strLineArray.Length)
                        {
                            string s = strLineArray[i];
                            switch (s.Trim().ToLower())
                            {
                                case "_id":
                                    iID = i;
                                    break;
                                case "_type":
                                    iType = i;
                                    break;
                                case "lat":
                                    iLat = i;
                                    break;
                                case "long":
                                    iLong = i;
                                    break;
                                case "date":
                                    iDate = i;
                                    break;
                                case "o3":
                                    iO3 = i;
                                    break;

                            }
                            i++;
                        }
                        while (strLine != null)
                        {
                            strLine = csv.ReadLine();
                            if (strLine == null) break;
                            strLineArray = strLine.Split(new char[] { ',' });
                            //if (strLineArray[iDate].Substring(0, 4) != startYear) continue;
                            if (lastYear == "") lastYear = strLineArray[iDate].Substring(0, 4);
                            if (strLineArray[iID] == "140001" && strLineArray[iDate] == "20150625")
                            {
                            }
                            if (dicOzoneModel.ContainsKey(strLineArray[iID].ToString().Trim()))
                            {
                                //dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzoneForecast.Add(strLineArray[iDate].Substring(4), Convert.ToSingle(strLineArray[iO3]));
                                float f = Convert.ToSingle(Convert.ToDecimal(strLineArray[iO3]));
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzone[strLineArray[iDate].Substring(4)][1] = f;// Convert.ToSingle(strLineArray[iO3]);
                            }
                            else
                            {

                            }

                        }
                        csv.Dispose(); fs.Dispose();
                        GC.Collect();
                    }
                }
                catch
                {
                    CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(ozoneAnalysisConfiguration.modelInput.forecastModelDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }
                //--------------修正dicQuarterlyModelDataPM的坐标系！-------------------
                #region
                double[] dConvertArrayModel = null;
                List<double> lstConvertArrayModel = new List<double>();
                List<string> lstKeyModel = dicOzoneModel.Keys.ToList();
                for (int iLstKey = 0; iLstKey < dicOzoneModel.Keys.Count; iLstKey++)
                {
                    lstConvertArrayModel.Add(dicOzoneModel[lstKeyModel[iLstKey]].longitude);
                    lstConvertArrayModel.Add(dicOzoneModel[lstKeyModel[iLstKey]].lat);
                }
                dConvertArrayModel = lstConvertArrayModel.ToArray();
                DotSpatial.Projections.Reproject.ReprojectPoints(dConvertArrayModel, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984,
                   DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ), 0, dConvertArrayModel.Length / 2);
                for (int iLstKey = 0; iLstKey < dicOzoneModel.Keys.Count; iLstKey++)
                {
                    dicOzoneModel[lstKeyModel[iLstKey]].longitudeLamber = dConvertArrayModel[2 * iLstKey] / 100.00;
                    dicOzoneModel[lstKeyModel[iLstKey]].latitudeLamber = dConvertArrayModel[2 * iLstKey + 1] / 100.00;
                }
                #endregion

                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish reading data: " + ozoneAnalysisConfiguration.dataInputO.forecastModelDataFile + CommonClass.TotalTime + " s.");
                //CommonClass.CurrentLog = "Finish reading data: " + ozoneAnalysisConfiguration.dataInputO.forecastModelDataFile + CommonClass.TotalTime + " s.";
                //CommonClass.CurrentProgressBar++;
                // DataSet dsModelControl = CommonClass.getDataSetFromCSV(ozoneAnalysisConfiguration.dataInputO.forecastFile);
                //读ModelControl
                #endregion
                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentLog = "Finish reading model data: " + CommonClass.TotalTime + " s.";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                //change project - write in dictionary (lat,long to lambert) - for draw map
                DataTable dt = new DataTable();
                dt.Columns.Add("id");
                dt.Columns.Add("lat");
                dt.Columns.Add("long");
                foreach (KeyValuePair<string, OzoneModel> keyvalue in dicOzoneModel)
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = keyvalue.Key;
                    dr[1] = keyvalue.Value.lat;
                    dr[2] = keyvalue.Value.longitude;
                    dt.Rows.Add(dr);
                }
                mats.changeProject(dt, "USA");


                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + ozoneAnalysisConfiguration.modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + ozoneAnalysisConfiguration.modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + ozoneAnalysisConfiguration.modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + ozoneAnalysisConfiguration.modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doQuarterlyModelData)
                //{
                //    SaveOzoneQuarterlyModelData(CommonClass.CurrentBaseScenario, dicOzoneModel, lastYear);
                //}

                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Begin computation of gradient structures");
                //CommonClass.CurrentLog = "Begin computation of gradient structures";
                _beginTime = DateTime.Now;
                //Del这个步骤
                foreach (KeyValuePair<string, OzoneModel> k in dicOzoneModel)
                {
                    getThresholdsOfOzoneModel(k.Value, ozoneAnalysisConfiguration, true);//model ozone base,future,rrf used in calculate vna/evna (1*1)
                }
                //if do vna/evna future and check do backstop, model data(base,future,rrf..) used in calculate monitor and spatial field is different.
                //output the model data used for calculate sparial field now..
                //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doQuarterlyModelData)
                //{
                //    SaveOzoneQuarterlyModelData(CommonClass.CurrentBaseScenario, dicOzoneModel, lastYear);
                //}
                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish computing gradient structures: " + CommonClass.TotalTime + " s.");
                CommonClass.CurrentLog = "Finish computing gradient structures: " + CommonClass.TotalTime + " s.";
                //CommonClass.CurrentProgressBar++;
                //int a = 0;
                #region Get Point Value And Save
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Creating required averages...");
                //CommonClass.CurrentLog = "Creating required averages...";
                _beginTime = DateTime.Now;
                //---------根据是否3*3 1*1得到Point等的值
                //cboGridOzone.Items.Add("1x1");
                //cboGridOzone.Items.Add("3x3");
                //cboGridOzone.Items.Add("5x5");
                //cboGridOzone.Items.Add("7x7");
                // ozoneAnalysisConfiguration.dataInputO.gridType
                //--------------首先得到monitor属于哪个网格-------简单的方法可以判断以最近的点作为它的网格。首先可以求出第一个网格的大小，在小于一倍网格宽度和长度的最大值求最近点
                Dictionary<string, string> dicMonitorInModel = new Dictionary<string, string>();
                double dFirst = dicOzoneModel.First().Value.longitude, dLen = 0, dLat = 0;
                int iFirst = Convert.ToInt32(dicOzoneModel.First().Key);

                if (dicOzoneModel.ContainsKey((((iFirst / 1000) + 1) * 1000 + iFirst % 1000).ToString()))
                {

                    dLen = Math.Abs(dicOzoneModel[(((iFirst / 1000) + 1) * 1000 + iFirst % 1000).ToString()].longitude -
                        dicOzoneModel.First().Value.longitude
                        );
                    dLat = Math.Abs(dicOzoneModel[(((iFirst / 1000)) * 1000 + iFirst % 1000 + 1).ToString()].lat -
                        dicOzoneModel.First().Value.lat
                        );
                    dLen *= 2; dLat *= 2;

                }
                //----------修正算法 首先计算出所有的左上角和右下角以及Model中心点的对应关系--------
                Dictionary<string, Extent> dicExtentForModel = new Dictionary<string, Extent>();
                foreach (KeyValuePair<string, OzoneModel> k in dicOzoneModel)
                {
                    try
                    {
                        if (k.Key == "182144")
                        {
                        }
                        int Col = Convert.ToInt32(k.Key) / 1000;
                        int Row = Convert.ToInt32(k.Key) % 1000;
                        //------如果没有上格，则使用下格
                        OzoneModel ozoneModelTop = null, ozoneModelLeft = null;
                        if (dicOzoneModel.ContainsKey(((Col - 1) * 1000 + Row).ToString()))
                        {
                            ozoneModelLeft = dicOzoneModel[((Col - 1) * 1000 + Row).ToString()];
                        }
                        else if (dicOzoneModel.ContainsKey(((Col + 1) * 1000 + Row).ToString()))
                        {
                            ozoneModelLeft = dicOzoneModel[((Col + 1) * 1000 + Row).ToString()];
                        }
                        if (dicOzoneModel.ContainsKey((Col * 1000 + Row + 1).ToString()))
                        {
                            ozoneModelTop = dicOzoneModel[(Col * 1000 + Row + 1).ToString()];
                        }
                        else if (dicOzoneModel.ContainsKey((Col * 1000 + Row - 1).ToString()))
                        {
                            ozoneModelTop = dicOzoneModel[(Col * 1000 + Row - 1).ToString()];
                        }
                        if (ozoneModelLeft != null && ozoneModelTop != null)
                        {
                            dicExtentForModel.Add(k.Key, new Extent(k.Value.longitude - Math.Abs(ozoneModelTop.longitude - ozoneModelLeft.longitude) / 2.00,
                                k.Value.lat - Math.Abs(ozoneModelLeft.lat - ozoneModelTop.lat) / 2.00, k.Value.longitude + Math.Abs(ozoneModelTop.longitude - ozoneModelLeft.longitude) / 2.00,
                                k.Value.lat + Math.Abs(ozoneModelLeft.lat - ozoneModelTop.lat) / 2.00));

                        }
                    }
                    catch
                    {
                    }

                }
                //---------计算两个网格之内；然后属于哪个的网格
                foreach (KeyValuePair<string, OzoneMonitor> k in dicOzoneMonitor)
                {
                    //double dlenTemp = dLen;
                    if (k.Key == "090050005")
                    {
                    }
                    try
                    {
                        var query = dicOzoneModel.Where(p => Math.Abs(p.Value.longitude - k.Value.longitude) < dLen && Math.Abs(p.Value.lat - k.Value.lat) < dLat).ToList();
                        string sModelIDTemp = "";
                        if (query.Count() > 0)
                        {
                            DotSpatial.Topology.Coordinate coor = new DotSpatial.Topology.Coordinate(k.Value.longitude, k.Value.lat);
                            //var querySec = dicExtentForModel.Where(p => query.Contains(p.Key)).ToList();
                            //double d = -1;
                            //foreach (KeyValuePair<string, Extent> kin in querySec)
                            //{
                            //    if(d==-1 )
                            //      Math.Sqrt(Math.Pow(kin.Value.Center.X - coor.X, 2) + Math.Pow(kin.Value.Center.Y - coor.Y, 2));
                            //    if(kin.Value.Contains(coor))
                            //    {
                            //         dicMonitorInModel.Add(k.Key, kin.Key);
                            //         sModelIDTemp = k.Key;
                            //    }
                            //}
                            if (k.Key == "90090027" || k.Key == "090090027")
                            {
                                Dictionary<string, double> dicDistance = new Dictionary<string, double>();
                                foreach (KeyValuePair<string, OzoneModel> kModel in query)
                                {
                                    dicDistance.Add(kModel.Key, CommonClass.getDistanceFrom2Point(kModel.Value.longitude, kModel.Value.lat, k.Value.longitude, k.Value.lat));
                                }
                            }
                            if (sModelIDTemp == "")
                            {
                                //sModelIDTemp = query.OrderBy(p => Math.Sqrt(Math.Pow(p.Value.longitude- coor.X, 2) + Math.Pow(p.Value.lat - coor.Y, 2))).First().Key;
                                sModelIDTemp = query.OrderBy(p => CommonClass.getDistanceFrom2Point(p.Value.longitude, p.Value.lat, k.Value.longitude, k.Value.lat)).First().Key;
                                //string sModelIDTemp = dicExtentForModel.Where(p => query.Contains(p.Key)).Where(p => p.Value.Contains(new DotSpatial.Topology.Coordinate(k.Value.longitude, k.Value.lat))).First().Key;// query.OrderBy(p => Math.Pow(p.Value.longitude - k.Value.longitude, 2) + Math.Pow(p.Value.lat - k.Value.lat, 2)).First().Key;
                                dicMonitorInModel.Add(k.Key, sModelIDTemp);
                            }
                        }
                    }
                    catch
                    {
                        //string sModelIDTemp = dicOzoneModel.OrderBy(p => Math.Abs(p.Value.longitude - k.Value.longitude)).First().Key;
                        //Dictionary<string, OzoneModel> dicTemp = dicOzoneModel.OrderBy(p => Math.Abs(p.Value.longitude - k.Value.longitude)).ToDictionary(p => p.Key, p => p.Value);

                        //dicMonitorInModel.Add(k.Key, sModelIDTemp);
                    }
                }
                /*
                DataTable dtMonitorInModel = new DataTable();
                dtMonitorInModel.Columns.Add("Monitor");
                dtMonitorInModel.Columns.Add("Model");
                foreach (KeyValuePair<string, string> k in dicMonitorInModel)
                {
                    DataRow dr = dtMonitorInModel.NewRow();
                    dr["Monitor"] = k.Key;
                    dr["Model"] = k.Value;
                    dtMonitorInModel.Rows.Add(dr);
                }
                CommonClass.SaveCSV(dtMonitorInModel, @"d:\MonitorInModel.csv", "Year");
                */
                //--------------------根据3*3 
                Dictionary<string, OzoneMonitorControl> dicOzoneMonitorControl = new Dictionary<string, OzoneMonitorControl>();
                Dictionary<string, OzoneMonitorControlMax> dicOzoneMonitorControlMax = new Dictionary<string, OzoneMonitorControlMax>();

                List<Dictionary<string, OzoneMonitorControl>> lstDicOzoneMonitorControlPeriod = new List<Dictionary<string, OzoneMonitorControl>>();
                if (false)//ozoneAnalysisConfiguration.chooseDesiredOutputO.doDesignValuePeriods)
                {
                    for (int i = 0; i < lstMonitorYear.Count; i++)
                    {
                        lstDicOzoneMonitorControlPeriod.Add(new Dictionary<string, OzoneMonitorControl>());
                    }
                    //lstDicOzoneMonitorControlPeriod.Add(new Dictionary<string, OzoneMonitorControl>());
                    //lstDicOzoneMonitorControlPeriod.Add(new Dictionary<string, OzoneMonitorControl>());

                }
                foreach (KeyValuePair<string, OzoneMonitor> k in dicOzoneMonitor)
                {
                    //---------首先根据
                    if (!dicMonitorInModel.ContainsKey(k.Key)) continue;
                    int Col = Convert.ToInt32(dicMonitorInModel[k.Key]) / 1000;
                    int Row = Convert.ToInt32(dicMonitorInModel[k.Key]) % 1000;
                    List<string> lstSurround = new List<string>();
                    switch ("3x3")//ozoneAnalysisConfiguration.dataInputO.temporalAdjustmentAtMonitorGrid)
                    {
                        case "1x1":
                            lstSurround.Add(dicMonitorInModel[k.Key]);
                            break;
                        case "3x3":
                            for (int i3 = -1; i3 <= 1; i3++)
                            {
                                for (int j3 = -1; j3 <= 1; j3++)
                                {
                                    lstSurround.Add(((Col + i3) * 1000 + (Row + j3)).ToString());
                                }

                            }
                            break;
                        case "5x5":
                            for (int i5 = -2; i5 <= 2; i5++)
                            {
                                for (int j5 = -2; j5 <= 2; j5++)
                                {
                                    lstSurround.Add(((Col + i5) * 1000 + (Row + j5)).ToString());
                                }

                            }
                            break;
                        case "7x7":
                            for (int i7 = -3; i7 <= 3; i7++)
                            {
                                for (int j7 = -3; j7 <= 3; j7++)
                                {
                                    lstSurround.Add(((Col + i7) * 1000 + (Row + j7)).ToString());
                                }

                            }
                            break;

                    }
                    //cboStatisticOzone.Items.Add("Mean");
                    // cboStatisticOzone.Items.Add("Maximum");
                    var query = dicOzoneModel.Where(p => lstSurround.Contains(p.Key)).ToList();
                    int iQueryCount = query.Count;
                    switch ("Maximum-paired in space")//ozoneAnalysisConfiguration.dataInputO.temporalAdjustmentType)
                    {
                        case "Mean":
                            //#region mean
                            //if (query.Count() > 0)
                            //{
                            //    //---------------------求每天的最大值--得到一个新的OzoneModel---重新算ppb等---------And future!!!
                            //    List<double> lstOzoneTemp = new List<double>();

                            //    OzoneModel omTemp = new OzoneModel()
                            //    {
                            //        id = k.Value.id,
                            //        lat = Convert.ToSingle(k.Value.lat),
                            //        longitude = Convert.ToSingle(k.Value.longitude),

                            //    };
                            //    Dictionary<string, float[]> dicOmBaseTemp = new Dictionary<string, float[]>();// query.First().Value.lstOzone;
                            //    foreach (KeyValuePair<string, float[]> kIn in query.First().Value.lstOzone)
                            //    {
                            //        dicOmBaseTemp.Add(kIn.Key, new float[] { kIn.Value[0], kIn.Value[1] });
                            //    }
                            //    //Dictionary<string, float> dicOmForcastTemp = query.First().Value.lstOzoneForecast;
                            //    List<string> lstDicOmBaseTempKeys = dicOmBaseTemp.Keys.ToList();
                            //    //List<string> lstDicOmForcastTempKeys = dicOmForcastTemp.Keys.ToList();
                            //    // foreach (KeyValuePair<string, OzoneModel> kin in query)
                            //    for (int iKin = 1; iKin < query.Count(); iKin++)
                            //    {
                            //        KeyValuePair<string, OzoneModel> kin = query.ToArray()[iKin];
                            //        foreach (KeyValuePair<string, float[]> kBase in kin.Value.lstOzone)
                            //        {

                            //            dicOmBaseTemp[kBase.Key][0] += kBase.Value[0];
                            //            dicOmBaseTemp[kBase.Key][1] += kBase.Value[1];

                            //        }
                            //        //foreach (KeyValuePair<string, float> kBase in kin.Value.lstOzoneForecast)
                            //        //{

                            //        //    dicOmForcastTemp[kBase.Key] += kBase.Value;


                            //        //}
                            //    }

                            //    foreach (string s in lstDicOmBaseTempKeys)
                            //    {

                            //        dicOmBaseTemp[s][0] = dicOmBaseTemp[s][0] / iQueryCount;
                            //        dicOmBaseTemp[s][1] = dicOmBaseTemp[s][1] / iQueryCount;

                            //    }

                            //    //foreach (string s in lstDicOmForcastTempKeys)
                            //    //{

                            //    //    dicOmForcastTemp[s] = dicOmForcastTemp[s] / iQueryCount;


                            //    //}
                            //    omTemp.lstOzone = dicOmBaseTemp;
                            //    //omTemp.lstOzoneForecast = dicOmForcastTemp;
                            //    getThresholdsOfOzoneModel(omTemp, ozoneAnalysisConfiguration, false);
                            //    omTemp.lstOzone.Clear();
                            //    //omTemp.lstOzoneForecast.Clear();
                            //    OzoneMonitorControl omControl = new OzoneMonitorControl()
                            //    {
                            //        id = k.Value.id,
                            //        lat = k.Value.lat,
                            //        longitude = k.Value.longitude,
                            //        rrf = omTemp.rrf,
                            //        days = omTemp.days,
                            //        lim = omTemp.lim,
                            //        ppb = omTemp.ppb,
                            //        ozonebase = k.Value.ozone,
                            //        ozonecontrol = k.Value.ozone < 0 ? -9 : omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.ozone * omTemp.rrf, 1),//omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.ozone * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //        county = k.Value.county,
                            //        referencecell = dicMonitorInModel[k.Key],// om.id,
                            //        state = k.Value.state
                            //    };
                            //    dicOzoneMonitorControl.Add(k.Value.id, omControl);
                            //    if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doMaxDesignValuePeriods)
                            //    {
                            //        KeyValuePair<string, double> ozonebMax = k.Value.dicOzone.Where(q => lstMonitorYear.Contains(q.Key)).ToDictionary(q => q.Key, q => q.Value).OrderByDescending(q => q.Value).First();//.Select(q => q.Value).ToList().Max();
                            //        OzoneMonitorControlMax omControlMax = new OzoneMonitorControlMax()
                            //        {
                            //            id = k.Value.id,
                            //            lat = k.Value.lat,
                            //            longitude = k.Value.longitude,
                            //            rrf = omTemp.rrf,
                            //            days = omTemp.days,
                            //            lim = omTemp.lim,
                            //            ppb = omTemp.ppb,
                            //            ozonebase = ozonebMax.Value,
                            //            ozonecontrol = ozonebMax.Value < 0 ? -9 : omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(ozonebMax.Value * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //            county = k.Value.county,
                            //            referencecell = dicMonitorInModel[k.Key],// om.id,
                            //            state = k.Value.state,
                            //            data = ozonebMax.Key
                            //        };
                            //        dicOzoneMonitorControlMax.Add(k.Value.id, omControlMax);
                            //    }
                            //    if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doDesignValuePeriods)
                            //    {
                            //        //----------存三个!
                            //        //if (ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods == "None selected")
                            //        //{
                            //        //            ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4) ||
                            //        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 1).ToString() ||
                            //        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 2).ToString()))
                            //        for (int iPeriod = 0; iPeriod < lstMonitorYear.Count; iPeriod++)
                            //        {
                            //            OzoneMonitorControl omControlPeriod1 = new OzoneMonitorControl()
                            //            {
                            //                id = k.Value.id,
                            //                lat = k.Value.lat,
                            //                longitude = k.Value.longitude,
                            //                rrf = omTemp.rrf,
                            //                days = omTemp.days,
                            //                lim = omTemp.lim,
                            //                ppb = omTemp.ppb,
                            //                ozonebase = k.Value.dicOzone[lstMonitorYear[iPeriod]],//(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + iPeriod).ToString()],
                            //                ozonecontrol = omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.dicOzone[lstMonitorYear[iPeriod]] * omTemp.rrf, 1),//[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + iPeriod).ToString()] * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //                county = k.Value.county,
                            //                referencecell = dicMonitorInModel[k.Key],// om.id,
                            //                state = k.Value.state
                            //            };
                            //            if (omControlPeriod1.ozonebase == -9 || omControlPeriod1.ozonebase == -7)
                            //            {
                            //                omControlPeriod1.ozonebase = -7;
                            //                omControlPeriod1.ozonecontrol = -9;
                            //            }
                            //            lstDicOzoneMonitorControlPeriod[iPeriod].Add(k.Value.id, omControlPeriod1);
                            //        }
                            //        //}
                            //        //else
                            //        //{
                            //        //    for (int iPeriod = 0; iPeriod < 3; iPeriod++)
                            //        //    {
                            //        //        OzoneMonitorControl omControlPeriod1 = new OzoneMonitorControl()
                            //        //        {
                            //        //            id = k.Value.id,
                            //        //            lat = k.Value.lat,
                            //        //            longitude = k.Value.longitude,
                            //        //            rrf = omTemp.rrf,
                            //        //            days = omTemp.days,
                            //        //            lim = omTemp.lim,
                            //        //            ppb = omTemp.ppb,
                            //        //            ozonebase = k.Value.dicOzone[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + iPeriod).ToString()],
                            //        //            ozonecontrol = omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.dicOzone[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + iPeriod).ToString()] * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //        //            county = k.Value.county,
                            //        //            referencecell = dicMonitorInModel[k.Key],// om.id,
                            //        //            state = k.Value.state
                            //        //        };
                            //        //        if (omControlPeriod1.ozonebase == -9 || omControlPeriod1.ozonebase == -7)
                            //        //        {
                            //        //            omControlPeriod1.ozonebase = -7;
                            //        //            omControlPeriod1.ozonecontrol = -9;
                            //        //        }
                            //        //        lstDicOzoneMonitorControlPeriod[iPeriod].Add(k.Value.id, omControlPeriod1);
                            //        //    }
                            //        //}
                            //    }
                            //}
                            //#endregion
                            break;
                        case "Maximum"://首先得到周围最大的，然后得到相应forecast的，然后计算rrf等等。应用到monitor计算出MonitorControl
                            //#region maximum
                            //if (query.Count() > 0)
                            //{
                            //    //---------------------求每天的最大值--得到一个新的OzoneModel---重新算ppb等---------And future!!!
                            //    List<double> lstOzoneTemp = new List<double>();
                            //    OzoneModel omTemp = new OzoneModel()
                            //    {
                            //        id = k.Value.id,
                            //        lat = Convert.ToSingle(k.Value.lat),
                            //        longitude = Convert.ToSingle(k.Value.longitude),

                            //    };
                            //    Dictionary<string, float[]> dicOmBaseTemp = new Dictionary<string, float[]>();// query.First().Value.lstOzone;
                            //    //Dictionary<string, float> dicOmForcastTemp = new Dictionary<string, float>();//query.First().Value.lstOzoneForecast;

                            //    foreach (KeyValuePair<string, OzoneModel> kin in query)
                            //    {
                            //        foreach (KeyValuePair<string, float[]> kBase in kin.Value.lstOzone)
                            //        {
                            //            if (!dicOmBaseTemp.ContainsKey(kBase.Key))
                            //            {
                            //                dicOmBaseTemp.Add(kBase.Key, new float[] { kBase.Value[0], kBase.Value[1] });
                            //            }
                            //            else if (dicOmBaseTemp[kBase.Key][0] < kBase.Value[0])
                            //            {
                            //                dicOmBaseTemp[kBase.Key][0] = kBase.Value[0];

                            //            }
                            //        }
                            //        foreach (KeyValuePair<string, float[]> kBase in kin.Value.lstOzone)
                            //        {
                            //            if (!dicOmBaseTemp.ContainsKey(kBase.Key))
                            //            {
                            //                dicOmBaseTemp.Add(kBase.Key, new float[] { kBase.Value[0], kBase.Value[1] });
                            //            }
                            //            else if (dicOmBaseTemp[kBase.Key][1] < kBase.Value[1])
                            //            {
                            //                dicOmBaseTemp[kBase.Key][1] = kBase.Value[1];

                            //            }
                            //        }
                            //        //foreach (KeyValuePair<string, float> kBase in kin.Value.lstOzoneForecast)
                            //        //{
                            //        //    if (!dicOmForcastTemp.ContainsKey(kBase.Key))
                            //        //    {
                            //        //        dicOmForcastTemp.Add(kBase.Key, kBase.Value);
                            //        //    }
                            //        //    else if (dicOmForcastTemp[kBase.Key] < kBase.Value)
                            //        //    {
                            //        //        dicOmForcastTemp[kBase.Key] = kBase.Value;

                            //        //    }
                            //        //}
                            //    }
                            //    omTemp.lstOzone = dicOmBaseTemp;
                            //    //omTemp.lstOzoneForecast = dicOmForcastTemp;
                            //    if (k.Value.id == "0120813002" || k.Value.id == "120813002"
                            //        || k.Value.id == "120813002" || k.Value.id == "0120813002"//120571035  291650023
                            //        || k.Value.id == "291650023" || k.Value.id == "0291650023"
                            //        || k.Value.id == "390490081" || k.Value.id == "0390490081"
                            //        )
                            //    {
                            //        string s = "";
                            //    }

                            //    getThresholdsOfOzoneModel(omTemp, ozoneAnalysisConfiguration, false);
                            //    omTemp.lstOzone.Clear();
                            //    //omTemp.lstOzoneForecast.Clear();
                            //    OzoneMonitorControl omControl = new OzoneMonitorControl()
                            //    {
                            //        id = k.Value.id,
                            //        lat = k.Value.lat,
                            //        longitude = k.Value.longitude,
                            //        rrf = omTemp.rrf,
                            //        days = omTemp.days,
                            //        lim = omTemp.lim,
                            //        ppb = omTemp.ppb,
                            //        ozonebase = k.Value.ozone,
                            //        ozonecontrol = k.Value.ozone < 0 ? -9 : omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.ozone * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //        county = k.Value.county,
                            //        referencecell = dicMonitorInModel[k.Key],// om.id,
                            //        state = k.Value.state
                            //    };
                            //    dicOzoneMonitorControl.Add(k.Value.id, omControl);
                            //    if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doMaxDesignValuePeriods)
                            //    {
                            //        KeyValuePair<string, double> ozonebMax = k.Value.dicOzone.Where(q => lstMonitorYear.Contains(q.Key)).ToDictionary(q => q.Key, q => q.Value).OrderByDescending(q => q.Value).First();//.Select(q => q.Value).ToList().Max();
                            //        OzoneMonitorControlMax omControlMax = new OzoneMonitorControlMax()
                            //        {
                            //            id = k.Value.id,
                            //            lat = k.Value.lat,
                            //            longitude = k.Value.longitude,
                            //            rrf = omTemp.rrf,
                            //            days = omTemp.days,
                            //            lim = omTemp.lim,
                            //            ppb = omTemp.ppb,
                            //            ozonebase = ozonebMax.Value,
                            //            ozonecontrol = ozonebMax.Value < 0 ? -9 : omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(ozonebMax.Value * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //            county = k.Value.county,
                            //            referencecell = dicMonitorInModel[k.Key],// om.id,
                            //            state = k.Value.state,
                            //            data = ozonebMax.Key
                            //        };
                            //        dicOzoneMonitorControlMax.Add(k.Value.id, omControlMax);
                            //    }
                            //    if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doDesignValuePeriods)
                            //    {
                            //        //----------存三个!
                            //        //if (ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods == "None Selected")
                            //        //{
                            //        //            ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4) ||
                            //        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 1).ToString() ||
                            //        //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 2).ToString()))
                            //        for (int iPeriod = 0; iPeriod < lstMonitorYear.Count; iPeriod++)
                            //        {
                            //            OzoneMonitorControl omControlPeriod1 = new OzoneMonitorControl()
                            //            {
                            //                id = k.Value.id,
                            //                lat = k.Value.lat,
                            //                longitude = k.Value.longitude,
                            //                rrf = omTemp.rrf,
                            //                days = omTemp.days,
                            //                lim = omTemp.lim,
                            //                ppb = omTemp.ppb,
                            //                ozonebase = k.Value.dicOzone[lstMonitorYear[iPeriod]],//(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + iPeriod).ToString()],
                            //                ozonecontrol = omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.dicOzone[lstMonitorYear[iPeriod]] * omTemp.rrf, 1),//[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + iPeriod).ToString()] * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //                county = k.Value.county,
                            //                referencecell = dicMonitorInModel[k.Key],// om.id,
                            //                state = k.Value.state
                            //            };
                            //            if (omControlPeriod1.ozonebase == -9 || omControlPeriod1.ozonebase == -7)
                            //            {
                            //                omControlPeriod1.ozonebase = -7;
                            //                omControlPeriod1.ozonecontrol = -9;
                            //            }
                            //            lstDicOzoneMonitorControlPeriod[iPeriod].Add(k.Value.id, omControlPeriod1);
                            //        }
                            //        //}
                            //        //else
                            //        //{
                            //        //    for (int iPeriod = 0; iPeriod < 3; iPeriod++)
                            //        //    {
                            //        //        OzoneMonitorControl omControlPeriod1 = new OzoneMonitorControl()
                            //        //        {
                            //        //            id = k.Value.id,
                            //        //            lat = k.Value.lat,
                            //        //            longitude = k.Value.longitude,
                            //        //            rrf = omTemp.rrf,
                            //        //            days = omTemp.days,
                            //        //            lim = omTemp.lim,
                            //        //            ppb = omTemp.ppb,
                            //        //            ozonebase = k.Value.dicOzone[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + iPeriod).ToString()],
                            //        //            ozonecontrol = omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.dicOzone[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + iPeriod).ToString()] * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                            //        //            county = k.Value.county,
                            //        //            referencecell = dicMonitorInModel[k.Key],// om.id,
                            //        //            state = k.Value.state
                            //        //        };
                            //        //        if (omControlPeriod1.ozonebase == -9 || omControlPeriod1.ozonebase == -7)
                            //        //        {
                            //        //            omControlPeriod1.ozonebase = -7;
                            //        //            omControlPeriod1.ozonecontrol = -9;
                            //        //        }
                            //        //        lstDicOzoneMonitorControlPeriod[iPeriod].Add(k.Value.id, omControlPeriod1);
                            //        //    }
                            //        //}
                            //    }
                            //}
                            //#endregion
                            break;
                        case "Maximum-paired in space"://The maximum value should be based on the baseline file maximum grid cell, and the RRF should be calculated at the same grid cell in the future (paired in space)
                            #region maximum-paired in space
                            if (query.Count() > 0)
                            {
                                //---------------------先得到baseline的每日最大值，根据base的id得到对应future的model，在计算RRF
                                List<double> lstOzoneTemp = new List<double>();
                                OzoneModel omTemp = new OzoneModel()
                                {
                                    id = k.Value.id,
                                    lat = Convert.ToSingle(k.Value.lat),
                                    longitude = Convert.ToSingle(k.Value.longitude),

                                };
                                Dictionary<string, float[]> dicOmBaseTemp = new Dictionary<string, float[]>();// query.First().Value.lstOzone;
                                //Dictionary<string, float> dicOmForcastTemp = new Dictionary<string, float>();//query.First().Value.lstOzoneForecast;

                                foreach (KeyValuePair<string, OzoneModel> kin in query)
                                {
                                    foreach (KeyValuePair<string, float[]> kBase in kin.Value.lstOzone)
                                    {
                                        if (!dicOmBaseTemp.ContainsKey(kBase.Key))
                                        {
                                            dicOmBaseTemp.Add(kBase.Key, new float[] { kBase.Value[0], kBase.Value[1] });
                                        }
                                        else if (dicOmBaseTemp[kBase.Key][0] < kBase.Value[0])
                                        {
                                            dicOmBaseTemp[kBase.Key] = kBase.Value;
                                            //dicOmBaseTemp[kBase.Key][0] = kBase.Value[0];
                                            //dicOmBaseTemp[kBase.Key][1] = kBase.Value[1];
                                        }
                                    }
                                    //foreach (KeyValuePair<string, float[]> kBase in kin.Value.lstOzone)
                                    //{
                                    //    if (!dicOmBaseTemp.ContainsKey(kBase.Key))
                                    //    {
                                    //        dicOmBaseTemp.Add(kBase.Key, new float[] { kBase.Value[0], kBase.Value[1] });
                                    //    }
                                    //    else if (dicOmBaseTemp[kBase.Key][1] < kBase.Value[1])
                                    //    {
                                    //        dicOmBaseTemp[kBase.Key][1] = kBase.Value[1];

                                    //    }
                                    //}

                                }
                                omTemp.lstOzone = dicOmBaseTemp;
                                //omTemp.lstOzoneForecast = dicOmForcastTemp;
                                if (k.Value.id == "0120813002" || k.Value.id == "120813002"
                                    || k.Value.id == "120813002" || k.Value.id == "0120813002"//120571035  291650023
                                    || k.Value.id == "291650023" || k.Value.id == "0291650023"
                                    || k.Value.id == "390490081" || k.Value.id == "0390490081"
                                    )
                                {
                                    string s = "";
                                }

                                getThresholdsOfOzoneModel(omTemp, ozoneAnalysisConfiguration, false);
                                omTemp.lstOzone.Clear();
                                //omTemp.lstOzoneForecast.Clear();
                                OzoneMonitorControl omControl = new OzoneMonitorControl()
                                {
                                    id = k.Value.id,
                                    lat = k.Value.lat,
                                    longitude = k.Value.longitude,
                                    rrf = omTemp.rrf,
                                    days = omTemp.days,
                                    lim = omTemp.lim,
                                    ppb = omTemp.ppb,
                                    ozonebase = k.Value.ozone,
                                    ozonecontrol = k.Value.ozone < 0 ? -9 : omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.ozone * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                                    county = k.Value.county,
                                    referencecell = dicMonitorInModel[k.Key],// om.id,
                                    state = k.Value.state
                                };
                                dicOzoneMonitorControl.Add(k.Value.id, omControl);
                                if (false)//ozoneAnalysisConfiguration.chooseDesiredOutputO.doMaxDesignValuePeriods)
                                {
                                    KeyValuePair<string, double> ozonebMax = k.Value.dicOzone.Where(q => lstMonitorYear.Contains(q.Key)).ToDictionary(q => q.Key, q => q.Value).OrderByDescending(q => q.Value).First();//.Select(q => q.Value).ToList().Max();
                                    OzoneMonitorControlMax omControlMax = new OzoneMonitorControlMax()
                                    {
                                        id = k.Value.id,
                                        lat = k.Value.lat,
                                        longitude = k.Value.longitude,
                                        rrf = omTemp.rrf,
                                        days = omTemp.days,
                                        lim = omTemp.lim,
                                        ppb = omTemp.ppb,
                                        ozonebase = ozonebMax.Value,
                                        ozonecontrol = ozonebMax.Value < 0 ? -9 : omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(ozonebMax.Value * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                                        county = k.Value.county,
                                        referencecell = dicMonitorInModel[k.Key],// om.id,
                                        state = k.Value.state,
                                        data = ozonebMax.Key
                                    };
                                    dicOzoneMonitorControlMax.Add(k.Value.id, omControlMax);
                                }
                                if (false)//ozoneAnalysisConfiguration.chooseDesiredOutputO.doDesignValuePeriods)
                                {
                                    //----------存三个!
                                    //if (ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods == "None Selected")
                                    //{
                                    //            ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4) ||
                                    //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 1).ToString() ||
                                    //kin.Key == (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.endYear.Substring(0, 4)) + 2).ToString()))
                                    for (int iPeriod = 0; iPeriod < lstMonitorYear.Count; iPeriod++)
                                    {
                                        OzoneMonitorControl omControlPeriod1 = new OzoneMonitorControl()
                                        {
                                            id = k.Value.id,
                                            lat = k.Value.lat,
                                            longitude = k.Value.longitude,
                                            rrf = omTemp.rrf,
                                            days = omTemp.days,
                                            lim = omTemp.lim,
                                            ppb = omTemp.ppb,
                                            ozonebase = k.Value.dicOzone[lstMonitorYear[iPeriod]],// (Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + iPeriod).ToString()],
                                            ozonecontrol = omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.dicOzone[lstMonitorYear[iPeriod]] * omTemp.rrf, 1),//[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(0, 4)) + iPeriod).ToString()] * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                                            county = k.Value.county,
                                            referencecell = dicMonitorInModel[k.Key],// om.id,
                                            state = k.Value.state
                                        };
                                        if (omControlPeriod1.ozonebase == -9 || omControlPeriod1.ozonebase == -7)
                                        {
                                            omControlPeriod1.ozonebase = -7;
                                            omControlPeriod1.ozonecontrol = -9;
                                        }
                                        lstDicOzoneMonitorControlPeriod[iPeriod].Add(k.Value.id, omControlPeriod1);
                                    }
                                    //}
                                    //else
                                    //{
                                    //    for (int iPeriod = 0; iPeriod < 3; iPeriod++)
                                    //    {
                                    //        OzoneMonitorControl omControlPeriod1 = new OzoneMonitorControl()
                                    //        {
                                    //            id = k.Value.id,
                                    //            lat = k.Value.lat,
                                    //            longitude = k.Value.longitude,
                                    //            rrf = omTemp.rrf,
                                    //            days = omTemp.days,
                                    //            lim = omTemp.lim,
                                    //            ppb = omTemp.ppb,
                                    //            ozonebase = k.Value.dicOzone[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + iPeriod).ToString()],
                                    //            ozonecontrol = omTemp.rrf == -9 ? -9 : CommonClass.ToFixed(k.Value.dicOzone[(Convert.ToInt32(ozoneAnalysisConfiguration.filteringInterpolationO.requiredDVPeriods.Substring(0, 4)) + iPeriod).ToString()] * omTemp.rrf, 1),// Convert.ToInt16(k.Value.ozone*om.rrf*10)/10,
                                    //            county = k.Value.county,
                                    //            referencecell = dicMonitorInModel[k.Key],// om.id,
                                    //            state = k.Value.state
                                    //        };
                                    //        if (omControlPeriod1.ozonebase == -9 || omControlPeriod1.ozonebase == -7)
                                    //        {
                                    //            omControlPeriod1.ozonebase = -7;
                                    //            omControlPeriod1.ozonecontrol = -9;
                                    //        }
                                    //        lstDicOzoneMonitorControlPeriod[iPeriod].Add(k.Value.id, omControlPeriod1);
                                    //    }
                                    //}
                                }
                            }
                            #endregion
                            break;
                    }

                }
                //if (!Directory.Exists(Application.StartupPath + @"\Result\Output\" + ozoneAnalysisConfiguration.chooseDesiredOutputO.scenarioName))
                //{
                //    Directory.CreateDirectory(Application.StartupPath + @"\Result\Output\" + ozoneAnalysisConfiguration.chooseDesiredOutputO.scenarioName);
                //}
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + ozoneAnalysisConfiguration.modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + ozoneAnalysisConfiguration.modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + ozoneAnalysisConfiguration.modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + ozoneAnalysisConfiguration.modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //SaveDicOzoneMonitorControl(dicOzoneMonitorControl, baseScenario, lastYear, "");
                //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doMaxDesignValuePeriods)
                //{
                //    SaveDicOzoneMonitorControlMax(dicOzoneMonitorControlMax, baseScenario, lastYear);
                //    dicOzoneMonitorControlMax.Clear();
                //}
                //SaveDicOzoneMonitorControlCounty(dicOzoneMonitorControl, baseScenario, lastYear, "");
                //dicOzoneMonitorControl.Clear();
                GC.Collect();
                //CommonClass.CurrentProgressBar++;
                //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doDesignValuePeriods)
                //{
                //    for (int iPeriod = 0; iPeriod < lstMonitorYear.Count; iPeriod++)
                //    {
                //        //SaveDicOzoneMonitorControl(lstDicOzoneMonitorControlPeriod[iPeriod], baseScenario, (Convert.ToInt32(lastYear) - 3 + iPeriod).ToString(), "Period " + (iPeriod + 1).ToString());
                //        //SaveDicOzoneMonitorControlCounty(lstDicOzoneMonitorControlPeriod[iPeriod], baseScenario, (Convert.ToInt32(lastYear) - 3 + iPeriod).ToString(), "Period " + (iPeriod + 1).ToString());
                //        SaveDicOzoneMonitorControl(lstDicOzoneMonitorControlPeriod[iPeriod], baseScenario, lastYear, "Period " + (iPeriod + 1).ToString());
                //        SaveDicOzoneMonitorControlCounty(lstDicOzoneMonitorControlPeriod[iPeriod], baseScenario, lastYear, "Period " + (iPeriod + 1).ToString());

                //    }
                //}
                lstDicOzoneMonitorControlPeriod.Clear();
                GC.Collect();
                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish creating required averages: " + CommonClass.TotalTime + " s.");
                CommonClass.CurrentLog = "Finish creating required averages: " + CommonClass.TotalTime + " s.";
                #endregion
                #region clear lstOzone
                foreach (KeyValuePair<string, OzoneModel> k in dicOzoneModel)
                {
                    k.Value.lstOzone.Clear();
                }
                GC.Collect();
                #endregion
                #region VNA
                _beginTime = DateTime.Now;
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Begin interpolation to spatial field");
                //CommonClass.CurrentLog = "Begin interpolation to spatial field";
                //----------求OzoneControl----------
                //if (true)ozoneAnalysisConfiguration.chooseDesiredOutputO.doSpatialFieldEstimates || ozoneAnalysisConfiguration.chooseDesiredOutputO.doBaseOnlyVNA || ozoneAnalysisConfiguration.chooseDesiredOutputO.doFutureOnlyVNA || ozoneAnalysisConfiguration.chooseDesiredOutputO.doSpatialFieldEstimatesGradAdj || ozoneAnalysisConfiguration.chooseDesiredOutputO.doBaseOnlyEVNA || ozoneAnalysisConfiguration.chooseDesiredOutputO.doFutureOnlyEVNA)
                //{
                    Dictionary<string, NeighborFileClass> dicNeighborFile = new Dictionary<string, NeighborFileClass>();
                    //-------------如果需要VNA求VNA------------------------------------------------
                    //-----------得到Neighbor --VNA---------
                    Dictionary<string, OzoneMonitorControl> dicOzoneMonitorLatLong = new Dictionary<string, OzoneMonitorControl>();
                    double iMinLong = 180, iMinLat = 180, iMaxLong = -180, iMaxLat = -180, dLong10 = 1, dLat10 = 1;
                    foreach (KeyValuePair<string, OzoneMonitorControl> kin in dicOzoneMonitorControl)
                    {
                        if (dicOzoneMonitor.ContainsKey(kin.Key) && !dicOzoneMonitorLatLong.ContainsKey(dicOzoneMonitor[kin.Key].longitudeLamber + "," + dicOzoneMonitor[kin.Key].latitudeLamber))
                        {
                            if (dicOzoneMonitor[kin.Key].ozone > 0)
                            {
                                dicOzoneMonitorLatLong.Add(dicOzoneMonitor[kin.Key].longitudeLamber + "," + dicOzoneMonitor[kin.Key].latitudeLamber, kin.Value);
                                if (kin.Value.longitude > iMaxLong) iMaxLong = kin.Value.longitude;
                                if (kin.Value.lat > iMaxLat) iMaxLat = kin.Value.lat;
                                if (kin.Value.longitude < iMinLong) iMinLong = kin.Value.longitude;
                                if (kin.Value.lat < iMinLat) iMinLat = kin.Value.lat;

                            }
                        }
                        else
                        {
                        }
                    }
                    dLong10 = (iMaxLong - iMinLong) / 10.00;
                    dLat10 = (iMaxLat - iMinLat) / 10.00;
                    List<OzoneModelOutput> lstOzoneModelOutput = new List<OzoneModelOutput>();

                    bool VNAorEVNA = (ozoneAnalysisConfiguration.monitorInput.useEVNA|| ozoneAnalysisConfiguration.monitorInput.useVNA);


                    foreach (KeyValuePair<string, OzoneModel> k in dicOzoneModel)
                    {
                        if (k.Key.Replace("\"", "") == "6081" || k.Key.Replace("\"", "") == "06081"
                            ////|| k.Key.Replace("\"", "") == "2001" || k.Key.Replace("\"", "") == "02001"
                            ////   || k.Key.Replace("\"", "") == "3001" || k.Key.Replace("\"", "") == "03001"
                            )
                        {
                            string s = "";
                        }
                        List<double> fsInter = new List<double>();
                        fsInter.Add(k.Value.longitudeLamber);
                        fsInter.Add(k.Value.latitudeLamber);
                        OzoneModelOutput ozoneModelOutput = new OzoneModelOutput()
                        {
                            id = k.Value.id,
                            lat = k.Value.lat,
                            longitude = k.Value.longitude,
                            Date = lastYear,
                            days = k.Value.daysforSptailfield,
                            ppb = k.Value.ppbforSptailfield,
                            type = "",
                            rrf = k.Value.rrfforSptailfield,
                            bO3modelForSpatialField = k.Value.bO3forSptailfield,
                        };
                        if (VNAorEVNA)
                        {

                            //VNA简化算法求半径范围内的监测点做VNA ，一开始以5个经纬度来算一直达到10个为止
                            Dictionary<string, double> dicDistanceMonitor = new Dictionary<string, double>();

                            foreach (KeyValuePair<string, OzoneMonitorControl> kin in dicOzoneMonitorLatLong)
                            {
                                if (dicMonitorInModel.ContainsKey(kin.Value.id))
                                {
                                    dicDistanceMonitor.Add(kin.Value.id, (k.Value.longitude - kin.Value.longitude) * (k.Value.longitude - kin.Value.longitude) + (k.Value.lat - kin.Value.lat) * (k.Value.lat - kin.Value.lat));
                                }
                            }
                            List<KeyValuePair<string, double>> query = new List<KeyValuePair<string, double>>();
                            bool isSame = false;
                            if (dicOzoneMonitorLatLong.ContainsKey(k.Value.longitudeLamber + "," + k.Value.latitudeLamber)) isSame = true;
                            if (!isSame)
                            {
                                if (Math.Abs(k.Value.longitude - iMinLong) < dLong10 || Math.Abs(iMaxLong - k.Value.longitude) < dLong10
                                    || Math.Abs(k.Value.lat - iMinLat) < dLat10 || Math.Abs(iMaxLat - k.Value.lat) < dLat10)
                                {
                                    query = dicDistanceMonitor.Where(p => p.Value < 484).ToList();
                                }
                                else
                                {
                                    query = dicDistanceMonitor.Where(p => p.Value < 64).ToList();//.OrderBy(p=>p.Value).ToList().GetRange(0,idicMonitorValues).ToDictionary(p=>p.Key,p=>p.Value);// .Where(p => lstDouble.GetRange(0, idicMonitorValues).Contains(p.Value));
                                    int iDistanceForQuery = 1;
                                    while (query.Count < 20 && query.Count < dicDistanceMonitor.Count)
                                    {
                                        query = dicDistanceMonitor.Where(p => p.Value < 64 + iDistanceForQuery).ToList();
                                        iDistanceForQuery++;

                                    }
                                }

                                foreach (KeyValuePair<string, double> kin in query)
                                {
                                    if (dicOzoneMonitor.ContainsKey(kin.Key))
                                    {
                                        fsInter.Add(dicOzoneMonitor[kin.Key].longitudeLamber);
                                        fsInter.Add(dicOzoneMonitor[kin.Key].latitudeLamber);

                                    }
                                }
                            }
                            //----------------end VNA简化算法
                            double vnaSum = 0, evnaSum = 0, distanceSum = 0, distance = 0, distanceSumEvna = 0;
                            double vna = 0, evna = 0, vnaForcast = 0, evnaForcast = 0;
                            List<double> fsout = new List<double>();
                            if (!isSame)
                                CommonClass.VoronoiPoints(fsInter.ToArray(), ref fsout);//
                            else
                            {
                                fsout.Add(k.Value.longitudeLamber);
                                fsout.Add(k.Value.latitudeLamber);
                            }
                            //----------------根据得到的邻居计算数值----------------
                            List<string> fsoutString = new List<string>();
                            for (int ifsout = 0; ifsout < fsout.Count; ifsout++)
                            {
                                if (ifsout % 2 == 1)
                                {
                                    fsoutString.Add(fsout[ifsout - 1] + "," + fsout[ifsout]);
                                }
                            }
                            //-----------------加入对NeighborsFile的考虑需要导出NeighborsFile
                            dicNeighborFile.Add(k.Key, new NeighborFileClass()
                            {
                                id = k.Key,
                                monitorLat = k.Value.lat,
                                monitorLong = k.Value.longitude,
                                //quarter = 1,
                                dicNeighbors = new Dictionary<string, NeighborInfo>(),
                            });
                            //-------------------------------------------------------------
                            if (fsoutString.Count == 0) continue;
                            switch ("Inverse Distance Weights")//ozoneAnalysisConfiguration.filteringInterpolationO.defaultInterpolationMethod)
                            {
                                case "Equal Weighting of Monitors"://不需要求距离直接平均
                                    //int n = 0;
                                    //foreach (string s in fsoutString)
                                    //{
                                    //    double d = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicOzoneMonitorLatLong[s].longitude, dicOzoneMonitorLatLong[s].lat);
                                    //    if (ozoneAnalysisConfiguration.filteringInterpolationO.doCheckToSetMaxDistance && d > ozoneAnalysisConfiguration.filteringInterpolationO.maxDistance) continue;
                                    //    vnaSum += dicOzoneMonitorLatLong[s].ozonebase;
                                    //    if (k.Value.srf > 0 && dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf > 0)
                                    //    {
                                    //        evnaSum += dicOzoneMonitorLatLong[s].ozonebase * dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf / k.Value.srf;
                                    //        n++;
                                    //    }
                                    //    dicNeighborFile[k.Key].dicNeighbors.Add(dicOzoneMonitorLatLong[s].id, new NeighborInfo()
                                    //    {
                                    //        neighbor = dicOzoneMonitorLatLong[s].id,
                                    //        neighbor_gridcell = dicMonitorInModel[dicOzoneMonitorLatLong[s].id],
                                    //        distance = d,
                                    //    });
                                    //}
                                    //try
                                    //{
                                    //    if (vnaSum < 0 || Double.IsNaN(vnaSum))
                                    //        vna = -13;
                                    //    else
                                    //        vna = Math.Round(vnaSum / fsoutString.Count, 1);
                                    //    if (evnaSum < 0 || Double.IsNaN(evnaSum) || n == 0)
                                    //        evna = -8;
                                    //    else
                                    //        evna = Math.Round(evnaSum / n, 1);
                                    //    if (k.Value.rrf < 0)
                                    //        vnaForcast = -9;
                                    //    else
                                    //        vnaForcast = CommonClass.ToFixed(vna * k.Value.rrf, 1);
                                    //    if (evna < 0 || k.Value.rrf < 0 || Double.IsNaN(evna))
                                    //        evnaForcast = -9;
                                    //    else
                                    //        evnaForcast = CommonClass.ToFixed(evna * k.Value.rrf, 1);
                                    //}
                                    //catch
                                    //{

                                    //}
                                    break;
                                case "Inverse Distance Weights": //1/distance
                                    foreach (string s in fsoutString)
                                    {
                                        double d = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicOzoneMonitorLatLong[s].longitude, dicOzoneMonitorLatLong[s].lat);
                                        if (false)//ozoneAnalysisConfiguration.filteringInterpolationO.doCheckToSetMaxDistance && d > ozoneAnalysisConfiguration.filteringInterpolationO.maxDistance)
                                            continue;
                                        distance = d == 0 ? 1 : 1.0000 / d;
                                        distanceSum += distance;
                                        vnaSum += dicOzoneMonitorLatLong[s].ozonebase * distance;
                                        dicNeighborFile[k.Key].dicNeighbors.Add(dicOzoneMonitorLatLong[s].id, new NeighborInfo()
                                        {
                                            neighbor = dicOzoneMonitorLatLong[s].id,
                                            neighbor_gridcell = dicMonitorInModel[dicOzoneMonitorLatLong[s].id],
                                            distance = d,
                                        });
                                        try
                                        {
                                            if (k.Value.srf > 0 && dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf > 0)
                                            {
                                                evnaSum += dicOzoneMonitorLatLong[s].ozonebase * distance * k.Value.srf / dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf;
                                                distanceSumEvna += distance;
                                            }
                                        }
                                        catch
                                        {
                                        }
                                    }
                                    try
                                    {
                                        if (vnaSum < 0 || Double.IsNaN(vnaSum) || distanceSum == 0)
                                            vna = 0;//-13;
                                        else
                                            vna = vnaSum / distanceSum;// Math.Round(vnaSum / distanceSum, 1);
                                        if (evnaSum < 0 || Double.IsNaN(evnaSum) || distanceSumEvna == 0)
                                            evna = 0;//-8;
                                        else
                                            evna = evnaSum / distanceSumEvna;// Math.Round(evnaSum / distanceSumEvna, 1);
                                        if (k.Value.rrfforSptailfield < 0)
                                            vnaForcast = 0;//-9;
                                        else
                                            vnaForcast = vna * k.Value.rrfforSptailfield;// CommonClass.ToFixed(vna * k.Value.rrfforSptailfield, 1);

                                        if (evna < 0 || k.Value.rrfforSptailfield < 0 || Double.IsNaN(evna))
                                            evnaForcast = 0;//-9;
                                        else
                                            evnaForcast = evna * k.Value.rrfforSptailfield;// CommonClass.ToFixed(evna * k.Value.rrfforSptailfield, 1);
                                    }
                                    catch
                                    {
                                    }
                                    break;
                                case "Inverse Distance Squared Weights"://1/Math.Pow(distance,2)
                                    foreach (string s in fsoutString)
                                    {
                                        double d = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicOzoneMonitorLatLong[s].longitude, dicOzoneMonitorLatLong[s].lat);
                                        if (false)//ozoneAnalysisConfiguration.filteringInterpolationO.doCheckToSetMaxDistance && d > ozoneAnalysisConfiguration.filteringInterpolationO.maxDistance) continue;
                                            distance = d == 0 ? 1 : 1.0000 / Math.Pow(d, 2);
                                        distanceSum += distance;
                                        vnaSum += dicOzoneMonitorLatLong[s].ozonebase * distance;
                                        dicNeighborFile[k.Key].dicNeighbors.Add(dicOzoneMonitorLatLong[s].id, new NeighborInfo()
                                        {
                                            neighbor = dicOzoneMonitorLatLong[s].id,
                                            neighbor_gridcell = dicMonitorInModel[dicOzoneMonitorLatLong[s].id],
                                            distance = d,
                                        });
                                        try
                                        {
                                            if (k.Value.srf > 0 && dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf > 0)
                                            {
                                                evnaSum += dicOzoneMonitorLatLong[s].ozonebase * distance * k.Value.srf / dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf;
                                                distanceSumEvna += distance;
                                            }
                                        }
                                        catch
                                        {
                                        }
                                    }
                                    try
                                    {
                                        if (vnaSum < 0 || Double.IsNaN(vnaSum) || distanceSum == 0)
                                            vna = 0;//-13;
                                        else
                                            vna = vnaSum / distanceSum;// Math.Round(vnaSum / distanceSum, 1);
                                        if (evnaSum < 0 || Double.IsNaN(evnaSum) || distanceSumEvna == 0)
                                            evna = 0;//-9;
                                        else
                                            evna = evnaSum / distanceSumEvna;// Math.Round(evnaSum / distanceSumEvna, 1);
                                        if (k.Value.rrfforSptailfield < 0)
                                            vnaForcast = 0;//-9;
                                        else
                                            vnaForcast = vna * k.Value.rrfforSptailfield;// CommonClass.ToFixed(vna * k.Value.rrfforSptailfield, 1);
                                        if (evna < 0 || k.Value.rrfforSptailfield < 0 || Double.IsNaN(evna))
                                            evnaForcast = 0;//-9;
                                        else
                                            evnaForcast = evna * k.Value.rrfforSptailfield;// CommonClass.ToFixed(evna * k.Value.rrfforSptailfield, 1);
                                    }
                                    catch
                                    {
                                    }
                                    break;
                            }
                            #region
                            //}
                            //else
                            //{
                            //    switch (ozoneAnalysisConfiguration.filteringInterpolationO.defaultInterpolationMethod)
                            //    {
                            //        case "Equal Weighting of Monitors"://不需要求距离直接平均
                            //            foreach (string s in fsoutString)
                            //            {
                            //                vnaSum += dicOzoneMonitorLatLong[s].ozone;
                            //                evnaSum += dicOzoneMonitorLatLong[s].ozone * dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf / k.Value.srf;
                            //                dicNeighborFile[k.Key].dicNeighbors.Add(dicOzoneMonitorLatLong[s].id, new NeighborInfo()
                            //                {
                            //                    neighbor = dicOzoneMonitorLatLong[s].id,
                            //                    neighbor_gridcell = dicMonitorInModel[dicOzoneMonitorLatLong[s].id],
                            //                    distance = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicOzoneMonitorLatLong[s].longitude, dicOzoneMonitorLatLong[s].lat),
                            //                });
                            //            }
                            //            try
                            //            {
                            //                if (vnaSum < 0 || Double.IsNaN(vnaSum))
                            //                    vna = -13;
                            //                else
                            //                    vna = Convert.ToInt32(10 * vnaSum / fsoutString.Count);
                            //                if (evnaSum < 0 || Double.IsNaN(evnaSum))
                            //                    evna = -8;
                            //                else
                            //                    evna = Convert.ToInt32(10 * evnaSum / fsoutString.Count) / 10;
                            //                if (k.Value.rrf < 0)
                            //                    vnaForcast = -9;
                            //                else
                            //                    vnaForcast = Convert.ToInt32(10 * vna * k.Value.rrf) / 10;
                            //                if (evna < 0 || k.Value.rrf < 0)
                            //                    evnaForcast = -9;
                            //                else
                            //                    evnaForcast = Convert.ToInt32(10 * evna * k.Value.rrf) / 10;
                            //            }
                            //            catch
                            //            {

                            //            }
                            //            break;
                            //        case "Inverse Distance Weights": //1/distance
                            //            foreach (string s in fsoutString)
                            //            {
                            //                //if (dicOzoneMonitorLatLong[s].ozone > 0)
                            //                //{
                            //                double d = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicOzoneMonitorLatLong[s].longitude, dicOzoneMonitorLatLong[s].lat);
                            //                distance = 1.0000 / d;
                            //                distanceSum += distance;
                            //                vnaSum += dicOzoneMonitorLatLong[s].ozone * distance;
                            //                dicNeighborFile[k.Key].dicNeighbors.Add(dicOzoneMonitorLatLong[s].id, new NeighborInfo()
                            //                {
                            //                    neighbor = dicOzoneMonitorLatLong[s].id,
                            //                    neighbor_gridcell = dicMonitorInModel[dicOzoneMonitorLatLong[s].id],
                            //                    distance = d,
                            //                });
                            //                try
                            //                {
                            //                    //evnaSum += dicOzoneMonitorLatLong[s].ozone * distance * dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].ozone / k.Value.ozone;
                            //                    ////if()
                            //                    ////evnaSum = -9;
                            //                    ////evnaSum += dicOzoneMonitorLatLong[s].ozone * distance * dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf / k.Value.srf;
                            //                    ////if (dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf == 0)
                            //                    ////    evnaSum += -13;
                            //                    ////else
                            //                    if (k.Value.srf != -9 && dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf != -9)
                            //                        evnaSum += dicOzoneMonitorLatLong[s].ozone * distance * k.Value.srf / dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf;
                            //                }
                            //                catch
                            //                {
                            //                }
                            //                //}
                            //            }
                            //            try
                            //            {
                            //                if (vnaSum < 0 || Double.IsNaN(vnaSum))
                            //                    vna = -13;
                            //                else
                            //                    vna = Math.Round(vnaSum / distanceSum, 1);
                            //                if (evnaSum < 0 || Double.IsNaN(evnaSum))
                            //                    evna = -8;
                            //                else
                            //                    evna = Math.Round(evnaSum / distanceSum, 1);
                            //                if (k.Value.rrf < 0)
                            //                    vnaForcast = -9;
                            //                else
                            //                    vnaForcast = Math.Round(vna * k.Value.rrf, 1);

                            //                if (evna < 0 || k.Value.rrf < 0)
                            //                    evnaForcast = -9;
                            //                else
                            //                    evnaForcast = Math.Round(evna * k.Value.rrf, 1);
                            //            }
                            //            catch
                            //            {
                            //            }
                            //            break;
                            //        case "Inverse Distance Squared Weights"://1/Math.Pow(distance,2)
                            //            foreach (string s in fsoutString)
                            //            {
                            //                double d = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicOzoneMonitorLatLong[s].longitude, dicOzoneMonitorLatLong[s].lat);
                            //                distance = 1.0000 / Math.Pow(d, 2);
                            //                distanceSum += distance;
                            //                vnaSum += dicOzoneMonitorLatLong[s].ozone * distance;
                            //                dicNeighborFile[k.Key].dicNeighbors.Add(dicOzoneMonitorLatLong[s].id, new NeighborInfo()
                            //                {
                            //                    neighbor = dicOzoneMonitorLatLong[s].id,
                            //                    neighbor_gridcell = dicMonitorInModel[dicOzoneMonitorLatLong[s].id],
                            //                    distance = d
                            //                });
                            //                try
                            //                {
                            //                    if (k.Value.srf != -9 && dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf != -9)
                            //                        evnaSum += dicOzoneMonitorLatLong[s].ozone * distance * k.Value.srf / dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf;
                            //                    //evnaSum += dicOzoneMonitorLatLong[s].ozone * distance * dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].ozone / k.Value.ozone;
                            //                }
                            //                catch
                            //                {
                            //                }
                            //            }
                            //            try
                            //            {
                            //                if (vnaSum < 0 || Double.IsNaN(vnaSum))
                            //                    vna = -13;
                            //                else
                            //                    vna = Convert.ToInt32(10 * vnaSum / distanceSum) / 10;
                            //                if (evnaSum < 0 || Double.IsNaN(evnaSum))
                            //                    evna = -9;
                            //                else
                            //                    evna = Convert.ToInt32(10 * evnaSum / distanceSum) / 10;
                            //                if (k.Value.rrf < 0)
                            //                    vnaForcast = -9;
                            //                else
                            //                    vnaForcast = Convert.ToInt32(10 * vna * k.Value.rrf) / 10;
                            //                if (evna < 0 || k.Value.rrf < 0)
                            //                    evnaForcast = -9;
                            //                else
                            //                    evnaForcast = Convert.ToInt32(10 * evna * k.Value.rrf) / 10;
                            //            }
                            //            catch
                            //            {
                            //            }
                            //            break;
                            //    }
                            //}
                            #endregion


                            ozoneModelOutput.vna = Convert.ToSingle(vna);
                            ozoneModelOutput.evna = Convert.ToSingle(evna);
                            ozoneModelOutput.ga_conc = Convert.ToSingle(k.Value.srf);
                            ozoneModelOutput.vnaForcast = Convert.ToSingle(vnaForcast);
                            ozoneModelOutput.evnaForcast = Convert.ToSingle(evnaForcast);
                            ozoneModelOutput.referencecell = k.Value.id;
                        }
                        lstOzoneModelOutput.Add(ozoneModelOutput);
                    }

                    #region Downscaler begins here by Yangwenwei
                    List<DownscaleR.Ozone.OzoneModel> lstDSresult = new List<DownscaleR.Ozone.OzoneModel>();
                    if (ozoneAnalysisConfiguration.monitorInput.doDownscaler)
                    {
                        _beginTime = DateTime.Now;
                        CommonClass.CurrentLog = "Start downscaler computation.";
                        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);


                        string[] lstModelID4DS = dicOzoneModel.Select(p => p.Value.id).ToArray();
                        double[] lstModelLat4DS = dicOzoneModel.Select(p => p.Value.lat).ToArray();
                        double[] lstModelLong4DS = dicOzoneModel.Select(p => p.Value.longitude).ToArray();
                        double[] lstModel4DS = dicOzoneModel.Select(p => Convert.ToDouble(p.Value.bO3forSptailfield)).ToArray();
                        Tuple<string[], double[], double[], double[]> _tupleModel4DS = new Tuple<string[], double[], double[], double[]>(
                            lstModelID4DS,
                            lstModelLat4DS,
                            lstModelLong4DS,
                            lstModel4DS
                            );
                        #region output model
                        //SaveDSModelData(dicOzoneModel);
                        #endregion

                        string[] lstMonitorID4DS = dicOzoneMonitorControl.Select(p => p.Value.id).ToArray();
                        double[] lstMonitorLat4DS = dicOzoneMonitorControl.Select(p => p.Value.lat).ToArray();
                        double[] lstMonitorLongl4DS = dicOzoneMonitorControl.Select(p => p.Value.longitude).ToArray();
                        double[] lstMonitor4DS = dicOzoneMonitorControl.Select(p => p.Value.ozonebase).ToArray();
                        Tuple<string[], double[], double[], double[]> _tupleMonitor4DS = new Tuple<string[], double[], double[], double[]>(
                            lstMonitorID4DS,
                            lstMonitorLat4DS,
                            lstMonitorLongl4DS,
                            lstMonitor4DS
                            );
                        #region output monitor
                        //SaveDSMonitorData(dicOzoneMonitorControl);
                        #endregion

                        DownscaleR.CommonSettings common = new DownscaleR.CommonSettings();
                        common.Burn = ozoneAnalysisConfiguration.monitorInput.DSBurn;
                        common.Cmaqres = ozoneAnalysisConfiguration.monitorInput.DSCmaqres;
                        common.Thin = ozoneAnalysisConfiguration.monitorInput.DSThin;
                        common.Numit = ozoneAnalysisConfiguration.monitorInput.DSNumit;

                        //DateTime start = DateTime.Now;

                        DownscaleR.Ozone.OzoneAnalysis analysis = new DownscaleR.Ozone.OzoneAnalysis(common, _tupleMonitor4DS, _tupleModel4DS);
                        analysis.Start();
                        // 获取结果
                        //analysis.MCMCOutputData //蒙特卡洛输出结果
                        lstDSresult = analysis.ResultOutputData;// 预测值

                        //DateTime end = DateTime.Now;
                        _endTime = DateTime.Now;

                        CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                        CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish downscalser computation in " + CommonClass.TotalTime + " s.");
                        CommonClass.CurrentLog = "Finish downscalser computation in " + CommonClass.TotalTime + " s.";
                    }
                    #endregion
                    //SaveLstOzoneModelOutput(lstOzoneModelOutput, baseScenario, lastYear);
                    //lstOzoneModelOutput.Clear();
                    GC.Collect();
                    //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doNeighborFileSpatial)
                    //{
                    //    SaveOzoneNeighborFileSpatialField(CommonClass.CurrentBaseScenario, dicNeighborFile);
                    //}
                    dicNeighborFile.Clear();
                    GC.Collect();
                //}
                #endregion

                #region read shape file
                Dictionary<double[], int[]> dic = new Dictionary<double[], int[]>();
                IFeatureSet ifs = FeatureSet.Open(ozoneAnalysisConfiguration.gridDefinitionFile);
                if (!ifs.AttributesPopulated) ifs.FillAttributes();
                //change projection
                ifs.Projection = DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984;
                ifs.Reproject(DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ));
                Dictionary<string, int[]> dicColRow = new Dictionary<string, int[]>();

                foreach (IFeature f in ifs.Features)
                {
                    dic.Add(new double[2] { f.Centroid().Coordinates.First().X / 100.0, f.Centroid().Coordinates.First().Y / 100.0 }, new int[2] { Convert.ToInt16(f.DataRow["COL"]), Convert.ToInt16(f.DataRow["ROW"]) });
                }

                foreach (var kv in dicOzoneModel)
                {
                    var q = dic.Where(p => Math.Abs(kv.Value.longitudeLamber - p.Key[0]) <= 60 && Math.Abs(kv.Value.latitudeLamber - p.Key[1]) <= 60).ToList();
                    if (q.Count >= 0)
                    {
                        var v = q.OrderBy(p => Math.Pow(kv.Value.longitudeLamber - p.Key[0], 2) + Math.Pow(kv.Value.latitudeLamber - p.Key[1], 2)).First();
                        dicColRow.Add(kv.Value.id, new int[2] { v.Value[0], v.Value[1] });
                    }
                    else
                    {
                        var v = dic.OrderBy(p => Math.Pow(kv.Value.longitudeLamber - p.Key[0], 2) + Math.Pow(kv.Value.latitudeLamber - p.Key[1], 2)).ToList().First();
                        dicColRow.Add(kv.Value.id, new int[2] { v.Value[0], v.Value[1] });
                    }
                }




                #endregion

                if (ozoneAnalysisConfiguration.monitorInput.useVNA)
                {
                    SaveOzoneSpatialField(baseScenario, lstOzoneModelOutput, dicColRow);
                }
                if (ozoneAnalysisConfiguration.monitorInput.useEVNA)
                {
                    SaveOzoneSpatialFieldGradAdj(baseScenario, lstOzoneModelOutput, dicColRow);
                } 
                if (ozoneAnalysisConfiguration.monitorInput.doDownscaler)
                {
                    SaveOzoneSpatialFieldDS(baseScenario, lstOzoneModelOutput, dicColRow, lstDSresult);
                }
                SaveDeltaOzoneSpatialField(baseScenario, lstOzoneModelOutput, dicColRow, lstDSresult,
                    ozoneAnalysisConfiguration.monitorInput.doDownscaler,
                    ozoneAnalysisConfiguration.monitorInput.useVNA,
                    ozoneAnalysisConfiguration.monitorInput.useEVNA);

                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish interpolating spatial field: " + CommonClass.TotalTime + " s.");
                CommonClass.CurrentLog = "Finish interpolating spatial field: " + CommonClass.TotalTime + " s.";
                //CommonClass.CurrentProgressBar++;
                //------------------

                //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doQuarterlyModelData)
                //{
                //    BaseOutput bo = CommonClass.CurrentBaseScenario.lstOutput[0];
                //    CommonClass.CurrentBaseScenario.lstOutput.RemoveAt(0);
                //    CommonClass.CurrentBaseScenario.lstOutput.Add(bo);
                //}
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {

            }
        }
        
        public static void getThresholdsOfOzoneModel(OzoneModel ozoneModel, BenMAPOzoneAnalysisConfiguration ozoneAnalysisConfiguration, bool IsSpatialField)
        {
            try
            {
                //if (ozoneModel.id == "92117" || ozoneModel.id == "092117"
                //    || ozoneModel.id == "101121" || ozoneModel.id == "0101121"
                //    || ozoneModel.id == "102009" || ozoneModel.id == "0102009"
                //    || ozoneModel.id == "127138" || ozoneModel.id == "0127138"
                //    || ozoneModel.id == "134079" || ozoneModel.id == "0134079"
                //    || ozoneModel.id == "169130" || ozoneModel.id == "0169130"
                //    || ozoneModel.id == "192078" || ozoneModel.id == "0192078"
                //    || ozoneModel.id == "165137" || ozoneModel.id == "0165137"
                //    || ozoneModel.id == "198135" || ozoneModel.id == "0198135"
                //    )
                //{
                //}
                //if (ozoneModel.id.Trim() == "4021")
                //{ }

                int firstDay = 1;//ozoneAnalysisConfiguration.rrfSpatialGradientO.subrangeFirstDay;
                int endDay = 153;// ozoneAnalysisConfiguration.rrfSpatialGradientO.subrangeLastDay;
                if (endDay > ozoneModel.lstOzone.Count())
                    endDay = ozoneModel.lstOzone.Count();
                int getDays = endDay - firstDay + 1;
                Dictionary<string, float[]> dicUsedinRRF = ozoneModel.lstOzone.OrderBy(q => q.Key).ToList().GetRange(firstDay - 1, getDays).OrderByDescending(p => p.Value[0]).ToDictionary(q => q.Key, q => q.Value);
                ozoneModel.lstOzone = ozoneModel.lstOzone.OrderByDescending(p => p.Value[0]).ToDictionary(p => p.Key, p => p.Value);
                float[] values = ozoneModel.lstOzone.Values.Select(p => p[0]).ToArray();
                if (values[0] == -9 || values[0] == -7)
                {
                    ozoneModel.ozone = -9;
                    ozoneModel.futureOzone = -9;
                    ozoneModel.bO3forSptailfield = -9;//added by Yangwenwei
                    if (IsSpatialField)
                    {
                        //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doSpatialFieldEstimatesGradAdj || ozoneAnalysisConfiguration.chooseDesiredOutputO.doFutureOnlyEVNA)
                        //{
                            ozoneModel.ppb = -8;
                            ozoneModel.days = -8;
                            ozoneModel.rrf = -8;
                            ozoneModel.srf = -13;
                    //    }
                    //    else
                    //    {
                    //        if (ozoneAnalysisConfiguration.rrfSpatialGradientO.doBackstop)
                    //            ozoneModel.ppb = Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField);//65;
                    //        else
                    //            ozoneModel.ppb = Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue);//70;
                    //        ozoneModel.days = 0;
                    //        ozoneModel.rrf = -9;
                    //        ozoneModel.srf = -9;
                    //    }
                    }
                    //else
                    //{
                    //    ozoneModel.ppb = Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue);//70;
                    //    ozoneModel.days = 0;
                    //    ozoneModel.rrf = -9;
                    //    ozoneModel.srf = -9;
                    //}
                    //---------- -13?
                    return;
                }
                //------------求SRF-------根据StartDay,EndDay--------
                ozoneModel.srf = Math.Round(values.ToList().GetRange(1-1,5-1+1).Average(),1);//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.SRF_StartValue) - 1,Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.SRF_EndValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.SRF_StartValue) + 1).Average(), 1);

                //select model days according to subrang first and last day
                values = dicUsedinRRF.Select(p => p.Value[0]).ToArray();
                int j = 0, iThresh = 0;
                if (false)//ozoneAnalysisConfiguration.rrfSpatialGradientO.useInitialThreshold)
                {
                    while (j <= 85-60)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue))
                    {
                        iThresh = 0;
                        while (iThresh < dicUsedinRRF.Count)//ozoneModel.lstOzone.Count)
                        {
                            if (values[iThresh] < 85)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - j) 
                                break;
                            iThresh++;
                        }
                        if (iThresh >= 5)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumofDaysAtorAboveThreshold)) 
                            break;
                        j++;

                    }
                    if (j > 85-60)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue))
                        j = 85-60;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue);

                    ozoneModel.ppb = 85-j;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - j;

                }
                else
                {
                    if (values[10-1]>60)//(values[ozoneAnalysisConfiguration.rrfSpatialGradientO.topXDays - 1] > Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue))
                    {
                        iThresh = 10;//ozoneAnalysisConfiguration.rrfSpatialGradientO.topXDays;
                        ozoneModel.ppb = (int)Math.Floor(values[iThresh - 1]);
                    }
                    else
                    {
                        while (j <= Math.Ceiling(values[0]) - 60)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue))
                        {
                            iThresh = 0;
                            while (iThresh < dicUsedinRRF.Count)//ozoneModel.lstOzone.Count)
                            {
                                if (values[iThresh] < Math.Ceiling(values[0]) - j) break;
                                iThresh++;
                            }
                            if (iThresh >= 5)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumofDaysAtorAboveThreshold)) 
                                break;
                            j++;

                        }
                        if (j > (int)Math.Ceiling(values[0]) - 60)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue))
                            j = (int)Math.Ceiling(values[0]) - 60;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue);

                        ozoneModel.ppb = (int)Math.Ceiling(values[0]) - j;
                    }
                }

                //if (j > Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue))
                //    j = Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue);
                float[] valuesTemp = values.Where(p => p > -9).ToArray();
                //if (iThresh ==90)
                //{ 
                //}

                ozoneModel.days = iThresh;

                if ((iThresh < 5) && (!IsSpatialField || !false))//(iThresh < Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumDaysAtorAboveMinAllowableThreshold) && (!IsSpatialField || !ozoneAnalysisConfiguration.rrfSpatialGradientO.doBackstop))
                {
                    ozoneModel.ozone = -9;
                    ozoneModel.futureOzone = -9;
                    ozoneModel.rrf = -9;
                    //ozoneModel.ppb = 0;
                    if (ozoneModel.days == 0) ozoneModel.ppb = 60;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue);//70;
                    //return;
                }
                /*
                else if ((iThresh < 5) && IsSpatialField && false)//(iThresh < Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumDaysAtorAboveMinAllowableThreshold) && IsSpatialField && ozoneAnalysisConfiguration.rrfSpatialGradientO.doBackstop)
                {
                    if (false)//ozoneAnalysisConfiguration.rrfSpatialGradientO.useInitialThreshold)
                    {
                        while (j <= 85-60)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField))
                        {
                            iThresh = 0;
                            while (iThresh < dicUsedinRRF.Count)//ozoneModel.lstOzone.Count)
                            {
                                if (values[iThresh] < 85-j)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - j) 
                                    break;
                                iThresh++;
                            }
                            if (iThresh >= 5)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumDaysAtorAboveMinAllowableThreshold)) 
                                break;
                            j++;

                        }
                        if (j > 85-60)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField))
                            j = 85-60;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField);

                        ozoneModel.ppb = 85-j;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - j;
                    }
                    else
                    {
                        if (values[10-1]>60)//(values[ozoneAnalysisConfiguration.rrfSpatialGradientO.topXDays - 1] > Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField))
                        {
                            iThresh = 10;//ozoneAnalysisConfiguration.rrfSpatialGradientO.topXDays;
                            ozoneModel.ppb = (int)Math.Floor(values[iThresh - 1]);
                        }
                        else
                        {
                            while (j <= Math.Ceiling(values[0]) - 60)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField))
                            {
                                iThresh = 0;
                                while (iThresh < dicUsedinRRF.Count)//ozoneModel.lstOzone.Count)
                                {
                                    if (values[iThresh] < Math.Ceiling(values[0]) - j) break;
                                    iThresh++;
                                }
                                if (iThresh >= 5)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumDaysAtorAboveMinAllowableThreshold)) 
                                    break;
                                j++;

                            }
                            if (j > (int)Math.Ceiling(values[0]) -60)// Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField))
                                j = (int)Math.Ceiling(values[0]) -60;// Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField);
                            ozoneModel.ppb = (int)Math.Ceiling(values[0]) - j;
                        }
                    }

                    ozoneModel.days = iThresh;

                    if (iThresh < 5)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumDaysAtorAboveMinAllowableThreshold))
                    {
                        ozoneModel.ozone = -9;
                        ozoneModel.futureOzone = -9;
                        ozoneModel.rrf = -9;
                        //ozoneModel.ppb = 0;
                        if (ozoneModel.days == 0) ozoneModel.ppb = 60;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField);
                        return;
                    }

                    ozoneModel.ozone = Convert.ToSingle(Convert.ToDecimal(valuesTemp.ToList().GetRange(0, valuesTemp.Length > iThresh ? iThresh : valuesTemp.Length).Average()));
                    //ozoneModel.ppb = Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - j;
                    ozoneModel.lim = iThresh;
                }
                 */
                else
                    ozoneModel.ozone = Convert.ToSingle(Convert.ToDecimal(valuesTemp.ToList().GetRange(0, valuesTemp.Length > iThresh ? iThresh : valuesTemp.Length).Average()));

                #region by Yangwenwei
                if (IsSpatialField)
                {
                    //select model days according to subrang first and last day
                    values = dicUsedinRRF.Select(p => p.Value[0]).ToArray();

                    int Thresh_Step = 0, count = 0;

                    int miniThresh = 0;//= ozoneAnalysisConfiguration.rrfSpatialGradientO.doBackstop ? Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.backstopMinThresholdforSpatialField) : 0;

                    if (false)//ozoneAnalysisConfiguration.rrfSpatialGradientO.useInitialThreshold)
                    {
                        //int iniThresh = Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue);

                        //while (Thresh_Step <= iniThresh - miniThresh)
                        //{
                        //    count = 0;
                        //    while (iThresh < dicUsedinRRF.Count)//ozoneModel.lstOzone.Count)
                        //    {
                        //        if (values[count] < iniThresh - Thresh_Step) break;
                        //        count++;
                        //    }
                        //    if (count >= Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumofDaysAtorAboveThreshold)) break;//enough,stop
                        //    Thresh_Step++;

                        //}
                        //if (Thresh_Step > iniThresh - miniThresh)
                        //    Thresh_Step = iniThresh - miniThresh;

                        //ozoneModel.ppbforSptailfield = iniThresh - Thresh_Step;

                    }
                    else
                    {
                        if (values[10-1]>miniThresh)//ozoneAnalysisConfiguration.rrfSpatialGradientO.topXDays - 1] > miniThresh)
                        {
                            count = 10;// ozoneAnalysisConfiguration.rrfSpatialGradientO.topXDays;
                            ozoneModel.ppbforSptailfield = (int)Math.Floor(values[count - 1]);
                        }
                        else
                        {
                            while (Thresh_Step <= Math.Ceiling(values[0]) - miniThresh)
                            {
                                count = 0;
                                while (count < dicUsedinRRF.Count)//ozoneModel.lstOzone.Count)
                                {
                                    if (values[count] < Math.Ceiling(values[0]) - Thresh_Step) break;
                                    count++;
                                }
                                if (count >= 5) break;//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumofDaysAtorAboveThreshold)) break;
                                Thresh_Step++;

                            }
                            if (Thresh_Step > (int)Math.Ceiling(values[0]) - miniThresh)
                                Thresh_Step = (int)Math.Ceiling(values[0]) - miniThresh;

                            ozoneModel.ppbforSptailfield = (int)Math.Ceiling(values[0]) - Thresh_Step;
                        }
                    }

                    //if (j > Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue))
                    //    j = Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.initialThresholdValue) - Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minAllowableThresholdValue);
                    float[] ValidValues = values.Where(p => p > -9).ToArray();
                    //if (iThresh ==90)
                    //{ 
                    //}

                    ozoneModel.daysforSptailfield = count;
                    if (count < 5)//Convert.ToInt32(ozoneAnalysisConfiguration.rrfSpatialGradientO.minNumDaysAtorAboveMinAllowableThreshold))
                    {
                        ozoneModel.bO3forSptailfield = -9;
                        //return;
                    }
                    else
                        ozoneModel.bO3forSptailfield = Convert.ToSingle(Convert.ToDecimal(ValidValues.ToList().GetRange(0, ValidValues.Length > count ? count : ValidValues.Length).Average()));


                    if (ozoneModel.bO3forSptailfield > 0)
                    {
                        if (!false)//ozoneAnalysisConfiguration.rrfSpatialGradientO.doPairDays)
                        {
                            string[] IDArray = dicUsedinRRF.Keys.ToList().GetRange(0, count).ToArray();//ozoneModel.lstOzone.Keys.ToList().GetRange(0, ozoneModel.days).ToArray();
                            float[] valuesForecast = new float[count];
                            for (int iArray = 0; iArray < count; iArray++)
                            {
                                if (dicUsedinRRF[IDArray[iArray]][1] >= 0)
                                    valuesForecast[iArray] = dicUsedinRRF[IDArray[iArray]][1];
                            }
                            //if (valuesForecast.Average() == -9 || valuesForecast.Average() == -7) { ozoneModel.rrf = -9; return; }
                            //double[] valuesForecast = ozoneModel.lstOzoneForecast.Select(p => p.Value).Where(p => p != -9).OrderByDescending(p => p).ToArray();
                            // valuesForecast = valuesForecast.Where(p => p > 0).ToArray();
                            if (valuesForecast.Count() > 0)
                            {

                                ozoneModel.rrfforSptailfield = CommonClass.ToFixed(Convert.ToSingle(valuesForecast.Average()) / ozoneModel.bO3forSptailfield, 4);// Math.Round(valuesForecast.Where(p => p != -9).Average() / ozoneModel.ozone, 3);
                                //ozoneModel.futureOzone = Convert.ToSingle(valuesForecast.Average());
                            }
                            else
                            {
                                ozoneModel.rrfforSptailfield = -9;
                                //ozoneModel.futureOzone = -9;
                            }

                        }
                        else
                        {
                            List<float> lstfuture = dicUsedinRRF.OrderByDescending(q => q.Value[1]).Select(q => q.Value[1]).ToList().GetRange(0, count).Where(q => q >= 0).ToList();
                            if (lstfuture.Count > 0)
                            {
                                ozoneModel.rrfforSptailfield = CommonClass.ToFixed(Convert.ToSingle(lstfuture.Average()) / ozoneModel.ozone, 4);
                                //ozoneModel.futureOzone = Convert.ToSingle(lstfuture.Average());
                            }
                            else
                            {
                                ozoneModel.rrfforSptailfield = -9;
                                //ozoneModel.futureOzone = -9;
                            }
                        }
                    }
                    else { ozoneModel.rrfforSptailfield = -9; }

                }

                #endregion 


                //得到rrf
                //-----首先得到OzoneForecast,
                if (ozoneModel.ozone > 0)
                {
                    try
                    {
                        if (!false)//!ozoneAnalysisConfiguration.rrfSpatialGradientO.doPairDays)
                        {
                            string[] IDArray = dicUsedinRRF.Keys.ToList().GetRange(0, ozoneModel.days).ToArray();//ozoneModel.lstOzone.Keys.ToList().GetRange(0, ozoneModel.days).ToArray();
                            float[] valuesForecast = new float[ozoneModel.days];
                            for (int iArray = 0; iArray < ozoneModel.days; iArray++)
                            {
                                if (dicUsedinRRF[IDArray[iArray]][1] >= 0)
                                    valuesForecast[iArray] = dicUsedinRRF[IDArray[iArray]][1];
                            }
                            if (valuesForecast.Average() == -9 || valuesForecast.Average() == -7) { ozoneModel.rrf = -9; return; }
                            //double[] valuesForecast = ozoneModel.lstOzoneForecast.Select(p => p.Value).Where(p => p != -9).OrderByDescending(p => p).ToArray();
                            // valuesForecast = valuesForecast.Where(p => p > 0).ToArray();
                            if (valuesForecast.Count() > 0)
                            {

                                ozoneModel.rrf = CommonClass.ToFixed(Convert.ToSingle(valuesForecast.Average()) / ozoneModel.ozone, 4);// Math.Round(valuesForecast.Where(p => p != -9).Average() / ozoneModel.ozone, 3);
                                ozoneModel.futureOzone = Convert.ToSingle(valuesForecast.Average());
                            }
                            else
                            {
                                ozoneModel.rrf = -9;
                                ozoneModel.futureOzone = -9;
                            }

                        }
                        else
                        {
                            List<float> lstfuture = dicUsedinRRF.OrderByDescending(q => q.Value[1]).Select(q => q.Value[1]).ToList().GetRange(0, ozoneModel.days).Where(q => q >= 0).ToList();
                            if (lstfuture.Count > 0)
                            {
                                ozoneModel.rrf = CommonClass.ToFixed(Convert.ToSingle(lstfuture.Average()) / ozoneModel.ozone, 4);
                                ozoneModel.futureOzone = Convert.ToSingle(lstfuture.Average());
                            }
                            else
                            {
                                ozoneModel.rrf = -9;
                                ozoneModel.futureOzone = -9;
                            }
                        }
                    }
                    catch
                    {
                    }
                }
                else
                    ozoneModel.futureOzone = -9;
            }
            catch
            {
            }

        }
        
        public static bool SaveOzoneSpatialField(BaseScenario baseScenario, List<OzoneModelOutput>lstOzoneOpt, Dictionary<string, int[]> dicColRow)
        {
            if (!(baseScenario.configuration is BenMAPOzoneAnalysisConfiguration))
                return false;
            try
            {
                //lstOzoneOpt = lstOzoneOpt.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                BenMAPOzoneAnalysisConfiguration BenMapOzone = baseScenario.configuration as BenMAPOzoneAnalysisConfiguration;
                DataTable dtOzoneSpatial = new DataTable();
                DataTable dtControl = new DataTable();
                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA)
                {
                    #region
                    dtOzoneSpatial.Columns.Add("Column");
                    dtOzoneSpatial.Columns.Add("Row");
                    dtOzoneSpatial.Columns.Add("Metric");
                    dtOzoneSpatial.Columns.Add("Seasonal Metric");
                    dtOzoneSpatial.Columns.Add("Statistic");
                    dtOzoneSpatial.Columns.Add("Values");
                    dtOzoneSpatial.Columns.Add("gridcell_lat");
                    dtOzoneSpatial.Columns.Add("gridcell_long");

                    dtControl.Columns.Add("Column");
                    dtControl.Columns.Add("Row");
                    dtControl.Columns.Add("Metric");
                    dtControl.Columns.Add("Seasonal Metric");
                    dtControl.Columns.Add("Statistic");
                    dtControl.Columns.Add("Values");
                    dtControl.Columns.Add("gridcell_lat");
                    dtControl.Columns.Add("gridcell_long");
                    //dtAnnualPMSpatial.Columns.Add("_id");
                    //dtAnnualPMSpatial.Columns.Add("gridcell_lat");
                    //dtAnnualPMSpatial.Columns.Add("gridcell_long");
                    //dtAnnualPMSpatial.Columns.Add("b_pm25_ann_DV");
                    //dtAnnualPMSpatial.Columns.Add("f_pm25_ann_DV");
                    //dtAnnualPMSpatial.Columns.Add("b_blank_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_crustal_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_EC_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_NH4_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_Ocmb_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_SO4_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_NO3_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_water_mass");
                    //dtAnnualPMSpatial.Columns.Add("b_salt_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_blank_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_crustal_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_EC_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_NH4_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_Ocmb_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_SO4_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_NO3_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_water_mass");
                    //dtAnnualPMSpatial.Columns.Add("f_salt_mass");
                    //dtAnnualPMSpatial.Columns.Add("rrf_crustal");
                    //dtAnnualPMSpatial.Columns.Add("rrf_ec");
                    //dtAnnualPMSpatial.Columns.Add("rrf_nh4");
                    //dtAnnualPMSpatial.Columns.Add("rrf_oc");
                    //dtAnnualPMSpatial.Columns.Add("rrf_so4");
                    //dtAnnualPMSpatial.Columns.Add("rrf_no3");
                    //dtAnnualPMSpatial.Columns.Add("rrf_water_mass");
                    //dtAnnualPMSpatial.Columns.Add("rrf_salt");
                    #endregion
                    #region
                    foreach (var k in lstOzoneOpt)
                    {
                        DataRow dr = dtOzoneSpatial.NewRow();
                        DataRow dr2 = dtControl.NewRow();
                        dr[0] = dicColRow[k.id][0];
                        dr[1] = dicColRow[k.id][1];
                        dr[2] = "D8HourMax";
                        dr[3] = "";
                        dr[4] = "Mean";
                        dr[5] = Math.Round(k.vna, 8);
                        dr[6] = Math.Round(k.lat, 6);
                        dr[7] = Math.Round(k.longitude, 6);
                        dtOzoneSpatial.Rows.Add(dr);
                        dr2[0] = dicColRow[k.id][0];
                        dr2[1] = dicColRow[k.id][1];
                        dr2[2] = "D8HourMax";
                        dr2[3] = "";
                        dr2[4] = "Mean";
                        dr2[5] = Math.Round(k.vnaForcast, 8);
                        dr2[6] = Math.Round(k.lat, 6);
                        dr2[7] = Math.Round(k.longitude, 6);
                        dtControl.Rows.Add(dr2);
                        //dr[0] = k.Value.id;
                        //dr[1] = Math.Round(k.Value.latitude, 6);
                        //dr[2] = Math.Round(k.Value.longitude, 6);
                        //dr[3] = CommonClass.ToFixed(k.Value.dicQuarterlySpatial.Select(p => p.Value.bPMAnnDV).Average(), 2);
                        //dr[4] = CommonClass.ToFixed(k.Value.dicQuarterlySpatial.Select(p => p.Value.fPMAnnDV).Average(), 2);
                        //dr[5] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        //dr[6] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bCrustalMass).Average(), CommonClass.Species_calc_precision);
                        //dr[7] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bECMass).Average(), CommonClass.Species_calc_precision);
                        //dr[8] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bNH4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[9] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bOcmbMass).Average(), CommonClass.Species_calc_precision);
                        //dr[10] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bSO4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[11] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bNO3rMass).Average(), CommonClass.Species_calc_precision);
                        //dr[12] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bWaterMass).Average(), CommonClass.Species_calc_precision);
                        //dr[13] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bSaltMass).Average(), CommonClass.Species_calc_precision);
                        //dr[14] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        //dr[15] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fCrustalMass).Average(), CommonClass.Species_calc_precision);
                        //dr[16] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fECMass).Average(), CommonClass.Species_calc_precision);
                        //dr[17] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fNH4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[18] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fOcmbMass).Average(), CommonClass.Species_calc_precision);
                        //dr[19] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fSO4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[20] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fNO3Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[21] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fWaterMass).Average(), CommonClass.Species_calc_precision);
                        //dr[22] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fSaltMass).Average(), CommonClass.Species_calc_precision);
                        //dr[23] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fCrustalMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bCrustalMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fCrustalMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bCrustalMass).Average(), 4);
                        //dr[24] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fECMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bECMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fECMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bECMass).Average(), 4);
                        //dr[25] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fNH4Mass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bNH4Mass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fNH4Mass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bNH4Mass).Average(), 4);
                        //dr[26] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fOcmbMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bOcmbMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fOcmbMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bOcmbMass).Average(), 4);
                        //dr[27] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fSO4Mass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bSO4Mass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fSO4Mass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bSO4Mass).Average(), 4);
                        ////dr[28] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fNO3Mass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bNO3rMass).Average(), 4);
                        //dr[28] = Double.IsNaN(k.Value.dicQuarterlySpatial.Select(p => p.Value.bNO3rMass).Average() == 0 ? 0 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fNO3Mass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bNO3rMass).Average(), 4)) ? -9 : k.Value.dicQuarterlySpatial.Select(p => p.Value.bNO3rMass).Average() == 0 ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fNO3Mass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bNO3rMass).Average(), 4);
                        //dr[29] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fWaterMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bWaterMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fWaterMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bWaterMass).Average(), 4);
                        //dr[30] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fSaltMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bSaltMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.fSaltMass).Average() / k.Value.dicQuarterlySpatial.Select(p => p.Value.bSaltMass).Average(), 4);
                        //dtAnnualPMSpatial.Rows.Add(dr);
                    }
                    #endregion
                }
                //else if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA)
                //{
                //    dtAnnualPMSpatial.Columns.Add("_id");
                //    dtAnnualPMSpatial.Columns.Add("gridcell_lat");
                //    dtAnnualPMSpatial.Columns.Add("gridcell_long");
                //    dtAnnualPMSpatial.Columns.Add("b_pm25_ann_DV");
                //    dtAnnualPMSpatial.Columns.Add("b_blank_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_crustal_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_EC_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_NH4_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_Ocmb_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_SO4_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_NO3_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_water_mass");
                //    dtAnnualPMSpatial.Columns.Add("b_salt_mass");

                //    #region
                //    foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpatialField)
                //    {
                //        DataRow dr = dtAnnualPMSpatial.NewRow();
                //        dr[0] = k.Value.id;
                //        dr[1] = Math.Round(k.Value.latitude, 6);
                //        dr[2] = Math.Round(k.Value.longitude, 6);
                //        dr[3] = CommonClass.ToFixed(k.Value.dicQuarterlySpatial.Select(p => p.Value.bPMAnnDV).Average(), 2);
                //        dr[4] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                //        dr[5] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bCrustalMass).Average(), CommonClass.Species_calc_precision);
                //        dr[6] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bECMass).Average(), CommonClass.Species_calc_precision);
                //        dr[7] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bNH4Mass).Average(), CommonClass.Species_calc_precision);
                //        dr[8] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bOcmbMass).Average(), CommonClass.Species_calc_precision);
                //        dr[9] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bSO4Mass).Average(), CommonClass.Species_calc_precision);
                //        dr[10] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bNO3rMass).Average(), CommonClass.Species_calc_precision);
                //        dr[11] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bWaterMass).Average(), CommonClass.Species_calc_precision);
                //        dr[12] = Math.Round(k.Value.dicQuarterlySpatial.Select(p => p.Value.bSaltMass).Average(), CommonClass.Species_calc_precision);
                //        dtAnnualPMSpatial.Rows.Add(dr);
                //    }
                //    #endregion
                //}
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = BenMapOzone.modelInput.scenarioName + " Ozone Spatial Field Base (VNA).csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtOzoneSpatial, _resultFilePath + @"\" + strFile, "");
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                dtOzoneSpatial.Dispose();

                strFile = BenMapOzone.modelInput.scenarioName + " Ozone Spatial Field Future (VNA).csv";
                BaseOutput baseOutput2 = new BaseOutput();
                CommonClass.SaveCSV(dtControl, _resultFilePath + @"\" + strFile, "");
                baseOutput2.outputName = strFile.Replace(".csv", "");
                baseOutput2.outputType = "Monitor Network";
                baseOutput2.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput2.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput2.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput2);
                dtControl.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveOzoneSpatialFieldGradAdj(BaseScenario baseScenario, List<OzoneModelOutput> lstOzoneOpt, Dictionary<string, int[]> dicColRow)
        {
            if (!(baseScenario.configuration is BenMAPOzoneAnalysisConfiguration))
                return false;
            try
            {
                //lstOzoneOpt = lstOzoneOpt.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                BenMAPOzoneAnalysisConfiguration BenMapOzone = baseScenario.configuration as BenMAPOzoneAnalysisConfiguration;
                DataTable dtGradAdjOzoneSpatial = new DataTable();
                DataTable dtControl = new DataTable();
                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna)
                //{
                //    #region
                //    dtGradAdjAnnualSpatial.Columns.Add("_id");
                //    dtGradAdjAnnualSpatial.Columns.Add("gridcell_lat");
                //    dtGradAdjAnnualSpatial.Columns.Add("gridcell_long");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_pm25_ann_DV_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_blank_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_crustal_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_EC_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_NH4_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_Ocmb_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_SO4_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_NO3_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_water_mass_ga");
                //    dtGradAdjAnnualSpatial.Columns.Add("b_salt_mass_ga");
                //    #endregion
                //    #region
                //    foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpatialFieldGradAdj)
                //    {
                //        DataRow dr = dtGradAdjAnnualSpatial.NewRow();
                //        dr[0] = k.Value.id;
                //        dr[1] = Math.Round(k.Value.latitude, 6);
                //        dr[2] = Math.Round(k.Value.longitude, 6);
                //        dr[3] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bPMAnnDV).Average(), 2);
                //        dr[4] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                //        dr[5] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bCrustalMass).Average(), CommonClass.Species_calc_precision);
                //        dr[6] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bECMass).Average(), CommonClass.Species_calc_precision);
                //        dr[7] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNH4Mass).Average(), CommonClass.Species_calc_precision);
                //        dr[8] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bOcmbMass).Average(), CommonClass.Species_calc_precision);
                //        dr[9] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSO4Mass).Average(), CommonClass.Species_calc_precision);
                //        dr[10] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNO3rMass).Average(), CommonClass.Species_calc_precision);
                //        dr[11] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bWaterMass).Average(), CommonClass.Species_calc_precision);
                //        dr[12] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSaltMass).Average(), CommonClass.Species_calc_precision);
                //        dtGradAdjAnnualSpatial.Rows.Add(dr);
                //    }
                //    #endregion
                //}
                //else if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna)
                {
                    #region
                    dtGradAdjOzoneSpatial.Columns.Add("Column");
                    dtGradAdjOzoneSpatial.Columns.Add("Row");
                    dtGradAdjOzoneSpatial.Columns.Add("Metric");
                    dtGradAdjOzoneSpatial.Columns.Add("Seasonal Metric");
                    dtGradAdjOzoneSpatial.Columns.Add("Statistic");
                    dtGradAdjOzoneSpatial.Columns.Add("Values");
                    dtGradAdjOzoneSpatial.Columns.Add("gridcell_lat");
                    dtGradAdjOzoneSpatial.Columns.Add("gridcell_long");

                    dtControl.Columns.Add("Column");
                    dtControl.Columns.Add("Row");
                    dtControl.Columns.Add("Metric");
                    dtControl.Columns.Add("Seasonal Metric");
                    dtControl.Columns.Add("Statistic");
                    dtControl.Columns.Add("Values");
                    dtControl.Columns.Add("gridcell_lat");
                    dtControl.Columns.Add("gridcell_long");
                    //dtGradAdjAnnualSpatial.Columns.Add("_id");
                    //dtGradAdjAnnualSpatial.Columns.Add("gridcell_lat");
                    //dtGradAdjAnnualSpatial.Columns.Add("gridcell_long");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_pm25_ann_DV_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_pm25_ann_DV_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_blank_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_crustal_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_EC_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_NH4_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_Ocmb_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_SO4_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_NO3_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_water_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("b_salt_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_blank_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_crustal_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_EC_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_NH4_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_Ocmb_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_SO4_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_NO3_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_water_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("f_salt_mass_ga");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_crustal");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_ec");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_nh4");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_oc");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_so4");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_no3");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_water_mass");
                    //dtGradAdjAnnualSpatial.Columns.Add("rrf_salt");
                    #endregion
                    #region
                    foreach (var k in lstOzoneOpt)
                    {
                        DataRow dr = dtGradAdjOzoneSpatial.NewRow();
                        DataRow dr2 = dtControl.NewRow();
                        dr[0] = dicColRow[k.id][0];
                        dr[1] = dicColRow[k.id][1];
                        dr[2] = "D8HourMax";
                        dr[3] = "";
                        dr[4] = "Mean";
                        dr[5] = Math.Round(k.evna, 8);
                        dr[6] = Math.Round(k.lat, 6);
                        dr[7] = Math.Round(k.longitude, 6);
                        dtGradAdjOzoneSpatial.Rows.Add(dr);
                        dr2[0] = dicColRow[k.id][0];
                        dr2[1] = dicColRow[k.id][1];
                        dr2[2] = "D8HourMax";
                        dr2[3] = "";
                        dr2[4] = "Mean";
                        dr2[5] = Math.Round(k.evnaForcast, 8);
                        dr2[6] = Math.Round(k.lat, 6);
                        dr2[7] = Math.Round(k.longitude, 6);
                        dtControl.Rows.Add(dr2);
                        //dr[0] = k.Value.id;
                        //dr[1] = Math.Round(k.Value.latitude, 6);
                        //dr[2] = Math.Round(k.Value.longitude, 6);
                        //dr[3] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bPMAnnDV).Average(), 2);
                        //dr[4] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fPMAnnDV).Average(), 2);
                        //dr[5] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        //dr[6] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bCrustalMass).Average(), CommonClass.Species_calc_precision);
                        //dr[7] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bECMass).Average(), CommonClass.Species_calc_precision);
                        //dr[8] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNH4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[9] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bOcmbMass).Average(), CommonClass.Species_calc_precision);
                        //dr[10] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSO4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[11] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNO3rMass).Average(), CommonClass.Species_calc_precision);
                        //dr[12] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bWaterMass).Average(), CommonClass.Species_calc_precision);
                        //dr[13] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSaltMass).Average(), CommonClass.Species_calc_precision);
                        //dr[14] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        //dr[15] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fCrustalMass).Average(), CommonClass.Species_calc_precision);
                        //dr[16] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fECMass).Average(), CommonClass.Species_calc_precision);
                        //dr[17] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fNH4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[18] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fOcmbMass).Average(), CommonClass.Species_calc_precision);
                        //dr[19] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fSO4Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[20] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fNO3Mass).Average(), CommonClass.Species_calc_precision);
                        //dr[21] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fWaterMass).Average(), CommonClass.Species_calc_precision);
                        //dr[22] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fSaltMass).Average(), CommonClass.Species_calc_precision);
                        //dr[23] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fCrustalMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bCrustalMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fCrustalMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bCrustalMass).Average(), 4);
                        //dr[24] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fECMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bECMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fECMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bECMass).Average(), 4);
                        //dr[25] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fNH4Mass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNH4Mass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fNH4Mass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNH4Mass).Average(), 4);
                        //dr[26] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fOcmbMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bOcmbMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fOcmbMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bOcmbMass).Average(), 4);
                        //dr[27] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fSO4Mass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSO4Mass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fSO4Mass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSO4Mass).Average(), 4);
                        ////dr[28] = Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fNO3Mass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNO3rMass).Average(), 4);
                        //dr[28] = k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNO3rMass).Average() == 0 ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fNO3Mass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bNO3rMass).Average(), 4);
                        //dr[29] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fWaterMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bWaterMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fWaterMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bWaterMass).Average(), 4);
                        //dr[30] = Double.IsNaN(Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fSaltMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSaltMass).Average(), 4)) ? -9 : Math.Round(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fSaltMass).Average() / k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bSaltMass).Average(), 4);
                        //dtGradAdjAnnualSpatial.Rows.Add(dr);
                    }
                    #endregion
                }
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = BenMapOzone.modelInput.scenarioName + " Ozone Spatial Field Base (eVNA).csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtGradAdjOzoneSpatial, _resultFilePath + @"\" + strFile, "");
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                dtGradAdjOzoneSpatial.Dispose();

                strFile = BenMapOzone.modelInput.scenarioName + " Ozone Spatial Field Future (eVNA).csv";
                BaseOutput baseOutput2 = new BaseOutput();
                CommonClass.SaveCSV(dtControl, _resultFilePath + @"\" + strFile, "");
                baseOutput2.outputName = strFile.Replace(".csv", "");
                baseOutput2.outputType = "Monitor Network";
                baseOutput2.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput2.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput2.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput2);
                dtControl.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }
        public static bool SaveOzoneSpatialFieldDS(BaseScenario baseScenario, List<OzoneModelOutput> lstOzoneOpt, Dictionary<string, int[]> dicColRow, List<DownscaleR.Ozone.OzoneModel> lstDSvalue)
        {
            if (!(baseScenario.configuration is BenMAPOzoneAnalysisConfiguration))
                return false;
            try
            {
                //lstOzoneOpt = lstOzoneOpt.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                BenMAPOzoneAnalysisConfiguration BenMapOzone = baseScenario.configuration as BenMAPOzoneAnalysisConfiguration;
                DataTable dtOzoneDSBase = new DataTable();
                DataTable dtOzoneDSControl = new DataTable();              
                {
                    #region Add coloum
                    dtOzoneDSBase.Columns.Add("Column");
                    dtOzoneDSBase.Columns.Add("Row");
                    dtOzoneDSBase.Columns.Add("Metric");
                    dtOzoneDSBase.Columns.Add("Seasonal Metric");
                    dtOzoneDSBase.Columns.Add("Statistic");
                    dtOzoneDSBase.Columns.Add("Values");
                    dtOzoneDSBase.Columns.Add("gridcell_lat");
                    dtOzoneDSBase.Columns.Add("gridcell_long");

                    dtOzoneDSControl.Columns.Add("Column");
                    dtOzoneDSControl.Columns.Add("Row");
                    dtOzoneDSControl.Columns.Add("Metric");
                    dtOzoneDSControl.Columns.Add("Seasonal Metric");
                    dtOzoneDSControl.Columns.Add("Statistic");
                    dtOzoneDSControl.Columns.Add("Values");
                    dtOzoneDSControl.Columns.Add("gridcell_lat");
                    dtOzoneDSControl.Columns.Add("gridcell_long");
                    #endregion
                    #region
                    for (int i = 0; i < lstOzoneOpt.Count; i++)
                    {
                        DataRow dr = dtOzoneDSBase.NewRow();
                        DataRow dr2 = dtOzoneDSControl.NewRow();
                        dr[0] = dicColRow[lstOzoneOpt[i].id][0];
                        dr[1] = dicColRow[lstOzoneOpt[i].id][1];
                        dr[2] = "D8HourMax";
                        dr[3] = "";
                        dr[4] = "Mean";
                        dr[5] = lstDSvalue[i].DS_Prediction;
                        dr[6] = Math.Round(lstOzoneOpt[i].lat, 6);
                        dr[7] = Math.Round(lstOzoneOpt[i].longitude, 6);
                        dtOzoneDSBase.Rows.Add(dr);
                        dr2[0] = dicColRow[lstOzoneOpt[i].id][0];
                        dr2[1] = dicColRow[lstOzoneOpt[i].id][1];
                        dr2[2] = "D8HourMax";
                        dr2[3] = "";
                        dr2[4] = "Mean";
                        dr2[5] = lstOzoneOpt[i].rrf < 0 ? -9 : (lstDSvalue[i].DS_Prediction < 0 ? -9 : lstDSvalue[i].DS_Prediction * lstOzoneOpt[i].rrf);
                        dr2[6] = Math.Round(lstOzoneOpt[i].lat, 6);
                        dr2[7] = Math.Round(lstOzoneOpt[i].longitude, 6);
                        dtOzoneDSControl.Rows.Add(dr2);
                        //dtGradAdjAnnualSpatial.Rows.Add(dr);
                    }
                    //foreach (var k in lstOzoneOpt)
                    //{
                    //    DataRow dr = dtOzoneDSBase.NewRow();
                    //    DataRow dr2 = dtOzoneDSControl.NewRow();
                    //    dr[0] = dicColRow[k.id][0];
                    //    dr[1] = dicColRow[k.id][1];
                    //    dr[2] = "D8HourMax";
                    //    dr[3] = "";
                    //    dr[4] = "Mean";
                    //    dr[5] = Math.Round(k.evna, 2);
                    //    dr[6] = Math.Round(k.lat, 6);
                    //    dr[7] = Math.Round(k.longitude, 6);
                    //    dtOzoneDSBase.Rows.Add(dr);
                    //    dr2[0] = dicColRow[k.id][0];
                    //    dr2[1] = dicColRow[k.id][1];
                    //    dr2[2] = "D8HourMax";
                    //    dr2[3] = "";
                    //    dr2[4] = "Mean";
                    //    dr2[5] = Math.Round(k.evnaForcast, 2);
                    //    dr2[6] = Math.Round(k.lat, 6);
                    //    dr2[7] = Math.Round(k.longitude, 6);
                    //    dtOzoneDSControl.Rows.Add(dr2);
                    //    //dtGradAdjAnnualSpatial.Rows.Add(dr);
                    //}
                    #endregion
                }
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = BenMapOzone.modelInput.scenarioName + " Ozone Spatial Field Base (Downscaler).csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtOzoneDSBase, _resultFilePath + @"\" + strFile, "");
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Spatial Field";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                dtOzoneDSBase.Dispose();

                strFile = BenMapOzone.modelInput.scenarioName + " Ozone Spatial Field Future (Downscaler).csv";
                BaseOutput baseOutput2 = new BaseOutput();
                CommonClass.SaveCSV(dtOzoneDSControl, _resultFilePath + @"\" + strFile, "");
                baseOutput2.outputName = strFile.Replace(".csv", "");
                baseOutput2.outputType = "Spatial Field";
                baseOutput2.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput2.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput2.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput2);
                dtOzoneDSControl.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }
        public static bool SaveDeltaOzoneSpatialField(BaseScenario baseScenario, List<OzoneModelOutput> lstOzoneOpt, Dictionary<string, int[]> dicColRow, List<DownscaleR.Ozone.OzoneModel> lstDSvalue,bool DS,bool VNA,bool eVNA)
        {
            if (!(baseScenario.configuration is BenMAPOzoneAnalysisConfiguration))
                return false;
            try
            {
                #region delta option
                if (!(DS || VNA || eVNA))
                    return false;
                bool dsvna = DS && VNA;
                bool dsevna = DS && eVNA;
                bool evnavna = eVNA && VNA;
                #endregion

                BenMAPOzoneAnalysisConfiguration BenMapOzone = baseScenario.configuration as BenMAPOzoneAnalysisConfiguration;
                DataTable dtOzoneDSBase = new DataTable();
                {
                    dtOzoneDSBase.Columns.Add("Column");
                    dtOzoneDSBase.Columns.Add("Row");
                    dtOzoneDSBase.Columns.Add("Metric");
                    dtOzoneDSBase.Columns.Add("Seasonal Metric");
                    dtOzoneDSBase.Columns.Add("Statistic");
                    if (dsvna) 
                    {   dtOzoneDSBase.Columns.Add("Deltab_O3_(DS-VNA)");
                        dtOzoneDSBase.Columns.Add("Deltaf_O3_(DS-VNA)");}
                    if (dsevna) 
                    {  
                        dtOzoneDSBase.Columns.Add("Deltab_O3_(DS-eVNA)");
                        dtOzoneDSBase.Columns.Add("Deltaf_O3_(DS-eVNA)");
                    }
                    if(DS)
                    {
                        dtOzoneDSBase.Columns.Add("Deltab_O3_(DS-model)");
                        dtOzoneDSBase.Columns.Add("Deltaf_O3_(DS-model)");
                    }
                    if (evnavna)
                    {
                        dtOzoneDSBase.Columns.Add("Deltab_O3_(eVNA-VNA)");
                        dtOzoneDSBase.Columns.Add("Deltaf_O3_(eVNA-VNA)");
                    }
                    if (eVNA)
                    {
                        dtOzoneDSBase.Columns.Add("Deltab_O3_(eVNA-model)");
                        dtOzoneDSBase.Columns.Add("Deltaf_O3_(eVNA-model)");
                    }
                    if (VNA)
                    {
                        dtOzoneDSBase.Columns.Add("Deltab_O3_(VNA-model)");
                        dtOzoneDSBase.Columns.Add("Deltaf_O3_(VNA-model)");
                    }
                    dtOzoneDSBase.Columns.Add("gridcell_lat");
                    dtOzoneDSBase.Columns.Add("gridcell_long");
                    for (int i = 0; i < lstOzoneOpt.Count; i++)
                    {
                        int r = 0;
                        DataRow dr = dtOzoneDSBase.NewRow();
                        dr[r++] = dicColRow[lstOzoneOpt[i].id][0];
                        dr[r++] = dicColRow[lstOzoneOpt[i].id][1];
                        dr[r++] = "D8HourMax";
                        dr[r++] = "";
                        dr[r++] = "Mean";
                        if (dsvna)
                        {
                            dr[r++] = lstDSvalue[i].DS_Prediction < 0 ? -9 : lstDSvalue[i].DS_Prediction - lstOzoneOpt[i].vna;
                            dr[r++] = lstOzoneOpt[i].rrf < 0 ? -9 : (lstDSvalue[i].DS_Prediction < 0 ? -9 : lstDSvalue[i].DS_Prediction * lstOzoneOpt[i].rrf - lstOzoneOpt[i].vnaForcast);
                        }
                        if (dsevna)
                        {
                            dr[r++] = lstDSvalue[i].DS_Prediction < 0 ? -9 : lstDSvalue[i].DS_Prediction - lstOzoneOpt[i].evna;
                            dr[r++] = lstOzoneOpt[i].rrf < 0 ? -9 : (lstDSvalue[i].DS_Prediction < 0 ? -9 : lstDSvalue[i].DS_Prediction * lstOzoneOpt[i].rrf - lstOzoneOpt[i].evnaForcast);
                        }
                        if (DS)
                        {
                            dr[r++] = lstDSvalue[i].DS_Prediction < 0 ? -9 : lstDSvalue[i].DS_Prediction - lstOzoneOpt[i].bO3modelForSpatialField;
                            dr[r++] = lstOzoneOpt[i].rrf < 0 ? -9 : (lstDSvalue[i].DS_Prediction < 0 ? -9 : lstDSvalue[i].DS_Prediction * lstOzoneOpt[i].rrf - lstOzoneOpt[i].bO3modelForSpatialField * lstOzoneOpt[i].rrf);
                        }
                        if (evnavna)
                        {
                            dr[r++] = lstOzoneOpt[i].evna - lstOzoneOpt[i].vna;
                            dr[r++] = lstOzoneOpt[i].evnaForcast - lstOzoneOpt[i].vnaForcast;
                        }
                        if (eVNA)
                        {
                            dr[r++] = lstOzoneOpt[i].evna - lstOzoneOpt[i].bO3modelForSpatialField;
                            dr[r++] = lstOzoneOpt[i].evnaForcast - lstOzoneOpt[i].bO3modelForSpatialField * lstOzoneOpt[i].rrf;
                        }
                        if (VNA)
                        {
                            dr[r++] = lstOzoneOpt[i].vna - lstOzoneOpt[i].bO3modelForSpatialField;
                            dr[r++] = lstOzoneOpt[i].vnaForcast - lstOzoneOpt[i].bO3modelForSpatialField * lstOzoneOpt[i].rrf;
                        }
                        dr[r++] = Math.Round(lstOzoneOpt[i].lat, 6);
                        dr[r++] = Math.Round(lstOzoneOpt[i].longitude, 6);
                        dtOzoneDSBase.Rows.Add(dr);
                    }
                }
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPOzoneAnalysisConfiguration).modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = BenMapOzone.modelInput.scenarioName + " Delta Ozone Spatial Field.csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtOzoneDSBase, _resultFilePath + @"\" + strFile, "");
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Spatial Field";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                dtOzoneDSBase.Dispose();
               
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }
 
    }
}
