public static void SetSingleAnnualClimate(IEcoregion ecoregion, int year, Climate.Phase spinupOrfuture)
        {
            int actualYear = Climate.Future_MonthlyData.Keys.Min() + year;

            if (spinupOrfuture == Climate.Phase.Future_Climate)
            {
                if (Climate.Future_MonthlyData.ContainsKey(actualYear))
                {
                    AnnualWeather[ecoregion] = Climate.Future_MonthlyData[actualYear][ecoregion.Index];
                }
            }
            else
            {
                if (Climate.Spinup_MonthlyData.ContainsKey(actualYear))
                {
                    AnnualWeather[ecoregion] = Climate.Spinup_MonthlyData[actualYear][ecoregion.Index];
                }
            }
        }
        //---------------------------------------------------------------------
        // Generates new climate parameters for a SINGLE ECOREGION at an annual time step.
        public static void SetSingleAnnualClimate(IEcoregion ecoregion, int year, Climate.Phase spinupOrfuture)
        {
            int actualYear = Climate.Future_MonthlyData.Keys.Min() + year;

            if (spinupOrfuture == Climate.Phase.Future_Climate)
            {
                //PlugIn.ModelCore.UI.WriteLine("Retrieving {0} for year {1}.", spinupOrfuture.ToString(), actualYear);
                if (Climate.Future_MonthlyData.ContainsKey(actualYear))
                {
                    AnnualWeather[ecoregion] = Climate.Future_MonthlyData[actualYear][ecoregion.Index];
                }
                //else
                //    PlugIn.ModelCore.UI.WriteLine("Key is missing: Retrieving {0} for year {1}.", spinupOrfuture.ToString(), actualYear);
            }
            else
            {
                //PlugIn.ModelCore.UI.WriteLine("Retrieving {0} for year {1}.", spinupOrfuture.ToString(), actualYear);
                if (Climate.Spinup_MonthlyData.ContainsKey(actualYear))
                {
                    AnnualWeather[ecoregion] = Climate.Spinup_MonthlyData[actualYear][ecoregion.Index];
                }
            }
        }
