Пример #1
0
        /// <summary>
        /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData
        /// </summary>
        ///
        public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase)
        {
            if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily"))
            {
                future_allData_granularity = TemporalGranularity.Daily;
            }

            else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly"))
            {
                future_allData_granularity = TemporalGranularity.Monthly;
            }

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily"))
            {
                spinup_allData_granularity = TemporalGranularity.Daily;
            }

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly"))
            {
                spinup_allData_granularity = TemporalGranularity.Monthly;
            }

            if (timeSeries.Contains("Daily"))
            {
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);
            }

            else if (timeSeries.Contains("Monthly"))
            {
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);
            }

            return;
        }
Пример #2
0
        //------
        public ClimateFileFormatProvider(string format)
        {
            this.format               = format;
            this.maxTempTriggerWord   = "maxtemp";
            this.minTempTriggerWord   = "mintemp";
            this.precipTriggerWord    = "ppt";
            this.rhTriggerWord        = "rh";
            this.windSpeedTriggerWord = "windSpeed";

            //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily);
            switch (this.format.ToLower())
            {
            case "ipcc3_daily":      //was 'gfdl_a1fi'
            {
                this.timeStep = TemporalGranularity.Daily;
                break;
            }

            case "ipcc3_monthly":      //ADD
            {
                this.timeStep = TemporalGranularity.Monthly;
                break;
            }

            case "ipcc5_monthly":
            {
                this.timeStep = TemporalGranularity.Monthly;
                break;
            }

            case "ipcc5_daily":      //ADD
            {
                this.timeStep = TemporalGranularity.Daily;
                break;
            }

            case "prism_monthly":      //was 'prism'
            {
                this.timeStep = TemporalGranularity.Monthly;
                break;
            }

            case "Mauer_daily":      //was griddedobserved
            {
                this.timeStep = TemporalGranularity.Daily;
                break;
            }

            default:
            {
                Climate.ModelCore.UI.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format);
                throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported.");
                //break;
            }
            }
        }
        //------
        public ClimateFileFormatProvider(string format)
        {
            this.format = format;
            this.maxTempTriggerWord = "maxtemp";
            this.minTempTriggerWord = "mintemp";
            this.precipTriggerWord = "ppt";
            this.rhTriggerWord = "rh";
            this.windSpeedTriggerWord = "windSpeed";

            //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily);
            switch (this.format.ToLower())
            {
                case "ipcc3_daily":  //was 'gfdl_a1fi'
                {
                    this.timeStep = TemporalGranularity.Daily;
                    break;
                }
                case "ipcc3_monthly":  //ADD
                {
                    this.timeStep = TemporalGranularity.Monthly;
                    break;
                }
                case "ipcc5_monthly":
                {
                    this.timeStep = TemporalGranularity.Monthly;
                    break;
                }
                case "ipcc5_daily":  //ADD
                {
                    this.timeStep = TemporalGranularity.Daily;
                    break;
                }
                case "prism_monthly":  //was 'prism'
                {
                    this.timeStep = TemporalGranularity.Monthly;
                    break;
                }
                case "Mauer_daily":  //was griddedobserved
                {
                    this.timeStep = TemporalGranularity.Daily;
                    break;
                }
                default:
                {
                    Climate.ModelCore.UI.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format);
                    throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported.");
                    //break;
                }
            }
        }
Пример #4
0
        public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase)
        {
            // **
            // John McNabb:  new parsing code
            List <int> yearKeys;
            List <List <ClimateRecord>[]> climateRecords;

            Convert_USGS_to_ClimateData2(timeStep, climateFile, climateFileFormat, out yearKeys, out climateRecords);

            Dictionary <int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly

            if (climatePhase == Climate.Phase.Future_Climate)
            {
                allDataRef = Climate.Future_AllData;
            }

            if (climatePhase == Climate.Phase.SpinUp_Climate)
            {
                allDataRef = Climate.Spinup_AllData;
            }

            if (allDataRef == null)
            {
                allDataRef = new Dictionary <int, ClimateRecord[][]>();
            }
            else
            {
                allDataRef.Clear();
            }

            for (var i = 0; i < yearKeys.Count; ++i)
            {
                var ecoRecords = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][];
                allDataRef[yearKeys[i]] = ecoRecords;

                for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j)
                {
                    // convert the parsed climateRecords for this year from List<ClimateRecord>[] to ClimateRecord[][]
                    ecoRecords[j] = climateRecords[i][j].ToArray();
                }
            }
        }
Пример #5
0
        //public static void GetPDSI_Test()
        //{
        //    IEcoregion ecoregion = Climate.ModelCore.Ecoregions[0];
        //    //here:
        //    string outputFilePath = @"C:\Program Files\LANDIS-II\v6\examples\base-BDA_1\PDSI_BaseBDA_Test2.csv";
        //    File.WriteAllText(outputFilePath, String.Empty);
        //    int startYear = 1893, endYear = 1897;
        //    AnnualClimate_Monthly[] acs;
        //    if (endYear > startYear)
        //    {
        //        int numOfYears = endYear - startYear + 1;
        //        acs = new AnnualClimate_Monthly[numOfYears];

        //        double[] mon_T_normal = new double[12] { 19.693, 23.849, 34.988, 49.082, 60.467, 70.074, 75.505, 73.478, 64.484, 52.634, 36.201, 24.267 };
        //        IClimateRecord[] climateRecs = new ClimateRecord[12];

        //        //Climate.TimestepData = allData[0];
        //        //for (int mo = 0; mo < 12; mo++)
        //        //{
        //        //    climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo];
        //        //    //mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2;
        //        //}

        //        acs[0] = new AnnualClimate_Monthly(ecoregion, 1893, 0);
        //        ((AnnualClimate_Monthly)acs[0]).MonthlyTemp = new double[] { 14.371, 14.000, 26.435, 44.250, 54.645, 70.683, 73.355, 69.323, 63.600, 48.806, 32.867, 19.161 };
        //        //acs[0].MonthlyPrecip = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
        //        ((AnnualClimate_Monthly)acs[0]).MonthlyPrecip = new double[] { 0.610, 1.500, 1.730, 4.050, 1.950, 0.790, 3.020, 2.570, 1.430, 0.850, 1.260, 2.350 };

        //        acs[1] = new AnnualClimate_Monthly(ecoregion, 1894, 0);
        //        ((AnnualClimate_Monthly)acs[1]).MonthlyTemp = new double[] { 12.705, 14.979, 37.984, 49.700, 61.209, 71.463, 77.935, 74.312, 65.283, 51.516, 34.767, 29.548 };
        //        ((AnnualClimate_Monthly)acs[1]).MonthlyPrecip = new double[] { 0.700, 0.550, 0.580, 4.240, 2.430, 1.150, 0.580, 1.480, 0.550, 1.760, 0.050, 1.000 };

        //        acs[2] = new AnnualClimate_Monthly(ecoregion, 1895, 0);
        //        ((AnnualClimate_Monthly)acs[2]).MonthlyTemp = new double[] { 12.519, 17.964, 33.994, 54.506, 60.411, 66.172, 70.548, 69.622, 65.288, 44.795, 32.433, 23.333 };
        //        ((AnnualClimate_Monthly)acs[2]).MonthlyPrecip = new double[] { 0.650, 0.540, 0.520, 3.980, 2.380, 6.240, 2.320, 3.920, 4.770, 0.060, 1.040, 0.000 };

        //        acs[3] = new AnnualClimate_Monthly(ecoregion, 1896, 0);
        //        ((AnnualClimate_Monthly)acs[3]).MonthlyTemp = new double[] { 23.258, 27.397, 26.425, 48.833, 62.790, 68.054, 71.365, 70.677, 57.991, 46.355, 21.154, 28.597 };
        //        ((AnnualClimate_Monthly)acs[3]).MonthlyPrecip = new double[] { 0.250, 0.270, 1.670, 5.680, 6.240, 7.740, 5.550, 1.660, 1.810, 3.230, 3.850, 0.230 };

        //        acs[4] = new AnnualClimate_Monthly(ecoregion, 1897, 0);
        //        ((AnnualClimate_Monthly)acs[4]).MonthlyTemp = new double[] { 13.758, 20.179, 26.613, 46.700, 59.016, 66.533, 74.032, 67.928, 71.617, 54.613, 32.450, 18.686 };
        //        ((AnnualClimate_Monthly)acs[4]).MonthlyPrecip = new double[] { 2.500, 0.540, 3.010, 4.480, 0.980, 5.820, 3.780, 1.600, 1.010, 1.940, 0.910, 2.950 };



        //        //for (int i = startYear; i <= endYear; i++)
        //        //{
        //        //    acs[i - startYear] = new AnnualClimate(ecoregion, i, 0); // Latitude should be given
        //        //    //Climate.ModelCore.UI.WriteLine(ac.MonthlyTemp[0].ToString() + "\n");
        //        //    //Climate.ModelCore.UI.WriteLine(ac.MonthlyPrecip[0].ToString() + "\n");
        //        //}



        //        //for (int mo = 0; mo < 12; mo++)
        //        //{
        //        //    climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo];
        //        //    mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2;
        //        //}

        //        double AWC = 0.3;//Landis.Extension.Succession.Century.EcoregionData.FieldCapacity[ecoregion] - Landis.Extension.Succession.Century.EcoregionData.WiltingPoint[ecoregion];
        //        double latitude = 42.60;//Landis.Extension.Succession.Century.EcoregionData.Latitude[ecoregion];
        //        new PDSI_Calculator().CalculatePDSI(acs, mon_T_normal, AWC, latitude, /*outputFilePath,*/ UnitSystem.USCustomaryUnits);

        //    }


        /// <summary>
        /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData
        /// </summary>
        ///
        public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase)
        {
            if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily"))
            {
                future_allData_granularity = TemporalGranularity.Daily;
            }

            else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly"))
            {
                future_allData_granularity = TemporalGranularity.Monthly;
            }

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily"))
            {
                spinup_allData_granularity = TemporalGranularity.Daily;
            }

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly"))
            {
                spinup_allData_granularity = TemporalGranularity.Monthly;
            }

            if (timeSeries.Contains("Daily"))
            {
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);
            }

            else if (timeSeries.Contains("Monthly"))
            {
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);
            }

            //string readableFile = "";
            //if (timeSeries.Contains("MonthlyStandard"))
            //{
            //    ModelCore.UI.WriteLine("Loading from file with Monthly Standard format...\n");
            //    if (future_allData_granularity == TemporalGranularity.Daily)
            //    {
            //        ClimateParser parser = new ClimateParser();
            //        future_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, parser);
            //    }
            //    else if (future_allData_granularity == TemporalGranularity.Monthly)
            //    {
            //        ClimateParser spinup_parser = new ClimateParser();
            //        spinup_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, spinup_parser);
            //    }
            //    return; // filePath;
            //}

            //else if (timeSeries.Contains("Average") || timeSeries.Contains("Random"))
            //{
            //    if (timeSeries.Contains("Daily"))
            //        //return readableFile =
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);
            //    else if (timeSeries.Contains("Monthly"))
            //        //return readableFile =
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);

            //}

            //else if (timeSeries.Contains("MonthlyAverage"))//AverageMonthly
            //{
            //    //return readableFile =
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);
            //}

            ////else if (timeSeries.Contains("Random"))
            ////{
            ////    if (timeSeries.Contains("Daily"))
            ////        return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, File, fileFormat, climatePhase);
            ////    else if (timeSeries.Contains("Monthly"))
            ////        return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, File, fileFormat, climatePhase);
            ////}

            //else if (timeSeries.Contains("DailyGCM"))
            //{
            //    //return readableFile =
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);
            //}

            //else if (timeSeries.Contains("MonthlyGCM"))
            //{
            //    //return readableFile =
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);
            //}

            //else
            //{
            //    ModelCore.UI.WriteLine("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file.");
            //    throw new Exception("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file.");
            //}
            return;// readableFile;
        }
        //------
        public ClimateFileFormatProvider(string format)
        {
            this.format = format;

            // default trigger words
            this.maxTempTriggerWord = new List<string>() { "maxTemp", "Tmax" };
            this.minTempTriggerWord = new List<string>() { "minTemp", "Tmin"};
            this.precipTriggerWord = new List<string>() { "ppt", "precip", "Prcp" };
            this.windDirectionTriggerWord = new List<string>() { "windDirect", "wd", "winddirection", "wind_from_direction" };
            this.windSpeedTriggerWord = new List<string>() { "windSpeed", "ws", "wind_speed" };
            this.nDepositionTriggerWord = new List<string>() { "Ndeposition", "Ndep" };
            this.co2TriggerWord = new List<string>() { "CO2", "CO2conc" };

            //IMPORTANT FOR ML:  Need to add these as optional trigger words.
            //this.precipTriggerWord = "Prcp";
            //    this.maxTempTriggerWord = "Tmax";
            //    this.minTempTriggerWord = "Tmin";

            // Transformations used for all formats that have temps in C and precip in mm
            this.PrecipTransformation = 0.1;        // Assumes data is in mm and so it converts the data from mm to cm.
            this.TemperatureTransformation = 0.0;   // Assumes data is in degrees Celsius so no transformation is needed.
            this.WindSpeedTransformation = 3.6;  //Assumes datas is in m/s so it converts the data to km/h
            this.WindDirectionTransformation = 180;  //Assumes datas is expressed as the direction the wind comes FROM so it converts it to the direction where wind is blowing TO.

            //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily);
            switch (this.format.ToLower())
            {
                case "daily_temp-c_precip-mmday":  //was 'gfdl_a1fi' then ipcc3_daily
                    this.timeStep = TemporalGranularity.Daily;  //temp data are in oC and precip is in mm. CFFP (climate file format provider, L62) converts them to cm.
                    break;

                case "monthly_temp-c_precip-mmmonth":  // was ipcc3_monthly
                    this.timeStep = TemporalGranularity.Monthly;    //temp data are in oC and precip is in mm. CFFP converts them to cm.
                    break;

                case "monthly_temp-k_precip-kgm2sec":               //ipcc5 option
                    this.timeStep = TemporalGranularity.Monthly;
                    this.TemperatureTransformation = ABS_ZERO;      // ipcc5 temp. data are in Kelvin.
                    this.PrecipTransformation = 262974.6;            // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / month
                    break;

                case "daily_temp-k_precip-kgm2sec":             //ipcc5 option
                    this.timeStep = TemporalGranularity.Daily;
                    this.TemperatureTransformation = ABS_ZERO;      // ipcc5 temp. data are in Kelvin.
                    this.PrecipTransformation = 8640.0;             // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / day
                    break;

                case "monthly_temp-k_precip-mmmonth":               //not currently being used on USGS data portal but it's an option nevertheless
                    this.timeStep = TemporalGranularity.Monthly;
                    this.TemperatureTransformation = ABS_ZERO;      // Temp. data in Kelvin. Precip in mm.      CFFP converts them to cm.
                    break;

                case "daily_temp-k_precip-mmday":               // U of Idaho data
                    this.timeStep = TemporalGranularity.Daily;     //Temp are in Kelvin and precip is in mm.
                    this.TemperatureTransformation = ABS_ZERO;
                    break;

                //case "prism_monthly":  //was 'prism'
                //    this.timeStep = TemporalGranularity.Monthly;
                //    break;

                //case "mauer_daily":  //was griddedobserved
                //    this.timeStep = TemporalGranularity.Daily;
                //    this.precipTriggerWord = "Prcp";
                //    this.maxTempTriggerWord = "Tmax";
                //    this.minTempTriggerWord = "Tmin";
                //    // RH and wind speed for Mauer are the default trigger words
                    //break;

                default:
                    Climate.TextLog.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format);
                    throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported.");

            }
        }
        /// <summary>
        /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData
        /// </summary>
        /// 
        public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase)
        {
            if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily"))
                future_allData_granularity = TemporalGranularity.Daily;

            else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly"))
                future_allData_granularity = TemporalGranularity.Monthly;

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily"))
                spinup_allData_granularity = TemporalGranularity.Daily;

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly"))
                spinup_allData_granularity = TemporalGranularity.Monthly;

            if (timeSeries.Contains("Daily"))
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);

            else if (timeSeries.Contains("Monthly"))
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);

            return;
        }
        //------
        public ClimateFileFormatProvider(string format)
        {
            this.format = format;

            // default trigger words
            this.maxTempTriggerWord = new List <string>()
            {
                "maxTemp", "Tmax"
            };
            this.minTempTriggerWord = new List <string>()
            {
                "minTemp", "Tmin"
            };
            this.precipTriggerWord = new List <string>()
            {
                "ppt", "precip", "Prcp"
            };
            this.windDirectionTriggerWord = new List <string>()
            {
                "windDirect", "wd", "winddirection", "wind_from_direction"
            };
            this.windSpeedTriggerWord = new List <string>()
            {
                "windSpeed", "ws", "wind_speed"
            };
            this.windEastingTriggerWord = new List <string>()
            {
                "wind_easting", "easting"
            };
            this.windNorthingTriggerWord = new List <string>()
            {
                "northing", "wind_northing"
            };
            this.nDepositionTriggerWord = new List <string>()
            {
                "Ndeposition", "Ndep"
            };
            this.co2TriggerWord = new List <string>()
            {
                "CO2", "CO2conc"
            };
            this.relativeHumidityTriggerWord = new List <string>()
            {
                "relative_humidity", "RH"
            };
            this.maxRHTriggerWord = new List <string>()
            {
                "max_relative_humidity", "maxRH"
            };
            this.minRHTriggerWord = new List <string>()
            {
                "min_relative_humidity", "minRH"
            };
            this.specificHumidityTriggerWord = new List <string>()
            {
                "specific_humidity", "SH"
            };
            this.petTriggerWord = new List <string>()
            {
                "pet", "PET", "potentialevapotranspiration"
            };
            this.parTriggerWord = new List <string>()
            {
                "PAR", "Light"
            };
            this.ozoneTriggerWord = new List <string>()
            {
                "ozone", "O3"
            };
            this.shortWaveRadiationTriggerWord = new List <string>()
            {
                "shortwave_radiation", "SW_radiation", "SWR"
            };
            this.temperatureTriggerWord = new List <string>()
            {
                "Temp", "Temperature"
            };

            //IMPORTANT FOR ML:  Need to add these as optional trigger words.
            //this.precipTriggerWord = "Prcp";
            //    this.maxTempTriggerWord = "Tmax";
            //    this.minTempTriggerWord = "Tmin";

            // Transformations used for all formats that have temps in C and precip in mm
            this.PrecipTransformation        = 0.1; // Assumes data are in mm and so it converts the data from mm to cm.
            this.TemperatureTransformation   = 0.0; // Assumes data are in degrees Celsius so no transformation is needed.
            this.WindSpeedTransformation     = 3.6; //Assumes data are in m/s so it converts the data to km/h
            this.WindDirectionTransformation = 180; //Assumes data are expressed as the direction the wind comes FROM so it converts it to the direction where wind is blowing TO.


            //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily);
            switch (this.format.ToLower())
            {
            case "daily_temp-c_precip-mmday":              //was 'gfdl_a1fi' then ipcc3_daily
                this.timeStep = TemporalGranularity.Daily; //temp data are in oC and precip is in mm. CFFP (climate file format provider, L62) converts them to cm.
                break;

            case "monthly_temp-c_precip-mmmonth":            // was ipcc3_monthly
                this.timeStep = TemporalGranularity.Monthly; //temp data are in oC and precip is in mm. CFFP converts them to cm.
                break;

            case "monthly_temp-k_precip-kgm2sec":                   //ipcc5 option
                this.timeStep = TemporalGranularity.Monthly;
                this.TemperatureTransformation = ABS_ZERO;          // ipcc5 temp. data are in Kelvin.
                this.PrecipTransformation      = 262974.6;          // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / month
                break;

            case "daily_temp-k_precip-kgm2sec":                 //ipcc5 option
                this.timeStep = TemporalGranularity.Daily;
                this.TemperatureTransformation = ABS_ZERO;      // ipcc5 temp. data are in Kelvin.
                this.PrecipTransformation      = 8640.0;        // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / day
                break;

            case "monthly_temp-k_precip-mmmonth":                   //not currently being used on USGS data portal but it's an option nevertheless
                this.timeStep = TemporalGranularity.Monthly;
                this.TemperatureTransformation = ABS_ZERO;          // Temp. data in Kelvin. Precip in mm.      CFFP converts them to cm.
                break;

            case "daily_temp-k_precip-mmday":                   // U of Idaho data
                this.timeStep = TemporalGranularity.Daily;      //Temp are in Kelvin and precip is in mm.
                this.TemperatureTransformation = ABS_ZERO;
                break;

            default:
                Climate.TextLog.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format);
                throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported.");
            }
        }
