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

namespace SMAT_CE
{
    class OzoneChinaCommonClass
    {
        public static DateTime _beginTime;//记录开始时间
        public static DateTime _endTime;//记录结束时间
        public static string _resultFilePath = "";

        public static bool OzoneChinaAnalysis(BaseScenario basecenario, SMAT_CE mats)
        {
            if (!(basecenario.configuration is OzoneAnalysisChinaConfiguration))
                return false;
            try
            {
                OzoneAnalysisChinaConfiguration ozonechinaconfiguration = basecenario.configuration as OzoneAnalysisChinaConfiguration;
           

                DotSpatial.Projections.ProjectionInfo proj = new DotSpatial.Projections.ProjectionInfo();
             
                if (CommonClass.CurrentAnalysis == enumAnalysis.OzoneOther)
                {
                    proj = DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projOther);
                }
                else
                {
                    if (mats.mainMap.Layers.Count > 0 && mats.mainMap.Layers[mats.mainMap.Layers.Count - 1].LegendText == "China_prov_WGS84_LCC")
                        proj = mats.mainMap.Layers[mats.mainMap.Layers.Count - 1].Projection;
                    else
                    {
                        mats.mainMap.Layers.Add(System.Windows.Forms.Application.StartupPath + @"\Data\ShapeFiles\China_prov_WGS84_LCC.shp");
                        proj = mats.mainMap.Layers[mats.mainMap.Layers.Count - 1].Projection;
                        mats.mainMap.Layers.RemoveAt(mats.mainMap.Layers.Count - 1);
                    }
                    proj = mats.mainMap.Projection;
                }              


                #region Read Monitor data

                //----open Monitor File && output Log Message----
                _beginTime = DateTime.Now;
                bool erroroccur = false;
                string sFirstLine = "";
                DataTable dtMonitor = new DataTable();
                CommonClass.CurrentLog = "Read monitor data \"" + Path.GetFileName(ozonechinaconfiguration.monitorDataOzoneChina.ozoneMonitorDataFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                dtMonitor = CommonClass.getDataSetFromCSVAndFirstLine(ozonechinaconfiguration.monitorDataOzoneChina.ozoneMonitorDataFile, ref sFirstLine, ref erroroccur);
                if (dtMonitor == null || erroroccur)
                {
                    CommonClass.CurrentLog = "Fail to read monitor data \"" + Path.GetFileName(ozonechinaconfiguration.monitorDataOzoneChina.ozoneMonitorDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }

                //----Read Monitor Data----
                Dictionary<string, OzoneMonitor> dicOzoneMonitor = new Dictionary<string, OzoneMonitor>();
                //------各个字段------
                int iID = -1, iType = -1, iLat = -1, iLong = -1, iDVYearQuarter = -1, iO3 = -1, iLocation = -1, iStation = -1;
                try
                {
                    //-------首先得到各个字段的index-------
                    for (int i = 0; i < dtMonitor.Columns.Count; i++)
                    {
                        switch (dtMonitor.Columns[i].ColumnName.ToLower().Trim())
                        {
                            case "_id": iID = i; break;
                            case "_type": iType = i; break;
                            case "lat": iLat = i; break;
                            case "long": iLong = i; break;
                            case "season_dv": iDVYearQuarter = i; break;
                            case "o3": iO3 = i; break;
                            case "location_name": iLocation = i; break;
                            case "station_name": iStation = i; break;
                        }
                    }

                    foreach (DataRow dr in dtMonitor.Rows)
                    {
                        if (dicOzoneMonitor.ContainsKey(dr[iID].ToString()))
                        {
                            dicOzoneMonitor[dr[iID].ToString()].dicOzone.Add(dr[iDVYearQuarter].ToString(), Convert.ToDouble(dr[iO3]));
                        }
                        else
                        {
                            dicOzoneMonitor.Add(dr[iID].ToString(), new OzoneMonitor());
                            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[iLocation].ToString();
                            dicOzoneMonitor[dr[iID].ToString()].state = dr[iStation].ToString();
                            dicOzoneMonitor[dr[iID].ToString()].dicOzone = new Dictionary<string, double>();
                            dicOzoneMonitor[dr[iID].ToString()].dicOzone.Add(dr[iDVYearQuarter].ToString(), Convert.ToDouble(dr[iO3]));
                        }
                    }
                }
                catch (Exception)
                {
                    CommonClass.CurrentLog = "Fail to read monitor data \"" + Path.GetFileName(ozonechinaconfiguration.monitorDataOzoneChina.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 修正坐标系

                double[] dConvertMonitor = null;
                List<double> lstConvertMonitor = new List<double>();
                List<string> lstMonitorKey = dicOzoneMonitor.Keys.ToList();
                foreach (string key in lstMonitorKey)
                {
                    lstConvertMonitor.Add(dicOzoneMonitor[key].longitude);
                    lstConvertMonitor.Add(dicOzoneMonitor[key].lat);
                }

                dConvertMonitor = lstConvertMonitor.ToArray();
                DotSpatial.Projections.Reproject.ReprojectPoints(dConvertMonitor, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984, proj, 0, dConvertMonitor.Length / 2);
                for (int i = 0; i < lstMonitorKey.Count; i++)
                {
                    dicOzoneMonitor[lstMonitorKey[i]].longitudeLamber = dConvertMonitor[i * 2] / 100;
                    dicOzoneMonitor[lstMonitorKey[i]].latitudeLamber = dConvertMonitor[i * 2 + 1] / 100;
                }


                #endregion

                //----Set Monitor Year----
                string startYear = ozonechinaconfiguration.monitorDataOzoneChina.ozoneStartYear;
                string endYear = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear;
                string lastYear = "";
                List<string> lstMonitorYear = new List<string>();
                for (int i = Convert.ToInt16(startYear); i <= Convert.ToInt16(endYear); i++)
                {
                    lstMonitorYear.Add(i.ToString());
                }
                foreach (string key in dicOzoneMonitor.Keys)
                {
                    List<double> lstSumTemp = new List<double>();
                    int iValid = 0;
                    foreach (KeyValuePair<string, double> YearOzone in dicOzoneMonitor[key].dicOzone)
                    {
                        if (lstMonitorYear.Contains(YearOzone.Key.Substring(0, 4)) && YearOzone.Value > 0)
                        {
                            lstSumTemp.Add(YearOzone.Value);
                            iValid++;
                        }
                    }
                    if (iValid == 0)
                        dicOzoneMonitor[key].ozone = -7;
                    else
                    {
                        dicOzoneMonitor[key].ozone = lstSumTemp.Sum() / iValid;
                        dicOzoneMonitor[key].datacount = lstSumTemp.Count;
                    }
                }


                #endregion

                #region Read Model Data

                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read model data \"" + Path.GetFileName(ozonechinaconfiguration.modelDataOzoneChina.baselineModelDataFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                //------各字段------
                iID = -1; iType = -1; iLat = -1; iLong = -1; iO3 = -1; iDVYearQuarter = -1;
                Dictionary<string, OzoneModel> dicOzoneModel = new Dictionary<string, OzoneModel>();

                //-----Base------
                FileStream fs = new FileStream(ozonechinaconfiguration.modelDataOzoneChina.baselineModelDataFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                try
                {
                    using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                    {
                        csv.ReadLine();
                        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 "season": iDVYearQuarter = i; break;
                                case "o3": iO3 = i; break;
                            }
                            i++;
                        }
                        while (strLine != null)
                        {
                            strLine = csv.ReadLine();
                            if (strLine == null)
                                break;
                            strLineArray = strLine.Split(new char[] { ',' });
                            if (dicOzoneModel.ContainsKey(strLineArray[iID].ToString().Trim()))
                            {
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzone.Add(strLineArray[iDVYearQuarter].Substring(4), new float[2] { Convert.ToSingle(strLineArray[iO3]), -9 });
                            }
                            else
                            {
                                dicOzoneModel.Add(strLineArray[iID].ToString().Trim(), new OzoneModel());
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].id = strLineArray[iID];
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].type = strLineArray[iType];
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lat = Convert.ToDouble(strLineArray[iLat]);
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].longitude = Convert.ToDouble(strLineArray[iLong]);
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].Date = strLineArray[iDVYearQuarter].Substring(0, 4);
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzone = new Dictionary<string, float[]>();
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzone.Add(strLineArray[iDVYearQuarter].Substring(4), new float[2] { Convert.ToSingle(strLineArray[iO3]), -9 });
                            }
                        }
                        csv.Dispose(); fs.Dispose();
                        GC.Collect();
                    }
                }
                catch (Exception)
                {
                    CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(ozonechinaconfiguration.modelDataOzoneChina.baselineModelDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }

                _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);

                //------Future-----
                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read model data \"" + Path.GetFileName(ozonechinaconfiguration.modelDataOzoneChina.forecastModelDataFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                //------各字段------
                iID = -1; iType = -1; iLat = -1; iLong = -1; iO3 = -1; iDVYearQuarter = -1;
                fs = new FileStream(ozonechinaconfiguration.modelDataOzoneChina.forecastModelDataFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                try
                {
                    using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                    {
                        csv.ReadLine();
                        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 "season": iDVYearQuarter = i; break;
                                case "o3": iO3 = i; break;
                            }
                            i++;
                        }
                        while (strLine != null)
                        {
                            strLine = csv.ReadLine();
                            if (strLine == null)
                                break;
                            strLineArray = strLine.Split(new char[] { ',' });
                            if (lastYear == "") lastYear = strLineArray[iDVYearQuarter].Substring(0, 4);
                            if (dicOzoneModel.ContainsKey(strLineArray[iID].ToString().Trim()))
                            {
                                dicOzoneModel[strLineArray[iID].ToString().Trim()].lstOzone[strLineArray[iDVYearQuarter].Substring(4)][1] = Convert.ToSingle(Convert.ToDecimal(strLineArray[iO3]));
                            }
                            else
                            {
                            }
                        }
                        csv.Dispose(); fs.Dispose();
                        GC.Collect();
                    }
                    List<string> key = dicOzoneModel.First().Value.lstOzone.Keys.ToList();
                    float ozone = 0, futureozone = 0;
                    foreach (KeyValuePair<string, OzoneModel> k in dicOzoneModel)
                    {
                        ozone = 0;
                        futureozone = 0;
                        for (int i = 0; i < key.Count; i++)
                        {
                            ozone += k.Value.lstOzone[key[i]][0];
                            futureozone += k.Value.lstOzone[key[i]][1];
                        }
                        k.Value.ozone = ozone;
                        k.Value.futureOzone = futureozone;
                    }
                }
                catch (Exception)
                {
                    CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(ozonechinaconfiguration.modelDataOzoneChina.forecastModelDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }

                _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);

                #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,
                   proj, 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 修正坐标系

                #endregion Read Model Data

                //---calculate srf,rrf in Model
                foreach (KeyValuePair<string, OzoneModel> kModel in dicOzoneModel)
                {
                    kModel.Value.srf = kModel.Value.lstOzone.Values.Select(p => p[0]).ToList().Average();
                    kModel.Value.rrf = kModel.Value.lstOzone.Values.Select(p => p[1]).ToList().Average() / kModel.Value.srf;
                }

                //----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, "China");

                //------create output folder------
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + ozonechinaconfiguration.modelDataOzoneChina.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + ozonechinaconfiguration.modelDataOzoneChina.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + ozonechinaconfiguration.modelDataOzoneChina.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + ozonechinaconfiguration.modelDataOzoneChina.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //------save base,future,delta model------
                SaveOzoneQuarterlyModelData(basecenario, dicOzoneModel, lastYear);

                #region Get Point Value
                _beginTime = DateTime.Now;
                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>>();

                //--------------得到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;

                }
                //---------计算两个网格之内；然后属于哪个的网格
                foreach (KeyValuePair<string, OzoneMonitor> k in dicOzoneMonitor)
                {
                    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);
                            if (sModelIDTemp == "")
                            {
                                sModelIDTemp = query.OrderBy(p => CommonClass.getDistanceFrom2Point(p.Value.longitude, p.Value.lat, k.Value.longitude, k.Value.lat)).First().Key;
                                dicMonitorInModel.Add(k.Key, sModelIDTemp);
                            }
                        }
                    }
                    catch
                    {
                    }
                }

                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")
                    {
                        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;

                    }
                    var lstOzoneModelSurround = dicOzoneModel.Where(p => lstSurround.Contains(p.Key)).ToList();
                    int iQueryCount = lstOzoneModelSurround.Count;
                    switch ("Maximum")
                    {
                        case "Mean":
                            #region mean
                            if (lstOzoneModelSurround.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),

                                };
                                List<float> lsttempbase = new List<float>();
                                List<float> lsttempfuture = new List<float>();
                                foreach (KeyValuePair<string, OzoneModel> OzoneModelSurround in lstOzoneModelSurround)
                                {
                                    lsttempbase.Add(OzoneModelSurround.Value.lstOzone.Values.Select(p => p[0]).ToList().Average());
                                    lsttempfuture.Add(OzoneModelSurround.Value.lstOzone.Values.Select(p => p[1]).ToList().Average());
                                }
                                omTemp.rrf = lsttempfuture.Average() / lsttempbase.Average();

                                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)
                                if (false)
                                {
                                    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 (false)
                                {
                                    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);
                                    }
                                }
                            }
                            #endregion
                            break;
                        case "Maximum"://首先得到周围最大的，然后得到相应forecast的，然后计算rrf等等。应用到monitor计算出MonitorControl
                            #region maximum
                            if (lstOzoneModelSurround.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;
                                List<float> lstBase = new List<float>();
                                List<float> lstFuture = new List<float>();
                                foreach (KeyValuePair<string, OzoneModel> kin in lstOzoneModelSurround)
                                {
                                    lstBase.Add(kin.Value.lstOzone.Values.Select(p => p[0]).Average());
                                    lstFuture.Add(kin.Value.lstOzone.Values.Select(p => p[1]).Average());
                                }
                                omTemp.rrf = lstFuture.OrderByDescending(p => p).First() / lstBase.OrderByDescending(p => p).First();

                                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)
                                if (false)
                                {
                                    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 (false)
                                {
                                    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);
                                    }

                                }
                            }
                            #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 (lstOzoneModelSurround.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 lstOzoneModelSurround)
                                {
                                    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];
                                        }
                                    }


                                }
                                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)
                                if (false)
                                {
                                    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 (false)
                                {
                                    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);
                                    }
                                }
                            }
                            #endregion
                            break;
                    }
                }
                SaveDicOzoneMonitorControl(dicOzoneMonitorControl, basecenario, lastYear, "");

                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 VNA
                _beginTime = DateTime.Now;
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Begin interpolation to spatial field");
                //CommonClass.CurrentLog = "Begin interpolation to spatial field";
                //----------求OzoneControl----------
                if (ozonechinaconfiguration.monitorDataOzoneChina.useVNA || ozonechinaconfiguration.monitorDataOzoneChina.useEVNA || ozonechinaconfiguration.monitorDataOzoneChina.usewVNA || ozonechinaconfiguration.monitorDataOzoneChina.useNS)
                {
                    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> kMonitor in dicOzoneMonitorControl)
                    {
                        if (dicOzoneMonitor.ContainsKey(kMonitor.Key) && !dicOzoneMonitorLatLong.ContainsKey(dicOzoneMonitor[kMonitor.Key].longitudeLamber + "," + dicOzoneMonitor[kMonitor.Key].latitudeLamber))
                        {
                            if (dicOzoneMonitor[kMonitor.Key].ozone > 0)
                            {
                                dicOzoneMonitorLatLong.Add(dicOzoneMonitor[kMonitor.Key].longitudeLamber + "," + dicOzoneMonitor[kMonitor.Key].latitudeLamber, kMonitor.Value);
                                if (kMonitor.Value.longitude > iMaxLong) iMaxLong = kMonitor.Value.longitude;
                                if (kMonitor.Value.lat > iMaxLat) iMaxLat = kMonitor.Value.lat;
                                if (kMonitor.Value.longitude < iMinLong) iMinLong = kMonitor.Value.longitude;
                                if (kMonitor.Value.lat < iMinLat) iMinLat = kMonitor.Value.lat;

                            }
                        }
                        else
                        {
                        }
                    }
                    dLong10 = (iMaxLong - iMinLong) / 10.00;
                    dLat10 = (iMaxLat - iMinLat) / 10.00;
                    List<OzoneModelOutput> lstOzoneModelOutput = new List<OzoneModelOutput>();
                    foreach (KeyValuePair<string, OzoneModel> kModel in dicOzoneModel)
                    {
                        List<double> fsInter = new List<double>();
                        fsInter.Add(kModel.Value.longitudeLamber);
                        fsInter.Add(kModel.Value.latitudeLamber);
                        OzoneModelOutput ozoneModelOutput = new OzoneModelOutput()
                        {
                            id = kModel.Value.id,
                            lat = kModel.Value.lat,
                            longitude = kModel.Value.longitude,
                            Date = lastYear,
                            //days = kModel.Value.days,
                            //ppb = kModel.Value.ppb,
                            type = "",
                            rrf = kModel.Value.rrf,
                        };
                        //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, (kModel.Value.longitude - kin.Value.longitude) * (kModel.Value.longitude - kin.Value.longitude) + (kModel.Value.lat - kin.Value.lat) * (kModel.Value.lat - kin.Value.lat));
                            }
                        }
                        List<KeyValuePair<string, double>> query = new List<KeyValuePair<string, double>>();
                        bool isSame = false;
                        if (dicOzoneMonitorLatLong.ContainsKey(kModel.Value.longitudeLamber + "," + kModel.Value.latitudeLamber)) isSame = true;
                        if (!isSame)
                        {
                            if (Math.Abs(kModel.Value.longitude - iMinLong) < dLong10 || Math.Abs(iMaxLong - kModel.Value.longitude) < dLong10
                                || Math.Abs(kModel.Value.lat - iMinLat) < dLat10 || Math.Abs(iMaxLat - kModel.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, wvna = 0, ns = 0, vnaForcast = 0, evnaForcast = 0, wvnaForcast = 0, nsForcast = 0;
                        List<double> fsout = new List<double>();
                        if (!isSame)
                            CommonClass.VoronoiPoints(fsInter.ToArray(), ref fsout);//
                        else
                        {
                            fsout.Add(kModel.Value.longitudeLamber);
                            fsout.Add(kModel.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(kModel.Key, new NeighborFileClass()
                        {
                            id = kModel.Key,
                            monitorLat = kModel.Value.lat,
                            monitorLong = kModel.Value.longitude,
                            //quarter = 1,
                            dicNeighbors = new Dictionary<string, NeighborInfo>(),
                        });
                        //-------------------------------------------------------------
                        if (fsoutString.Count == 0) continue;
                        switch ("Inverse Distance Weights")
                        {
                            case "Equal Weighting of Monitors"://不需要求距离直接平均                              
                                break;
                            case "Inverse Distance Weights": //1/distance
                                foreach (string s in fsoutString)
                                {
                                    double d = CommonClass.getDistanceFrom2Point(kModel.Value.longitude, kModel.Value.lat, dicOzoneMonitorLatLong[s].longitude, dicOzoneMonitorLatLong[s].lat);
                                    //if (ozoneAnalysisConfiguration.filteringInterpolationO.doCheckToSetMaxDistance && d > ozoneAnalysisConfiguration.filteringInterpolationO.maxDistance) continue;
                                    distance = d == 0 ? 1 : 1.0000 / d;
                                    distanceSum += distance;
                                    vnaSum += dicOzoneMonitorLatLong[s].ozonebase * distance;
                                    dicNeighborFile[kModel.Key].dicNeighbors.Add(dicOzoneMonitorLatLong[s].id, new NeighborInfo()
                                    {
                                        neighbor = dicOzoneMonitorLatLong[s].id,
                                        neighbor_gridcell = dicMonitorInModel[dicOzoneMonitorLatLong[s].id],
                                        distance = d,
                                    });
                                    try
                                    {
                                        if (kModel.Value.srf > 0 && dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf > 0)
                                        {
                                            evnaSum += dicOzoneMonitorLatLong[s].ozonebase * distance * kModel.Value.srf / dicOzoneModel[dicMonitorInModel[dicOzoneMonitorLatLong[s].id]].srf;
                                            distanceSumEvna += distance;
                                        }
                                    }
                                    catch
                                    {
                                    }
                                }
                                try
                                {
                                    if (vnaSum < 0 || Double.IsNaN(vnaSum) || distanceSum == 0)
                                        vna = -13;
                                    else
                                        vna = Math.Round(vnaSum / distanceSum, 1);
                                    if (evnaSum < 0 || Double.IsNaN(evnaSum) || distanceSumEvna == 0)
                                        evna = -8;
                                    else
                                        evna = Math.Round(evnaSum / distanceSumEvna, 1);
                                    if (kModel.Value.rrf < 0)
                                        vnaForcast = -9;
                                    else
                                        vnaForcast = CommonClass.ToFixed(vna * kModel.Value.rrf, 1);

                                    if (evna < 0 || kModel.Value.rrf < 0 || Double.IsNaN(evna))
                                        evnaForcast = -9;
                                    else
                                        evnaForcast = CommonClass.ToFixed(evna * kModel.Value.rrf, 1);
                                }
                                catch
                                {
                                }
                                break;
                            case "Inverse Distance Squared Weights"://1/Math.Pow(distance,2)

                                break;
                        }

                        ozoneModelOutput.vna = Convert.ToSingle(vna);
                        ozoneModelOutput.evna = Convert.ToSingle(evna);
                        ozoneModelOutput.ga_conc = Convert.ToSingle(kModel.Value.srf);
                        ozoneModelOutput.vnaForcast = Convert.ToSingle(vnaForcast);
                        ozoneModelOutput.evnaForcast = Convert.ToSingle(evnaForcast);
                        ozoneModelOutput.referencecell = kModel.Value.id;

                        //计算wVNA
                        // wVNA = w * eVNA + ( 1- w) * VNA
                        if (ozonechinaconfiguration.monitorDataOzoneChina.usewVNA)
                        {
                            var w = ozonechinaconfiguration.monitorDataOzoneChina.usewVNAWeight;
                            if (evna > 0d && vna > 0d)
                            {
                                wvna = w * evna + (1d - w) * vna;
                            }
                            else
                            {
                                // 给了 -13.0
                                wvna = -13.0;
                            }
                            if (evnaForcast > 0d && vnaForcast > 0d)
                            {
                                wvnaForcast = w * evnaForcast + (1d - w) * vnaForcast;
                            }
                            else
                            {
                                // 给了 -13.0
                                wvnaForcast = -13.0;
                            }
                        }
                        ozoneModelOutput.wvna = Convert.ToSingle(wvna);
                        ozoneModelOutput.wvnaForcast = Convert.ToSingle(wvnaForcast);

                        // 计算 NearestSite
                        // 找到最近的点
                        if (ozonechinaconfiguration.monitorDataOzoneChina.useNS)
                        {
                            var minItem = dicDistanceMonitor.OrderBy(t => t.Value).FirstOrDefault();
                            if (!minItem.Equals(default(KeyValuePair<string, double>)))
                            {
                                var minMonitor = dicOzoneMonitorLatLong.Values.FirstOrDefault(t => t.id == minItem.Key);
                                if (minMonitor != null)
                                {
                                    ns = minMonitor.ozonebase;
                                }
                                else
                                {
                                    // 给了 -13.0
                                    ns = -13.0;
                                }
                            }
                            else
                            {
                                // 给了 -13.0
                                ns = -13.0;
                            }
                            if (ns < 0 || kModel.Value.rrf < 0 || Double.IsNaN(ns))
                            {
                                nsForcast = -13.0;
                            }
                            else
                            {
                                nsForcast = CommonClass.ToFixed(ns * kModel.Value.rrf, 1);
                            }
                        }
                        ozoneModelOutput.ns = Convert.ToSingle(ns);
                        ozoneModelOutput.nsForcast = Convert.ToSingle(nsForcast);

                        lstOzoneModelOutput.Add(ozoneModelOutput);
                    }
                    SaveLstOzoneModelOutput(lstOzoneModelOutput, basecenario, lastYear);

                    #region BenMAP-ready
                    /*
                    bool useVNA = ozonechinaconfiguration.monitorDataOzoneChina.useEVNA;
                    bool useEVNA = ozonechinaconfiguration.monitorDataOzoneChina.useEVNA;

                    if (vnab || vnaf || evnab || evnaf || dsb || dsf)
                    {
                        Dictionary<double[], int[]> dic = new Dictionary<double[], int[]>();
                        IFeatureSet ifs = FeatureSet.Open(Application.StartupPath + @"\Data\ShapeFiles\CMAQ_12km_Nation.shp");
                        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] });
                            }
                        }



                        if (vnab || vnaf)
                        {
                            SaveOzoneSpatialFieldForBenMAP(baseScenario, lstOzoneModelOutput, dicColRow, vnab, vnaf);
                        }
                        if (evnab || evnaf)
                        {
                            SaveOzoneSpatialFieldGradAdjForBenMAP(baseScenario, lstOzoneModelOutput, dicColRow, evnab, evnaf);
                        }
                        if (dsb || dsf)
                        {
                            SaveOzoneSpatialFieldDSForBenMAP(baseScenario, lstOzoneModelOutput, dicColRow, lstDSresult, dsb, dsf);
                        }
                    }
                    */

                    string spatialFieldFile = CommonClass.ResultFilePath + string.Format(@"\Result\Output\{0}\{0} - Spatial Field -- interpolated monitor data, temporally adjusted; gradient-adjusted monitor data, {1}.csv", Path.GetFileNameWithoutExtension(CommonClass.ProjectName), lastYear);
                    if (File.Exists(spatialFieldFile))
                    {
                        OutputOzoneDataForBenMAP(spatialFieldFile, ozonechinaconfiguration.monitorDataOzoneChina);
                    }
               

                    #endregion





                    lstOzoneModelOutput.Clear();
                    GC.Collect();
                    //if (ozoneAnalysisConfiguration.chooseDesiredOutputO.doNeighborFileSpatial)
                    //{
                    //    SaveOzoneNeighborFileSpatialField(CommonClass.CurrentBaseScenario, dicNeighborFile);
                    //}
                    dicNeighborFile.Clear();
                    GC.Collect();
                    _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.";
                }
                #endregion
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// output data for BenMAP
        /// benmapBase.csv
        /// benmapControl.csv
        /// add by sclong
        /// 201605-15
        /// </summary>
        /// <param name="filePath"></param>
        private static void OutputOzoneDataForBenMAP(string filePath, MonitorDataOzoneChina monitorDataOzoneChina)
        {
            try
            {
                string strFirstLine = "";
                //bool errorOccur = false;
                int iMaxCount = 0;
                bool erroroccur = false;
                //DataTable dt = CommonClass.getDataSetFromCSVAndFirstLine(filePath, ref strFirstLine,iMaxCount);
                DataTable dt = CommonClass.getDataSetFromCSVAndFirstLine(filePath, ref strFirstLine, ref erroroccur);
                //                 CommonClass.getDataSetFromCSVAndFirstLine(filePath, ref strFirstLine, ref errorOccur, 0, 0, ref iMaxCount);
                if (dt == null || dt.Rows.Count <= 0)
                {
                    return;

                }
                
                string columns = "Column,Row,Metric,Seasonal Metric,Statistic,Values";

                Dictionary<string, List<string>> dicOutput = new Dictionary<string, List<string>>();
                if (monitorDataOzoneChina.useVNA)
                {
                    dicOutput.Add("Base (VNA)", new List<string>() { columns });
                    dicOutput.Add("Future (VNA)", new List<string>() { columns });
                }
                if (monitorDataOzoneChina.useEVNA)
                {
                    dicOutput.Add("Base (eVNA)", new List<string>() { columns });
                    dicOutput.Add("Future (eVNA)", new List<string>() { columns });
                }
                //if (monitorDataOzoneChina.usewVNA)
                //{
                //    dicOutput.Add("Base (wVNA)", new List<string>() { columns });
                //    dicOutput.Add("Future (wVNA)", new List<string>() { columns });
                //}
                //if (monitorDataOzoneChina.useNS)
                //{
                //    dicOutput.Add("Base (Nearest Site)", new List<string>() { columns });
                //    dicOutput.Add("Future (Nearest Site)", new List<string>() { columns });
                //}

                int iLat = 0, iLong = 0, iO3b = 0, iO3f = 0, i_b_ga_o3 = 0, i_f_ga_o3 = 0, iQuarter = 0, iID = 0;//i_b_ns_o3 = 0, i_f_ns_o3=0, i_b_o3_wvna = 0, i_f_o3_wvna = 0,
                foreach (DataColumn dc in dt.Columns)
                {
                    switch (dc.ColumnName.ToLower().Trim())
                    {
                        case "lat":
                            iLat = dt.Columns.IndexOf(dc);
                            break;
                        case "long":
                            iLong = dt.Columns.IndexOf(dc);
                            break;
                        case "i_b_o3"://vna base
                            iO3b = dt.Columns.IndexOf(dc);
                            break;
                        case "i_f_o3"://vna future
                            iO3f = dt.Columns.IndexOf(dc);
                            break;
                        case "i_b_ga_o3"://evna base
                            i_b_ga_o3 = dt.Columns.IndexOf(dc);
                            break;
                        case "i_f_ga_o3"://evna future
                            i_f_ga_o3 = dt.Columns.IndexOf(dc);
                            break;
                        //case "i_b_o3_wvna"://wvna base
                        //    i_b_o3_wvna = dt.Columns.IndexOf(dc);
                        //    break;
                        //case "i_f_o3_wvna"://wvna future
                        //    i_f_o3_wvna = dt.Columns.IndexOf(dc);
                        //    break;
                        //case "i_b_ns_o3"://ns base
                        //    i_b_ns_o3 = dt.Columns.IndexOf(dc);
                        //    break;
                        //case "i_f_ns_o3"://ns future
                        //    i_f_ns_o3 = dt.Columns.IndexOf(dc);
                        //    break;
                        case "quarter":
                            iQuarter = dt.Columns.IndexOf(dc);
                            break;
                        case "_id":
                            iID = dt.Columns.IndexOf(dc);
                            break;
                    }
                }

                foreach (DataRow dr in dt.Rows)
                {
                    int id = Convert.ToInt32(dr[iID]);
                    int col = Convert.ToInt32(id / 1000);
                    int row = Convert.ToInt32(id % 1000);
                    if (monitorDataOzoneChina.useVNA)
                    {
                        dicOutput["Base (VNA)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[iO3b])));
                        dicOutput["Future (VNA)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[iO3f])));
                    }
                    if (monitorDataOzoneChina.useEVNA)
                    {
                        dicOutput["Base (eVNA)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[i_b_ga_o3])));
                        dicOutput["Future (eVNA)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[i_f_ga_o3])));
                    }
                    //if (monitorDataOzoneChina.usewVNA)
                    //{
                    //    dicOutput["Base (wVNA)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[i_b_o3_wvna])));
                    //    dicOutput["Future (wVNA)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[i_f_o3_wvna])));
                    //}
                    //if (monitorDataOzoneChina.useNS)
                    //{
                    //    dicOutput["Base (Nearest Site)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[i_b_ns_o3])));
                    //    dicOutput["Future (Nearest Site)"].Add(string.Format("{0},{1},{2},{3},{4}", col + "," + row, "D8HourMax", "", "Mean", Convert.ToDouble(dr[i_f_ns_o3])));
                    //}
                }
                string strPathB = "";
                foreach (var item in dicOutput)
                {
                    strPathB = Path.GetDirectoryName(filePath) + @"\BenMAP-ready O3 Spatial Field " + item.Key + ".csv";
                    System.IO.StreamWriter swB = new System.IO.StreamWriter(strPathB, false);
                    foreach (string s in item.Value)
                    {
                        swB.WriteLine(s);
                    }
                    swB.Flush();
                }
                dicOutput.Clear();
                GC.Collect();
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
            }
            finally
            {
                GC.Collect();
            }
        }


        public static bool SaveOzoneQuarterlyModelData(BaseScenario baseScenario, Dictionary<string, OzoneModel> dicOzoneModel, string lastYear)
        {
            if (!(baseScenario.configuration is OzoneAnalysisChinaConfiguration))
            {
                return false;
            }
            try
            {
                OzoneAnalysisChinaConfiguration ozonechinaconfiguration = baseScenario.configuration as OzoneAnalysisChinaConfiguration;

                DataTable dt = new DataTable();
                dt.Columns.Add("_id");
                dt.Columns.Add("_type");
                dt.Columns.Add("lat");
                dt.Columns.Add("long");
                dt.Columns.Add("b_o3");
                dt.Columns.Add("f_o3");
                dt.Columns.Add("Delta(o3)");

                foreach (KeyValuePair<string, OzoneModel> k in dicOzoneModel)
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = k.Key;
                    dr[1] = k.Value.type;
                    dr[2] = k.Value.lat;
                    dr[3] = k.Value.longitude;
                    dr[4] = k.Value.ozone * 2.000;
                    dr[5] = k.Value.futureOzone * 2.000;
                    if (k.Value.ozone > 0 && k.Value.futureOzone > 0)
                        dr[6] = Math.Round((k.Value.ozone - k.Value.futureOzone) * 2.000, 8);
                    else
                        dr[6] = -9;

                    dt.Rows.Add(dr);
                }

                //------------修正OutPutFileName----------------
                string strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Base & Future Model Data .csv";

                CommonClass.SaveCSV(dt, _resultFilePath + @"\" + strFile, "Year");
                BaseOutput baseOutput = new BaseOutput();
                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);
                dt.Clear();
                GC.Collect();//end
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }

        }
        public static bool SaveDicOzoneMonitorControl(Dictionary<string, OzoneMonitorControl> dicOzoneMonitorControl, BaseScenario baseScenario, string forcastYear, string period)
        {
            //------------------OutputMonitorControl && OutputMonitorCountyHight----------
            //_id	_type	lat	long	date	b_o3_DV	f_o3_DV	referencecell	rrf	ppb	days	_state_name	_county_name
            if (!(baseScenario.configuration is OzoneAnalysisChinaConfiguration))
            {
                return false;
            }
            try
            {
                OzoneAnalysisChinaConfiguration ozonechinaconfiguration = (baseScenario.configuration) as OzoneAnalysisChinaConfiguration;
                DataTable dtOutMonitorControl = new DataTable();
                dtOutMonitorControl.Columns.Add("_id");
                dtOutMonitorControl.Columns.Add("_type");
                dtOutMonitorControl.Columns.Add("lat");
                dtOutMonitorControl.Columns.Add("long");
                dtOutMonitorControl.Columns.Add("date");
                dtOutMonitorControl.Columns.Add("b_o3_DV");
                dtOutMonitorControl.Columns.Add("f_o3_DV");
                dtOutMonitorControl.Columns.Add("referencecell");
                dtOutMonitorControl.Columns.Add("rrf");
                //dtOutMonitorControl.Columns.Add("ppb");
                //dtOutMonitorControl.Columns.Add("days");
                dtOutMonitorControl.Columns.Add("location_name");
                dtOutMonitorControl.Columns.Add("station_name");
                string date = period == "" ? ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.Substring(ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.Length - 4) : Convert.ToString(Convert.ToInt16(ozonechinaconfiguration.monitorDataOzoneChina.ozoneStartYear.Substring(ozonechinaconfiguration.monitorDataOzoneChina.ozoneStartYear.Length - 4)) + Convert.ToInt16(period.Split(' ')[1]) - 1);
                foreach (KeyValuePair<string, OzoneMonitorControl> k in dicOzoneMonitorControl)
                {
                    DataRow dr = dtOutMonitorControl.NewRow();
                    dr[0] = k.Value.id;
                    dr[1] = "";//---------少了type
                    dr[2] = k.Value.lat;
                    dr[3] = k.Value.longitude;
                    dr[4] = date;//ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Substring(ozoneAnalysisConfiguration.filteringInterpolationO.ozoneEndYear.Length - 4);//------------得重新计算date
                    dr[5] = k.Value.ozonebase;
                    dr[6] = k.Value.ozonecontrol;
                    dr[7] = k.Value.referencecell;
                    dr[8] = k.Value.rrf;
                    //dr[9] = k.Value.ppb;
                    //dr[10] = k.Value.days;
                    dr[9] = k.Value.county;
                    dr[10] = k.Value.state;
                    dtOutMonitorControl.Rows.Add(dr);
                }

                //------------修正OutPutFileName----------------
                string strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Ozone Monitors -- temporally adjusted " + forcastYear + " " + period + ".csv";

                CommonClass.SaveCSV(dtOutMonitorControl, _resultFilePath + @"\" + strFile, "Year");
                BaseOutput baseOutput = new BaseOutput();
                baseOutput.outputName = strFile.Replace(".csv", "");
                //baseOutput.outputName = ozoneAnalysisConfiguration.chooseDesiredOutputO.scenarioName + " - Ozone Monitors -- monitor data, temporally adjusted " + forcastYear + " " + period;
                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.Insert(0, baseOutput);
                dtOutMonitorControl.Clear();
                GC.Collect();
                return true;
            }
            catch
            {
                return false;
            }
        }
        public static bool SaveLstOzoneModelOutput(List<OzoneModelOutput> lstOzoneModelOutput, BaseScenario baseScenario, string forcastYear)
        {
            try
            {
                if (!(baseScenario.configuration is OzoneAnalysisChinaConfiguration))
                {
                    return false;
                }
                OzoneAnalysisChinaConfiguration ozonechinaconfiguration = (baseScenario.configuration) as OzoneAnalysisChinaConfiguration;
                BaseOutput baseOutput = null;
                string strFile = "";
                string dataType = "";
                DataTable dtOutMonitorControl = new DataTable();
                #region
                if (ozonechinaconfiguration.monitorDataOzoneChina.useVNA && ozonechinaconfiguration.monitorDataOzoneChina.useEVNA)
                {
                    if (ozonechinaconfiguration.monitorDataOzoneChina.usewVNA)
                    {
                        if (ozonechinaconfiguration.monitorDataOzoneChina.useNS)
                        {
                            #region vna+evna+wvna+ns
                            dtOutMonitorControl.Columns.Add("_id");
                            dtOutMonitorControl.Columns.Add("_type");
                            dtOutMonitorControl.Columns.Add("lat");
                            dtOutMonitorControl.Columns.Add("long");
                            dtOutMonitorControl.Columns.Add("date");
                            dtOutMonitorControl.Columns.Add("ga_conc");
                            dtOutMonitorControl.Columns.Add("i_b_o3");
                            dtOutMonitorControl.Columns.Add("i_f_o3");
                            dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                            dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                            dtOutMonitorControl.Columns.Add("i_b_o3_wvna");
                            dtOutMonitorControl.Columns.Add("i_f_o3_wvna");
                            dtOutMonitorControl.Columns.Add("i_b_ns_o3");
                            dtOutMonitorControl.Columns.Add("i_f_ns_o3");
                            //dtOutMonitorControl.Columns.Add("ppb");
                            //dtOutMonitorControl.Columns.Add("days");
                            dtOutMonitorControl.Columns.Add("referencecell");
                            dtOutMonitorControl.Columns.Add("rrf");
                            foreach (OzoneModelOutput om in lstOzoneModelOutput)
                            {

                                DataRow dr = dtOutMonitorControl.NewRow();
                                dr[0] = om.id;
                                dr[1] = "";//---------少了type
                                dr[2] = om.lat;
                                dr[3] = om.longitude;
                                dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                                dr[5] = Math.Round(om.ga_conc * 2.000, 8);
                                dr[6] = Math.Round(om.vna, 8);
                                dr[7] = Math.Round(om.vnaForcast, 8);
                                dr[8] = Math.Round(om.evna, 8);
                                dr[9] = Math.Round(om.evnaForcast, 8);
                                dr[10] = Math.Round(om.wvna, 8);
                                dr[11] = Math.Round(om.wvnaForcast, 8);
                                dr[12] = Math.Round(om.ns, 8);
                                dr[13] = Math.Round(om.nsForcast, 8);
                                //dr[10] = om.ppb;
                                //dr[11] = om.days;
                                dr[14] = om.referencecell;
                                dr[15] = Math.Round(om.rrf, 8);
                                dtOutMonitorControl.Rows.Add(dr);
                            }
                            //------------修正OutPutFileName----------------
                            dataType = "Year";
                            strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, temporally adjusted; gradient-adjusted monitor data(VNA+eVNA+wVNA+NS), " + forcastYear + ".csv";
                            #endregion
                        }
                        else
                        {
                            #region wvna
                            dtOutMonitorControl.Columns.Add("_id");
                            dtOutMonitorControl.Columns.Add("_type");
                            dtOutMonitorControl.Columns.Add("lat");
                            dtOutMonitorControl.Columns.Add("long");
                            dtOutMonitorControl.Columns.Add("date");
                            dtOutMonitorControl.Columns.Add("ga_conc");
                            dtOutMonitorControl.Columns.Add("i_b_o3");
                            dtOutMonitorControl.Columns.Add("i_f_o3");
                            dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                            dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                            dtOutMonitorControl.Columns.Add("i_b_o3_wvna");
                            dtOutMonitorControl.Columns.Add("i_f_o3_wvna");
                            //dtOutMonitorControl.Columns.Add("ppb");
                            //dtOutMonitorControl.Columns.Add("days");
                            dtOutMonitorControl.Columns.Add("referencecell");
                            dtOutMonitorControl.Columns.Add("rrf");
                            foreach (OzoneModelOutput om in lstOzoneModelOutput)
                            {

                                DataRow dr = dtOutMonitorControl.NewRow();
                                dr[0] = om.id;
                                dr[1] = "";//---------少了type
                                dr[2] = om.lat;
                                dr[3] = om.longitude;
                                dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                                dr[5] = Math.Round(om.ga_conc * 2.000, 8);
                                dr[6] = Math.Round(om.vna, 8);
                                dr[7] = Math.Round(om.vnaForcast, 8);
                                dr[8] = Math.Round(om.evna, 8);
                                dr[9] = Math.Round(om.evnaForcast, 8);
                                dr[10] = Math.Round(om.wvna, 8);
                                dr[11] = Math.Round(om.wvnaForcast, 8);
                                //dr[8] = Math.Round(om.evna, 8);
                                //dr[9] = Math.Round(om.evnaForcast, 8);
                                //dr[10] = om.ppb;
                                //dr[11] = om.days;
                                dr[12] = om.referencecell;
                                dr[13] = Math.Round(om.rrf, 8);
                                dtOutMonitorControl.Rows.Add(dr);
                            }
                            //------------修正OutPutFileName----------------
                            dataType = "Year";
                            strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, temporally adjusted; gradient-adjusted monitor data(wVNA), " + forcastYear + ".csv";
                            #endregion
                        }
                    }
                    else
                    {
                        if (ozonechinaconfiguration.monitorDataOzoneChina.useNS)
                        {
                            #region vna+evna+ns
                            dtOutMonitorControl.Columns.Add("_id");
                            dtOutMonitorControl.Columns.Add("_type");
                            dtOutMonitorControl.Columns.Add("lat");
                            dtOutMonitorControl.Columns.Add("long");
                            dtOutMonitorControl.Columns.Add("date");
                            dtOutMonitorControl.Columns.Add("ga_conc");
                            dtOutMonitorControl.Columns.Add("i_b_o3");
                            dtOutMonitorControl.Columns.Add("i_f_o3");
                            dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                            dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                            dtOutMonitorControl.Columns.Add("i_b_ns_o3");
                            dtOutMonitorControl.Columns.Add("i_f_ns_o3");
                            //dtOutMonitorControl.Columns.Add("ppb");
                            //dtOutMonitorControl.Columns.Add("days");
                            dtOutMonitorControl.Columns.Add("referencecell");
                            dtOutMonitorControl.Columns.Add("rrf");
                            foreach (OzoneModelOutput om in lstOzoneModelOutput)
                            {

                                DataRow dr = dtOutMonitorControl.NewRow();
                                dr[0] = om.id;
                                dr[1] = "";//---------少了type
                                dr[2] = om.lat;
                                dr[3] = om.longitude;
                                dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                                dr[5] = Math.Round(om.ga_conc * 2.000, 8);
                                dr[6] = Math.Round(om.vna, 8);
                                dr[7] = Math.Round(om.vnaForcast, 8);
                                dr[8] = Math.Round(om.evna, 8);
                                dr[9] = Math.Round(om.evnaForcast, 8);
                                dr[10] = Math.Round(om.ns, 8);
                                dr[11] = Math.Round(om.nsForcast, 8);
                                //dr[10] = om.ppb;
                                //dr[11] = om.days;
                                dr[12] = om.referencecell;
                                dr[13] = Math.Round(om.rrf, 8);
                                dtOutMonitorControl.Rows.Add(dr);
                            }
                            //------------修正OutPutFileName----------------
                            dataType = "Year";
                            strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, temporally adjusted; gradient-adjusted monitor data(VNA+eVNA+NS), " + forcastYear + ".csv";
                            #endregion
                        }
                        else
                        {
                            #region vna+evna
                            dtOutMonitorControl.Columns.Add("_id");
                            dtOutMonitorControl.Columns.Add("_type");
                            dtOutMonitorControl.Columns.Add("lat");
                            dtOutMonitorControl.Columns.Add("long");
                            dtOutMonitorControl.Columns.Add("date");
                            dtOutMonitorControl.Columns.Add("ga_conc");
                            dtOutMonitorControl.Columns.Add("i_b_o3");
                            dtOutMonitorControl.Columns.Add("i_f_o3");
                            dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                            dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                            //dtOutMonitorControl.Columns.Add("ppb");
                            //dtOutMonitorControl.Columns.Add("days");
                            dtOutMonitorControl.Columns.Add("referencecell");
                            dtOutMonitorControl.Columns.Add("rrf");
                            foreach (OzoneModelOutput om in lstOzoneModelOutput)
                            {
                                DataRow dr = dtOutMonitorControl.NewRow();
                                dr[0] = om.id;
                                dr[1] = "";//---------少了type
                                dr[2] = om.lat;
                                dr[3] = om.longitude;
                                dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                                dr[5] = Math.Round(om.ga_conc * 2.000, 8);
                                dr[6] = Math.Round(om.vna, 8);
                                dr[7] = Math.Round(om.vnaForcast, 8);
                                dr[8] = Math.Round(om.evna, 8);
                                dr[9] = Math.Round(om.evnaForcast, 8);
                                //dr[10] = om.ppb;
                                //dr[11] = om.days;
                                dr[10] = om.referencecell;
                                dr[11] = Math.Round(om.rrf, 8);
                                dtOutMonitorControl.Rows.Add(dr);
                            }
                            //------------修正OutPutFileName----------------
                            dataType = "Year";
                            strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, temporally adjusted; gradient-adjusted monitor data, " + forcastYear + ".csv";
                            #endregion
                        }
                    }
                }
                else if (ozonechinaconfiguration.monitorDataOzoneChina.useVNA)
                //else if (ozonechinaconfiguration.monitorDataOzoneChina.useVNA && (!ozonechinaconfiguration.monitorDataOzoneChina.useEVNA))
                {
                    if (ozonechinaconfiguration.monitorDataOzoneChina.useNS)
                    {
                        #region vna+ns
                        dtOutMonitorControl.Columns.Add("_id");
                        dtOutMonitorControl.Columns.Add("_type");

                        dtOutMonitorControl.Columns.Add("lat");
                        dtOutMonitorControl.Columns.Add("long");
                        dtOutMonitorControl.Columns.Add("date");
                        //dtOutMonitorControl.Columns.Add("ga_conc");
                        dtOutMonitorControl.Columns.Add("i_b_o3");
                        dtOutMonitorControl.Columns.Add("i_f_o3");
                        dtOutMonitorControl.Columns.Add("i_b_ns_o3");
                        dtOutMonitorControl.Columns.Add("i_f_ns_o3");
                        //dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                        //dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                        //dtOutMonitorControl.Columns.Add("ppb");
                        //dtOutMonitorControl.Columns.Add("days");
                        dtOutMonitorControl.Columns.Add("referencecell");
                        dtOutMonitorControl.Columns.Add("rrf");
                        foreach (OzoneModelOutput om in lstOzoneModelOutput)
                        {

                            DataRow dr = dtOutMonitorControl.NewRow();
                            dr[0] = om.id;
                            dr[1] = "";//---------少了type
                            dr[2] = om.lat;
                            dr[3] = om.longitude;
                            dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                            dr[5] = Math.Round(om.vna, 8);
                            dr[6] = Math.Round(om.vnaForcast, 8);
                            dr[7] = Math.Round(om.ns, 8);
                            dr[8] = Math.Round(om.nsForcast, 8);
                            //dr[8] = Math.Round(om.evna, 8);
                            //dr[9] = Math.Round(om.evnaForcast, 8);
                            //dr[10] = om.ppb;
                            //dr[11] = om.days;
                            dr[9] = om.referencecell;
                            dr[10] = Math.Round(om.rrf, 8);
                            dtOutMonitorControl.Rows.Add(dr);
                        }
                        //------------修正OutPutFileName----------------
                        dataType = "Year";
                        strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, temporally adjusted monitor data(VNA+NS), " + forcastYear + ".csv";
                        #endregion
                    }
                    else
                    {
                        #region vna
                        dtOutMonitorControl.Columns.Add("_id");
                        dtOutMonitorControl.Columns.Add("_type");

                        dtOutMonitorControl.Columns.Add("lat");
                        dtOutMonitorControl.Columns.Add("long");
                        dtOutMonitorControl.Columns.Add("date");
                        //dtOutMonitorControl.Columns.Add("ga_conc");
                        dtOutMonitorControl.Columns.Add("i_b_o3");
                        dtOutMonitorControl.Columns.Add("i_f_o3");
                        //dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                        //dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                        //dtOutMonitorControl.Columns.Add("ppb");
                        //dtOutMonitorControl.Columns.Add("days");
                        dtOutMonitorControl.Columns.Add("referencecell");
                        dtOutMonitorControl.Columns.Add("rrf");
                        foreach (OzoneModelOutput om in lstOzoneModelOutput)
                        {

                            DataRow dr = dtOutMonitorControl.NewRow();
                            dr[0] = om.id;
                            dr[1] = "";//---------少了type
                            dr[2] = om.lat;
                            dr[3] = om.longitude;
                            dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                            //dr[5] = Math.Round(om.ga_conc, 8);
                            dr[5] = Math.Round(om.vna, 8);
                            dr[6] = Math.Round(om.vnaForcast, 8);
                            //dr[8] = Math.Round(om.evna, 8);
                            //dr[9] = Math.Round(om.evnaForcast, 8);
                            //dr[10] = om.ppb;
                            //dr[11] = om.days;
                            dr[7] = om.referencecell;
                            dr[8] = Math.Round(om.rrf, 8);
                            dtOutMonitorControl.Rows.Add(dr);
                        }
                        //------------修正OutPutFileName----------------
                        dataType = "Year";
                        strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, temporally adjusted monitor data, " + forcastYear + ".csv";
                        #endregion
                    }
                }
                else if (ozonechinaconfiguration.monitorDataOzoneChina.useEVNA)
                //else if (!(ozonechinaconfiguration.monitorDataOzoneChina.useVNA && ozonechinaconfiguration.monitorDataOzoneChina.useEVNA))
                {
                    if (ozonechinaconfiguration.monitorDataOzoneChina.useNS)
                    {
                        #region evna+ns
                        dtOutMonitorControl.Columns.Add("_id");
                        dtOutMonitorControl.Columns.Add("_type");

                        dtOutMonitorControl.Columns.Add("lat");
                        dtOutMonitorControl.Columns.Add("long");
                        dtOutMonitorControl.Columns.Add("date");
                        dtOutMonitorControl.Columns.Add("ga_conc");
                        dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                        dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                        dtOutMonitorControl.Columns.Add("i_b_ns_o3");
                        dtOutMonitorControl.Columns.Add("i_f_ns_o3");
                        //dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                        //dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                        //dtOutMonitorControl.Columns.Add("ppb");
                        //dtOutMonitorControl.Columns.Add("days");
                        dtOutMonitorControl.Columns.Add("referencecell");
                        dtOutMonitorControl.Columns.Add("rrf");
                        foreach (OzoneModelOutput om in lstOzoneModelOutput)
                        {

                            DataRow dr = dtOutMonitorControl.NewRow();
                            dr[0] = om.id;
                            dr[1] = "";//---------少了type
                            dr[2] = om.lat;
                            dr[3] = om.longitude;
                            dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                            dr[5] = Math.Round(om.ga_conc * 2.000, 8);
                            dr[6] = Math.Round(om.evna, 8);
                            dr[7] = Math.Round(om.evnaForcast, 8);
                            dr[8] = Math.Round(om.ns, 8);
                            dr[9] = Math.Round(om.nsForcast, 8);
                            //dr[10] = om.ppb;
                            //dr[11] = om.days;
                            dr[10] = om.referencecell;
                            dr[11] = Math.Round(om.rrf, 8);
                            dtOutMonitorControl.Rows.Add(dr);
                        }
                        //------------修正OutPutFileName----------------
                        dataType = "Year";
                        strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, temporally adjusted monitor data(eVNA+NS), " + forcastYear + ".csv";
                        #endregion
                    }
                    else
                    {
                        #region evna
                        dtOutMonitorControl.Columns.Add("_id");
                        dtOutMonitorControl.Columns.Add("_type");
                        dtOutMonitorControl.Columns.Add("lat");
                        dtOutMonitorControl.Columns.Add("long");
                        dtOutMonitorControl.Columns.Add("date");
                        dtOutMonitorControl.Columns.Add("ga_conc");
                        //dtOutMonitorControl.Columns.Add("i_b_o3");
                        //dtOutMonitorControl.Columns.Add("i_f_o3");
                        dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                        dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                        //dtOutMonitorControl.Columns.Add("ppb");
                        //dtOutMonitorControl.Columns.Add("days");
                        dtOutMonitorControl.Columns.Add("referencecell");
                        dtOutMonitorControl.Columns.Add("rrf");
                        foreach (OzoneModelOutput om in lstOzoneModelOutput)
                        {

                            DataRow dr = dtOutMonitorControl.NewRow();
                            dr[0] = om.id;
                            dr[1] = "";//---------少了type
                            dr[2] = om.lat;
                            dr[3] = om.longitude;
                            dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                            dr[5] = Math.Round(om.ga_conc * 2.000, 8);
                            //dr[5] = Math.Round(om.vna, 8);
                            //dr[6] = Math.Round(om.vnaForcast, 8);
                            dr[6] = Math.Round(om.evna, 8);
                            dr[7] = Math.Round(om.evnaForcast, 8);
                            //dr[10] = om.ppb;
                            //dr[11] = om.days;
                            dr[8] = om.referencecell;
                            dr[9] = Math.Round(om.rrf, 8);
                            dtOutMonitorControl.Rows.Add(dr);
                        }
                        //------------修正OutPutFileName----------------
                        dataType = "Year";
                        strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Spatial Field -- interpolated monitor data, gradient-adjusted adjusted monitor data, " + forcastYear + ".csv";
                        #endregion
                    }
                }
                if ((!(ozonechinaconfiguration.monitorDataOzoneChina.useVNA) && ozonechinaconfiguration.monitorDataOzoneChina.useNS) && (!(ozonechinaconfiguration.monitorDataOzoneChina.useEVNA) && ozonechinaconfiguration.monitorDataOzoneChina.useNS) && (!(ozonechinaconfiguration.monitorDataOzoneChina.usewVNA) && ozonechinaconfiguration.monitorDataOzoneChina.useNS) && (!(ozonechinaconfiguration.monitorDataOzoneChina.useVNA && ozonechinaconfiguration.monitorDataOzoneChina.useEVNA) && ozonechinaconfiguration.monitorDataOzoneChina.useNS) && !(ozonechinaconfiguration.monitorDataOzoneChina.useVNA && ozonechinaconfiguration.monitorDataOzoneChina.useEVNA && ozonechinaconfiguration.monitorDataOzoneChina.usewVNA) && ozonechinaconfiguration.monitorDataOzoneChina.useNS)
                {
                    #region ns
                    dtOutMonitorControl.Columns.Add("_id");
                    dtOutMonitorControl.Columns.Add("_type");

                    dtOutMonitorControl.Columns.Add("lat");
                    dtOutMonitorControl.Columns.Add("long");
                    dtOutMonitorControl.Columns.Add("date");
                    //dtOutMonitorControl.Columns.Add("ga_conc");
                    dtOutMonitorControl.Columns.Add("i_b_ns_o3");
                    dtOutMonitorControl.Columns.Add("i_f_ns_o3");
                    //dtOutMonitorControl.Columns.Add("i_b_ga_o3");
                    //dtOutMonitorControl.Columns.Add("i_f_ga_o3");
                    //dtOutMonitorControl.Columns.Add("ppb");
                    //dtOutMonitorControl.Columns.Add("days");
                    dtOutMonitorControl.Columns.Add("referencecell");
                    dtOutMonitorControl.Columns.Add("rrf");
                    foreach (OzoneModelOutput om in lstOzoneModelOutput)
                    {

                        DataRow dr = dtOutMonitorControl.NewRow();
                        dr[0] = om.id;
                        dr[1] = "";//---------少了type
                        dr[2] = om.lat;
                        dr[3] = om.longitude;
                        dr[4] = ozonechinaconfiguration.monitorDataOzoneChina.ozoneEndYear.ToString();
                        //dr[5] = Math.Round(om.ga_conc, 8);
                        dr[5] = Math.Round(om.ns, 8);
                        dr[6] = Math.Round(om.nsForcast, 8);
                        //dr[8] = Math.Round(om.evna, 8);
                        //dr[9] = Math.Round(om.evnaForcast, 8);
                        //dr[10] = om.ppb;
                        //dr[11] = om.days;
                        dr[7] = om.referencecell;
                        dr[8] = Math.Round(om.rrf, 8);
                        dtOutMonitorControl.Rows.Add(dr);
                    }
                    //------------修正OutPutFileName----------------
                    dataType = "Year";
                    strFile = ozonechinaconfiguration.modelDataOzoneChina.scenarioName + " - Nearest Site Spatial Field -- interpolated monitor data, temporally adjusted monitor data, " + forcastYear + ".csv";
                    #endregion
                }
                #endregion
                CommonClass.SaveCSV(dtOutMonitorControl, _resultFilePath + @"\" + strFile, dataType);
                baseOutput = new BaseOutput();
                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);
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}