Beispiel #3
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();
                }
            }
        }
        private ClimateRecord[] AnnualClimate_From_AnnualClimate_Daily(IEcoregion ecoregion, double latitude, Climate.Phase spinupOrfuture, int timeStep, int timeStepIndex)
        {
            var monthlyData = new ClimateRecord[12];

            int nDays;
            int dayOfYear = 0;
            AnnualClimate_Daily annDaily = new AnnualClimate_Daily(ecoregion, latitude, spinupOrfuture, timeStep, timeStepIndex); //for the same timeStep

            // if annDaily data come from averaging over years, it will always have 365 days, so I can't use the DaysInMonth() method based on the actualYear
            var daysInMonth = annDaily.DailyDataIsLeapYear ? new int[] { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } : new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

            if (spinupOrfuture == Climate.Phase.Future_Climate)
            {
                Climate.Future_DailyData[timeStep][ecoregion.Index] = annDaily;
            }
            else
            {
                Climate.Spinup_DailyData[timeStep][ecoregion.Index] = annDaily;
            }

            for (int mo = 0; mo < 12; mo++)
            {
                var monthlyMinTemp       = 0.0;
                var monthlyMaxTemp       = 0.0;
                var monthlyVarTemp       = 0.0;
                var monthlyPptVarTemp    = 0.0;
                var monthlyPrecip        = 0.0;
                var monthlyPAR           = 0.0;
                var monthlyWindDirection = 0.0;
                var monthlyWindSpeed     = 0.0;
                var monthlyNDeposition   = 0.0;
                var monthlyCO2           = 0.0;
                //var monthlyMinRH = 0.0;
                //var monthlyMaxRH = 0.0;
                var monthlyFWI = 0.0;

                nDays = daysInMonth[mo];
                for (int d = 0; d < nDays; d++)
                {
                    monthlyMinTemp       += annDaily.DailyMinTemp[dayOfYear];
                    monthlyMaxTemp       += annDaily.DailyMaxTemp[dayOfYear];
                    monthlyVarTemp       += annDaily.DailyVarTemp[dayOfYear];
                    monthlyPptVarTemp    += annDaily.DailyVarPpt[dayOfYear];
                    monthlyPrecip        += annDaily.DailyPrecip[dayOfYear];
                    monthlyPAR           += annDaily.DailyPAR[dayOfYear];
                    monthlyWindDirection += annDaily.DailyWindDirection[dayOfYear];
                    monthlyWindSpeed     += annDaily.DailyWindSpeed[dayOfYear];
                    monthlyNDeposition   += annDaily.DailyNDeposition[dayOfYear];
                    monthlyCO2           += annDaily.DailyCO2[dayOfYear];
                    //monthlyMaxRH += annDaily.DailyMaxRH[dayOfYear];
                    //monthlyMinRH += annDaily.DailyMinRH[dayOfYear];
                    monthlyFWI += annDaily.DailyFireWeatherIndex[dayOfYear];

                    dayOfYear++;
                }

                monthlyData[mo] = new ClimateRecord();

                monthlyData[mo].AvgMinTemp       = monthlyMinTemp / nDays;
                monthlyData[mo].AvgMaxTemp       = monthlyMaxTemp / nDays;
                monthlyData[mo].AvgVarTemp       = monthlyVarTemp / nDays;
                monthlyData[mo].StdDevTemp       = Math.Sqrt(monthlyVarTemp / nDays);
                monthlyData[mo].AvgVarPpt        = monthlyPptVarTemp / nDays;
                monthlyData[mo].AvgPpt           = monthlyPrecip;
                monthlyData[mo].StdDevPpt        = Math.Sqrt(monthlyPrecip / nDays);
                monthlyData[mo].AvgPAR           = monthlyPAR / nDays;
                monthlyData[mo].AvgWindDirection = monthlyWindDirection / nDays;
                monthlyData[mo].AvgWindSpeed     = monthlyWindSpeed / nDays;
                monthlyData[mo].AvgNDeposition   = monthlyNDeposition / nDays;
                monthlyData[mo].AvgCO2           = monthlyCO2 / nDays;
                //monthlyData[mo].AvgMinRH = monthlyMinRH / nDays;
                //monthlyData[mo].AvgMaxRH = monthlyMaxRH / nDays;
                monthlyData[mo].AvgFWI = monthlyFWI / nDays;
            }

            return(monthlyData);
        }
        public AnnualClimate_Monthly(IEcoregion ecoregion, double latitude, Climate.Phase spinupOrfuture, int timeStep, int timeStepIndex)
        {
            this.climatePhase = spinupOrfuture;
            this.Latitude     = latitude;

            // ------------------------------------------------------------------------------------------------------
            // Case:  Daily data used for future climate.  Note: No need to ever use daily data with spinup climate
            //if (Climate.AllData_granularity == TemporalGranularity.Daily && spinupOrfuture == Climate.Phase.Future_Climate)
            //{
            //    //Climate.TextLog.WriteLine("  Processing Daily data into Monthly data.  Ecoregion = {0}, Year = {1}, timestep = {2}.", ecoregion.Name, monthlyDataKey, timeStep);
            //    this.AnnualClimate_From_AnnualClimate_Daily(ecoregion, monthlyDataKey, latitude, spinupOrfuture, timeStep);
            //    return;
            //}

            ClimateRecord[][] timestepData = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][];
            for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            {
                timestepData[i] = new ClimateRecord[12];
            }

            // ------------------------------------------------------------------------------------------------------

            string climateOption = Climate.ConfigParameters.ClimateTimeSeries;

            if (this.climatePhase == Climate.Phase.SpinUp_Climate)
            {
                climateOption = Climate.ConfigParameters.SpinUpClimateTimeSeries;
            }

            ClimateRecord[] monthlyData;

            int actualTimeStep;

            switch (climateOption)
            {
            case "Monthly_AverageAllYears":
            {
                TimeStep       = timeStep;
                actualTimeStep = 0;
                monthlyData    = AnnualClimate_AvgMonth(ecoregion, latitude);
                CalculateMonthlyData(ecoregion, monthlyData, actualTimeStep, latitude);
                Climate.TextLog.WriteLine("  Completed calculations for {0} using AVERAGE MONTHLY data. Ecoregion = {1}, SimulatedYear = AVERAGED.", this.climatePhase, ecoregion.Name, actualTimeStep);
                break;
            }

            case "Monthly_AverageWithVariation":     //this case is not working as of 5/15/14
            {
                TimeStep       = timeStep;
                actualTimeStep = 0;
                monthlyData    = AnnualClimate_AvgMonth(ecoregion, latitude);
                Climate.TextLog.WriteLine("  Completed calculations for {0} from AVERAGE MONTHLY data. Ecoregion = {1}, SimulatedYear = AVERAGED.", this.climatePhase, ecoregion.Name, actualTimeStep);
                //timestepData = AnnualClimate_AvgMonth(ecoregion, monthlyDataKey, latitude);
                //CalculateMonthlyData_AddVariance(ecoregion, monthlyData, actualTimeStep, latitude);
                break;
            }

            case "Monthly_RandomYears":
            {
                TimeStep = timeStep;
                Dictionary <int, ClimateRecord[][]> allData;
                List <int> randomKeyList;

                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    allData       = Climate.Future_AllData;
                    randomKeyList = Climate.RandSelectedTimeKeys_future;
                }
                else
                {
                    allData       = Climate.Spinup_AllData;
                    randomKeyList = Climate.RandSelectedTimeKeys_spinup;
                }

                if (timeStepIndex >= randomKeyList.Count())
                {
                    throw new ApplicationException(string.Format("Exception: the requested Time-step {0} is out-of-range for the {1} input file.", timeStep, this.climatePhase));
                }
                else
                {
                    actualTimeStep = randomKeyList[timeStepIndex];
                }

                //Climate.TextLog.WriteLine("  AnnualClimate_Monthly: Monthly_RandomYear: timeStep = {0}, actualYear = {1}, phase = {2}.", timeStep, actualTimeStep, this.climatePhase);
                Climate.TextLog.WriteLine("  Completed calculations for {0} using RandomYear_Monthly. Ecoregion = {1}, SimulatedYear = {2}, actualYearUsed={3}.", this.climatePhase, ecoregion.Name, timeStep, actualTimeStep);

                monthlyData = allData[actualTimeStep][ecoregion.Index];
                CalculateMonthlyData(ecoregion, monthlyData, actualTimeStep, latitude);
                break;
            }

            case "Monthly_SequencedYears":
            {
                TimeStep       = timeStep;
                actualTimeStep = timeStep;
                Dictionary <int, ClimateRecord[][]> allData;

                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    allData = Climate.Future_AllData;
                }
                else
                {
                    allData = Climate.Spinup_AllData;
                }

                ClimateRecord[][] yearRecords;

                // get the climate records for the requested year, or if the year is not found, get the records for the last year
                if (!allData.TryGetValue(timeStep, out yearRecords))
                {
                    actualTimeStep = allData.Keys.Max();
                    yearRecords    = allData[actualTimeStep];
                }

                monthlyData = yearRecords[ecoregion.Index];
                CalculateMonthlyData(ecoregion, monthlyData, actualTimeStep, latitude);

                Climate.TextLog.WriteLine("  Completed calculations for {0} using Monthly_SequencedYears. Ecoregion = {1}, SimulatedYear = {2}, actualYearUsed={3}.", this.climatePhase, ecoregion.Name, timeStep, actualTimeStep);
                break;
            }

            case "Daily_RandomYears":
            {
                TimeStep = timeStep;
                Dictionary <int, ClimateRecord[][]> allData;
                List <int> randomKeyList;

                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    allData       = Climate.Future_AllData;
                    randomKeyList = Climate.RandSelectedTimeKeys_future;
                }
                else
                {
                    allData       = Climate.Spinup_AllData;
                    randomKeyList = Climate.RandSelectedTimeKeys_spinup;
                }

                if (timeStepIndex >= randomKeyList.Count())
                {
                    throw new ApplicationException(string.Format("Exception: the requested Time-step {0} is out-of-range for the {1} input file.", timeStep, this.climatePhase));
                }
                else
                {
                    actualTimeStep = randomKeyList[timeStepIndex];
                }

                Climate.TextLog.WriteLine("  Completed calculations for {0} using Daily_RandomYear. Ecoregion = {1}, SimulatedYear = {2}, actualYearUsed={3}.", this.climatePhase, ecoregion.Name, timeStep, actualTimeStep);


                monthlyData = AnnualClimate_From_AnnualClimate_Daily(ecoregion, latitude, spinupOrfuture, timeStep, timeStepIndex);
                CalculateMonthlyData(ecoregion, monthlyData, actualTimeStep, latitude);
                break;
            }

            case "Daily_AverageAllYears":
            {
                TimeStep       = timeStep;
                actualTimeStep = 0;
                monthlyData    = AnnualClimate_From_AnnualClimate_Daily(ecoregion, latitude, spinupOrfuture, timeStep, timeStepIndex);
                CalculateMonthlyData(ecoregion, monthlyData, actualTimeStep, latitude);
                //Climate.TextLog.WriteLine("  Completed calculations for {0} using Daily_AverageAllYears. Ecoregion = {1}, SimulatedYear = {2}.", this.climatePhase, ecoregion.Name, timeStep);
                break;
            }

            case "Daily_SequencedYears":
            {
                TimeStep       = timeStep;
                actualTimeStep = timeStep;
                Dictionary <int, ClimateRecord[][]> allData;

                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    allData = Climate.Future_AllData;
                }
                else
                {
                    allData = Climate.Spinup_AllData;
                }

                if (!allData.ContainsKey(timeStep))
                {
                    actualTimeStep = allData.Keys.Max();
                }

                monthlyData = AnnualClimate_From_AnnualClimate_Daily(ecoregion, latitude, spinupOrfuture, timeStep, timeStepIndex);
                CalculateMonthlyData(ecoregion, monthlyData, actualTimeStep, latitude);
                //Climate.TextLog.WriteLine("  Completed calculations for {0} using Daily_SequencedYears. Ecoregion = {1}, SimulatedYear = {2}, actualYearUsed={3}.", this.climatePhase, ecoregion.Name, timeStep, actualTimeStep);
                break;
            }

            default:
                throw new ApplicationException(String.Format("Unknown Climate Time Series: {0}", climateOption));
            }

            //this.MonthlyPET = CalculatePotentialEvapotranspiration();
            this.MonthlyPET = CalculatePotentialEvapotranspirationThornwaite();
            this.MonthlyVPD = CalculateVaporPressureDeficit();
            this.MonthlyGDD = CalculatePnETGDD();

            this.beginGrowing      = CalculateBeginGrowingSeason();
            this.endGrowing        = CalculateEndGrowingSeason();
            this.growingDegreeDays = GrowSeasonDegreeDays();

            this.JJAtemperature = 0.0;
            for (int mo = 5; mo < 8; mo++)
            {
                this.JJAtemperature += this.MonthlyTemp[mo];
            }
            this.JJAtemperature /= 3.0;
        }