Пример #9
0
        //public static void GetPDSI_Test()
        //{
        //    IEcoregion ecoregion = Climate.ModelCore.Ecoregions[0];
        //    //here:
        //    string outputFilePath = @"C:\Program Files\LANDIS-II\v6\examples\base-BDA_1\PDSI_BaseBDA_Test2.csv";
        //    File.WriteAllText(outputFilePath, String.Empty);
        //    int startYear = 1893, endYear = 1897;
        //    AnnualClimate_Monthly[] acs;
        //    if (endYear > startYear)
        //    {
        //        int numOfYears = endYear - startYear + 1;
        //        acs = new AnnualClimate_Monthly[numOfYears];

        //        double[] mon_T_normal = new double[12] { 19.693, 23.849, 34.988, 49.082, 60.467, 70.074, 75.505, 73.478, 64.484, 52.634, 36.201, 24.267 };
        //        IClimateRecord[] climateRecs = new ClimateRecord[12];

        //        //Climate.TimestepData = allData[0];
        //        //for (int mo = 0; mo < 12; mo++)
        //        //{
        //        //    climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo];
        //        //    //mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2;
        //        //}

        //        acs[0] = new AnnualClimate_Monthly(ecoregion, 1893, 0);
        //        ((AnnualClimate_Monthly)acs[0]).MonthlyTemp = new double[] { 14.371, 14.000, 26.435, 44.250, 54.645, 70.683, 73.355, 69.323, 63.600, 48.806, 32.867, 19.161 };
        //        //acs[0].MonthlyPrecip = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
        //        ((AnnualClimate_Monthly)acs[0]).MonthlyPrecip = new double[] { 0.610, 1.500, 1.730, 4.050, 1.950, 0.790, 3.020, 2.570, 1.430, 0.850, 1.260, 2.350 };

        //        acs[1] = new AnnualClimate_Monthly(ecoregion, 1894, 0);
        //        ((AnnualClimate_Monthly)acs[1]).MonthlyTemp = new double[] { 12.705, 14.979, 37.984, 49.700, 61.209, 71.463, 77.935, 74.312, 65.283, 51.516, 34.767, 29.548 };
        //        ((AnnualClimate_Monthly)acs[1]).MonthlyPrecip = new double[] { 0.700, 0.550, 0.580, 4.240, 2.430, 1.150, 0.580, 1.480, 0.550, 1.760, 0.050, 1.000 };

        //        acs[2] = new AnnualClimate_Monthly(ecoregion, 1895, 0);
        //        ((AnnualClimate_Monthly)acs[2]).MonthlyTemp = new double[] { 12.519, 17.964, 33.994, 54.506, 60.411, 66.172, 70.548, 69.622, 65.288, 44.795, 32.433, 23.333 };
        //        ((AnnualClimate_Monthly)acs[2]).MonthlyPrecip = new double[] { 0.650, 0.540, 0.520, 3.980, 2.380, 6.240, 2.320, 3.920, 4.770, 0.060, 1.040, 0.000 };

        //        acs[3] = new AnnualClimate_Monthly(ecoregion, 1896, 0);
        //        ((AnnualClimate_Monthly)acs[3]).MonthlyTemp = new double[] { 23.258, 27.397, 26.425, 48.833, 62.790, 68.054, 71.365, 70.677, 57.991, 46.355, 21.154, 28.597 };
        //        ((AnnualClimate_Monthly)acs[3]).MonthlyPrecip = new double[] { 0.250, 0.270, 1.670, 5.680, 6.240, 7.740, 5.550, 1.660, 1.810, 3.230, 3.850, 0.230 };

        //        acs[4] = new AnnualClimate_Monthly(ecoregion, 1897, 0);
        //        ((AnnualClimate_Monthly)acs[4]).MonthlyTemp = new double[] { 13.758, 20.179, 26.613, 46.700, 59.016, 66.533, 74.032, 67.928, 71.617, 54.613, 32.450, 18.686 };
        //        ((AnnualClimate_Monthly)acs[4]).MonthlyPrecip = new double[] { 2.500, 0.540, 3.010, 4.480, 0.980, 5.820, 3.780, 1.600, 1.010, 1.940, 0.910, 2.950 };



        //        //for (int i = startYear; i <= endYear; i++)
        //        //{
        //        //    acs[i - startYear] = new AnnualClimate(ecoregion, i, 0); // Latitude should be given
        //        //    //Climate.ModelCore.UI.WriteLine(ac.MonthlyTemp[0].ToString() + "\n");
        //        //    //Climate.ModelCore.UI.WriteLine(ac.MonthlyPrecip[0].ToString() + "\n");
        //        //}



        //        //for (int mo = 0; mo < 12; mo++)
        //        //{
        //        //    climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo];
        //        //    mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2;
        //        //}

        //        double AWC = 0.3;//Landis.Extension.Succession.Century.EcoregionData.FieldCapacity[ecoregion] - Landis.Extension.Succession.Century.EcoregionData.WiltingPoint[ecoregion];
        //        double latitude = 42.60;//Landis.Extension.Succession.Century.EcoregionData.Latitude[ecoregion];
        //        new PDSI_Calculator().CalculatePDSI(acs, mon_T_normal, AWC, latitude, /*outputFilePath,*/ UnitSystem.USCustomaryUnits);

        //    }


        /// <summary>
        /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData
        /// </summary>
        /// 
        public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase)
        {
            if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily"))
                future_allData_granularity = TemporalGranularity.Daily;
                
            else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly"))
                future_allData_granularity = TemporalGranularity.Monthly;

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily"))
                spinup_allData_granularity = TemporalGranularity.Daily;

            else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly"))
                spinup_allData_granularity = TemporalGranularity.Monthly;

            if (timeSeries.Contains("Daily"))
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);
            
            else if (timeSeries.Contains("Monthly"))
                ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);

                //string readableFile = "";
            //if (timeSeries.Contains("MonthlyStandard"))
            //{
            //    ModelCore.UI.WriteLine("Loading from file with Monthly Standard format...\n"); 
            //    if (future_allData_granularity == TemporalGranularity.Daily)
            //    {
            //        ClimateParser parser = new ClimateParser();
            //        future_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, parser);
            //    }
            //    else if (future_allData_granularity == TemporalGranularity.Monthly)
            //    {
            //        ClimateParser spinup_parser = new ClimateParser();
            //        spinup_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, spinup_parser);
            //    }
            //    return; // filePath;
            //}

            //else if (timeSeries.Contains("Average") || timeSeries.Contains("Random"))
            //{
            //    if (timeSeries.Contains("Daily"))
            //        //return readableFile = 
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);
            //    else if (timeSeries.Contains("Monthly"))
            //        //return readableFile = 
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);

            //}

            //else if (timeSeries.Contains("MonthlyAverage"))//AverageMonthly
            //{
            //    //return readableFile = 
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);
            //}

            ////else if (timeSeries.Contains("Random"))
            ////{
            ////    if (timeSeries.Contains("Daily"))
            ////        return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, File, fileFormat, climatePhase);
            ////    else if (timeSeries.Contains("Monthly"))
            ////        return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, File, fileFormat, climatePhase);
            ////}

            //else if (timeSeries.Contains("DailyGCM"))
            //{
            //    //return readableFile = 
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase);
            //}

            //else if (timeSeries.Contains("MonthlyGCM"))
            //{
            //    //return readableFile = 
            //        ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase);
            //}

            //else
            //{
            //    ModelCore.UI.WriteLine("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file.");
            //    throw new Exception("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file.");
            //}
            return;// readableFile;

        }
