using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
using DotSpatial.Topology.Voronoi;
using DotSpatial.Data;

namespace SMAT_CE
{
    class BenMAPAnnualPMCommonClass
    {
        public static DateTime _beginTime;//记录开始时间
        public static DateTime _endTime;//记录结束时间
        public static string baseYear = "";//base model year
        public static string controlYear = "";//future model year

        public static string _resultFilePath = "";

        #region VNA & EVNA METHODS
        public static bool AnnualVNAEVNA(ref Dictionary<string, Dictionary<string, float>> dicNeighborDistance, string quarter, string pollutantName, Dictionary<string, Dictionary<string, ModelDataSpecies>> dicGradAdjValues, string interpolationMethod, double distanceInterpolation, ref double dVNA, ref double dEVNA, Dictionary<string, float> fsoutStringSpecies, Dictionary<string, PMMonitorOutput> dicSpeciesMonitors)
        {
            try
            {
                double distanceSpecies = 0, distanceSumSpecies = 0, vnaSum = 0, gvnaSum = 0;
                int n = 0;
                Dictionary<string, float> dic = new Dictionary<string, float>();
                switch (interpolationMethod)
                {
                    case "Equal Weighting of Monitors":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                n++;
                                switch (pollutantName)
                                {
                                    //---------10个-------
                                    #region
                                    case "so4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * dicGradAdjValues[s.Key][quarter].so4;
                                        break;
                                    case "no3r":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "ocb":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * dicGradAdjValues[s.Key][quarter].oc;
                                        break;
                                    case "ec":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * dicGradAdjValues[s.Key][quarter].ec;
                                        break;
                                    case "crustal":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * dicGradAdjValues[s.Key][quarter].crustal;
                                        break;
                                    case "salt":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * dicGradAdjValues[s.Key][quarter].salt;
                                        break;
                                    case "no3":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "NH4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * dicGradAdjValues[s.Key][quarter].nh4;
                                        break;
                                    case "DON":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bDON;
                                        gvnaSum = vnaSum;
                                        break;
                                    case "pm25":
                                        vnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter];
                                        gvnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * dicGradAdjValues[s.Key][quarter].pm25;
                                        break;
                                    #endregion
                                }
                            }
                            catch { }
                        }
                        try
                        {
                            dVNA = Math.Round(Double.IsNaN(vnaSum / n) ? 0 : vnaSum / n, CommonClass.Species_calc_precision);
                            dEVNA = Math.Round(Double.IsNaN(gvnaSum / n) ? 0 : gvnaSum / n, CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                    case "Inverse Distance Weights":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                distanceSpecies = s.Value == 0 ? 1 : 1.0000 / s.Value;
                                distanceSumSpecies += distanceSpecies;
                                switch (pollutantName)
                                {
                                    //---------10个
                                    #region
                                    case "so4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].so4;
                                        break;
                                    case "no3r":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "ocb":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].oc;
                                        break;
                                    case "ec":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].ec;
                                        break;
                                    case "crustal":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].crustal;
                                        break;
                                    case "salt":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].salt;
                                        break;
                                    case "no3":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "NH4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].nh4;
                                        break;
                                    case "DON":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bDON * distanceSpecies;
                                        gvnaSum = vnaSum;
                                        //gvnaSum += dicSpeciesMonitors[s.Key].dicSpecies[Convert.ToString(i)].bDON * distanceSpecies * dicGradAdjValues[s.Key][Convert.ToString(i)].no3;
                                        break;
                                    case "pm25":
                                        vnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies * dicGradAdjValues[s.Key][quarter].pm25;
                                        break;
                                    #endregion
                                }
                            }
                            catch { }
                        }
                        try
                        {
                            dVNA = Math.Round(Double.IsNaN(vnaSum / distanceSumSpecies) ? 0 : vnaSum / distanceSumSpecies, CommonClass.Species_calc_precision);
                            dEVNA = Math.Round(Double.IsNaN(gvnaSum / distanceSumSpecies) ? 0 : gvnaSum / distanceSumSpecies, CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                    case "Inverse Distance Squared Weights":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                distanceSpecies = s.Value == 0 ? 1 : 1.0000 / Math.Pow(s.Value, 2);
                                distanceSumSpecies += distanceSpecies;
                                switch (pollutantName)
                                {
                                    //---------10个
                                    #region
                                    case "so4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].so4;
                                        break;
                                    case "no3r":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "ocb":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].oc;
                                        break;
                                    case "ec":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].ec;
                                        break;
                                    case "crustal":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].crustal;
                                        break;
                                    case "salt":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].salt;
                                        break;
                                    case "no3":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "NH4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].nh4;
                                        break;
                                    case "DON":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bDON * distanceSpecies;
                                        gvnaSum = vnaSum;
                                        //gvnaSum += dicSpeciesMonitors[s.Key].dicSpecies[Convert.ToString(i)].bDON * distanceSpecies * dicGradAdjValues[s.Key][Convert.ToString(i)].no3;
                                        break;
                                    case "pm25":
                                        vnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies;
                                        gvnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies * dicGradAdjValues[s.Key][quarter].pm25;
                                        break;
                                    #endregion
                                }
                            }
                            catch
                            {
                            }
                        }
                        try
                        {
                            dVNA = Math.Round(Double.IsNaN(vnaSum / distanceSumSpecies) ? 0 : vnaSum / distanceSumSpecies, CommonClass.Species_calc_precision);
                            dEVNA = Math.Round(Double.IsNaN(gvnaSum / distanceSumSpecies) ? 0 : gvnaSum / distanceSumSpecies, CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool AnnualVNA(ref Dictionary<string, Dictionary<string, float>> dicNeighborDistance, string quarter, string pollutantName, string interpolationMethod, double distanceInterpolation, ref double dVNA, Dictionary<string, float> fsoutStringSpecies, Dictionary<string, PMMonitorOutput> dicSpeciesMonitors)
        {
            try
            {
                double distanceSpecies = 0, distanceSumSpecies = 0, vnaSum = 0;
                int n = 0;
                Dictionary<string, float> dic = new Dictionary<string, float>();
                switch (interpolationMethod)
                {
                    case "Equal Weighting of Monitors":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                n++;
                                switch (pollutantName)
                                {
                                    //---------10个-------
                                    #region
                                    case "so4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass;
                                        break;
                                    case "no3r":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass;
                                        break;
                                    case "ocb":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass;
                                        break;
                                    case "ec":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass;
                                        break;
                                    case "crustal":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass;
                                        break;
                                    case "salt":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass;
                                        break;
                                    case "no3":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass;
                                        break;
                                    case "NH4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass;
                                        break;
                                    case "DON":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bDON;
                                        break;
                                    case "pm25":
                                        vnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter];
                                        break;
                                    #endregion
                                }
                            }
                            catch { }
                        }
                        try
                        {
                            dVNA = Math.Round(Double.IsNaN(vnaSum / n) ? 0 : vnaSum / n, CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                    case "Inverse Distance Weights":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || float.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                distanceSpecies = s.Value == 0 ? 1 : Convert.ToSingle(1.0000 / s.Value);
                                distanceSumSpecies += distanceSpecies;
                                switch (pollutantName)
                                {
                                    //---------10个
                                    #region
                                    case "so4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies;
                                        break;
                                    case "no3r":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies;
                                        break;
                                    case "ocb":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies;
                                        break;
                                    case "ec":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies;
                                        break;
                                    case "crustal":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies;
                                        break;
                                    case "salt":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies;
                                        break;
                                    case "no3":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies;
                                        break;
                                    case "NH4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies;
                                        break;
                                    case "DON":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bDON * distanceSpecies;
                                        break;
                                    case "pm25":
                                        vnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies;
                                        break;
                                    #endregion
                                }
                            }
                            catch { }
                        }
                        try
                        {
                            dVNA = Math.Round(Double.IsNaN(vnaSum / distanceSumSpecies) ? 0 : vnaSum / distanceSumSpecies, CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                    case "Inverse Distance Squared Weights":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                distanceSpecies = s.Value == 0 ? 1 : Convert.ToSingle(1.0000 / Math.Pow(s.Value, 2));
                                distanceSumSpecies += distanceSpecies;
                                switch (pollutantName)
                                {
                                    //---------10个
                                    #region
                                    case "so4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies;
                                        break;
                                    case "no3r":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies;
                                        break;
                                    case "ocb":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies;
                                        break;
                                    case "ec":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies;
                                        break;
                                    case "crustal":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies;
                                        break;
                                    case "salt":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies;
                                        break;
                                    case "no3":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies;
                                        break;
                                    case "NH4":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies;
                                        break;
                                    case "DON":
                                        vnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bDON * distanceSpecies;
                                        break;
                                    case "pm25":
                                        vnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies;
                                        break;
                                    #endregion
                                }
                            }
                            catch
                            {
                            }
                        }
                        try
                        {
                            double d = Double.IsNaN(vnaSum / distanceSumSpecies) ? 0 : vnaSum / distanceSumSpecies;
                            dVNA = Math.Round(Double.IsNaN(vnaSum / distanceSumSpecies) ? 0 : vnaSum / distanceSumSpecies, CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool AnnualEVNA(ref Dictionary<string, Dictionary<string, float>> dicNeighborDistance, string quarter, string pollutantName, Dictionary<string, Dictionary<string, ModelDataSpecies>> dicGradAdjValues, string interpolationMethod, double distanceInterpolation, ref double dEVNA, Dictionary<string, float> fsoutStringSpecies, Dictionary<string, PMMonitorOutput> dicSpeciesMonitors)
        {
            try
            {
                double distanceSpecies = 0, distanceSumSpecies = 0, gvnaSum = 0;
                int n = 0;
                Dictionary<string, float> dic = new Dictionary<string, float>();
                switch (interpolationMethod)
                {
                    case "Equal Weighting of Monitors":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                n++;
                                switch (pollutantName)
                                {
                                    //---------10个-------
                                    #region
                                    case "so4":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * dicGradAdjValues[s.Key][quarter].so4;
                                        break;
                                    case "no3r":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "ocb":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * dicGradAdjValues[s.Key][quarter].oc;
                                        break;
                                    case "ec":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * dicGradAdjValues[s.Key][quarter].ec;
                                        break;
                                    case "crustal":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * dicGradAdjValues[s.Key][quarter].crustal;
                                        break;
                                    case "salt":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * dicGradAdjValues[s.Key][quarter].salt;
                                        break;
                                    case "no3":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "NH4":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * dicGradAdjValues[s.Key][quarter].nh4;
                                        break;
                                    case "DON":
                                        gvnaSum = dicSpeciesMonitors[id].dicSpecies[quarter].bDON;
                                        break;
                                    case "pm25":
                                        gvnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * dicGradAdjValues[s.Key][quarter].pm25;
                                        break;
                                    #endregion
                                }
                            }
                            catch { }
                        }
                        try
                        {
                            dEVNA = Math.Round(Double.IsNaN(gvnaSum / n) ? 0 : gvnaSum / n, CommonClass.Species_calc_precision);
                        }
                        catch
                        {
                        }
                        #endregion
                        break;
                    case "Inverse Distance Weights":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                distanceSpecies = s.Value == 0 ? 1 : 1.0000 / s.Value;
                                distanceSumSpecies += distanceSpecies;
                                switch (pollutantName)
                                {
                                    //---------10个
                                    #region
                                    case "so4":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].so4;
                                        break;
                                    case "no3r":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "ocb":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].oc;
                                        break;
                                    case "ec":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].ec;
                                        break;
                                    case "crustal":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].crustal;
                                        break;
                                    case "salt":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].salt;
                                        break;
                                    case "no3":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "NH4":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].nh4;
                                        break;
                                    case "DON":
                                        gvnaSum = dicSpeciesMonitors[id].dicSpecies[quarter].bDON * distanceSpecies;
                                        break;
                                    case "pm25":
                                        gvnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies * dicGradAdjValues[s.Key][quarter].pm25;
                                        break;
                                    #endregion
                                }
                            }
                            catch { }
                        }
                        try
                        {
                            dEVNA = Math.Round(Double.IsNaN(gvnaSum / distanceSumSpecies) ? 0 : Convert.ToSingle(gvnaSum / distanceSumSpecies), CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                    case "Inverse Distance Squared Weights":
                        #region
                        foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                        {
                            string id = s.Key.Substring(0, s.Key.IndexOf(","));
                            if (s.Value > distanceInterpolation) continue;
                            try
                            {
                                //------------10个------------
                                #region
                                if (pollutantName == "so4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass))) continue;
                                if (pollutantName == "no3r" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass))) continue;
                                if (pollutantName == "ocb" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass))) continue;
                                if (pollutantName == "ec" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bECMass))) continue;
                                if (pollutantName == "crustal" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass))) continue;
                                if (pollutantName == "salt" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass))) continue;
                                if (pollutantName == "no3" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass))) continue;
                                if (pollutantName == "NH4" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass))) continue;
                                if (pollutantName == "DON" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicSpecies.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicSpecies[quarter].bDON))) continue;
                                if (pollutantName == "pm25" && (!dicSpeciesMonitors.ContainsKey(id) || !dicSpeciesMonitors[id].dicUnofficialPM.ContainsKey(quarter) || Double.IsNaN(dicSpeciesMonitors[id].dicUnofficialPM[quarter]))) continue;
                                #endregion
                                if (dicNeighborDistance.ContainsKey(pollutantName + "," + quarter))
                                {
                                    dicNeighborDistance[pollutantName + "," + quarter].Add(s.Key, s.Value);
                                }
                                else
                                {
                                    dic.Add(s.Key, s.Value);
                                    dicNeighborDistance.Add(pollutantName + "," + quarter, dic);
                                }
                                distanceSpecies = s.Value == 0 ? 1 : 1.0000 / Math.Pow(s.Value, 2);
                                distanceSumSpecies += distanceSpecies;
                                switch (pollutantName)
                                {
                                    //---------10个
                                    #region
                                    case "so4":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSO4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].so4;
                                        break;
                                    case "no3r":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3rMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "ocb":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bOCBMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].oc;
                                        break;
                                    case "ec":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bECMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].ec;
                                        break;
                                    case "crustal":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bCrustalMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].crustal;
                                        break;
                                    case "salt":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bSaltMass * distanceSpecies * dicGradAdjValues[s.Key][quarter].salt;
                                        break;
                                    case "no3":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNO3Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].no3;
                                        break;
                                    case "NH4":
                                        gvnaSum += dicSpeciesMonitors[id].dicSpecies[quarter].bNH4Mass * distanceSpecies * dicGradAdjValues[s.Key][quarter].nh4;
                                        break;
                                    case "DON":
                                        gvnaSum = dicSpeciesMonitors[id].dicSpecies[quarter].bDON * distanceSpecies;
                                        break;
                                    case "pm25":
                                        gvnaSum += dicSpeciesMonitors[id].dicUnofficialPM[quarter] * distanceSpecies * dicGradAdjValues[s.Key][quarter].pm25;
                                        break;
                                    #endregion
                                }
                            }
                            catch
                            {
                            }
                        }
                        try
                        {
                            dEVNA = Math.Round(Double.IsNaN(gvnaSum / distanceSumSpecies) ? 0 : Convert.ToSingle(gvnaSum / distanceSumSpecies), CommonClass.Species_calc_precision);
                        }
                        catch { }
                        #endregion
                        break;
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }
        #endregion

        public static bool AnnualPMAnalysis(BaseScenario baseScenario, SMAT_CE mats)
        {
            if (!(baseScenario.configuration is BenMAPAnnualPMAnalysisConfiguration))
            {
                return false;
            }
            try
            {
                _beginTime = DateTime.Now;
                BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration;
                //save files时先生成相应的文件夹
                #region save files时先生成相应的文件夹
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                #endregion
                #region model data--baseline/future
                Dictionary<string, PmModelDataOutput> dicQuarterlyModelDataPM = new Dictionary<string, PmModelDataOutput>();
                string baseModelYear = "", futureModelYear = "";
                string isOK = "";

                CommonClass.CurrentLog = "Read model data \"" + Path.GetFileName(annualPMAnalysisConfiguration.modelInput.baselineFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                if (annualPMAnalysisConfiguration.modelInput.doQuarterlyModelData)
                {
                    isOK = GetModelDataQuarterly(annualPMAnalysisConfiguration, ref dicQuarterlyModelDataPM, ref baseModelYear, ref futureModelYear);
                    switch (isOK)//error message when loading file
                    {
                        case "wrongBaseline":
                            CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(annualPMAnalysisConfiguration.modelInput.baselineFile) + "\".";
                            CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                            return false;
                        case "wrongFuture":
                            CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(annualPMAnalysisConfiguration.modelInput.forecastFile) + "\".";
                            CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                            return false;
                        case "unknow":
                            CommonClass.CurrentLog = "Fail to read model data.";
                            CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                            return false;
                    }
                    //if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doQuarterlyModelData)
                    //{
                    //    SaveQuarterlyModelDataCopyDirectly(CommonClass.CurrentBaseScenario, dicQuarterlyModelDataPM);
                    //}
                }
                else if (annualPMAnalysisConfiguration.modelInput.doDailyModelData)
                {
                    isOK = GetModelDataDaily(annualPMAnalysisConfiguration, ref dicQuarterlyModelDataPM, ref baseModelYear, ref futureModelYear);
                    switch (isOK)//error message when loading file
                    {
                        case "wrongBaseline":
                            CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(annualPMAnalysisConfiguration.modelInput.baselineFile) + "\".";
                            CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                            return false;
                        case "wrongFuture":
                            CommonClass.CurrentLog = "Fail to read model data \"" + Path.GetFileName(annualPMAnalysisConfiguration.modelInput.forecastFile) + "\".";
                            CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                            return false;
                        case "unknow":
                            CommonClass.CurrentLog = "Fail to read model data.";
                            CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                            return false;
                    }
                    //if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doQuarterlyModelData)
                    //{
                    //    SaveModelDataQuarterly(CommonClass.CurrentBaseScenario, dicQuarterlyModelDataPM, baseModelYear, futureModelYear);
                    //}
                }
                else if (annualPMAnalysisConfiguration.modelInput.doInputfromCMAQ)
                {
                    GetModelDataFromCMAQ(annualPMAnalysisConfiguration);
                    //if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doQuarterlyModelData)
                    //{

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

                //change project - write in dictionary (lat,long to lambert) - for draw map
                DataTable dt = new DataTable();
                dt.Columns.Add("id");
                dt.Columns.Add("lat");
                dt.Columns.Add("long");
                foreach (KeyValuePair<string, PmModelDataOutput> keyvalue in dicQuarterlyModelDataPM)
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = keyvalue.Key;
                    dr[1] = keyvalue.Value.lat;
                    dr[2] = keyvalue.Value.longitude;
                    dt.Rows.Add(dr);
                }
                mats.changeProject(dt, "USA");
                //--------------修正dicQuarterlyModelDataPM的坐标系！-------------------
                #region
                double[] dConvertArrayModel = null;
                List<double> lstConvertArrayModel = new List<double>();
                List<string> lstKeyModel = dicQuarterlyModelDataPM.Keys.ToList();
                for (int iLstKey = 0; iLstKey < dicQuarterlyModelDataPM.Keys.Count; iLstKey++)
                {
                    lstConvertArrayModel.Add(dicQuarterlyModelDataPM[lstKeyModel[iLstKey]].longitude);
                    lstConvertArrayModel.Add(dicQuarterlyModelDataPM[lstKeyModel[iLstKey]].lat);
                }
                dConvertArrayModel = lstConvertArrayModel.ToArray();
                DotSpatial.Projections.Reproject.ReprojectPoints(dConvertArrayModel, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984,
                   DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ), 0, dConvertArrayModel.Length / 2);
                for (int iLstKey = 0; iLstKey < dicQuarterlyModelDataPM.Keys.Count; iLstKey++)
                {
                    dicQuarterlyModelDataPM[lstKeyModel[iLstKey]].longitudeLamber = dConvertArrayModel[2 * iLstKey] / 100.00;
                    dicQuarterlyModelDataPM[lstKeyModel[iLstKey]].latitudeLamber = dConvertArrayModel[2 * iLstKey + 1] / 100.00;
                }
                #endregion
                #endregion
                //_endTime = DateTime.Now;
                //CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish reading model data: " + CommonClass.TotalTime + " s.");
                //CommonClass.CurrentLog = "Finish reading model data: " + CommonClass.TotalTime + " s";
                //load FRM data 和 STN/IMPROVE data

                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Loading FRM and STN/Improve monitor data.");
                //CommonClass.CurrentLog = "Loading FRM and STN/Improve monitor data...";
                _beginTime = DateTime.Now;
                #region
                //CommonClass.CurrentLog = "Read official PM monitor data \"" + Path.GetFileName(annualPMAnalysisConfiguration.dataInputA.officialMonitorDataFile) + "\".";
                //CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                //Dictionary<string, PMMonitorOutput> dicOfficialPMMonitors = new Dictionary<string, PMMonitorOutput>();
                //----------读取official PM monitors file------------
                //isOK = GetOfficialPmMonitors(annualPMAnalysisConfiguration, ref dicOfficialPMMonitors);
                //if (dicOfficialPMMonitors.Count <= 0 || isOK == "unknow")//error message when loading file
                //{
                //    CommonClass.CurrentLog = "Fail to read official PM monitor data \"" + Path.GetFileName(annualPMAnalysisConfiguration.dataInputA.officialMonitorDataFile) + "\".";
                //    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 official PM monitor data: " + CommonClass.TotalTime + " s.";
                //CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                //----------获取设置中的DV periods-----------
                List<string> dicDesignValluePeriods = new List<string>();
                int startYear = Convert.ToInt32(annualPMAnalysisConfiguration.monitorInput.startYear);
                int endYear = Convert.ToInt32(annualPMAnalysisConfiguration.monitorInput.endYear);
                if (endYear < startYear + 2)
                {
                    dicDesignValluePeriods.Add(startYear.ToString() + "-" + endYear.ToString());
                }
                else
                {
                    for (int i = 0; i < endYear - startYear - 1; i++)
                    {
                        dicDesignValluePeriods.Add((startYear + i).ToString() + "-" + (startYear + 2 + i).ToString());
                    }
                }
                #region get baseline FRM data,including official DV and custom DV
                //Dictionary<string, PMMonitorOutput> dicFrmMonitorBaseline = new Dictionary<string, PMMonitorOutput>();
                //List<string> lstYear = new List<string>();
                //if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.choiceOfficialDV)
                //{
                //    PMCalculationOfficialChoice(annualPMAnalysisConfiguration, dicOfficialPMMonitors, dicDesignValluePeriods, ref dicFrmMonitorBaseline);
                //}
                //else if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.choiceCustomDV)
                //{
                //    PMCalculationCustomChoice(annualPMAnalysisConfiguration, dicOfficialPMMonitors, dicDesignValluePeriods, ref dicFrmMonitorBaseline);
                //}
                #endregion
                //dicOfficialPMMonitors.Clear();//modifyby xiejp 先保留最后去掉 --
                GC.Collect();
                #region get unofficial PM25 for all species fractions & spatial field

                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read unofficial PM monitor data \"" + Path.GetFileName(annualPMAnalysisConfiguration.monitorInput.unofficialFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                Dictionary<string, PMMonitorOutput> dicUnofficialMonitorsDaily = new Dictionary<string, PMMonitorOutput>();
                isOK = GetUnofficialPmMonitors(annualPMAnalysisConfiguration, ref dicUnofficialMonitorsDaily);
                if (dicUnofficialMonitorsDaily.Count <= 0 || isOK == "unknow")//error message when loading file
                {
                    CommonClass.CurrentLog = "Fail to read unofficial PM monitor data \"" + Path.GetFileName(annualPMAnalysisConfiguration.monitorInput.unofficialFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    return false;
                }
                //else
                //{
                //    if (isOK == "errorRow")
                //    {
                //        CommonClass.CurrentLog = "There are errors in the monitor file of " + annualPMAnalysisConfiguration.dataInputA.unofficialMonitorDataFile + ". The error rows were removed.";
                //        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                //    }
                //}
                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentLog = "Finish reading unofficial PM monitor data: " + CommonClass.TotalTime + " s.";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                #region min requirements
                //-------mini days per quarter and min years per quarter
                List<string> lstYears = new List<string>();
                Dictionary<string, List<string>> dicMinYearPerQuarter = new Dictionary<string, List<string>>();
                Dictionary<string, Dictionary<string, List<string>>> dicMinDaysYears = new Dictionary<string, Dictionary<string, List<string>>>();
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicUnofficialMonitorsDaily)
                {
                    dicMinYearPerQuarter = new Dictionary<string, List<string>>();
                    foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, float>>> kQ in k.Value.dicUnofficialPMDaily)
                    {
                        lstYears = new List<string>();
                        foreach (KeyValuePair<string, Dictionary<string, float>> kYear in kQ.Value)
                        {
                            if (kYear.Value.Count >= 11)//annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialMinDays)
                            {
                                lstYears.Add(kYear.Key);
                            }
                        }
                        if (lstYears.Count >= 1)//annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialMinYears)
                        {
                            dicMinYearPerQuarter.Add(kQ.Key, lstYears);
                        }
                    }
                    dicMinDaysYears.Add(k.Key, dicMinYearPerQuarter);
                }

                //-----------min quarters per monitors--------------
                Dictionary<string, string> dicMinQuarters = new Dictionary<string, string>();
                foreach (KeyValuePair<string, Dictionary<string, List<string>>> k in dicMinDaysYears)
                {
                    if (k.Value.Count >= 1)//annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialMinSeasonsPoint)
                    {
                        dicMinQuarters.Add(k.Key, k.Key);
                    }
                }
                #endregion

                #region monitor in model grid cell
                Dictionary<string, string> dicMonitorInModelUnofficial = new Dictionary<string, string>();
                Dictionary<string, string> dicMonitorInModelUnofficialTrue = new Dictionary<string, string>();
                GetGridCellUnofficialMonitors(ref dicMonitorInModelUnofficial, ref dicMonitorInModelUnofficialTrue, dicQuarterlyModelDataPM, dicUnofficialMonitorsDaily);
                #endregion

                //----------quarterly average--------------
                #region
                Dictionary<string, PMMonitorOutput> dicUnofficialMonitors = new Dictionary<string, PMMonitorOutput>();
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicUnofficialMonitorsDaily)
                {
                    if (!dicMinQuarters.ContainsKey(k.Key)) continue;
                    dicUnofficialMonitors.Add(k.Key, new PMMonitorOutput()
                    {
                        id = k.Value.id,
                        type = k.Value.type,
                        latitude = k.Value.latitude,
                        longitude = k.Value.longitude,
                        gridcell = dicMonitorInModelUnofficial[k.Key],
                        dicUnofficialPM = new Dictionary<string, float>(),
                    });
                    double pm = 0;
                    foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, float>>> kQ in k.Value.dicUnofficialPMDaily)
                    {
                        pm = 0;
                        var query = dicMinDaysYears[k.Key].Where(p => p.Key == kQ.Key).Select(p => p.Value);
                        if (query.Count() > 0)
                        {
                            List<string> lst = query.First().ToList();
                            int iListCount = lst.Count();
                            for (int i = 0; i < iListCount; i++)
                            {
                                pm += kQ.Value[lst[i]].Select(p => p.Value).Average();
                            }
                            dicUnofficialMonitors[k.Key].dicUnofficialPM.Add(kQ.Key, Convert.ToSingle(Math.Round(Convert.ToSingle(pm / iListCount), CommonClass.Pm_defaultformat)));
                        }
                    }
                }
                #endregion

                //--------------修正dicUnofficialMonitor的坐标系！-------------------
                #region
                double[] dConvertArrayUnofficial = null;
                List<string> lstKey = dicUnofficialMonitors.Keys.ToList();
                List<double> lstConvertArrayUnofficial = new List<double>();
                for (int iLstKey = 0; iLstKey < dicUnofficialMonitors.Keys.Count; iLstKey++)
                {
                    lstConvertArrayUnofficial.Add(dicUnofficialMonitors[lstKey[iLstKey]].longitude);
                    lstConvertArrayUnofficial.Add(dicUnofficialMonitors[lstKey[iLstKey]].latitude);
                }
                dConvertArrayUnofficial = lstConvertArrayUnofficial.ToArray();
                DotSpatial.Projections.Reproject.ReprojectPoints(dConvertArrayUnofficial, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984,
                   DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ), 0, dConvertArrayUnofficial.Length / 2);
                for (int iLstKey = 0; iLstKey < dicUnofficialMonitors.Keys.Count; iLstKey++)
                {
                    dicUnofficialMonitors[lstKey[iLstKey]].longitudeLamber = dConvertArrayUnofficial[2 * iLstKey] / 100.00;
                    dicUnofficialMonitors[lstKey[iLstKey]].latitudeLamber = dConvertArrayUnofficial[2 * iLstKey + 1] / 100.00;
                }
                #endregion
                //-------------------------------------

                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgSpeciatedMonitors)
                //{
                //    SaveQuarterlyAveragePMMonitors(CommonClass.CurrentBaseScenario, dicUnofficialMonitors);
                //}
                #endregion

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

                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Interpolate to FRM sites.");
                //CommonClass.CurrentLog = "Interpolate to FRM sites...";
                _beginTime = DateTime.Now;
                #region get speciated monitor values and species fraction
                Dictionary<string, PMMonitorOutput> dicSpeciesFractions = new Dictionary<string, PMMonitorOutput>();
                Dictionary<string, PMMonitorOutput> dicSpeciesLongLat = new Dictionary<string, PMMonitorOutput>();
                Dictionary<string, string> dicSpeciesNH4DON = new Dictionary<string, string>();
                List<Dictionary<string, PMMonitorOutput>> lstSpecFracPointPeriod = new List<Dictionary<string, PMMonitorOutput>>();
                Dictionary<string, PMMonitorOutput> dicSpecFracSpatial = new Dictionary<string, PMMonitorOutput>();
                Dictionary<string, PMMonitorOutput> dicPmMonitorsLatLong = new Dictionary<string, PMMonitorOutput>();
                Dictionary<string, PMMonitorOutput> dicNeighborFileSpatial = new Dictionary<string, PMMonitorOutput>();
                if (annualPMAnalysisConfiguration.speciesMonitorInput.doSpeciesFractionFile)
                {
                    #region
                    //_beginTime = DateTime.Now;
                    //CommonClass.CurrentLog = "Read species fraction data \"" + Path.GetFileName(annualPMAnalysisConfiguration.dataInputA.specFracPointFile) + "\".";
                    //CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                    //isOK = GetSpeciesFractionPoint(annualPMAnalysisConfiguration, ref dicSpeciesFractions);
                    //if (!string.IsNullOrEmpty(isOK))//error message when loading file
                    //{
                    //    CommonClass.CurrentLog = "Fail to read species fraction data \"" + Path.GetFileName(annualPMAnalysisConfiguration.dataInputA.specFracPointFile) + "\".";
                    //    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 species fraction data: " + CommonClass.TotalTime + " s.";
                    //CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                    //if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doSpeciesFraction)
                    //{
                    //    SaveQuarterlySpecFracPointCopyDirectly(CommonClass.CurrentBaseScenario);
                    //}
                    //if (annualPMAnalysisConfiguration.dataInputA.specFracModeSpatial == "spatial field" && !string.IsNullOrEmpty(annualPMAnalysisConfiguration.dataInputA.specFracSpatialFile))
                    if(annualPMAnalysisConfiguration.monitorInput.useVNA)
                    {
                        _beginTime = DateTime.Now;
                        CommonClass.CurrentLog = "Read species fraction spatial field data \"" + Path.GetFileName(annualPMAnalysisConfiguration.speciesMonitorInput.specFracSpatialFile) + "\".";
                        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                        isOK = GetSpeciesFractionSpatialField(annualPMAnalysisConfiguration, ref dicSpecFracSpatial);
                        if (!string.IsNullOrEmpty(isOK))//error message when loading file
                        {
                            CommonClass.CurrentLog = "Fail to read species fraction spatial field data \"" + Path.GetFileName(annualPMAnalysisConfiguration.speciesMonitorInput.specFracSpatialFile) + "\".";
                            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 species fraction spatial field data: " + CommonClass.TotalTime + " s.";
                        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial)
                        //{
                        //    SaveSpecFracSpatialFieldCopyDirectly(CommonClass.CurrentBaseScenario);
                        //}
                    }
                    //else if (annualPMAnalysisConfiguration.dataInputA.specFracModeSpatial == "grad adj spatial field" && !string.IsNullOrEmpty(annualPMAnalysisConfiguration.dataInputA.specFracSpatialFile))
                    if(annualPMAnalysisConfiguration.monitorInput.useEVNA)
                    {
                        _beginTime = DateTime.Now;
                        CommonClass.CurrentLog = "Read species fraction grad adj spatial field data \"" + Path.GetFileName(annualPMAnalysisConfiguration.speciesMonitorInput.gradAdjSpecFracSpatialFile) + "\".";
                        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                        isOK = GetSpeciesFractionSpatialFieldGradAdj(annualPMAnalysisConfiguration, ref dicSpecFracSpatial);
                        if (!string.IsNullOrEmpty(isOK))//error message when loading file
                        {
                            CommonClass.CurrentLog = "Fail to read species fraction grad adj spatial field data \"" + Path.GetFileName(annualPMAnalysisConfiguration.speciesMonitorInput.gradAdjSpecFracSpatialFile) + "\".";
                            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 species fraction grad adj spatial field data: " + CommonClass.TotalTime + " s.";
                        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj)
                        //{
                        //    SaveSpecFracSpatialFieldCopyDirectly(CommonClass.CurrentBaseScenario);
                        //}
                    }
                    #endregion
                }
                else if (annualPMAnalysisConfiguration.speciesMonitorInput.doSpeciesMonitorDataFile)
                {
                    #region get speciatd monitor data
                    #region speciated Monitors
                    _beginTime = DateTime.Now;
                    CommonClass.CurrentLog = "Read species monitor data \"" + Path.GetFileName(annualPMAnalysisConfiguration.speciesMonitorInput.speciesMonitorDataFile) + "\".";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                    Dictionary<string, PMMonitorOutput> dicSpeciesMonitors = new Dictionary<string, PMMonitorOutput>();
                    isOK = GetSpeciesMonitors(annualPMAnalysisConfiguration, dicSpeciesMonitors);
                    if (dicSpeciesMonitors.Count <= 0 || isOK == "unknow")//error message when loading file
                    {
                        CommonClass.CurrentLog = "Fail to read species monitor data \"" + Path.GetFileName(annualPMAnalysisConfiguration.speciesMonitorInput.speciesMonitorDataFile) + "\".";
                        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                        return false;
                    }
                    //else
                    //{
                    //    if (isOK == "errorRow")
                    //    {
                    //        CommonClass.CurrentLog = "There are errors in the monitor file of " + annualPMAnalysisConfiguration.dataInputA.speciesMonitorDataFile + ". The error rows were removed.";
                    //        CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                    //    }
                    //}
                    _endTime = DateTime.Now;
                    CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                    CommonClass.CurrentLog = "Finish reading species monitor data: " + CommonClass.TotalTime + " s.";
                    CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                    #region min requirements
                    //-------mini days per quarter and min years per quarter
                    lstYears = new List<string>();
                    dicMinYearPerQuarter = new Dictionary<string, List<string>>();
                    dicMinDaysYears = new Dictionary<string, Dictionary<string, List<string>>>();
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeciesMonitors)
                    {
                        dicMinYearPerQuarter = new Dictionary<string, List<string>>();
                        foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, SpeciesMonitors>>> kQ in k.Value.dicSpeciesDaily)
                        {
                            lstYears = new List<string>();
                            foreach (KeyValuePair<string, Dictionary<string, SpeciesMonitors>> kYear in kQ.Value)
                            {
                                if (kYear.Value.Count >= 11)//annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_MinDays)
                                {
                                    lstYears.Add(kYear.Key);
                                }
                            }
                            if (lstYears.Count >= 1)//annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_MinYear)
                            {
                                dicMinYearPerQuarter.Add(kQ.Key, lstYears);
                            }
                        }
                        dicMinDaysYears.Add(k.Key, dicMinYearPerQuarter);
                    }

                    //-----------min quarters per monitors--------------
                    dicMinQuarters = new Dictionary<string, string>();
                    foreach (KeyValuePair<string, Dictionary<string, List<string>>> k in dicMinDaysYears)
                    {
                        if (k.Value.Count >= 1)//annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_MinSeasons)
                        {
                            dicMinQuarters.Add(k.Key, k.Key);
                        }
                    }
                    #endregion

                    #region monitor in model grid cell
                    Dictionary<string, string> dicMonitorInModelSpecies = new Dictionary<string, string>();
                    GetGridCellSpeciatedMonitors(ref dicMonitorInModelSpecies, dicQuarterlyModelDataPM, dicSpeciesMonitors);
                    #endregion
                    //-----------------修正dicSpeciesMonitors的坐标系！----
                    #region
                    double[] dConvertArray = null;
                    List<string> lstKeySpeciesMonitors = dicSpeciesMonitors.Keys.ToList();
                    List<double> lstConvertArray = new List<double>();
                    for (int iLstKey = 0; iLstKey < dicSpeciesMonitors.Keys.Count; iLstKey++)
                    {
                        lstConvertArray.Add(dicSpeciesMonitors[lstKeySpeciesMonitors[iLstKey]].longitude);
                        lstConvertArray.Add(dicSpeciesMonitors[lstKeySpeciesMonitors[iLstKey]].latitude);
                    }
                    dConvertArray = lstConvertArray.ToArray();
                    DotSpatial.Projections.Reproject.ReprojectPoints(dConvertArray, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984,
                       DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ), 0, dConvertArray.Length / 2);
                    for (int iLstKey = 0; iLstKey < dicSpeciesMonitors.Keys.Count; iLstKey++)
                    {
                        dicSpeciesMonitors[lstKeySpeciesMonitors[iLstKey]].longitudeLamber = dConvertArray[2 * iLstKey] / 100.00;
                        dicSpeciesMonitors[lstKeySpeciesMonitors[iLstKey]].latitudeLamber = dConvertArray[2 * iLstKey + 1] / 100.00;
                    }
                    #endregion

                    #region quarterly average
                    GetQuarterlyAverageSpecies(ref dicSpeciesMonitors, dicMinQuarters, dicMonitorInModelSpecies, dicMinDaysYears);
                    #endregion

                    //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgSpeciatedMonitors)
                    //{
                    //    SaveQuarterlyAverageSpeciatedMonitors(CommonClass.CurrentBaseScenario, dicSpeciesMonitors);
                    //}
                    dicMonitorInModelSpecies.Clear();
                    GC.Collect();
                    #endregion
                    #endregion

                    #region species fraction point
                    //if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doSpeciesFraction || annualPMAnalysisConfiguration.chooseDesiredOutputA.doStandardAnalysis
                    //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA
                    //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA
                    //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj
                    //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doNeighborFileSpatial || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial
                    //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial_GraAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial
                    //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj)
                    //{
                    //    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                    //    {
                    //        for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                    //        {
                    //            lstSpecFracPointPeriod.Add(new Dictionary<string, PMMonitorOutput>());
                    //        }
                    //    }
                    //    dicSpeciesLongLat = new Dictionary<string, PMMonitorOutput>();

                    //    //根据unofficial pm25得到其周围的speciated monitors,根据species fractions calculation窗体中选择的interpolation method，最终计算species fractions=species values/FRM-blank_mass
                    //    foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeciesMonitors)
                    //    {
                    //        if (!dicSpeciesLongLat.ContainsKey(k.Value.longitudeLamber + "," + k.Value.latitudeLamber))
                    //            dicSpeciesLongLat.Add(k.Value.longitudeLamber + "," + k.Value.latitudeLamber, k.Value);
                    //        foreach (KeyValuePair<string, SpeciesMonitors> kin in k.Value.dicSpecies)
                    //        {
                    //            if (Double.IsNaN(kin.Value.bDON)) continue;
                    //            if (dicSpeciesNH4DON.ContainsKey(k.Key)) break;
                    //            dicSpeciesNH4DON.Add(k.Key, k.Value.longitude + "," + k.Value.latitude);
                    //        }
                    //    }

                    //    //----------保存neighbor file point-----------------
                    //    Dictionary<string, PMMonitorOutput> dicNeighborFilePoint = new Dictionary<string, PMMonitorOutput>();

                    //    foreach (KeyValuePair<string, PMMonitorOutput> kPM in dicUnofficialMonitors)
                    //    {
                    //        if (!dicFrmMonitorBaseline.ContainsKey(kPM.Key) || !dicMonitorInModelUnofficialTrue.ContainsKey(kPM.Key)
                    //            || kPM.Value.dicUnofficialPM.Count == 0 || kPM.Value.type.Replace("\"", "") != "FRM" ||
                    //            (dicFrmMonitorBaseline[kPM.Key].stateName.Replace("\"", "") == "Alaska"
                    //            || dicFrmMonitorBaseline[kPM.Key].stateName.Replace("\"", "") == "Puerto Rico"
                    //            || dicFrmMonitorBaseline[kPM.Key].stateName.Replace("\"", "") == "Hawaii")) continue;

                    //        //-----当unofficial和official的id相同时，将official的经纬度赋值给unofficial
                    //        if (dicFrmMonitorBaseline.ContainsKey(kPM.Key))
                    //        {
                    //            dicUnofficialMonitors[kPM.Key].latitude = dicFrmMonitorBaseline[kPM.Key].latitude;
                    //            dicUnofficialMonitors[kPM.Key].longitude = dicFrmMonitorBaseline[kPM.Key].longitude;
                    //        }

                    //        //--------添加neighbor file point-----------
                    //        dicNeighborFilePoint.Add(kPM.Key, new PMMonitorOutput()
                    //        {
                    //            id = kPM.Value.id,
                    //            type = kPM.Value.type,
                    //            latitude = kPM.Value.latitude,
                    //            longitude = kPM.Value.longitude,
                    //            stateName = dicFrmMonitorBaseline[kPM.Key].stateName,
                    //            countyName = dicFrmMonitorBaseline[kPM.Key].countyName,
                    //            gridcell = kPM.Value.gridcell,
                    //            dicNeighborFile = new Dictionary<string, Dictionary<string, float>>(),
                    //        });

                    //        Dictionary<string, Dictionary<string, float>> dicNeighborDistance = new Dictionary<string, Dictionary<string, float>>();
                    //        foreach (KeyValuePair<string, float> kQ in kPM.Value.dicUnofficialPM)
                    //        {
                    //            //----------不同的季度分别进行VNA----------
                    //            #region
                    //            List<double> fsInterSpecies = new List<double>();
                    //            fsInterSpecies.Add(kPM.Value.longitudeLamber);
                    //            fsInterSpecies.Add(kPM.Value.latitudeLamber);

                    //            List<double> fsInterNH4DON = new List<double>();
                    //            fsInterNH4DON.Add(kPM.Value.longitudeLamber);
                    //            fsInterNH4DON.Add(kPM.Value.latitudeLamber);

                    //            #region species except NH4 && DON
                    //            bool isSame = false;
                    //            List<double> fsOutSpecies = new List<double>();
                    //            //----判断是否一模一样，如果一样就不需要计算---
                    //            if (dicSpeciesLongLat.ContainsKey(kPM.Value.longitudeLamber + "," + kPM.Value.latitudeLamber)
                    //                && dicSpeciesLongLat[kPM.Value.longitudeLamber + "," + kPM.Value.latitudeLamber].dicSpecies.ContainsKey(kQ.Key))
                    //                isSame = true;
                    //            if (!isSame)
                    //            {
                    //                //-------简化VNA算法：求指定半径内的监测点做VNA,一开始是以5个经纬度来算，一直达到10个为止
                    //                Dictionary<string, double> dicDistanceMonitorSpecies = new Dictionary<string, double>();
                    //                foreach (KeyValuePair<string, PMMonitorOutput> kin in dicSpeciesMonitors)
                    //                {
                    //                    if (!kin.Value.dicSpecies.ContainsKey(kQ.Key)) continue;
                    //                    //if (kin.Value.dicSpecies.Count == 0) continue;
                    //                    dicDistanceMonitorSpecies.Add(kin.Key, (kPM.Value.longitude - kin.Value.longitude) * (kPM.Value.longitude - kin.Value.longitude) + (kPM.Value.latitude - kin.Value.latitude) * (kPM.Value.latitude - kin.Value.latitude));
                    //                }
                    //                var query = dicDistanceMonitorSpecies.Where(p => p.Value < 49).ToList();
                    //                int iDistanceForQuery = 1;
                    //                while (query.Count < 20 && query.Count < dicDistanceMonitorSpecies.Count)
                    //                {
                    //                    query = dicDistanceMonitorSpecies.Where(p => p.Value < 49 + iDistanceForQuery).ToList();
                    //                    iDistanceForQuery++;
                    //                }
                    //                foreach (KeyValuePair<string, double> item in query)
                    //                {
                    //                    fsInterSpecies.Add(dicSpeciesMonitors[item.Key].longitudeLamber);
                    //                    fsInterSpecies.Add(dicSpeciesMonitors[item.Key].latitudeLamber);
                    //                }
                    //                //-----------end VNA-------------
                    //                CommonClass.VoronoiPoints(fsInterSpecies.ToArray(), ref fsOutSpecies);
                    //            }
                    //            else
                    //            {
                    //                fsOutSpecies.Add(kPM.Value.longitudeLamber);
                    //                fsOutSpecies.Add(kPM.Value.latitudeLamber);
                    //            }
                    //            //---------根据得到的neighbor进行计算--------------
                    //            Dictionary<string, float> fsOutString = new Dictionary<string, float>();
                    //            for (int ifsout = 0; ifsout < fsOutSpecies.Count; ifsout++)
                    //            {
                    //                if (ifsout % 2 == 1)
                    //                {
                    //                    float distance = CommonClass.getDistanceFrom2Point(dicSpeciesLongLat[fsOutSpecies[ifsout - 1] + "," + fsOutSpecies[ifsout]].longitude, dicSpeciesLongLat[fsOutSpecies[ifsout - 1] + "," + fsOutSpecies[ifsout]].latitude, kPM.Value.longitude, kPM.Value.latitude);
                    //                    fsOutString.Add(dicSpeciesLongLat[fsOutSpecies[ifsout - 1] + "," + fsOutSpecies[ifsout]].id + "," + dicSpeciesLongLat[fsOutSpecies[ifsout - 1] + "," + fsOutSpecies[ifsout]].gridcell, distance);
                    //                }
                    //            }
                    //            #endregion
                    //            if (fsOutString.Count == 0) continue;
                    //            #region nh4 && don
                    //            isSame = false;
                    //            if (dicSpeciesLongLat.ContainsKey(kPM.Value.longitudeLamber + "," + kPM.Value.latitudeLamber)
                    //                && dicSpeciesLongLat[kPM.Value.longitudeLamber + "," + kPM.Value.latitudeLamber].dicSpecies.ContainsKey(kQ.Key)
                    //                && dicSpeciesNH4DON.ContainsKey(dicSpeciesLongLat[kPM.Value.longitudeLamber + "," + kPM.Value.latitudeLamber].id)
                    //                )
                    //            {
                    //                isSame = true;
                    //            }
                    //            //-------简化VNA算法：求指定半径内的监测点做VNA,一开始是以5个经纬度来算，一直达到10个为止
                    //            if (!isSame)
                    //            {
                    //                Dictionary<string, double> dicDistanceMonitorNH4DON = new Dictionary<string, double>();
                    //                foreach (KeyValuePair<string, string> kin in dicSpeciesNH4DON)
                    //                {
                    //                    if (!dicSpeciesMonitors[kin.Key].dicSpecies.ContainsKey(kQ.Key)) continue;
                    //                    dicDistanceMonitorNH4DON.Add(kin.Key, (kPM.Value.longitude - Convert.ToDouble(kin.Value.Substring(0, kin.Value.IndexOf(",")))) * (kPM.Value.longitude - Convert.ToDouble(kin.Value.Substring(0, kin.Value.IndexOf(",")))) + (kPM.Value.latitude - Convert.ToDouble(kin.Value.Substring(kin.Value.IndexOf(",") + 1))) * (kPM.Value.latitude - Convert.ToDouble(kin.Value.Substring(kin.Value.IndexOf(",") + 1))));
                    //                }
                    //                var query = dicDistanceMonitorNH4DON.Where(p => p.Value < 49).ToList();
                    //                int iDistanceForQuery = 1;
                    //                while (query.Count < 20 && query.Count < dicDistanceMonitorNH4DON.Count)
                    //                {
                    //                    query = dicDistanceMonitorNH4DON.Where(p => p.Value < 49 + iDistanceForQuery).ToList();
                    //                    iDistanceForQuery++;
                    //                }

                    //                foreach (KeyValuePair<string, double> item in query)
                    //                {
                    //                    fsInterNH4DON.Add(dicSpeciesMonitors[item.Key].longitudeLamber);
                    //                    fsInterNH4DON.Add(dicSpeciesMonitors[item.Key].latitudeLamber);
                    //                }
                    //            }
                    //            //--------end VNA--------------
                    //            List<double> fsOutNH4DON = new List<double>();
                    //            if (!isSame)
                    //            {
                    //                CommonClass.VoronoiPoints(fsInterNH4DON.ToArray(), ref fsOutNH4DON);
                    //            }
                    //            else
                    //            {
                    //                fsOutNH4DON.Add(kPM.Value.longitudeLamber);
                    //                fsOutNH4DON.Add(kPM.Value.latitudeLamber);
                    //            }
                    //            Dictionary<string, float> fsoutStringNH4DON = new Dictionary<string, float>();
                    //            for (int ifsout = 0; ifsout < fsOutNH4DON.Count; ifsout++)
                    //            {
                    //                if (ifsout % 2 == 1)
                    //                {
                    //                    float distance = CommonClass.getDistanceFrom2Point(dicSpeciesLongLat[fsOutNH4DON[ifsout - 1] + "," + fsOutNH4DON[ifsout]].longitude, dicSpeciesLongLat[fsOutNH4DON[ifsout - 1] + "," + fsOutNH4DON[ifsout]].latitude, kPM.Value.longitude, kPM.Value.latitude);
                    //                    fsoutStringNH4DON.Add(dicSpeciesLongLat[fsOutNH4DON[ifsout - 1] + "," + fsOutNH4DON[ifsout]].id + "," + dicSpeciesLongLat[fsOutNH4DON[ifsout - 1] + "," + fsOutNH4DON[ifsout]].gridcell, distance);
                    //                }
                    //            }
                    //            #endregion
                    //            if (fsOutString.Count == 0 || fsoutStringNH4DON.Count == 0) continue;
                    //            #endregion
                    //            double vnaCrustal = 0, vnaEC = 0, vnaNH4 = 0, vnaSO4 = 0, vnaOC = 0, vnaSalt = 0, vnaNO3r = 0, vnaDON = 0, vnaPBW = 0, vnaNO3 = 0;
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "so4", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodSO4, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceSO4, ref vnaSO4, fsOutString, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "no3r", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodNO3, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceNO3, ref vnaNO3r, fsOutString, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "ocb", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodOC, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceOC, ref vnaOC, fsOutString, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "ec", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodEC, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceEC, ref vnaEC, fsOutString, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "crustal", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodCrustal, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceCrustal, ref vnaCrustal, fsOutString, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "salt", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodSalt, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceSalt, ref vnaSalt, fsOutString, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "no3", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodNO3, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceNO3, ref vnaNO3, fsOutString, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "NH4", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodNH4, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceNH4, ref vnaNH4, fsoutStringNH4DON, dicSpeciesMonitors);
                    //            AnnualVNA(ref dicNeighborDistance, kQ.Key, "DON", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodDON, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceDON, ref vnaDON, fsoutStringNH4DON, dicSpeciesMonitors);
                    //            dicNeighborFilePoint[kPM.Key].dicNeighborFile = dicNeighborDistance;
                    //            //-----------先保存插值得到的各个species concentration------------
                    //            SpecFracPM sfAnnual = new SpecFracPM();
                    //            GetSpeciesFractionValuesPointEstimates(annualPMAnalysisConfiguration, ref sfAnnual, vnaCrustal, vnaEC, vnaNH4, vnaSO4, vnaOC, vnaSalt, vnaNO3r, vnaDON, vnaPBW, vnaNO3, kQ.Value);
                    //            #region
                    //            if (dicSpeciesFractions.ContainsKey(kPM.Key))
                    //            {
                    //                dicSpeciesFractions[kPM.Key].dicSpeciesFraction.Add(kQ.Key, sfAnnual);
                    //            }
                    //            else
                    //            {
                    //                dicSpeciesFractions.Add(kPM.Key, new PMMonitorOutput()
                    //                {
                    //                    id = kPM.Value.id,
                    //                    type = kPM.Value.type,
                    //                    gridcell = dicMonitorInModelUnofficialTrue[kPM.Key],
                    //                    stateName = dicFrmMonitorBaseline[kPM.Key].stateName,
                    //                    countyName = dicFrmMonitorBaseline[kPM.Key].countyName,
                    //                    latitude = kPM.Value.latitude,
                    //                    longitude = kPM.Value.longitude,
                    //                    dicSpeciesFraction = new Dictionary<string, SpecFracPM>(),
                    //                });
                    //                dicSpeciesFractions[kPM.Key].dicSpeciesFraction.Add(kQ.Key, sfAnnual);
                    //            }
                    //            #region dv period
                    //            if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                    //            {
                    //                if (lstSpecFracPointPeriod.Count == 0) continue;
                    //                //---------全部存3个-----------
                    //                int i = -1;
                    //                foreach (string s in dicDesignValluePeriods)
                    //                {
                    //                    i++;
                    //                    if (!dicFrmMonitorBaseline[kPM.Key].dicOfficialPMPeriod[kQ.Key].ContainsKey(s)) continue;
                    //                    if (Double.IsNaN(dicFrmMonitorBaseline[kPM.Key].dicOfficialPMPeriod[kQ.Key][s].pm)) continue;
                    //                    if (lstSpecFracPointPeriod[i].ContainsKey(kPM.Key))
                    //                    {
                    //                        lstSpecFracPointPeriod[i][kPM.Key].dicSpeciesFraction.Add(kQ.Key, sfAnnual);
                    //                    }
                    //                    else
                    //                    {
                    //                        lstSpecFracPointPeriod[i].Add(kPM.Key, new PMMonitorOutput()
                    //                        {
                    //                            id = kPM.Value.id,
                    //                            type = kPM.Value.type,
                    //                            gridcell = dicMonitorInModelUnofficialTrue[kPM.Key],
                    //                            stateName = dicFrmMonitorBaseline[kPM.Key].stateName,
                    //                            countyName = dicFrmMonitorBaseline[kPM.Key].countyName,
                    //                            latitude = kPM.Value.latitude,
                    //                            longitude = kPM.Value.longitude,
                    //                            dicSpeciesFraction = new Dictionary<string, SpecFracPM>(),
                    //                        });
                    //                        lstSpecFracPointPeriod[i][kPM.Key].dicSpeciesFraction.Add(kQ.Key, sfAnnual);
                    //                    }
                    //                }
                    //            }
                    //            #endregion
                    //            #endregion
                    //        }
                    //    }
                    //    dicSpeciesLongLat.Clear();
                    //    dicUnofficialMonitors.Clear();
                    //    dicMonitorInModelUnofficialTrue.Clear();
                    //    GC.Collect();
                    //    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doNeighborFilePoint)
                    //    {
                    //        SaveNeighborFilePoint(CommonClass.CurrentBaseScenario, dicNeighborFilePoint);
                    //    }
                    //    dicNeighborFilePoint.Clear();
                    //    GC.Collect();
                    //    if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doSpeciesFraction)
                    //    {
                    //        SaveQuarterlySpeciesFractionsPoint(CommonClass.CurrentBaseScenario, dicSpeciesFractions, "");
                    //        if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                    //        {
                    //            for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                    //            {
                    //                SaveQuarterlySpeciesFractionsPoint(CommonClass.CurrentBaseScenario, lstSpecFracPointPeriod[i], " Period " + (i + 1).ToString());
                    //            }
                    //        }
                    //    }
                    //}
                    #endregion
                    //_endTime = DateTime.Now;
                    //CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                    //CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish interpolating FRM sites: " + CommonClass.TotalTime + " s.");
                    //CommonClass.CurrentLog = "Finish interpolating FRM sites: " + CommonClass.TotalTime + " s.";

                    //CommonClass.CurrentBaseScenario.log.lstLog.Add("Interpolating SI,FRM data to grid.");
                    //CommonClass.CurrentLog = "Interpolating SI,FRM data to grid...";
                    _beginTime = DateTime.Now;
                    #region species fraction spatial field
                    //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA
                    //|| annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA
                    //|| annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj
                    //|| annualPMAnalysisConfiguration.outputChoiceAdvancedA.doNeighborFileSpatial || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial
                    //|| annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial_GraAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial
                    //|| annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj)
                    {
                        #region species values Longitude and Latitude
                        dicSpeciesLongLat = new Dictionary<string, PMMonitorOutput>();
                        dicSpeciesNH4DON = new Dictionary<string, string>();
                        foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeciesMonitors)
                        {
                            if (!dicSpeciesLongLat.ContainsKey(k.Value.longitudeLamber + "," + k.Value.latitudeLamber))
                            {
                                dicSpeciesLongLat.Add(k.Value.longitudeLamber + "," + k.Value.latitudeLamber, k.Value);
                            }
                            if (!dicSpeciesNH4DON.ContainsKey(k.Key))
                            {
                                foreach (KeyValuePair<string, SpeciesMonitors> kin in k.Value.dicSpecies)
                                {
                                    if (Double.IsNaN(kin.Value.bDON)) continue;
                                    if (dicSpeciesNH4DON.ContainsKey(k.Key)) break;
                                    dicSpeciesNH4DON.Add(k.Key, k.Value.longitude + "," + k.Value.latitude);
                                }
                            }
                        }
                        #endregion
                        //--------------unofficial pm---------min requirements-----------
                        //------pm25 values for spatial field has different min requirements from point----------
                        #region unofficial pm
                        Dictionary<string, PMMonitorOutput> dicUnofficialPmSpatial = new Dictionary<string, PMMonitorOutput>();
                        RecalculateUnofficialMonitorsForSpatialField(annualPMAnalysisConfiguration, ref dicUnofficialPmSpatial, dicUnofficialMonitorsDaily, dicMinQuarters, dicMonitorInModelUnofficial);
                        //--------------修正dicUnofficialMonitor的坐标系！-------------------
                        #region
                        double[] dConvertArraySpatial = null;
                        List<double> lstConvertArraySpatial = new List<double>();
                        List<string> lstKeySpatial = dicUnofficialPmSpatial.Keys.ToList();
                        for (int iLstKey = 0; iLstKey < dicUnofficialPmSpatial.Keys.Count; iLstKey++)
                        {
                            lstConvertArraySpatial.Add(dicUnofficialPmSpatial[lstKeySpatial[iLstKey]].longitude);
                            lstConvertArraySpatial.Add(dicUnofficialPmSpatial[lstKeySpatial[iLstKey]].latitude);
                        }
                        dConvertArraySpatial = lstConvertArraySpatial.ToArray();
                        DotSpatial.Projections.Reproject.ReprojectPoints(dConvertArraySpatial, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984,
                           DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ), 0, dConvertArraySpatial.Length / 2);
                        for (int iLstKey = 0; iLstKey < dicUnofficialPmSpatial.Keys.Count; iLstKey++)
                        {
                            dicUnofficialPmSpatial[lstKeySpatial[iLstKey]].longitudeLamber = dConvertArraySpatial[2 * iLstKey] / 100.00;
                            dicUnofficialPmSpatial[lstKeySpatial[iLstKey]].latitudeLamber = dConvertArraySpatial[2 * iLstKey + 1] / 100.00;
                        }
                        #endregion
                        #endregion
                        #region unofficial pm Longitude & Latitude
                        foreach (KeyValuePair<string, PMMonitorOutput> k in dicUnofficialPmSpatial)
                        {
                            if (!dicPmMonitorsLatLong.ContainsKey(k.Value.longitudeLamber + "," + k.Value.latitudeLamber))
                            {
                                dicPmMonitorsLatLong.Add(k.Value.longitudeLamber + "," + k.Value.latitudeLamber, k.Value);
                            }
                        }
                        #endregion
                        dicUnofficialMonitorsDaily.Clear();
                        GC.Collect();
                        //获取species和pm的neighbors及相关的数据参数
                        #region
                        List<string> lstGradAdjId = new List<string>();
                        double dInUSA = 16;
                        Dictionary<string, Dictionary<string, float>> dicNeighborDistance = new Dictionary<string, Dictionary<string, float>>();
                        //直接用Polygon来做是否用简略方法处理
                        //Feature fUSA = new Feature();
                        //List<DotSpatial.Topology.Coordinate> lstUSA = new List<DotSpatial.Topology.Coordinate>();
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(-19131.63, 12011.57));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(-12255.43, 9568.71));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(4075.57, 8573.47));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(10725.59, 3732.98));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(18054.18, 5044.88));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(12173.21, -7486.09));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(-1398.24, -6852.76));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(-12979.23, -5631.33));
                        //lstUSA.Add(new DotSpatial.Topology.Coordinate(-21257.82, 837.73));
                        DotSpatial.Topology.Polygon pUSA = CommonClass.generatePolygonWithinUSA("CMAQ");//new DotSpatial.Topology.Polygon(lstUSA);

                        foreach (KeyValuePair<string, PmModelDataOutput> k in dicQuarterlyModelDataPM)
                        {
                            if (pUSA.Contains(new DotSpatial.Topology.Point(k.Value.longitudeLamber, k.Value.latitudeLamber)))
                            {
                                dInUSA = 7;
                            }
                            else
                                dInUSA = 15;
                            //---------add neighbors------------
                            //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doNeighborFileSpatial)
                            //{
                            //    dicNeighborFileSpatial.Add(k.Key, new PMMonitorOutput()
                            //    {
                            //        id = k.Value.id,
                            //        latitude = k.Value.lat,
                            //        longitude = k.Value.longitude,
                            //        dicNeighborFile = new Dictionary<string, Dictionary<string, float>>(),
                            //    });
                            //}
                            dicNeighborDistance = new Dictionary<string, Dictionary<string, float>>();
                            #region
                            foreach (KeyValuePair<string, ModelDataSpecies> kQ in k.Value.dicBaselineModel)
                            {
                                #region pm && species
                                #region species values except NH4 & DON
                                List<double> fsInterSpecies = new List<double>();
                                fsInterSpecies.Add(k.Value.longitudeLamber);
                                fsInterSpecies.Add(k.Value.latitudeLamber);
                                bool isSame = false;

                                //简化VNA算法：求半径范围内的监测点做VNA，一开始以5个经纬度来算一直达到10个为止
                                Dictionary<string, double> dicDistanceMonitorSpecies = new Dictionary<string, double>();
                                foreach (KeyValuePair<string, PMMonitorOutput> kSpecies in dicSpeciesMonitors)
                                {
                                    if (!kSpecies.Value.dicSpecies.ContainsKey(kQ.Key)) continue;
                                    //----------改成extent----
                                    double dLongAbs = Math.Abs(kSpecies.Value.longitude - k.Value.longitude);
                                    if (dLongAbs > dInUSA) continue;
                                    double dLatAbs = Math.Abs(kSpecies.Value.latitude - k.Value.lat);
                                    if (dLatAbs > dInUSA) continue;
                                    if (dLongAbs > dLatAbs)
                                    {
                                        dicDistanceMonitorSpecies.Add(kSpecies.Key, dLongAbs);
                                    }
                                    else
                                    {
                                        dicDistanceMonitorSpecies.Add(kSpecies.Key, dLatAbs);
                                    }
                                }
                                List<KeyValuePair<string, double>> query = new List<KeyValuePair<string, double>>();

                                query = dicDistanceMonitorSpecies.ToList();

                                foreach (KeyValuePair<string, double> kSpecies in query)
                                {
                                    fsInterSpecies.Add(dicSpeciesMonitors[kSpecies.Key].longitudeLamber);
                                    fsInterSpecies.Add(dicSpeciesMonitors[kSpecies.Key].latitudeLamber);
                                    if (k.Value.longitudeLamber == dicSpeciesMonitors[kSpecies.Key].longitudeLamber
                                       && k.Value.latitudeLamber == dicSpeciesMonitors[kSpecies.Key].latitudeLamber)
                                    {
                                        isSame = true;
                                        break;
                                    }
                                }
                                //------------end VNA 简化算法
                                List<double> fsoutSpecies = new List<double>();
                                if (!isSame)
                                {
                                    CommonClass.VoronoiPoints(fsInterSpecies.ToArray(), ref fsoutSpecies);
                                }
                                else
                                {
                                    fsoutSpecies.Add(k.Value.longitudeLamber);
                                    fsoutSpecies.Add(k.Value.latitudeLamber);
                                }
                                if (fsoutSpecies.Count == 0) continue;
                                //----------------根据得到的邻居计算数值----------------
                                Dictionary<string, float> fsoutStringSpecies = new Dictionary<string, float>();
                                for (int ifsoutSpecies = 0; ifsoutSpecies < fsoutSpecies.Count; ifsoutSpecies++)
                                {
                                    if (ifsoutSpecies % 2 == 1)
                                    {
                                        float distance = CommonClass.getDistanceFrom2Point(dicSpeciesLongLat[fsoutSpecies[ifsoutSpecies - 1] + "," + fsoutSpecies[ifsoutSpecies]].longitude, dicSpeciesLongLat[fsoutSpecies[ifsoutSpecies - 1] + "," + fsoutSpecies[ifsoutSpecies]].latitude, k.Value.longitude, k.Value.lat);
                                        fsoutStringSpecies.Add(dicSpeciesLongLat[fsoutSpecies[ifsoutSpecies - 1] + "," + fsoutSpecies[ifsoutSpecies]].id + "," + dicSpeciesLongLat[fsoutSpecies[ifsoutSpecies - 1] + "," + fsoutSpecies[ifsoutSpecies]].gridcell, distance);
                                    }
                                }
                                #endregion

                                #region NH4 & DON
                                List<double> fsInterNH4DON = new List<double>();
                                fsInterNH4DON.Add(k.Value.longitudeLamber);
                                fsInterNH4DON.Add(k.Value.latitudeLamber);
                                //简化VNA算法：求半径范围内的监测点做VNA，一开始以5个经纬度来算一直达到10个为止
                                Dictionary<string, double> dicDistanceMonitorsNH4DON = new Dictionary<string, double>();
                                foreach (KeyValuePair<string, string> kNH4DON in dicSpeciesNH4DON)
                                {
                                    if (!dicSpeciesMonitors[kNH4DON.Key].dicSpecies.ContainsKey(kQ.Key)) continue;
                                    //----------改成extent----
                                    double dLongAbs = Math.Abs((k.Value.longitude - Convert.ToDouble(kNH4DON.Value.Substring(0, kNH4DON.Value.IndexOf(",")))));
                                    if (dLongAbs > dInUSA) continue;
                                    double dLatAbs = Math.Abs((k.Value.lat - Convert.ToDouble(kNH4DON.Value.Substring(kNH4DON.Value.IndexOf(",") + 1))));
                                    if (dLatAbs > dInUSA) continue;
                                    if (dLongAbs > dLatAbs)
                                    {
                                        dicDistanceMonitorsNH4DON.Add(kNH4DON.Key, dLongAbs);
                                    }
                                    else
                                    {
                                        dicDistanceMonitorsNH4DON.Add(kNH4DON.Key, dLatAbs);
                                    }
                                }
                                query = dicDistanceMonitorsNH4DON.ToList();
                                isSame = false;
                                foreach (KeyValuePair<string, double> kNH4DON in query)
                                {
                                    fsInterNH4DON.Add(dicSpeciesMonitors[kNH4DON.Key].longitudeLamber);
                                    fsInterNH4DON.Add(dicSpeciesMonitors[kNH4DON.Key].latitudeLamber);
                                    if (k.Value.longitudeLamber == dicSpeciesMonitors[kNH4DON.Key].longitudeLamber
                                      && k.Value.latitudeLamber == dicSpeciesMonitors[kNH4DON.Key].latitudeLamber)
                                    {
                                        isSame = true;
                                        break;
                                    }
                                }
                                //------------end VNA 简化算法
                                List<double> fsoutNH4DON = new List<double>();
                                if (!isSame)
                                {
                                    CommonClass.VoronoiPoints(fsInterNH4DON.ToArray(), ref fsoutNH4DON);
                                }
                                else
                                {
                                    fsoutNH4DON.Add(k.Value.longitudeLamber);
                                    fsoutNH4DON.Add(k.Value.latitudeLamber);
                                }
                                if (fsoutNH4DON.Count == 0) continue;
                                //----------------根据得到的邻居计算数值----------------
                                Dictionary<string, float> fsoutStringNH4DON = new Dictionary<string, float>();
                                for (int ifsoutNH4DON = 0; ifsoutNH4DON < fsoutNH4DON.Count; ifsoutNH4DON++)
                                {
                                    if (ifsoutNH4DON % 2 == 1)
                                    {
                                        float distance = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicSpeciesLongLat[fsoutNH4DON[ifsoutNH4DON - 1] + "," + fsoutNH4DON[ifsoutNH4DON]].longitude, dicSpeciesLongLat[fsoutNH4DON[ifsoutNH4DON - 1] + "," + fsoutNH4DON[ifsoutNH4DON]].latitude);
                                        fsoutStringNH4DON.Add(dicSpeciesLongLat[fsoutNH4DON[ifsoutNH4DON - 1] + "," + fsoutNH4DON[ifsoutNH4DON]].id + "," + dicSpeciesLongLat[fsoutNH4DON[ifsoutNH4DON - 1] + "," + fsoutNH4DON[ifsoutNH4DON]].gridcell, distance);
                                    }
                                }
                                #endregion

                                #region pm values
                                List<double> fsInterPM = new List<double>();
                                fsInterPM.Add(k.Value.longitudeLamber);
                                fsInterPM.Add(k.Value.latitudeLamber);
                                //简化VNA算法：求半径范围内的监测点做VNA，一开始以5个经纬度来算一直达到10个为止
                                Dictionary<string, double> dicDistanceMonitorPM = new Dictionary<string, double>();
                                foreach (KeyValuePair<string, PMMonitorOutput> kPM in dicUnofficialPmSpatial)
                                {
                                    if (!kPM.Value.dicUnofficialPM.ContainsKey(kQ.Key)) continue;
                                    //----------改成extent----
                                    double dLongAbs = Math.Abs(kPM.Value.longitude - k.Value.longitude);
                                    if (dLongAbs > dInUSA) continue;
                                    double dLatAbs = Math.Abs(kPM.Value.latitude - k.Value.lat);
                                    if (dLatAbs > dInUSA) continue;
                                    if (dLongAbs > dLatAbs)
                                    {
                                        dicDistanceMonitorPM.Add(kPM.Key, dLongAbs);
                                    }
                                    else
                                    {
                                        dicDistanceMonitorPM.Add(kPM.Key, dLatAbs);
                                    }
                                }
                                query = dicDistanceMonitorPM.ToList();
                                isSame = false;
                                foreach (KeyValuePair<string, double> kPM in query)
                                {
                                    fsInterPM.Add(dicUnofficialPmSpatial[kPM.Key].longitudeLamber);
                                    fsInterPM.Add(dicUnofficialPmSpatial[kPM.Key].latitudeLamber);
                                    if (k.Value.longitudeLamber == dicUnofficialPmSpatial[kPM.Key].longitudeLamber
                                        && k.Value.latitudeLamber == dicUnofficialPmSpatial[kPM.Key].latitudeLamber)
                                    {
                                        isSame = true;
                                        break;
                                    }
                                }
                                //------------end VNA 简化算法
                                List<double> fsoutPM = new List<double>();
                                if (!isSame)
                                {
                                    CommonClass.VoronoiPoints(fsInterPM.ToArray(), ref fsoutPM);
                                }
                                else
                                {
                                    fsInterPM.Add(k.Value.longitudeLamber);
                                    fsInterPM.Add(k.Value.latitudeLamber);
                                }
                                if (fsoutPM.Count == 0) continue;
                                //----------------根据得到的邻居计算数值----------------
                                Dictionary<string, float> fsoutStringPM = new Dictionary<string, float>();
                                //List<NeighborFile> lstPMNeighbors = new List<NeighborFile>();
                                for (int ifsoutPM = 0; ifsoutPM < fsoutPM.Count; ifsoutPM++)
                                {
                                    if (ifsoutPM % 2 == 1)
                                    {
                                        float distance = CommonClass.getDistanceFrom2Point(k.Value.longitude, k.Value.lat, dicPmMonitorsLatLong[fsoutPM[ifsoutPM - 1] + "," + fsoutPM[ifsoutPM]].longitude, dicPmMonitorsLatLong[fsoutPM[ifsoutPM - 1] + "," + fsoutPM[ifsoutPM]].latitude);
                                        fsoutStringPM.Add(dicPmMonitorsLatLong[fsoutPM[ifsoutPM - 1] + "," + fsoutPM[ifsoutPM]].id + "," + dicPmMonitorsLatLong[fsoutPM[ifsoutPM - 1] + "," + fsoutPM[ifsoutPM]].gridcell, distance);
                                    }
                                }
                                #endregion
                                #endregion
                                if (fsoutStringNH4DON.Count == 0 || fsoutStringSpecies.Count == 0 || fsoutStringPM.Count == 0) continue;
                                Dictionary<string, Dictionary<string, ModelDataSpecies>> dicGradAdjValues = new Dictionary<string, Dictionary<string, ModelDataSpecies>>();
                                GetGradAdjValues(ref dicGradAdjValues, fsoutStringSpecies, fsoutStringNH4DON, fsoutStringPM, k.Value.dicBaselineModel, dicQuarterlyModelDataPM);
                                double vnaCrustal = 0, vnaEC = 0, vnaNH4 = 0, vnaSO4 = 0, vnaOC = 0, vnaSalt = 0, vnaNO3r = 0, vnaDON = 0, vnaPBW = 0, vnaNO3 = 0,
                                    gvnaCrustal = 0, gvnaEC = 0, gvnaNH4 = 0, gvnaSO4 = 0, gvnaOC = 0, gvnaSalt = 0, gvnaNO3r = 0, gvnaDON = 0, gvnaPBW = 0, gvnaNO3 = 0,
                                    vnaPM = 0, gvnaPM = 0;
                                //--------根据用户选择计算vna和evna----------------
                                #region
                                //if ((annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial)
                                //     && (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj))
                                if (annualPMAnalysisConfiguration.monitorInput.useVNA && annualPMAnalysisConfiguration.monitorInput.useEVNA)
                                {
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "so4", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaSO4, ref gvnaSO4, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "no3r", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaNO3r, ref gvnaNO3r, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "ocb", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaOC, ref gvnaOC, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "ec", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaEC, ref gvnaEC, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "crustal", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaCrustal, ref gvnaCrustal, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "salt", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaSalt, ref gvnaSalt, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "no3", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaNO3, ref gvnaNO3, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "NH4", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaNH4, ref gvnaNH4, fsoutStringNH4DON, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "DON", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaDON, ref gvnaDON, fsoutStringNH4DON, dicSpeciesMonitors);
                                    AnnualVNAEVNA(ref dicNeighborDistance, kQ.Key, "pm25", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref vnaPM, ref gvnaPM, fsoutStringPM, dicUnofficialPmSpatial);
                                }
                                //else if ((annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial)
                                //          && (!annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj && !annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna && !annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna && !annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj))
                                else if(annualPMAnalysisConfiguration.monitorInput.useVNA)
                                {
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "so4", "Inverse Distance Squared Weights", 9000000000, ref vnaSO4, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "no3r", "Inverse Distance Squared Weights", 9000000000, ref vnaNO3r, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "ocb", "Inverse Distance Squared Weights", 9000000000, ref vnaOC, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "ec", "Inverse Distance Squared Weights", 9000000000, ref vnaEC, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "crustal", "Inverse Distance Squared Weights", 9000000000, ref vnaCrustal, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "salt", "Inverse Distance Squared Weights", 9000000000, ref vnaSalt, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "no3", "Inverse Distance Squared Weights", 9000000000, ref vnaNO3, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "NH4", "Inverse Distance Squared Weights", 9000000000, ref vnaNH4, fsoutStringNH4DON, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "DON", "Inverse Distance Squared Weights", 9000000000, ref vnaDON, fsoutStringNH4DON, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "pm25", "Inverse Distance Squared Weights", 9000000000, ref vnaPM, fsoutStringPM, dicUnofficialPmSpatial);
                                }
                                //else if (!(annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj && !annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA && !annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA && !annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial)
                                //     && (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj))
                                else if(annualPMAnalysisConfiguration.monitorInput.useEVNA)
                                {
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "so4", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaSO4, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "no3r", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaNO3r, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "ocb", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaOC, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "ec", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaEC, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "crustal", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaCrustal, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "salt", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaSalt, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "no3", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaNO3, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "NH4", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaNH4, fsoutStringNH4DON, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "DON", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaDON, fsoutStringNH4DON, dicSpeciesMonitors);
                                    AnnualEVNA(ref dicNeighborDistance, kQ.Key, "pm25", dicGradAdjValues, "Inverse Distance Squared Weights", 9000000000, ref gvnaPM, fsoutStringPM, dicUnofficialPmSpatial);
                                }
                                else if (annualPMAnalysisConfiguration.monitorInput.doDownscaler)
                                {
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "so4", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodSO4, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceSO4, ref vnaSO4, fsoutStringSpecies, dicSpeciesMonitors);
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "no3r", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodNO3, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceNO3, ref vnaNO3r, fsoutStringSpecies, dicSpeciesMonitors);
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "ocb", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodOC, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceOC, ref vnaOC, fsoutStringSpecies, dicSpeciesMonitors);
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "ec", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodEC, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceEC, ref vnaEC, fsoutStringSpecies, dicSpeciesMonitors);
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "crustal", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodCrustal, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceCrustal, ref vnaCrustal, fsoutStringSpecies, dicSpeciesMonitors);
                                    AnnualVNA(ref dicNeighborDistance, kQ.Key, "salt", "Inverse Distance Squared Weights", 9000000000, ref vnaSalt, fsoutStringSpecies, dicSpeciesMonitors);
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "no3", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodNO3, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceNO3, ref vnaNO3, fsoutStringSpecies, dicSpeciesMonitors);
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "NH4", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodNH4, annualPMAnalysisConfiguration.speciesFractionOptionsA.distanceNH4, ref vnaNH4, fsoutStringNH4DON, dicSpeciesMonitors);
                                   AnnualVNA(ref dicNeighborDistance, kQ.Key, "DON", "Inverse Distance Squared Weights", 9000000000, ref vnaDON, fsoutStringNH4DON, dicSpeciesMonitors);
                                    //AnnualVNA(ref dicNeighborDistance, kQ.Key, "pm25", annualPMAnalysisConfiguration.speciesFractionOptionsA.interpolationMethodPM25, annualPMAnalysisConfiguration.speciesFractionOptionsA.distancePM25, ref vnaPM, fsoutStringPM, dicUnofficialPmSpatial);
                                }


                                #endregion
                                //------保存vna和evna插值结果
                   
                                SpecFracPM sfAnnualSpatialGradAdj = new SpecFracPM();
                                SpecFracPM sfAnnualSpatial = new SpecFracPM();
                                #region VNA
                                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial)
                                if(annualPMAnalysisConfiguration.monitorInput.useVNA)
                                {
                                    GetSpeciesFractionValuesVNAEVNA(annualPMAnalysisConfiguration, ref sfAnnualSpatial, vnaCrustal, vnaEC, vnaNH4, vnaSO4, vnaOC, vnaSalt, vnaNO3r, vnaDON, vnaPBW, vnaNO3, vnaPM);
                                    #region species fractions
                                    if (dicSpecFracSpatial.ContainsKey(k.Key))
                                    {
                                        dicSpecFracSpatial[k.Key].dicSpecFracSpatial.Add(kQ.Key, sfAnnualSpatial);
                                    }
                                    else
                                    {
                                        dicSpecFracSpatial.Add(k.Key, new PMMonitorOutput()
                                        {
                                            id = k.Value.id,
                                            latitude = k.Value.lat,
                                            longitude = k.Value.longitude,
                                            dicSpecFracSpatial = new Dictionary<string, SpecFracPM>(),
                                        });
                                        dicSpecFracSpatial[k.Key].dicSpecFracSpatial.Add(kQ.Key, sfAnnualSpatial);
                                    }
                                    #endregion
                                }
                                else if (annualPMAnalysisConfiguration.monitorInput.doDownscaler)
                                {
                                    GetSpeciesFractionValuesVNAEVNA(annualPMAnalysisConfiguration, ref sfAnnualSpatial, 0, 0, 0, 0, 0, vnaSalt, 0, vnaDON, 0, 0, 0);
                                    #region species fractions
                                    if (dicSpecFracSpatial.ContainsKey(k.Key))
                                    {
                                        dicSpecFracSpatial[k.Key].dicSpecFracSpatial.Add(kQ.Key, sfAnnualSpatial);
                                    }
                                    else
                                    {
                                        dicSpecFracSpatial.Add(k.Key, new PMMonitorOutput()
                                        {
                                            id = k.Value.id,
                                            latitude = k.Value.lat,
                                            longitude = k.Value.longitude,
                                            dicSpecFracSpatial = new Dictionary<string, SpecFracPM>(),
                                        });
                                        dicSpecFracSpatial[k.Key].dicSpecFracSpatial.Add(kQ.Key, sfAnnualSpatial);
                                    }
                                    #endregion
                                }
                                #endregion
                                #region eVNA
                                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj)
                                if(annualPMAnalysisConfiguration.monitorInput.useEVNA)
                                {
                                    GetSpeciesFractionValuesVNAEVNA(annualPMAnalysisConfiguration, ref sfAnnualSpatialGradAdj, gvnaCrustal, gvnaEC, gvnaNH4, gvnaSO4, gvnaOC, gvnaSalt, gvnaNO3r, gvnaDON, gvnaPBW, gvnaNO3, gvnaPM);
                                    #region species fractions
                                    if (dicSpecFracSpatial.ContainsKey(k.Key))
                                    {
                                        if (dicSpecFracSpatial[k.Key].dicSpecFracSpatialGradAdj == null)
                                            dicSpecFracSpatial[k.Key].dicSpecFracSpatialGradAdj = new Dictionary<string, SpecFracPM>();
                                        dicSpecFracSpatial[k.Key].dicSpecFracSpatialGradAdj.Add(kQ.Key, sfAnnualSpatialGradAdj);
                                    }
                                    else
                                    {
                                        dicSpecFracSpatial.Add(k.Key, new PMMonitorOutput()
                                        {
                                            id = k.Value.id,
                                            latitude = k.Value.lat,
                                            longitude = k.Value.longitude,
                                            dicSpecFracSpatialGradAdj = new Dictionary<string, SpecFracPM>(),
                                        });
                                        dicSpecFracSpatial[k.Key].dicSpecFracSpatialGradAdj.Add(kQ.Key, sfAnnualSpatialGradAdj);
                                    }
                                    #endregion
                                }
                                
                                #endregion
                                //dicGradAdjValues.Clear();
                                fsoutStringPM.Clear();
                                fsoutStringNH4DON.Clear();
                                fsoutStringSpecies.Clear();
                            }
                            //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doNeighborFileSpatial)
                            //{
                            //    dicNeighborFileSpatial[k.Key].dicNeighborFile = dicNeighborDistance;
                            //}
                            //else
                            //    dicNeighborDistance.Clear();
                            #endregion
                        }
                        #endregion


                        if (annualPMAnalysisConfiguration.monitorInput.doDownscaler)
                        {
                            //==========================downscaler begins here==========================================
                            DateTime s = DateTime.Now;
                            CommonClass.CurrentLog = "Start downscaler computation...";
                            CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);


                            DownscaleR.CommonSettings setting = new DownscaleR.CommonSettings();
                            setting.Cmaqres = annualPMAnalysisConfiguration.monitorInput.DS_Cmaqres;
                            setting.Burn = annualPMAnalysisConfiguration.monitorInput.DS_Burn;
                            setting.Thin = annualPMAnalysisConfiguration.monitorInput.DS_Thin;
                            setting.Numit = annualPMAnalysisConfiguration.monitorInput.DS_Numit;
                            setting.ModelFilePath = annualPMAnalysisConfiguration.modelInput.baselineFile;
                            DownscaleR.AnnualPM.AnnualPMAnalysis analysis = new DownscaleR.AnnualPM.AnnualPMAnalysis(setting, dicQuarterlyModelDataPM, dicSpeciesMonitors, dicUnofficialPmSpatial);
                            bool ok = analysis.StartAnalysis();
                            DateTime d = DateTime.Now;


                            foreach (var dsOpt in analysis.DSOutputValue)
                            {
                                foreach (var dsOptQuarter in dsOpt.Value.DicQuarterlyDSValue)
                                {
                                    #region
                                    if (analysis.ModelMissingSpecies.Contains("salt"))
                                    {
                                        dsOptQuarter.Value.Salt_DS_Prediction = dicSpecFracSpatial[dsOpt.Key].dicSpecFracSpatial[dsOptQuarter.Key].iSalt;
                                    }
                                    if (analysis.ModelMissingSpecies.Contains("don"))
                                    {
                                        dsOptQuarter.Value.DON_DS_Prediction = dicSpecFracSpatial[dsOpt.Key].dicSpecFracSpatial[dsOptQuarter.Key].iDON;
                                    }
                                    #endregion
                                    //------------------Save species into "dicSpecFracSpatial"--------------------
                                    SpecFracPM sfAnnualSpatialDS = new SpecFracPM();
                                    GetSpeciesFractionValuesVNAEVNA(annualPMAnalysisConfiguration, ref sfAnnualSpatialDS
                                        , dsOptQuarter.Value.Crustal_DS_Prediction
                                        , dsOptQuarter.Value.EC_DS_Prediction
                                        , dsOptQuarter.Value.NH4_DS_Prediction
                                        , dsOptQuarter.Value.SO4_DS_Prediction
                                        , dsOptQuarter.Value.OCB_DS_Prediction
                                        , dsOptQuarter.Value.Salt_DS_Prediction
                                        , dsOptQuarter.Value.NO3R_DS_Prediction
                                        , dsOptQuarter.Value.DON_DS_Prediction
                                        , dsOptQuarter.Value.PBW_DS_Prediction
                                        , dsOptQuarter.Value.NO3_DS_Prediction
                                        , dsOptQuarter.Value.PM25_DS_Prediction);

                                    if (dicSpecFracSpatial.ContainsKey(dsOpt.Key))
                                    {
                                        if (dicSpecFracSpatial[dsOpt.Key].dicSpecFracSpatialDS == null)
                                            dicSpecFracSpatial[dsOpt.Key].dicSpecFracSpatialDS = new Dictionary<string, SpecFracPM>();
                                        dicSpecFracSpatial[dsOpt.Key].dicSpecFracSpatialDS.Add(dsOptQuarter.Key, sfAnnualSpatialDS);
                                    }
                                    else
                                    {
                                        dicSpecFracSpatial.Add(dsOpt.Key, new PMMonitorOutput()
                                        {
                                            id = dsOpt.Value.Id,
                                            latitude = dsOpt.Value.Lat,
                                            longitude = dsOpt.Value.Lon,
                                            dicSpecFracSpatialDS = new Dictionary<string, SpecFracPM>(),
                                        });
                                        dicSpecFracSpatial[dsOpt.Key].dicSpecFracSpatialDS.Add(dsOptQuarter.Key, sfAnnualSpatialDS);
                                    }
                                }
                            }



                            TimeSpan ts = d - s;
                            double m = ts.TotalSeconds;
                            analysis.Dispose();// 最后调用

                            CommonClass.TotalTime = Math.Round(ts.TotalSeconds, 3);
                            CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish downscalser computation in " + CommonClass.TotalTime + " s.");
                            CommonClass.CurrentLog = "Finish downscalser computation in " + CommonClass.TotalTime + " s.";
                            //=======================================downscaler end====================================
                        }

                        dicUnofficialPmSpatial.Clear();
                        GC.Collect();
                        dicSpeciesLongLat.Clear();
                        GC.Collect();
                        dicSpeciesMonitors.Clear();
                        GC.Collect();
                        dicSpeciesNH4DON.Clear();
                        GC.Collect();
                        dicPmMonitorsLatLong.Clear();
                        GC.Collect();
                        dicMonitorInModelUnofficialTrue.Clear();
                        GC.Collect();
                        dicMonitorInModelUnofficial.Clear();
                        GC.Collect();

                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial)
                        //{
                        //    SaveSpecFracSpatialField(CommonClass.CurrentBaseScenario, dicSpecFracSpatial, "");
                        //    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                        //    {
                        //        for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                        //        {
                        //            SaveSpecFracSpatialField(CommonClass.CurrentBaseScenario, dicSpecFracSpatial, " Period " + (i + 1).ToString());
                        //        }
                        //    }
                        //}
                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj)
                        //{
                        //    SaveSpecFracSpatialFieldGradAdj(CommonClass.CurrentBaseScenario, dicSpecFracSpatial, "");
                        //    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                        //    {
                        //        for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                        //        {
                        //            SaveSpecFracSpatialFieldGradAdj(CommonClass.CurrentBaseScenario, dicSpecFracSpatial, " Period " + (i + 1).ToString());
                        //        }
                        //    }
                        //}
                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doNeighborFileSpatial)
                        //{
                        //    SaveNeighborFileSpatialField(CommonClass.CurrentBaseScenario, dicNeighborFileSpatial, "");
                        //    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                        //    {
                        //        for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                        //        {
                        //            SaveNeighborFileSpatialField(CommonClass.CurrentBaseScenario, dicNeighborFileSpatial, " Period " + (i + 1).ToString());
                        //        }
                        //    }
                        //}
                        dicNeighborFileSpatial.Clear();
                        GC.Collect();
                    }
                    #endregion
                    _endTime = DateTime.Now;
                    CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                    CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish interpolating SI,FRM data to grid. " + CommonClass.TotalTime + " s.");
                    CommonClass.CurrentLog = "Finish interpolating SI,FRM data to grid. " + CommonClass.TotalTime + " s.";
                }
                #endregion

                #region get baseline species values
                //Dictionary<string, PMMonitorOutput> dicQuarterlyPMPoint = new Dictionary<string, PMMonitorOutput>();
                //foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeciesFractions)
                //{
                //    dicQuarterlyPMPoint.Add(k.Key, new PMMonitorOutput()
                //    {
                //        id = k.Key,
                //        type = string.IsNullOrEmpty(k.Value.type) ? dicUnofficialMonitors[k.Key].type : k.Value.type,
                //        stateName = k.Value.stateName,
                //        countyName = k.Value.countyName,
                //        latitude = k.Value.latitude,
                //        longitude = k.Value.longitude,
                //        gridcell = string.IsNullOrEmpty(k.Value.gridcell) ? dicMonitorInModelUnofficialTrue[k.Key] : k.Value.gridcell,
                //        dicQuarterlyPoint = new Dictionary<string, PMPoint>(),
                //    });
                //    double nonBlankMass = 0;
                //    foreach (KeyValuePair<string, SpecFracPM> kin in k.Value.dicSpeciesFraction)
                //    {
                //        nonBlankMass = dicFrmMonitorBaseline[k.Key].dicOfficialPM[kin.Key].pm - Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass);
                //        dicQuarterlyPMPoint[k.Key].dicQuarterlyPoint.Add(kin.Key, new PMPoint()
                //        {
                //            bPMDV = dicFrmMonitorBaseline[k.Key].dicOfficialPM[kin.Key].pm,
                //            bSO4Mass = nonBlankMass * kin.Value.fSO4,
                //            bNO3Mass = nonBlankMass * kin.Value.fNO3r,
                //            bOcmbMass = nonBlankMass * kin.Value.fOcm,
                //            bECMass = nonBlankMass * kin.Value.fEC,
                //            bWaterMass = nonBlankMass * kin.Value.fWater,
                //            bNH4Mass = nonBlankMass * kin.Value.fNH4,
                //            bCrustalMass = nonBlankMass * kin.Value.fCr,
                //            bSaltMass = nonBlankMass * kin.Value.fSalt,
                //            bDON = kin.Value.don,
                //        });
                //    }
                //}
                //dicSpeciesFractions.Clear();
                GC.Collect();
                #region dv periods
                //List<Dictionary<string, PMMonitorOutput>> lstQuarterlyPointPeriod = new List<Dictionary<string, PMMonitorOutput>>();
                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                //{
                //    for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                //    {
                //        lstQuarterlyPointPeriod.Add(new Dictionary<string, PMMonitorOutput>());
                //    }
                //    #region
                //    for (int i = 0; i < lstSpecFracPointPeriod.Count; i++)
                //    {
                //        foreach (KeyValuePair<string, PMMonitorOutput> k in lstSpecFracPointPeriod[i])
                //        {
                //            lstQuarterlyPointPeriod[i].Add(k.Key, new PMMonitorOutput()
                //            {
                //                id = k.Key,
                //                type = k.Value.type,
                //                stateName = k.Value.stateName,
                //                countyName = k.Value.countyName,
                //                latitude = k.Value.latitude,
                //                longitude = k.Value.longitude,
                //                gridcell = k.Value.gridcell,
                //                dicQuarterlyPoint = new Dictionary<string, PMPoint>(),
                //            });
                //            double nonBlankMass = 0;
                //            foreach (KeyValuePair<string, SpecFracPM> kQ in k.Value.dicSpeciesFraction)
                //            {
                //                nonBlankMass = kQ.Value.pm25MassFrac - Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass);
                //                lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint.Add(kQ.Key, new PMPoint()
                //                {
                //                    bPMDV = kQ.Value.pm25MassFrac,
                //                    bSO4Mass = nonBlankMass * kQ.Value.fSO4,
                //                    bNO3Mass = nonBlankMass * kQ.Value.fNO3r,
                //                    bOcmbMass = nonBlankMass * kQ.Value.fOcm,
                //                    bECMass = nonBlankMass * kQ.Value.fEC,
                //                    bWaterMass = nonBlankMass * kQ.Value.fWater,
                //                    bNH4Mass = nonBlankMass * kQ.Value.fNH4,
                //                    bCrustalMass = nonBlankMass * kQ.Value.fCr,
                //                    bSaltMass = nonBlankMass * kQ.Value.fSalt,
                //                    bDON = kQ.Value.don,
                //                });
                //            }
                //        }
                //    }
                //    #endregion
                //}
                #endregion
                //dicFrmMonitorBaseline.Clear();
                //lstSpecFracPointPeriod.Clear();
                GC.Collect();
                #endregion

                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Start computing RRFs.");
                //CommonClass.CurrentLog = "Start computing RRFs...";
                //_beginTime = DateTime.Now;
                #region RRF values and future values
                //#region quarterly pm point
                //List<string> lstUsedModelData = new List<string>();
                //foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlyPMPoint)
                //{
                //    int Col = Convert.ToInt32(k.Value.gridcell) / 1000;
                //    int Row = Convert.ToInt32(k.Value.gridcell) % 1000;
                //    List<string> lstArrond = new List<string>();

                //    PMPoint pmPoint = new PMPoint();

                //    //-------首先根据gridtype获取周围的网格数
                //    #region
                //    switch (annualPMAnalysisConfiguration.modelDataOptionsA.temporalAdjustmentAtMonitorGrid)
                //    {
                //        case "1x1":
                //            lstArrond.Add(dicQuarterlyModelDataPM[k.Value.gridcell].id);
                //            break;
                //        case "3x3":
                //            for (int m3 = -1; m3 <= 1; m3++)
                //            {
                //                for (int n3 = -1; n3 <= 1; n3++)
                //                {
                //                    lstArrond.Add(((Col + m3) * 1000 + (Row + n3)).ToString());
                //                }
                //            }
                //            break;
                //        case "5x5":
                //            for (int m5 = -2; m5 <= 2; m5++)
                //            {
                //                for (int j5 = -2; j5 <= 2; j5++)
                //                {
                //                    lstArrond.Add(((Col + m5) * 1000 + (Row + j5)).ToString());
                //                }
                //            }
                //            break;
                //        case "7x7":
                //            for (int m7 = -3; m7 <= 3; m7++)
                //            {
                //                for (int j7 = -3; j7 <= 3; j7++)
                //                {
                //                    lstArrond.Add(((Col + m7) * 1000 + (Row + j7)).ToString());
                //                }
                //            }
                //            break;
                //    }
                //    #endregion
                //    for (int i = 0; i < lstArrond.Count; i++)
                //    {
                //        if (!lstUsedModelData.Contains(lstArrond[i]))
                //            lstUsedModelData.Add(lstArrond[i]);
                //    }
                //    //然后求所有网格的baseline和control的均值,得到rrf，然后求future values
                //    #region
                //    var query = dicQuarterlyModelDataPM.Where(p => lstArrond.Contains(p.Key)).ToList();
                //    if (query.Count() > 0)
                //    {
                //        int iQueryCount = query.Count();
                //        Dictionary<string, ModelDataSpecies> dicAmBaseline = new Dictionary<string, ModelDataSpecies>();
                //        Dictionary<string, ModelDataSpecies> dicAmFuture = new Dictionary<string, ModelDataSpecies>();

                //        for (int i = 0; i < iQueryCount; i++)
                //        {
                //            KeyValuePair<string, PmModelDataOutput> kin = query.ToArray()[i];
                //            foreach (KeyValuePair<string, ModelDataSpecies> kBase in kin.Value.dicBaselineModel)
                //            {
                //                if (dicAmBaseline.ContainsKey(kBase.Key))
                //                {
                //                    dicAmBaseline[kBase.Key].crustal += kBase.Value.crustal;
                //                    dicAmBaseline[kBase.Key].nh4 += kBase.Value.nh4;
                //                    dicAmBaseline[kBase.Key].so4 += kBase.Value.so4;
                //                    dicAmBaseline[kBase.Key].ec += kBase.Value.ec;
                //                    dicAmBaseline[kBase.Key].no3 += kBase.Value.no3;
                //                    dicAmBaseline[kBase.Key].oc += kBase.Value.oc;
                //                    dicAmBaseline[kBase.Key].pm25 += kBase.Value.pm25;
                //                    //dicAmBaseline[kBase.Key].cm += kBase.Value.cm;
                //                    dicAmBaseline[kBase.Key].salt += kBase.Value.salt;
                //                }
                //                else
                //                {
                //                    dicAmBaseline.Add(kBase.Key, new ModelDataSpecies()
                //                    {
                //                        crustal = kBase.Value.crustal,
                //                        nh4 = kBase.Value.nh4,
                //                        so4 = kBase.Value.so4,
                //                        ec = kBase.Value.ec,
                //                        no3 = kBase.Value.no3,
                //                        oc = kBase.Value.oc,
                //                        pm25 = kBase.Value.pm25,
                //                        cm = kBase.Value.cm,
                //                        salt = kBase.Value.salt,
                //                    });
                //                }
                //            }
                //            foreach (KeyValuePair<string, ModelDataSpecies> kFuture in kin.Value.dicFutureModel)
                //            {
                //                if (dicAmFuture.ContainsKey(kFuture.Key))
                //                {
                //                    dicAmFuture[kFuture.Key].crustal += kFuture.Value.crustal;
                //                    dicAmFuture[kFuture.Key].nh4 += kFuture.Value.nh4;
                //                    dicAmFuture[kFuture.Key].so4 += kFuture.Value.so4;
                //                    dicAmFuture[kFuture.Key].ec += kFuture.Value.ec;
                //                    dicAmFuture[kFuture.Key].no3 += kFuture.Value.no3;
                //                    dicAmFuture[kFuture.Key].oc += kFuture.Value.oc;
                //                    dicAmFuture[kFuture.Key].pm25 += kFuture.Value.pm25;
                //                    dicAmFuture[kFuture.Key].salt += kFuture.Value.salt;
                //                }
                //                else
                //                {
                //                    dicAmFuture.Add(kFuture.Key, new ModelDataSpecies()
                //                    {
                //                        crustal = kFuture.Value.crustal,
                //                        nh4 = kFuture.Value.nh4,
                //                        so4 = kFuture.Value.so4,
                //                        ec = kFuture.Value.ec,
                //                        no3 = kFuture.Value.no3,
                //                        oc = kFuture.Value.oc,
                //                        pm25 = kFuture.Value.pm25,
                //                        salt = kFuture.Value.salt,
                //                    });
                //                }
                //            }
                //        }
                //        //-----------RRF limitation----------------
                //        foreach (KeyValuePair<string, ModelDataSpecies> kBase in dicAmBaseline)
                //        {//CRUSTAL_b NH4_b SO4_b EC_b NO3_b OC_b salt_b PM25_b
                //            if (kBase.Value.crustal < CommonClass.RrfLimit) kBase.Value.crustal = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kBase.Value.ec < CommonClass.RrfLimit) kBase.Value.ec = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kBase.Value.no3 < CommonClass.RrfLimit) kBase.Value.no3 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kBase.Value.so4 < CommonClass.RrfLimit) kBase.Value.so4 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kBase.Value.nh4 < CommonClass.RrfLimit) kBase.Value.nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kBase.Value.oc < CommonClass.RrfLimit) kBase.Value.oc = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kBase.Value.pm25 < CommonClass.RrfLimit) kBase.Value.pm25 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (Double.IsNaN(kBase.Value.salt) || kBase.Value.salt < CommonClass.RrfLimit) kBase.Value.salt = Convert.ToSingle(CommonClass.RrfLimit);
                //        }
                //        foreach (KeyValuePair<string, ModelDataSpecies> kFuture in dicAmFuture)
                //        {
                //            if (kFuture.Value.crustal < CommonClass.RrfLimit) kFuture.Value.crustal = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kFuture.Value.ec < CommonClass.RrfLimit) kFuture.Value.ec = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kFuture.Value.no3 < CommonClass.RrfLimit) kFuture.Value.no3 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kFuture.Value.so4 < CommonClass.RrfLimit) kFuture.Value.so4 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kFuture.Value.nh4 < CommonClass.RrfLimit) kFuture.Value.nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kFuture.Value.oc < CommonClass.RrfLimit) kFuture.Value.oc = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (kFuture.Value.pm25 < CommonClass.RrfLimit) kFuture.Value.pm25 = Convert.ToSingle(CommonClass.RrfLimit);
                //            if (Double.IsNaN(kFuture.Value.salt) || kFuture.Value.salt < CommonClass.RrfLimit) kFuture.Value.salt = Convert.ToSingle(CommonClass.RrfLimit);
                //        }

                //        foreach (KeyValuePair<string, PMPoint> kQ in k.Value.dicQuarterlyPoint)
                //        {
                //            #region
                //            #region rrf and species values except for nh4,pbw
                //            pmPoint.rrfCrustal = CommonClass.ToFixed(dicAmFuture[kQ.Key].crustal / dicAmBaseline[kQ.Key].crustal, 4);
                //            pmPoint.fCrustalMass = kQ.Value.bCrustalMass * pmPoint.rrfCrustal;
                //            pmPoint.rrfEC = CommonClass.ToFixed(dicAmFuture[kQ.Key].ec / dicAmBaseline[kQ.Key].ec, 4);
                //            pmPoint.fECMass = kQ.Value.bECMass * pmPoint.rrfEC;
                //            pmPoint.rrfNO3 = CommonClass.ToFixed(dicAmFuture[kQ.Key].no3 / dicAmBaseline[kQ.Key].no3, 4);
                //            pmPoint.fNO3Mass = kQ.Value.bNO3Mass * pmPoint.rrfNO3;
                //            pmPoint.rrfOC = CommonClass.ToFixed(dicAmFuture[kQ.Key].oc / dicAmBaseline[kQ.Key].oc, 4);
                //            pmPoint.fOcmbMass = kQ.Value.bOcmbMass * pmPoint.rrfOC;
                //            pmPoint.rrfSO4 = CommonClass.ToFixed(dicAmFuture[kQ.Key].so4 / dicAmBaseline[kQ.Key].so4, 4);
                //            pmPoint.fSO4Mass = kQ.Value.bSO4Mass * pmPoint.rrfSO4;
                //            pmPoint.rrfSalt = CommonClass.ToFixed(dicAmFuture[kQ.Key].salt / dicAmBaseline[kQ.Key].salt, 4);
                //            pmPoint.fSaltMass = kQ.Value.bSaltMass * pmPoint.rrfSalt;
                //            pmPoint.rrfNH4 = Math.Round(dicAmFuture[kQ.Key].nh4 / dicAmBaseline[kQ.Key].nh4, 4);
                //            #endregion
                //            //----------nh4-----------------
                //            #region nh4
                //            if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromDON)
                //            {
                //                pmPoint.fNH4Mass = kQ.Value.bDON * pmPoint.fSO4Mass + 0.29 * pmPoint.fNO3Mass;
                //            }
                //            else if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromRRF)
                //            {
                //                pmPoint.fNH4Mass = kQ.Value.bNH4Mass * pmPoint.rrfNH4;
                //            }
                //            #endregion
                //            //----------pbw--------------
                //            #region calculate PBW
                //            CommonClass.CalculationWater(pmPoint.fSO4Mass, pmPoint.fNO3Mass, pmPoint.fNH4Mass, kQ.Value.bDON, ref  pmPoint.fWaterMass);
                //            pmPoint.rrfWater = Math.Round(pmPoint.fWaterMass / kQ.Value.bWaterMass, 4);
                //            #endregion
                //            pmPoint.fPMDV = pmPoint.fSO4Mass + pmPoint.fNO3Mass + pmPoint.fOcmbMass + pmPoint.fECMass + pmPoint.fCrustalMass + pmPoint.fNH4Mass + pmPoint.fWaterMass + pmPoint.fSaltMass + Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass);
                //            #endregion

                //            kQ.Value.rrfCrustal = pmPoint.rrfCrustal;
                //            kQ.Value.fCrustalMass = pmPoint.fCrustalMass;
                //            kQ.Value.rrfEC = pmPoint.rrfEC;
                //            kQ.Value.fECMass = pmPoint.fECMass;
                //            kQ.Value.rrfNO3 = pmPoint.rrfNO3;
                //            kQ.Value.fNO3Mass = pmPoint.fNO3Mass;
                //            kQ.Value.rrfOC = pmPoint.rrfOC;
                //            kQ.Value.fOcmbMass = pmPoint.fOcmbMass;
                //            kQ.Value.rrfSO4 = pmPoint.rrfSO4;
                //            kQ.Value.fSO4Mass = pmPoint.fSO4Mass;
                //            kQ.Value.rrfSalt = pmPoint.rrfSalt;
                //            kQ.Value.fSaltMass = pmPoint.fSaltMass;
                //            kQ.Value.fNH4Mass = pmPoint.fNH4Mass;
                //            kQ.Value.rrfNH4 = pmPoint.rrfNH4;
                //            kQ.Value.fWaterMass = pmPoint.fWaterMass;
                //            kQ.Value.rrfWater = pmPoint.rrfWater;
                //            kQ.Value.fPMDV = pmPoint.fPMDV;
                //            #region dv periods
                //            if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                //            {
                //                //---------------保存所有的periods--------------
                //                for (int i = 0; i < lstQuarterlyPointPeriod.Count; i++)
                //                {
                //                    if (!lstQuarterlyPointPeriod[i].ContainsKey(k.Key)) continue;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfCrustal = pmPoint.rrfCrustal;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfCrustal = pmPoint.rrfCrustal;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fCrustalMass = pmPoint.fCrustalMass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfEC = pmPoint.rrfEC;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fECMass = pmPoint.fECMass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfNO3 = pmPoint.rrfNO3;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fNO3Mass = pmPoint.fNO3Mass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfOC = pmPoint.rrfOC;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fOcmbMass = pmPoint.fOcmbMass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfSO4 = pmPoint.rrfSO4;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fSO4Mass = pmPoint.fSO4Mass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfSalt = pmPoint.rrfSalt;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fSaltMass = pmPoint.fSaltMass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fNH4Mass = pmPoint.fNH4Mass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfNH4 = pmPoint.rrfNH4;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fWaterMass = pmPoint.fWaterMass;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].rrfWater = pmPoint.rrfWater;
                //                    lstQuarterlyPointPeriod[i][k.Key].dicQuarterlyPoint[kQ.Key].fPMDV = pmPoint.fPMDV;
                //                }
                //            }
                //            #endregion
                //        }
                //    }
                //    #endregion
                //}
                ////if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFilePoint)
                ////{
                ////    SaveQuarterlyPMPoint(CommonClass.CurrentBaseScenario, dicQuarterlyPMPoint, "");
                ////    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                ////    {
                ////        for (int i = 0; i < lstQuarterlyPointPeriod.Count(); i++)
                ////        {
                ////            SaveQuarterlyPMPoint(CommonClass.CurrentBaseScenario, lstQuarterlyPointPeriod[i], " Period " + (i + 1).ToString());
                ////        }
                ////    }
                ////}
                ////if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doUsedQuarterlyAvgModelData)
                ////{
                ////    SaveUsedModelDataQuarterly(CommonClass.CurrentBaseScenario, dicQuarterlyModelDataPM, baseModelYear, futureModelYear, lstUsedModelData);
                ////}
                //lstUsedModelData.Clear();
                //GC.Collect();
                //#endregion
                //#region annual pm point
                //Dictionary<string, PMPoint> dicAnnualPMPoint = new Dictionary<string, PMPoint>();
                //foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlyPMPoint)
                //{
                //    dicAnnualPMPoint.Add(k.Key, new PMPoint()
                //    {
                //        id = k.Value.id,
                //        type = k.Value.type,
                //        stateName = k.Value.stateName,
                //        countyName = k.Value.countyName,
                //        monitorLat = k.Value.latitude,
                //        monitorLong = k.Value.longitude,
                //        monitorGridcell = k.Value.gridcell,
                //        bPMDV = k.Value.dicQuarterlyPoint.Select(p => p.Value.bPMDV).Average(),
                //        fPMDV = k.Value.dicQuarterlyPoint.Select(p => p.Value.fPMDV).Average(),
                //        bCrustalMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bCrustalMass).Average(),
                //        bECMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bECMass).Average(),
                //        bNH4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bNH4Mass).Average(),
                //        bNO3Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bNO3Mass).Average(),
                //        bOcmbMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bOcmbMass).Average(),
                //        bSaltMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bSaltMass).Average(),
                //        bSO4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bSO4Mass).Average(),
                //        bWaterMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bWaterMass).Average(),
                //        fCrustalMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fCrustalMass).Average(),
                //        fECMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fECMass).Average(),
                //        fNH4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fNH4Mass).Average(),
                //        fNO3Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fNO3Mass).Average(),
                //        fOcmbMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fOcmbMass).Average(),
                //        fSaltMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fSaltMass).Average(),
                //        fSO4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fSO4Mass).Average(),
                //        fWaterMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fWaterMass).Average(),
                //    });
                //    dicAnnualPMPoint[k.Key].rrfCrustal = Double.IsNaN(dicAnnualPMPoint[k.Key].fCrustalMass / dicAnnualPMPoint[k.Key].bCrustalMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fCrustalMass / dicAnnualPMPoint[k.Key].bCrustalMass) ? -9 : dicAnnualPMPoint[k.Key].fCrustalMass / dicAnnualPMPoint[k.Key].bCrustalMass;
                //    dicAnnualPMPoint[k.Key].rrfEC = Double.IsNaN(dicAnnualPMPoint[k.Key].fECMass / dicAnnualPMPoint[k.Key].bECMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fECMass / dicAnnualPMPoint[k.Key].bECMass) ? -9 : dicAnnualPMPoint[k.Key].fECMass / dicAnnualPMPoint[k.Key].bECMass;
                //    dicAnnualPMPoint[k.Key].rrfNH4 = Double.IsNaN(dicAnnualPMPoint[k.Key].fNH4Mass / dicAnnualPMPoint[k.Key].bNH4Mass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fNH4Mass / dicAnnualPMPoint[k.Key].bNH4Mass) ? -9 : dicAnnualPMPoint[k.Key].fNH4Mass / dicAnnualPMPoint[k.Key].bNH4Mass;
                //    dicAnnualPMPoint[k.Key].rrfNO3 = Double.IsNaN(dicAnnualPMPoint[k.Key].fNO3Mass / dicAnnualPMPoint[k.Key].bNO3Mass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fNO3Mass / dicAnnualPMPoint[k.Key].bNO3Mass) ? -9 : dicAnnualPMPoint[k.Key].fNO3Mass / dicAnnualPMPoint[k.Key].bNO3Mass;
                //    dicAnnualPMPoint[k.Key].rrfOC = Double.IsNaN(dicAnnualPMPoint[k.Key].fOcmbMass / dicAnnualPMPoint[k.Key].bOcmbMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fOcmbMass / dicAnnualPMPoint[k.Key].bOcmbMass) ? -9 : dicAnnualPMPoint[k.Key].fOcmbMass / dicAnnualPMPoint[k.Key].bOcmbMass;
                //    dicAnnualPMPoint[k.Key].rrfSalt = Double.IsNaN(dicAnnualPMPoint[k.Key].fSaltMass / dicAnnualPMPoint[k.Key].bSaltMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fSaltMass / dicAnnualPMPoint[k.Key].bSaltMass) ? -9 : dicAnnualPMPoint[k.Key].fSaltMass / dicAnnualPMPoint[k.Key].bSaltMass;
                //    dicAnnualPMPoint[k.Key].rrfSO4 = Double.IsNaN(dicAnnualPMPoint[k.Key].fSO4Mass / dicAnnualPMPoint[k.Key].bSO4Mass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fSO4Mass / dicAnnualPMPoint[k.Key].bSO4Mass) ? -9 : dicAnnualPMPoint[k.Key].fSO4Mass / dicAnnualPMPoint[k.Key].bSO4Mass;
                //    dicAnnualPMPoint[k.Key].rrfWater = Double.IsNaN(dicAnnualPMPoint[k.Key].fWaterMass / dicAnnualPMPoint[k.Key].bWaterMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fWaterMass / dicAnnualPMPoint[k.Key].bWaterMass) ? -9 : dicAnnualPMPoint[k.Key].fWaterMass / dicAnnualPMPoint[k.Key].bWaterMass;
                //}
                //dicQuarterlyPMPoint.Clear();
                //GC.Collect();
                //List<Dictionary<string, PMPoint>> lstAnnualPointPeriod = new List<Dictionary<string, PMPoint>>();
                //#region dv period
                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                //{
                //    for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                //    {
                //        lstAnnualPointPeriod.Add(new Dictionary<string, PMPoint>());
                //    }
                //    #region
                //    for (int i = 0; i < lstQuarterlyPointPeriod.Count; i++)
                //    {
                //        foreach (KeyValuePair<string, PMMonitorOutput> k in lstQuarterlyPointPeriod[i])
                //        {
                //            lstAnnualPointPeriod[i].Add(k.Key, new PMPoint()
                //            {
                //                id = k.Value.id,
                //                type = k.Value.type,
                //                stateName = k.Value.stateName,
                //                countyName = k.Value.countyName,
                //                monitorLat = k.Value.latitude,
                //                monitorLong = k.Value.longitude,
                //                monitorGridcell = k.Value.gridcell,
                //                bPMDV = k.Value.dicQuarterlyPoint.Select(p => p.Value.bPMDV).Average(),
                //                fPMDV = k.Value.dicQuarterlyPoint.Select(p => p.Value.fPMDV).Average(),
                //                bCrustalMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bCrustalMass).Average(),
                //                bECMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bECMass).Average(),
                //                bNH4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bNH4Mass).Average(),
                //                bNO3Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bNO3Mass).Average(),
                //                bOcmbMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bOcmbMass).Average(),
                //                bSaltMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bSaltMass).Average(),
                //                bSO4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bSO4Mass).Average(),
                //                bWaterMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.bWaterMass).Average(),
                //                fCrustalMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fCrustalMass).Average(),
                //                fECMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fECMass).Average(),
                //                fNH4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fNH4Mass).Average(),
                //                fNO3Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fNO3Mass).Average(),
                //                fOcmbMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fOcmbMass).Average(),
                //                fSaltMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fSaltMass).Average(),
                //                fSO4Mass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fSO4Mass).Average(),
                //                fWaterMass = k.Value.dicQuarterlyPoint.Select(p => p.Value.fWaterMass).Average(),
                //            });
                //            lstAnnualPointPeriod[i][k.Key].rrfCrustal = Double.IsNaN(dicAnnualPMPoint[k.Key].fCrustalMass / dicAnnualPMPoint[k.Key].bCrustalMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fCrustalMass / dicAnnualPMPoint[k.Key].bCrustalMass) ? -9 : dicAnnualPMPoint[k.Key].fCrustalMass / dicAnnualPMPoint[k.Key].bCrustalMass;
                //            lstAnnualPointPeriod[i][k.Key].rrfEC = Double.IsNaN(dicAnnualPMPoint[k.Key].fECMass / dicAnnualPMPoint[k.Key].bECMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fECMass / dicAnnualPMPoint[k.Key].bECMass) ? -9 : dicAnnualPMPoint[k.Key].fECMass / dicAnnualPMPoint[k.Key].bECMass;
                //            lstAnnualPointPeriod[i][k.Key].rrfNH4 = Double.IsNaN(dicAnnualPMPoint[k.Key].fNH4Mass / dicAnnualPMPoint[k.Key].bNH4Mass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fNH4Mass / dicAnnualPMPoint[k.Key].bNH4Mass) ? -9 : dicAnnualPMPoint[k.Key].fNH4Mass / dicAnnualPMPoint[k.Key].bNH4Mass;
                //            lstAnnualPointPeriod[i][k.Key].rrfNO3 = Double.IsNaN(dicAnnualPMPoint[k.Key].fNO3Mass / dicAnnualPMPoint[k.Key].bNO3Mass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fNO3Mass / dicAnnualPMPoint[k.Key].bNO3Mass) ? -9 : dicAnnualPMPoint[k.Key].fNO3Mass / dicAnnualPMPoint[k.Key].bNO3Mass;
                //            lstAnnualPointPeriod[i][k.Key].rrfOC = Double.IsNaN(dicAnnualPMPoint[k.Key].fOcmbMass / dicAnnualPMPoint[k.Key].bOcmbMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fOcmbMass / dicAnnualPMPoint[k.Key].bOcmbMass) ? -9 : dicAnnualPMPoint[k.Key].fOcmbMass / dicAnnualPMPoint[k.Key].bOcmbMass;
                //            lstAnnualPointPeriod[i][k.Key].rrfSalt = Double.IsNaN(dicAnnualPMPoint[k.Key].fSaltMass / dicAnnualPMPoint[k.Key].bSaltMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fSaltMass / dicAnnualPMPoint[k.Key].bSaltMass) ? -9 : dicAnnualPMPoint[k.Key].fSaltMass / dicAnnualPMPoint[k.Key].bSaltMass;
                //            lstAnnualPointPeriod[i][k.Key].rrfSO4 = Double.IsNaN(dicAnnualPMPoint[k.Key].fSO4Mass / dicAnnualPMPoint[k.Key].bSO4Mass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fSO4Mass / dicAnnualPMPoint[k.Key].bSO4Mass) ? -9 : dicAnnualPMPoint[k.Key].fSO4Mass / dicAnnualPMPoint[k.Key].bSO4Mass;
                //            lstAnnualPointPeriod[i][k.Key].rrfWater = Double.IsNaN(dicAnnualPMPoint[k.Key].fWaterMass / dicAnnualPMPoint[k.Key].bWaterMass) || Double.IsInfinity(dicAnnualPMPoint[k.Key].fWaterMass / dicAnnualPMPoint[k.Key].bWaterMass) ? -9 : dicAnnualPMPoint[k.Key].fWaterMass / dicAnnualPMPoint[k.Key].bWaterMass;
                //        }
                //    }
                //    #endregion
                //}
                //lstQuarterlyPointPeriod.Clear();
                //GC.Collect();
                //#endregion
                //#endregion
                ////if (annualPMAnalysisConfiguration.chooseDesiredOutputA.doStandardAnalysis)
                ////{
                ////    SaveAnnualPMPoint(CommonClass.CurrentBaseScenario, dicAnnualPMPoint, "");
                ////    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                ////    {
                ////        for (int i = 0; i < lstAnnualPointPeriod.Count; i++)
                ////        {
                ////            SaveAnnualPMPoint(CommonClass.CurrentBaseScenario, lstAnnualPointPeriod[i], " Period " + (i + 1).ToString());
                ////        }
                ////    }
                ////}

                ////if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doHighCountySites)
                ////{
                ////    SaveHighCountyPoint(CommonClass.CurrentBaseScenario, dicAnnualPMPoint, "");
                ////    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                ////    {
                ////        for (int i = 0; i < lstAnnualPointPeriod.Count; i++)
                ////        {
                ////            SaveHighCountyPoint(CommonClass.CurrentBaseScenario, lstAnnualPointPeriod[i], " Period " + (i + 1).ToString());
                ////        }
                ////    }
                ////}
                //dicAnnualPMPoint.Clear();
                //lstAnnualPointPeriod.Clear();
                GC.Collect();
                #endregion
                //_endTime = DateTime.Now;
                //CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Finish computing RRF: " + CommonClass.TotalTime + " s.");
                //CommonClass.CurrentLog = "Finish computing RRF: " + CommonClass.TotalTime + " s.";
                #endregion

                //CommonClass.CurrentBaseScenario.log.lstLog.Add("Begin interpolation to spatial field.");
                //CommonClass.CurrentLog = "Begin interpolation to spatial field...";
                _beginTime = DateTime.Now;
                #region Spatial Field
                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA
                //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA
                //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj
                //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doNeighborFileSpatial || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial
                //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial_GraAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial
                //    || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj)
                {
                    Dictionary<string, PMMonitorOutput> dicQuarterlySpatialField = new Dictionary<string, PMMonitorOutput>();
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpecFracSpatial)
                    {
                        dicQuarterlySpatialField.Add(k.Key, new PMMonitorOutput()
                        {
                            id = k.Key,
                            latitude = k.Value.latitude,
                            longitude = k.Value.longitude,
                        });
                        double nonBlankMass = 0;
                        #region VNA
                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial)
                        if(annualPMAnalysisConfiguration.monitorInput.useVNA)
                        {
                            dicQuarterlySpatialField[k.Key].dicQuarterlySpatial = new Dictionary<string, PMSpatial>();
                            foreach (KeyValuePair<string, SpecFracPM> kQ in k.Value.dicSpecFracSpatial)
                            {
                                nonBlankMass = kQ.Value.pm25MassFrac - kQ.Value.blankMass;
                                dicQuarterlySpatialField[k.Key].dicQuarterlySpatial.Add(kQ.Key, new PMSpatial()
                                {
                                    bPMAnnDV = Convert.ToSingle(kQ.Value.pm25MassFrac),
                                    bBlankMass = Convert.ToSingle(kQ.Value.blankMass),
                                    bCrustalMass = Convert.ToSingle(kQ.Value.fCr * nonBlankMass),
                                    bECMass = Convert.ToSingle(kQ.Value.fEC * nonBlankMass),
                                    bNH4Mass = Convert.ToSingle(kQ.Value.fNH4 * nonBlankMass),
                                    bOcmbMass = Convert.ToSingle(kQ.Value.fOcm * nonBlankMass),
                                    bSO4Mass = Convert.ToSingle(kQ.Value.fSO4 * nonBlankMass),
                                    bNO3rMass = Convert.ToSingle(kQ.Value.fNO3r * nonBlankMass),
                                    bWaterMass = Convert.ToSingle(kQ.Value.fWater * nonBlankMass),
                                    bSaltMass = Convert.ToSingle(kQ.Value.fSalt * nonBlankMass),
                                    bDON = Convert.ToSingle(kQ.Value.don),
                                    fBlankMass = Convert.ToSingle(kQ.Value.blankMass),
                                });
                                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA)
                                {
                                    //----------判断是否满足最小值要求------------------
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt = Convert.ToSingle(CommonClass.RrfLimit);

                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt = Convert.ToSingle(CommonClass.RrfLimit);

                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfCrustal = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfEC = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfNH4 = Math.Round(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfOC = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfSO4 = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfNO3 = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfSalt = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt, 4);

                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fCrustalMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfCrustal * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bCrustalMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fECMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfEC * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bECMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fOcmbMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfOC * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bOcmbMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fSO4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfSO4 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bSO4Mass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNO3Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfNO3 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bNO3rMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fSaltMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfSalt * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bSaltMass);
                                    //-----对于future NH4的计算需要另外计算------------
                                    #region NH4
                                    //if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromRRF)
                                    //{
                                        //dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNH4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfNH4 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bNH4Mass);
                                    //}
                                    //else if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromDON)
                                    //{
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNH4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bDON * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fSO4Mass + 0.29 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNO3Mass);
                                    //}
                                    #endregion
                                    #region future pbw
                                    double water = 0;
                                    CommonClass.CalculationWater(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fSO4Mass, dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNO3Mass,
                                                                 dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNH4Mass, dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bDON,
                                                                 ref water);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fWaterMass = double.IsNaN(water) ? 0 : Convert.ToSingle(water);
                                    #endregion
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].rrfWaterMass = Double.IsNaN(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fWaterMass / dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bWaterMass) ? 0 : Math.Round(dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fWaterMass / dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].bWaterMass, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fPMAnnDV = dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fCrustalMass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fECMass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fOcmbMass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fSaltMass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fSO4Mass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNO3Mass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fNH4Mass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fWaterMass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatial[kQ.Key].fBlankMass;
                                }
                            }
                        }
                        #endregion

                        #region EVNA
                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doSpeciesFractionSpatial_GraAdj)
                        if(annualPMAnalysisConfiguration.monitorInput.useEVNA)
                        {
                            dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted = new Dictionary<string, PMSpatial>();
                            foreach (KeyValuePair<string, SpecFracPM> kQ in k.Value.dicSpecFracSpatialGradAdj)
                            {
                                nonBlankMass = kQ.Value.pm25MassFrac - kQ.Value.blankMass;
                                dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted.Add(kQ.Key, new PMSpatial()
                                {
                                    bPMAnnDV = Convert.ToSingle(kQ.Value.pm25MassFrac),
                                    bBlankMass = Convert.ToSingle(kQ.Value.blankMass),
                                    bCrustalMass = Convert.ToSingle(kQ.Value.fCr * nonBlankMass),
                                    bECMass = Convert.ToSingle(kQ.Value.fEC * nonBlankMass),
                                    bNH4Mass = Convert.ToSingle(kQ.Value.fNH4 * nonBlankMass),
                                    bOcmbMass = Convert.ToSingle(kQ.Value.fOcm * nonBlankMass),
                                    bSO4Mass = Convert.ToSingle(kQ.Value.fSO4 * nonBlankMass),
                                    bNO3rMass = Convert.ToSingle(kQ.Value.fNO3r * nonBlankMass),
                                    bWaterMass = Convert.ToSingle(kQ.Value.fWater * nonBlankMass),
                                    bSaltMass = Convert.ToSingle(kQ.Value.fSalt * nonBlankMass),
                                    bDON = Convert.ToSingle(kQ.Value.don),
                                    fBlankMass = Convert.ToSingle(kQ.Value.blankMass),
                                });
                                //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna)
                                {
                                    //------------判断是否满足最小值要求-----------
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt = Convert.ToSingle(CommonClass.RrfLimit);

                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 = Convert.ToSingle(CommonClass.RrfLimit);
                                    if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt < CommonClass.RrfLimit) dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt = Convert.ToSingle(CommonClass.RrfLimit);

                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfCrustal = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfEC = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfNH4 = Math.Round(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfOC = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfSO4 = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfNO3 = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfSalt = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt, 4);

                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fCrustalMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfCrustal * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bCrustalMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fECMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfEC * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bECMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fOcmbMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfOC * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bOcmbMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fSO4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfSO4 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bSO4Mass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNO3Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfNO3 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bNO3rMass);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fSaltMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfSalt * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bSaltMass);
                                    //-----对于future NH4的计算需要另外计算------------
                                    #region NH4
                                    //if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromRRF)
                                    //{
                                    //    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNH4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfNH4 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bNH4Mass);
                                    //}
                                    //else if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromDON)
                                    //{
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNH4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bDON * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fSO4Mass + 0.29 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNO3Mass);
                                    //}
                                    #endregion
                                    #region future pbw
                                    double water = 0;
                                    CommonClass.CalculationWater(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fSO4Mass, dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNO3Mass,
                                                                 dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNH4Mass, dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bDON,
                                                                 ref water);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fWaterMass = double.IsNaN(water) ? 0 : Convert.ToSingle(water);
                                    #endregion
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].rrfWaterMass = Double.IsNaN(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fWaterMass / dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bWaterMass) ? 0 : Math.Round(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fWaterMass / dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].bWaterMass, 4);
                                    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fPMAnnDV = dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fCrustalMass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fECMass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fOcmbMass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fSaltMass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fSO4Mass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNO3Mass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fNH4Mass
                                                                                                               + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fWaterMass + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialGradientAdjusted[kQ.Key].fBlankMass;
                                }
                            }

                        }
                        #endregion

                        #region DS
                        if (annualPMAnalysisConfiguration.monitorInput.doDownscaler)
                        {
                            dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS = new Dictionary<string, PMSpatial>();
                            foreach (KeyValuePair<string, SpecFracPM> kQ in k.Value.dicSpecFracSpatialDS)
                            {
                                nonBlankMass = kQ.Value.pm25MassFrac - kQ.Value.blankMass;
                                dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS.Add(kQ.Key, new PMSpatial()
                                {
                                    bPMAnnDV = Convert.ToSingle(kQ.Value.pm25MassFrac),
                                    bBlankMass = Convert.ToSingle(kQ.Value.blankMass),
                                    bCrustalMass = Convert.ToSingle(kQ.Value.fCr * nonBlankMass),
                                    bECMass = Convert.ToSingle(kQ.Value.fEC * nonBlankMass),
                                    bNH4Mass = Convert.ToSingle(kQ.Value.fNH4 * nonBlankMass),
                                    bOcmbMass = Convert.ToSingle(kQ.Value.fOcm * nonBlankMass),
                                    bSO4Mass = Convert.ToSingle(kQ.Value.fSO4 * nonBlankMass),
                                    bNO3rMass = Convert.ToSingle(kQ.Value.fNO3r * nonBlankMass),
                                    bWaterMass = Convert.ToSingle(kQ.Value.fWater * nonBlankMass),
                                    bSaltMass = Convert.ToSingle(kQ.Value.fSalt * nonBlankMass),
                                    bDON = Convert.ToSingle(kQ.Value.don),
                                    fBlankMass = Convert.ToSingle(kQ.Value.blankMass),
                                });
                                if (annualPMAnalysisConfiguration.monitorInput.doDownscaler)
                                {
                                    try
                                    {


                                        //------------判断是否满足最小值要求-----------
                                        if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4 < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4 < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4 = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3 < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3 = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt = Convert.ToSingle(CommonClass.RrfLimit);

                                        if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 = Convert.ToSingle(CommonClass.RrfLimit);
                                        if (dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt < CommonClass.RrfLimit)
                                            dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt = Convert.ToSingle(CommonClass.RrfLimit);

                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfCrustal = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].crustal / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].crustal, 4);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfEC = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].ec / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].ec, 4);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfNH4 = Math.Round(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].nh4 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].nh4, 4);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfOC = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].oc / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].oc, 4);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfSO4 = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].so4 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].so4, 4);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfNO3 = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].no3 / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].no3, 4);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfSalt = CommonClass.ToFixed(dicQuarterlyModelDataPM[k.Key].dicFutureModel[kQ.Key].salt / dicQuarterlyModelDataPM[k.Key].dicBaselineModel[kQ.Key].salt, 4);

                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fCrustalMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfCrustal * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bCrustalMass);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fECMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfEC * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bECMass);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fOcmbMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfOC * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bOcmbMass);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fSO4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfSO4 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bSO4Mass);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNO3Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfNO3 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bNO3rMass);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fSaltMass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfSalt * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bSaltMass);
                                        //-----对于future NH4的计算需要另外计算------------
                                        #region NH4
                                        //if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromRRF)
                                        //{
                                        //    dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNH4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfNH4 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bNH4Mass);
                                        //}
                                        //else if (annualPMAnalysisConfiguration.pm25CalculationOptionsA.doCalcNH4fromDON)
                                        //{
                                            dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNH4Mass = Convert.ToSingle(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bDON * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fSO4Mass + 0.29 * dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNO3Mass);
                                        //}
                                        #endregion
                                        #region future pbw
                                        double water = 0;
                                        CommonClass.CalculationWater(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fSO4Mass, dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNO3Mass,
                                                                     dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNH4Mass, dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bDON,
                                                                     ref water);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fWaterMass = double.IsNaN(water) ? 0 : Convert.ToSingle(water);
                                        #endregion
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].rrfWaterMass = Double.IsNaN(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fWaterMass / dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bWaterMass) ? 0 : Math.Round(dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fWaterMass / dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].bWaterMass, 4);
                                        dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fPMAnnDV =
                                              dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fCrustalMass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fECMass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fOcmbMass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fSaltMass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fSO4Mass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNO3Mass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fNH4Mass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fWaterMass
                                            + dicQuarterlySpatialField[k.Key].dicQuarterlySpatialDS[kQ.Key].fBlankMass;

                                    }
                                    catch (Exception)
                                    {

                                    }
                                }
                            }

                        }
                        #endregion
                    }
                    dicQuarterlyModelDataPM.Clear();
                    GC.Collect();
                    dicSpecFracSpatial.Clear();
                    GC.Collect();

                    double[] dConvertArraySpatial = null;
                    List<double> lstConvertArraySpatial = new List<double>();
                    List<string> lstKeySpatial = dicQuarterlySpatialField.Keys.ToList();
                    for (int iLstKey = 0; iLstKey < dicQuarterlySpatialField.Keys.Count; iLstKey++)
                    {
                        lstConvertArraySpatial.Add(dicQuarterlySpatialField[lstKeySpatial[iLstKey]].longitude);
                        lstConvertArraySpatial.Add(dicQuarterlySpatialField[lstKeySpatial[iLstKey]].latitude);
                    }
                    dConvertArraySpatial = lstConvertArraySpatial.ToArray();
                    DotSpatial.Projections.Reproject.ReprojectPoints(dConvertArraySpatial, null, DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984,
                       DotSpatial.Projections.ProjectionInfo.FromProj4String(CommonClass.projUSACMAQ), 0, dConvertArraySpatial.Length / 2);
                    for (int iLstKey = 0; iLstKey < dicQuarterlySpatialField.Keys.Count; iLstKey++)
                    {
                        dicQuarterlySpatialField[lstKeySpatial[iLstKey]].longitudeLamber = dConvertArraySpatial[2 * iLstKey] / 100.00;
                        dicQuarterlySpatialField[lstKeySpatial[iLstKey]].latitudeLamber = dConvertArraySpatial[2 * iLstKey + 1] / 100.00;
                    }

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

                    foreach (IFeature f in fs.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 (KeyValuePair<string, PMMonitorOutput> kv in dicQuarterlySpatialField)
                    {
                        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.Key, 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.Key, new int[2] { v.Value[0], v.Value[1] });
                        }
                    }


                    #endregion

                    #region save files
                    //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA)
                    if(annualPMAnalysisConfiguration.monitorInput.useVNA)
                    {
                        SaveAnnualPointSpatialField(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, dicColRow);
                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                        //{
                        //    for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                        //    {
                        //        SaveAnnualPointSpatialField(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, " Period " + (i + 1).ToString());
                        //    }
                        //}
                    }

                    //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial)
                    //{
                    //    SaveQuarterlySpatialField(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, "");
                    //    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                    //    {
                    //        for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                    //        {
                    //            SaveQuarterlySpatialField(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, " Period " + (i + 1).ToString());
                    //        }
                    //    }
                    //}

                    //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doQuarterlyAvgFileSpatial_GraAdj)
                    //{
                    //    SaveQuarterlySpatialFieldGradAdj(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, "");
                    //    if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                    //    {
                    //        for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                    //        {
                    //            SaveQuarterlySpatialFieldGradAdj(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, " Period " + (i + 1).ToString());
                    //        }
                    //    }
                    //}

                    //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna)
                    if(annualPMAnalysisConfiguration.monitorInput.useEVNA)
                    {
                        SaveAnnualPointSpatialFieldGradAdj(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, dicColRow);
                        //if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                        //{
                        //    for (int i = 0; i < dicDesignValluePeriods.Count; i++)
                        //    {
                        //        SaveAnnualPointSpatialFieldGradAdj(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, " Period " + (i + 1).ToString());
                        //    }
                        //}
                    }
                    #endregion
                    if (annualPMAnalysisConfiguration.monitorInput.doDownscaler)
                    {
                        SaveAnnualPointSpatialFieldDS(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, dicColRow);
                    }
                    SaveDeltaAnnualPointSpatialField(CommonClass.CurrentBaseScenario, dicQuarterlySpatialField, dicColRow);


                    dicQuarterlySpatialField.Clear();
                    GC.Collect();
                }
                #endregion
                _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.";
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        #region Get input files
        public static bool GetNeighborFilePointFromSMAT_CE(AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref Dictionary<string, NeighborFileClass> dicNeighborFileFromSMAT_CE)
        {
            try
            {
                //string dataType = "";
                //DataTable dtNeighborFilePoint = CommonClass.getDataSetFromCSVAndFirstLine(@"D:\Annual neighbor file point\Annual PM25-1021 Neighbor File Point.csv", ref dataType);
                int iID = -1, iStateName = -1, iCountyName = -1, iMonitorLong = -1, iMonitorLat = -1, iMonitorGridcell = -1, iDate = -1, iNeighbor = -1, iNeighborGridcell = -1, iDistance = -1, iWeightDistance = -1, iWeightDistanceSquared = -1, iPollutant = -1;
                FileStream fs = new FileStream(@"D:\Annual neighbor file\Annual PM25-1021 Neighbor File Point.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    string strLine = csv.ReadLine();
                    string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                    int i = 0;
                    //------------获取各个字段的index------------
                    #region
                    while (i < strLineArray.Length)
                    {
                        string s = strLineArray[i];
                        switch (s.Trim().ToLower().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_state_name":
                                iStateName = i;
                                break;
                            case "_county_name":
                                iCountyName = i;
                                break;
                            case "monitor_long":
                                iMonitorLong = i;
                                break;
                            case "monitor_lat":
                                iMonitorLat = i;
                                break;
                            case "monitor_gridcell":
                                iMonitorGridcell = i;
                                break;
                            case "quarter":
                                iDate = i;
                                break;
                            case "neighbor":
                                iNeighbor = i;
                                break;
                            case "neighbor_gridcell":
                                iNeighborGridcell = i;
                                break;
                            case "distance":
                                iDistance = i;
                                break;
                            case "weightdistance":
                                iWeightDistance = i;
                                break;
                            case "weightdistancesquared":
                                iWeightDistanceSquared = i;
                                break;
                            case "pollutant":
                                iPollutant = i;
                                break;
                        }
                        i++;
                    }
                    #endregion
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        strLineArray = strLine.Split(new char[] { ',' });
                        if (dicNeighborFileFromSMAT_CE.ContainsKey(strLineArray[iID].ToString().Replace("\"", "")))
                        {
                            if (dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint.ContainsKey(strLineArray[iDate].ToString().Replace("\"", "")))
                            {
                                if (dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")].ContainsKey(strLineArray[iNeighbor].ToString().Replace("\"", "")))
                                {
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iNeighbor].ToString().Replace("\"", "")].neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", "");
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iNeighbor].ToString().Replace("\"", "")].distance = Convert.ToDouble(strLineArray[iDistance]);
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iNeighbor].ToString().Replace("\"", "")].weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]);
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iNeighbor].ToString().Replace("\"", "")].weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]);
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iNeighbor].ToString().Replace("\"", "")].lstPollutant.Add(strLineArray[iPollutant].ToString().Replace("\"", ""));
                                }
                                else
                                {
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")].Add(strLineArray[iNeighbor].ToString().Replace("\"", ""), new NeighborInfo()
                                    {
                                        // neighbor = strLineArray[iNeighbor].ToString().Replace("\"", ""),
                                        neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", ""),
                                        distance = Convert.ToDouble(strLineArray[iDistance]),
                                        weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]),
                                        weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]),
                                        //pollutant = strLineArray[iPollutant].ToString().Replace("\"", ""),
                                        lstPollutant = new List<string>() { strLineArray[iPollutant].ToString().Replace("\"", "") },
                                    });
                                }
                            }
                            else
                            {
                                dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint.Add(strLineArray[iDate].ToString().Replace("\"", ""), new Dictionary<string, NeighborInfo>());
                                dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")].Add(strLineArray[iNeighbor].ToString().Replace("\"", ""), new NeighborInfo()

                                {
                                    //neighbor = strLineArray[iNeighbor].ToString().Replace("\"", ""),
                                    neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", ""),
                                    distance = Convert.ToDouble(strLineArray[iDistance]),
                                    weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]),
                                    weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]),
                                    lstPollutant = new List<string>() { strLineArray[iPollutant].ToString().Replace("\"", "") },
                                    //pollutant = strLineArray[iPollutant].ToString().Replace("\"", ""),
                                });
                            }
                        }
                        else
                        {
                            dicNeighborFileFromSMAT_CE.Add(strLineArray[iID].ToString().Replace("\"", ""), new NeighborFileClass()
                            {
                                id = strLineArray[iID].ToString().Replace("\"", ""),
                                stateName = strLineArray[iStateName].ToString().Replace("\"", ""),
                                countyName = strLineArray[iCountyName].ToString().Replace("\"", ""),
                                monitorLat = Convert.ToDouble(strLineArray[iMonitorLat].ToString().Replace("\"", "")),
                                monitorLong = Convert.ToDouble(strLineArray[iMonitorLong].ToString().Replace("\"", "")),
                                monitor_gridcell = strLineArray[iMonitorGridcell].ToString().Replace("\"", ""),
                                dicNeighborsPoint = new Dictionary<string, Dictionary<string, NeighborInfo>>(),
                            });
                            dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint.Add(strLineArray[iDate].ToString().Replace("\"", ""), new Dictionary<string, NeighborInfo>());
                            dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborsPoint[strLineArray[iDate].ToString().Replace("\"", "")].Add(strLineArray[iNeighbor].ToString().Replace("\"", ""), new NeighborInfo()
                            {
                                //neighbor = strLineArray[iNeighbor].ToString().Replace("\"", ""),
                                neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", ""),
                                distance = Convert.ToDouble(strLineArray[iDistance]),
                                weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]),
                                weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]),
                                lstPollutant = new List<string>() { strLineArray[iPollutant].ToString().Replace("\"", "") },
                                //pollutant = strLineArray[iPollutant].ToString().Replace("\"", ""),
                            });
                        }
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetNeighborFileSpatialFromSMAT_CE(ref Dictionary<string, NeighborFileClass> dicNeighborFileFromSMAT_CE)
        {
            try
            {
                int iID = -1, iGridcellLong = -1, iGridcellLat = -1, iDate = -1, iNeighbor = -1, iNeighborGridcell = -1, iDistance = -1, iWeightDistance = -1, iWeightDistanceSquared = -1, iPollutant = -1;
                FileStream fs = new FileStream(@"D:\Annual neighbor file\Annual PM25-1021 Neighbor File Spatial Field.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    string strLine = csv.ReadLine();
                    string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                    int i = 0;
                    //------------获取各个字段的index------------
                    #region
                    while (i < strLineArray.Length)
                    {
                        string s = strLineArray[i];
                        switch (s.Trim().ToLower().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "gridcell_long":
                                iGridcellLong = i;
                                break;
                            case "gridcell_lat":
                                iGridcellLat = i;
                                break;
                            case "quarter":
                                iDate = i;
                                break;
                            case "neighbor":
                                iNeighbor = i;
                                break;
                            case "neighbor_gridcell":
                                iNeighborGridcell = i;
                                break;
                            case "distance":
                                iDistance = i;
                                break;
                            case "weightdistance":
                                iWeightDistance = i;
                                break;
                            case "weightdistancesquared":
                                iWeightDistanceSquared = i;
                                break;
                            case "pollutant":
                                iPollutant = i;
                                break;
                        }
                        i++;
                    }
                    #endregion
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        strLineArray = strLine.Split(new char[] { ',' });
                        if (strLineArray[iID].ToString().Replace("\"", "") == "188119" ||
                             strLineArray[iID].ToString().Replace("\"", "") == "0188119")
                        { }
                        if (dicNeighborFileFromSMAT_CE.ContainsKey(strLineArray[iID].ToString().Replace("\"", "")))
                        {
                            if (dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField.ContainsKey(strLineArray[iDate].ToString().Replace("\"", "")))
                            {
                                if (dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")].ContainsKey(strLineArray[iPollutant].ToString().Replace("\"", "")))
                                {
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iPollutant].ToString().Replace("\"", "")].Add(strLineArray[iNeighbor].ToString().Replace("\"", ""), new NeighborInfo()
                                    {
                                        neighbor = strLineArray[iNeighbor].ToString().Replace("\"", ""),
                                        neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", ""),
                                        distance = Convert.ToDouble(strLineArray[iDistance]),
                                        weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]),
                                        weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]),
                                    });
                                }
                                else
                                {
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")].Add(strLineArray[iPollutant].ToString().Replace("\"", ""), new Dictionary<string, NeighborInfo>());
                                    dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iPollutant].ToString().Replace("\"", "")].Add(strLineArray[iNeighbor].ToString().Replace("\"", ""), new NeighborInfo()
                                    {
                                        neighbor = strLineArray[iNeighbor].ToString().Replace("\"", ""),
                                        neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", ""),
                                        distance = Convert.ToDouble(strLineArray[iDistance]),
                                        weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]),
                                        weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]),
                                    });
                                }
                            }
                            else
                            {
                                dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField.Add(strLineArray[iDate].ToString().Replace("\"", ""), new Dictionary<string, Dictionary<string, NeighborInfo>>());
                                dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")].Add(strLineArray[iPollutant].ToString().Replace("\"", ""), new Dictionary<string, NeighborInfo>());
                                dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iPollutant].ToString().Replace("\"", "")].Add(strLineArray[iNeighbor].ToString().Replace("\"", ""), new NeighborInfo()
                                {
                                    neighbor = strLineArray[iNeighbor].ToString().Replace("\"", ""),
                                    neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", ""),
                                    distance = Convert.ToDouble(strLineArray[iDistance]),
                                    weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]),
                                    weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]),
                                });
                            }
                        }
                        else
                        {
                            dicNeighborFileFromSMAT_CE.Add(strLineArray[iID].ToString().Replace("\"", ""), new NeighborFileClass()
                            {
                                id = strLineArray[iID].ToString().Replace("\"", ""),
                                monitorLat = Convert.ToDouble(strLineArray[iGridcellLat].ToString().Replace("\"", "")),
                                monitorLong = Convert.ToDouble(strLineArray[iGridcellLong].ToString().Replace("\"", "")),
                                dicNeighborSpatialField = new Dictionary<string, Dictionary<string, Dictionary<string, NeighborInfo>>>(),
                                //dicNeighborsPoint = new Dictionary<string, Dictionary<string, NeighborInfo>>(),
                            });
                            dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField.Add(strLineArray[iDate].ToString().Replace("\"", ""), new Dictionary<string, Dictionary<string, NeighborInfo>>());
                            dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")].Add(strLineArray[iPollutant].ToString().Replace("\"", ""), new Dictionary<string, NeighborInfo>());
                            dicNeighborFileFromSMAT_CE[strLineArray[iID].ToString().Replace("\"", "")].dicNeighborSpatialField[strLineArray[iDate].ToString().Replace("\"", "")][strLineArray[iPollutant].ToString().Replace("\"", "")].Add(strLineArray[iNeighbor].ToString().Replace("\"", ""), new NeighborInfo()
                            {
                                neighbor = strLineArray[iNeighbor].ToString().Replace("\"", ""),
                                neighbor_gridcell = strLineArray[iNeighborGridcell].ToString().Replace("\"", ""),
                                distance = Convert.ToDouble(strLineArray[iDistance]),
                                weightDistance = Convert.ToDouble(strLineArray[iWeightDistance]),
                                weightDistanceSquared = Convert.ToDouble(strLineArray[iWeightDistanceSquared]),
                            });
                        }
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetGradAdjValues(ref Dictionary<string, Dictionary<string, ModelDataSpecies>> dicGradAdjValues, Dictionary<string, float> fsoutStringSpecies, Dictionary<string, float> fsoutStringNH4DON, Dictionary<string, float> fsoutStringPM, Dictionary<string, ModelDataSpecies> dicBaselineModel, Dictionary<string, PmModelDataOutput> dicQuarterlyModelDataPM)
        {
            try
            {
                foreach (KeyValuePair<string, float> s in fsoutStringSpecies)
                {
                    string id = s.Key.Substring(0, s.Key.IndexOf(","));
                    string gridcell = s.Key.Substring(s.Key.IndexOf(",") + 1);
                    Dictionary<string, ModelDataSpecies> dic = new Dictionary<string, ModelDataSpecies>();
                    foreach (KeyValuePair<string, ModelDataSpecies> kQin in dicBaselineModel)
                    {
                        if (dicGradAdjValues.ContainsKey(s.Key))
                        {
                            if (dicGradAdjValues[s.Key].ContainsKey(kQin.Key))
                            {
                                dicGradAdjValues[s.Key][kQin.Key].so4 = (kQin.Value.so4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.so4) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].so4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].so4);
                                dicGradAdjValues[s.Key][kQin.Key].no3 = (kQin.Value.no3 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.no3) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].no3 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].no3);
                                dicGradAdjValues[s.Key][kQin.Key].oc = (kQin.Value.oc < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.oc) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].oc < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].oc);
                                dicGradAdjValues[s.Key][kQin.Key].ec = (kQin.Value.ec < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.ec) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].ec < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].ec);
                                dicGradAdjValues[s.Key][kQin.Key].crustal = (kQin.Value.crustal < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.crustal) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].crustal < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].crustal);
                                dicGradAdjValues[s.Key][kQin.Key].salt = (kQin.Value.salt < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.salt) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].salt < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].salt);
                            }
                            else
                            {
                                dicGradAdjValues[s.Key].Add(kQin.Key, new ModelDataSpecies()
                                {
                                    so4 = (kQin.Value.so4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.so4) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].so4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].so4),
                                    no3 = (kQin.Value.no3 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.no3) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].no3 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].no3),
                                    oc = (kQin.Value.oc < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.oc) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].oc < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].oc),
                                    ec = (kQin.Value.ec < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.ec) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].ec < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].ec),
                                    crustal = (kQin.Value.crustal < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.crustal) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].crustal < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].crustal),
                                    salt = (kQin.Value.salt < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.salt) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].salt < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].salt),
                                });
                            }
                        }
                        else
                        {
                            dic.Add(kQin.Key, new ModelDataSpecies()
                            {
                                so4 = (kQin.Value.so4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.so4) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].so4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].so4),
                                no3 = (kQin.Value.no3 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.no3) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].no3 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].no3),
                                oc = (kQin.Value.oc < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.oc) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].oc < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].oc),
                                ec = (kQin.Value.ec < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.ec) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].ec < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].ec),
                                crustal = (kQin.Value.crustal < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.crustal) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].crustal < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].crustal),
                                salt = (kQin.Value.salt < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.salt) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].salt < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].salt),
                            });
                            dicGradAdjValues.Add(s.Key, dic);
                        }
                    }
                }
                foreach (KeyValuePair<string, float> s in fsoutStringNH4DON)
                {
                    string id = s.Key.Substring(0, s.Key.IndexOf(","));
                    string gridcell = s.Key.Substring(s.Key.IndexOf(",") + 1);
                    Dictionary<string, ModelDataSpecies> dic = new Dictionary<string, ModelDataSpecies>();
                    foreach (KeyValuePair<string, ModelDataSpecies> kQin in dicBaselineModel)
                    {
                        if (dicGradAdjValues.ContainsKey(s.Key))
                        {
                            if (dicGradAdjValues[s.Key].ContainsKey(kQin.Key))
                            {
                                dicGradAdjValues[s.Key][kQin.Key].nh4 = (kQin.Value.nh4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.nh4) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].nh4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].nh4);
                            }
                            else
                            {
                                dicGradAdjValues[s.Key].Add(kQin.Key, new ModelDataSpecies()
                                {
                                    nh4 = (kQin.Value.nh4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.nh4) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].nh4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].nh4),
                                });
                            }
                        }
                        else
                        {
                            dic.Add(kQin.Key, new ModelDataSpecies()
                            {
                                nh4 = (kQin.Value.nh4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.nh4) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].nh4 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].nh4),
                            });
                            dicGradAdjValues.Add(s.Key, dic);
                        }
                    }
                }
                foreach (KeyValuePair<string, float> s in fsoutStringPM)
                {
                    string id = s.Key.Substring(0, s.Key.IndexOf(","));
                    string gridcell = s.Key.Substring(s.Key.IndexOf(",") + 1);
                    foreach (KeyValuePair<string, ModelDataSpecies> kQin in dicBaselineModel)
                    {
                        if (dicGradAdjValues.ContainsKey(s.Key))
                        {
                            if (dicGradAdjValues[s.Key].ContainsKey(kQin.Key))
                            {
                                dicGradAdjValues[s.Key][kQin.Key].pm25 = (kQin.Value.pm25 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.pm25) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].pm25 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].pm25);
                            }
                            else
                            {
                                dicGradAdjValues[s.Key].Add(kQin.Key, new ModelDataSpecies()
                                {
                                    pm25 = (kQin.Value.pm25 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.pm25) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].pm25 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].pm25),
                                });
                            }
                        }
                        else
                        {
                            Dictionary<string, ModelDataSpecies> dic = new Dictionary<string, ModelDataSpecies>();
                            dic.Add(kQin.Key, new ModelDataSpecies()
                            {
                                pm25 = (kQin.Value.pm25 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : kQin.Value.pm25) / (dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].pm25 < CommonClass.GradLimit ? Convert.ToSingle(CommonClass.GradLimit) : dicQuarterlyModelDataPM[gridcell].dicBaselineModel[kQin.Key].pm25),
                            });
                            dicGradAdjValues.Add(s.Key, dic);
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetSpeciesFractionValuesPointEstimates(AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref SpecFracPM sfAnnualPM, double vnaCrustal, double vnaEC, double vnaNH4, double vnaSO4, double vnaOC, double vnaSalt, double vnaNO3r, double vnaDON, double vnaPBW, double vnaNO3, double pmValue)
        {
            try
            {
                sfAnnualPM = new SpecFracPM()
                {
                    don = vnaDON,
                    iDON = vnaDON,
                    iCrustal = vnaCrustal,
                    iNH4 = vnaNH4,
                    iEC = vnaEC,
                    iNO3 = vnaNO3,
                    iNO3r = vnaNO3r,
                    iSO4 = vnaSO4,
                    iSalt = vnaSalt,
                    iOcb = vnaOC,
                    pm25MassFrac = pmValue,
                };
                #region nh4
                if (annualPMAnalysisConfiguration.speciesFractionOptionsA.doUseDonValues)
                {
                    vnaNH4 = Math.Round(vnaDON * vnaSO4 + 0.29 * vnaNO3r, CommonClass.Species_calc_precision);
                }
                else if (annualPMAnalysisConfiguration.speciesFractionOptionsA.doUseAmmoniumValues)
                {
                    double nh4_adj = vnaNH4 - (annualPMAnalysisConfiguration.speciesFractionOptionsA.nh4PercentageEvaporating * 0.29 * (vnaNO3 - vnaNO3r));
                    double nh4_so4 = nh4_adj - 0.29 * vnaNO3r;
                    double don_calc = nh4_so4 / vnaSO4;
                    vnaNH4 = Math.Round(don_calc * vnaSO4 + 0.29 * vnaNO3r, CommonClass.Species_calc_precision);
                    vnaDON = Math.Round(don_calc, CommonClass.Species_calc_precision);
                }
                #endregion
                #region pbw
                CommonClass.CalculationWater(vnaSO4, vnaNO3r, vnaNH4, vnaDON, ref vnaPBW);
                #endregion
                #region adjustment OCMmb
                double oc_floor = 0, nonBlankMass = 0, oc_max = 0, oc_ceiling = 0, oc = 0, checkOC = 0, change = 0;
                nonBlankMass = pmValue - Math.Round(Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass), CommonClass.Species_calc_precision);
                oc = nonBlankMass - (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC);
                oc_floor = Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.floorOCMMB) * vnaOC;
                oc_max = Math.Max(oc, oc_floor);
                oc_ceiling = Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.ceilingOCMMB) * nonBlankMass;
                vnaOC = Math.Min(oc_max, oc_ceiling);
                //--------当各species的和大于或小于NonBlankMass时调整OCMmb-------------SO4 + NO3r + NH4r + PBW + crustal + EC + OCMmb_calc + salt
                checkOC = nonBlankMass - (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC + vnaOC);
                change = checkOC / (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC);
                vnaCrustal = Math.Round((1 + change) * vnaCrustal, CommonClass.Species_calc_precision);
                vnaEC = Math.Round((1 + change) * vnaEC, CommonClass.Species_calc_precision);
                vnaNH4 = Math.Round((1 + change) * vnaNH4, CommonClass.Species_calc_precision);
                vnaNO3r = Math.Round((1 + change) * vnaNO3r, CommonClass.Species_calc_precision);
                vnaSO4 = Math.Round((1 + change) * vnaSO4, CommonClass.Species_calc_precision);
                vnaSalt = Math.Round((1 + change) * vnaSalt, CommonClass.Species_calc_precision);
                vnaPBW = Math.Round((1 + change) * vnaPBW, CommonClass.Species_calc_precision);
                #endregion
                //-----利用调整之后的值计算spec frac-----------
                sfAnnualPM.fCr = Math.Round(vnaCrustal / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fNH4 = Math.Round(vnaNH4 / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fEC = Math.Round(vnaEC / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fNO3 = Math.Round(vnaNO3 / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fNO3r = Math.Round(vnaNO3r / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fSO4 = Math.Round(vnaSO4 / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fSalt = Math.Round(vnaSalt / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fOcm = Math.Round(vnaOC / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.fWater = Math.Round(vnaPBW / nonBlankMass, CommonClass.Species_fraction_precision);
                sfAnnualPM.blankMass = Math.Round(Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass), CommonClass.Species_calc_precision);
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetSpeciesFractionValuesVNAEVNA(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref SpecFracPM sfAnnualPM, double vnaCrustal, double vnaEC, double vnaNH4, double vnaSO4, double vnaOC, double vnaSalt, double vnaNO3r, double vnaDON, double vnaPBW, double vnaNO3, double vnaPM)
        {
            try
            {
                sfAnnualPM = new SpecFracPM
                {
                    don = vnaDON,
                    iSO4 = vnaSO4,
                    iNO3r = vnaNO3r,
                    iOcb = vnaOC,
                    iEC = vnaEC,
                    iCrustal = vnaCrustal,
                    iDON = vnaDON,
                    iNH4 = vnaNH4,
                    iNO3 = vnaNO3,
                    iSalt = vnaSalt,
                };
                //------------nh4-------------------------
                //if (annualPMAnalysisConfiguration.speciesFractionOptionsA.doUseDonValues)
                {
                    vnaNH4 = Math.Round(vnaDON * vnaSO4 + 0.29 * vnaNO3r, CommonClass.Species_calc_precision);
                }
                //else if (annualPMAnalysisConfiguration.speciesFractionOptionsA.doUseAmmoniumValues)
                //{
                //    double nh4_adj = vnaNH4 - (annualPMAnalysisConfiguration.speciesFractionOptionsA.nh4PercentageEvaporating * 0.29 * (vnaNO3 - vnaNO3r));
                //    double nh4_so4 = nh4_adj - 0.29 * vnaNO3r;
                //    double don_calc = nh4_so4 / vnaSO4;
                //    vnaNH4 = Math.Round(don_calc * vnaSO4 + 0.29 * vnaNO3r, CommonClass.Species_calc_precision);
                //    vnaDON = Math.Round(don_calc, CommonClass.Species_calc_precision);
                //}
                //------------pbw--------------
                CommonClass.CalculationWater(vnaSO4, vnaNO3r, vnaNH4, vnaDON, ref vnaPBW);
                vnaPBW = Double.IsNaN(vnaPBW) ? 0 : Math.Round(vnaPBW, CommonClass.Species_calc_precision);
                //------------adjustment ocmmb--------------
                #region
                double oc_floor = 0, nonBlankMass = 0, oc_max = 0, oc_ceiling = 0, oc = 0, checkOC = 0, change = 0;
                //当vna得出的pm为0时，直接将所有species之和对其赋值
                vnaPM = vnaPM == 0 ? (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC + 0.5) : vnaPM;//Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass)) : vnaPM;
                nonBlankMass = vnaPM - 0.5;//Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass);
                oc = nonBlankMass - (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC);
                oc_floor = 1.0 * vnaOC;//Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.floorOCMMB) * vnaOC;
                oc_max = Math.Max(oc, oc_floor);
                oc_ceiling = 0.8 * nonBlankMass;//Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.ceilingOCMMB) * nonBlankMass;
                vnaOC = Math.Round(Math.Min(oc_max, oc_ceiling), CommonClass.Species_calc_precision);
                //--------当各species的和大于或小于NonBlankMass时调整OCMmb-------------SO4 + NO3r + NH4r + PBW + crustal + EC + OCMmb_calc + salt
                checkOC = nonBlankMass - (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC + vnaOC);
                change = Double.IsNaN(checkOC / (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC)) || Double.IsInfinity(checkOC / (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC)) ? 0 : checkOC / (vnaCrustal + vnaSO4 + vnaNO3r + vnaNH4 + vnaPBW + vnaSalt + vnaEC);
                vnaCrustal = Math.Round((1 + change) * vnaCrustal, CommonClass.Species_calc_precision);
                vnaEC = Math.Round((1 + change) * vnaEC, CommonClass.Species_calc_precision);
                vnaNH4 = Math.Round((1 + change) * vnaNH4, CommonClass.Species_calc_precision);
                vnaNO3r = Math.Round((1 + change) * vnaNO3r, CommonClass.Species_calc_precision);
                vnaSO4 = Math.Round((1 + change) * vnaSO4, CommonClass.Species_calc_precision);
                vnaSalt = Math.Round((1 + change) * vnaSalt, CommonClass.Species_calc_precision);
                vnaPBW = Math.Round((1 + change) * vnaPBW, CommonClass.Species_calc_precision);
                #endregion
                #region species fractions
                float nonBlankMassPM = Convert.ToSingle(vnaSO4 + vnaSalt + vnaNO3r + vnaNH4 + vnaOC + vnaPBW + vnaCrustal + vnaEC);
                sfAnnualPM.pm25MassFrac = Math.Round(nonBlankMassPM + 0.5, CommonClass.Pm_defaultformat);//Convert.ToSingle(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass), CommonClass.Pm_defaultformat);
                sfAnnualPM.fCr = Math.Round(vnaCrustal / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.fEC = Math.Round(vnaEC / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.fNH4 = Math.Round(vnaNH4 / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.fOcm = Math.Round(vnaOC / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.fNO3r = Math.Round(vnaNO3r / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.fWater = Math.Round(vnaPBW / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.fSalt = Math.Round(vnaSalt / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.fSO4 = Math.Round(vnaSO4 / nonBlankMassPM, CommonClass.Species_fraction_precision);
                sfAnnualPM.blankMass = Math.Round(0.5, CommonClass.Species_calc_precision);//Convert.ToDouble(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass), CommonClass.Species_calc_precision);
                #endregion
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }
        /// <summary>
        /// read model data daily
        /// </summary>
        /// <param name="annualPMAnalysisConfiguration"></param>
        /// <param name="dicQuarterlyModelDataPM"></param>
        /// <param name="baseModelYear"></param>
        /// <param name="futureModelYear"></param>
        /// <returns></returns>
        public static string GetModelDataDaily(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref Dictionary<string, PmModelDataOutput> dicQuarterlyModelDataPM, ref string baseModelYear, ref string futureModelYear)
        {
            try
            {
                #region daily baseline model data
                Dictionary<string, Dictionary<string, int>> dicDayCount = new Dictionary<string, Dictionary<string, int>>();
                int iID = -1, iType = -1, iLat = -1, iLong = -1, iDate = -1, iCrustal = -1, iNH4 = -1, iSO4 = -1, iEC = -1, iNO3 = -1, iOC = -1, iPM25 = -1, iCM = -1;
                FileStream fs = new FileStream(annualPMAnalysisConfiguration.modelInput.baselineFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8);
                string q = "";
                try
                {
                    using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                    {
                        string strLine = csv.ReadLine();
                        string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                        int i = 0;
                        //------------获取各个字段的index------------
                        #region
                        while (i < strLineArray.Length)
                        {
                            string s = strLineArray[i];
                            switch (s.Trim().ToLower().Replace("\"", ""))
                            {
                                case "_id":
                                    iID = i;
                                    break;
                                case "_type":
                                    iType = i;
                                    break;
                                case "lat":
                                    iLat = i;
                                    break;
                                case "long":
                                    iLong = i;
                                    break;
                                case "date":
                                    iDate = i;
                                    break;
                                case "crustal":
                                    iCrustal = i;
                                    break;
                                case "nh4":
                                    iNH4 = i;
                                    break;
                                case "so4":
                                    iSO4 = i;
                                    break;
                                case "ec":
                                    iEC = i;
                                    break;
                                case "no3":
                                    iNO3 = i;
                                    break;
                                case "oc":
                                    iOC = i;
                                    break;
                                case "pm25":
                                    iPM25 = i;
                                    break;
                                case "cm":
                                    iCM = i;
                                    break;
                            }
                            i++;
                        }
                        #endregion
                        while (strLine != null)
                        {
                            strLine = csv.ReadLine();
                            if (strLine == null) break;
                            strLineArray = strLine.Split(new char[] { ',' });
                            if (baseModelYear == "") baseModelYear = strLineArray[iDate].Substring(0, 4).Replace("\"", "");
                            switch (strLineArray[iDate].ToString().Substring(4, 2).Replace("\"", ""))
                            {
                                case "01":
                                case "02":
                                case "03":
                                    q = "1";
                                    break;
                                case "04":
                                case "05":
                                case "06":
                                    q = "2";
                                    break;
                                case "07":
                                case "08":
                                case "09":
                                    q = "3";
                                    break;
                                case "10":
                                case "11":
                                case "12":
                                    q = "4";
                                    break;

                            }
                            if (dicQuarterlyModelDataPM.ContainsKey(strLineArray[iID].Trim().ToString().Replace("\"", "")))
                            {
                                if (dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel.ContainsKey(q))
                                {
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].crustal = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].crustal) + Convert.ToDecimal(strLineArray[iCrustal]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].nh4 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].nh4) + Convert.ToDecimal(strLineArray[iNH4]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].so4 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].so4) + Convert.ToDecimal(strLineArray[iSO4]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].oc = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].oc) + Convert.ToDecimal(strLineArray[iOC]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].no3 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].no3) + Convert.ToDecimal(strLineArray[iNO3]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].ec = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].ec) + Convert.ToDecimal(strLineArray[iEC]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].pm25 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].pm25) + Convert.ToDecimal(strLineArray[iPM25]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].cm = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel[q].cm) + Convert.ToDecimal(strLineArray[iCM]));
                                    dicDayCount[strLineArray[iID].Trim().ToString().Replace("\"", "")][q] += 1;
                                }
                                else
                                {
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel.Add(q, new ModelDataSpecies()
                                    {
                                        crustal = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCrustal])),
                                        nh4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNH4])),
                                        so4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iSO4])),
                                        oc = Convert.ToSingle(Convert.ToDecimal(strLineArray[iOC])),
                                        no3 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNO3])),
                                        ec = Convert.ToSingle(Convert.ToDecimal(strLineArray[iEC])),
                                        pm25 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iPM25])),
                                        cm = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCM])),
                                    });
                                    dicDayCount[strLineArray[iID].Trim().ToString().Replace("\"", "")].Add(q, 1);
                                }
                            }
                            else
                            {
                                dicQuarterlyModelDataPM.Add(strLineArray[iID].Trim().ToString().Replace("\"", ""), new PmModelDataOutput()
                                {
                                    id = strLineArray[iID].Trim().ToString().Replace("\"", ""),
                                    type = strLineArray[iType].ToString().Replace("\"", ""),
                                    lat = Convert.ToDouble(strLineArray[iLat].ToString()),
                                    longitude = Convert.ToDouble(strLineArray[iLong].ToString()),
                                    dicBaselineModel = new Dictionary<string, ModelDataSpecies>(),
                                    dicFutureModel = new Dictionary<string, ModelDataSpecies>(),
                                });
                                dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicBaselineModel.Add(q, new ModelDataSpecies()
                                {
                                    crustal = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCrustal])),
                                    nh4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNH4])),
                                    so4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iSO4])),
                                    oc = Convert.ToSingle(Convert.ToDecimal(strLineArray[iOC])),
                                    no3 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNO3])),
                                    ec = Convert.ToSingle(Convert.ToDecimal(strLineArray[iEC])),
                                    pm25 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iPM25])),
                                    cm = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCM])),
                                });
                                dicDayCount.Add(strLineArray[iID].Trim().ToString().Replace("\"", ""), new Dictionary<string, int>());
                                dicDayCount[strLineArray[iID].Trim().ToString().Replace("\"", "")].Add(q, 1);
                            }
                        }
                        csv.Dispose(); fs.Dispose();
                        GC.Collect();
                    }
                }
                catch
                {
                    return "wrongBaseline";
                }
                #region quarterly model data
                foreach (KeyValuePair<string, PmModelDataOutput> k in dicQuarterlyModelDataPM)
                {
                    foreach (KeyValuePair<string, ModelDataSpecies> kQ in k.Value.dicBaselineModel)
                    {
                        kQ.Value.crustal = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.crustal) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.nh4 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.nh4) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.so4 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.so4) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.oc = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.oc) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.no3 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.no3) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.ec = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.ec) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.pm25 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.pm25) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.cm = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.cm) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                    }
                }
                dicDayCount.Clear();
                GC.Collect();
                #endregion
                #endregion

                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentLog = "Finish reading model data: " + CommonClass.TotalTime + " s.";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read model data \"" + Path.GetFileName(annualPMAnalysisConfiguration.modelInput.forecastFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                #region daily future model data
                dicDayCount = new Dictionary<string, Dictionary<string, int>>();
                iID = -1; iType = -1; iLat = -1; iLong = -1; iDate = -1; iCrustal = -1; iNH4 = -1; iSO4 = -1; iEC = -1; iNO3 = -1; iOC = -1; iPM25 = -1; iCM = -1;
                fs = new FileStream(annualPMAnalysisConfiguration.modelInput.forecastFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                sr = new StreamReader(fs, System.Text.Encoding.UTF8);
                q = "";
                try
                {
                    using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                    {
                        string strLine = csv.ReadLine();
                        string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                        int i = 0;
                        //------------获取各个字段的index------------
                        #region
                        while (i < strLineArray.Length)
                        {
                            string s = strLineArray[i];
                            switch (s.Trim().ToLower().Replace("\"", ""))
                            {
                                case "_id":
                                    iID = i;
                                    break;
                                case "_type":
                                    iType = i;
                                    break;
                                case "lat":
                                    iLat = i;
                                    break;
                                case "long":
                                    iLong = i;
                                    break;
                                case "date":
                                    iDate = i;
                                    break;
                                case "crustal":
                                    iCrustal = i;
                                    break;
                                case "nh4":
                                    iNH4 = i;
                                    break;
                                case "so4":
                                    iSO4 = i;
                                    break;
                                case "ec":
                                    iEC = i;
                                    break;
                                case "no3":
                                    iNO3 = i;
                                    break;
                                case "oc":
                                    iOC = i;
                                    break;
                                case "pm25":
                                    iPM25 = i;
                                    break;
                                case "cm":
                                    iCM = i;
                                    break;
                            }
                            i++;
                        }
                        #endregion
                        while (strLine != null)
                        {
                            strLine = csv.ReadLine();
                            if (strLine == null) break;
                            strLineArray = strLine.Split(new char[] { ',' });
                            if (futureModelYear == "") futureModelYear = strLineArray[iDate].Replace("\"", "").Substring(0, 4);
                            switch (strLineArray[iDate].ToString().Replace("\"", "").Substring(4, 2))
                            {
                                case "01":
                                case "02":
                                case "03":
                                    q = "1";
                                    break;
                                case "04":
                                case "05":
                                case "06":
                                    q = "2";
                                    break;
                                case "07":
                                case "08":
                                case "09":
                                    q = "3";
                                    break;
                                case "10":
                                case "11":
                                case "12":
                                    q = "4";
                                    break;

                            }
                            if (dicQuarterlyModelDataPM.ContainsKey(strLineArray[iID].Trim().ToString().Replace("\"", "")))
                            {
                                if (!dicDayCount.ContainsKey(strLineArray[iID].Trim().ToString().Replace("\"", "")))
                                    dicDayCount.Add(strLineArray[iID].Trim().ToString().Replace("\"", ""), new Dictionary<string, int>());
                                if (dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel.ContainsKey(q))
                                {
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].crustal = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].crustal) + Convert.ToDecimal(strLineArray[iCrustal]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].nh4 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].nh4) + Convert.ToDecimal(strLineArray[iNH4]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].so4 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].so4) + Convert.ToDecimal(strLineArray[iSO4]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].oc = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].oc) + Convert.ToDecimal(strLineArray[iOC]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].no3 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].no3) + Convert.ToDecimal(strLineArray[iNO3]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].ec = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].ec) + Convert.ToDecimal(strLineArray[iEC]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].pm25 = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].pm25) + Convert.ToDecimal(strLineArray[iPM25]));
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].cm = Convert.ToSingle(Convert.ToDecimal(dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel[q].cm) + Convert.ToDecimal(strLineArray[iCM]));
                                    if (dicDayCount[strLineArray[iID].Trim().ToString().Replace("\"", "")].ContainsKey(q))
                                    {
                                        dicDayCount[strLineArray[iID].Trim().ToString().Replace("\"", "")][q] += 1;
                                    }
                                    else
                                    {
                                        dicDayCount[strLineArray[iID].Trim().ToString().Replace("\"", "")].Add(q, 1);
                                    }
                                }
                                else
                                {
                                    dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel.Add(q, new ModelDataSpecies()
                                    {
                                        crustal = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCrustal])),
                                        nh4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNH4])),
                                        so4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iSO4])),
                                        oc = Convert.ToSingle(Convert.ToDecimal(strLineArray[iOC])),
                                        no3 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNO3])),
                                        ec = Convert.ToSingle(Convert.ToDecimal(strLineArray[iEC])),
                                        pm25 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iPM25])),
                                        cm = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCM])),
                                    });
                                    dicDayCount[strLineArray[iID].Trim().ToString().Replace("\"", "")].Add(q, 1);
                                }
                            }
                            else
                            {
                                dicQuarterlyModelDataPM.Add(strLineArray[iID].Trim().ToString().Replace("\"", ""), new PmModelDataOutput()
                                {
                                    id = strLineArray[iID].Trim().ToString().Replace("\"", ""),
                                    type = strLineArray[iType].ToString().Replace("\"", ""),
                                    lat = Convert.ToDouble(strLineArray[iLat].ToString()),
                                    longitude = Convert.ToDouble(strLineArray[iLong].ToString()),
                                    dicBaselineModel = new Dictionary<string, ModelDataSpecies>(),
                                    dicFutureModel = new Dictionary<string, ModelDataSpecies>(),
                                });
                                dicQuarterlyModelDataPM[strLineArray[iID].Trim().ToString().Replace("\"", "")].dicFutureModel.Add(q, new ModelDataSpecies()
                                {
                                    crustal = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCrustal])),
                                    nh4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNH4])),
                                    so4 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iSO4])),
                                    oc = Convert.ToSingle(Convert.ToDecimal(strLineArray[iOC])),
                                    no3 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iNO3])),
                                    ec = Convert.ToSingle(Convert.ToDecimal(strLineArray[iEC])),
                                    pm25 = Convert.ToSingle(Convert.ToDecimal(strLineArray[iPM25])),
                                    cm = Convert.ToSingle(Convert.ToDecimal(strLineArray[iCM])),
                                });
                            }
                        }
                        csv.Dispose(); fs.Dispose();
                        GC.Collect();
                    }
                }
                catch
                {
                    return "wrongFuture";
                }
                #region
                foreach (KeyValuePair<string, PmModelDataOutput> k in dicQuarterlyModelDataPM)
                {
                    foreach (KeyValuePair<string, ModelDataSpecies> kQ in k.Value.dicFutureModel)
                    {
                        kQ.Value.crustal = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.crustal) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.nh4 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.nh4) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.so4 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.so4) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.oc = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.oc) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.no3 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.no3) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.ec = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.ec) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.pm25 = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.pm25) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                        kQ.Value.cm = Convert.ToSingle(Math.Round(Convert.ToSingle(Convert.ToDecimal(kQ.Value.cm) / Convert.ToDecimal(dicDayCount[k.Key][kQ.Key])), CommonClass.Species_calc_precision));
                    }
                }
                dicDayCount.Clear();
                GC.Collect();
                #endregion
                #endregion
                return "";
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }
        }

        /// <summary>
        /// read model data quarterly
        /// </summary>
        /// <param name="annualPMAnalysisConfiguration"></param>
        /// <param name="dicQuarterlyModelDataPM"></param>
        /// <param name="baseModelYear"></param>
        /// <param name="futureModelYear"></param>
        /// <returns></returns>
        public static string GetModelDataQuarterly(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref Dictionary<string, PmModelDataOutput> dicQuarterlyModelDataPM, ref string baseModelYear, ref string futureModelYear)
        {
            try
            {
                #region quarterly baseline model data
                string dataType = "";
                bool errorOccur = false;
                DataTable dtModel = CommonClass.getDataSetFromCSVAndFirstLine(annualPMAnalysisConfiguration.modelInput.baselineFile, ref dataType, ref errorOccur);
                if (dtModel == null)
                    return "wrongBaseline";
                int iID = -1, iType = -1, iLat = -1, iLong = -1, iDate = -1, iCrustal = -1, iNH4 = -1, iSO4 = -1, iEC = -1, iNO3 = -1, iOC = -1, iPM25 = -1, iCM = -1;
                try
                {
                    #region get index for each field
                    for (int i = 0; i < dtModel.Columns.Count; i++)
                    {
                        switch (dtModel.Columns[i].ColumnName.ToLower().Trim().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_type":
                                iType = i;
                                break;
                            case "lat":
                                iLat = i;
                                break;
                            case "long":
                                iLong = i;
                                break;
                            case "date":
                                iDate = i;
                                break;
                            case "crustal":
                                iCrustal = i;
                                break;
                            case "nh4":
                                iNH4 = i;
                                break;
                            case "so4":
                                iSO4 = i;
                                break;
                            case "ec":
                                iEC = i;
                                break;
                            case "no3":
                                iNO3 = i;
                                break;
                            case "oc":
                                iOC = i;
                                break;
                            case "pm25":
                                iPM25 = i;
                                break;
                            case "cm":
                                iCM = i;
                                break;
                        }
                    }
                    #endregion
                    foreach (DataRow dr in dtModel.Rows)
                    {
                        if (baseModelYear == "") baseModelYear = dr[iDate].ToString().Replace("\"", "").Substring(0, 4);
                        string q = "";
                        switch (dr[iDate].ToString().Replace("\"", "").Substring(4))
                        {
                            case "01":
                                q = "1";
                                break;
                            case "04":
                                q = "2";
                                break;
                            case "07":
                                q = "3";
                                break;
                            case "10":
                                q = "4";
                                break;
                        }
                        if (dicQuarterlyModelDataPM.ContainsKey(dr[iID].ToString().Replace("\"", "")))
                        {
                            dicQuarterlyModelDataPM[dr[iID].ToString().Replace("\"", "")].dicBaselineModel.Add(q, new ModelDataSpecies()
                            {
                                crustal = Convert.ToSingle(dr[iCrustal].ToString()),
                                nh4 = Convert.ToSingle(dr[iNH4].ToString()),
                                so4 = Convert.ToSingle(dr[iSO4].ToString()),
                                ec = Convert.ToSingle(dr[iEC].ToString()),
                                no3 = Convert.ToSingle(dr[iNO3].ToString()),
                                oc = Convert.ToSingle(dr[iOC].ToString()),
                                pm25 = Convert.ToSingle(dr[iPM25].ToString()),
                                cm = Convert.ToSingle(dr[iCM].ToString()),
                            });
                        }
                        else
                        {
                            dicQuarterlyModelDataPM.Add(dr[iID].ToString().Replace("\"", ""), new PmModelDataOutput()
                            {
                                id = dr[iID].ToString().Replace("\"", ""),
                                type = dr[iType].ToString().Replace("\"", ""),
                                lat = Convert.ToDouble(dr[iLat].ToString()),
                                longitude = Convert.ToDouble(dr[iLong].ToString()),
                                dicBaselineModel = new Dictionary<string, ModelDataSpecies>(),
                                dicFutureModel = new Dictionary<string, ModelDataSpecies>(),
                            });
                            dicQuarterlyModelDataPM[dr[iID].ToString().Replace("\"", "")].dicBaselineModel.Add(q, new ModelDataSpecies()
                            {
                                crustal = Convert.ToSingle(dr[iCrustal].ToString()),
                                nh4 = Convert.ToSingle(dr[iNH4].ToString()),
                                so4 = Convert.ToSingle(dr[iSO4].ToString()),
                                ec = Convert.ToSingle(dr[iEC].ToString()),
                                no3 = Convert.ToSingle(dr[iNO3].ToString()),
                                oc = Convert.ToSingle(dr[iOC].ToString()),
                                pm25 = Convert.ToSingle(dr[iPM25].ToString()),
                                cm = Convert.ToSingle(dr[iCM].ToString()),
                            });
                        }
                    }
                    dtModel.Dispose();
                    GC.Collect();
                }
                catch
                {
                    return "wrongBaseline";
                }
                #endregion

                _endTime = DateTime.Now;
                CommonClass.TotalTime = Math.Round(_endTime.Subtract(_beginTime).TotalSeconds, 3);
                CommonClass.CurrentLog = "Finish reading model data: " + CommonClass.TotalTime + " s.";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);
                _beginTime = DateTime.Now;
                CommonClass.CurrentLog = "Read model data \"" + Path.GetFileName(annualPMAnalysisConfiguration.modelInput.forecastFile) + "\".";
                CommonClass.CurrentBaseScenario.log.lstLog.Add(CommonClass.CurrentLog);

                #region quarterly future model data
                errorOccur = false;
                dtModel = CommonClass.getDataSetFromCSVAndFirstLine(annualPMAnalysisConfiguration.modelInput.forecastFile, ref dataType, ref errorOccur);
                if (dtModel == null)
                    return "wrongFuture";

                //保存字段的索引
                iID = -1; iType = -1; iLat = -1; iLong = -1; iDate = -1; iCrustal = -1; iNH4 = -1; iSO4 = -1; iEC = -1; iNO3 = -1; iOC = -1; iPM25 = -1; iCM = -1;
                try
                {
                    #region get index for each field
                    for (int i = 0; i < dtModel.Columns.Count; i++)
                    {
                        switch (dtModel.Columns[i].ColumnName.ToLower().Trim().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_type":
                                iType = i;
                                break;
                            case "lat":
                                iLat = i;
                                break;
                            case "long":
                                iLong = i;
                                break;
                            case "date":
                                iDate = i;
                                break;
                            case "crustal":
                                iCrustal = i;
                                break;
                            case "nh4":
                                iNH4 = i;
                                break;
                            case "so4":
                                iSO4 = i;
                                break;
                            case "ec":
                                iEC = i;
                                break;
                            case "no3":
                                iNO3 = i;
                                break;
                            case "oc":
                                iOC = i;
                                break;
                            case "pm25":
                                iPM25 = i;
                                break;
                            case "cm":
                                iCM = i;
                                break;
                        }
                    }
                    #endregion
                    foreach (DataRow dr in dtModel.Rows)
                    {
                        if (futureModelYear == "") futureModelYear = dr[iDate].ToString().Replace("\"", "").Substring(0, 4);
                        string q = "";
                        switch (dr[iDate].ToString().Replace("\"", "").Substring(4))
                        {
                            case "01":
                                q = "1";
                                break;
                            case "04":
                                q = "2";
                                break;
                            case "07":
                                q = "3";
                                break;
                            case "10":
                                q = "4";
                                break;
                        }
                        if (dicQuarterlyModelDataPM.ContainsKey(dr[iID].ToString().Replace("\"", "")))
                        {
                            dicQuarterlyModelDataPM[dr[iID].ToString().Replace("\"", "")].dicFutureModel.Add(q, new ModelDataSpecies()
                            {
                                crustal = Convert.ToSingle(dr[iCrustal].ToString()),
                                nh4 = Convert.ToSingle(dr[iNH4].ToString()),
                                so4 = Convert.ToSingle(dr[iSO4].ToString()),
                                ec = Convert.ToSingle(dr[iEC].ToString()),
                                no3 = Convert.ToSingle(dr[iNO3].ToString()),
                                oc = Convert.ToSingle(dr[iOC].ToString()),
                                pm25 = Convert.ToSingle(dr[iPM25].ToString()),
                                cm = Convert.ToSingle(dr[iCM].ToString()),
                            });
                        }
                        else
                        {
                            dicQuarterlyModelDataPM.Add(dr[iID].ToString().Replace("\"", ""), new PmModelDataOutput()
                            {
                                id = dr[iID].ToString().Replace("\"", ""),
                                type = dr[iType].ToString().Replace("\"", ""),
                                lat = Convert.ToDouble(dr[iLat].ToString()),
                                longitude = Convert.ToDouble(dr[iLong].ToString()),
                                dicBaselineModel = new Dictionary<string, ModelDataSpecies>(),
                                dicFutureModel = new Dictionary<string, ModelDataSpecies>(),
                            });
                            dicQuarterlyModelDataPM[dr[iID].ToString().Replace("\"", "")].dicFutureModel.Add(q, new ModelDataSpecies()
                            {
                                crustal = Convert.ToSingle(dr[iCrustal].ToString()),
                                nh4 = Convert.ToSingle(dr[iNH4].ToString()),
                                so4 = Convert.ToSingle(dr[iSO4].ToString()),
                                ec = Convert.ToSingle(dr[iEC].ToString()),
                                no3 = Convert.ToSingle(dr[iNO3].ToString()),
                                oc = Convert.ToSingle(dr[iOC].ToString()),
                                pm25 = Convert.ToSingle(dr[iPM25].ToString()),
                                cm = Convert.ToSingle(dr[iCM].ToString()),
                            });
                        }
                    }
                }
                catch
                {
                    return "wrongFuture";
                }
                dtModel.Dispose();
                GC.Collect();
                #endregion
                return "";
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }

        }

        public static bool GetModelDataFromCMAQ(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration)
        {
            try
            {
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }

        }

        /// <summary>
        /// read official pm25 monitors file
        /// </summary>
        /// <param name="annualPMAnalysisConfiguration"></param>
        /// <param name="dicOfficialPMMonitors"></param>
        /// <returns></returns>
        public static string GetOfficialPmMonitors(AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref  Dictionary<string, PMMonitorOutput> dicOfficialPMMonitors)
        {
            try
            {
                //string error = "";
                #region read offcial pm25
                //字段索引值
                int iID = -1, iType = -1, iLat = -1, iLong = -1, iDate = -1, iPM25 = -1;
                int iNdays = -1, iSubCode = -1, iComCode = -1, iStateName = -1, iCountyName = -1;
                FileStream fs = new FileStream(annualPMAnalysisConfiguration.dataInputA.officialMonitorDataFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    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().Replace(" ", "").Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_type":
                                iType = i;
                                break;
                            case "lat":
                                iLat = i;
                                break;
                            case "long":
                                iLong = i;
                                break;
                            case "date":
                                iDate = i;
                                break;
                            case "pm25":
                                iPM25 = i;
                                break;
                            case "ndays":
                                iNdays = i;
                                break;
                            case "_substitution_code":
                                iSubCode = i;
                                break;
                            case "completion_code":
                                iComCode = i;
                                break;
                            case "_state_name":
                                iStateName = i;
                                break;
                            case "_county_name":
                                iCountyName = i;
                                break;
                        }
                        i++;
                    }
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        //try
                        //{
                        strLineArray = strLine.Split(new char[] { ',' });
                        //首先判断是否满足start year和end year
                        if (Convert.ToInt32(strLineArray[iDate].Replace("\"", "").Substring(0, 4)) >= Convert.ToInt32(annualPMAnalysisConfiguration.pm25CalculationOptionsA.officialPM25StartYear)
                            && Convert.ToInt32(strLineArray[iDate].Replace("\"", "").Substring(0, 4)) <= Convert.ToInt32(annualPMAnalysisConfiguration.pm25CalculationOptionsA.officialPM25EndYear))
                        {
                            if (dicOfficialPMMonitors.ContainsKey(strLineArray[iID].ToString().Replace("\"", "")))
                            {
                                dicOfficialPMMonitors[strLineArray[iID].ToString().Replace("\"", "")].dicOfficialPM.Add(strLineArray[iDate].Replace("\"", "").Substring(0, 6), new PMOfficialPoint()
                                {
                                    date = strLineArray[iDate].Replace("\"", "").Substring(0, 6),
                                    nDays = Convert.ToInt32(strLineArray[iNdays]),
                                    pm = Convert.ToSingle(strLineArray[iPM25]) == -9 ? float.NaN : Convert.ToSingle(strLineArray[iPM25]),
                                    subCode = strLineArray[iSubCode].Replace("\"", ""),
                                    comCode = Convert.ToInt32(strLineArray[iComCode]),
                                });
                            }
                            else
                            {
                                dicOfficialPMMonitors.Add(strLineArray[iID].ToString().Replace("\"", ""), new PMMonitorOutput()
                                {
                                    id = strLineArray[iID].Replace("\"", ""),
                                    latitude = Convert.ToDouble(strLineArray[iLat]),
                                    longitude = Convert.ToDouble(strLineArray[iLong]),
                                    type = strLineArray[iType].Replace("\"", ""),
                                    stateName = strLineArray[iStateName].Replace("\"", ""),
                                    countyName = strLineArray[iCountyName].Replace("\"", ""),
                                    dicOfficialPM = new Dictionary<string, PMOfficialPoint>(),
                                });
                                dicOfficialPMMonitors[strLineArray[iID].ToString().Replace("\"", "")].dicOfficialPM.Add(strLineArray[iDate].Replace("\"", "").Substring(0, 6), new PMOfficialPoint()
                                {
                                    date = strLineArray[iDate].Replace("\"", "").Substring(0, 6),
                                    nDays = Convert.ToInt32(strLineArray[iNdays]),
                                    pm = Convert.ToSingle(strLineArray[iPM25]) == -9 ? float.NaN : Convert.ToSingle(strLineArray[iPM25]),
                                    subCode = strLineArray[iSubCode].Replace("\"", ""),
                                    comCode = Convert.ToInt32(strLineArray[iComCode]),
                                });
                            }
                        }
                        //}
                        //catch
                        //{
                        //    error = "errorRow";
                        //}
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                #endregion
                return "";
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }

        }

        public static bool PMCalculationOfficialChoice(AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, Dictionary<string, PMMonitorOutput> dicOfficialPMMonitors, List<string> dicDesignValluePeriods, ref Dictionary<string, PMMonitorOutput> dicFrmMonitorBaseline)
        {
            try
            {
                Dictionary<string, PMMonitorOutput> dicQuarterlyAverageByYear = new Dictionary<string, PMMonitorOutput>();
                Dictionary<string, PMOfficialPoint> dic = new Dictionary<string, PMOfficialPoint>();
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicOfficialPMMonitors)
                {
                    try
                    {
                        dicQuarterlyAverageByYear.Add(k.Key, new PMMonitorOutput()
                        {
                            id = k.Value.id,
                            type = k.Value.type,
                            latitude = k.Value.latitude,
                            longitude = k.Value.longitude,
                            stateName = k.Value.stateName,
                            countyName = k.Value.countyName,
                            dicOfficialPMPeriod = new Dictionary<string, Dictionary<string, PMOfficialPoint>>(),
                            dicOfficialPM = new Dictionary<string, PMOfficialPoint>(),
                        });
                        foreach (string s in dicDesignValluePeriods)
                        {
                            List<string> lstYear = new List<string>();
                            //lstYear.Add(s.Substring(0, s.IndexOf("-")));
                            //lstYear.Add((Convert.ToInt32(s.Substring(0, s.IndexOf("-"))) + 1).ToString());
                            //lstYear.Add(s.Substring(s.IndexOf("-") + 1));
                            for (int j = Convert.ToInt16(s.Substring(0, s.IndexOf("-"))); j <= Convert.ToInt16(s.Substring(s.IndexOf("-") + 1)); j++)
                            {
                                lstYear.Add(j.ToString());
                            }
                            lstYear.Sort();
                            var query = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode);
                            if (query.Count() == 0) continue;
                            for (int i = 1; i <= 4; i++)
                            {
                                dic = new Dictionary<string, PMOfficialPoint>();
                                switch (i)
                                {
                                    case 1:
                                        //int comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First();
                                        if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                        {
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "01" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        else
                                        {
                                            dic.Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "01" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        break;
                                    case 2:
                                        if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                        {
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "04" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        else
                                        {
                                            dic.Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "04" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        break;
                                    case 3:
                                        if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                        {
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "07" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        else
                                        {
                                            dic.Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "07" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        break;
                                    case 4:
                                        if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                        {
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "10" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        else
                                        {
                                            dic.Add(s, new PMOfficialPoint()
                                            {
                                                pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "10" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                            });
                                            dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2)
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                            }
                                        }
                                        break;
                                }
                                if (!dicQuarterlyAverageByYear[k.Key].dicOfficialPM.ContainsKey((i).ToString()))
                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPM.Add((i).ToString(), new PMOfficialPoint());

                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Where(p => !Double.IsNaN(p.Value.pm)).Select(p => p.Value.pm).Count() == 0)
                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPM[Convert.ToString(i)].pm = float.NaN;
                                else
                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPM[Convert.ToString(i)].pm = dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Where(p => !Double.IsNaN(p.Value.pm)).Select(p => p.Value.pm).Average();
                            }
                        }
                    }
                    catch
                    {
                    }
                }
                //------delete missing value----
                #region
                if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                {
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlyAverageByYear)
                    {
                        try
                        {
                            if (!Double.IsNaN(k.Value.dicOfficialPM["1"].pm) && k.Value.dicOfficialPM.Count() >= 4)
                            {
                                dicFrmMonitorBaseline.Add(k.Key, new PMMonitorOutput()
                                {
                                    id = k.Value.id,
                                    type = k.Value.type,
                                    latitude = k.Value.latitude,
                                    longitude = k.Value.longitude,
                                    stateName = k.Value.stateName,
                                    countyName = k.Value.countyName,
                                    dicOfficialPM = new Dictionary<string, PMOfficialPoint>(),
                                    dicOfficialPMPeriod = new Dictionary<string, Dictionary<string, PMOfficialPoint>>(),
                                });
                                dicFrmMonitorBaseline[k.Key].dicOfficialPM = k.Value.dicOfficialPM;
                                dicFrmMonitorBaseline[k.Key].dicOfficialPMPeriod = k.Value.dicOfficialPMPeriod;
                            }
                        }
                        catch
                        {
                        }
                    }
                }
                else
                {
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlyAverageByYear)
                    {
                        try
                        {
                            if (!Double.IsNaN(k.Value.dicOfficialPM["1"].pm) && k.Value.dicOfficialPM.Count() >= 4)
                            {
                                dicFrmMonitorBaseline.Add(k.Key, new PMMonitorOutput()
                                {
                                    id = k.Value.id,
                                    type = k.Value.type,
                                    latitude = k.Value.latitude,
                                    longitude = k.Value.longitude,
                                    stateName = k.Value.stateName,
                                    countyName = k.Value.countyName,
                                    dicOfficialPM = new Dictionary<string, PMOfficialPoint>(),
                                });
                                dicFrmMonitorBaseline[k.Key].dicOfficialPM = k.Value.dicOfficialPM;
                            }
                        }
                        catch
                        {
                        }
                    }
                }
                #endregion
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool PMCalculationCustomChoice(AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, Dictionary<string, PMMonitorOutput> dicOfficialPMMonitors, List<string> dicDesignValluePeriods, ref Dictionary<string, PMMonitorOutput> dicFrmMonitorBaseline)
        {
            try
            {
                #region Custom DV
                //判断季度最小天数，并将不满足的设为NaN
                #region
                Dictionary<string, PMMonitorOutput> dicCustomMonitor = new Dictionary<string, PMMonitorOutput>();
                dicCustomMonitor = dicOfficialPMMonitors;
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicOfficialPMMonitors)
                {
                    try
                    {
                        var query = dicOfficialPMMonitors[k.Key].dicOfficialPM.Where(p => p.Value.nDays < (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).pm25CalculationOptionsA.minDaysForValidFRMQuarters).ToList();
                        if (query.Count() > 0)
                        {
                            foreach (KeyValuePair<string, PMOfficialPoint> item in query)
                            {
                                dicCustomMonitor[k.Key].dicOfficialPM[item.Key].pm = float.NaN;
                            }
                        }
                    }
                    catch { }
                }
                #endregion
                //跨年求季度均值
                Dictionary<string, PMMonitorOutput> dicQuarterlyAverageByYear = new Dictionary<string, PMMonitorOutput>();
                Dictionary<string, PMOfficialPoint> dic = new Dictionary<string, PMOfficialPoint>();
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicCustomMonitor)
                {
                    try
                    {
                        dicQuarterlyAverageByYear.Add(k.Key, new PMMonitorOutput()
                        {
                            id = k.Value.id,
                            type = k.Value.type,
                            latitude = k.Value.latitude,
                            longitude = k.Value.longitude,
                            stateName = k.Value.stateName,
                            countyName = k.Value.countyName,
                            dicOfficialPM = new Dictionary<string, PMOfficialPoint>(),
                            dicOfficialPMPeriod = new Dictionary<string, Dictionary<string, PMOfficialPoint>>(),
                        });

                        foreach (string s in dicDesignValluePeriods)
                        {
                            List<string> lstYear = new List<string>();
                            //lstYear.Add(s.Substring(0, s.IndexOf("-")));
                            //lstYear.Add((Convert.ToInt32(s.Substring(0, s.IndexOf("-"))) + 1).ToString());
                            //lstYear.Add(s.Substring(s.IndexOf("-") + 1));
                            for (int j = Convert.ToInt16(s.Substring(0, s.IndexOf("-"))); j <= Convert.ToInt16(s.Substring(s.IndexOf("-") + 1)); j++)
                            {
                                lstYear.Add(j.ToString());
                            }
                            lstYear.Sort();
                            if (k.Value.dicOfficialPM.Where(p => lstYear.Contains(p.Value.date.Substring(0, 4))).Count() < annualPMAnalysisConfiguration.pm25CalculationOptionsA.minQuartersForValidFRMDesignValues)
                            {
                                //----------min quarters---------------
                                #region
                                for (int i = 1; i <= 4; i++)
                                {
                                    dic = new Dictionary<string, PMOfficialPoint>();
                                    if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                    {
                                        dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                        {
                                            pm = float.NaN,
                                            bad_dv = 1,
                                        });
                                    }
                                    else
                                    {
                                        dic.Add((i).ToString(), new PMOfficialPoint()
                                        {
                                            pm = float.NaN,
                                            bad_dv = 1,
                                        });
                                        dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                    }
                                }
                                #endregion
                            }
                            else
                            {
                                #region
                                for (int i = 1; i <= 4; i++)
                                {
                                    dic = new Dictionary<string, PMOfficialPoint>();
                                    switch (i)
                                    {
                                        case 1:
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "01" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            else
                                            {
                                                dic.Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "01" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            break;
                                        case 2:
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "04" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            else
                                            {
                                                dic.Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "04" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            break;
                                        case 3:
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "07" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            else
                                            {
                                                dic.Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "07" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            break;
                                        case 4:
                                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.ContainsKey((i).ToString()))
                                            {
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "10" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            else
                                            {
                                                dic.Add(s, new PMOfficialPoint()
                                                {
                                                    pm = k.Value.dicOfficialPM.Where(p => p.Value.date.Substring(4, 2) == "10" && lstYear.Contains(p.Value.date.Substring(0, 4))).Select(p => p.Value.pm).Average(),
                                                    comCode = k.Value.dicOfficialPM.Where(p => lstYear[lstYear.Count - 1] == p.Value.date.Substring(0, 4)).Select(p => p.Value.comCode).First(),
                                                });
                                                dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod.Add((i).ToString(), dic);
                                                if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 1 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 2
                                                    && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 3 && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].comCode != 4)
                                                {
                                                    dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()][s].pm = float.NaN;
                                                }
                                            }
                                            break;
                                    }
                                }
                                #endregion
                            }
                        }
                        //Minimum Number of DV，若不满足则三个period的季度均值全为NaN
                        #region
                        if (3 - dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod["1"].Where(p => p.Value.bad_dv == 1).Count() < (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).pm25CalculationOptionsA.minNumDVPeriodsForValidFRMMonitors)
                        {
                            foreach (KeyValuePair<string, Dictionary<string, PMOfficialPoint>> kQ in dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod)
                            {
                                foreach (KeyValuePair<string, PMOfficialPoint> kPeriod in kQ.Value)
                                {
                                    kPeriod.Value.pm = float.NaN;
                                }
                            }
                        }
                        #endregion
                        //Required DV
                        #region
                        List<string> lstPeriod = (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).pm25CalculationOptionsA.requiredDVPeriodsForValidFRMMonitors.Split(',').ToList();
                        for (int i = 0; i < lstPeriod.Count(); i++)
                        {
                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod["1"].ContainsKey(lstPeriod[i])
                                && dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod["1"][lstPeriod[i]].bad_dv == 1)
                            {
                                foreach (KeyValuePair<string, Dictionary<string, PMOfficialPoint>> kQ in dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod)
                                {
                                    foreach (KeyValuePair<string, PMOfficialPoint> kPeriod in kQ.Value)
                                    {
                                        kPeriod.Value.pm = float.NaN;
                                    }
                                }
                                break;
                            }
                        }
                        #endregion
                        //------average----------
                        #region
                        for (int i = 1; i <= 4; i++)
                        {
                            if (!dicQuarterlyAverageByYear[k.Key].dicOfficialPM.ContainsKey((i).ToString()))
                                dicQuarterlyAverageByYear[k.Key].dicOfficialPM.Add((i).ToString(), new PMOfficialPoint());
                            if (dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Where(p => !Double.IsNaN(p.Value.pm)).Select(p => p.Value.pm).Count() == 0)
                                dicQuarterlyAverageByYear[k.Key].dicOfficialPM[Convert.ToString(i)].pm = float.NaN;
                            else
                                dicQuarterlyAverageByYear[k.Key].dicOfficialPM[Convert.ToString(i)].pm = dicQuarterlyAverageByYear[k.Key].dicOfficialPMPeriod[(i).ToString()].Where(p => !Double.IsNaN(p.Value.pm)).Select(p => p.Value.pm).Average();
                        }
                        #endregion
                    }
                    catch
                    {
                    }
                }
                //delete missing value
                #region
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlyAverageByYear)
                {
                    try
                    {
                        if (!Double.IsNaN(dicQuarterlyAverageByYear[k.Key].dicOfficialPM["1"].pm) && dicQuarterlyAverageByYear[k.Key].dicOfficialPM.Count() >= 4)
                        {
                            dicFrmMonitorBaseline.Add(k.Key, new PMMonitorOutput()
                            {
                                id = k.Value.id,
                                type = k.Value.type,
                                latitude = k.Value.latitude,
                                longitude = k.Value.longitude,
                                stateName = k.Value.stateName,
                                countyName = k.Value.countyName,
                                dicOfficialPM = new Dictionary<string, PMOfficialPoint>(),
                                dicOfficialPMPeriod = new Dictionary<string, Dictionary<string, PMOfficialPoint>>(),
                            });
                            if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doDesignValuePeriods)
                                dicFrmMonitorBaseline[k.Key].dicOfficialPMPeriod = new Dictionary<string, Dictionary<string, PMOfficialPoint>>();
                            dicFrmMonitorBaseline[k.Key].dicOfficialPM = dicQuarterlyAverageByYear[k.Key].dicOfficialPM;
                        }
                    }
                    catch
                    {
                    }
                }
                #endregion
                #endregion
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetGridCellOfficialMonitors(Dictionary<string, PmModelDataOutput> dicQuarterlyModelDataPM)
        {
            try
            {
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetGridCellUnofficialMonitors(ref Dictionary<string, string> dicMonitorInModelUnofficial, ref Dictionary<string, string> dicMonitorInModelUnofficialTrue, Dictionary<string, PmModelDataOutput> dicQuarterlyModelDataPM, Dictionary<string, PMMonitorOutput> dicUnofficialMonitorsDaily)
        {
            try
            {
                //得到species monitor属于哪个网格--------简单的方法可以判断以最近的点作为它的网格。首先可以求出第一个网格的大小，在小于一倍网格宽度和长度的最大值求最近点

                double dLon = 0, dLat = 0;
                //modified by Yangwenwei
                List<string> lstkey = dicQuarterlyModelDataPM.Keys.ToList();
                foreach (string tempKey in lstkey)
                {
                    int iKey = Convert.ToInt32(tempKey);
                    string Next1 = (((iKey / 1000) + 1) * 1000 + iKey % 1000).ToString();
                    string Next2 = (((iKey / 1000)) * 1000 + iKey % 1000 + 1).ToString();
                    if (lstkey.Contains(Next1) && lstkey.Contains(Next2))
                    {
                        dLon = Math.Abs(dicQuarterlyModelDataPM[Next1].longitude - dicQuarterlyModelDataPM[tempKey].longitude
                            );
                        dLat = Math.Abs(dicQuarterlyModelDataPM[Next2].lat - dicQuarterlyModelDataPM[tempKey].lat
                            );
                        dLon *= 2; dLat *= 2;

                        break;
                    }
                }

                //double dFirst = dicQuarterlyModelDataPM.First().Value.longitude, dLon = 0, dLat = 0;
                //int iFirst = Convert.ToInt32(dicQuarterlyModelDataPM.First().Key);
                //if (dicQuarterlyModelDataPM.ContainsKey((((iFirst / 1000) + 1) * 1000 + iFirst % 1000).ToString()))
                //{
                //    dLon = Math.Abs(dicQuarterlyModelDataPM[(((iFirst / 1000) + 1) * 1000 + iFirst % 1000).ToString()].longitude -
                //            dicQuarterlyModelDataPM.First().Value.longitude
                //            );
                //    dLat = Math.Abs(dicQuarterlyModelDataPM[(((iFirst / 1000)) * 1000 + iFirst % 1000 + 1).ToString()].lat -
                //        dicQuarterlyModelDataPM.First().Value.lat
                //        );
                //    dLon *= 2; dLat *= 2;
                //}

                //---------计算两个网格之内；然后属于哪个的网格，根据距离判断属于哪个网格
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicUnofficialMonitorsDaily)
                {
                    try
                    {
                        var query = dicQuarterlyModelDataPM.Where(p => Math.Abs(p.Value.longitude - k.Value.longitude) < dLon && Math.Abs(p.Value.lat - k.Value.latitude) < dLat).ToList();
                        string sModelIDTemp = "";
                        if (query.Count() > 0)
                        {
                            DotSpatial.Topology.Coordinate coor = new DotSpatial.Topology.Coordinate(k.Value.longitude, k.Value.latitude);
                            sModelIDTemp = query.OrderBy(p => CommonClass.getDistanceFrom2Point(p.Value.longitude, p.Value.lat, k.Value.longitude, k.Value.latitude)).First().Key;
                            dicMonitorInModelUnofficialTrue.Add(k.Key, sModelIDTemp);
                        }
                        else
                        {
                            sModelIDTemp = dicQuarterlyModelDataPM.OrderBy(p => CommonClass.getDistanceFrom2Point(p.Value.longitude, p.Value.lat, k.Value.longitude, k.Value.latitude)).First().Key;
                        }
                        dicMonitorInModelUnofficial.Add(k.Key, sModelIDTemp);
                    }
                    catch
                    {
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetGridCellSpeciatedMonitors(ref Dictionary<string, string> dicMonitorInModelSpecies, Dictionary<string, PmModelDataOutput> dicQuarterlyModelDataPM, Dictionary<string, PMMonitorOutput> dicSpeciesMonitors)
        {
            try
            {
                //得到species monitor属于哪个网格--------简单的方法可以判断以最近的点作为它的网格。首先可以求出第一个网格的大小，在小于一倍网格宽度和长度的最大值求最近点
                double dFirst = dicQuarterlyModelDataPM.First().Value.longitude, dLon = 0, dLat = 0;
                int iFirst = Convert.ToInt32(dicQuarterlyModelDataPM.First().Key);
                if (dicQuarterlyModelDataPM.ContainsKey((((iFirst / 1000) + 1) * 1000 + iFirst % 1000).ToString()))
                {
                    dLon = Math.Abs(dicQuarterlyModelDataPM[(((iFirst / 1000) + 1) * 1000 + iFirst % 1000).ToString()].longitude -
                            dicQuarterlyModelDataPM.First().Value.longitude
                            );
                    dLat = Math.Abs(dicQuarterlyModelDataPM[(((iFirst / 1000)) * 1000 + iFirst % 1000 + 1).ToString()].lat -
                        dicQuarterlyModelDataPM.First().Value.lat
                        );
                    dLon *= 2; dLat *= 2;
                }

                //---------计算两个网格之内；然后属于哪个的网格，根据距离判断属于哪个网格
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeciesMonitors)
                {
                    try
                    {
                        var query = dicQuarterlyModelDataPM.Where(p => Math.Abs(p.Value.longitude - k.Value.longitude) < dLon && Math.Abs(p.Value.lat - k.Value.latitude) < dLat).ToList();
                        string sModelIDTemp = "";
                        if (query.Count() > 0)
                        {
                            DotSpatial.Topology.Coordinate coor = new DotSpatial.Topology.Coordinate(k.Value.longitude, k.Value.latitude);
                            sModelIDTemp = query.OrderBy(p => CommonClass.getDistanceFrom2Point(p.Value.longitude, p.Value.lat, k.Value.longitude, k.Value.latitude)).First().Key;
                        }
                        else
                        {
                            sModelIDTemp = dicQuarterlyModelDataPM.OrderBy(p => CommonClass.getDistanceFrom2Point(p.Value.longitude, p.Value.lat, k.Value.longitude, k.Value.latitude)).First().Key;
                        }
                        dicMonitorInModelSpecies.Add(k.Key, sModelIDTemp);
                    }
                    catch
                    {
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static string GetUnofficialPmMonitors(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref Dictionary<string, PMMonitorOutput> dicUnofficialMonitorsDaily)
        {
            try
            {
                #region read unoffcial pm25
                //字段索引值
                int iID = -1, iType = -1, iLat = -1, iLong = -1, iDate = -1, iPM25 = -1, iEpaFlag = -1, iUserFlag = -1;
                string quarter = "";
                string error = "";
                //bool isOKinfilter = true;

                FileStream fs = new FileStream(annualPMAnalysisConfiguration.monitorInput.unofficialFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    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().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_type":
                                iType = i;
                                break;
                            case "lat":
                                iLat = i;
                                break;
                            case "long":
                                iLong = i;
                                break;
                            case "date":
                                iDate = i;
                                break;
                            case "pm25":
                                iPM25 = i;
                                break;
                            case "epa_flag":
                                iEpaFlag = i;
                                break;
                            case "user_flag":
                                iUserFlag = i;
                                break;
                        }
                        i++;
                    }
                    //-----------记录id和type，判断是否有id相同而type不同的monitors
                    Dictionary<string, string> dicIdType = new Dictionary<string, string>();
                    Dictionary<string, float> dicDaily1 = new Dictionary<string, float>();
                    Dictionary<string, float> dicDaily2 = new Dictionary<string, float>();
                    Dictionary<string, float> dicDaily3 = new Dictionary<string, float>();
                    Dictionary<string, float> dicDaily4 = new Dictionary<string, float>();
                    Dictionary<string, Dictionary<string, float>> dicQYDaily1 = new Dictionary<string, Dictionary<string, float>>();
                    Dictionary<string, Dictionary<string, float>> dicQYDaily2 = new Dictionary<string, Dictionary<string, float>>();
                    Dictionary<string, Dictionary<string, float>> dicQYDaily3 = new Dictionary<string, Dictionary<string, float>>();
                    Dictionary<string, Dictionary<string, float>> dicQYDaily4 = new Dictionary<string, Dictionary<string, float>>();
                    string id = "", date = "", type = "";
                    int count = 0;
                    //---------根据species frations calculation窗体中的设置进行数据筛选
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        strLineArray = strLine.Split(new char[] { ',' });
                        //-----------记录id和type，判断是否有id相同而type不同的monitors
                        if (dicIdType.ContainsKey(strLineArray[iID].Replace("\"", "")) && strLineArray[iType].Replace("\"", "").ToString() == "IMPROVE")
                        {
                            if (!dicIdType.ContainsKey(strLineArray[iID].Replace("\"", "") + "^IMPROVE") && (dicIdType.ContainsKey(strLineArray[iID].Replace("\"", "")) && dicIdType[strLineArray[iID].Replace("\"", "")].ToString() == "FRM"))
                                dicIdType.Add(strLineArray[iID].Replace("\"", "") + "^IMPROVE", strLineArray[iType].Replace("\"", ""));
                        }
                        else
                            if (!dicIdType.ContainsKey(strLineArray[iID].Replace("\"", "")))
                                dicIdType.Add(strLineArray[iID].Replace("\"", ""), strLineArray[iType].Replace("\"", ""));

                        //----------epa_flag/user_flag-----------------start year && end year,并判断pm25是否存在，若pm25<0,则delete
                        if (Convert.ToInt32(strLineArray[iDate].Substring(0, 4)) >= Convert.ToInt32(annualPMAnalysisConfiguration.monitorInput.startYear)
                                && Convert.ToInt32(strLineArray[iDate].Substring(0, 4)) <= Convert.ToInt32(annualPMAnalysisConfiguration.monitorInput.endYear)
                            && Convert.ToDouble(strLineArray[iPM25]) >= 0
                            )
                        {
                            bool isOK = true;
                            //if (annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialEPADeletionChoice && !annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialUserDeletionChoice)
                            {
                                #region epa deletion
                                if (strLineArray[iEpaFlag].Replace("\"", "") == "0" && strLineArray[iEpaFlag].Length > 0)
                                {
                                    isOK = ReadUnofficialMonitorsDaily(ref dicUnofficialMonitorsDaily, strLineArray, ref  dicDaily1, ref  dicDaily2, ref  dicDaily3, ref  dicDaily4, ref  dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref  dicQYDaily4, ref  iID, ref iType, ref iLat, ref  iLong, ref iDate, ref  iPM25, ref iEpaFlag, ref iUserFlag, ref  id, ref date, ref  type, ref  count, ref  quarter, ref dicIdType);
                                }
                                #endregion
                            }
                            //else if (annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialUserDeletionChoice && !annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialEPADeletionChoice)
                            //{
                            //    #region user deletion
                            //    if (strLineArray[iUserFlag].Replace("\"", "") == "0" && strLineArray[iUserFlag].Length > 0)
                            //    {
                            //        isOK = ReadUnofficialMonitorsDaily(ref dicUnofficialMonitorsDaily, strLineArray, ref  dicDaily1, ref  dicDaily2, ref  dicDaily3, ref  dicDaily4, ref  dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref  dicQYDaily4, ref  iID, ref iType, ref iLat, ref  iLong, ref iDate, ref  iPM25, ref iEpaFlag, ref iUserFlag, ref  id, ref date, ref  type, ref  count, ref  quarter, ref dicIdType);
                            //    }
                            //    #endregion
                            //}
                            //else if (annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialUserDeletionChoice && annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialEPADeletionChoice)
                            //{
                            //    #region epa && user deletion
                            //    if (strLineArray[iEpaFlag].Replace("\"", "") == "0" && strLineArray[iEpaFlag].Length > 0 && strLineArray[iUserFlag] == "0" && strLineArray[iUserFlag].Length > 0)
                            //    {
                            //        isOK = ReadUnofficialMonitorsDaily(ref dicUnofficialMonitorsDaily, strLineArray, ref  dicDaily1, ref  dicDaily2, ref  dicDaily3, ref  dicDaily4, ref  dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref  dicQYDaily4, ref  iID, ref iType, ref iLat, ref  iLong, ref iDate, ref  iPM25, ref iEpaFlag, ref iUserFlag, ref  id, ref date, ref  type, ref  count, ref  quarter, ref dicIdType);
                            //    }
                            //    #endregion
                            //}
                            //else if (!annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialUserDeletionChoice && !annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialEPADeletionChoice)
                            //{
                            //    #region none
                            //    isOK = ReadUnofficialMonitorsDaily(ref dicUnofficialMonitorsDaily, strLineArray, ref  dicDaily1, ref  dicDaily2, ref  dicDaily3, ref  dicDaily4, ref  dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref  dicQYDaily4, ref  iID, ref iType, ref iLat, ref  iLong, ref iDate, ref  iPM25, ref iEpaFlag, ref iUserFlag, ref  id, ref date, ref  type, ref  count, ref  quarter, ref dicIdType);
                            //    #endregion
                            //}
                            if (!isOK)
                                return "unknow";
                        }
                        if (csv.EndOfStream)
                        {
                            for (int j = 1; j <= 4; j++)
                            {
                                switch (j)
                                {
                                    case 1:
                                        quarter = "1";
                                        if (dicQYDaily1.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily1);
                                        break;
                                    case 2:
                                        quarter = "2";
                                        if (dicQYDaily2.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily2);
                                        break;
                                    case 3:
                                        quarter = "3";
                                        if (dicQYDaily3.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily3);
                                        break;
                                    case 4:
                                        quarter = "4";
                                        if (dicQYDaily4.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily4);
                                        break;
                                }
                            }
                        }
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                #endregion
                //if (!isOKinfilter)
                //    return "errorRow";
                return error;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }

        }

        public static bool ReadUnofficialMonitorsDaily(ref Dictionary<string, PMMonitorOutput> dicUnofficialMonitorsDaily, string[] strLineArray, ref Dictionary<string, float> dicDaily1, ref Dictionary<string, float> dicDaily2, ref Dictionary<string, float> dicDaily3, ref Dictionary<string, float> dicDaily4,
           ref Dictionary<string, Dictionary<string, float>> dicQYDaily1, ref Dictionary<string, Dictionary<string, float>> dicQYDaily2, ref Dictionary<string, Dictionary<string, float>> dicQYDaily3, ref Dictionary<string, Dictionary<string, float>> dicQYDaily4,
           ref int iID, ref int iType, ref int iLat, ref int iLong, ref int iDate, ref int iPM25, ref int iEpaFlag, ref int iUserFlag, ref string id, ref string date, ref string type, ref int count, ref string quarter, ref Dictionary<string, string> dicIdType)
        {
            try
            {
                if (strLineArray[iID].Replace("\"", "") == id.Replace("^IMPROVE", "").Replace("\"", "") && strLineArray[iDate].Replace("\"", "").Substring(0, 4) == date && strLineArray[iType].Replace("\"", "") == type)
                {
                    switch (strLineArray[iDate].Replace("\"", "").Substring(4, 2))
                    {
                        case "01":
                        case "02":
                        case "03":
                            if (dicQYDaily1.ContainsKey(date))
                            {
                                dicQYDaily1[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily1.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily1.Add(date, dicDaily1);
                            }
                            break;
                        case "04":
                        case "05":
                        case "06":
                            if (dicQYDaily2.ContainsKey(date))
                            {
                                dicQYDaily2[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily2.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily2.Add(date, dicDaily2);
                            }
                            break;
                        case "07":
                        case "08":
                        case "09":
                            if (dicQYDaily3.ContainsKey(date))
                            {
                                dicQYDaily3[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily3.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily3.Add(date, dicDaily3);
                            }
                            break;
                        case "10":
                        case "11":
                        case "12":
                            if (dicQYDaily4.ContainsKey(date))
                            {
                                dicQYDaily4[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily4.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily4.Add(date, dicDaily4);
                            }
                            break;
                    }
                    count++;
                }
                else
                {
                    if (count > 0)
                    {
                        if (strLineArray[iID].Replace("\"", "") != id.Replace("^IMPROVE", "").Replace("\"", ""))
                        {
                            //为每年的四个季度添加pm25的值
                            #region
                            for (int j = 1; j <= 4; j++)
                            {
                                switch (j)
                                {
                                    case 1:
                                        quarter = "1";
                                        if (dicQYDaily1.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily1);
                                        break;
                                    case 2:
                                        quarter = "2";
                                        if (dicQYDaily2.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily2);
                                        break;
                                    case 3:
                                        quarter = "3";
                                        if (dicQYDaily3.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily3);
                                        break;
                                    case 4:
                                        quarter = "4";
                                        if (dicQYDaily4.Count > 0)
                                            dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily4);
                                        break;
                                }
                            }
                            #endregion
                            count = 0;
                            dicDaily1 = new Dictionary<string, float>();
                            dicDaily3 = new Dictionary<string, float>();
                            dicDaily4 = new Dictionary<string, float>();
                            dicDaily2 = new Dictionary<string, float>();
                            dicQYDaily1 = new Dictionary<string, Dictionary<string, float>>();
                            dicQYDaily2 = new Dictionary<string, Dictionary<string, float>>();
                            dicQYDaily3 = new Dictionary<string, Dictionary<string, float>>();
                            dicQYDaily4 = new Dictionary<string, Dictionary<string, float>>();
                        }
                        else
                        {
                            if (id != strLineArray[iID].Replace("\"", "") + "^IMPROVE" && dicIdType.ContainsKey(id + "^IMPROVE"))
                            {
                                for (int j = 1; j <= 4; j++)
                                {
                                    switch (j)
                                    {
                                        case 1:
                                            quarter = "1";
                                            if (dicQYDaily1.Count > 0)
                                                dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily1);
                                            break;
                                        case 2:
                                            quarter = "2";
                                            if (dicQYDaily2.Count > 0)
                                                dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily2);
                                            break;
                                        case 3:
                                            quarter = "3";
                                            if (dicQYDaily3.Count > 0)
                                                dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily3);
                                            break;
                                        case 4:
                                            quarter = "4";
                                            if (dicQYDaily4.Count > 0)
                                                dicUnofficialMonitorsDaily[id].dicUnofficialPMDaily.Add(quarter, dicQYDaily4);
                                            break;
                                    }
                                }
                                count = 0;
                                dicDaily1 = new Dictionary<string, float>();
                                dicDaily3 = new Dictionary<string, float>();
                                dicDaily4 = new Dictionary<string, float>();
                                dicDaily2 = new Dictionary<string, float>();
                                dicQYDaily1 = new Dictionary<string, Dictionary<string, float>>();
                                dicQYDaily2 = new Dictionary<string, Dictionary<string, float>>();
                                dicQYDaily3 = new Dictionary<string, Dictionary<string, float>>();
                                dicQYDaily4 = new Dictionary<string, Dictionary<string, float>>();
                            }
                        }
                        dicDaily1 = new Dictionary<string, float>();
                        dicDaily3 = new Dictionary<string, float>();
                        dicDaily4 = new Dictionary<string, float>();
                        dicDaily2 = new Dictionary<string, float>();
                    }

                    id = strLineArray[iID].Replace("\"", "");
                    if (strLineArray[iType].Replace("\"", "") == "IMPROVE")
                    {
                        if (dicIdType.ContainsKey(id + "^IMPROVE"))
                        {
                            id = id + "^IMPROVE";
                        }
                    }
                    type = strLineArray[iType].Replace("\"", "");
                    date = strLineArray[iDate].Substring(0, 4).Replace("\"", "").ToString();
                    if (!dicUnofficialMonitorsDaily.ContainsKey(id))
                    {
                        dicUnofficialMonitorsDaily.Add(id, new PMMonitorOutput()
                        {
                            id = id,
                            type = strLineArray[iType].Replace("\"", ""),
                            latitude = Convert.ToDouble(strLineArray[iLat]),
                            longitude = Convert.ToDouble(strLineArray[iLong]),
                            dicUnofficialPMDaily = new Dictionary<string, Dictionary<string, Dictionary<string, float>>>(),
                            //dicUnofficialPM = new Dictionary<string,double>(),
                        });
                    }
                    switch (strLineArray[iDate].Substring(4, 2).Replace("\"", ""))
                    {
                        case "01":
                        case "02":
                        case "03":
                            if (dicQYDaily1.ContainsKey(date))
                            {
                                dicQYDaily1[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily1.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily1.Add(date, dicDaily1);
                            }
                            break;
                        case "04":
                        case "05":
                        case "06":
                            if (dicQYDaily2.ContainsKey(date))
                            {
                                dicQYDaily2[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily2.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily2.Add(date, dicDaily2);
                            }
                            break;
                        case "07":
                        case "08":
                        case "09":
                            if (dicQYDaily3.ContainsKey(date))
                            {
                                dicQYDaily3[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily3.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily3.Add(date, dicDaily3);
                            }
                            break;
                        case "10":
                        case "11":
                        case "12":
                            if (dicQYDaily4.ContainsKey(date))
                            {
                                dicQYDaily4[date].Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                            }
                            else
                            {
                                dicDaily4.Add(strLineArray[iDate].Replace("\"", ""), Convert.ToSingle(strLineArray[iPM25]));
                                dicQYDaily4.Add(date, dicDaily4);
                            }
                            break;
                    }
                    count++;
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool RecalculateUnofficialMonitorsForSpatialField(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref  Dictionary<string, PMMonitorOutput> dicUnofficialPmSpatial, Dictionary<string, PMMonitorOutput> dicUnofficialMonitorsDaily, Dictionary<string, string> dicMinQuarters, Dictionary<string, string> dicMonitorInModelUnofficial)
        {
            try
            {
                //--------------unofficial pm---------min requirements-----------
                //------pm25 values for spatial field has different min requirements from point----------
                #region unofficial pm
                #region min requirements
                //-------mini days per quarter and min years per quarter
                List<string> lstYears = new List<string>();
                Dictionary<string, List<string>> dicMinYearPerQuarter = new Dictionary<string, List<string>>();
                Dictionary<string, Dictionary<string, List<string>>> dicMinDaysYears = new Dictionary<string, Dictionary<string, List<string>>>();
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicUnofficialMonitorsDaily)
                {
                    if (k.Value.type.Replace("\"", "") != "FRM" && k.Value.type.Replace("\"", "") != "IMPROVE") continue;
                    dicMinYearPerQuarter = new Dictionary<string, List<string>>();
                    foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, float>>> kQ in k.Value.dicUnofficialPMDaily)
                    {
                        lstYears = new List<string>();
                        foreach (KeyValuePair<string, Dictionary<string, float>> kYear in kQ.Value)
                        {
                            if (kYear.Value.Count >= 11)//annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialMinDays)
                            {
                                lstYears.Add(kYear.Key);
                            }
                        }
                        if (lstYears.Count >= 1)//annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialMinYears)
                        {
                            dicMinYearPerQuarter.Add(kQ.Key, lstYears);
                        }
                    }
                    dicMinDaysYears.Add(k.Key, dicMinYearPerQuarter);
                }

                //-----------min quarters per monitors--------------
                dicMinQuarters = new Dictionary<string, string>();
                foreach (KeyValuePair<string, Dictionary<string, List<string>>> k in dicMinDaysYears)
                {
                    if (k.Value.Count >= 1)//annualPMAnalysisConfiguration.speciesFractionOptionsA.unofficialMinSeasonsSpatial)
                    {
                        dicMinQuarters.Add(k.Key, k.Key);
                    }
                }
                #endregion

                //Dictionary<string, PMMonitorOutput> dicUnofficialPmSpatial = new Dictionary<string, PMMonitorOutput>();
                //----------quarterly average for spatial field--------------
                #region
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicUnofficialMonitorsDaily)
                {
                    if (!dicMinQuarters.ContainsKey(k.Key)) continue;
                    dicUnofficialPmSpatial.Add(k.Key, new PMMonitorOutput()
                    {
                        id = k.Value.id,
                        type = k.Value.type,
                        stateName = k.Value.stateName,
                        countyName = k.Value.countyName,
                        latitude = k.Value.latitude,
                        longitude = k.Value.longitude,
                        gridcell = dicMonitorInModelUnofficial[k.Key],
                        dicUnofficialPM = new Dictionary<string, float>(),
                    });
                    double pm = 0;
                    foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, float>>> kQ in k.Value.dicUnofficialPMDaily)
                    {
                        pm = 0;
                        var query = dicMinDaysYears[k.Key].Where(p => p.Key == kQ.Key).Select(p => p.Value);
                        if (query.Count() > 0)
                        {
                            List<string> lst = query.First().ToList();
                            int iListCount = lst.Count();
                            for (int i = 0; i < iListCount; i++)
                            {
                                pm += kQ.Value[lst[i]].Select(p => p.Value).Average();
                            }
                            dicUnofficialPmSpatial[k.Key].dicUnofficialPM.Add(kQ.Key, Convert.ToSingle(Math.Round(Convert.ToSingle(pm / iListCount), CommonClass.Pm_defaultformat)));
                        }
                    }
                }
                #endregion
                #endregion
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static string GetSpeciesMonitors(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, Dictionary<string, PMMonitorOutput> dicSpeciesMonitors)
        {
            try
            {
                #region read species monitor data
                //字段索引值
                int iID = -1, iType = -1, iLat = -1, iLong = -1, iDate = -1, iSO4 = -1, iNO3 = -1, iNH4 = -1, iOC = -1, iEC = -1, iCrustal = -1, iEpaFlag = -1, iUserFlag = -1;
                int iNO3r = -1, iSalt = -1, iDON = -1, iOCB = -1;
                string quarter = "";
                //string error = "";
                //bool isOKinfilter = true;
                FileStream fs = new FileStream(annualPMAnalysisConfiguration.speciesMonitorInput.speciesMonitorDataFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    string strLine = csv.ReadLine();
                    string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                    int i = 0;
                    //----------get index for each field------------
                    #region
                    while (i < strLineArray.Length)
                    {
                        string s = strLineArray[i];
                        switch (s.Trim().ToLower().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_type":
                                iType = i;
                                break;
                            case "lat":
                                iLat = i;
                                break;
                            case "long":
                                iLong = i;
                                break;
                            case "date":
                                iDate = i;
                                break;
                            case "so4":
                                iSO4 = i;
                                break;
                            case "no3r":
                                iNO3r = i;
                                break;
                            case "nh4":
                                iNH4 = i;
                                break;
                            case "ocb":
                                iOCB = i;
                                break;
                            case "ec":
                                iEC = i;
                                break;
                            case "crustal":
                                iCrustal = i;
                                break;
                            case "salt":
                                iSalt = i;
                                break;
                            case "don":
                                iDON = i;
                                break;
                            case "no3":
                                iNO3 = i;
                                break;
                            case "epa_flag":
                                iEpaFlag = i;
                                break;
                            case "user_flag":
                                iUserFlag = i;
                                break;
                        }
                        i++;
                    }
                    #endregion
                    Dictionary<string, SpeciesMonitors> dicDaily1 = new Dictionary<string, SpeciesMonitors>();
                    Dictionary<string, SpeciesMonitors> dicDaily2 = new Dictionary<string, SpeciesMonitors>();
                    Dictionary<string, SpeciesMonitors> dicDaily3 = new Dictionary<string, SpeciesMonitors>();
                    Dictionary<string, SpeciesMonitors> dicDaily4 = new Dictionary<string, SpeciesMonitors>();
                    Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily1 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                    Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily2 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                    Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily3 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                    Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily4 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                    int count = 0;
                    string id = "", date = "";
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        //try
                        //{
                        strLineArray = strLine.Split(new char[] { ',' });
                        //对于各种species，首先必须将其值为null，或者负数的全部设为null，OCB除外，对于OCB为负数的值不需要设为null，否则结果不能与SMAT_CE的相匹配
                        if (Convert.ToInt32(strLineArray[iDate].Replace("\"", "").Substring(0, 4)) >= Convert.ToInt32(annualPMAnalysisConfiguration.monitorInput.startYear)
                                && Convert.ToInt32(strLineArray[iDate].Replace("\"", "").Substring(0, 4)) <= Convert.ToInt32(annualPMAnalysisConfiguration.monitorInput.endYear))
                        {
                            bool isOK = true;
                            //if (annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_EPADeletionChoice && !annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_UserDeletionChoice)
                            {
                                #region epa deletion
                                if (strLineArray[iEpaFlag].Replace("\"", "") == "0" && strLineArray[iEpaFlag].Length > 0)
                                {
                                    isOK = ReadSpecieatedMonitorsDaily(ref dicSpeciesMonitors, strLineArray, ref dicDaily1, ref dicDaily2, ref dicDaily3, ref dicDaily4, ref dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref dicQYDaily4, ref iID, ref iType, ref iLat, ref iLong, ref iDate, ref iSO4, ref iNO3, ref iNH4, ref iOC, ref iEC, ref iCrustal, ref iEpaFlag, ref iUserFlag, ref iNO3r, ref iSalt, ref iDON, ref iOCB, ref id, ref date, ref count, ref quarter);
                                }
                                #endregion
                            }
                            //else if (!annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_UserDeletionChoice && annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_UserDeletionChoice)
                            //{
                            //    #region epa deletion
                            //    if (strLineArray[iUserFlag].Replace("\"", "") == "0" && strLineArray[iUserFlag].Length > 0)
                            //    {
                            //        isOK = ReadSpecieatedMonitorsDaily(ref dicSpeciesMonitors, strLineArray, ref dicDaily1, ref dicDaily2, ref dicDaily3, ref dicDaily4, ref dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref dicQYDaily4, ref iID, ref iType, ref iLat, ref iLong, ref iDate, ref iSO4, ref iNO3, ref iNH4, ref iOC, ref iEC, ref iCrustal, ref iEpaFlag, ref iUserFlag, ref iNO3r, ref iSalt, ref iDON, ref iOCB, ref id, ref date, ref count, ref quarter);
                            //    }
                            //    #endregion
                            //}
                            //else if (annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_UserDeletionChoice && annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_UserDeletionChoice)
                            //{
                            //    #region epa && user deletion
                            //    if (strLineArray[iUserFlag].Replace("\"", "") == "0" && strLineArray[iUserFlag].Length > 0 && strLineArray[iEpaFlag] == "0" && strLineArray[iEpaFlag].Length > 0)
                            //    {
                            //        isOK = ReadSpecieatedMonitorsDaily(ref dicSpeciesMonitors, strLineArray, ref dicDaily1, ref dicDaily2, ref dicDaily3, ref dicDaily4, ref dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref dicQYDaily4, ref iID, ref iType, ref iLat, ref iLong, ref iDate, ref iSO4, ref iNO3, ref iNH4, ref iOC, ref iEC, ref iCrustal, ref iEpaFlag, ref iUserFlag, ref iNO3r, ref iSalt, ref iDON, ref iOCB, ref id, ref date, ref count, ref quarter);
                            //    }
                            //    #endregion
                            //}
                            //else if (!annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_UserDeletionChoice && !annualPMAnalysisConfiguration.speciesFractionOptionsA.IMPROVESTN_UserDeletionChoice)
                            //{
                            //    #region none deletion
                            //    isOK = ReadSpecieatedMonitorsDaily(ref dicSpeciesMonitors, strLineArray, ref dicDaily1, ref dicDaily2, ref dicDaily3, ref dicDaily4, ref dicQYDaily1, ref dicQYDaily2, ref dicQYDaily3, ref dicQYDaily4, ref iID, ref iType, ref iLat, ref iLong, ref iDate, ref iSO4, ref iNO3, ref iNH4, ref iOC, ref iEC, ref iCrustal, ref iEpaFlag, ref iUserFlag, ref iNO3r, ref iSalt, ref iDON, ref iOCB, ref id, ref date, ref count, ref quarter);
                            //    #endregion
                            //}
                            if (!isOK)
                                return "unknow";
                        }
                        //}
                        //catch
                        //{
                        //    error = "errorRow";
                        //}
                        //----------------读取到文件末尾------------
                        if (csv.EndOfStream)
                        {
                            for (int j = 1; j <= 4; j++)
                            {
                                switch (j)
                                {
                                    case 1:
                                        quarter = "1";
                                        if (dicQYDaily1.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily1);
                                        break;
                                    case 2:
                                        quarter = "2";
                                        if (dicQYDaily2.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily2);
                                        break;
                                    case 3:
                                        quarter = "3";
                                        if (dicQYDaily3.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily3);
                                        break;
                                    case 4:
                                        quarter = "4";
                                        if (dicQYDaily4.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily4);
                                        break;
                                }
                            }
                        }
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                #endregion
                //if (!isOKinfilter)
                //    return "errorRow";
                return "";
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }

        }

        public static bool ReadSpecieatedMonitorsDaily(ref Dictionary<string, PMMonitorOutput> dicSpeciesMonitors, string[] strLineArray, ref Dictionary<string, SpeciesMonitors> dicDaily1, ref Dictionary<string, SpeciesMonitors> dicDaily2, ref Dictionary<string, SpeciesMonitors> dicDaily3, ref Dictionary<string, SpeciesMonitors> dicDaily4, ref Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily1, ref Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily2, ref Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily3, ref Dictionary<string, Dictionary<string, SpeciesMonitors>> dicQYDaily4,
             ref int iID, ref int iType, ref int iLat, ref int iLong, ref int iDate, ref int iSO4, ref int iNO3, ref int iNH4, ref int iOC, ref int iEC, ref int iCrustal, ref int iEpaFlag, ref int iUserFlag, ref int iNO3r, ref int iSalt, ref int iDON, ref int iOCB, ref string id, ref string date, ref int count, ref string quarter)
        {
            try
            {
                if (strLineArray[iID].Replace("\"", "") == id && strLineArray[iDate].Replace("\"", "").Substring(0, 4) == date)
                {
                    switch (strLineArray[iDate].Replace("\"", "").Substring(4, 2))
                    {
                        case "01":
                        case "02":
                        case "03":
                            if (dicQYDaily1.ContainsKey(date))
                            {
                                dicQYDaily1[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily1.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily1.Add(date, dicDaily1);
                            }
                            break;
                        case "04":
                        case "05":
                        case "06":
                            if (dicQYDaily2.ContainsKey(date))
                            {
                                dicQYDaily2[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily2.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily2.Add(date, dicDaily2);
                            }
                            break;
                        case "07":
                        case "08":
                        case "09":
                            if (dicQYDaily3.ContainsKey(date))
                            {
                                dicQYDaily3[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily3.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily3.Add(date, dicDaily3);
                            }
                            break;
                        case "10":
                        case "11":
                        case "12":
                            if (dicQYDaily4.ContainsKey(date))
                            {
                                dicQYDaily4[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily4.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily4.Add(date, dicDaily4);
                            }
                            break;
                    }
                }
                else
                {
                    if (count > 0)
                    {
                        if (strLineArray[iID].Replace("\"", "") != id)
                        {
                            for (int j = 1; j <= 4; j++)
                            {
                                switch (j)
                                {
                                    case 1:
                                        quarter = "1";
                                        if (dicQYDaily1.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily1);
                                        break;
                                    case 2:
                                        quarter = "2";
                                        if (dicQYDaily2.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily2);
                                        break;
                                    case 3:
                                        quarter = "3";
                                        if (dicQYDaily3.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily3);
                                        break;
                                    case 4:
                                        quarter = "4";
                                        if (dicQYDaily4.Count > 0)
                                            dicSpeciesMonitors[id].dicSpeciesDaily.Add(quarter, dicQYDaily4);
                                        break;
                                }
                            }
                            count = 0;
                            dicDaily1 = new Dictionary<string, SpeciesMonitors>();
                            dicDaily3 = new Dictionary<string, SpeciesMonitors>();
                            dicDaily4 = new Dictionary<string, SpeciesMonitors>();
                            dicDaily2 = new Dictionary<string, SpeciesMonitors>();
                            dicQYDaily1 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                            dicQYDaily2 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                            dicQYDaily3 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                            dicQYDaily4 = new Dictionary<string, Dictionary<string, SpeciesMonitors>>();
                        }
                        dicDaily1 = new Dictionary<string, SpeciesMonitors>();
                        dicDaily3 = new Dictionary<string, SpeciesMonitors>();
                        dicDaily4 = new Dictionary<string, SpeciesMonitors>();
                        dicDaily2 = new Dictionary<string, SpeciesMonitors>();
                    }

                    id = strLineArray[iID].Replace("\"", "");
                    date = strLineArray[iDate].Replace("\"", "").Substring(0, 4).ToString();
                    if (!dicSpeciesMonitors.ContainsKey(strLineArray[iID].Replace("\"", "")))
                    {
                        dicSpeciesMonitors.Add(strLineArray[iID].Replace("\"", ""), new PMMonitorOutput()
                        {
                            id = strLineArray[iID].Replace("\"", ""),
                            type = strLineArray[iType].Replace("\"", ""),
                            latitude = Convert.ToDouble(strLineArray[iLat]),
                            longitude = Convert.ToDouble(strLineArray[iLong]),
                            dicSpeciesDaily = new Dictionary<string, Dictionary<string, Dictionary<string, SpeciesMonitors>>>(),
                            dicSpecies = new Dictionary<string, SpeciesMonitors>(),
                        });
                    }
                    switch (strLineArray[iDate].Replace("\"", "").Substring(4, 2))
                    {
                        case "01":
                        case "02":
                        case "03":
                            if (dicQYDaily1.ContainsKey(date))
                            {
                                dicQYDaily1[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily1.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily1.Add(date, dicDaily1);
                            }
                            break;
                        case "04":
                        case "05":
                        case "06":
                            if (dicQYDaily2.ContainsKey(date))
                            {
                                dicQYDaily2[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily2.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily2.Add(date, dicDaily2);
                            }
                            break;
                        case "07":
                        case "08":
                        case "09":
                            if (dicQYDaily3.ContainsKey(date))
                            {
                                dicQYDaily3[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily3.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily3.Add(date, dicDaily3);
                            }
                            break;
                        case "10":
                        case "11":
                        case "12":
                            if (dicQYDaily4.ContainsKey(date))
                            {
                                dicQYDaily4[date].Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),

                                });
                            }
                            else
                            {
                                dicDaily4.Add(strLineArray[iDate].Replace("\"", ""), new SpeciesMonitors()
                                {
                                    bCrustalMass = strLineArray[iCrustal] == "" && strLineArray[iCrustal].Length == 0 || Convert.ToSingle(strLineArray[iCrustal]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iCrustal]),
                                    bECMass = strLineArray[iEC] == "" && strLineArray[iEC].Length == 0 || Convert.ToSingle(strLineArray[iEC]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iEC]),
                                    bOCBMass = strLineArray[iOCB] == "" && strLineArray[iOCB].Length == 0 ? float.NaN : Convert.ToSingle(strLineArray[iOCB]),
                                    bSO4Mass = strLineArray[iSO4] == "" && strLineArray[iSO4].Length == 0 || Convert.ToSingle(strLineArray[iSO4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSO4]),
                                    bNO3Mass = strLineArray[iNO3] == "" && strLineArray[iNO3].Length == 0 || Convert.ToSingle(strLineArray[iNO3]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3]),
                                    bNO3rMass = strLineArray[iNO3r] == "" && strLineArray[iNO3r].Length == 0 || Convert.ToSingle(strLineArray[iNO3r]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNO3r]),
                                    bNH4Mass = strLineArray[iNH4] == "" && strLineArray[iNH4].Length == 0 || Convert.ToSingle(strLineArray[iNH4]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iNH4]),
                                    bSaltMass = strLineArray[iSalt] == "" && strLineArray[iSalt].Length == 0 || Convert.ToSingle(strLineArray[iSalt]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iSalt]),
                                    bDON = strLineArray[iDON] == "" && strLineArray[iDON].Length == 0 || Convert.ToSingle(strLineArray[iDON]) < 0 ? float.NaN : Convert.ToSingle(strLineArray[iDON]),
                                });
                                dicQYDaily4.Add(date, dicDaily4);
                            }
                            break;
                    }
                    count++;
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool GetQuarterlyAverageSpecies(ref Dictionary<string, PMMonitorOutput> dicSpeciesMonitors, Dictionary<string, string> dicMinQuarters, Dictionary<string, string> dicMonitorInModelSpecies, Dictionary<string, Dictionary<string, List<string>>> dicMinDaysYears)
        {
            try
            {
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeciesMonitors)
                {
                    if (!dicMinQuarters.ContainsKey(k.Key)) continue;
                    k.Value.gridcell = dicMonitorInModelSpecies[k.Key];
                    Dictionary<string, SpeciesMonitors> dic = new Dictionary<string, SpeciesMonitors>();
                    foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, SpeciesMonitors>>> kQ in k.Value.dicSpeciesDaily)
                    {
                        dic = new Dictionary<string, SpeciesMonitors>();
                        var query = dicMinDaysYears[k.Key].Where(p => p.Key == kQ.Key).Select(p => p.Value);
                        if (query.Count() > 0)
                        {
                            List<string> lst = query.First().ToList();
                            int iListCount = lst.Count();
                            int cCrustal = 0, cEC = 0, cOCB = 0, cSO4 = 0, cNO3r = 0, cNO3 = 0, cNH4 = 0, cSalt = 0, cDON = 0;
                            for (int i = 0; i < iListCount; i++)
                            {
                                if (dic.ContainsKey(kQ.Key))
                                {
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bCrustalMass)).Select(p => p.Value.bCrustalMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bCrustalMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bCrustalMass)).Select(p => p.Value.bCrustalMass).Average();
                                        cCrustal++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bECMass)).Select(p => p.Value.bECMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bECMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bECMass)).Select(p => p.Value.bECMass).Average();
                                        cEC++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bOCBMass)).Select(p => p.Value.bOCBMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bOCBMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bOCBMass)).Select(p => p.Value.bOCBMass).Average();
                                        cOCB++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSO4Mass)).Select(p => p.Value.bSO4Mass).Count() > 0)
                                    {
                                        dic[kQ.Key].bSO4Mass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSO4Mass)).Select(p => p.Value.bSO4Mass).Average();
                                        cSO4++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3rMass)).Select(p => p.Value.bNO3rMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bNO3rMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3rMass)).Select(p => p.Value.bNO3rMass).Average();
                                        cNO3r++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3Mass)).Select(p => p.Value.bNO3Mass).Count() > 0)
                                    {
                                        dic[kQ.Key].bNO3Mass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3Mass)).Select(p => p.Value.bNO3Mass).Average();
                                        cNO3++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNH4Mass)).Select(p => p.Value.bNH4Mass).Count() > 0)
                                    {
                                        dic[kQ.Key].bNH4Mass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNH4Mass)).Select(p => p.Value.bNH4Mass).Average();
                                        cNH4++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSaltMass)).Select(p => p.Value.bSaltMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bSaltMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSaltMass)).Select(p => p.Value.bSaltMass).Average();
                                        cSalt++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bDON)).Select(p => p.Value.bDON).Count() > 0)
                                    {
                                        dic[kQ.Key].bDON += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bDON)).Select(p => p.Value.bDON).Average();
                                        cDON++;
                                    }
                                }
                                else
                                {
                                    dic.Add(kQ.Key, new SpeciesMonitors());
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bCrustalMass)).Select(p => p.Value.bCrustalMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bCrustalMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bCrustalMass)).Select(p => p.Value.bCrustalMass).Average();
                                        cCrustal++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bECMass)).Select(p => p.Value.bECMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bECMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bECMass)).Select(p => p.Value.bECMass).Average();
                                        cEC++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bOCBMass)).Select(p => p.Value.bOCBMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bOCBMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bOCBMass)).Select(p => p.Value.bOCBMass).Average();
                                        cOCB++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSO4Mass)).Select(p => p.Value.bSO4Mass).Count() > 0)
                                    {
                                        dic[kQ.Key].bSO4Mass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSO4Mass)).Select(p => p.Value.bSO4Mass).Average();
                                        cSO4++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3rMass)).Select(p => p.Value.bNO3rMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bNO3rMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3rMass)).Select(p => p.Value.bNO3rMass).Average();
                                        cNO3r++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3Mass)).Select(p => p.Value.bNO3Mass).Count() > 0)
                                    {
                                        dic[kQ.Key].bNO3Mass += Convert.ToSingle(Math.Round(kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNO3Mass)).Select(p => p.Value.bNO3Mass).Average(), 8));
                                        cNO3++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNH4Mass)).Select(p => p.Value.bNH4Mass).Count() > 0)
                                    {
                                        dic[kQ.Key].bNH4Mass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bNH4Mass)).Select(p => p.Value.bNH4Mass).Average();
                                        cNH4++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSaltMass)).Select(p => p.Value.bSaltMass).Count() > 0)
                                    {
                                        dic[kQ.Key].bSaltMass += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bSaltMass)).Select(p => p.Value.bSaltMass).Average();
                                        cSalt++;
                                    }
                                    if (kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bDON)).Select(p => p.Value.bDON).Count() > 0)
                                    {
                                        dic[kQ.Key].bDON += kQ.Value[lst[i]].Where(p => !Double.IsNaN(p.Value.bDON)).Select(p => p.Value.bDON).Average();
                                        cDON++;
                                    }
                                }
                            }

                            k.Value.dicSpecies.Add(kQ.Key, new SpeciesMonitors()
                            {
                                bCrustalMass = Convert.ToSingle(Math.Round(dic[kQ.Key].bCrustalMass / cCrustal, CommonClass.Species_calc_precision)),
                                bECMass = Convert.ToSingle(Math.Round(dic[kQ.Key].bECMass / cEC, CommonClass.Species_calc_precision)),
                                bOCBMass = Convert.ToSingle(Math.Round(dic[kQ.Key].bOCBMass / cOCB, CommonClass.Species_calc_precision)),
                                bSO4Mass = Convert.ToSingle(Math.Round(dic[kQ.Key].bSO4Mass / cSO4, CommonClass.Species_calc_precision)),
                                bNO3rMass = Convert.ToSingle(Math.Round(dic[kQ.Key].bNO3rMass / cNO3r, CommonClass.Species_calc_precision)),
                                bNO3Mass = Convert.ToSingle(Math.Round(dic[kQ.Key].bNO3Mass / cNO3, CommonClass.Species_calc_precision)),
                                bNH4Mass = Convert.ToSingle(Math.Round(dic[kQ.Key].bNH4Mass / cNH4, CommonClass.Species_calc_precision)),
                                bSaltMass = Convert.ToSingle(Math.Round(dic[kQ.Key].bSaltMass / cSalt, CommonClass.Species_calc_precision)),
                                bDON = Convert.ToSingle(Math.Round(dic[kQ.Key].bDON / cDON, CommonClass.Species_calc_precision)),
                            });
                        }
                    }
                    k.Value.dicSpeciesDaily.Clear();
                    GC.Collect();
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static string GetSpeciesFractionPoint(AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref Dictionary<string, PMMonitorOutput> dicSpeciesFractions)
        {
            try
            {
                #region
                int iID = -1, iLat = -1, iLong = -1, iDate = -1, iPM25 = -1, iSO4 = -1, iNO3 = -1, iOC = -1, iEC = -1, iCrustal = -1, iNH4 = -1, iFcr = -1, iFec = -1, iFnh4 = -1, iFocm = -1, iFso4 = -1, iFno3 = -1,
                    iFwater = -1, iFsalt = -1, iBlankMass = -1, iDON = -1, iIdon = -1, iNO3r = -1, iSalt = -1, iStateName = -1, iCountyName = -1;
                FileStream fs = new FileStream(annualPMAnalysisConfiguration.dataInputA.specFracPointFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    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().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "_state_name":
                                iStateName = i;
                                break;
                            case "_county_name":
                                iCountyName = i;
                                break;
                            case "monitor_lat":
                                iLat = i;
                                break;
                            case "monitor_long":
                                iLong = i;
                                break;
                            case "quarter":
                                iDate = i;
                                break;
                            case "pm25_mass_frac":
                                iPM25 = i;
                                break;
                            case "fcr":
                                iFcr = i;
                                break;
                            case "fec":
                                iFec = i;
                                break;
                            case "fnh4":
                                iFnh4 = i;
                                break;
                            case "focm":
                                iFocm = i;
                                break;
                            case "fso4":
                                iFso4 = i;
                                break;
                            case "fno3":
                                iFno3 = i;
                                break;
                            case "fwater":
                                iFwater = i;
                                break;
                            case "fsalt":
                                iFsalt = i;
                                break;
                            case "blank_mass":
                                iBlankMass = i;
                                break;
                            case "don":
                                iDON = i;
                                break;
                            case "i_so4":
                                iSO4 = i;
                                break;
                            case "i_no3r":
                                iNO3r = i;
                                break;
                            case "i_ocb":
                                iOC = i;
                                break;
                            case "i_ec":
                                iEC = i;
                                break;
                            case "i_crustal":
                                iCrustal = i;
                                break;
                            case "i_don":
                                iIdon = i;
                                break;
                            case "i_nh4":
                                iNH4 = i;
                                break;
                            case "i_no3":
                                iNO3 = i;
                                break;
                            case "i_salt":
                                iSalt = i;
                                break;
                        }
                        i++;
                    }
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        strLineArray = strLine.Split(new char[] { ',' });
                        if (dicSpeciesFractions.ContainsKey(strLineArray[iID].Replace("\"", "")))
                        {
                            dicSpeciesFractions[strLineArray[iID].Replace("\"", "")].dicSpeciesFraction.Add(strLineArray[iDate].Replace("\"", ""), new SpecFracPM()
                            {
                                pm25MassFrac = Convert.ToDouble(strLineArray[iPM25]),
                                fCr = Convert.ToDouble(strLineArray[iFcr]),
                                fEC = Convert.ToDouble(strLineArray[iFec]),
                                fNH4 = Convert.ToDouble(strLineArray[iFnh4]),
                                fOcm = Convert.ToDouble(strLineArray[iFocm]),
                                fSO4 = Convert.ToDouble(strLineArray[iFso4]),
                                fNO3r = Convert.ToDouble(strLineArray[iFno3]),
                                fWater = Convert.ToDouble(strLineArray[iFwater]),
                                fSalt = Convert.ToDouble(strLineArray[iFsalt]),
                                blankMass = Convert.ToDouble(strLineArray[iBlankMass]),
                                don = Convert.ToDouble(strLineArray[iDON]),
                                iSO4 = Convert.ToDouble(strLineArray[iSO4]),
                                iNO3r = Convert.ToDouble(strLineArray[iNO3r]),
                                iOcb = Convert.ToDouble(strLineArray[iOC]),
                                iEC = Convert.ToDouble(strLineArray[iEC]),
                                iCrustal = Convert.ToDouble(strLineArray[iCrustal]),
                                iDON = Convert.ToDouble(strLineArray[iIdon]),
                                iNH4 = Convert.ToDouble(strLineArray[iNH4]),
                                iNO3 = Convert.ToDouble(strLineArray[iNO3]),
                                iSalt = Convert.ToDouble(strLineArray[iSalt]),
                            });
                        }
                        else
                        {
                            dicSpeciesFractions.Add(strLineArray[iID].Replace("\"", ""), new PMMonitorOutput()
                            {
                                id = strLineArray[iID].Replace("\"", ""),
                                latitude = Convert.ToDouble(strLineArray[iLat]),
                                longitude = Convert.ToDouble(strLineArray[iLong]),
                                stateName = strLineArray[iStateName].Replace("\"", ""),
                                countyName = strLineArray[iCountyName].Replace("\"", ""),
                                dicSpeciesFraction = new Dictionary<string, SpecFracPM>(),
                            });
                            dicSpeciesFractions[strLineArray[iID].Replace("\"", "")].dicSpeciesFraction.Add(strLineArray[iDate].Replace("\"", ""), new SpecFracPM()
                            {
                                pm25MassFrac = Convert.ToDouble(strLineArray[iPM25]),
                                fCr = Convert.ToDouble(strLineArray[iFcr]),
                                fEC = Convert.ToDouble(strLineArray[iFec]),
                                fNH4 = Convert.ToDouble(strLineArray[iFnh4]),
                                fOcm = Convert.ToDouble(strLineArray[iFocm]),
                                fSO4 = Convert.ToDouble(strLineArray[iFso4]),
                                fNO3r = Convert.ToDouble(strLineArray[iFno3]),
                                fWater = Convert.ToDouble(strLineArray[iFwater]),
                                fSalt = Convert.ToDouble(strLineArray[iFsalt]),
                                blankMass = Convert.ToDouble(strLineArray[iBlankMass]),
                                don = Convert.ToDouble(strLineArray[iDON]),
                                iSO4 = Convert.ToDouble(strLineArray[iSO4]),
                                iNO3r = Convert.ToDouble(strLineArray[iNO3r]),
                                iOcb = Convert.ToDouble(strLineArray[iOC]),
                                iEC = Convert.ToDouble(strLineArray[iEC]),
                                iCrustal = Convert.ToDouble(strLineArray[iCrustal]),
                                iDON = Convert.ToDouble(strLineArray[iIdon]),
                                iNH4 = Convert.ToDouble(strLineArray[iNH4]),
                                iNO3 = Convert.ToDouble(strLineArray[iNO3]),
                                iSalt = Convert.ToDouble(strLineArray[iSalt]),
                            });
                        }
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                #endregion
                return "";
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }

        }

        public static string GetSpeciesFractionSpatialField(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref Dictionary<string, PMMonitorOutput> dicSpecFracSpatial)
        {
            try
            {
                #region
                int iID = -1, iLat = -1, iLong = -1, iDate = -1, iPM25 = -1, iSO4 = -1, iNO3 = -1, iOC = -1, iEC = -1, iCrustal = -1, iNH4 = -1, iFcr = -1, iFec = -1, iFnh4 = -1, iFocm = -1, iFso4 = -1, iFno3 = -1,
                    iFwater = -1, iFsalt = -1, iBlankMass = -1, iDON = -1, iIdon = -1, iNO3r = -1, iSalt = -1;
                FileStream fs = new FileStream(annualPMAnalysisConfiguration.speciesMonitorInput.specFracSpatialFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    string strLine = csv.ReadLine();
                    string[] strLineArray = csv.ReadLine().Split(new char[] { ',' });
                    int i = 0;
                    #region
                    while (i < strLineArray.Length)
                    {
                        string s = strLineArray[i];
                        switch (s.Trim().ToLower().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "gridcell_lat":
                                iLat = i;
                                break;
                            case "gridcell_long":
                                iLong = i;
                                break;
                            case "quarter":
                                iDate = i;
                                break;
                            case "pm25_mass_frac":
                                iPM25 = i;
                                break;
                            case "fcr":
                                iFcr = i;
                                break;
                            case "fec":
                                iFec = i;
                                break;
                            case "fnh4":
                                iFnh4 = i;
                                break;
                            case "focm":
                                iFocm = i;
                                break;
                            case "fso4":
                                iFso4 = i;
                                break;
                            case "fno3":
                                iFno3 = i;
                                break;
                            case "fwater":
                                iFwater = i;
                                break;
                            case "fsalt":
                                iFsalt = i;
                                break;
                            case "blank_mass":
                                iBlankMass = i;
                                break;
                            case "don":
                                iDON = i;
                                break;
                            case "i_so4":
                                iSO4 = i;
                                break;
                            case "i_no3r":
                                iNO3r = i;
                                break;
                            case "i_ocb":
                                iOC = i;
                                break;
                            case "i_ec":
                                iEC = i;
                                break;
                            case "i_crustal":
                                iCrustal = i;
                                break;
                            case "i_don":
                                iIdon = i;
                                break;
                            case "i_nh4":
                                iNH4 = i;
                                break;
                            case "i_no3":
                                iNO3 = i;
                                break;
                            case "i_salt":
                                iSalt = i;
                                break;
                        }
                        i++;
                    }
                    #endregion
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        strLineArray = strLine.Split(new char[] { ',' });
                        if (dicSpecFracSpatial.ContainsKey(strLineArray[iID].Replace("\"", "")))
                        {
                            dicSpecFracSpatial[strLineArray[iID].Replace("\"", "")].dicSpecFracSpatial.Add(strLineArray[iDate].Replace("\"", ""), new SpecFracPM()
                            {
                                pm25MassFrac = Convert.ToDouble(strLineArray[iPM25]),
                                fCr = Convert.ToDouble(strLineArray[iFcr]),
                                fEC = Convert.ToDouble(strLineArray[iFec]),
                                fNH4 = Convert.ToDouble(strLineArray[iFnh4]),
                                fOcm = Convert.ToDouble(strLineArray[iFocm]),
                                fSO4 = Convert.ToDouble(strLineArray[iFso4]),
                                fNO3r = Convert.ToDouble(strLineArray[iFno3]),
                                fWater = Convert.ToDouble(strLineArray[iFwater]),
                                fSalt = Convert.ToDouble(strLineArray[iFsalt]),
                                blankMass = Convert.ToDouble(strLineArray[iBlankMass]),
                                don = Convert.ToDouble(strLineArray[iDON]),
                                iSO4 = Convert.ToDouble(strLineArray[iSO4]),
                                iNO3r = Convert.ToDouble(strLineArray[iNO3r]),
                                iOcb = Convert.ToDouble(strLineArray[iOC]),
                                iEC = Convert.ToDouble(strLineArray[iEC]),
                                iCrustal = Convert.ToDouble(strLineArray[iCrustal]),
                                iDON = Convert.ToDouble(strLineArray[iIdon]),
                                iNH4 = Convert.ToDouble(strLineArray[iNH4]),
                                iNO3 = Convert.ToDouble(strLineArray[iNO3]),
                                iSalt = Convert.ToDouble(strLineArray[iSalt]),
                            });
                        }
                        else
                        {
                            dicSpecFracSpatial.Add(strLineArray[iID].Replace("\"", ""), new PMMonitorOutput()
                            {
                                id = strLineArray[iID].Replace("\"", ""),
                                latitude = Convert.ToDouble(strLineArray[iLat]),
                                longitude = Convert.ToDouble(strLineArray[iLong]),
                                //stateName = strLineArray[iStateName].Replace("\"", ""),
                                //countyName = strLineArray[iCountyName].Replace("\"", ""),
                                dicSpecFracSpatial = new Dictionary<string, SpecFracPM>(),
                            });
                            dicSpecFracSpatial[strLineArray[iID].Replace("\"", "")].dicSpecFracSpatial.Add(strLineArray[iDate].Replace("\"", ""), new SpecFracPM()
                            {
                                pm25MassFrac = Convert.ToDouble(strLineArray[iPM25]),
                                fCr = Convert.ToDouble(strLineArray[iFcr]),
                                fEC = Convert.ToDouble(strLineArray[iFec]),
                                fNH4 = Convert.ToDouble(strLineArray[iFnh4]),
                                fOcm = Convert.ToDouble(strLineArray[iFocm]),
                                fSO4 = Convert.ToDouble(strLineArray[iFso4]),
                                fNO3r = Convert.ToDouble(strLineArray[iFno3]),
                                fWater = Convert.ToDouble(strLineArray[iFwater]),
                                fSalt = Convert.ToDouble(strLineArray[iFsalt]),
                                blankMass = Convert.ToDouble(strLineArray[iBlankMass]),
                                don = Convert.ToDouble(strLineArray[iDON]),
                                iSO4 = Convert.ToDouble(strLineArray[iSO4]),
                                iNO3r = Convert.ToDouble(strLineArray[iNO3r]),
                                iOcb = Convert.ToDouble(strLineArray[iOC]),
                                iEC = Convert.ToDouble(strLineArray[iEC]),
                                iCrustal = Convert.ToDouble(strLineArray[iCrustal]),
                                iDON = Convert.ToDouble(strLineArray[iIdon]),
                                iNH4 = Convert.ToDouble(strLineArray[iNH4]),
                                iNO3 = Convert.ToDouble(strLineArray[iNO3]),
                                iSalt = Convert.ToDouble(strLineArray[iSalt]),
                            });
                        }
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                #endregion
                return "";
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }
        }

        public static string GetSpeciesFractionSpatialFieldGradAdj(BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration, ref Dictionary<string, PMMonitorOutput> dicSpecFracSpatial)
        {
            try
            {
                #region
                int iID = -1, iLat = -1, iLong = -1, iDate = -1, iPM25 = -1, iSO4 = -1, iNO3 = -1, iOC = -1, iEC = -1, iCrustal = -1, iNH4 = -1, iFcr = -1, iFec = -1, iFnh4 = -1, iFocm = -1, iFso4 = -1, iFno3 = -1,
                    iFwater = -1, iFsalt = -1, iBlankMass = -1, iDON = -1, iIdon = -1, iNO3r = -1, iSalt = -1;
                FileStream fs = new FileStream(annualPMAnalysisConfiguration.speciesMonitorInput.gradAdjSpecFracSpatialFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using (StreamReader csv = new StreamReader(fs, System.Text.Encoding.UTF8))
                {
                    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().Replace("\"", ""))
                        {
                            case "_id":
                                iID = i;
                                break;
                            case "gridcell_lat":
                                iLat = i;
                                break;
                            case "gridcell_long":
                                iLong = i;
                                break;
                            case "quarter":
                                iDate = i;
                                break;
                            case "pm25_mass_frac_ga":
                                iPM25 = i;
                                break;
                            case "fcr_ga":
                                iFcr = i;
                                break;
                            case "fec_ga":
                                iFec = i;
                                break;
                            case "fnh4_ga":
                                iFnh4 = i;
                                break;
                            case "focm_ga":
                                iFocm = i;
                                break;
                            case "fso4_ga":
                                iFso4 = i;
                                break;
                            case "fno3_ga":
                                iFno3 = i;
                                break;
                            case "fwater_ga":
                                iFwater = i;
                                break;
                            case "fsalt_ga":
                                iFsalt = i;
                                break;
                            case "blank_mass_ga":
                                iBlankMass = i;
                                break;
                            case "don_ga":
                                iDON = i;
                                break;
                            case "i_so4_ga":
                                iSO4 = i;
                                break;
                            case "i_no3r_ga":
                                iNO3r = i;
                                break;
                            case "i_ocb_ga":
                                iOC = i;
                                break;
                            case "i_ec_ga":
                                iEC = i;
                                break;
                            case "i_crustal_ga":
                                iCrustal = i;
                                break;
                            case "i_don_ga":
                                iIdon = i;
                                break;
                            case "i_nh4_ga":
                                iNH4 = i;
                                break;
                            case "i_no3_ga":
                                iNO3 = i;
                                break;
                            case "i_salt_ga":
                                iSalt = i;
                                break;
                        }
                        i++;
                    }
                    while (strLine != null)
                    {
                        strLine = csv.ReadLine();
                        if (strLine == null) break;
                        strLineArray = strLine.Split(new char[] { ',' });
                        if (dicSpecFracSpatial.ContainsKey(strLineArray[iID].Replace("\"", "")))
                        {
                            if (dicSpecFracSpatial[strLineArray[iID].Replace("\"", "")].dicSpecFracSpatialGradAdj == null)
                                dicSpecFracSpatial[strLineArray[iID].Replace("\"", "")].dicSpecFracSpatialGradAdj = new Dictionary<string, SpecFracPM>();
                            dicSpecFracSpatial[strLineArray[iID].Replace("\"", "")].dicSpecFracSpatialGradAdj.Add(strLineArray[iDate].Replace("\"", ""), new SpecFracPM()
                            {
                                pm25MassFrac = Convert.ToDouble(strLineArray[iPM25]),
                                fCr = Convert.ToDouble(strLineArray[iFcr]),
                                fEC = Convert.ToDouble(strLineArray[iFec]),
                                fNH4 = Convert.ToDouble(strLineArray[iFnh4]),
                                fOcm = Convert.ToDouble(strLineArray[iFocm]),
                                fSO4 = Convert.ToDouble(strLineArray[iFso4]),
                                fNO3r = Convert.ToDouble(strLineArray[iFno3]),
                                fWater = Convert.ToDouble(strLineArray[iFwater]),
                                fSalt = Convert.ToDouble(strLineArray[iFsalt]),
                                blankMass = Convert.ToDouble(strLineArray[iBlankMass]),
                                don = Convert.ToDouble(strLineArray[iDON]),
                                iSO4 = Convert.ToDouble(strLineArray[iSO4]),
                                iNO3r = Convert.ToDouble(strLineArray[iNO3r]),
                                iOcb = Convert.ToDouble(strLineArray[iOC]),
                                iEC = Convert.ToDouble(strLineArray[iEC]),
                                iCrustal = Convert.ToDouble(strLineArray[iCrustal]),
                                iDON = Convert.ToDouble(strLineArray[iIdon]),
                                iNH4 = Convert.ToDouble(strLineArray[iNH4]),
                                iNO3 = Convert.ToDouble(strLineArray[iNO3]),
                                iSalt = Convert.ToDouble(strLineArray[iSalt]),
                            });
                        }
                        else
                        {
                            dicSpecFracSpatial.Add(strLineArray[iID].Replace("\"", ""), new PMMonitorOutput()
                            {
                                id = strLineArray[iID].Replace("\"", ""),
                                latitude = Convert.ToDouble(strLineArray[iLat]),
                                longitude = Convert.ToDouble(strLineArray[iLong]),
                                //stateName = strLineArray[iStateName].Replace("\"", ""),
                                //countyName = strLineArray[iCountyName].Replace("\"", ""),
                                dicSpecFracSpatialGradAdj = new Dictionary<string, SpecFracPM>(),
                            });
                            dicSpecFracSpatial[strLineArray[iID].Replace("\"", "")].dicSpecFracSpatialGradAdj.Add(strLineArray[iDate].Replace("\"", ""), new SpecFracPM()
                            {
                                pm25MassFrac = Convert.ToDouble(strLineArray[iPM25]),
                                fCr = Convert.ToDouble(strLineArray[iFcr]),
                                fEC = Convert.ToDouble(strLineArray[iFec]),
                                fNH4 = Convert.ToDouble(strLineArray[iFnh4]),
                                fOcm = Convert.ToDouble(strLineArray[iFocm]),
                                fSO4 = Convert.ToDouble(strLineArray[iFso4]),
                                fNO3r = Convert.ToDouble(strLineArray[iFno3]),
                                fWater = Convert.ToDouble(strLineArray[iFwater]),
                                fSalt = Convert.ToDouble(strLineArray[iFsalt]),
                                blankMass = Convert.ToDouble(strLineArray[iBlankMass]),
                                don = Convert.ToDouble(strLineArray[iDON]),
                                iSO4 = Convert.ToDouble(strLineArray[iSO4]),
                                iNO3r = Convert.ToDouble(strLineArray[iNO3r]),
                                iOcb = Convert.ToDouble(strLineArray[iOC]),
                                iEC = Convert.ToDouble(strLineArray[iEC]),
                                iCrustal = Convert.ToDouble(strLineArray[iCrustal]),
                                iDON = Convert.ToDouble(strLineArray[iIdon]),
                                iNH4 = Convert.ToDouble(strLineArray[iNH4]),
                                iNO3 = Convert.ToDouble(strLineArray[iNO3]),
                                iSalt = Convert.ToDouble(strLineArray[iSalt]),
                            });
                        }
                    }
                    csv.Dispose(); fs.Dispose();
                    GC.Collect();
                }
                #endregion
                return "";
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return "unknow";
            }
        }
        #endregion

        #region Save files
        public static bool SaveQuarterlyModelDataCopyDirectly(BaseScenario baseScenario, Dictionary<string, PmModelDataOutput> dicModelData)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
            {
                return false;
            }
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                #region
                File.Copy((CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).dataInputA.baselineModelDataFile, _resultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName + " Baseline Quarterly Avg Model Data.csv", true);
                FileInfo fileInfo = null;
                if (CommonClass.CurrentBaseScenario.lstOutput == null)
                    CommonClass.CurrentBaseScenario.lstOutput = new List<BaseOutput>();
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Baseline Quarterly Avg Model Data.csv";
                BaseOutput baseOutput = new BaseOutput();
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);

                strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Future Quarterly Avg Model Data.csv";
                baseOutput = new BaseOutput();
                File.Copy((CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).dataInputA.forecastModelDataFile, _resultFilePath + @"\" + strFile, true);
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                #endregion

                //added by yangwenwei 
                //added by Yangwenwei 20131220
                DataTable dtDeltaModelData = new DataTable();
                //Construct the DataTable "dtDeltaModelData". added by Yangwenwei 20131219
                dtDeltaModelData.Columns.Add("_id");
                dtDeltaModelData.Columns.Add("_type");
                dtDeltaModelData.Columns.Add("lat");
                dtDeltaModelData.Columns.Add("long");
                dtDeltaModelData.Columns.Add("date");
                dtDeltaModelData.Columns.Add("DeltaC(crustal)");
                dtDeltaModelData.Columns.Add("DeltaC(nh4)");
                dtDeltaModelData.Columns.Add("DeltaC(so4)");
                dtDeltaModelData.Columns.Add("DeltaC(ec)");
                dtDeltaModelData.Columns.Add("DeltaC(no3)");
                dtDeltaModelData.Columns.Add("DeltaC(oc)");
                dtDeltaModelData.Columns.Add("DeltaC(pm25)");
                dtDeltaModelData.Columns.Add("DeltaC(cm)");

                //read data in dicQuarterlyModel and write Delta data
                dicModelData = dicModelData.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                foreach (KeyValuePair<string, PmModelDataOutput> k in dicModelData)
                {
                    foreach (KeyValuePair<string, ModelDataSpecies> kFuture in dicModelData[k.Key].dicFutureModel)
                    {
                        DataRow drDelta = dtDeltaModelData.NewRow();
                        drDelta[0] = k.Key;
                        drDelta[1] = k.Value.type;
                        drDelta[2] = Math.Round(k.Value.lat, 6);
                        drDelta[3] = Math.Round(k.Value.longitude, 6);
                        switch (kFuture.Key)
                        {
                            case "1":
                                drDelta[4] = "01";
                                break;
                            case "2":
                                drDelta[4] = "04";
                                break;
                            case "3":
                                drDelta[4] = "07";
                                break;
                            case "4":
                                drDelta[4] = "10";
                                break;
                        }
                        drDelta[5] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].crustal - kFuture.Value.crustal, 8);
                        drDelta[6] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].nh4 - kFuture.Value.nh4, 8);
                        drDelta[7] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].so4 - kFuture.Value.so4, 8);
                        drDelta[8] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].ec - kFuture.Value.ec, 8);
                        drDelta[9] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].no3 - kFuture.Value.no3, 8);
                        drDelta[10] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].oc - kFuture.Value.oc, 8);
                        drDelta[11] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].pm25 - kFuture.Value.pm25, 8);
                        drDelta[12] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].cm - kFuture.Value.cm, 8);
                        dtDeltaModelData.Rows.Add(drDelta);
                    }
                }

                //create Delta CSV added by Yangwenwei 20131219
                strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Delta Quarterly Avg Model Data.csv";
                baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtDeltaModelData, _resultFilePath + @"\" + strFile, "Quarter");
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                CommonClass.CurrentBaseScenario.lstOutput.Add(baseOutput);
                dtDeltaModelData.Dispose();//end
                GC.Collect();


                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        /// <summary>
        /// 保存quarterly model data
        /// </summary>
        /// <param name="baseScenario"></param>
        /// <param name="dicModelData"></param>
        /// <param name="baseModelYear">base year</param>
        /// <param name="futureModelYear">control year</param>
        /// <returns></returns>
        public static bool SaveModelDataQuarterly(BaseScenario baseScenario, Dictionary<string, PmModelDataOutput> dicModelData, string baseModelYear, string futureModelYear)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
            {
                return false;
            }
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dtBaseline = new DataTable();
                DataTable dtFuture = new DataTable();
                DataTable dtDelta = new DataTable();
                DataRow dr = null;
                DataRow drDelta = null;
                dtBaseline.Columns.Add("_id");
                dtBaseline.Columns.Add("_type");
                dtBaseline.Columns.Add("lat");
                dtBaseline.Columns.Add("long");
                dtBaseline.Columns.Add("date");
                dtBaseline.Columns.Add("crustal");
                dtBaseline.Columns.Add("nh4");
                dtBaseline.Columns.Add("so4");
                dtBaseline.Columns.Add("ec");
                dtBaseline.Columns.Add("no3");
                dtBaseline.Columns.Add("oc");
                dtBaseline.Columns.Add("pm25");
                dtBaseline.Columns.Add("cm");

                dtFuture.Columns.Add("_id");
                dtFuture.Columns.Add("_type");
                dtFuture.Columns.Add("lat");
                dtFuture.Columns.Add("long");
                dtFuture.Columns.Add("date");
                dtFuture.Columns.Add("crustal");
                dtFuture.Columns.Add("nh4");
                dtFuture.Columns.Add("so4");
                dtFuture.Columns.Add("ec");
                dtFuture.Columns.Add("no3");
                dtFuture.Columns.Add("oc");
                dtFuture.Columns.Add("pm25");
                dtFuture.Columns.Add("cm");

                dtDelta.Columns.Add("_id");
                dtDelta.Columns.Add("_type");
                dtDelta.Columns.Add("lat");
                dtDelta.Columns.Add("long");
                dtDelta.Columns.Add("date");
                dtDelta.Columns.Add("DeltaC(crustal)");
                dtDelta.Columns.Add("DeltaC(nh4)");
                dtDelta.Columns.Add("DeltaC(so4)");
                dtDelta.Columns.Add("DeltaC(ec)");
                dtDelta.Columns.Add("DeltaC(no3)");
                dtDelta.Columns.Add("DeltaC(oc)");
                dtDelta.Columns.Add("DeltaC(pm25)");
                dtDelta.Columns.Add("DeltaC(cm)");

                dicModelData = dicModelData.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                foreach (KeyValuePair<string, PmModelDataOutput> k in dicModelData)
                {
                    foreach (KeyValuePair<string, ModelDataSpecies> kBase in k.Value.dicBaselineModel)
                    {
                        dr = dtBaseline.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = k.Value.type;
                        dr[2] = Math.Round(k.Value.lat, 6);
                        dr[3] = Math.Round(k.Value.longitude, 6);
                        switch (kBase.Key)
                        {
                            case "1":
                                dr[4] = baseModelYear + "01";
                                break;
                            case "2":
                                dr[4] = baseModelYear + "04";
                                break;
                            case "3":
                                dr[4] = baseModelYear + "07";
                                break;
                            case "4":
                                dr[4] = baseModelYear + "10";
                                break;
                        }
                        dr[5] = Math.Round(kBase.Value.crustal, CommonClass.Species_calc_precision);
                        dr[6] = Math.Round(kBase.Value.nh4, CommonClass.Species_calc_precision);
                        dr[7] = Math.Round(kBase.Value.so4, CommonClass.Species_calc_precision);
                        dr[8] = Math.Round(kBase.Value.ec, CommonClass.Species_calc_precision);
                        dr[9] = Math.Round(kBase.Value.no3, CommonClass.Species_calc_precision);
                        dr[10] = Math.Round(kBase.Value.oc, CommonClass.Species_calc_precision);
                        dr[11] = Math.Round(kBase.Value.pm25, CommonClass.Species_calc_precision);
                        dr[12] = Math.Round(kBase.Value.cm, CommonClass.Species_calc_precision);
                        dtBaseline.Rows.Add(dr);
                    }

                    foreach (KeyValuePair<string, ModelDataSpecies> kFuture in k.Value.dicFutureModel)
                    {
                        dr = dtFuture.NewRow();
                        drDelta = dtDelta.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = k.Value.type;
                        dr[2] = Math.Round(k.Value.lat, 6);
                        dr[3] = Math.Round(k.Value.longitude, 6);
                        drDelta[0] = k.Value.id;
                        drDelta[1] = k.Value.type;
                        drDelta[2] = Math.Round(k.Value.lat, 6);
                        drDelta[3] = Math.Round(k.Value.longitude, 6);
                        switch (kFuture.Key)
                        {
                            case "1":
                                dr[4] = futureModelYear + "01";
                                drDelta[4] = "01";
                                break;
                            case "2":
                                dr[4] = futureModelYear + "04";
                                drDelta[4] = "04";
                                break;
                            case "3":
                                dr[4] = futureModelYear + "07";
                                drDelta[4] = "07";
                                break;
                            case "4":
                                dr[4] = futureModelYear + "10";
                                drDelta[4] = "10";
                                break;
                        }
                        dr[5] = Math.Round(kFuture.Value.crustal, CommonClass.Species_calc_precision);
                        dr[6] = Math.Round(kFuture.Value.nh4, CommonClass.Species_calc_precision);
                        dr[7] = Math.Round(kFuture.Value.so4, CommonClass.Species_calc_precision);
                        dr[8] = Math.Round(kFuture.Value.ec, CommonClass.Species_calc_precision);
                        dr[9] = Math.Round(kFuture.Value.no3, CommonClass.Species_calc_precision);
                        dr[10] = Math.Round(kFuture.Value.oc, CommonClass.Species_calc_precision);
                        dr[11] = Math.Round(kFuture.Value.pm25, CommonClass.Species_calc_precision);
                        dr[12] = Math.Round(kFuture.Value.cm, CommonClass.Species_calc_precision);
                        dtFuture.Rows.Add(dr);
                        drDelta[5] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].crustal - kFuture.Value.crustal, CommonClass.Species_calc_precision);
                        drDelta[6] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].nh4 - kFuture.Value.nh4, CommonClass.Species_calc_precision);
                        drDelta[7] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].so4 - kFuture.Value.so4, CommonClass.Species_calc_precision);
                        drDelta[8] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].ec - kFuture.Value.ec, CommonClass.Species_calc_precision);
                        drDelta[9] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].no3 - kFuture.Value.no3, CommonClass.Species_calc_precision);
                        drDelta[10] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].oc - kFuture.Value.oc, CommonClass.Species_calc_precision);
                        drDelta[11] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].pm25 - kFuture.Value.pm25, CommonClass.Species_calc_precision);
                        drDelta[12] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].cm - kFuture.Value.cm, CommonClass.Species_calc_precision);
                        dtDelta.Rows.Add(drDelta);
                    }
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Baseline Quarterly Avg Model Data.csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtBaseline, _resultFilePath + @"\" + strFile, "Quarter");
                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);

                strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Future Quarterly Avg Model Data.csv";
                baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtFuture, _resultFilePath + @"\" + strFile, "Quarter");
                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);

                strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Delta Quarterly Avg Model Data.csv";
                baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtDelta, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtBaseline.Dispose();
                dtFuture.Dispose();
                dtDelta.Dispose();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveUsedModelDataQuarterly(BaseScenario baseScenario, Dictionary<string, PmModelDataOutput> dicModelData, string baseModelYear, string futureModelYear, List<string> lstUsedModelData)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dtBaseline = new DataTable();
                DataTable dtFuture = new DataTable();
                DataTable dtDelta = new DataTable();//added by Yangwenwei 
                DataRow drDelta = null;
                DataRow dr = null;
                dtBaseline.Columns.Add("_id");
                dtBaseline.Columns.Add("_type");
                dtBaseline.Columns.Add("lat");
                dtBaseline.Columns.Add("long");
                dtBaseline.Columns.Add("date");
                dtBaseline.Columns.Add("crustal");
                dtBaseline.Columns.Add("nh4");
                dtBaseline.Columns.Add("so4");
                dtBaseline.Columns.Add("ec");
                dtBaseline.Columns.Add("no3");
                dtBaseline.Columns.Add("oc");
                dtBaseline.Columns.Add("pm25");
                dtBaseline.Columns.Add("cm");

                dtFuture.Columns.Add("_id");
                dtFuture.Columns.Add("_type");
                dtFuture.Columns.Add("lat");
                dtFuture.Columns.Add("long");
                dtFuture.Columns.Add("date");
                dtFuture.Columns.Add("crustal");
                dtFuture.Columns.Add("nh4");
                dtFuture.Columns.Add("so4");
                dtFuture.Columns.Add("ec");
                dtFuture.Columns.Add("no3");
                dtFuture.Columns.Add("oc");
                dtFuture.Columns.Add("pm25");
                dtFuture.Columns.Add("cm");


                //Construct the DataTable "dtDelta". added by Yangwenwei 20131219
                dtDelta.Columns.Add("_id");
                dtDelta.Columns.Add("_type");
                dtDelta.Columns.Add("lat");
                dtDelta.Columns.Add("long");
                dtDelta.Columns.Add("date");
                dtDelta.Columns.Add("DeltaC(crustal)");
                dtDelta.Columns.Add("DeltaC(nh4)");
                dtDelta.Columns.Add("DeltaC(so4)");
                dtDelta.Columns.Add("DeltaC(ec)");
                dtDelta.Columns.Add("DeltaC(no3)");
                dtDelta.Columns.Add("DeltaC(oc)");
                dtDelta.Columns.Add("DeltaC(pm25)");
                dtDelta.Columns.Add("DeltaC(cm)");//end

                lstUsedModelData.Sort();
                dicModelData = dicModelData.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                foreach (KeyValuePair<string, PmModelDataOutput> k in dicModelData)
                {
                    if (!lstUsedModelData.Contains(k.Key)) continue;
                    foreach (KeyValuePair<string, ModelDataSpecies> kBase in k.Value.dicBaselineModel)
                    {
                        dr = dtBaseline.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = k.Value.type;
                        dr[2] = Math.Round(k.Value.lat, 6);
                        dr[3] = Math.Round(k.Value.longitude, 6);
                        switch (kBase.Key)
                        {
                            case "1":
                                dr[4] = baseModelYear + "01";
                                break;
                            case "2":
                                dr[4] = baseModelYear + "04";
                                break;
                            case "3":
                                dr[4] = baseModelYear + "07";
                                break;
                            case "4":
                                dr[4] = baseModelYear + "10";
                                break;
                        }
                        dr[5] = Math.Round(kBase.Value.crustal, CommonClass.Species_calc_precision);
                        dr[6] = Math.Round(kBase.Value.nh4, CommonClass.Species_calc_precision);
                        dr[7] = Math.Round(kBase.Value.so4, CommonClass.Species_calc_precision);
                        dr[8] = Math.Round(kBase.Value.ec, CommonClass.Species_calc_precision);
                        dr[9] = Math.Round(kBase.Value.no3, CommonClass.Species_calc_precision);
                        dr[10] = Math.Round(kBase.Value.oc, CommonClass.Species_calc_precision);
                        dr[11] = Math.Round(kBase.Value.pm25, CommonClass.Species_calc_precision);
                        dr[12] = Math.Round(kBase.Value.cm, CommonClass.Species_calc_precision);
                        dtBaseline.Rows.Add(dr);
                    }

                    foreach (KeyValuePair<string, ModelDataSpecies> kFuture in k.Value.dicFutureModel)
                    {
                        dr = dtFuture.NewRow();
                        drDelta = dtDelta.NewRow();//added by Yangwenwei

                        dr[0] = k.Value.id;
                        dr[1] = k.Value.type;
                        dr[2] = Math.Round(k.Value.lat, 6);
                        dr[3] = Math.Round(k.Value.longitude, 6);
                        switch (kFuture.Key)
                        {
                            case "1":
                                dr[4] = futureModelYear + "01";
                                drDelta[4] = "01";
                                break;
                            case "2":
                                dr[4] = futureModelYear + "04";
                                drDelta[4] = "02";
                                break;
                            case "3":
                                dr[4] = futureModelYear + "07";
                                drDelta[4] = "03";
                                break;
                            case "4":
                                dr[4] = futureModelYear + "10";
                                drDelta[4] = "04";
                                break;
                        }
                        dr[5] = Math.Round(kFuture.Value.crustal, CommonClass.Species_calc_precision);
                        dr[6] = Math.Round(kFuture.Value.nh4, CommonClass.Species_calc_precision);
                        dr[7] = Math.Round(kFuture.Value.so4, CommonClass.Species_calc_precision);
                        dr[8] = Math.Round(kFuture.Value.ec, CommonClass.Species_calc_precision);
                        dr[9] = Math.Round(kFuture.Value.no3, CommonClass.Species_calc_precision);
                        dr[10] = Math.Round(kFuture.Value.oc, CommonClass.Species_calc_precision);
                        dr[11] = Math.Round(kFuture.Value.pm25, CommonClass.Species_calc_precision);
                        dr[12] = Math.Round(kFuture.Value.cm, CommonClass.Species_calc_precision);
                        dtFuture.Rows.Add(dr);

                        //write Delta Data in "dtDelta".added by Yangwenwei 20131219

                        drDelta[0] = k.Key;
                        drDelta[1] = k.Value.type;
                        drDelta[2] = Math.Round(k.Value.lat, 6);
                        drDelta[3] = Math.Round(k.Value.longitude, 6);
                        drDelta[5] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].crustal - kFuture.Value.crustal, CommonClass.Species_calc_precision);
                        drDelta[6] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].nh4 - kFuture.Value.nh4, CommonClass.Species_calc_precision);
                        drDelta[7] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].so4 - kFuture.Value.so4, CommonClass.Species_calc_precision);
                        drDelta[8] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].ec - kFuture.Value.ec, CommonClass.Species_calc_precision);
                        drDelta[9] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].no3 - kFuture.Value.no3, CommonClass.Species_calc_precision);
                        drDelta[10] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].oc - kFuture.Value.oc, CommonClass.Species_calc_precision);
                        drDelta[11] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].pm25 - kFuture.Value.pm25, CommonClass.Species_calc_precision);
                        drDelta[12] = Math.Round(k.Value.dicBaselineModel[kFuture.Key].cm - kFuture.Value.cm, CommonClass.Species_calc_precision);
                        dtDelta.Rows.Add(drDelta);//end
                    }
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }

                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Used Baseline Quarterly Avg Model Data.csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtBaseline, _resultFilePath + @"\" + strFile, "Quarter");
                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);

                strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Used Future Quarterly Avg Model Data.csv";
                baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtFuture, _resultFilePath + @"\" + strFile, "Quarter");
                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);

                //create Delta CSV added by Yangwenwei 20131219
                strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Used Delta Quarterly Avg Model Data.csv";
                baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtDelta, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtDelta.Dispose();//end
                dtBaseline.Dispose();
                dtFuture.Dispose();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        /// <summary>
        /// 保存quarterly pm25 monitors
        /// </summary>
        /// <param name="baseScenario"></param>
        /// <param name="dicUnofficialPM"></param>
        /// <returns></returns>
        public static bool SaveQuarterlyAveragePMMonitors(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicUnofficialPM)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
            {
                return true;
            }
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dt = new DataTable();
                dt.Columns.Add("_id");
                dt.Columns.Add("_type");
                dt.Columns.Add("monitor_lat");
                dt.Columns.Add("monitor_long");
                dt.Columns.Add("monitor_gridcell");
                dt.Columns.Add("quarter");
                dt.Columns.Add("b_pm25_mass");

                dicUnofficialPM = dicUnofficialPM.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicUnofficialPM)
                {
                    foreach (KeyValuePair<string, float> kQ in k.Value.dicUnofficialPM)
                    {
                        DataRow dr = dt.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = k.Value.type;
                        dr[2] = Math.Round(k.Value.latitude, 6);
                        dr[3] = Math.Round(k.Value.longitude, 6);
                        dr[4] = k.Value.gridcell;
                        dr[5] = kQ.Key;
                        //dr[6] = kQ.Value;
                        dr[6] = Math.Round(kQ.Value, CommonClass.Pm_defaultformat);
                        dt.Rows.Add(dr);
                    }
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly Avg PM2.5 Monitors.csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dt, _resultFilePath + @"\" + strFile, "Quarter");
                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.Dispose();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveQuarterlyAverageSpeciatedMonitors(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicSpeices)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
            {
                return false;
            }
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dtSpeciatedMonitors = new DataTable();
                dtSpeciatedMonitors.Columns.Add("_id");
                dtSpeciatedMonitors.Columns.Add("_type");
                dtSpeciatedMonitors.Columns.Add("monitor_lat");
                dtSpeciatedMonitors.Columns.Add("monitor_long");
                dtSpeciatedMonitors.Columns.Add("monitor_gridcell");
                dtSpeciatedMonitors.Columns.Add("quarter");
                dtSpeciatedMonitors.Columns.Add("b_crustal_mass");
                dtSpeciatedMonitors.Columns.Add("b_EC_mass");
                dtSpeciatedMonitors.Columns.Add("b_OCB_mass");
                dtSpeciatedMonitors.Columns.Add("b_SO4_mass");
                dtSpeciatedMonitors.Columns.Add("b_NO3_mass");
                dtSpeciatedMonitors.Columns.Add("b_no3r_mass");
                dtSpeciatedMonitors.Columns.Add("b_salt_mass");

                DataTable dtNH4 = new DataTable();
                dtNH4.Columns.Add("_id");
                dtNH4.Columns.Add("_type");
                dtNH4.Columns.Add("monitor_lat");
                dtNH4.Columns.Add("monitor_long");
                dtNH4.Columns.Add("monitor_gridcell");
                dtNH4.Columns.Add("quarter");
                dtNH4.Columns.Add("b_nh4_mass");
                dtNH4.Columns.Add("b_don");

                foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeices)
                {
                    if (k.Value.dicSpecies.Count == 0) continue;
                    for (int i = 1; i <= 4; i++)
                    {
                        DataRow dr = dtSpeciatedMonitors.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = k.Value.type;
                        dr[2] = Math.Round(k.Value.latitude, 6);
                        dr[3] = Math.Round(k.Value.longitude, 6);
                        dr[4] = k.Value.gridcell;
                        dr[5] = i;
                        if (k.Value.dicSpecies.ContainsKey(Convert.ToString(i)))
                        {
                            dr[6] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bCrustalMass, CommonClass.Species_calc_precision);
                            dr[7] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bECMass, CommonClass.Species_calc_precision);
                            dr[8] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bOCBMass, CommonClass.Species_calc_precision);
                            dr[9] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bSO4Mass, CommonClass.Species_calc_precision);
                            dr[10] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bNO3Mass, CommonClass.Species_calc_precision);
                            dr[11] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bNO3rMass, CommonClass.Species_calc_precision);
                            dr[12] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bSaltMass, CommonClass.Species_calc_precision);
                        }
                        else
                        {
                            dr[6] = -9;
                            dr[7] = -9;
                            dr[8] = -9;
                            dr[9] = -9;
                            dr[10] = -9;
                            dr[11] = -9;
                            dr[12] = -9;
                        }
                        dtSpeciatedMonitors.Rows.Add(dr);
                    }

                    if (k.Value.type.Trim().Replace("\"", "") == "STN")
                    {
                        for (int i = 1; i <= 4; i++)
                        {
                            DataRow drNH = dtNH4.NewRow();
                            drNH[0] = k.Value.id;
                            drNH[1] = k.Value.type;
                            drNH[2] = Math.Round(k.Value.latitude, 6);
                            drNH[3] = Math.Round(k.Value.longitude, 6);
                            drNH[4] = k.Value.gridcell;
                            drNH[5] = i;
                            if (k.Value.dicSpecies.ContainsKey(Convert.ToString(i)))
                            {
                                drNH[6] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bNH4Mass, CommonClass.Species_calc_precision);
                                drNH[7] = Math.Round(k.Value.dicSpecies[Convert.ToString(i)].bDON, CommonClass.Species_calc_precision);
                            }
                            else
                            {
                                drNH[6] = -9;
                                drNH[7] = -9;
                            }
                            dtNH4.Rows.Add(drNH);
                        }
                    }
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly Avg Speciated Monitors.csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtSpeciatedMonitors, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtSpeciatedMonitors.Dispose();

                //修正文件名称
                strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly Avg NH4_DON Monitors.csv";
                baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtNH4, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtNH4.Dispose();

                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveQuarterlySpecFracPointCopyDirectly(BaseScenario baseScenario)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                #region
                File.Copy((CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).dataInputA.specFracPointFile, _resultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName + " Quarterly Avg Spec Frac Point.csv", true);
                FileInfo fileInfo = null;
                if (CommonClass.CurrentBaseScenario.lstOutput == null)
                    CommonClass.CurrentBaseScenario.lstOutput = new List<BaseOutput>();
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly Avg Spec Frac Point.csv";
                BaseOutput baseOutput = new BaseOutput();
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                #endregion
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveQuarterlySpeciesFractionsPoint(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicSpeciesFractions, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration)) return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dt = new DataTable();
                dt.Columns.Add("_id");
                dt.Columns.Add("_STATE_NAME");
                dt.Columns.Add("_COUNTY_NAME");
                dt.Columns.Add("monitor_lat");
                dt.Columns.Add("monitor_long");
                dt.Columns.Add("quarter");
                dt.Columns.Add("pm25_mass_frac");
                dt.Columns.Add("fcr");
                dt.Columns.Add("fec");
                dt.Columns.Add("fnh4");
                dt.Columns.Add("focm");
                dt.Columns.Add("fso4");
                dt.Columns.Add("fno3");
                dt.Columns.Add("fwater");
                dt.Columns.Add("fsalt");
                dt.Columns.Add("blank_mass");
                dt.Columns.Add("don");
                dt.Columns.Add("i_so4");
                dt.Columns.Add("i_no3r");
                dt.Columns.Add("i_ocb");
                dt.Columns.Add("i_ec");
                dt.Columns.Add("i_crustal");
                dt.Columns.Add("i_don");
                dt.Columns.Add("i_nh4");
                dt.Columns.Add("i_no3");
                dt.Columns.Add("i_salt");
                dicSpeciesFractions = dicSpeciesFractions.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpeciesFractions)
                {
                    foreach (KeyValuePair<string, SpecFracPM> kQ in k.Value.dicSpeciesFraction)
                    {
                        DataRow dr = dt.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = k.Value.stateName;
                        dr[2] = k.Value.countyName;
                        dr[3] = Math.Round(k.Value.latitude, 6);
                        dr[4] = Math.Round(k.Value.longitude, 6);
                        dr[5] = kQ.Key;
                        dr[6] = Math.Round(kQ.Value.pm25MassFrac, CommonClass.Pm_defaultformat);
                        dr[7] = Math.Round(kQ.Value.fCr, CommonClass.Species_fraction_precision);
                        dr[8] = Math.Round(kQ.Value.fEC, CommonClass.Species_fraction_precision);
                        dr[9] = Math.Round(kQ.Value.fNH4, CommonClass.Species_fraction_precision);
                        dr[10] = Math.Round(kQ.Value.fOcm, CommonClass.Species_fraction_precision);
                        dr[11] = Math.Round(kQ.Value.fSO4, CommonClass.Species_fraction_precision);
                        dr[12] = Math.Round(kQ.Value.fNO3r, CommonClass.Species_fraction_precision);
                        dr[13] = Math.Round(kQ.Value.fWater, CommonClass.Species_fraction_precision);
                        dr[14] = Math.Round(kQ.Value.fSalt, CommonClass.Species_fraction_precision);
                        dr[15] = Math.Round(kQ.Value.blankMass, CommonClass.Species_calc_precision);
                        dr[16] = Math.Round(kQ.Value.don, CommonClass.Species_calc_precision);
                        dr[17] = Math.Round(kQ.Value.iSO4, CommonClass.Species_calc_precision);
                        dr[18] = Math.Round(kQ.Value.iNO3r, CommonClass.Species_calc_precision);
                        dr[19] = Math.Round(kQ.Value.iOcb, CommonClass.Species_calc_precision);
                        dr[20] = Math.Round(kQ.Value.iEC, CommonClass.Species_calc_precision);
                        dr[21] = Math.Round(kQ.Value.iCrustal, CommonClass.Species_calc_precision);
                        dr[22] = Math.Round(kQ.Value.iDON, CommonClass.Species_calc_precision);
                        dr[23] = Math.Round(kQ.Value.iNH4, CommonClass.Species_calc_precision);
                        dr[24] = Math.Round(kQ.Value.iNO3, CommonClass.Species_calc_precision);
                        dr[25] = Math.Round(kQ.Value.iSalt, CommonClass.Species_calc_precision);
                        dt.Rows.Add(dr);
                    }
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly Avg Spec Frac Point" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dt, _resultFilePath + @"\" + strFile, "Quarter");
                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.Dispose();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveQuarterlyPMPoint(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicQuarterlyPM, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dt = new DataTable();
                dt.Columns.Add("_id");
                dt.Columns.Add("_type");
                dt.Columns.Add("_STATE_NAME");
                dt.Columns.Add("_COUNTY_NAME");
                dt.Columns.Add("monitor_lat");
                dt.Columns.Add("monitor_long");
                dt.Columns.Add("monitor_gridcell");
                dt.Columns.Add("quarter");
                dt.Columns.Add("b_pm25_ann_q_DV");
                dt.Columns.Add("f_pm25_ann_q_DV");
                dt.Columns.Add("b_blank_mass_q");
                dt.Columns.Add("b_crustal_mass_q");
                dt.Columns.Add("b_EC_mass_q");
                dt.Columns.Add("b_NH4_mass_q");
                dt.Columns.Add("b_Ocmb_mass_q");
                dt.Columns.Add("b_SO4_mass_q");
                dt.Columns.Add("b_NO3_mass_q");
                dt.Columns.Add("b_water_mass_q");
                dt.Columns.Add("b_salt_mass_q");
                dt.Columns.Add("f_blank_mass_q");
                dt.Columns.Add("f_crustal_mass_q");
                dt.Columns.Add("f_EC_mass_q");
                dt.Columns.Add("f_NH4_mass_q");
                dt.Columns.Add("f_Ocmb_mass_q");
                dt.Columns.Add("f_SO4_mass_q");
                dt.Columns.Add("f_NO3_mass_q");
                dt.Columns.Add("f_water_mass_q");
                dt.Columns.Add("f_salt_mass_q");
                dt.Columns.Add("rrf_crustal_q");
                dt.Columns.Add("rrf_ec_q");
                dt.Columns.Add("rrf_nh4_q");
                dt.Columns.Add("rrf_oc_q");
                dt.Columns.Add("rrf_so4_q");
                dt.Columns.Add("rrf_no3_q");
                dt.Columns.Add("rrf_salt_q");
                dt.Columns.Add("rrf_water_q");

                dicQuarterlyPM = dicQuarterlyPM.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlyPM)
                {
                    foreach (KeyValuePair<string, PMPoint> kin in k.Value.dicQuarterlyPoint)
                    {
                        DataRow dr = dt.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = k.Value.type;
                        dr[2] = k.Value.stateName;
                        dr[3] = k.Value.countyName;
                        dr[4] = Math.Round(k.Value.latitude, 6);
                        dr[5] = Math.Round(k.Value.longitude, 6);
                        dr[6] = k.Value.gridcell;
                        dr[7] = kin.Key;
                        dr[8] = Math.Round(kin.Value.bPMDV, CommonClass.Pm_defaultformat);
                        dr[9] = Math.Round(kin.Value.fPMDV, CommonClass.Pm_defaultformat);
                        dr[10] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        dr[11] = Math.Round(kin.Value.bCrustalMass, CommonClass.Species_calc_precision);
                        dr[12] = Math.Round(kin.Value.bECMass, CommonClass.Species_calc_precision);
                        dr[13] = Math.Round(kin.Value.bNH4Mass, CommonClass.Species_calc_precision);
                        dr[14] = Math.Round(kin.Value.bOcmbMass, CommonClass.Species_calc_precision);
                        dr[15] = Math.Round(kin.Value.bSO4Mass, CommonClass.Species_calc_precision);
                        dr[16] = Math.Round(kin.Value.bNO3Mass, CommonClass.Species_calc_precision);
                        dr[17] = Math.Round(kin.Value.bWaterMass, CommonClass.Species_calc_precision);
                        dr[18] = Math.Round(kin.Value.bSaltMass, CommonClass.Species_calc_precision);
                        dr[19] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        dr[20] = Math.Round(kin.Value.fCrustalMass, CommonClass.Species_calc_precision);
                        dr[21] = Math.Round(kin.Value.fECMass, CommonClass.Species_calc_precision);
                        dr[22] = Math.Round(kin.Value.fNH4Mass, CommonClass.Species_calc_precision);
                        dr[23] = Math.Round(kin.Value.fOcmbMass, CommonClass.Species_calc_precision);
                        dr[24] = Math.Round(kin.Value.fSO4Mass, CommonClass.Species_calc_precision);
                        dr[25] = Math.Round(kin.Value.fNO3Mass, CommonClass.Species_calc_precision);
                        dr[26] = Math.Round(kin.Value.fWaterMass, CommonClass.Species_calc_precision);
                        dr[27] = Math.Round(kin.Value.fSaltMass, CommonClass.Species_calc_precision);
                        dr[28] = Double.IsNaN(kin.Value.rrfCrustal) ? -9 : Math.Round(kin.Value.rrfCrustal, 4);
                        dr[29] = Double.IsNaN(kin.Value.rrfEC) ? -9 : Math.Round(kin.Value.rrfEC, 4);
                        dr[30] = Double.IsNaN(kin.Value.rrfNH4) ? -9 : Math.Round(kin.Value.rrfNH4, 4);
                        dr[31] = Double.IsNaN(kin.Value.rrfOC) ? -9 : Math.Round(kin.Value.rrfOC, 4);
                        dr[32] = Double.IsNaN(kin.Value.rrfSO4) ? -9 : Math.Round(kin.Value.rrfSO4, 4);
                        dr[33] = Double.IsNaN(kin.Value.rrfNO3) ? -9 : Math.Round(kin.Value.rrfNO3, 4);
                        dr[34] = Double.IsNaN(kin.Value.rrfSalt) ? -9 : Math.Round(kin.Value.rrfSalt, 4);
                        dr[35] = Double.IsNaN(kin.Value.rrfWater) ? -9 : Math.Round(kin.Value.rrfWater, 4);
                        dt.Rows.Add(dr);
                    }
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly PM25 Point" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dt, _resultFilePath + @"\" + strFile, "Quarter");
                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.Dispose();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveAnnualPMPoint(BaseScenario baseScenario, Dictionary<string, PMPoint> dicAnnualPoint, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dt = new DataTable();
                dt.Columns.Add("_id");
                dt.Columns.Add("_type");
                dt.Columns.Add("_STATE_NAME");
                dt.Columns.Add("_COUNTY_NAME");
                dt.Columns.Add("monitor_lat");
                dt.Columns.Add("monitor_long");
                dt.Columns.Add("monitor_gridcell");
                dt.Columns.Add("b_pm25_ann_DV");
                dt.Columns.Add("f_pm25_ann_DV");
                dt.Columns.Add("b_blank_mass");
                dt.Columns.Add("b_crustal_mass");
                dt.Columns.Add("b_EC_mass");
                dt.Columns.Add("b_NH4_mass");
                dt.Columns.Add("b_Ocmb_mass");
                dt.Columns.Add("b_SO4_mass");
                dt.Columns.Add("b_NO3_mass");
                dt.Columns.Add("b_water_mass");
                dt.Columns.Add("b_salt_mass");
                dt.Columns.Add("f_blank_mass");
                dt.Columns.Add("f_crustal_mass");
                dt.Columns.Add("f_EC_mass");
                dt.Columns.Add("f_NH4_mass");
                dt.Columns.Add("f_Ocmb_mass");
                dt.Columns.Add("f_SO4_mass");
                dt.Columns.Add("f_NO3_mass");
                dt.Columns.Add("f_water_mass");
                dt.Columns.Add("f_salt_mass");
                dt.Columns.Add("rrf_crustal");
                dt.Columns.Add("rrf_ec");
                dt.Columns.Add("rrf_nh4");
                dt.Columns.Add("rrf_oc");
                dt.Columns.Add("rrf_so4");
                dt.Columns.Add("rrf_no3");
                dt.Columns.Add("rrf_water");
                dt.Columns.Add("rrf_salt");
                dicAnnualPoint = dicAnnualPoint.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                foreach (KeyValuePair<string, PMPoint> k in dicAnnualPoint)
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = k.Value.id;
                    dr[1] = k.Value.type;
                    dr[2] = k.Value.stateName;
                    dr[3] = k.Value.countyName;
                    dr[4] = Math.Round(k.Value.monitorLat, 6);
                    dr[5] = Math.Round(k.Value.monitorLong, 6);
                    dr[6] = k.Value.monitorGridcell;
                    dr[7] = CommonClass.ToFixed(k.Value.bPMDV, 2);
                    dr[8] = CommonClass.ToFixed(k.Value.fPMDV, 2);
                    dr[9] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                    dr[10] = Math.Round(k.Value.bCrustalMass, CommonClass.Species_calc_precision);
                    dr[11] = Math.Round(k.Value.bECMass, CommonClass.Species_calc_precision);
                    dr[12] = Math.Round(k.Value.bNH4Mass, CommonClass.Species_calc_precision);
                    dr[13] = Math.Round(k.Value.bOcmbMass, CommonClass.Species_calc_precision);
                    dr[14] = Math.Round(k.Value.bSO4Mass, CommonClass.Species_calc_precision);
                    dr[15] = Math.Round(k.Value.bNO3Mass, CommonClass.Species_calc_precision);
                    dr[16] = Math.Round(k.Value.bWaterMass, CommonClass.Species_calc_precision);
                    dr[17] = Math.Round(k.Value.bSaltMass, CommonClass.Species_calc_precision);
                    dr[18] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                    dr[19] = Math.Round(k.Value.fCrustalMass, CommonClass.Species_calc_precision);
                    dr[20] = Math.Round(k.Value.fECMass, CommonClass.Species_calc_precision);
                    dr[21] = Math.Round(k.Value.fNH4Mass, CommonClass.Species_calc_precision);
                    dr[22] = Math.Round(k.Value.fOcmbMass, CommonClass.Species_calc_precision);
                    dr[23] = Math.Round(k.Value.fSO4Mass, CommonClass.Species_calc_precision);
                    dr[24] = Math.Round(k.Value.fNO3Mass, CommonClass.Species_calc_precision);
                    dr[25] = Math.Round(k.Value.fWaterMass, CommonClass.Species_calc_precision);
                    dr[26] = Math.Round(k.Value.fSaltMass, CommonClass.Species_calc_precision);
                    dr[27] = Double.IsNaN(k.Value.rrfCrustal) ? -9 : Math.Round(k.Value.rrfCrustal, 4);
                    dr[28] = Double.IsNaN(k.Value.rrfEC) ? -9 : Math.Round(k.Value.rrfEC, 4);
                    dr[29] = Double.IsNaN(k.Value.rrfNH4) ? -9 : Math.Round(k.Value.rrfNH4, 4);
                    dr[30] = Double.IsNaN(k.Value.rrfOC) ? -9 : Math.Round(k.Value.rrfOC, 4);
                    dr[31] = Double.IsNaN(k.Value.rrfSO4) ? -9 : Math.Round(k.Value.rrfSO4, 4);
                    dr[32] = Double.IsNaN(k.Value.rrfNO3) ? -9 : Math.Round(k.Value.rrfNO3, 4);
                    dr[33] = Double.IsNaN(k.Value.rrfWater) ? -9 : Math.Round(k.Value.rrfWater, 4);
                    dr[34] = Double.IsNaN(k.Value.rrfSalt) ? -9 : Math.Round(k.Value.rrfSalt, 4);
                    dt.Rows.Add(dr);
                }
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Annual PM25 Point" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dt, _resultFilePath + @"\" + strFile, "Year");
                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.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveHighCountyPoint(BaseScenario baseScenario, Dictionary<string, PMPoint> dicAnnualPoint, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dt = new DataTable();
                dt.Columns.Add("_id");
                dt.Columns.Add("_type");
                dt.Columns.Add("_STATE_NAME");
                dt.Columns.Add("_COUNTY_NAME");
                dt.Columns.Add("monitor_lat");
                dt.Columns.Add("monitor_long");
                dt.Columns.Add("monitor_gridcell");
                dt.Columns.Add("b_pm25_ann_DV");
                dt.Columns.Add("f_pm25_ann_DV");
                dt.Columns.Add("b_blank_mass");
                dt.Columns.Add("b_crustal_mass");
                dt.Columns.Add("b_EC_mass");
                dt.Columns.Add("b_NH4_mass");
                dt.Columns.Add("b_Ocmb_mass");
                dt.Columns.Add("b_SO4_mass");
                dt.Columns.Add("b_NO3_mass");
                dt.Columns.Add("b_water_mass");
                dt.Columns.Add("b_salt_mass");
                dt.Columns.Add("f_blank_mass");
                dt.Columns.Add("f_crustal_mass");
                dt.Columns.Add("f_EC_mass");
                dt.Columns.Add("f_NH4_mass");
                dt.Columns.Add("f_Ocmb_mass");
                dt.Columns.Add("f_SO4_mass");
                dt.Columns.Add("f_NO3_mass");
                dt.Columns.Add("f_water_mass");
                dt.Columns.Add("f_salt_mass");
                dt.Columns.Add("rrf_crustal");
                dt.Columns.Add("rrf_ec");
                dt.Columns.Add("rrf_nh4");
                dt.Columns.Add("rrf_oc");
                dt.Columns.Add("rrf_so4");
                dt.Columns.Add("rrf_no3");
                dt.Columns.Add("rrf_water");
                dt.Columns.Add("rrf_salt");
                dicAnnualPoint = dicAnnualPoint.OrderBy(p => p.Value.stateName).ThenBy(p => p.Value.countyName).ToDictionary(p => p.Key, p => p.Value);
                Dictionary<string, List<string>> dicStateCounty = new Dictionary<string, List<string>>();
                foreach (KeyValuePair<string, PMPoint> k in dicAnnualPoint)
                {
                    if (dicStateCounty.ContainsKey(k.Value.stateName))
                    {
                        if (!dicStateCounty[k.Value.stateName].Contains(k.Value.countyName))
                        {
                            dicStateCounty[k.Value.stateName].Add(k.Value.countyName);
                        }
                    }
                    else
                    {
                        dicStateCounty.Add(k.Value.stateName, new List<string>() { k.Value.countyName });
                    }
                }
                Dictionary<string, PMPoint> dic = new Dictionary<string, PMPoint>();
                PMPoint annualPM = new PMPoint();
                foreach (KeyValuePair<string, List<string>> kState in dicStateCounty)
                {
                    foreach (string sCounty in kState.Value)
                    {
                        annualPM = dicAnnualPoint.Where(p => p.Value.stateName == kState.Key && p.Value.countyName == sCounty).OrderBy(p => p.Value.fPMDV).Last().Value;
                        DataRow dr = dt.NewRow();
                        dr[0] = annualPM.id;
                        dr[1] = annualPM.type;
                        dr[2] = annualPM.stateName;
                        dr[3] = annualPM.countyName;
                        dr[4] = Math.Round(annualPM.monitorLat, 6);
                        dr[5] = Math.Round(annualPM.monitorLong, 6);
                        dr[6] = annualPM.monitorGridcell;
                        dr[7] = Math.Round(annualPM.bPMDV, 8);
                        dr[8] = Math.Round(annualPM.fPMDV, 8);
                        dr[9] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        dr[10] = Math.Round(annualPM.bCrustalMass, CommonClass.Species_calc_precision);
                        dr[11] = Math.Round(annualPM.bECMass, CommonClass.Species_calc_precision);
                        dr[12] = Math.Round(annualPM.bNH4Mass, CommonClass.Species_calc_precision);
                        dr[13] = Math.Round(annualPM.bOcmbMass, CommonClass.Species_calc_precision);
                        dr[14] = Math.Round(annualPM.bSO4Mass, CommonClass.Species_calc_precision);
                        dr[15] = Math.Round(annualPM.bNO3Mass, CommonClass.Species_calc_precision);
                        dr[16] = Math.Round(annualPM.bWaterMass, CommonClass.Species_calc_precision);
                        dr[17] = Math.Round(annualPM.bSaltMass, CommonClass.Species_calc_precision);
                        dr[18] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                        dr[19] = Math.Round(annualPM.fCrustalMass, CommonClass.Species_calc_precision);
                        dr[20] = Math.Round(annualPM.fECMass, CommonClass.Species_calc_precision);
                        dr[21] = Math.Round(annualPM.fNH4Mass, CommonClass.Species_calc_precision);
                        dr[22] = Math.Round(annualPM.fOcmbMass, CommonClass.Species_calc_precision);
                        dr[23] = Math.Round(annualPM.fSO4Mass, CommonClass.Species_calc_precision);
                        dr[24] = Math.Round(annualPM.fNO3Mass, CommonClass.Species_calc_precision);
                        dr[25] = Math.Round(annualPM.fWaterMass, CommonClass.Species_calc_precision);
                        dr[26] = Math.Round(annualPM.fSaltMass, CommonClass.Species_calc_precision);
                        dr[27] = Double.IsNaN(annualPM.rrfCrustal) ? -9 : Math.Round(annualPM.rrfCrustal, 8);
                        dr[28] = Double.IsNaN(annualPM.rrfEC) ? -9 : Math.Round(annualPM.rrfEC, 8);
                        dr[29] = Double.IsNaN(annualPM.rrfNH4) ? -9 : Math.Round(annualPM.rrfNH4, 8);
                        dr[30] = Double.IsNaN(annualPM.rrfOC) ? -9 : Math.Round(annualPM.rrfOC, 8);
                        dr[31] = Double.IsNaN(annualPM.rrfSO4) ? -9 : Math.Round(annualPM.rrfSO4, 8);
                        dr[32] = Double.IsNaN(annualPM.rrfNO3) ? -9 : Math.Round(annualPM.rrfNO3, 8);
                        dr[33] = Double.IsNaN(annualPM.rrfWater) ? -9 : Math.Round(annualPM.rrfWater, 8);
                        dr[34] = Double.IsNaN(annualPM.rrfSalt) ? -9 : Math.Round(annualPM.rrfSalt, 8);
                        dt.Rows.Add(dr);
                    }
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " High County Sites" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dt, _resultFilePath + @"\" + strFile, "Year");
                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.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveNeighborFilePoint(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicNeighborPoint)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Neighbor File Point.csv";

                FileStream fs = new FileStream(_resultFilePath + @"\" + strFile, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                StreamWriter sw = new StreamWriter(fs, Encoding.Default);
                sw.WriteLine("Quarter");
                string data = "";
                data += "_id";
                data += ",";
                data += "_state_name";
                data += ",";
                data += "_county_name";
                data += ",";
                data += "monitor_lat";
                data += ",";
                data += "monitor_long";
                data += ",";
                data += "monitor_gridcell";
                data += ",";
                data += "quarter";
                data += ",";
                data += "neighbor";
                data += ",";
                data += "neighbor_gridcell";
                data += ",";
                data += "distance";
                data += ",";
                data += "weightdistance";
                data += ",";
                data += "weightdistancesquared";
                data += ",";
                data += "pollutant";
                sw.WriteLine(data);
                double distanceSum = 0, distanceSquaredSum = 0;
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicNeighborPoint)
                {
                    foreach (KeyValuePair<string, Dictionary<string, float>> kPollutant in k.Value.dicNeighborFile)
                    {
                        distanceSum = distanceSquaredSum = 0;
                        distanceSum = kPollutant.Value.Select(p => p.Value == 0 ? 0 : 1.0000 / p.Value).Sum();
                        distanceSquaredSum = kPollutant.Value.Select(p => p.Value == 0 ? 0 : 1.0000 / Math.Pow(p.Value, 2)).Sum();
                        foreach (KeyValuePair<string, float> kNeighbor in kPollutant.Value)
                        {
                            data = "";
                            data += k.Value.id;
                            data += ",";
                            data += k.Value.stateName;
                            data += ",";
                            data += k.Value.countyName;
                            data += ",";
                            data += k.Value.latitude;
                            data += ",";
                            data += k.Value.longitude;
                            data += ",";
                            data += k.Value.gridcell;
                            data += ",";
                            data += kPollutant.Key.Substring(kPollutant.Key.IndexOf(",") + 1);
                            data += ",";
                            data += kNeighbor.Key.Substring(0, kNeighbor.Key.IndexOf(","));
                            data += ",";
                            data += kNeighbor.Key.Substring(kNeighbor.Key.IndexOf(",") + 1);
                            data += ",";
                            data += kNeighbor.Value;
                            data += ",";
                            data += distanceSum == 0 ? 1 : 1.0000 / kNeighbor.Value / distanceSum;
                            data += ",";
                            data += distanceSquaredSum == 0 ? 1 : 1.0000 / Math.Pow(kNeighbor.Value, 2) / distanceSquaredSum;
                            data += ",";
                            data += kPollutant.Key.Substring(0, kPollutant.Key.IndexOf(","));
                            sw.WriteLine(data);
                        }
                    }
                }
                sw.Close();
                fs.Close();
                GC.Collect();
                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);
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveQuarterlySpatialField(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicQuarterSpatialField, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                dicQuarterSpatialField = dicQuarterSpatialField.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dtQuarterPMSpatial = new DataTable();
                if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyVNA)
                {
                    #region
                    dtQuarterPMSpatial.Columns.Add("_id");
                    dtQuarterPMSpatial.Columns.Add("gridcell_lat");
                    dtQuarterPMSpatial.Columns.Add("gridcell_long");
                    dtQuarterPMSpatial.Columns.Add("quarter");
                    dtQuarterPMSpatial.Columns.Add("b_pm25_ann_q_DV");
                    dtQuarterPMSpatial.Columns.Add("f_pm25_ann_q_DV");
                    dtQuarterPMSpatial.Columns.Add("b_blank_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_crustal_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_EC_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_NH4_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_Ocmb_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_SO4_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_NO3_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_water_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_salt_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_blank_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_crustal_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_EC_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_NH4_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_Ocmb_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_SO4_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_NO3_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_water_mass_q");
                    dtQuarterPMSpatial.Columns.Add("f_salt_mass_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_crustal_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_ec_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_nh4_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_oc_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_so4_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_no3_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_salt_q");
                    dtQuarterPMSpatial.Columns.Add("rrf_water_mass_q");
                    #endregion
                    #region
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterSpatialField)
                    {
                        foreach (KeyValuePair<string, PMSpatial> kQ in k.Value.dicQuarterlySpatial)
                        {
                            DataRow dr = dtQuarterPMSpatial.NewRow();
                            dr[0] = k.Value.id;
                            dr[1] = Math.Round(k.Value.latitude, 6);
                            dr[2] = Math.Round(k.Value.longitude, 6);
                            dr[3] = kQ.Key;
                            dr[4] = Math.Round(kQ.Value.bPMAnnDV, CommonClass.Pm_defaultformat);
                            dr[5] = Math.Round(kQ.Value.fPMAnnDV, CommonClass.Pm_defaultformat);
                            dr[6] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                            dr[7] = Math.Round(kQ.Value.bCrustalMass, CommonClass.Species_calc_precision);
                            dr[8] = Math.Round(kQ.Value.bECMass, CommonClass.Species_calc_precision);
                            dr[9] = Math.Round(kQ.Value.bNH4Mass, CommonClass.Species_calc_precision);
                            dr[10] = Math.Round(kQ.Value.bOcmbMass, CommonClass.Species_calc_precision);
                            dr[11] = Math.Round(kQ.Value.bSO4Mass, CommonClass.Species_calc_precision);
                            dr[12] = Math.Round(kQ.Value.bNO3rMass, CommonClass.Species_calc_precision);
                            dr[13] = Math.Round(kQ.Value.bWaterMass, CommonClass.Species_calc_precision);
                            dr[14] = Math.Round(kQ.Value.bSaltMass, CommonClass.Species_calc_precision);
                            dr[15] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                            dr[16] = Math.Round(kQ.Value.fCrustalMass, CommonClass.Species_calc_precision);
                            dr[17] = Math.Round(kQ.Value.fECMass, CommonClass.Species_calc_precision);
                            dr[18] = Math.Round(kQ.Value.fNH4Mass, CommonClass.Species_calc_precision);
                            dr[19] = Math.Round(kQ.Value.fOcmbMass, CommonClass.Species_calc_precision);
                            dr[20] = Math.Round(kQ.Value.fSO4Mass, CommonClass.Species_calc_precision);
                            dr[21] = Math.Round(kQ.Value.fNO3Mass, CommonClass.Species_calc_precision);
                            dr[22] = Math.Round(kQ.Value.fWaterMass, CommonClass.Species_calc_precision);
                            dr[23] = Math.Round(kQ.Value.fSaltMass, CommonClass.Species_calc_precision);
                            dr[24] = Double.IsNaN(kQ.Value.rrfCrustal) ? -9 : Math.Round(kQ.Value.rrfCrustal, 8);
                            dr[25] = Double.IsNaN(kQ.Value.rrfEC) ? -9 : Math.Round(kQ.Value.rrfEC, 8);
                            dr[26] = Double.IsNaN(kQ.Value.rrfNH4) ? -9 : Math.Round(kQ.Value.rrfNH4, 8);
                            dr[27] = Double.IsNaN(kQ.Value.rrfOC) ? -9 : Math.Round(kQ.Value.rrfOC, 8);
                            dr[28] = Double.IsNaN(kQ.Value.rrfSO4) ? -9 : Math.Round(kQ.Value.rrfSO4, 8);
                            dr[29] = Double.IsNaN(kQ.Value.rrfNO3) ? -9 : Math.Round(kQ.Value.rrfNO3, 8);
                            dr[30] = Double.IsNaN(kQ.Value.rrfSalt) ? -9 : Math.Round(kQ.Value.rrfSalt, 8);
                            dr[31] = Double.IsNaN(kQ.Value.rrfWaterMass) ? -9 : Math.Round(kQ.Value.rrfWaterMass, 8);
                            dtQuarterPMSpatial.Rows.Add(dr);
                        }
                    }
                    #endregion
                }
                else if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyVNA)
                {
                    #region
                    dtQuarterPMSpatial.Columns.Add("_id");
                    dtQuarterPMSpatial.Columns.Add("gridcell_lat");
                    dtQuarterPMSpatial.Columns.Add("gridcell_long");
                    dtQuarterPMSpatial.Columns.Add("quarter");
                    dtQuarterPMSpatial.Columns.Add("b_pm25_ann_q_DV");
                    dtQuarterPMSpatial.Columns.Add("b_blank_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_crustal_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_EC_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_NH4_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_Ocmb_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_SO4_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_NO3_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_water_mass_q");
                    dtQuarterPMSpatial.Columns.Add("b_salt_mass_q");
                    //dtQuarterPMSpatial.Columns.Add("rrf_ec_q");
                    //dtQuarterPMSpatial.Columns.Add("rrf_nh4_q");
                    //dtQuarterPMSpatial.Columns.Add("rrf_oc_q");
                    //dtQuarterPMSpatial.Columns.Add("rrf_so4_q");
                    //dtQuarterPMSpatial.Columns.Add("rrf_no3_q");
                    //dtQuarterPMSpatial.Columns.Add("rrf_water_mass_q");
                    //dtQuarterPMSpatial.Columns.Add("rrf_salt_q");
                    #endregion
                    #region
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterSpatialField)
                    {
                        foreach (KeyValuePair<string, PMSpatial> kQ in k.Value.dicQuarterlySpatial)
                        {
                            DataRow dr = dtQuarterPMSpatial.NewRow();
                            dr[0] = k.Value.id;
                            dr[1] = Math.Round(k.Value.latitude, 6);
                            dr[2] = Math.Round(k.Value.longitude, 6);
                            dr[3] = kQ.Key;
                            dr[4] = Math.Round(kQ.Value.bPMAnnDV, CommonClass.Pm_defaultformat);
                            dr[5] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                            dr[6] = Math.Round(kQ.Value.bCrustalMass, CommonClass.Species_calc_precision);
                            dr[7] = Math.Round(kQ.Value.bECMass, CommonClass.Species_calc_precision);
                            dr[8] = Math.Round(kQ.Value.bNH4Mass, CommonClass.Species_calc_precision);
                            dr[9] = Math.Round(kQ.Value.bOcmbMass, CommonClass.Species_calc_precision);
                            dr[10] = Math.Round(kQ.Value.bSO4Mass, CommonClass.Species_calc_precision);
                            dr[11] = Math.Round(kQ.Value.bNO3rMass, CommonClass.Species_calc_precision);
                            dr[12] = Math.Round(kQ.Value.bWaterMass, CommonClass.Species_calc_precision);
                            dr[13] = Math.Round(kQ.Value.bSaltMass, CommonClass.Species_calc_precision);
                            dtQuarterPMSpatial.Rows.Add(dr);
                        }
                    }
                    #endregion
                }
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly PM25 Spatial Field" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtQuarterPMSpatial, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtQuarterPMSpatial.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveQuarterlySpatialFieldGradAdj(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicQuarterlySpatialFieldGradAdj, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                dicQuarterlySpatialFieldGradAdj = dicQuarterlySpatialFieldGradAdj.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dtGradAdjQuarterSpatial = new DataTable();
                if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doInterpolatedSFETempAdj_GradAdj || annualPMAnalysisConfiguration.outputChoiceAdvancedA.doFutureOnlyEvna)
                {
                    #region
                    dtGradAdjQuarterSpatial.Columns.Add("_id");
                    dtGradAdjQuarterSpatial.Columns.Add("gridcell_lat");
                    dtGradAdjQuarterSpatial.Columns.Add("gridcell_long");
                    dtGradAdjQuarterSpatial.Columns.Add("quarter");
                    dtGradAdjQuarterSpatial.Columns.Add("b_pm25_ann_q_DV_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_pm25_ann_q_DV_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_blank_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_crustal_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_EC_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_NH4_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_Ocmb_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_SO4_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_NO3_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_water_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_salt_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_blank_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_crustal_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_EC_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_NH4_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_Ocmb_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_SO4_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_NO3_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_water_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("f_salt_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_crustal_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_ec_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_nh4_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_oc_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_so4_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_no3_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_salt_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("rrf_water_mass_q_ga");
                    #endregion
                    #region
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlySpatialFieldGradAdj)
                    {
                        foreach (KeyValuePair<string, PMSpatial> kQ in k.Value.dicQuarterlySpatialGradientAdjusted)
                        {
                            DataRow dr = dtGradAdjQuarterSpatial.NewRow();
                            dr[0] = k.Value.id;
                            dr[1] = Math.Round(k.Value.latitude, 6);
                            dr[2] = Math.Round(k.Value.longitude, 6);
                            dr[3] = kQ.Key;
                            dr[4] = Math.Round(kQ.Value.bPMAnnDV, 2);
                            dr[5] = Math.Round(kQ.Value.fPMAnnDV, 2);
                            dr[6] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                            dr[7] = Math.Round(kQ.Value.bCrustalMass, CommonClass.Species_calc_precision);
                            dr[8] = Math.Round(kQ.Value.bECMass, CommonClass.Species_calc_precision);
                            dr[9] = Math.Round(kQ.Value.bNH4Mass, CommonClass.Species_calc_precision);
                            dr[10] = Math.Round(kQ.Value.bOcmbMass, CommonClass.Species_calc_precision);
                            dr[11] = Math.Round(kQ.Value.bSO4Mass, CommonClass.Species_calc_precision);
                            dr[12] = Math.Round(kQ.Value.bNO3rMass, CommonClass.Species_calc_precision);
                            dr[13] = Math.Round(kQ.Value.bWaterMass, CommonClass.Species_calc_precision);
                            dr[14] = Math.Round(kQ.Value.bSaltMass, CommonClass.Species_calc_precision);
                            dr[15] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                            dr[16] = Math.Round(kQ.Value.fCrustalMass, CommonClass.Species_calc_precision);
                            dr[17] = Math.Round(kQ.Value.fECMass, CommonClass.Species_calc_precision);
                            dr[18] = Math.Round(kQ.Value.fNH4Mass, CommonClass.Species_calc_precision);
                            dr[19] = Math.Round(kQ.Value.fOcmbMass, CommonClass.Species_calc_precision);
                            dr[20] = Math.Round(kQ.Value.fSO4Mass, CommonClass.Species_calc_precision);
                            dr[21] = Math.Round(kQ.Value.fNO3Mass, CommonClass.Species_calc_precision);
                            dr[22] = Math.Round(kQ.Value.fWaterMass, CommonClass.Species_calc_precision);
                            dr[23] = Math.Round(kQ.Value.fSaltMass, CommonClass.Species_calc_precision);
                            dr[24] = Double.IsNaN(kQ.Value.rrfCrustal) ? -9 : Math.Round(kQ.Value.rrfCrustal, 8);
                            dr[25] = Double.IsNaN(kQ.Value.rrfEC) ? -9 : Math.Round(kQ.Value.rrfEC, 8);
                            dr[26] = Double.IsNaN(kQ.Value.rrfNH4) ? -9 : Math.Round(kQ.Value.rrfNH4, 8);
                            dr[27] = Double.IsNaN(kQ.Value.rrfOC) ? -9 : Math.Round(kQ.Value.rrfOC, 8);
                            dr[28] = Double.IsNaN(kQ.Value.rrfSO4) ? -9 : Math.Round(kQ.Value.rrfSO4, 8);
                            dr[29] = Double.IsNaN(kQ.Value.rrfNO3) ? -9 : Math.Round(kQ.Value.rrfNO3, 8);
                            dr[30] = Double.IsNaN(kQ.Value.rrfSalt) ? -9 : Math.Round(kQ.Value.rrfSalt, 8);
                            dr[31] = Double.IsNaN(kQ.Value.rrfWaterMass) ? -9 : Math.Round(kQ.Value.rrfWaterMass, 8);
                            dtGradAdjQuarterSpatial.Rows.Add(dr);
                        }
                    }
                    #endregion
                }
                else if (annualPMAnalysisConfiguration.outputChoiceAdvancedA.doBaseOnlyEvna)
                {
                    #region
                    dtGradAdjQuarterSpatial.Columns.Add("_id");
                    dtGradAdjQuarterSpatial.Columns.Add("gridcell_lat");
                    dtGradAdjQuarterSpatial.Columns.Add("gridcell_long");
                    dtGradAdjQuarterSpatial.Columns.Add("quarter");
                    dtGradAdjQuarterSpatial.Columns.Add("b_pm25_ann_q_DV_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_blank_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_crustal_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_EC_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_NH4_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_Ocmb_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_SO4_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_NO3_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_water_mass_q_ga");
                    dtGradAdjQuarterSpatial.Columns.Add("b_salt_mass_q_ga");
                    #endregion
                    #region
                    foreach (KeyValuePair<string, PMMonitorOutput> k in dicQuarterlySpatialFieldGradAdj)
                    {
                        foreach (KeyValuePair<string, PMSpatial> kQ in k.Value.dicQuarterlySpatialGradientAdjusted)
                        {
                            DataRow dr = dtGradAdjQuarterSpatial.NewRow();
                            dr[0] = k.Value.id;
                            dr[1] = Math.Round(k.Value.latitude, 6);
                            dr[2] = Math.Round(k.Value.longitude, 6);
                            dr[3] = kQ.Key;
                            dr[4] = Math.Round(kQ.Value.bPMAnnDV, 2);
                            dr[5] = Math.Round(annualPMAnalysisConfiguration.speciesFractionOptionsA.defaultBlankMass, CommonClass.Species_calc_precision);
                            dr[6] = Math.Round(kQ.Value.bCrustalMass, CommonClass.Species_calc_precision);
                            dr[7] = Math.Round(kQ.Value.bECMass, CommonClass.Species_calc_precision);
                            dr[8] = Math.Round(kQ.Value.bNH4Mass, CommonClass.Species_calc_precision);
                            dr[9] = Math.Round(kQ.Value.bOcmbMass, CommonClass.Species_calc_precision);
                            dr[10] = Math.Round(kQ.Value.bSO4Mass, CommonClass.Species_calc_precision);
                            dr[11] = Math.Round(kQ.Value.bNO3rMass, CommonClass.Species_calc_precision);
                            dr[12] = Math.Round(kQ.Value.bWaterMass, CommonClass.Species_calc_precision);
                            dr[13] = Math.Round(kQ.Value.bSaltMass, CommonClass.Species_calc_precision);
                            dtGradAdjQuarterSpatial.Rows.Add(dr);
                        }
                    }
                    #endregion
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);

                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Grad Adj Quarterly PM25 Spatial Field" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtGradAdjQuarterSpatial, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtGradAdjQuarterSpatial.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

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

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

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

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

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

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

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

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

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

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

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

        public static bool SaveDeltaAnnualPointSpatialField(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicSpatialFieldDS, Dictionary<string, int[]> dicColRow)
        {
            if (!(baseScenario.configuration is BenMAPAnnualPMAnalysisConfiguration))
                return false;
            try
            {
                #region delta option
                bool DS = (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).monitorInput.doDownscaler;
                bool VNA = (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).monitorInput.useVNA;
                bool eVNA = (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).monitorInput.useEVNA;
                if (!(DS || VNA || eVNA))
                    return false;
                bool dsvna = DS && VNA;
                bool dsevna = DS && eVNA;
                bool evnavna = eVNA && VNA;
                #endregion

                dicSpatialFieldDS = dicSpatialFieldDS.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                BenMAPAnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration;
                DataTable dtGradAdjAnnualSpatial = new DataTable();

                dtGradAdjAnnualSpatial.Columns.Add("Column");
                dtGradAdjAnnualSpatial.Columns.Add("Row");
                dtGradAdjAnnualSpatial.Columns.Add("Metric");
                dtGradAdjAnnualSpatial.Columns.Add("Seasonal Metric");
                dtGradAdjAnnualSpatial.Columns.Add("Statistic");
                if (dsvna)
                {
                    dtGradAdjAnnualSpatial.Columns.Add("Deltab_PM25_(DS-VNA)");
                    dtGradAdjAnnualSpatial.Columns.Add("Deltaf_PM25_(DS-VNA)");
                }
                if (dsevna)
                {
                    dtGradAdjAnnualSpatial.Columns.Add("Deltab_PM25_(DS-eVNA)");
                    dtGradAdjAnnualSpatial.Columns.Add("Deltaf_PM25_(DS-eVNA)");
                }
                if (evnavna)
                {
                    dtGradAdjAnnualSpatial.Columns.Add("Deltab_PM25_(eVNA-VNA)");
                    dtGradAdjAnnualSpatial.Columns.Add("Deltaf_PM25_(eVNA-VNA)");
                }
                dtGradAdjAnnualSpatial.Columns.Add("gridcell_lat");
                dtGradAdjAnnualSpatial.Columns.Add("gridcell_long");

                foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpatialFieldDS)
                {
                    int r = 0;
                    DataRow dr = dtGradAdjAnnualSpatial.NewRow();
                    dr[r++] = dicColRow[k.Key][0];
                    dr[r++] = dicColRow[k.Key][1];
                    dr[r++] = "D24HourMean";
                    dr[r++] = "QuarterlyMean";
                    dr[r++] = "Mean";
                    if (dsvna)
                    {
                        dr[r++] = CommonClass.ToFixed(k.Value.dicQuarterlySpatialDS.Select(p => p.Value.bPMAnnDV).Average(), 2)
                            - CommonClass.ToFixed(k.Value.dicQuarterlySpatial.Select(p => p.Value.bPMAnnDV).Average(), 2);
                        dr[r++] = CommonClass.ToFixed(k.Value.dicQuarterlySpatialDS.Select(p => p.Value.fPMAnnDV).Average(), 2)
                            - CommonClass.ToFixed(k.Value.dicQuarterlySpatial.Select(p => p.Value.fPMAnnDV).Average(), 2); 
                    }
                    if (dsevna)
                    {
                        dr[r++] = CommonClass.ToFixed(k.Value.dicQuarterlySpatialDS.Select(p => p.Value.bPMAnnDV).Average(), 2)
                            - CommonClass.ToFixed(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bPMAnnDV).Average(), 2);
                        dr[r++] = CommonClass.ToFixed(k.Value.dicQuarterlySpatialDS.Select(p => p.Value.fPMAnnDV).Average(), 2)
                            - CommonClass.ToFixed(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fPMAnnDV).Average(), 2); 
                    }
                    if (evnavna)
                    {
                        dr[r++] = CommonClass.ToFixed(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.bPMAnnDV).Average(), 2)
                            - CommonClass.ToFixed(k.Value.dicQuarterlySpatial.Select(p => p.Value.bPMAnnDV).Average(), 2);
                        dr[r++] = CommonClass.ToFixed(k.Value.dicQuarterlySpatialGradientAdjusted.Select(p => p.Value.fPMAnnDV).Average(), 2)
                            - CommonClass.ToFixed(k.Value.dicQuarterlySpatial.Select(p => p.Value.fPMAnnDV).Average(), 2); 
                    }
                    dr[r++] = Math.Round(k.Value.latitude, 6);
                    dr[r++] = Math.Round(k.Value.longitude, 6);
                    dtGradAdjAnnualSpatial.Rows.Add(dr);
                }

                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as BenMAPAnnualPMAnalysisConfiguration).modelInput.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.modelInput.scenarioName + " Delta Annual PM25 Spatial Field Base.csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtGradAdjAnnualSpatial, _resultFilePath + @"\" + strFile, "");
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    FileInfo fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                dtGradAdjAnnualSpatial.Dispose();
               
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }


        public static bool SaveSpecFracSpatialFieldCopyDirectly(BaseScenario baseScenario)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                string fileNameInfo = "";
                switch (annualPMAnalysisConfiguration.dataInputA.specFracModeSpatial)
                {
                    case "spatial field":
                        fileNameInfo = " Quarterly Avg Spec Frac Spatial Field.csv";
                        break;
                    case "grad adj spatial field":
                        fileNameInfo = " Grad Adj Quarterly Avg Spec Frac Spatial Field.csv";
                        break;
                }
                File.Copy((CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).dataInputA.specFracSpatialFile, _resultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName + fileNameInfo, true);
                FileInfo fileInfo = null;
                if (CommonClass.CurrentBaseScenario.lstOutput == null)
                    CommonClass.CurrentBaseScenario.lstOutput = new List<BaseOutput>();
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + fileNameInfo;
                BaseOutput baseOutput = new BaseOutput();
                baseOutput.outputName = strFile.Replace(".csv", "");
                baseOutput.outputType = "Monitor Network";
                baseOutput.outputFilePath = _resultFilePath + @"\" + strFile;
                if (File.Exists(_resultFilePath + @"\" + strFile))
                {
                    fileInfo = new FileInfo(_resultFilePath + @"\" + strFile);
                    baseOutput.outputSize = Convert.ToInt32(fileInfo.Length / 1024);
                }
                else
                {
                    baseOutput.outputSize = 0;
                }
                baseScenario.lstOutput.Add(baseOutput);
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveSpecFracSpatialField(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicSpecFracSpatialField, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                dicSpecFracSpatialField = dicSpecFracSpatialField.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dtQuarterAvgSpecFracSpatial = new DataTable();
                dtQuarterAvgSpecFracSpatial.Columns.Add("_id");
                dtQuarterAvgSpecFracSpatial.Columns.Add("gridcell_lat");
                dtQuarterAvgSpecFracSpatial.Columns.Add("gridcell_long");
                dtQuarterAvgSpecFracSpatial.Columns.Add("quarter");
                dtQuarterAvgSpecFracSpatial.Columns.Add("pm25_mass_frac");
                dtQuarterAvgSpecFracSpatial.Columns.Add("fcr");
                dtQuarterAvgSpecFracSpatial.Columns.Add("fec");
                dtQuarterAvgSpecFracSpatial.Columns.Add("fnh4");
                dtQuarterAvgSpecFracSpatial.Columns.Add("focm");
                dtQuarterAvgSpecFracSpatial.Columns.Add("fso4");
                dtQuarterAvgSpecFracSpatial.Columns.Add("fno3");
                dtQuarterAvgSpecFracSpatial.Columns.Add("fwater");
                dtQuarterAvgSpecFracSpatial.Columns.Add("fsalt");
                dtQuarterAvgSpecFracSpatial.Columns.Add("blank_mass");
                dtQuarterAvgSpecFracSpatial.Columns.Add("don");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_so4");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_no3r");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_ocb");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_ec");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_crustal");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_don");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_nh4");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_no3");
                dtQuarterAvgSpecFracSpatial.Columns.Add("i_salt");
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpecFracSpatialField)
                {
                    foreach (KeyValuePair<string, SpecFracPM> kQ in k.Value.dicSpecFracSpatial)
                    {
                        DataRow dr = dtQuarterAvgSpecFracSpatial.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = Math.Round(k.Value.latitude, 6);
                        dr[2] = Math.Round(k.Value.longitude, 6);
                        dr[3] = kQ.Key;
                        dr[4] = Math.Round(kQ.Value.pm25MassFrac, CommonClass.Pm_defaultformat);
                        dr[5] = Math.Round(kQ.Value.fCr, CommonClass.Species_fraction_precision);
                        dr[6] = Math.Round(kQ.Value.fEC, CommonClass.Species_fraction_precision);
                        dr[7] = Math.Round(kQ.Value.fNH4, CommonClass.Species_fraction_precision);
                        dr[8] = Math.Round(kQ.Value.fOcm, CommonClass.Species_fraction_precision);
                        dr[9] = Math.Round(kQ.Value.fSO4, CommonClass.Species_fraction_precision);
                        dr[10] = Math.Round(kQ.Value.fNO3r, CommonClass.Species_fraction_precision);
                        dr[11] = Math.Round(kQ.Value.fWater, CommonClass.Species_fraction_precision);
                        dr[12] = Math.Round(kQ.Value.fSalt, CommonClass.Species_fraction_precision);
                        dr[13] = Math.Round(kQ.Value.blankMass, CommonClass.Species_calc_precision);
                        dr[14] = Math.Round(kQ.Value.don, CommonClass.Species_calc_precision);
                        dr[15] = Math.Round(kQ.Value.iSO4, CommonClass.Species_calc_precision);
                        dr[16] = Math.Round(kQ.Value.iNO3r, CommonClass.Species_calc_precision);
                        dr[17] = Math.Round(kQ.Value.iOcb, CommonClass.Species_calc_precision);
                        dr[18] = Math.Round(kQ.Value.iEC, CommonClass.Species_calc_precision);
                        dr[19] = Math.Round(kQ.Value.iCrustal, CommonClass.Species_calc_precision);
                        dr[20] = Math.Round(kQ.Value.iDON, CommonClass.Species_calc_precision);
                        dr[21] = Math.Round(kQ.Value.iNH4, CommonClass.Species_calc_precision);
                        dr[22] = Math.Round(kQ.Value.iNO3, CommonClass.Species_calc_precision);
                        dr[23] = Math.Round(kQ.Value.iSalt, CommonClass.Species_calc_precision);
                        dtQuarterAvgSpecFracSpatial.Rows.Add(dr);
                    }
                }
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Quarterly Avg Spec Frac Spatial Field" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtQuarterAvgSpecFracSpatial, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtQuarterAvgSpecFracSpatial.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveSpecFracSpatialFieldGradAdj(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicSpecFracGradAdj, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                dicSpecFracGradAdj = dicSpecFracGradAdj.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                DataTable dtGradAdjSpecFracSpatial = new DataTable();
                dtGradAdjSpecFracSpatial.Columns.Add("_id");
                dtGradAdjSpecFracSpatial.Columns.Add("gridcell_lat");
                dtGradAdjSpecFracSpatial.Columns.Add("gridcell_long");
                dtGradAdjSpecFracSpatial.Columns.Add("quarter");
                dtGradAdjSpecFracSpatial.Columns.Add("pm25_mass_frac_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("fcr_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("fec_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("fnh4_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("focm_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("fso4_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("fno3_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("fwater_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("fsalt_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("blank_mass_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("don_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_so4_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_no3r_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_ocb_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_ec_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_crustal_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_don_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_nh4_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_no3_ga");
                dtGradAdjSpecFracSpatial.Columns.Add("i_salt_ga");

                foreach (KeyValuePair<string, PMMonitorOutput> k in dicSpecFracGradAdj)
                {
                    foreach (KeyValuePair<string, SpecFracPM> kQ in k.Value.dicSpecFracSpatialGradAdj)
                    {
                        DataRow dr = dtGradAdjSpecFracSpatial.NewRow();
                        dr[0] = k.Value.id;
                        dr[1] = Math.Round(k.Value.latitude, 6);
                        dr[2] = Math.Round(k.Value.longitude, 6);
                        dr[3] = kQ.Key;
                        dr[4] = Math.Round(kQ.Value.pm25MassFrac, CommonClass.Pm_defaultformat);
                        dr[5] = Math.Round(kQ.Value.fCr, CommonClass.Species_fraction_precision);
                        dr[6] = Math.Round(kQ.Value.fEC, CommonClass.Species_fraction_precision);
                        dr[7] = Math.Round(kQ.Value.fNH4, CommonClass.Species_fraction_precision);
                        dr[8] = Math.Round(kQ.Value.fOcm, CommonClass.Species_fraction_precision);
                        dr[9] = Math.Round(kQ.Value.fSO4, CommonClass.Species_fraction_precision);
                        dr[10] = Math.Round(kQ.Value.fNO3r, CommonClass.Species_fraction_precision);
                        dr[11] = Math.Round(kQ.Value.fWater, CommonClass.Species_fraction_precision);
                        dr[12] = Math.Round(kQ.Value.fSalt, CommonClass.Species_fraction_precision);
                        dr[13] = Math.Round(kQ.Value.blankMass, CommonClass.Species_calc_precision);
                        dr[14] = Math.Round(kQ.Value.don, CommonClass.Species_calc_precision);
                        dr[15] = Math.Round(kQ.Value.iSO4, CommonClass.Species_calc_precision);
                        dr[16] = Math.Round(kQ.Value.iNO3r, CommonClass.Species_calc_precision);
                        dr[17] = Math.Round(kQ.Value.iOcb, CommonClass.Species_calc_precision);
                        dr[18] = Math.Round(kQ.Value.iEC, CommonClass.Species_calc_precision);
                        dr[19] = Math.Round(kQ.Value.iCrustal, CommonClass.Species_calc_precision);
                        dr[20] = Math.Round(kQ.Value.iDON, CommonClass.Species_calc_precision);
                        dr[21] = Math.Round(kQ.Value.iNH4, CommonClass.Species_calc_precision);
                        dr[22] = Math.Round(kQ.Value.iNO3, CommonClass.Species_calc_precision);
                        dr[23] = Math.Round(kQ.Value.iSalt, CommonClass.Species_calc_precision);
                        dtGradAdjSpecFracSpatial.Rows.Add(dr);
                    }
                }
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                //修正文件名称
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Grad Adj Quarterly Avg Spec Frac Spatial Field" + period + ".csv";
                BaseOutput baseOutput = new BaseOutput();
                CommonClass.SaveCSV(dtGradAdjSpecFracSpatial, _resultFilePath + @"\" + strFile, "Quarter");
                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);
                dtGradAdjSpecFracSpatial.Dispose();
                GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }

        public static bool SaveNeighborFileSpatialField(BaseScenario baseScenario, Dictionary<string, PMMonitorOutput> dicNeighborFile, string period)
        {
            if (!(baseScenario.configuration is AnnualPMAnalysisConfiguration))
                return false;
            try
            {
                AnnualPMAnalysisConfiguration annualPMAnalysisConfiguration = baseScenario.configuration as AnnualPMAnalysisConfiguration;
                if (!CommonClass.IsBatch)
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\Result\Output\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                else
                {
                    if (_resultFilePath == "" && _resultFilePath.Length == 0 || _resultFilePath != CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName)
                        _resultFilePath = CommonClass.ResultFilePath + @"\" + (CommonClass.CurrentBaseScenario.configuration as AnnualPMAnalysisConfiguration).chooseDesiredOutputA.scenarioName;
                }
                if (!Directory.Exists(_resultFilePath))
                    System.IO.Directory.CreateDirectory(_resultFilePath);
                string strFile = annualPMAnalysisConfiguration.chooseDesiredOutputA.scenarioName + " Neighbor File Spatial Field" + period + ".csv";
                FileStream fs = new FileStream(_resultFilePath + @"\" + strFile, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                StreamWriter sw = new StreamWriter(fs, Encoding.Default);
                sw.WriteLine("Quarter");
                string data = "";
                data += "_id";
                data += ",";
                data += "gridcell_lat";
                data += ",";
                data += "gridcell_long";
                data += ",";
                data += "quarter";
                data += ",";
                data += "neighbor";
                data += ",";
                data += "neighbor_gridcell";
                data += ",";
                data += "distance";
                data += ",";
                data += "weightdistance";
                data += ",";
                data += "weightdistancesquared";
                data += ",";
                data += "pollutant";
                sw.WriteLine(data);
                double distanceSum = 0, distanceSquaredSum = 0;
                foreach (KeyValuePair<string, PMMonitorOutput> k in dicNeighborFile)
                {
                    foreach (KeyValuePair<string, Dictionary<string, float>> kPollutant in k.Value.dicNeighborFile)
                    {
                        distanceSum = distanceSquaredSum = 0;
                        distanceSum = kPollutant.Value.Select(p => p.Value == 0 ? 0 : 1.0000 / p.Value).Sum();
                        distanceSquaredSum = kPollutant.Value.Select(p => p.Value == 0 ? 0 : 1.0000 / Math.Pow(p.Value, 2)).Sum();
                        foreach (KeyValuePair<string, float> kNeighbor in kPollutant.Value)
                        {
                            data = "";
                            data += k.Value.id;
                            data += ",";
                            data += k.Value.latitude;
                            data += ",";
                            data += k.Value.longitude;
                            data += ",";
                            data += kPollutant.Key.Substring(kPollutant.Key.IndexOf(",") + 1);
                            data += ",";
                            data += kNeighbor.Key.Substring(0, kNeighbor.Key.IndexOf(","));
                            data += ",";
                            data += kNeighbor.Key.Substring(kNeighbor.Key.IndexOf(",") + 1);
                            data += ",";
                            data += kNeighbor.Value;
                            data += ",";
                            data += distanceSum == 0 ? 1 : (1.0000 / kNeighbor.Value) / distanceSum;
                            data += ",";
                            data += distanceSquaredSum == 0 ? 1 : (1.0000 / Math.Pow(kNeighbor.Value, 2)) / distanceSquaredSum;
                            data += ",";
                            data += kPollutant.Key.Substring(0, kPollutant.Key.IndexOf(","));
                            sw.WriteLine(data);
                        }
                    }
                }
                sw.Close();
                fs.Close();
                GC.Collect();

                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);
                return true;
            }
            catch (Exception ex)
            {
                CommonClass.LogError(ex);
                return false;
            }
        }
        #endregion
    }
}