Beispiel #6
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;
        }
Beispiel #7
0
        //For Sequenced and Random timeStep arg should be passed
        public AnnualClimate_Daily(IEcoregion ecoregion, double latitude, Climate.Phase spinupOrfuture, int timeStep, int timeStepIndex)
        {
            this.climatePhase = spinupOrfuture;
            ClimateRecord[][] timestepData = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][];
            for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i)
            {
                timestepData[i] = new ClimateRecord[366];
            }

            string climateOption = Climate.ConfigParameters.ClimateTimeSeries;

            if (this.climatePhase == Climate.Phase.SpinUp_Climate)
            {
                climateOption = Climate.ConfigParameters.SpinUpClimateTimeSeries;
            }

            ClimateRecord[] dailyData = null;

            int actualTimeStep;

            switch (climateOption)
            {
            case "Daily_RandomYears":
            {
                // JM: this code assumes that the constructor for AnnualClimate_Daily is ONLY called from within
                //  AnnualClimate_Monthly.AnnualClimate_From_AnnualClimate_Daily(), and, for Daily_RandomYear, the
                //  actualYear contains the randomly-selected year.

                TimeStep = timeStep;
                Dictionary <int, ClimateRecord[][]> allData;
                List <int> randomKeyList;

                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    allData       = Climate.Future_AllData;
                    randomKeyList = Climate.RandSelectedTimeKeys_future;
                }
                else
                {
                    allData       = Climate.Spinup_AllData;
                    randomKeyList = Climate.RandSelectedTimeKeys_spinup;
                }

                if (timeStepIndex >= randomKeyList.Count())
                {
                    throw new ApplicationException(string.Format("Exception: the requested Time-step {0} is out-of-range for the {1} input file.", timeStep, this.climatePhase));
                }
                else
                {
                    actualTimeStep = randomKeyList[timeStepIndex];
                }

                Climate.TextLog.WriteLine("  AnnualClimate_Daily: Daily_RandomYear: timeStep = {0}, actualYear = {1}, phase = {2}.", timeStep, actualTimeStep, this.climatePhase);

                dailyData = allData[actualTimeStep][ecoregion.Index];
                CalculateDailyData(ecoregion, dailyData, actualTimeStep, latitude);
                break;
            }

            case "Daily_AverageAllYears":
            {
                TimeStep       = timeStep;
                actualTimeStep = 0;

                dailyData = AnnualClimate_AvgDaily(ecoregion, latitude);
                CalculateDailyData(ecoregion, dailyData, actualTimeStep, latitude);
                break;
            }

            case "Daily_SequencedYears":
            {
                TimeStep       = timeStep;
                actualTimeStep = timeStep;
                Dictionary <int, ClimateRecord[][]> allData;

                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    allData = Climate.Future_AllData;
                }
                else
                {
                    allData = Climate.Spinup_AllData;
                }

                ClimateRecord[][] yearRecords;

                // get the climate records for the requested year, or if the year is not found, get the records for the last year
                if (!allData.TryGetValue(timeStep, out yearRecords))
                {
                    actualTimeStep = allData.Keys.Max();
                    yearRecords    = allData[actualTimeStep];
                }

                dailyData = yearRecords[ecoregion.Index];
                CalculateDailyData(ecoregion, dailyData, actualTimeStep, latitude);
                break;
            }

            default:
                throw new ApplicationException(String.Format("Unknown Climate Time Series: {0}", climateOption));
            }

            this.beginGrowing        = CalculateBeginGrowingDay_Daily(dailyData); //ecoClimate);
            this.endGrowing          = CalculateEndGrowingDay_Daily(dailyData);
            this.growingDegreeDays   = GrowSeasonDegreeDays();
            this.DailyDataIsLeapYear = dailyData.Length == 366;
        }