Пример #10
0
        public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase)
        {
            //Dictionary<int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly
            //if (climatePhase == Climate.Phase.Future_Climate)
            //    allDataRef = Climate.Future_AllData;

            //if (climatePhase == Climate.Phase.SpinUp_Climate)
            //    allDataRef = Climate.Spinup_AllData;

            //// parse the input file into lists of timestamps and corresponding climate records arrays
            //List<string> timeStamps;
            //List<ClimateRecord>[] climateRecords;       // indexing: [ecoregion.Count][i]
            //Convert_USGS_to_ClimateData(timeStep, climateFile, climateFileFormat, out timeStamps, out climateRecords);

            //// break up the ecoregion lists into a dictionary by year based on timeStamp keys
            //var yearData = new Dictionary<int, List<ClimateRecord>[]>();    // indexing: [year][ecoregion][i]

            //var currentYear = -999;

            //List<ClimateRecord>[] yearRecords = null;

            //for (var j = 0; j < timeStamps.Count; ++j)
            //{
            //    var year = int.Parse(timeStamps[j].Substring(0, 4));

            //    // timestamps are grouped by year in the input files
            //    if (year != currentYear)
            //    {
            //        // make yearRecords instance for the new year
            //        yearRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count];
            //        for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            //            yearRecords[i] = new List<ClimateRecord>();

            //        yearData[year] = yearRecords;
            //        currentYear = year;
            //    }

            //    // add the climate records onto the year records
            //    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            //        yearRecords[i].Add(climateRecords[i][j]);
            //}

            //// transfer the data to allDataRef and
            //// do some basic error checking

            //if (allDataRef == null)
            //    allDataRef = new Dictionary<int, ClimateRecord[][]>();
            //else
            //    allDataRef.Clear();

            //foreach (var key in yearData.Keys)
            //{
            //    allDataRef[key] = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][];

            //    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            //    {
            //        if (timeStep == TemporalGranularity.Monthly && yearData[key][i].Count != 12)
            //            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Monthly data for year {0} in climate file '{1}' does not have 12 records.  It has {2} records.", key, climateFile, yearData[key][i].Count));

            //        if (timeStep == TemporalGranularity.Daily && yearData[key][i].Count != 365)
            //            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Daily data for year {0} in climate file '{1}' does not have 365 records.  It has {2} records.", key, climateFile, yearData[key][i].Count));

            //        // convert the yearRecords from List<ClimateRecord>[] to ClimateRecord[][]
            //        allDataRef[key][i] = yearData[key][i].ToArray();
            //    }
            //}

            // **
            // John McNabb:  new parsing code
            List <int> yearKeys;
            List <List <ClimateRecord>[]> climateRecords;

            Convert_USGS_to_ClimateData2(timeStep, climateFile, climateFileFormat, out yearKeys, out climateRecords);

            Dictionary <int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly

            if (climatePhase == Climate.Phase.Future_Climate)
            {
                allDataRef = Climate.Future_AllData;
            }

            if (climatePhase == Climate.Phase.SpinUp_Climate)
            {
                allDataRef = Climate.Spinup_AllData;
            }

            if (allDataRef == null)
            {
                allDataRef = new Dictionary <int, ClimateRecord[][]>();
            }
            else
            {
                allDataRef.Clear();
            }

            for (var i = 0; i < yearKeys.Count; ++i)
            {
                var ecoRecords = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][];
                allDataRef[yearKeys[i]] = ecoRecords;

                for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j)
                {
                    // convert the parsed climateRecords for this year from List<ClimateRecord>[] to ClimateRecord[][]
                    ecoRecords[j] = climateRecords[i][j].ToArray();
                }
            }
        }
        //--------------------------------------------------------------------
        /// <summary>
        /// This function converts Monthly to Monthly and Daily to Monthly
        /// </summary>
        /// <returns>string: file name of the converted monthly file </returns>
        public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase)
        {
            Dictionary<int, IClimateRecord[,]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly
            if (climatePhase == Climate.Phase.Future_Climate)
                allDataRef = Climate.Future_AllData;
            
            if (climatePhase == Climate.Phase.SpinUp_Climate)
                allDataRef = Climate.Spinup_AllData;

            //The Convert conversts the csv file data to a dictionary (of either daily or monthly data)
            //--------------------------------------------------------------------
            //string resultingFileName = 
                Convert_USGS_to_ClimateData(timeStep, climateFile, climateFileFormat);
            //-------------------------------------------------------------------- 
            //Then read from the dictionary and convert it to IClimate records 

            //if (timeStep == TimeStep.Daily)
            //{
            //setIndexed(checkRHWindSpeed);
            IndexMaxT_Mean = 0;
            IndexMaxT_Var = 1;
            IndexMaxT_STD = 2;
            IndexMinT_Mean = 3;
            IndexMinT_Var = 4;
            IndexMinT_STD = 5;
            IndexPrcp_Mean = 6;
            IndexPrcp_Var = 7;
            IndexPrcp_STD = 8;

            IndexRH_Mean = 9;
            IndexRH_Var = 10;
            IndexRH_STD = 11;

            IndexwindSpeed_Mean = 12;
            IndexwindSpeed_Var = 13;
            IndexwindSpeed_STD = 14;


            for (int j = firstYear; j <= lastYear; j++)//for each year
            {
                currentYear = j.ToString();

                //Dictionary<string, double[]> climate_Dic_currentYear = (Dictionary<string, double[]>)climate_Dic.Where(r => r.Key.Substring(0, 4).ToString() == currentYear);
                IEnumerable<KeyValuePair<string, double[]>> climate_Dic_currentYear = climate_Dic.Where(r => r.Key.Substring(0, 4).ToString() == currentYear);

                IClimateRecord[,] icrs = new IClimateRecord[Climate.ModelCore.Ecoregions.Count, climate_Dic_currentYear.Count()]; // climate_Dic_currentYear.Count: number of days/months in a year
                
                for (int i = 0; i < Climate.ModelCore.Ecoregions.Count; i++) //for each ecoregion either active or inactive
                {
                    //IClimateRecord icr;
                    List<IClimateRecord> icrList = new List<IClimateRecord>();
                    int icrCount = 0;
                    foreach (KeyValuePair<string, double[]> row in climate_Dic_currentYear) // foreach day/month in a certain year-ecoregion
                    {

                        IClimateRecord icr = new ClimateRecord(row.Value[IndexMinT_Mean], row.Value[IndexMaxT_Mean], (row.Value[IndexMinT_STD] + row.Value[IndexMaxT_STD]) / 2, row.Value[IndexPrcp_Mean], row.Value[IndexPrcp_STD], 0, (row.Value[IndexMinT_Var] + row.Value[IndexMaxT_Var]) / 2, 0, row.Value[IndexRH_Mean], row.Value[IndexRH_Var], row.Value[IndexRH_STD], row.Value[IndexwindSpeed_Mean], row.Value[IndexwindSpeed_Var], row.Value[IndexwindSpeed_STD]);
                        if (Climate.ModelCore.Ecoregions[i].Active)
                            icrs[i, icrCount++] = icr;//new KeyValuePair<int, IClimateRecord>(i, icr);

                    }

                }

                allDataRef.Add(j, icrs);
            }

            return;// resultingFileName;
        }
        public static void Convert_USGS_to_ClimateData(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat)
        {

            ClimateFileFormatProvider formatProvider = new ClimateFileFormatProvider(climateFileFormat);
            maxTriggerWord = formatProvider.MaxTempTriggerWord;
            minTriggerWord = formatProvider.MinTempTriggerWord;
            prcpTriggerWord = formatProvider.PrecipTriggerWord;
            rhTriggerWord = formatProvider.RhTriggerWord;
            windSpeedTriggerWord = formatProvider.WindSpeedTriggerWord;
            bool checkRHWindSpeed = false;


            string unmatched_TriggerWords;

            if (checkRHWindSpeed == false)
                unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord;// +", " + rhTriggerWord + ", " + windSpeedTriggerWord;
            else
                unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord;

            int triggerWordsCheckingTime = 0;
            string path = climateFile;
            StreamReader sreader;
            string centuryPath = "";
            // monthly and daily climates should be filled before in order to chack weather input climatefile can be processed as daily or monthly
            //List<string> montlyClimates;
            //List<string> DailyClimate;

            climateFileFormat = climateFileFormat.ToLower();
            Climate.ModelCore.UI.WriteLine("   Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat, sourceTemporalGranularity);


            #region IPCC3 Input file 
            if (climateFileFormat == "ipcc3_daily" || climateFileFormat == "ipcc3_monthly") 
            {
                exportToTxtFormatFile = false;
                sreader = new StreamReader(path);
                string line;
                string[] fields;
                DataTable _dataTableDataByTime = new DataTable();
                line = sreader.ReadLine();
                fields = line.Split(',');
                line = sreader.ReadLine();
                fields = line.Split(',');

                string CurrentScenarioType = "";
                climate_Dic = new Dictionary<string, double[]>();


                string key = "";
                currentYear = "";
                int currentTimeS = 0;
                currentMonth = 1;
                int tempEco = 1;
                double AverageMax = 0;
                double AverageMin = 0;
                double SumPrecp = 0;

                double AverageSTDT = 0;
                double SumVarPpt = 0;
                int numberOfDays = 0;
                double[] tempSum = new double[31];
                double[] tempPrp = new double[31];
                //bool emptytxt = false;
                int updatedIndex = 0;

                //int ecoIndex = -1;
                climateFileActiveEcoregions = new SortedList<int, Core.IEcoregion>();

                foreach (string field in fields)
                {

                    if (field != "")
                    {
                        //if (Convert.ToInt16(field) > ecoIndex)
                        //{
                        //    ecoIndex = Convert.ToInt16(field);
                            IEcoregion eco = Climate.ModelCore.Ecoregions[field]; //.Where(P => P.Index == ecoIndex).FirstOrDefault();
                            //numberOfAllEcoregions = Convert.ToInt16(field);
                            if (eco != null && eco.Active)
                            {
                                if (!climateFileActiveEcoregions.ContainsKey(eco.Index))
                                    climateFileActiveEcoregions.Add(eco.Index, eco);
                            }
                            else
                            {
                                //Climate.ModelCore.UI.WriteLine("ClimateDataConvertor: Number of active ecoregions does not match the input file. The climate data for ecoregion with index {0} was ignored.", numberOfAllEcoregions);
                                Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; Number of active ecoregions does not match the input file.", climateFile);
                                throw new ApplicationException("Error in ClimateDataConvertor: Converting" + climateFile + "file into standard format; Number of active ecoregions does not match the input file.");
                            }

                        }
                }


                //12 beacuse for each ecoriogn we need Max_MinT,Max_MaxT,Max_Var Max_Std, Min_MinT,Min_MaxT,Min_Var Min_Std, Prcp_MinT,Prcp_MaxT,Prcp_Var Prcp_Std
                int dicSize = climateFileActiveEcoregions.Count * 15; 
                sreader.Close();
                StreamReader reader = new StreamReader(path);

                while (reader.Peek() >= 0)
                {
                    line = reader.ReadLine();
                    fields = line.Split(',');
                    foreach (string field in fields)
                    {
                        if (field.Contains("#"))
                        {
                            triggerWordsCheckingTime++;
                            if (triggerWordsCheckingTime > 1)
                                if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord && checkRHWindSpeed == true)
                                {
                                    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following trigger words did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat);
                                    throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                                }
                                else if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord && checkRHWindSpeed == false)
                                {
                                    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following trigger words did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat);
                                    throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                                }

                            //tempScenarioName = CurrentScenarioName;
                            //if (field.ToLower().Contains(maxTriggerWord) || field.ToLower().Contains(minTriggerWord))
                            //{
                            //CurrentScenarioName = field.Substring(1, field.LastIndexOf("t") - 2);
                            if (field.ToLower().Contains(maxTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = maxTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(maxTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(minTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = minTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + minTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(prcpTriggerWord.ToLower()))
                            {
                                //CurrentScenarioName = field.Substring(1, field.LastIndexOf("p") - 2);
                                CurrentScenarioType = prcpTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + prcpTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(rhTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = rhTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + rhTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(windSpeedTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = windSpeedTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + windSpeedTriggerWord, "");
                            }


                        }



                    }


                    if (fields[0] == string.Empty && !fields[0].Contains("#"))
                    {
                        line = reader.ReadLine();
                        fields = line.Split(',');

                        if (fields[0].Contains("TIME"))
                        {
                            line = reader.ReadLine();
                            fields = line.Split(',');

                            //now fill array 
                            //Get the lenght of array according to the number of ecorigions/
                            //

                        }
                    }
                    if (!fields[0].Contains("#"))
                    //if (CurrentScenarioName == tempScenarioName && !fields[0].Contains("#"))
                    {

                        key = fields[0].ToString();
                        if (CurrentScenarioType.ToLower().Contains(maxTriggerWord.ToLower()))
                        {
                            IndexMaxT_Mean = 0;
                            //IndexMax_MaxT = 1;
                            IndexMaxT_Var = 1;
                            IndexMaxT_STD = 2;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });

                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                //currentT = fields[i+1];
                                //if (indexofSTD < 26)
                                //{

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMaxT_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMax_MaxT);
                                //updatedIndex +=  numberOfAllEcoregions;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_STD);
                                IndexMaxT_Mean = IndexMaxT_Mean + 9;
                                //IndexMax_MaxT = IndexMax_MaxT + 12;
                                IndexMaxT_Var = IndexMaxT_Var + 9;
                                IndexMaxT_STD = IndexMaxT_STD + 9;
                                updatedIndex = 0;

                                //indexofSTD++;
                                //}

                            }
                        }
                        else if (CurrentScenarioType.ToLower().Contains(minTriggerWord.ToLower()))
                        {
                            IndexMinT_Mean = 3;
                            //IndexMin_MaxT = 5;
                            IndexMinT_Var = 4;
                            IndexMinT_STD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                //currentT = fields[i+1];
                                //if (indexofSTD < 26)
                                //{
                                //currentSTD = fields[indexofSTD];
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMinT_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMin_MaxT);
                                //updatedIndex += numberOfAllEcoregions;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_STD);


                                //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD);
                                IndexMinT_Mean = IndexMinT_Mean + 9;
                                //IndexMin_MaxT = IndexMin_MaxT + 12;
                                IndexMinT_Var = IndexMinT_Var + 9;
                                IndexMinT_STD = IndexMinT_STD + 9;
                                updatedIndex = 0;
                                //    IndexSTD = IndexSTD + 6;
                                //    indexofSTD++;
                                //}

                            }
                        }
                        else if (CurrentScenarioType.ToLower().Contains(prcpTriggerWord.ToLower()))
                        {
                            IndexPrcp_Mean = 6;
                            //IndexPrcp_MaxT = 9;
                            IndexPrcp_Var = 7;
                            IndexPrcp_STD = 8;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            
                            //set index of Precipitation and STD for each ecoregion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                //currentT = fields[i+1];
                                //if (indexofSTD < 26)
                                //{
                                //currentSTD = fields[indexofSTD];
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) / 10, IndexPrcp_Mean); //  /10 is for mm to cm conversion
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexPrcp_MaxT);
                                //updatedIndex += numberOfAllEcoregions;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_Var); 
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_STD); //NOTE: this might be a wrong conversion for converting IndexPrcp_STD from mm to cm because STD is calculate using root square.


                                //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD);
                                IndexPrcp_Mean = IndexPrcp_Mean + 9;
                                //IndexPrcp_MaxT = IndexPrcp_MaxT + 12;
                                IndexPrcp_Var = IndexPrcp_Var + 9;
                                IndexPrcp_STD = IndexPrcp_STD + 9;
                                updatedIndex = 0;
                                //IndexSTD = IndexSTD + 6;
                                //indexofSTD++;
                            }

                        }


                        //-----
                        else if (CurrentScenarioType.ToLower().Contains(rhTriggerWord.ToLower()))
                        {
                            IndexRH_Mean = 9;
                            IndexRH_Var = 10;
                            IndexRH_STD = 11;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexRH_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_STD);


                                IndexRH_Mean = IndexRH_Mean + 9;
                                IndexRH_Var = IndexRH_Var + 9;
                                IndexRH_STD = IndexRH_STD + 9;
                                updatedIndex = 0;

                            }

                        }

                        //-----
                        else if (CurrentScenarioType.ToLower().Contains(windSpeedTriggerWord.ToLower()))
                        {
                            IndexwindSpeed_Mean = 12;
                            IndexwindSpeed_Var = 13;
                            IndexwindSpeed_STD = 14;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexwindSpeed_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_STD);


                                IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9;
                                IndexwindSpeed_Var = IndexwindSpeed_Var + 9;
                                IndexwindSpeed_STD = IndexwindSpeed_STD + 9;
                                updatedIndex = 0;

                            }

                        }
                        //-----


                    }  //end while


                    //if (CurrentScenarioName != tempScenarioName || reader.EndOfStream)
                    if (reader.EndOfStream)
                    {
                        //Print file for one scenario then clear dictionary to use for another scenario

                        //Daily period
                        centuryPath = "Century_Climate_Inputs_Monthly.txt";
                        setIndexed();
                        //using (System.IO.StreamWriter file = new System.IO.StreamWriter(centuryPath, emptytxt))
                        //{
                        //    if (exportToTxtFormatFile)
                        //    {
                        //        file.WriteLine("LandisData" + " \"Climate Data\" \n");
                        //        file.WriteLine("ClimateTable \n");
                        //        //file.WriteLine(tempScenarioName + "\n");
                        //        file.WriteLine(">>Eco" + "\t\t" + "Time" + "\t" + "Month" + "\t" + "AvgMinT" + "\t" + "AvgMaxT" + "\t" + "StdDevT" + "\t" + "AvgPpt" + "\t" + "StdDevPpt" + "\t" + "PAR" + "\t" + "VarT" + "\t" + "VarPpt" + "\n");
                        //        file.WriteLine(">>Name" + "\t\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(k)" + "\t" + "(cm)" + "\t" + "Ppt" + "\t" + "µmol m-2 s-1" + "\t" + "(cm)" + "\t" + "(cm)" + "\n");

                        //    }
                        //    else
                        //    {
                        //        file.WriteLine("This file is not generated when converting a Daily Climate to Monthly.");
                        //        file.WriteLine("To enable the generation of this file:");
                        //        file.WriteLine("set 'exportToTxtFormatFile = true;' in 'if (sourceTemporalGranularity == TemporalGranularity.Daily) \n { \n \t exportToTxtFormatFile = false; ' in ClimateDataConvertor class.");
                        //        file.WriteLine("Caution: Note that the right AnnualCliamte_Monthly will not be generated if this generated Monthly-climate txt file is used as a climate input file.");
                        //    }
                            currentYear = climate_Dic.First().Key.Substring(0, 4).ToString();
                            //starting timestep
                            currentTimeS = 0;
                            currentMonth = Convert.ToInt16(climate_Dic.First().Key.Substring(5, 2).ToString());
                            tempEco = 1;


                            lastYear = climate_Dic.AsEnumerable().Select(ax => Convert.ToInt32(ax.Key.Substring(0, 4).ToString())).Distinct().ToList().Max();
                            firstYear = climate_Dic.AsEnumerable().Select(ai => Convert.ToInt32(ai.Key.Substring(0, 4).ToString())).Distinct().ToList().Min();
                            if ((double)climate_Dic.Count / 12 > (double)lastYear - firstYear)
                                lastYear = lastYear - 1;

                            for (int j = firstYear; j <= lastYear; j++)
                            {
                                for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                                {
                                    currentYear = j.ToString();

                                    foreach (KeyValuePair<string, double[]> row in climate_Dic)
                                    {
                                        if (currentYear == row.Key.Substring(0, 4).ToString())
                                        {

                                            if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2)))
                                            {

                                                //(row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean])/2
                                                //AverageMin += (row.Value[IndexMin_MaxT] + row.Value[IndexMinT_Mean]) / 2;
                                                //AverageMax += (row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean]) / 2;
                                                //AveragePrecp += (row.Value[IndexPrcp_MaxT] + row.Value[IndexPrcp_Mean]) / 2;
                                                //AverageSTDT += (row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2;
                                                //AverageMaxSTD += Math.Round(Convert.ToDouble(row.Value[2]), 2);
                                                AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                                AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                                SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2));
                                                AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                                SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]);


                                                numberOfDays++;

                                            }



                                            else
                                            {
                                                //if (exportToTxtFormatFile)
                                                //    file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(Math.Sqrt(SumVarPpt), 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(SumVarPpt, 2) + "\n");
                                                currentMonth = Convert.ToInt16(row.Key.Substring(5, 2));
                                                //if (tempMonth != currentMonth)
                                                alldays += numberOfDays;
                                                AverageMax = 0;
                                                AverageMin = 0;
                                                SumPrecp = 0;
                                                AverageSTDT = 0;
                                                SumVarPpt = 0;

                                                numberOfDays = 0;
                                                AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                                AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                                SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2));
                                                AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                                SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]);

                                                numberOfDays++;
                                            }


                                        }
                                        else
                                        {
                                            if (currentMonth == 12)
                                            {
                                                alldays += numberOfDays;
                                                if (!yearsdays.Keys.Contains(j))
                                                {
                                                    yearsdays.Add(j, alldays);
                                                    alldays = 0;
                                                }

                                            }
                                            

                                            alldays = 0;
                                            tempEco = i;
                                            currentMonth = 1;
                                            AverageMax = 0;
                                            //AverageMaxSTD = 0;
                                            AverageMin = 0;
                                            //AverageMinSTD = 0;
                                            SumPrecp = 0;
                                            //AveragePrecSTD = 0;

                                            AverageSTDT = 0;
                                            SumVarPpt = 0;

                                            numberOfDays = 0;
                                            AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                            AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                            SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2));
                                            AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                            SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]);
                                            //sums = 0;
                                            //stdTemp = 0;
                                            //prpSums = 0;
                                            //stdPrp = 0;
                                            numberOfDays++;
                                        }


                                    }
                                    tempEco = i;

                                    currentMonth = 1;
                                    AverageMax = 0;
                                    //AverageMaxSTD = 0;
                                    AverageMin = 0;
                                    //AverageMinSTD = 0;
                                    SumPrecp = 0;
                                    //AveragePrecSTD = 0;

                                    AverageSTDT = 0;
                                    SumVarPpt = 0;

                                    IndexMaxT_Mean = IndexMaxT_Mean + 9;
                                    //IndexMax_MaxT = IndexMax_MaxT + 12;
                                    IndexMaxT_Var = IndexMaxT_Var + 9;
                                    IndexMaxT_STD = IndexMaxT_STD + 9;
                                    IndexMinT_Mean = IndexMinT_Mean + 9;
                                    //IndexMin_MaxT = IndexMin_MaxT + 12;
                                    IndexMinT_Var = IndexMinT_Var + 9;
                                    IndexMinT_STD = IndexMinT_STD + 9;
                                    IndexPrcp_Mean = IndexPrcp_Mean + 9;
                                    //IndexPrcp_MaxT = IndexPrcp_MaxT + 12;
                                    IndexPrcp_Var = IndexPrcp_Var + 9;
                                    IndexPrcp_STD = IndexPrcp_STD + 9;


                                    IndexRH_Mean = IndexRH_Mean + 9;
                                    IndexRH_Var = IndexRH_Var + 9;
                                    IndexRH_STD = IndexRH_STD + 9;

                                    IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9;
                                    IndexwindSpeed_Var = IndexwindSpeed_Var + 9;
                                    IndexwindSpeed_STD = IndexwindSpeed_STD + 9;

                                }
                                //file.WriteLine("eco" + numberOfAllEcoregions.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(StdDevPpt), 2) + "\t" + "0.0" + "\n");

                                tempEco = 1;
                                currentTimeS = currentTimeS + 1;
                                IndexMaxT_Mean = 0;
                                //IndexMax_MaxT = 1;
                                IndexMaxT_Var = 1;
                                IndexMaxT_STD = 2;
                                IndexMinT_Mean = 3;
                                //IndexMin_MaxT = 5;
                                IndexMinT_Var = 4;
                                IndexMinT_STD = 5;
                                IndexPrcp_Mean = 6;
                                //IndexPrcp_MaxT = 9;
                                IndexPrcp_Var = 7;
                                IndexPrcp_STD = 8;

                                IndexRH_Mean = 9;
                                IndexRH_Var = 10;
                                IndexRH_STD = 11;

                                IndexwindSpeed_Mean = 12;
                                IndexwindSpeed_Var = 13;
                                IndexwindSpeed_STD = 14;

                                currentMonth = 1;
                                AverageMax = 0;
                                //AverageMaxSTD = 0;
                                AverageMin = 0;
                                //AverageMinSTD = 0;
                                SumPrecp = 0;
                                //AveragePrecSTD = 0;

                                AverageSTDT = 0;
                                SumVarPpt = 0;

                            }

                        }

                        //If file contains more than one scenario then these setting will be needed
                        //climate_Dic.Clear();
                        //emptytxt = true;
                        //tempScenarioName = CurrentScenarioName;

                    //}
                }
                //if (unmatched_TriggerWords != "")
                //{
                //    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format.", climateFile);
                //    Climate.ModelCore.UI.WriteLine("The following triggerWords did not match the triggerwords in the given file: {1}.  Selected format: {2}", unmatched_TriggerWords, formatProvider.SelectedFormat);
                //    throw new ApplicationException("Error in ClimateDataConvertor: See Log File."); //: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                //}

            }
            #endregion

            #region IPCC5 Input file
            else if (climateFileFormat == "ipcc5_monthly" || climateFileFormat == "ipcc5_daily") 
            {
                exportToTxtFormatFile = false;
                sreader = new StreamReader(path);
                string line;
                string[] fields;
                DataTable _dataTableDataByTime = new DataTable();
                line = sreader.ReadLine();
                fields = line.Split(',');
                line = sreader.ReadLine();
                fields = line.Split(',');

                string CurrentScenarioType = "";
                climate_Dic = new Dictionary<string, double[]>();


                string key = "";
                currentYear = "";
                int currentTimeS = 0;
                currentMonth = 1;
                int tempEco = 1;
                double AverageMax = 0;
                double AverageMin = 0;
                double SumPrecp = 0;

                double AverageSTDT = 0;
                double SumVarPpt = 0;
                int numberOfDays = 0;
                double[] tempSum = new double[31];
                double[] tempPrp = new double[31];
                //bool emptytxt = false;
                int updatedIndex = 0;

                //int ecoIndex = -1;
                climateFileActiveEcoregions = new SortedList<int, Core.IEcoregion>();

                foreach (string field in fields)
                {

                    if (field != "")
                        //if (Convert.ToInt16(field) > ecoIndex)
                        {
                            //ecoIndex = Convert.ToInt16(field);
                            IEcoregion eco = Climate.ModelCore.Ecoregions[field]; //.Where(P => P.Index == ecoIndex).FirstOrDefault();
                            if (eco != null && eco.Active)
                            {
                                if (!climateFileActiveEcoregions.ContainsKey(eco.Index))
                                    climateFileActiveEcoregions.Add(eco.Index, eco);
                            }
                            else
                            {
                                //Climate.ModelCore.UI.WriteLine("ClimateDataConvertor: Number of active ecoregions does not match the input file. The climate data for ecoregion with index {0} was ignored.", numberOfAllEcoregions);
                                Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; Number of active ecoregions does not match the input file.", climateFile);
                                throw new ApplicationException("Error in ClimateDataConvertor: Converting" + climateFile + "file into standard format; Number of active ecoregions does not match the input file.");
                            }

                        }
                }


                //12 beacuse for each ecoriogn we need Max_MinT,Max_MaxT,Max_Var Max_Std, Min_MinT,Min_MaxT,Min_Var Min_Std, Prcp_MinT,Prcp_MaxT,Prcp_Var Prcp_Std
                int dicSize = climateFileActiveEcoregions.Count * 15;
                sreader.Close();
                StreamReader reader = new StreamReader(path);

                while (reader.Peek() >= 0)
                {
                    line = reader.ReadLine();
                    fields = line.Split(',');
                    foreach (string field in fields)
                    {
                        if (field.Contains("#"))
                        {
                            triggerWordsCheckingTime++;
                            if (triggerWordsCheckingTime > 1)
                                if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord && checkRHWindSpeed == true)
                                {
                                    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat);
                                    throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                                }
                                else if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord && checkRHWindSpeed == false)
                                {
                                    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat);
                                    throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                                }

                            //tempScenarioName = CurrentScenarioName;
                            //if (field.ToLower().Contains(maxTriggerWord) || field.ToLower().Contains(minTriggerWord))
                            //{
                            //CurrentScenarioName = field.Substring(1, field.LastIndexOf("t") - 2);
                            if (field.ToLower().Contains(maxTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = maxTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(maxTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(minTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = minTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + minTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(prcpTriggerWord.ToLower()))
                            {
                                //CurrentScenarioName = field.Substring(1, field.LastIndexOf("p") - 2);
                                CurrentScenarioType = prcpTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + prcpTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(rhTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = rhTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + rhTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(windSpeedTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = windSpeedTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + windSpeedTriggerWord, "");
                            }


                        }



                    }


                    if (fields[0] == string.Empty && !fields[0].Contains("#"))
                    {
                        line = reader.ReadLine();
                        fields = line.Split(',');

                        if (fields[0].Contains("TIME"))
                        {
                            line = reader.ReadLine();
                            fields = line.Split(',');

                        }
                    }
                    if (!fields[0].Contains("#"))
                    {

                        key = fields[0].ToString();
                        if (CurrentScenarioType.ToLower().Contains(maxTriggerWord.ToLower()))
                        {
                            IndexMaxT_Mean = 0;
                            IndexMaxT_Var = 1;
                            IndexMaxT_STD = 2;
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);

                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) - 274.15, IndexMaxT_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_STD);
                                IndexMaxT_Mean = IndexMaxT_Mean + 9;
                                IndexMaxT_Var = IndexMaxT_Var + 9;
                                IndexMaxT_STD = IndexMaxT_STD + 9;
                                updatedIndex = 0;


                            }
                        }
                        else if (CurrentScenarioType.ToLower().Contains(minTriggerWord.ToLower()))
                        {
                            IndexMinT_Mean = 3;
                            IndexMinT_Var = 4;
                            IndexMinT_STD = 5;

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) - 274.15, IndexMinT_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) - 274.15, IndexMinT_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) - 274.15, IndexMinT_STD);

                                IndexMinT_Mean = IndexMinT_Mean + 9;
                                IndexMinT_Var = IndexMinT_Var + 9;
                                IndexMinT_STD = IndexMinT_STD + 9;
                                updatedIndex = 0;

                            }
                        }
                        else if (CurrentScenarioType.ToLower().Contains(prcpTriggerWord.ToLower()))
                        {
                            IndexPrcp_Mean = 6;
                            IndexPrcp_Var = 7;
                            IndexPrcp_STD = 8;

                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);

                            //set index of Precipitation and STD for each ecoregion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) * 315360, IndexPrcp_Mean); 
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) * 315360, IndexPrcp_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) * 315360, IndexPrcp_STD); //NOTE: this might be a wrong conversion for converting IndexPrcp_STD from mm to cm because STD is calculate using root square.

                                IndexPrcp_Mean = IndexPrcp_Mean + 9;
                                IndexPrcp_Var = IndexPrcp_Var + 9;
                                IndexPrcp_STD = IndexPrcp_STD + 9;
                                updatedIndex = 0;
                            }

                        }


                        //-----
                        else if (CurrentScenarioType.ToLower().Contains(rhTriggerWord.ToLower()))
                        {
                            IndexRH_Mean = 9;
                            IndexRH_Var = 10;
                            IndexRH_STD = 11;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexRH_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_STD);


                                IndexRH_Mean = IndexRH_Mean + 9;
                                IndexRH_Var = IndexRH_Var + 9;
                                IndexRH_STD = IndexRH_STD + 9;
                                updatedIndex = 0;

                            }

                        }

                        //-----
                        else if (CurrentScenarioType.ToLower().Contains(windSpeedTriggerWord.ToLower()))
                        {
                            IndexwindSpeed_Mean = 12;
                            IndexwindSpeed_Var = 13;
                            IndexwindSpeed_STD = 14;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexwindSpeed_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_STD);


                                IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9;
                                IndexwindSpeed_Var = IndexwindSpeed_Var + 9;
                                IndexwindSpeed_STD = IndexwindSpeed_STD + 9;
                                updatedIndex = 0;

                            }

                        }
                        //-----


                    }  //end while


                    //if (CurrentScenarioName != tempScenarioName || reader.EndOfStream)
                    if (reader.EndOfStream)
                    {
                        //Daily period
                        //centuryPath = "Century_Climate_Inputs_Monthly.txt";
                        setIndexed();
                        currentYear = climate_Dic.First().Key.Substring(0, 4).ToString();
                        //starting timestep
                        currentTimeS = 0;
                        currentMonth = Convert.ToInt16(climate_Dic.First().Key.Substring(5, 2).ToString());
                        tempEco = 1;


                        lastYear = climate_Dic.AsEnumerable().Select(ax => Convert.ToInt32(ax.Key.Substring(0, 4).ToString())).Distinct().ToList().Max();
                        firstYear = climate_Dic.AsEnumerable().Select(ai => Convert.ToInt32(ai.Key.Substring(0, 4).ToString())).Distinct().ToList().Min();
                        if ((double)climate_Dic.Count / 12 > (double)lastYear - firstYear)
                            lastYear = lastYear - 1;

                        for (int j = firstYear; j <= lastYear; j++)
                        {
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                currentYear = j.ToString();

                                foreach (KeyValuePair<string, double[]> row in climate_Dic)
                                {
                                    if (currentYear == row.Key.Substring(0, 4).ToString())
                                    {

                                        if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2)))
                                        {

                                            AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                            AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                            SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2));
                                            AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                            SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]);
                                            numberOfDays++;

                                        }
                                        else
                                        {
                                            //if (exportToTxtFormatFile)
                                            //    file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(Math.Sqrt(SumVarPpt), 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(SumVarPpt, 2) + "\n");
                                            currentMonth = Convert.ToInt16(row.Key.Substring(5, 2));
                                            //if (tempMonth != currentMonth)
                                            alldays += numberOfDays;
                                            AverageMax = 0;
                                            AverageMin = 0;
                                            SumPrecp = 0;
                                            AverageSTDT = 0;
                                            SumVarPpt = 0;

                                            numberOfDays = 0;
                                            AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                            AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                            SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2));
                                            AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                            SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]);

                                            numberOfDays++;
                                        }


                                    }
                                    else
                                    {
                                        if (currentMonth == 12)
                                        {
                                            alldays += numberOfDays;
                                            //if (exportToTxtFormatFile)
                                            //    file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(Math.Sqrt(SumVarPpt), 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(SumVarPpt, 2) + "\n");
                                            if (!yearsdays.Keys.Contains(j))
                                            {
                                                yearsdays.Add(j, alldays);
                                                alldays = 0;
                                            }
                                        }


                                        alldays = 0;
                                        tempEco = i;
                                        currentMonth = 1;
                                        AverageMax = 0;
                                        AverageMin = 0;
                                        SumPrecp = 0;

                                        AverageSTDT = 0;
                                        SumVarPpt = 0;

                                        numberOfDays = 0;
                                        AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                        AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                        SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2));
                                        AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                        SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]);
                                        numberOfDays++;
                                    }


                                }
                                tempEco = i;

                                currentMonth = 1;
                                AverageMax = 0;
                                //AverageMaxSTD = 0;
                                AverageMin = 0;
                                //AverageMinSTD = 0;
                                SumPrecp = 0;
                                //AveragePrecSTD = 0;

                                AverageSTDT = 0;
                                SumVarPpt = 0;

                                IndexMaxT_Mean = IndexMaxT_Mean + 9;
                                //IndexMax_MaxT = IndexMax_MaxT + 12;
                                IndexMaxT_Var = IndexMaxT_Var + 9;
                                IndexMaxT_STD = IndexMaxT_STD + 9;
                                IndexMinT_Mean = IndexMinT_Mean + 9;
                                //IndexMin_MaxT = IndexMin_MaxT + 12;
                                IndexMinT_Var = IndexMinT_Var + 9;
                                IndexMinT_STD = IndexMinT_STD + 9;
                                IndexPrcp_Mean = IndexPrcp_Mean + 9;
                                //IndexPrcp_MaxT = IndexPrcp_MaxT + 12;
                                IndexPrcp_Var = IndexPrcp_Var + 9;
                                IndexPrcp_STD = IndexPrcp_STD + 9;


                                IndexRH_Mean = IndexRH_Mean + 9;
                                IndexRH_Var = IndexRH_Var + 9;
                                IndexRH_STD = IndexRH_STD + 9;

                                IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9;
                                IndexwindSpeed_Var = IndexwindSpeed_Var + 9;
                                IndexwindSpeed_STD = IndexwindSpeed_STD + 9;

                            }
                            //file.WriteLine("eco" + numberOfAllEcoregions.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(StdDevPpt), 2) + "\t" + "0.0" + "\n");

                            tempEco = 1;
                            currentTimeS = currentTimeS + 1;
                            IndexMaxT_Mean = 0;
                            //IndexMax_MaxT = 1;
                            IndexMaxT_Var = 1;
                            IndexMaxT_STD = 2;
                            IndexMinT_Mean = 3;
                            //IndexMin_MaxT = 5;
                            IndexMinT_Var = 4;
                            IndexMinT_STD = 5;
                            IndexPrcp_Mean = 6;
                            //IndexPrcp_MaxT = 9;
                            IndexPrcp_Var = 7;
                            IndexPrcp_STD = 8;

                            IndexRH_Mean = 9;
                            IndexRH_Var = 10;
                            IndexRH_STD = 11;

                            IndexwindSpeed_Mean = 12;
                            IndexwindSpeed_Var = 13;
                            IndexwindSpeed_STD = 14;

                            currentMonth = 1;
                            AverageMax = 0;
                            //AverageMaxSTD = 0;
                            AverageMin = 0;
                            //AverageMinSTD = 0;
                            SumPrecp = 0;
                            //AveragePrecSTD = 0;

                            AverageSTDT = 0;
                            SumVarPpt = 0;

                        }

                    }

                    //If file contains more than one scenario then these setting will be needed
                    //climate_Dic.Clear();
                    //emptytxt = true;
                    //tempScenarioName = CurrentScenarioName;

                    //}
                }
                //if (unmatched_TriggerWords != "")
                //{
                //    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format.", climateFile);
                //    Climate.ModelCore.UI.WriteLine("The following triggerWords did not match the triggerwords in the given file: {1}.  Selected format: {2}", unmatched_TriggerWords, formatProvider.SelectedFormat);
                //    throw new ApplicationException("Error in ClimateDataConvertor: See Log File."); //: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                //}

            }
            #endregion

            #region PRISM Monthly Data
            //else if (sourceTemporalGranularity == TemporalGranularity.Monthly)
            else if (climateFileFormat == "prism_monthly") 
            {

                //unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord;// +", " + rhTriggerWord + ", " + windSpeedTriggerWord;

                sreader = new StreamReader(path);  // NEED TRY CATCH FILE OPEN HERE


                string line;
                string[] fields;
                checkRHWindSpeed = false;

                if (checkRHWindSpeed == false)
                    unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord;// +", " + rhTriggerWord + ", " + windSpeedTriggerWord;
                else
                    unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord;

                //string tempScenarioName = "";
                DataTable _dataTableDataByTime = new DataTable();
                //int numberOfAllEcoregions = 0;
                line = sreader.ReadLine();
                fields = line.Split(',');
                //tempScenarioName = fields[0].Substring(1, fields[0].LastIndexOf("t") - 2);
                //tempScenarioName = fields[0].Substring(1, 4);
                line = sreader.ReadLine();
                fields = line.Split(',');
                //int totalRows = 0;
                //string[,] wholedata;
                //string CurrentScenarioName = "";

                string CurrentScenarioType = "";
                climate_Dic = new Dictionary<string, double[]>();

                //string currentT;
                //string currentSTD;
                //string currentPart = "";
                //int totalRow = 0;
                string key = "";
                int IndexMaxT_Mean = 0;
                //int IndexMax_MaxT = 1;
                int IndexMaxT_Var = 1;
                int IndexMaxT_STD = 2;
                int IndexMinT_Mean = 3;
                //int IndexMin_MaxT = 5;
                int IndexMinT_Var = 4;
                int IndexMinT_STD = 5;
                int IndexPrcp_Mean = 6;
                //int IndexPrcp_MaxT = 9;
                int IndexPrcp_Var = 7;
                int IndexPrcp_STD = 8;
                int IndexRH_Mean = 9;
                int IndexRH_Var = 10;
                int IndexRH_STD = 11;
                int IndexwindSpeed_Mean = 12;
                int IndexwindSpeed_Var = 13;
                int IndexwindSpeed_STD = 14;

                //bool firstFlag = false;
                currentYear = "";
                //starting timestep
                int currentTimeS = 0;
                currentMonth = 1;
                int tempEco = 1;
                double AverageMax = 0;

                //double AverageMaxSTD = 0;
                double AverageMin = 0;
                //double AverageMinSTD = 0;
                double SumPrecp = 0;

                double AverageSTDT = 0;
                double sumVarPpt = 0;
                //double AveragePrecSTD = 0;
                int numberOfDays = 0;
                double[] tempSum = new double[31];
                double[] tempPrp = new double[31];
                //double sums = 0;
                //double prpSums = 0;
                //double stdTemp = 0;
                //double stdPrp = 0;
                bool emptytxt = false;
                int updatedIndex = 0;


                // IEnumerable<Core.IEcoregion> activeEcoregions = Climate.ModelCore.Ecoregions.Where(P => P.Active);
                //int ecoIndex = -1;
                climateFileActiveEcoregions = new SortedList<int, Core.IEcoregion>();

                foreach (string field in fields)
                {
                    if (field != "")
                    {
                        //if (Convert.ToInt16(field) > ecoIndex)
                        //{
                        //    ecoIndex = Convert.ToInt16(field);
                            IEcoregion eco = Climate.ModelCore.Ecoregions[field]; //.Where(P => P.Index == ecoIndex).FirstOrDefault();
                            //numberOfAllEcoregions = Convert.ToInt16(field);
                            if (eco != null && eco.Active)
                            {
                                if (!climateFileActiveEcoregions.ContainsKey(eco.Index))
                                    climateFileActiveEcoregions.Add(eco.Index, eco);
                            }
                            else
                            {
                                //Climate.ModelCore.UI.WriteLine("ClimateDataConvertor: Number of active ecoregions does not match the input file. The climate data for ecoregion with index {0} was ignored.", numberOfAllEcoregions);
                                Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; Number of active ecoregions does not match the input file.", climateFile);
                                throw new ApplicationException("Error in ClimateDataConvertor: Converting" + climateFile + "file into standard format; Number of active ecoregions does not match the input file.");
                            }

                     }
                }


                //12 beacuse for each ecoriogn we need Max_MinT,Max_MaxT,Max_Var Max_Std, Min_MinT,Min_MaxT,Min_Var Min_Std, Prcp_MinT,Prcp_MaxT,Prcp_Var Prcp_Std
                int dicSize = climateFileActiveEcoregions.Count * 15;// Climate.ModelCore.Ecoregions.Count * 9;
                sreader.Close();
                StreamReader reader = new StreamReader(path);

                while (reader.Peek() >= 0)
                {
                    line = reader.ReadLine();
                    fields = line.Split(',');
                    foreach (string field in fields)
                    {
                        if (field.Contains("#"))
                        {

                            triggerWordsCheckingTime++;
                            if (triggerWordsCheckingTime > 1)
                                if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord && checkRHWindSpeed == true)
                                {
                                    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat);
                                    throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                                }
                                else if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord && checkRHWindSpeed == false)
                                {
                                    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat);
                                    throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                                }


                            //tempScenarioName = CurrentScenarioName;
                            if (field.ToLower().Contains(prcpTriggerWord.ToLower()))
                            {
                                //CurrentScenarioName = field.Substring(1, 4);
                                CurrentScenarioType = prcpTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + prcpTriggerWord, "");
                            }

                            //else if (field.ToLower().Contains(maxTriggerWord.ToLower()) || field.ToLower().Contains(minTriggerWord.ToLower()))
                            //{
                            //CurrentScenarioName = field.Substring(1, 4);
                            else if (field.ToLower().Contains(maxTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = maxTriggerWord;
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(maxTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(minTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = minTriggerWord.ToLower();
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + minTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(rhTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = rhTriggerWord.ToLower();
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + rhTriggerWord, "");
                            }
                            else if (field.ToLower().Contains(windSpeedTriggerWord.ToLower()))
                            {
                                CurrentScenarioType = windSpeedTriggerWord.ToLower();
                                unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + windSpeedTriggerWord, "");
                            }
                            //}


                            //if (tempScenarioName != CurrentScenarioName)// firstFlag == false)
                            //{
                            //    tempScenarioName = CurrentScenarioName;
                            //    //firstFlag = true;
                            //}



                            //line = reader.ReadLine();
                            //fields = line.Split(',');

                        }



                    }

                    if (fields[0] == string.Empty && !fields[0].Contains("#"))
                    {
                        line = reader.ReadLine();
                        fields = line.Split(',');

                        if (fields[0].Contains("TIME"))
                        {
                            line = reader.ReadLine();
                            fields = line.Split(',');

                            //now fill array 
                            //Get the lenght of array according to the number of ecorigions/
                            //

                        }
                    }
                    if (!fields[0].Contains("#"))//(CurrentScenarioName == tempScenarioName && !fields[0].Contains("#"))
                    {

                        key = fields[0].ToString();
                        if (CurrentScenarioType.ToLower().Contains(prcpTriggerWord.ToLower()))
                        {
                            IndexPrcp_Mean = 6;
                            //IndexPrcp_MaxT = 9;
                            IndexPrcp_Var = 7;
                            IndexPrcp_STD = 8;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                //currentT = fields[i+1];
                                //if (indexofSTD < 26)
                                //{
                                //currentSTD = fields[indexofSTD];
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) / 10, IndexPrcp_Mean); // /10 is for mm to cm conversion
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexPrcp_MaxT);
                                //updatedIndex += numberOfAllEcoregions;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_STD);


                                //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD);
                                IndexPrcp_Mean = IndexPrcp_Mean + 9;
                                //IndexPrcp_MaxT = IndexPrcp_MaxT + 12;
                                IndexPrcp_Var = IndexPrcp_Var + 9;
                                IndexPrcp_STD = IndexPrcp_STD + 9;
                                updatedIndex = 0;
                                //IndexSTD = IndexSTD + 6;
                                //indexofSTD++;
                            }

                        }

                        else if (CurrentScenarioType.ToLower().Contains(maxTriggerWord.ToLower()))
                        {
                            IndexMaxT_Mean = 0;
                            //IndexMax_MaxT = 1;
                            IndexMaxT_Var = 1;
                            IndexMaxT_STD = 2;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });

                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {
                                //currentT = fields[i+1];
                                //if (indexofSTD < 26)
                                //{

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMaxT_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMax_MaxT);
                                //updatedIndex +=  numberOfAllEcoregions;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_STD);
                                IndexMaxT_Mean = IndexMaxT_Mean + 9;
                                //IndexMax_MaxT = IndexMax_MaxT + 12;
                                IndexMaxT_Var = IndexMaxT_Var + 9;
                                IndexMaxT_STD = IndexMaxT_STD + 9;
                                updatedIndex = 0;

                                //indexofSTD++;
                                //}

                            }
                        }
                        else if (CurrentScenarioType.ToLower().Contains(minTriggerWord.ToLower()))
                        {
                            IndexMinT_Mean = 3;
                            //IndexMin_MaxT = 5;
                            IndexMinT_Var = 4;
                            IndexMinT_STD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });

                            //set index of max and maxSTD for each ecorigion
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {

                                //currentT = fields[i+1];
                                //if (indexofSTD < 26)
                                //{
                                //currentSTD = fields[indexofSTD];
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMinT_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;
                                //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMin_MaxT);
                                //updatedIndex += numberOfAllEcoregions;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_STD);


                                //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD);
                                IndexMinT_Mean = IndexMinT_Mean + 9;
                                //IndexMin_MaxT = IndexMin_MaxT + 12;
                                IndexMinT_Var = IndexMinT_Var + 9;
                                IndexMinT_STD = IndexMinT_STD + 9;
                                updatedIndex = 0;
                                //    IndexSTD = IndexSTD + 6;
                                //    indexofSTD++;
                                //}

                            }
                        }

                         //-----
                        else if (CurrentScenarioType.ToLower().Contains(rhTriggerWord.ToLower()))
                        {
                            IndexRH_Mean = 9;
                            IndexRH_Var = 10;
                            IndexRH_STD = 11;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexRH_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_STD);


                                IndexRH_Mean = IndexRH_Mean + 9;
                                IndexRH_Var = IndexRH_Var + 9;
                                IndexRH_STD = IndexRH_STD + 9;
                                updatedIndex = 0;

                            }

                        }

                        //-----
                        else if (CurrentScenarioType.ToLower().Contains(windSpeedTriggerWord.ToLower()))
                        {
                            IndexwindSpeed_Mean = 12;
                            IndexwindSpeed_Var = 13;
                            IndexwindSpeed_STD = 14;

                            //IndexSTD = 5;
                            //int indexofSTD = 0;
                            //indexofSTD = fields.Length - (numberOfAllEcoregions);

                            // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 });
                            if (!climate_Dic.Keys.Contains(key))
                                climate_Dic.Add(key, new double[dicSize]);
                            //set index of max and maxSTD for each ecorigion
                            for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                            {

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexwindSpeed_Mean);
                                updatedIndex += i + climateFileActiveEcoregions.Count;

                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_Var);
                                updatedIndex += climateFileActiveEcoregions.Count;
                                climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_STD);


                                IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9;
                                IndexwindSpeed_Var = IndexwindSpeed_Var + 9;
                                IndexwindSpeed_STD = IndexwindSpeed_STD + 9;
                                updatedIndex = 0;

                            }

                        }


                    }

                    if (reader.EndOfStream)//CurrentScenarioName != tempScenarioName || reader.EndOfStream)
                    {
                        //tempScenarioName = CurrentScenarioName;
                        //Print file for one scenario then clear dictionary to use for another scenario

                        //Monthly peiod
                        centuryPath = "Century_Climate_Inputs_PRISM_Monthly.txt";
                        //int AverageMaxT = 0;
                        //int AverageMaxSTD = 1;
                        //int AverageMinT = 2;
                        //int AverageMinSTD = 3;
                        //int AveragePrec = 4;
                        //int AveragePrecSTD = 5;
                        IndexMaxT_Mean = 0;
                        //IndexMax_MaxT = 1;
                        IndexMaxT_Var = 1;
                        IndexMaxT_STD = 2;
                        IndexMinT_Mean = 3;
                        //IndexMin_MaxT = 5;
                        IndexMinT_Var = 4;
                        IndexMinT_STD = 5;
                        IndexPrcp_Mean = 6;
                        //IndexPrcp_MaxT = 9;
                        IndexPrcp_Var = 7;
                        IndexPrcp_STD = 8;
                        IndexRH_Mean = 9;
                        IndexRH_Var = 10;
                        IndexRH_STD = 11;

                        IndexwindSpeed_Mean = 12;
                        IndexwindSpeed_Var = 13;
                        IndexwindSpeed_STD = 14;


                        //int AverageMaxT = 0;
                        //int AverageMaxSTD = 1;
                        //int AverageMinT = 1;
                        //int AverageMinSTD = 3;
                        //int AveragePrec = 2;
                        //int AveragePrecSTD = 5;
                        using (System.IO.StreamWriter file = new System.IO.StreamWriter(centuryPath, emptytxt))
                        {
                            if (exportToTxtFormatFile)
                            {
                                file.WriteLine("LandisData" + " \"Climate Data\" \n");
                                file.WriteLine("ClimateTable \n");
                                //file.WriteLine(tempScenarioName + "\n");

                                file.WriteLine(">>Eco" + "\t\t" + "Time" + "\t" + "Month" + "\t" + "AvgMinT" + "\t" + "AvgMaxT" + "\t" + "StdDevT" + "\t" + "AvgPpt" + "\t" + "StdDevPpt" + "\t" + "PAR" + "\t" + "VarT" + "\t" + "VarPpt" + "\n");
                                file.WriteLine(">>Name" + "\t\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(k)" + "\t" + "(cm)" + "\t" + "Ppt" + "\t" + "µmol m-2 s-1" + "\t" + "(cm)" + "\t" + "(cm)" + "\n");
                                //file.WriteLine(">>Eco" + "\t" + "Time" + "\t" + "Month" + "\t" + "AvgMinT" + "\t" + "AvgMaxT" + "\t" + "StdDevT" + "\t" + "AvgPpt" + "\t" + "StdDev" + "\t" + "PAR" + "\n");
                                //file.WriteLine(">>Name" + "\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(k)" + "\t" + "(cm)" + "\t" + "Ppt" + "\t" + "µmol m-2 s-1" + "\n");
                                //file.WriteLine(">>Eco" + "\t" + "Time" + "\t" + "\t" + "AvgMaxT" + "\t" + "StdMaxT" + "\t" + "AvgMinT" + "\t" + "StdMinT" + "\t" + "AvgPpt" + "\t" + "StdDev" + "\n");
                                // file.WriteLine(">>Name" + "\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\n");
                            }
                            //initialize currentYear and month
                            currentYear = climate_Dic.First().Key.Substring(0, 4).ToString();
                            //starting timestep
                            currentTimeS = 0;
                            currentMonth = Convert.ToInt16(climate_Dic.First().Key.Substring(5, 2).ToString());
                            tempEco = 1;
                            lastYear = climate_Dic.AsEnumerable().Select(ax => Convert.ToInt32(ax.Key.Substring(0, 4).ToString())).Distinct().ToList().Max();
                            firstYear = climate_Dic.AsEnumerable().Select(ai => Convert.ToInt32(ai.Key.Substring(0, 4).ToString())).Distinct().ToList().Min();
                            if ((double)climate_Dic.Count / 12 > (double)lastYear - firstYear)
                                lastYear = lastYear - 1;
                            for (int j = firstYear; j <= lastYear; j++)
                            {
                                for (int i = 0; i < climateFileActiveEcoregions.Count; i++)
                                {
                                    currentYear = j.ToString();
                                    foreach (KeyValuePair<string, double[]> row in climate_Dic)
                                    {

                                        if (currentYear == row.Key.Substring(0, 4).ToString())
                                        {
                                            if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2)))
                                            {
                                                AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                                AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                                SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2));
                                                AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                                sumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]);
                                                numberOfDays++;

                                            }
                                            else
                                            {
                                                if (exportToTxtFormatFile)
                                                    file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\n");
                                                //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n");
                                                //tempMonth = currentMonth;
                                                currentMonth = Convert.ToInt16(row.Key.Substring(5, 2));
                                                //if (tempMonth != currentMonth)

                                                AverageMax = 0;
                                                //AverageMaxSTD = 0;
                                                AverageMin = 0;
                                                //AverageMinSTD = 0;
                                                SumPrecp = 0;
                                                //AveragePrecSTD = 0;
                                                AverageSTDT = 0;
                                                sumVarPpt = 0;
                                                numberOfDays = 0;
                                                AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                                                AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                                                SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); 
                                                AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                                                sumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]);
                                                //sums = 0;
                                                //stdTemp = 0;
                                                //prpSums = 0;
                                                //stdPrp = 0;
                                                numberOfDays++;
                                            }
                                        }
                                        else //  currentYear != row.Key.Substring(0, 4).ToString())
                                        {
                                            //if (tempEco != i && currentMonth == 12)
                                            //    file.WriteLine("eco" + tempEco.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n");

                                            if (exportToTxtFormatFile)
                                                if (currentMonth == 12)
                                                    file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\n");
                                            ////if (currentTimeS == 0 && currentMonth == 12 && i==2)
                                            //    file.WriteLine("eco2" + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n");

                                            //else if (tempEco != i)
                                            //    currentTimeS = 0;
                                            //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMaxT / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n");

                                            //currentYear = row.Key.Substring(0, 4).ToString();
                                            //currentTimeS = currentTimeS + 1;
                                            tempEco = i;
                                            currentMonth = 1;
                                            AverageMax = 0;
                                            //AverageMaxSTD = 0;
                                            AverageMin = 0;
                                            //AverageMinSTD = 0;
                                            SumPrecp = 0;
                                            //AveragePrecSTD = 0;

                                            AverageSTDT = 0;
                                            sumVarPpt = 0;

                                            numberOfDays = 0;

                                        }
                                    }
                                    tempEco = i;
                                    currentMonth = 1;
                                    AverageMax = 0;
                                    //AverageMaxSTD = 0;
                                    AverageMin = 0;
                                    //AverageMinSTD = 0;
                                    SumPrecp = 0;
                                    //AveragePrecSTD = 0;

                                    AverageSTDT = 0;
                                    sumVarPpt = 0;
                                    IndexMaxT_Mean = IndexMaxT_Mean + 9;
                                    //IndexMax_MaxT = IndexMax_MaxT + 12;
                                    IndexMaxT_Var = IndexMaxT_Var + 9;
                                    IndexMaxT_STD = IndexMaxT_STD + 9;
                                    IndexMinT_Mean = IndexMinT_Mean + 9;
                                    //IndexMin_MaxT = IndexMin_MaxT + 12;
                                    IndexMinT_Var = IndexMinT_Var + 9;
                                    IndexMinT_STD = IndexMinT_STD + 9;
                                    IndexPrcp_Mean = IndexPrcp_Mean + 9;
                                    //IndexPrcp_MaxT = IndexPrcp_MaxT + 12;
                                    IndexPrcp_Var = IndexPrcp_Var + 9;
                                    IndexPrcp_STD = IndexPrcp_STD + 9;

                                    IndexRH_Mean = IndexRH_Mean + 9;
                                    IndexRH_Var = IndexRH_Var + 9;
                                    IndexRH_STD = IndexRH_STD + 9;

                                    IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9;
                                    IndexwindSpeed_Var = IndexwindSpeed_Var + 9;
                                    IndexwindSpeed_STD = IndexwindSpeed_STD + 9;

                                }

                                tempEco = 1;
                                currentTimeS = currentTimeS + 1;
                                IndexMaxT_Mean = 0;
                                //IndexMax_MaxT = 1;
                                IndexMaxT_Var = 1;
                                IndexMaxT_STD = 2;
                                IndexMinT_Mean = 3;
                                //IndexMin_MaxT = 5;
                                IndexMinT_Var = 4;
                                IndexMinT_STD = 5;
                                IndexPrcp_Mean = 6;
                                //IndexPrcp_MaxT = 9;
                                IndexPrcp_Var = 7;
                                IndexPrcp_STD = 8;

                                IndexRH_Mean = 9;
                                IndexRH_Var = 10;
                                IndexRH_STD = 11;

                                IndexwindSpeed_Mean = 12;
                                IndexwindSpeed_Var = 13;
                                IndexwindSpeed_STD = 14;

                                currentMonth = 1;
                                AverageMax = 0;
                                //AverageMaxSTD = 0;
                                AverageMin = 0;
                                //AverageMinSTD = 0;
                                SumPrecp = 0;
                                //AveragePrecSTD = 0;

                                AverageSTDT = 0;
                                sumVarPpt = 0;
                            }


                            //    for (int i = 1; i <= numberOfAllEcoregions; i++)
                            //    {

                            //        foreach (KeyValuePair<string, double[]> row in climate_Dic)
                            //        {

                            //            //file.WriteLine("eco" + i.ToString() + "\t" + row.Key.Remove(10) + "\t" + Math.Round(row.Value[AverageMaxT], 2) +  "\t" + Math.Round(row.Value[AverageMinT], 2) +  "\t" + Math.Round(row.Value[AveragePrec], 2)  + "\n");
                            //            //file.WriteLine("eco" + i.ToString() + "\t" + row.Key.Remove(10) + "\t" + Math.Round(row.Value[AverageMaxT], 2) + "\t" + Math.Round(row.Value[AverageMaxSTD], 2) + "\t" + Math.Round(row.Value[AverageMinT], 2) + "\t" + Math.Round(row.Value[AverageMinSTD], 2) + "\t" + Math.Round(row.Value[AveragePrec], 2) + "\t" + Math.Round(row.Value[AveragePrecSTD], 2) + "\n");

                            //                if (currentYear == row.Key.Substring(0, 4).ToString())
                            //                {

                            //                    if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2)))
                            //                    {

                            //                        //(row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean])/2
                            //                        //AverageMin += (row.Value[IndexMin_MaxT] + row.Value[IndexMinT_Mean]) / 2;
                            //                        //AverageMax += (row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean]) / 2;
                            //                        //AveragePrecp += (row.Value[IndexPrcp_MaxT] + row.Value[IndexPrcp_Mean]) / 2;
                            //                        //AverageSTDT += (row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2;
                            //                        //AverageMaxSTD += Math.Round(Convert.ToDouble(row.Value[2]), 2);
                            //                        AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                            //                        AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                            //                        AveragePrecp += Math.Round(row.Value[IndexPrcp_Mean], 2);
                            //                        AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                            //                        StdDevPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]);

                            //                        //AverageMinSTD += Math.Round(Convert.ToDouble(row.Value[4]), 2);
                            //                        //AveragePrecp += Math.Round(row.Value[AveragePrec], 2);
                            //                        //AveragePrecSTD += Math.Round(Convert.ToDouble(row.Value[6]), 2);

                            //                        //Calculating STD of Tempeture
                            //                        //tempSum[numberOfDays] = (row.Value[AverageMaxT] + row.Value[AverageMinT]) / 2;
                            //                        //stdTemp = 0;
                            //                        //stdPrp = 0;


                            //                        //Calculating STD of Prp
                            //                        //tempPrp[numberOfDays] = row.Value[AveragePrec];

                            //                        numberOfDays++;

                            //                    }


                            //                    else
                            //                    {
                            //                        //for (int j = 0; j < numberOfDays; j++)
                            //                        //{
                            //                        //    sums += Math.Pow((tempSum[j] - (((AverageMax / numberOfDays) + (AverageMin / numberOfDays)) / 2)), 2);
                            //                        //    prpSums += Math.Pow(tempPrp[j] - (AveragePrec / numberOfDays), 2);
                            //                        //}

                            //                        //stdTemp = Math.Sqrt(sums / (numberOfDays - 1));
                            //                        //stdPrp = Math.Sqrt(prpSums / (numberOfDays - 1));
                            //                        file.WriteLine("eco" + i.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n");
                            //                        //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n");
                            //                        //tempMonth = currentMonth;
                            //                        currentMonth = Convert.ToInt16(row.Key.Substring(5, 2));
                            //                        //if (tempMonth != currentMonth)

                            //                        AverageMax = 0;
                            //                        //AverageMaxSTD = 0;
                            //                        AverageMin = 0;
                            //                        //AverageMinSTD = 0;
                            //                        AveragePrecp = 0;
                            //                        //AveragePrecSTD = 0;
                            //                        AverageSTDT = 0;
                            //                        StdDevPpt = 0;

                            //                        numberOfDays = 0;
                            //                        AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                            //                        AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                            //                        AveragePrecp += Math.Round(row.Value[IndexPrcp_Mean], 2);
                            //                        AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                            //                        StdDevPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]);
                            //                        //sums = 0;
                            //                        //stdTemp = 0;
                            //                        //prpSums = 0;
                            //                        //stdPrp = 0;
                            //                        numberOfDays++;
                            //                    }

                            //                }
                            //                else
                            //                {
                            //                    //If ecorigion has been changed
                            //                    if (tempEco != i && currentMonth == 12)
                            //                    {
                            //                        file.WriteLine("eco" + tempEco.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n");
                            //                        currentTimeS = 0;
                            //                    }

                            //                    else if (currentMonth == 12)
                            //                    {
                            //                        file.WriteLine("eco" + i.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n");
                            //                        currentTimeS = currentTimeS + 1;
                            //                    }
                            //                    else if (tempEco != i)
                            //                        currentTimeS = 0;
                            //                    //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMaxT / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n");

                            //                    currentYear = row.Key.Substring(0, 4).ToString();
                            //                    //currentTimeS = currentTimeS + 1;
                            //                    tempEco = i;
                            //                    currentMonth = 1;
                            //                    AverageMax = 0;
                            //                    //AverageMaxSTD = 0;
                            //                    AverageMin = 0;
                            //                    //AverageMinSTD = 0;
                            //                    AveragePrecp = 0;
                            //                    //AveragePrecSTD = 0;

                            //                    AverageSTDT = 0;
                            //                    StdDevPpt = 0;

                            //                    numberOfDays = 0;
                            //                    AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2);
                            //                    AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2);
                            //                    AveragePrecp += Math.Round(row.Value[IndexPrcp_Mean], 2);
                            //                    AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2);
                            //                    StdDevPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]);
                            //                    //sums = 0;
                            //                    //stdTemp = 0;
                            //                    //prpSums = 0;
                            //                    //stdPrp = 0;
                            //                    numberOfDays++;
                            //                }


                            //        }

                            //        IndexMaxT_Mean = IndexMaxT_Mean + 9;
                            //        //IndexMax_MaxT = IndexMax_MaxT + 12;
                            //        IndexMaxT_Var = IndexMaxT_Var + 9;
                            //        IndexMaxT_STD = IndexMaxT_STD + 9;
                            //        IndexMinT_Mean = IndexMinT_Mean + 9;
                            //        //IndexMin_MaxT = IndexMin_MaxT + 12;
                            //        IndexMinT_Var = IndexMinT_Var + 9;
                            //        IndexMinT_STD = IndexMinT_STD + 9;
                            //        IndexPrcp_Mean = IndexPrcp_Mean + 9;
                            //        //IndexPrcp_MaxT = IndexPrcp_MaxT + 12;
                            //        IndexPrcp_Var = IndexPrcp_Var + 9;
                            //        IndexPrcp_STD = IndexPrcp_STD + 9;
                            //    }
                            //    file.WriteLine("eco" + numberOfAllEcoregions.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n");



                        }


                        //If file contains more than one scenario then these setting will be needed
                        //climate_Dic.Clear();
                        //emptytxt = true;
                        //tempScenarioName = CurrentScenarioName;

                    }
                }

                if (unmatched_TriggerWords != "")
                {
                    Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat);
                    throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\"");
                }

            }

            #endregion

            return; // centuryPath;

        }
        public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase)
        {
            //Dictionary<int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly
            //if (climatePhase == Climate.Phase.Future_Climate)
            //    allDataRef = Climate.Future_AllData;

            //if (climatePhase == Climate.Phase.SpinUp_Climate)
            //    allDataRef = Climate.Spinup_AllData;

            //// parse the input file into lists of timestamps and corresponding climate records arrays
            //List<string> timeStamps;
            //List<ClimateRecord>[] climateRecords;       // indexing: [ecoregion.Count][i]
            //Convert_USGS_to_ClimateData(timeStep, climateFile, climateFileFormat, out timeStamps, out climateRecords);

            //// break up the ecoregion lists into a dictionary by year based on timeStamp keys
            //var yearData = new Dictionary<int, List<ClimateRecord>[]>();    // indexing: [year][ecoregion][i]

            //var currentYear = -999;

            //List<ClimateRecord>[] yearRecords = null;

            //for (var j = 0; j < timeStamps.Count; ++j)
            //{
            //    var year = int.Parse(timeStamps[j].Substring(0, 4));

            //    // timestamps are grouped by year in the input files
            //    if (year != currentYear)
            //    {
            //        // make yearRecords instance for the new year
            //        yearRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count];
            //        for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            //            yearRecords[i] = new List<ClimateRecord>();

            //        yearData[year] = yearRecords;
            //        currentYear = year;
            //    }

            //    // add the climate records onto the year records
            //    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            //        yearRecords[i].Add(climateRecords[i][j]);
            //}

            //// transfer the data to allDataRef and
            //// do some basic error checking

            //if (allDataRef == null)
            //    allDataRef = new Dictionary<int, ClimateRecord[][]>();
            //else
            //    allDataRef.Clear();

            //foreach (var key in yearData.Keys)
            //{
            //    allDataRef[key] = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][];

            //    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            //    {
            //        if (timeStep == TemporalGranularity.Monthly && yearData[key][i].Count != 12)
            //            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Monthly data for year {0} in climate file '{1}' does not have 12 records.  It has {2} records.", key, climateFile, yearData[key][i].Count));

            //        if (timeStep == TemporalGranularity.Daily && yearData[key][i].Count != 365)
            //            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Daily data for year {0} in climate file '{1}' does not have 365 records.  It has {2} records.", key, climateFile, yearData[key][i].Count));

            //        // convert the yearRecords from List<ClimateRecord>[] to ClimateRecord[][]
            //        allDataRef[key][i] = yearData[key][i].ToArray();
            //    }
            //}

            // **
            // John McNabb:  new parsing code
            List<int> yearKeys;
            List<List<ClimateRecord>[]> climateRecords;

            Convert_USGS_to_ClimateData2(timeStep, climateFile, climateFileFormat, out yearKeys, out climateRecords);

            Dictionary<int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly
            if (climatePhase == Climate.Phase.Future_Climate)
                allDataRef = Climate.Future_AllData;

            if (climatePhase == Climate.Phase.SpinUp_Climate)
                allDataRef = Climate.Spinup_AllData;

            if (allDataRef == null)
                allDataRef = new Dictionary<int, ClimateRecord[][]>();
            else
                allDataRef.Clear();

            for (var i = 0; i < yearKeys.Count; ++i)
            {
                var ecoRecords = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][];
                allDataRef[yearKeys[i]] = ecoRecords;

                for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j)
                {
                    // convert the parsed climateRecords for this year from List<ClimateRecord>[] to ClimateRecord[][]
                    ecoRecords[j] = climateRecords[i][j].ToArray();
                }
            }
        }
        private static void Convert_USGS_to_ClimateData2(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List<int> yearKeys, out List<List<ClimateRecord>[]> climateRecords)
        {
            var precipYearKeys = new List<int>();
            var windYearKeys = new List<int>();

            // indexing of precip and wind ClimateRecords:  [yearIndex][ecoregion][i], where yearIndex is [0..n] corresponding to the yearKeys index, i.e. index 0 is for 1950, index 1 for 1951, etc.
            var precipClimateRecords = new List<List<ClimateRecord>[]>();
            var windClimateRecords = new List<List<ClimateRecord>[]>();

            // get trigger words for parsing based on file format
            ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat);

            if (!File.Exists(climateFile))
            {
                throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile);
            }

            var reader = File.OpenText(climateFile);

            Climate.ModelCore.UI.WriteLine("   Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity);

            // maps from ecoregion column index in the input file to the ecoregion.index for the region
            int[] ecoRegionIndexMap = null;
            var ecoRegionCount = 0;

            var numberOfGroups = 2;     // the number of allowed groups. Presently:  (1) precip, tmin, tmax, Ndep, CO2;  (2) winddirection & windspeed
            var groupSectionCounts = new int[numberOfGroups];       // used to know if I'm beyond the first section in a group
            var groupTimeSteps = new List<string>[numberOfGroups];      // keeps track of timesteps within each group to ensure they match
            for (var i = 0; i < numberOfGroups; ++i)
                groupTimeSteps[i] = new List<string>();

            var sectionYearRowIndex = -1;
            var sectionYear = -1;
            var sectionYearIndex = -1;
            var sectionRowIndex = -1;

            FileSection section = 0;
            var groupIndex = -1;

            List<ClimateRecord>[] yearEcoRecords = null;        // could be either precip or wind data, depending on the section group.

            string row;

            while (!string.IsNullOrEmpty(row = reader.ReadLine()))
            {
                var fields = row.Replace(" ", "").Split(',').ToList();    // JM: don't know if stripping blanks is needed, but just in case

                // skip blank rows
                if (fields.All(x => string.IsNullOrEmpty(x)))
                    continue;

                // check for trigger word
                if (fields[0].StartsWith("#"))
                {
                    // determine which section we're in
                    var triggerWord = fields[0].TrimStart('#');   // remove the leading "#"

                    if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.Precipitation;
                        groupIndex = 0;
                    }
                    else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.MaxTemperature;
                        groupIndex = 0;
                    }
                    else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.MinTemperature;
                        groupIndex = 0;
                    }
                    else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.NDeposition;
                        groupIndex = 0;
                    }
                    else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.Winddirection;
                        groupIndex = 1;
                    }
                    else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.Windspeed;
                        groupIndex = 1;
                    }
                    else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.CO2;
                        groupIndex = 0;
                    }
                    else
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile));

                    // increment group section count
                    ++groupSectionCounts[groupIndex];

                    // if this is the first section in the file then parse the ecoregions, etc.
                    if (ecoRegionIndexMap == null)
                    {
                        // read next line to get ecoregion headers
                        var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList();
                        ecoRegionHeaders.RemoveAt(0);   // remove blank cell at the beginning of ecoregion header row

                        // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                        ecoRegionCount = ecoRegionHeaders.Count / 3;

                        if (ecoRegionCount == 0)
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile));

                        var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active);

                        if (ecoRegionCount != modelCoreActiveEcoRegionCount)
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount));

                        // determine the map from ecoregions in this file to ecoregion indices in ModelCore
                        ecoRegionIndexMap = new int[ecoRegionCount];
                        for (var i = 0; i < ecoRegionCount; ++i)
                        {
                            IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]];     // JM:  Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive.
                            if (eco != null && eco.Active)
                                ecoRegionIndexMap[i] = eco.Index;
                            else
                                throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile));
                        }
                    }
                    else
                        // skip ecoregion header line
                        reader.ReadLine();

                    // skip data headers
                    reader.ReadLine();

                    // get next line as first line of data
                    fields = reader.ReadLine().Replace(" ", "").Split(',').ToList();

                    sectionYear = -999;
                    sectionYearIndex = -1;
                    sectionRowIndex = -1;
                }

                // **
                // process line of data

                // grab the timeStep as the first field and remove it from the data
                var timeStep = fields[0];
                fields.RemoveAt(0);

                ++sectionRowIndex;
                // if this is the first section for this group, add the timeStep to the group timeStep List
                // otherwise check that the timeStep matches that of the same row in the first section for the group
                //  this also ensures that the sectionYearIndex exists in the yearEcoRecords below
                if (groupSectionCounts[groupIndex] == 1)
                {
                    groupTimeSteps[groupIndex].Add(timeStep);
                }
                else if (sectionRowIndex > groupTimeSteps[groupIndex].Count - 1 || timeStep != groupTimeSteps[groupIndex][sectionRowIndex])
                {
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}', timestamp '{1}', sectionRowIndex {2}, in climate file '{3}'.", section, timeStep, sectionRowIndex, climateFile));
                }

                // parse out the year
                var year = int.Parse(timeStep.Substring(0, 4));

                if (year != sectionYear)
                {
                    // start of a new year
                    sectionYear = year;
                    ++sectionYearIndex;

                    // if this is the first section for the group, then make a new yearEcoRecord and add it to the output data, either precip or wind
                    if (groupSectionCounts[groupIndex] == 1)
                    {
                        yearEcoRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count];
                        for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
                            yearEcoRecords[i] = new List<ClimateRecord>();

                        if (groupIndex == 0)
                        {
                            precipClimateRecords.Add(yearEcoRecords);
                            precipYearKeys.Add(year);
                        }
                        else if (groupIndex == 1)
                        {
                            windClimateRecords.Add(yearEcoRecords);
                            windYearKeys.Add(year);
                        }
                    }
                    else
                    {
                        // if not the first section, grab the ecorecords for this year, either precip or wind
                        yearEcoRecords = groupIndex == 0 ? precipClimateRecords[sectionYearIndex] : windClimateRecords[sectionYearIndex];
                    }

                    sectionYearRowIndex = -1;
                }

                // **
                // incorporate (or add) this row's data into yearEcoRecords

                ++sectionYearRowIndex;

                // if this is the first section for the group, add new ClimateRecords for each ecoregion.
                if (groupSectionCounts[groupIndex] == 1)
                    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
                        yearEcoRecords[i].Add(new ClimateRecord());

                for (var i = 0; i < ecoRegionCount; ++i)
                {
                    var ecoRecord = yearEcoRecords[ecoRegionIndexMap[i]][sectionYearRowIndex];      // if this is the first section for the group, sectionYearRowIndex will give the record just instantiated above

                    // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                    var mean = double.Parse(fields[i]);
                    var variance = double.Parse(fields[ecoRegionCount + i]);
                    var stdev = double.Parse(fields[2 * ecoRegionCount + i]);

                    if (groupIndex == 0)
                    {
                        // "precip" group
                        switch (section)
                        {
                            case FileSection.Precipitation:
                                ecoRecord.AvgPpt = mean * format.PrecipTransformation;
                                ecoRecord.StdDevPpt = stdev * format.PrecipTransformation;
                                break;

                            case FileSection.MaxTemperature:
                            case FileSection.MinTemperature:

                                mean += format.TemperatureTransformation;

                                if (section == FileSection.MaxTemperature)
                                    ecoRecord.AvgMaxTemp = mean;
                                else
                                    ecoRecord.AvgMinTemp = mean;

                                // for temperature variance wait until both min and max have been read before calculating the final value
                                if (ecoRecord.AvgVarTemp == -99.0)
                                    ecoRecord.AvgVarTemp = variance; // set AvgVarTemp to the first value we have (min or max)
                                else
                                    // have both min and max, so average the variance
                                    ecoRecord.AvgVarTemp = (ecoRecord.AvgVarTemp + variance) / 2.0;

                                ecoRecord.StdDevTemp = System.Math.Sqrt(ecoRecord.AvgVarTemp); // this will set the st dev even if the data file only has one temperature section
                                break;

                            case FileSection.NDeposition:
                                ecoRecord.AvgNDeposition = mean;
                                ecoRecord.AvgVarNDeposition = variance;
                                ecoRecord.StdDevNDeposition = stdev;
                                break;

                            case FileSection.CO2:
                                ecoRecord.AvgCO2 = mean;
                                ecoRecord.AvgVarCO2 = variance;
                                ecoRecord.StdDevCO2 = stdev;
                                break;
                        }
                    }
                    else if (groupIndex == 1)
                    {
                        // "wind" group
                        switch (section)
                        {
                            case FileSection.Winddirection:
                                mean += format.WindDirectionTransformation;
                                if (mean > 360.0) mean -= 360;
                                ecoRecord.AvgWindDirection = mean;

                                ecoRecord.AvgVarWindDirection = variance;
                                ecoRecord.StdDevWindDirection = stdev;
                                break;

                            case FileSection.Windspeed:
                                ecoRecord.AvgWindSpeed = mean * format.WindSpeedTransformation;
                                ecoRecord.AvgVarWindSpeed = variance;
                                ecoRecord.StdDevWindSpeed = stdev;
                                break;
                        }
                    }
                }
            }

            reader.Close();

            // **
            // basic data checks

            for (var i = 0; i < precipClimateRecords.Count; ++i)
            {
                var ecoRecords = precipClimateRecords[i][ecoRegionIndexMap[0]];     // check the first eco region provided in the file

                if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12)
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count));

                if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366)
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count));
            }

            // if wind data exist, check them, too
            if (groupSectionCounts[1] > 0)
            {
                for (var i = 0; i < windClimateRecords.Count; ++i)
                {
                    var ecoRecords = windClimateRecords[i][ecoRegionIndexMap[0]];     // check the first eco region provided in the file

                    if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12)
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count));

                    if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366)
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count));
                }

                // also check that the number of years matches that of the precip data
                if (precipClimateRecords.Count != windClimateRecords.Count)
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: The number of years ({0}) of Precip/Tmax/Tmin, etc. data does not equal the number of years ({1}) of Wind data in climate file '{2}'.", precipClimateRecords.Count, windClimateRecords.Count, climateFile));
            }

            // **
            // normalize daily data for leap years into 365 days
            if (sourceTemporalGranularity == TemporalGranularity.Daily)
            {
                // precip data first
                foreach (var yEcoRecords in precipClimateRecords)
                    foreach (var ecoRecords in yEcoRecords)
                        if (ecoRecords.Count == 366)
                        {
                            var feb28Record = ecoRecords[58];      // get data for Feb. 28 (day 59).
                            var feb29Record = ecoRecords[59];      // get data for Feb. 29 (day 60).
                            ecoRecords.RemoveAt(59);               // remove Feb. 29 from the ecoRecords

                            // ignore std. dev. and variance data from Feb. 29.

                            // average some Feb. 29 values with their corresponding Feb. 28 values
                            feb28Record.AvgMinTemp = 0.5 * (feb28Record.AvgMinTemp + feb29Record.AvgMinTemp);
                            feb28Record.AvgMaxTemp = 0.5 * (feb28Record.AvgMaxTemp + feb29Record.AvgMaxTemp);
                            feb28Record.AvgRH = 0.5 * (feb28Record.AvgRH + feb29Record.AvgRH);
                            feb28Record.AvgCO2 = 0.5 * (feb28Record.AvgCO2 + feb29Record.AvgCO2);
                            feb28Record.AvgPAR = 0.5 * (feb28Record.AvgPAR + feb29Record.AvgPAR);

                            // amortize (spread out) some Feb. 29 values over the entire month so that a monthly total still contains the Feb. 29 value.
                            //  do this rather than simply adding the Feb. 28 and Feb. 29 values, which would leave a spike in the final Feb. 28 data.
                            var avgPptIncrement = feb28Record.AvgPpt / 28.0;
                            var avgNDepositionIncrement = feb28Record.AvgNDeposition / 28.0;

                            var feb1 = 31;      // Feb. 1 index (day 32)
                            for (var j = feb1; j < feb1 + 28; ++j)
                            {
                                ecoRecords[j].AvgPpt += avgPptIncrement;
                                ecoRecords[j].AvgNDeposition += avgNDepositionIncrement;
                            }
                        }

                // wind data next (if it exists)
                if (groupSectionCounts[1] > 0)
                    foreach (var yEcoRecords in windClimateRecords)
                        foreach (var ecoRecords in yEcoRecords)
                            if (ecoRecords.Count == 366)
                            {
                                var feb28Record = ecoRecords[58];      // get data for Feb. 28 (day 59).
                                var feb29Record = ecoRecords[59];      // get data for Feb. 29 (day 60).
                                ecoRecords.RemoveAt(59);               // remove Feb. 29 from the ecoRecords

                                // ignore std. dev. and variance data from Feb. 29.

                                // average some Feb. 29 values with their corresponding Feb. 28 values
                                feb28Record.AvgWindDirection = 0.5 * (feb28Record.AvgWindDirection + feb29Record.AvgWindDirection);
                                feb28Record.AvgWindSpeed = 0.5 * (feb28Record.AvgWindSpeed + feb29Record.AvgWindSpeed);
                            }

            }

            // **
            // if wind data exist, combine them with precip data
            if (groupSectionCounts[1] > 0)
                for (var i = 0; i < precipClimateRecords.Count; ++i)
                    for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j)
                        for (var k = 0; k < precipClimateRecords[i][j].Count; ++k)
                        {
                            var precipRecord = precipClimateRecords[i][j][k];
                            var windRecord = windClimateRecords[i][j][k];

                            precipRecord.AvgWindDirection = windRecord.AvgWindDirection;
                            precipRecord.AvgVarWindDirection = windRecord.AvgVarWindDirection;
                            precipRecord.StdDevWindDirection = windRecord.StdDevWindDirection;

                            precipRecord.AvgWindSpeed = windRecord.AvgWindSpeed;
                            precipRecord.AvgVarWindSpeed = windRecord.AvgVarWindSpeed;
                            precipRecord.StdDevWindSpeed = windRecord.StdDevWindSpeed;
                        }

            // **
            // final data structures to return

            // yearKeys is the list of years in the file, e.g. 1950, 1951, etc. taken from the precip timesteps
            yearKeys = precipYearKeys;
            climateRecords = precipClimateRecords;
        }
        // no longer used
        private static void Convert_USGS_to_ClimateData(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List<string> timeStamps, out List<ClimateRecord>[] climateRecords)
        {
            // each item in timeStamps is the timeStamp 'key' for the data
            // each item in climateRecords is of length Climate.ModelCore.Ecoregions.Count, and is filled in with data from the input file, indexed by Ecoregion.Index.

            timeStamps = new List<string>();
            climateRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count];
            for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
                climateRecords[i] = new List<ClimateRecord>();

            // get trigger words for parsing based on file format
            ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat);

            if (!File.Exists(climateFile))
            {
                throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile);
            }

            var reader = File.OpenText(climateFile);

            Climate.ModelCore.UI.WriteLine("   Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity);

            // maps from ecoregion column index in the input file to the ecoregion.index for the region
            int[] ecoRegionIndexMap = null;
            var ecoRegionCount = 0;

            var rowIndex = -1;
            var sectionIndex = -1;
            FileSection section = 0;

            string row;

            while ((row = reader.ReadLine()) != null)
            {
                var fields = row.Replace(" ", "").Split(',').ToList();    // JM: don't know if stripping blanks is needed, but just in case

                // check for trigger word
                if (fields[0].StartsWith("#"))
                {
                    // determine which section we're in
                    var triggerWord = fields[0].TrimStart('#');   // remove the leading "#"

                    if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                        section = FileSection.Precipitation;
                    else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                        section = FileSection.MaxTemperature;
                    else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                        section = FileSection.MinTemperature;
                    else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                        section = FileSection.NDeposition;
                    else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                        section = FileSection.Winddirection;
                    else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                        section = FileSection.Windspeed;
                    else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                        section = FileSection.CO2;
                    else
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile));

                    sectionIndex++;

                    // if this is the first section then parse the ecoregions, etc.
                    if (sectionIndex == 0)
                    {
                        // read next line to get ecoregion headers
                        var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList();
                        ecoRegionHeaders.RemoveAt(0);   // remove blank cell at the beginning of ecoregion header row

                        // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                        ecoRegionCount = ecoRegionHeaders.Count / 3;

                        if (ecoRegionCount == 0)
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile));

                        var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active);

                        if (ecoRegionCount != modelCoreActiveEcoRegionCount)
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount));

                        // determine the map from ecoregions in this file to ecoregion indices in ModelCore
                        ecoRegionIndexMap = new int[ecoRegionCount];
                        for (var i = 0; i < ecoRegionCount; ++i)
                        {
                            IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]];     // JM:  Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive.
                            if (eco != null && eco.Active)
                                ecoRegionIndexMap[i] = eco.Index;
                            else
                                throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile));
                        }
                    }
                    else
                        // skip ecoregion header line
                        reader.ReadLine();

                    // skip data headers
                    reader.ReadLine();

                    // get next line as first line of data
                    fields = reader.ReadLine().Replace(" ", "").Split(',').ToList();

                    // reset row index
                    rowIndex = -1;
                }

                // **
                // process line of data

                ++rowIndex;

                // grab the key as the first field and remove it from the data
                var key = fields[0];
                fields.RemoveAt(0);

                // if this is the first section then add key to timestamps and add new climate records for this rowIndex to the ecoregion array
                if (sectionIndex == 0)
                {
                    timeStamps.Add(key);
                    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
                        climateRecords[i].Add(new ClimateRecord());
                }
                else
                {
                    // check that the timestamp key order matches
                    if (key != timeStamps[rowIndex])
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}' timestamp '{1}' in climate file '{2}'.", section, key, climateFile));
                }

                for (var i = 0; i < ecoRegionCount; ++i)
                {
                    var ecoIndex = ecoRegionIndexMap[i];

                    var ecoRecords = climateRecords[ecoIndex];

                    // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                    var mean = double.Parse(fields[i]);
                    var variance = double.Parse(fields[ecoRegionCount + i]);
                    var stdev = double.Parse(fields[2 * ecoRegionCount + i]);

                    switch (section)
                    {
                        case FileSection.Precipitation:
                            ecoRecords[rowIndex].AvgPpt = mean * format.PrecipTransformation;
                            ecoRecords[rowIndex].StdDevPpt = stdev * format.PrecipTransformation;
                            break;

                        case FileSection.MaxTemperature:
                        case FileSection.MinTemperature:

                            mean += format.TemperatureTransformation;

                            if (section == FileSection.MaxTemperature)
                                ecoRecords[rowIndex].AvgMaxTemp = mean;
                            else
                                ecoRecords[rowIndex].AvgMinTemp = mean;

                            // for temperature variance wait until both min and max have been read before calculating the final value
                            if (ecoRecords[rowIndex].AvgVarTemp == -99.0)
                                ecoRecords[rowIndex].AvgVarTemp = variance;        // set AvgVarTemp to the first value we have (min or max)
                            else
                                // have both min and max, so average the variance
                                ecoRecords[rowIndex].AvgVarTemp = (ecoRecords[rowIndex].AvgVarTemp + variance) / 2.0;

                            ecoRecords[rowIndex].StdDevTemp = System.Math.Sqrt(ecoRecords[rowIndex].AvgVarTemp);      // this will set the st dev even if the data file only has one temperature section
                            break;

                        case FileSection.Winddirection:
                            mean += format.WindDirectionTransformation;
                            if (mean > 360.0) mean -= 360;
                            ecoRecords[rowIndex].AvgWindDirection = mean;

                            ecoRecords[rowIndex].AvgVarWindDirection = variance;
                            ecoRecords[rowIndex].StdDevWindDirection = stdev;
                            break;

                        case FileSection.Windspeed:
                            ecoRecords[rowIndex].AvgWindSpeed = mean * format.WindSpeedTransformation;
                            ecoRecords[rowIndex].AvgVarWindSpeed = variance;
                            ecoRecords[rowIndex].StdDevWindSpeed = stdev;
                            break;

                        case FileSection.NDeposition:
                            ecoRecords[rowIndex].AvgNDeposition = mean;
                            ecoRecords[rowIndex].AvgVarNDeposition = variance;
                            ecoRecords[rowIndex].StdDevNDeposition = stdev;
                            break;

                        case FileSection.CO2:
                            ecoRecords[rowIndex].AvgCO2 = mean;
                            ecoRecords[rowIndex].AvgVarCO2 = variance;
                            ecoRecords[rowIndex].StdDevCO2 = stdev;
                            break;
                    }
                }
            }
        }