Beispiel #8
0
        public static List <IEcoregionPnETVariables> GetClimateRegionData(IEcoregionPnET ecoregion, DateTime start, DateTime end, Climate.Phase spinupOrfuture)
        {
            // Monthly simulation data untill but not including end
            List <IEcoregionPnETVariables> data = new List <IEcoregionPnETVariables>();

            // Date: the last date in the collection of running data
            DateTime date = new DateTime(start.Ticks);

            var oldYear = -1;

            while (end.Ticks > date.Ticks)
            {
                if (!all_values[ecoregion].ContainsKey(date))
                {
                    if (date.Year != oldYear)
                    {
                        //PlugIn.ModelCore.UI.WriteLine($"Retrieving Climate Library for year {date.Year}.");

                        if (spinupOrfuture == Climate.Phase.Future_Climate)
                        {
                            if (Climate.Future_MonthlyData.ContainsKey(date.Year))
                            {
                                ClimateRegionData.AnnualWeather[ecoregion] = Climate.Future_MonthlyData[date.Year][ecoregion.Index];
                            }
                        }
                        else
                        {
                            if (Climate.Spinup_MonthlyData.ContainsKey(date.Year))
                            {
                                ClimateRegionData.AnnualWeather[ecoregion] = Climate.Spinup_MonthlyData[date.Year][ecoregion.Index];
                            }
                        }

                        oldYear = date.Year;
                    }

                    var monthlyData = new MonthlyClimateRecord(ecoregion, date);

                    List <ISpeciesPNET> species = PlugIn.SpeciesPnET.AllSpecies.ToList();

                    IEcoregionPnETVariables ecoregion_variables = new ClimateRegionPnETVariables(monthlyData, date, wythers, dtemp, species, ecoregion.Latitude);

                    all_values[ecoregion].Add(date, ecoregion_variables);
                }
                data.Add(all_values[ecoregion][date]);

                date = date.AddMonths(1);
            }
            return(data);
        }