Пример #16
0
        private static void Convert_USGS_to_ClimateData2(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List <int> yearKeys, out List <List <ClimateRecord>[]> climateRecords)
        {
            var precipYearKeys = new List <int>();
            var windYearKeys   = new List <int>();

            // indexing of precip and wind ClimateRecords:  [yearIndex][ecoregion][i], where yearIndex is [0..n] corresponding to the yearKeys index, i.e. index 0 is for 1950, index 1 for 1951, etc.
            var precipClimateRecords = new List <List <ClimateRecord>[]>();
            var windClimateRecords   = new List <List <ClimateRecord>[]>();

            // get trigger words for parsing based on file format
            ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat);

            if (!File.Exists(climateFile))
            {
                throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile);
            }

            var reader = File.OpenText(climateFile);

            Climate.TextLog.WriteLine("   Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity);

            // maps from ecoregion column index in the input file to the ecoregion.index for the region
            int[] ecoRegionIndexMap = null;
            var   ecoRegionCount    = 0;

            var numberOfGroups     = 2;                                  // the number of allowed groups. Presently:  (1) precip, tmin, tmax, Ndep, CO2;  (2) winddirection & windspeed
            var groupSectionCounts = new int[numberOfGroups];            // used to know if I'm beyond the first section in a group
            var groupTimeSteps     = new List <string> [numberOfGroups]; // keeps track of timesteps within each group to ensure they match

            for (var i = 0; i < numberOfGroups; ++i)
            {
                groupTimeSteps[i] = new List <string>();
            }

            var sectionYearRowIndex = -1;
            var sectionYear         = -1;
            var sectionYearIndex    = -1;
            var sectionRowIndex     = -1;

            FileSection section    = 0;
            var         groupIndex = -1;

            List <ClimateRecord>[] yearEcoRecords = null;        // could be either precip or wind data, depending on the section group.

            string row;

            while (!string.IsNullOrEmpty(row = reader.ReadLine()))
            {
                var fields = row.Replace(" ", "").Split(',').ToList();    // JM: don't know if stripping blanks is needed, but just in case

                // skip blank rows
                if (fields.All(x => string.IsNullOrEmpty(x)))
                {
                    continue;
                }

                // check for trigger word
                if (fields[0].StartsWith("#"))
                {
                    // determine which section we're in
                    var triggerWord = fields[0].TrimStart('#');   // remove the leading "#"

                    if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section    = FileSection.Precipitation;
                        groupIndex = 0;
                    }
                    else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section    = FileSection.MaxTemperature;
                        groupIndex = 0;
                    }
                    else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section    = FileSection.MinTemperature;
                        groupIndex = 0;
                    }
                    else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section    = FileSection.NDeposition;
                        groupIndex = 0;
                    }
                    else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section    = FileSection.Winddirection;
                        groupIndex = 1;
                    }
                    else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section    = FileSection.Windspeed;
                        groupIndex = 1;
                    }
                    else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section    = FileSection.CO2;
                        groupIndex = 0;
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile));
                    }

                    // increment group section count
                    ++groupSectionCounts[groupIndex];

                    // if this is the first section in the file then parse the ecoregions, etc.
                    if (ecoRegionIndexMap == null)
                    {
                        // read next line to get ecoregion headers
                        var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList();
                        ecoRegionHeaders.RemoveAt(0);   // remove blank cell at the beginning of ecoregion header row

                        // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                        ecoRegionCount = ecoRegionHeaders.Count / 3;

                        if (ecoRegionCount == 0)
                        {
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile));
                        }

                        var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active);

                        if (ecoRegionCount != modelCoreActiveEcoRegionCount)
                        {
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount));
                        }

                        // determine the map from ecoregions in this file to ecoregion indices in ModelCore
                        ecoRegionIndexMap = new int[ecoRegionCount];
                        for (var i = 0; i < ecoRegionCount; ++i)
                        {
                            IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]];     // JM:  Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive.
                            if (eco != null && eco.Active)
                            {
                                ecoRegionIndexMap[i] = eco.Index;
                            }
                            else
                            {
                                throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile));
                            }
                        }
                    }
                    else
                    {
                        // skip ecoregion header line
                        reader.ReadLine();
                    }

                    // skip data headers
                    reader.ReadLine();

                    // get next line as first line of data
                    fields = reader.ReadLine().Replace(" ", "").Split(',').ToList();

                    sectionYear      = -999;
                    sectionYearIndex = -1;
                    sectionRowIndex  = -1;
                }


                // **
                // process line of data


                // grab the timeStep as the first field and remove it from the data
                var timeStep = fields[0];
                fields.RemoveAt(0);

                ++sectionRowIndex;
                // if this is the first section for this group, add the timeStep to the group timeStep List
                // otherwise check that the timeStep matches that of the same row in the first section for the group
                //  this also ensures that the sectionYearIndex exists in the yearEcoRecords below
                if (groupSectionCounts[groupIndex] == 1)
                {
                    groupTimeSteps[groupIndex].Add(timeStep);
                }
                else if (sectionRowIndex > groupTimeSteps[groupIndex].Count - 1 || timeStep != groupTimeSteps[groupIndex][sectionRowIndex])
                {
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}', timestamp '{1}', sectionRowIndex {2}, in climate file '{3}'.", section, timeStep, sectionRowIndex, climateFile));
                }

                // parse out the year
                var year = int.Parse(timeStep.Substring(0, 4));

                if (year != sectionYear)
                {
                    // start of a new year
                    sectionYear = year;
                    ++sectionYearIndex;

                    // if this is the first section for the group, then make a new yearEcoRecord and add it to the output data, either precip or wind
                    if (groupSectionCounts[groupIndex] == 1)
                    {
                        yearEcoRecords = new List <ClimateRecord> [Climate.ModelCore.Ecoregions.Count];
                        for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
                        {
                            yearEcoRecords[i] = new List <ClimateRecord>();
                        }

                        if (groupIndex == 0)
                        {
                            precipClimateRecords.Add(yearEcoRecords);
                            precipYearKeys.Add(year);
                        }
                        else if (groupIndex == 1)
                        {
                            windClimateRecords.Add(yearEcoRecords);
                            windYearKeys.Add(year);
                        }
                    }
                    else
                    {
                        // if not the first section, grab the ecorecords for this year, either precip or wind
                        yearEcoRecords = groupIndex == 0 ? precipClimateRecords[sectionYearIndex] : windClimateRecords[sectionYearIndex];
                    }

                    sectionYearRowIndex = -1;
                }


                // **
                // incorporate (or add) this row's data into yearEcoRecords

                ++sectionYearRowIndex;

                // if this is the first section for the group, add new ClimateRecords for each ecoregion.
                if (groupSectionCounts[groupIndex] == 1)
                {
                    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
                    {
                        yearEcoRecords[i].Add(new ClimateRecord());
                    }
                }

                for (var i = 0; i < ecoRegionCount; ++i)
                {
                    var ecoRecord = yearEcoRecords[ecoRegionIndexMap[i]][sectionYearRowIndex];      // if this is the first section for the group, sectionYearRowIndex will give the record just instantiated above

                    // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                    var mean     = double.Parse(fields[i]);
                    var variance = double.Parse(fields[ecoRegionCount + i]);
                    var stdev    = double.Parse(fields[2 * ecoRegionCount + i]);

                    if (groupIndex == 0)
                    {
                        // "precip" group
                        switch (section)
                        {
                        case FileSection.Precipitation:
                            ecoRecord.AvgPpt    = mean * format.PrecipTransformation;
                            ecoRecord.StdDevPpt = stdev * format.PrecipTransformation;
                            break;

                        case FileSection.MaxTemperature:
                        case FileSection.MinTemperature:

                            mean += format.TemperatureTransformation;


                            if (section == FileSection.MaxTemperature)
                            {
                                ecoRecord.AvgMaxTemp = mean;
                            }
                            else
                            {
                                ecoRecord.AvgMinTemp = mean;
                            }

                            // for temperature variance wait until both min and max have been read before calculating the final value
                            if (ecoRecord.AvgVarTemp == -99.0)
                            {
                                ecoRecord.AvgVarTemp = variance;     // set AvgVarTemp to the first value we have (min or max)
                            }
                            else
                            {
                                // have both min and max, so average the variance
                                ecoRecord.AvgVarTemp = (ecoRecord.AvgVarTemp + variance) / 2.0;
                            }

                            ecoRecord.StdDevTemp = System.Math.Sqrt(ecoRecord.AvgVarTemp);     // this will set the st dev even if the data file only has one temperature section
                            break;

                        case FileSection.NDeposition:
                            ecoRecord.AvgNDeposition    = mean;
                            ecoRecord.AvgVarNDeposition = variance;
                            ecoRecord.StdDevNDeposition = stdev;
                            break;

                        case FileSection.CO2:
                            ecoRecord.AvgCO2    = mean;
                            ecoRecord.AvgVarCO2 = variance;
                            ecoRecord.StdDevCO2 = stdev;
                            break;
                        }
                    }
                    else if (groupIndex == 1)
                    {
                        // "wind" group
                        switch (section)
                        {
                        case FileSection.Winddirection:
                            mean += format.WindDirectionTransformation;
                            if (mean > 360.0)
                            {
                                mean -= 360;
                            }
                            ecoRecord.AvgWindDirection = mean;

                            ecoRecord.AvgVarWindDirection = variance;
                            ecoRecord.StdDevWindDirection = stdev;
                            break;

                        case FileSection.Windspeed:
                            ecoRecord.AvgWindSpeed    = mean * format.WindSpeedTransformation;
                            ecoRecord.AvgVarWindSpeed = variance;
                            ecoRecord.StdDevWindSpeed = stdev;
                            break;
                        }
                    }
                }
            }

            reader.Close();

            // **
            // basic data checks

            for (var i = 0; i < precipClimateRecords.Count; ++i)
            {
                var ecoRecords = precipClimateRecords[i][ecoRegionIndexMap[0]];     // check the first eco region provided in the file

                if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12)
                {
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count));
                }

                if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366)
                {
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count));
                }
            }

            // if wind data exist, check them, too
            if (groupSectionCounts[1] > 0)
            {
                for (var i = 0; i < windClimateRecords.Count; ++i)
                {
                    var ecoRecords = windClimateRecords[i][ecoRegionIndexMap[0]];     // check the first eco region provided in the file

                    if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12)
                    {
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count));
                    }

                    if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366)
                    {
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count));
                    }
                }

                // also check that the number of years matches that of the precip data
                if (precipClimateRecords.Count != windClimateRecords.Count)
                {
                    throw new ApplicationException(string.Format("Error in ClimateDataConvertor: The number of years ({0}) of Precip/Tmax/Tmin, etc. data does not equal the number of years ({1}) of Wind data in climate file '{2}'.", precipClimateRecords.Count, windClimateRecords.Count, climateFile));
                }
            }

            // **
            // normalize daily data for leap years into 365 days
            if (sourceTemporalGranularity == TemporalGranularity.Daily)
            {
                // precip data first
                foreach (var yEcoRecords in precipClimateRecords)
                {
                    foreach (var ecoRecords in yEcoRecords)
                    {
                        if (ecoRecords.Count == 366)
                        {
                            var feb28Record = ecoRecords[58];      // get data for Feb. 28 (day 59).
                            var feb29Record = ecoRecords[59];      // get data for Feb. 29 (day 60).
                            ecoRecords.RemoveAt(59);               // remove Feb. 29 from the ecoRecords

                            // ignore std. dev. and variance data from Feb. 29.

                            // average some Feb. 29 values with their corresponding Feb. 28 values
                            feb28Record.AvgMinTemp = 0.5 * (feb28Record.AvgMinTemp + feb29Record.AvgMinTemp);
                            feb28Record.AvgMaxTemp = 0.5 * (feb28Record.AvgMaxTemp + feb29Record.AvgMaxTemp);
                            feb28Record.AvgRH      = 0.5 * (feb28Record.AvgRH + feb29Record.AvgRH);
                            feb28Record.AvgCO2     = 0.5 * (feb28Record.AvgCO2 + feb29Record.AvgCO2);
                            feb28Record.AvgPAR     = 0.5 * (feb28Record.AvgPAR + feb29Record.AvgPAR);

                            // amortize (spread out) some Feb. 29 values over the entire month so that a monthly total still contains the Feb. 29 value.
                            //  do this rather than simply adding the Feb. 28 and Feb. 29 values, which would leave a spike in the final Feb. 28 data.
                            var avgPptIncrement         = feb28Record.AvgPpt / 28.0;
                            var avgNDepositionIncrement = feb28Record.AvgNDeposition / 28.0;

                            var feb1 = 31;      // Feb. 1 index (day 32)
                            for (var j = feb1; j < feb1 + 28; ++j)
                            {
                                ecoRecords[j].AvgPpt         += avgPptIncrement;
                                ecoRecords[j].AvgNDeposition += avgNDepositionIncrement;
                            }
                        }
                    }
                }

                // wind data next (if it exists)
                if (groupSectionCounts[1] > 0)
                {
                    foreach (var yEcoRecords in windClimateRecords)
                    {
                        foreach (var ecoRecords in yEcoRecords)
                        {
                            if (ecoRecords.Count == 366)
                            {
                                var feb28Record = ecoRecords[58];      // get data for Feb. 28 (day 59).
                                var feb29Record = ecoRecords[59];      // get data for Feb. 29 (day 60).
                                ecoRecords.RemoveAt(59);               // remove Feb. 29 from the ecoRecords

                                // ignore std. dev. and variance data from Feb. 29.

                                // average some Feb. 29 values with their corresponding Feb. 28 values
                                feb28Record.AvgWindDirection = 0.5 * (feb28Record.AvgWindDirection + feb29Record.AvgWindDirection);
                                feb28Record.AvgWindSpeed     = 0.5 * (feb28Record.AvgWindSpeed + feb29Record.AvgWindSpeed);
                            }
                        }
                    }
                }
            }


            // **
            // if wind data exist, combine them with precip data
            if (groupSectionCounts[1] > 0)
            {
                for (var i = 0; i < precipClimateRecords.Count; ++i)
                {
                    for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j)
                    {
                        for (var k = 0; k < precipClimateRecords[i][j].Count; ++k)
                        {
                            var precipRecord = precipClimateRecords[i][j][k];
                            var windRecord   = windClimateRecords[i][j][k];

                            precipRecord.AvgWindDirection    = windRecord.AvgWindDirection;
                            precipRecord.AvgVarWindDirection = windRecord.AvgVarWindDirection;
                            precipRecord.StdDevWindDirection = windRecord.StdDevWindDirection;

                            precipRecord.AvgWindSpeed    = windRecord.AvgWindSpeed;
                            precipRecord.AvgVarWindSpeed = windRecord.AvgVarWindSpeed;
                            precipRecord.StdDevWindSpeed = windRecord.StdDevWindSpeed;
                        }
                    }
                }
            }

            // **
            // final data structures to return

            // yearKeys is the list of years in the file, e.g. 1950, 1951, etc. taken from the precip timesteps
            yearKeys       = precipYearKeys;
            climateRecords = precipClimateRecords;
        }