Beispiel #9
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;
        }
Beispiel #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();
                }
            }
        }
        //For Sequenced and Random timeStep arg should be passed
        public AnnualClimate_Daily(IEcoregion ecoregion, int actualYear, double latitude, Climate.Phase spinupOrfuture = Climate.Phase.Future_Climate, int timeStep = Int32.MinValue)
        {
            this.climatePhase = spinupOrfuture;
            IClimateRecord[,] timestepData = new IClimateRecord[Climate.ModelCore.Ecoregions.Count, 366];

            string climateOption = Climate.ConfigParameters.ClimateTimeSeries;

            if (this.climatePhase == Climate.Phase.SpinUp_Climate)
            {
                climateOption = Climate.ConfigParameters.SpinUpClimateTimeSeries;
            }

            //Climate.ModelCore.UI.WriteLine("  Calculating daily data ...  Ecoregion = {0}, Year = {1}, timestep = {2}.", ecoregion.Name, actualYear, timeStep);
            switch (climateOption)
            {
            case "Daily_RandomYear":
            {
                TimeStep = timeStep;
                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    timestepData = Climate.Future_AllData[Climate.RandSelectedTimeSteps_future[TimeStep]];
                }
                else if (this.climatePhase == Climate.Phase.SpinUp_Climate)
                {
                    timestepData = Climate.Spinup_AllData[Climate.RandSelectedTimeSteps_future[TimeStep]];
                }
                break;
            }

            case "Daily_AverageAllYears":
            {
                if (this.climatePhase == Climate.Phase.Future_Climate)
                {
                    timestepData = AnnualClimate_AvgDaily(ecoregion, actualYear, latitude);
                }
                else if (this.climatePhase == Climate.Phase.SpinUp_Climate)
                {
                    timestepData = AnnualClimate_AvgDaily(ecoregion, actualYear, latitude);
                }
                break;
            }

            case "Daily_SequencedYears":
            {
                TimeStep = timeStep;
                try
                {
                    timestepData = Climate.Future_AllData[TimeStep];
                }
                catch (System.Collections.Generic.KeyNotFoundException ex)
                {
                    throw new ClimateDataOutOfRangeException("Exception: The requested Time-step or ecoregion is out of range of the provided " + this.climatePhase.ToString() + " input file. This may be because the number of input climate data is not devisable to the number of specified time-steps or there is not enough historic climate data to run the model for the specified duration.", ex);
                }
                break;
            }

            default:
                throw new ApplicationException(String.Format("Unknown Climate Time Series: {}", climateOption));
            }


            IClimateRecord[] ecoClimate = new IClimateRecord[MaxDayInYear];

            this.Year         = actualYear;
            this.AnnualPrecip = 0.0;

            for (int day = 0; day < MaxDayInYear; day++)
            {
                ecoClimate[day] = timestepData[ecoregion.Index, day];

                if (ecoClimate[day] != null)
                {
                    double DailyAvgTemp = (ecoClimate[day].AvgMinTemp + ecoClimate[day].AvgMaxTemp) / 2.0;

                    //Climate.ModelCore.UI.WriteLine("Timestep Data.  PPt={0}, T={1}.", ecoClimate[day].AvgPpt, DailyAvgTemp);

                    this.DailyTemp[day]    = DailyAvgTemp;
                    this.DailyMinTemp[day] = ecoClimate[day].AvgMinTemp;
                    this.DailyMaxTemp[day] = ecoClimate[day].AvgMaxTemp;
                    this.DailyPrecip[day]  = Math.Max(0.0, ecoClimate[day].AvgPpt);
                    this.DailyPAR[day]     = ecoClimate[day].PAR;

                    this.AnnualPrecip += this.DailyPrecip[day];

                    if (this.DailyPrecip[day] < 0)
                    {
                        this.DailyPrecip[day] = 0;
                    }

                    double hr = CalculateDayNightLength(day, latitude);
                    this.DailyDayLength[day]   = (60.0 * 60.0 * hr);                // seconds of daylight/day
                    this.DailyNightLength[day] = (60.0 * 60.0 * (24 - hr));         // seconds of nighttime/day

                    //this.DOY[day] = DayOfYear(day);
                }
                else
                {
                    Climate.ModelCore.UI.WriteLine("Daily data = null.");
                }
            }

            this.beginGrowing      = CalculateBeginGrowingDay_Daily(); //ecoClimate);
            this.endGrowing        = CalculateEndGrowingDay_Daily(ecoClimate);
            this.growingDegreeDays = GrowSeasonDegreeDays(actualYear);

            //if (Climate.TimestepData.GetLength(1) > 365)
            if (timestepData.GetLength(1) > 365)
            {
                this.isLeapYear = true;
            }
        }
        //private void AnnualClimate_Base(IEcoregion ecoregion, int year, double latitude)
        //{
        //    //Climate.ModelCore.Log.WriteLine("  Generate new annual climate:  Yr={0}, Eco={1}.", year, ecoregion.Name);
        //    Ecoregion = ecoregion;
        //    IClimateRecord[] ecoClimate = new IClimateRecord[12];

        //    this.Year = year;
        //    this.AnnualPrecip = 0.0;
        //    //this.AnnualN = 0.0;
        //    this.Latitude = latitude;

        //    for (int mo = 0; mo < 12; mo++)
        //    {
        //        ecoClimate[mo] = Climate.TimestepData[ecoregion.Index, mo];

        //        double MonthlyAvgTemp = (ecoClimate[mo].AvgMinTemp + ecoClimate[mo].AvgMaxTemp) / 2.0;

        //        double standardDeviation = ecoClimate[mo].StdDevTemp * (Climate.ModelCore.GenerateUniform() * 2.0 - 1.0);

        //        this.MonthlyTemp[mo] = MonthlyAvgTemp + standardDeviation;
        //        this.MonthlyMinTemp[mo] = ecoClimate[mo].AvgMinTemp + standardDeviation;
        //        this.MonthlyMaxTemp[mo] = ecoClimate[mo].AvgMaxTemp + standardDeviation;
        //        this.MonthlyPrecip[mo] = Math.Max(0.0, ecoClimate[mo].AvgPpt + (ecoClimate[mo].StdDevPpt * (Climate.ModelCore.GenerateUniform() * 2.0 - 1.0)));
        //        this.MonthlyPAR[mo] = ecoClimate[mo].PAR;

        //        this.AnnualPrecip += this.MonthlyPrecip[mo];

        //        if (this.MonthlyPrecip[mo] < 0)
        //            this.MonthlyPrecip[mo] = 0;

        //        double hr = CalculateDayNightLength(mo, latitude);
        //        this.MonthlyDayLength[mo] = (60.0 * 60.0 * hr);                  // seconds of daylight/day
        //        this.MonthlyNightLength[mo] = (60.0 * 60.0 * (24 - hr));         // seconds of nighttime/day

        //        //this.DOY[mo] = DayOfYear(mo);
        //    }


        //    this.MonthlyPET = CalculatePotentialEvapotranspiration(); //ecoClimate);
        //    this.MonthlyVPD = CalculateVaporPressureDeficit(); //ecoClimate);
        //    this.MonthlyGDD = CalculatePnETGDD(); //this.MonthlyTemp, year);

        //    this.beginGrowing = CalculateBeginGrowingSeason(); //ecoClimate);
        //    this.endGrowing = CalculateEndGrowingSeason(); //ecoClimate);
        //    this.growingDegreeDays = GrowSeasonDegreeDays(); //year);

        //    for (int mo = 5; mo < 8; mo++)
        //        this.JJAtemperature += this.MonthlyTemp[mo];
        //    this.JJAtemperature /= 3.0;


        //}
        private void AnnualClimate_From_AnnualClimate_Daily(IEcoregion ecoregion, int actualYear, double latitude, Climate.Phase spinupOrfuture, int timeStep)
        {
            //Climate.ModelCore.UI.WriteLine("  Retrieve Daily data... Ecoregion = {0}, Year = {1}.", ecoregion.Name, actualYear);
            //timestepData = Climate.Future_AllData[Climate.RandSelectedTimeSteps_future[TimeStep]];

            int nDays;
            int dayOfYear = 0;
            AnnualClimate_Daily annDaily = new AnnualClimate_Daily(ecoregion, actualYear, latitude, spinupOrfuture, timeStep); //for the same timeStep

            if (spinupOrfuture == Climate.Phase.Future_Climate)
            {
                Climate.Future_DailyData[actualYear][ecoregion.Index] = annDaily;
            }
            else
            {
                Climate.Spinup_DailyData[actualYear][ecoregion.Index] = annDaily;
            }

            //IClimateRecord[] ecoClimate = new IClimateRecord[12];

            //----------------------------------------
            // Calculate precipitation and temperature
            for (int mo = 0; mo < 12; mo++)
            {
                //ecoClimate[mo] = Climate.TimestepData[ecoregion.Index, mo];

                nDays = DaysInMonth(mo, actualYear);
                for (int d = 1; d <= nDays; d++)
                {
                    this.MonthlyTemp[mo]       += annDaily.DailyTemp[dayOfYear];
                    this.MonthlyMinTemp[mo]    += annDaily.DailyMinTemp[dayOfYear];
                    this.MonthlyMaxTemp[mo]    += annDaily.DailyMaxTemp[dayOfYear];
                    this.MonthlyPrecip[mo]     += annDaily.DailyPrecip[dayOfYear];
                    this.MonthlyPAR[mo]        += annDaily.DailyPAR[dayOfYear];
                    this.MonthlyVarTemp[mo]    += annDaily.DailyVarTemp[dayOfYear];
                    this.MonthlyPptVarTemp[mo] += annDaily.DailyPptVarTemp[dayOfYear];

                    dayOfYear++;
                    //dayOfYear += nDays;
                }


                this.MonthlyTemp[mo]    /= nDays;
                this.MonthlyMinTemp[mo] /= nDays;
                this.MonthlyMaxTemp[mo] /= nDays;
                //MonthlyPrecip[mo] /= nDays;
                this.MonthlyPAR[mo]        /= nDays;
                this.MonthlyVarTemp[mo]    /= nDays;
                this.MonthlyPptVarTemp[mo] /= nDays;
            }

            //------------------------------------------------------------
            // Calculate monthly data derived from precipitation and temperature

            this.Year         = actualYear;
            this.AnnualPrecip = 0.0;
            for (int mo = 0; mo < 12; mo++)
            {
                //ecoClimate[mo] = Climate.TimestepData[ecoregion.Index, mo];

                this.AnnualPrecip += this.MonthlyPrecip[mo];

                if (this.MonthlyPrecip[mo] < 0)
                {
                    throw new System.ApplicationException(String.Format("Error: Precipitation < 0.  Year={0}, Month={1}, Ppt={2}", this.Year, mo, this.MonthlyPrecip[mo]));
                }

                double hr = CalculateDayNightLength(mo, latitude);
                this.MonthlyDayLength[mo]   = (60.0 * 60.0 * hr);                // seconds of daylight/day
                this.MonthlyNightLength[mo] = (60.0 * 60.0 * (24 - hr));         // seconds of nighttime/day
            }


            this.MonthlyPET = CalculatePotentialEvapotranspiration();
            this.MonthlyVPD = CalculateVaporPressureDeficit();
            this.MonthlyGDD = CalculatePnETGDD();


            this.beginGrowing      = annDaily.BeginGrowing;
            this.endGrowing        = annDaily.EndGrowing;
            this.growingDegreeDays = annDaily.GrowingDegreeDays;


            for (int mo = 5; mo < 8; mo++)
            {
                this.JJAtemperature += this.MonthlyTemp[mo];
            }
            this.JJAtemperature /= 3.0;

            //Climate.ModelCore.UI.WriteLine("  Completed calculations from daily data... Ecoregion = {0}, Year = {1}, BeginGrow = {2}.", ecoregion.Name, actualYear, this.beginGrowing);
        }
        public AnnualClimate_Monthly(IEcoregion ecoregion, int actualYear, double latitude, Climate.Phase spinupOrfuture = Climate.Phase.Future_Climate, int timeStep = Int32.MinValue) //For Hist and Random timeStep arg should be passed
        {
            this.climatePhase = spinupOrfuture;
            this.Latitude     = latitude;

            // ------------------------------------------------------------------------------------------------------
            // Case:  Daily data used for future climate.  Note: No need to ever use daily data with spinup climate
            //if (Climate.AllData_granularity == TemporalGranularity.Daily && spinupOrfuture == Climate.Phase.Future_Climate)
            //{
            //    //Climate.ModelCore.UI.WriteLine("  Processing Daily data into Monthly data.  Ecoregion = {0}, Year = {1}, timestep = {2}.", ecoregion.Name, actualYear, timeStep);
            //    this.AnnualClimate_From_AnnualClimate_Daily(ecoregion, actualYear, latitude, spinupOrfuture, timeStep);
            //    return;
            //}

            IClimateRecord[,] timestepData = new IClimateRecord[Climate.ModelCore.Ecoregions.Count, 12];

            // ------------------------------------------------------------------------------------------------------
            // PossibleValues = "MonthlyRandom, MonthlyAverage, DailyHistRandom, DailyHistAverage, MonthlyStandard, DailyGCM";

            string climateOption = Climate.ConfigParameters.ClimateTimeSeries;

            if (this.climatePhase == Climate.Phase.SpinUp_Climate)
            {
                climateOption = Climate.ConfigParameters.SpinUpClimateTimeSeries;
            }

            switch (climateOption)
            {
            case "Monthly_AverageAllYears":
            {
                //if (this.climatePhase == Climate.Phase.Future_Climate)
                //else if (this.climatePhase == Climate.Phase.SpinUp_Climate)
                //    timestepData = AnnualClimate_Avg(ecoregion, actualYear, latitude);
                timestepData = AnnualClimate_AvgMonth(ecoregion, actualYear, latitude);
                break;
            }

            case "Monthly_AverageWithVariation":
            {
                timestepData = AnnualClimate_AvgMonth(ecoregion, actualYear, latitude);
                CalculateMonthlyData_AddVariance(ecoregion, timestepData, actualYear, latitude);
                break;
            }

            case "Monthly_RandomYear":
            {
                TimeStep = timeStep;
                try {
                    if (this.climatePhase == Climate.Phase.Future_Climate)
                    {
                        timestepData = Climate.Future_AllData[Climate.RandSelectedTimeSteps_future[TimeStep]];
                    }
                    else if (this.climatePhase == Climate.Phase.SpinUp_Climate)
                    {
                        timestepData = Climate.Spinup_AllData[Climate.RandSelectedTimeSteps_spinup[TimeStep]];
                    }

                    CalculateMonthlyData_NoVariance(ecoregion, timestepData, actualYear, latitude);
                }
                catch (System.Collections.Generic.KeyNotFoundException ex)
                {
                    throw new ClimateDataOutOfRangeException("Exception: The requested Time-step is out of range for " + this.climatePhase.ToString() + " input file.", ex);
                }
                break;
            }

            case "Monthly_SequencedYears":
            {
                TimeStep = timeStep;
                try
                {
                    if (this.climatePhase == Climate.Phase.Future_Climate)
                    {
                        timestepData = Climate.Future_AllData[TimeStep];
                    }
                    else if (this.climatePhase == Climate.Phase.SpinUp_Climate)
                    {
                        timestepData = Climate.Spinup_AllData[TimeStep];
                    }

                    CalculateMonthlyData_NoVariance(ecoregion, timestepData, actualYear, latitude);
                }
                catch (System.Collections.Generic.KeyNotFoundException ex)
                {
                    throw new ClimateDataOutOfRangeException("Exception: The requested Time-step is out of range for " + this.climatePhase.ToString() + " input file.", ex);
                }
                break;
            }

            case "Daily_RandomYear":
            {
                this.AnnualClimate_From_AnnualClimate_Daily(ecoregion, actualYear, latitude, spinupOrfuture, timeStep);
                break;
            }

            case "Daily_AverageAllYears":
            {
                this.AnnualClimate_From_AnnualClimate_Daily(ecoregion, actualYear, latitude, spinupOrfuture, timeStep);
                return;
            }
            //case "MonthlyStandard":
            //    {
            //        TimeStep = timeStep;
            //        try
            //        {
            //            if (this.climatePhase == Climate.Phase.Future_Climate)
            //                timestepData = Climate.Future_AllData[TimeStep];
            //            else if (this.climatePhase == Climate.Phase.SpinUp_Climate)
            //                timestepData = Climate.Spinup_AllData[TimeStep];

            //            CalculateMonthlyData_AddVariance(ecoregion, timestepData, actualYear, latitude);
            //        }
            //        catch (System.Collections.Generic.KeyNotFoundException ex)
            //        {
            //            throw new ClimateDataOutOfRangeException("Exception: The requested Time-step is out of range for " + this.climatePhase.ToString() + " input file.", ex);
            //        }
            //        break;
            //    }
            case "Daily_SequencedYears":
            {
                this.AnnualClimate_From_AnnualClimate_Daily(ecoregion, actualYear, latitude, spinupOrfuture, timeStep);
                return;
            }

            default:
                throw new ApplicationException(String.Format("Unknown Climate Time Series: {}", climateOption));
            }

            this.MonthlyPET = CalculatePotentialEvapotranspiration();
            this.MonthlyVPD = CalculateVaporPressureDeficit();
            this.MonthlyGDD = CalculatePnETGDD();

            this.beginGrowing      = CalculateBeginGrowingSeason();
            this.endGrowing        = CalculateEndGrowingSeason();
            this.growingDegreeDays = GrowSeasonDegreeDays();

            for (int mo = 5; mo < 8; mo++)
            {
                this.JJAtemperature += this.MonthlyTemp[mo];
            }
            this.JJAtemperature /= 3.0;
        }