Пример #17
0
        // no longer used
        private static void Convert_USGS_to_ClimateData(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List <string> timeStamps, out List <ClimateRecord>[] climateRecords)
        {
            // each item in timeStamps is the timeStamp 'key' for the data
            // each item in climateRecords is of length Climate.ModelCore.Ecoregions.Count, and is filled in with data from the input file, indexed by Ecoregion.Index.

            timeStamps     = new List <string>();
            climateRecords = new List <ClimateRecord> [Climate.ModelCore.Ecoregions.Count];
            for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            {
                climateRecords[i] = new List <ClimateRecord>();
            }

            // get trigger words for parsing based on file format
            ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat);

            if (!File.Exists(climateFile))
            {
                throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile);
            }

            var reader = File.OpenText(climateFile);

            Climate.TextLog.WriteLine("   Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity);

            // maps from ecoregion column index in the input file to the ecoregion.index for the region
            int[] ecoRegionIndexMap = null;
            var   ecoRegionCount    = 0;

            var         rowIndex     = -1;
            var         sectionIndex = -1;
            FileSection section      = 0;

            string row;

            while ((row = reader.ReadLine()) != null)
            {
                var fields = row.Replace(" ", "").Split(',').ToList();    // JM: don't know if stripping blanks is needed, but just in case

                // check for trigger word
                if (fields[0].StartsWith("#"))
                {
                    // determine which section we're in
                    var triggerWord = fields[0].TrimStart('#');   // remove the leading "#"

                    if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.Precipitation;
                    }
                    else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.MaxTemperature;
                    }
                    else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.MinTemperature;
                    }
                    else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.NDeposition;
                    }
                    else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.Winddirection;
                    }
                    else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.Windspeed;
                    }
                    else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0)
                    {
                        section = FileSection.CO2;
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile));
                    }

                    sectionIndex++;

                    // if this is the first section then parse the ecoregions, etc.
                    if (sectionIndex == 0)
                    {
                        // read next line to get ecoregion headers
                        var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList();
                        ecoRegionHeaders.RemoveAt(0);   // remove blank cell at the beginning of ecoregion header row

                        // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                        ecoRegionCount = ecoRegionHeaders.Count / 3;

                        if (ecoRegionCount == 0)
                        {
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile));
                        }

                        var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active);

                        if (ecoRegionCount != modelCoreActiveEcoRegionCount)
                        {
                            throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount));
                        }

                        // determine the map from ecoregions in this file to ecoregion indices in ModelCore
                        ecoRegionIndexMap = new int[ecoRegionCount];
                        for (var i = 0; i < ecoRegionCount; ++i)
                        {
                            IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]];     // JM:  Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive.
                            if (eco != null && eco.Active)
                            {
                                ecoRegionIndexMap[i] = eco.Index;
                            }
                            else
                            {
                                throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile));
                            }
                        }
                    }
                    else
                    {
                        // skip ecoregion header line
                        reader.ReadLine();
                    }

                    // skip data headers
                    reader.ReadLine();

                    // get next line as first line of data
                    fields = reader.ReadLine().Replace(" ", "").Split(',').ToList();

                    // reset row index
                    rowIndex = -1;
                }


                // **
                // process line of data

                ++rowIndex;

                // grab the key as the first field and remove it from the data
                var key = fields[0];
                fields.RemoveAt(0);

                // if this is the first section then add key to timestamps and add new climate records for this rowIndex to the ecoregion array
                if (sectionIndex == 0)
                {
                    timeStamps.Add(key);
                    for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
                    {
                        climateRecords[i].Add(new ClimateRecord());
                    }
                }
                else
                {
                    // check that the timestamp key order matches
                    if (key != timeStamps[rowIndex])
                    {
                        throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}' timestamp '{1}' in climate file '{2}'.", section, key, climateFile));
                    }
                }

                for (var i = 0; i < ecoRegionCount; ++i)
                {
                    var ecoIndex = ecoRegionIndexMap[i];

                    var ecoRecords = climateRecords[ecoIndex];

                    // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev
                    var mean     = double.Parse(fields[i]);
                    var variance = double.Parse(fields[ecoRegionCount + i]);
                    var stdev    = double.Parse(fields[2 * ecoRegionCount + i]);

                    switch (section)
                    {
                    case FileSection.Precipitation:
                        ecoRecords[rowIndex].AvgPpt    = mean * format.PrecipTransformation;
                        ecoRecords[rowIndex].StdDevPpt = stdev * format.PrecipTransformation;
                        break;

                    case FileSection.MaxTemperature:
                    case FileSection.MinTemperature:

                        mean += format.TemperatureTransformation;


                        if (section == FileSection.MaxTemperature)
                        {
                            ecoRecords[rowIndex].AvgMaxTemp = mean;
                        }
                        else
                        {
                            ecoRecords[rowIndex].AvgMinTemp = mean;
                        }

                        // for temperature variance wait until both min and max have been read before calculating the final value
                        if (ecoRecords[rowIndex].AvgVarTemp == -99.0)
                        {
                            ecoRecords[rowIndex].AvgVarTemp = variance;            // set AvgVarTemp to the first value we have (min or max)
                        }
                        else
                        {
                            // have both min and max, so average the variance
                            ecoRecords[rowIndex].AvgVarTemp = (ecoRecords[rowIndex].AvgVarTemp + variance) / 2.0;
                        }

                        ecoRecords[rowIndex].StdDevTemp = System.Math.Sqrt(ecoRecords[rowIndex].AvgVarTemp);          // this will set the st dev even if the data file only has one temperature section
                        break;

                    case FileSection.Winddirection:
                        mean += format.WindDirectionTransformation;
                        if (mean > 360.0)
                        {
                            mean -= 360;
                        }
                        ecoRecords[rowIndex].AvgWindDirection = mean;

                        ecoRecords[rowIndex].AvgVarWindDirection = variance;
                        ecoRecords[rowIndex].StdDevWindDirection = stdev;
                        break;

                    case FileSection.Windspeed:
                        ecoRecords[rowIndex].AvgWindSpeed    = mean * format.WindSpeedTransformation;
                        ecoRecords[rowIndex].AvgVarWindSpeed = variance;
                        ecoRecords[rowIndex].StdDevWindSpeed = stdev;
                        break;

                    case FileSection.NDeposition:
                        ecoRecords[rowIndex].AvgNDeposition    = mean;
                        ecoRecords[rowIndex].AvgVarNDeposition = variance;
                        ecoRecords[rowIndex].StdDevNDeposition = stdev;
                        break;

                    case FileSection.CO2:
                        ecoRecords[rowIndex].AvgCO2    = mean;
                        ecoRecords[rowIndex].AvgVarCO2 = variance;
                        ecoRecords[rowIndex].StdDevCO2 = stdev;
                        break;
                    }
                }
            }
        }
        //------
        public ClimateFileFormatProvider(string format)
        {
            this.format = format;

            // default trigger words
            this.maxTempTriggerWord = new List <string>()
            {
                "maxTemp", "Tmax"
            };
            this.minTempTriggerWord = new List <string>()
            {
                "minTemp", "Tmin"
            };
            this.precipTriggerWord = new List <string>()
            {
                "ppt", "precip", "Prcp"
            };
            this.windDirectionTriggerWord = new List <string>()
            {
                "windDirect", "wd", "winddirection", "wind_from_direction"
            };
            this.windSpeedTriggerWord = new List <string>()
            {
                "windSpeed", "ws", "wind_speed"
            };
            this.nDepositionTriggerWord = new List <string>()
            {
                "Ndeposition", "Ndep"
            };
            this.co2TriggerWord = new List <string>()
            {
                "CO2", "CO2conc"
            };

            //IMPORTANT FOR ML:  Need to add these as optional trigger words.
            //this.precipTriggerWord = "Prcp";
            //    this.maxTempTriggerWord = "Tmax";
            //    this.minTempTriggerWord = "Tmin";

            // Transformations used for all formats that have temps in C and precip in mm
            this.PrecipTransformation        = 0.1; // Assumes data is in mm and so it converts the data from mm to cm.
            this.TemperatureTransformation   = 0.0; // Assumes data is in degrees Celsius so no transformation is needed.
            this.WindSpeedTransformation     = 3.6; //Assumes datas is in m/s so it converts the data to km/h
            this.WindDirectionTransformation = 180; //Assumes datas is expressed as the direction the wind comes FROM so it converts it to the direction where wind is blowing TO.

            //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily);
            switch (this.format.ToLower())
            {
            case "daily_temp-c_precip-mmday":              //was 'gfdl_a1fi' then ipcc3_daily
                this.timeStep = TemporalGranularity.Daily; //temp data are in oC and precip is in mm. CFFP (climate file format provider, L62) converts them to cm.
                break;

            case "monthly_temp-c_precip-mmmonth":            // was ipcc3_monthly
                this.timeStep = TemporalGranularity.Monthly; //temp data are in oC and precip is in mm. CFFP converts them to cm.
                break;

            case "monthly_temp-k_precip-kgm2sec":                   //ipcc5 option
                this.timeStep = TemporalGranularity.Monthly;
                this.TemperatureTransformation = ABS_ZERO;          // ipcc5 temp. data are in Kelvin.
                this.PrecipTransformation      = 262974.6;          // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / month
                break;

            case "daily_temp-k_precip-kgm2sec":                 //ipcc5 option
                this.timeStep = TemporalGranularity.Daily;
                this.TemperatureTransformation = ABS_ZERO;      // ipcc5 temp. data are in Kelvin.
                this.PrecipTransformation      = 8640.0;        // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / day
                break;

            case "monthly_temp-k_precip-mmmonth":                   //not currently being used on USGS data portal but it's an option nevertheless
                this.timeStep = TemporalGranularity.Monthly;
                this.TemperatureTransformation = ABS_ZERO;          // Temp. data in Kelvin. Precip in mm.      CFFP converts them to cm.
                break;

            case "daily_temp-k_precip-mmday":                   // U of Idaho data
                this.timeStep = TemporalGranularity.Daily;      //Temp are in Kelvin and precip is in mm.
                this.TemperatureTransformation = ABS_ZERO;
                break;

            //case "prism_monthly":  //was 'prism'
            //    this.timeStep = TemporalGranularity.Monthly;
            //    break;

            //case "mauer_daily":  //was griddedobserved
            //    this.timeStep = TemporalGranularity.Daily;
            //    this.precipTriggerWord = "Prcp";
            //    this.maxTempTriggerWord = "Tmax";
            //    this.minTempTriggerWord = "Tmin";
            //    // RH and wind speed for Mauer are the default trigger words
            //break;

            default:
                Climate.ModelCore.UI.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format);
                throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported.");
            }
        }