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);
        }
Ejemplo n.º 2
0
        public static void CalculateFireWeather(int year, ClimateRecord[][] TimestepData)
        {
            //double rHSlopeAdjust = Climate.ConfigParameters.RHSlopeAdjust;
            double FineFuelMoistureCode_yesterday = Climate.ConfigParameters.FineFuelMoistureCode_Yesterday;
            double DuffMoistureCode_yesterday     = Climate.ConfigParameters.DuffMoistureCode_Yesterday;
            double DroughtCode_yesterday          = Climate.ConfigParameters.DroughtCode_Yesterday;
            int    springStart = Climate.ConfigParameters.SpringStart;
            int    winterStart = Climate.ConfigParameters.WinterStart;

            int maxtimestep = 12;

            if (Climate.AllData_granularity == TemporalGranularity.Daily)
            {
                maxtimestep = 365;
            }
            WindSpeedVelocity = -9999.0;
            WindAzimuth       = -9999.0;
            double temperature      = -9999.0;
            double precipitation    = -9999.0;
            double relativeHumidity = -9999.0;

            foreach (IEcoregion ecoregion in Climate.ModelCore.Ecoregions)
            {
                if (ecoregion.Active)
                {
                    // These are seed values for the beginning of the fire season
                    //double FineFuelMoistureCode_yesterday = 85;
                    //double FineFuelMoistureCode_yesterday = 88;  //AK value
                    //double DuffMoistureCode_yesterday = 6;
                    //double DuffMoistureCode_yesterday = 59;  //AK value
                    //double DroughtCode_yesterday = 15;
                    //double DroughtCode_yesterday = 136;  //AK value
                    //for (int month = 0; month < 12; month++)
                    for (int timestep = 0; timestep < maxtimestep; timestep++)
                    {
                        if (timestep >= springStart && timestep < winterStart)
                        {
                            //temperature = (TimestepData[ecoregion.Index][timestep].AvgMaxTemp + TimestepData[ecoregion.Index][timestep].AvgMinTemp) / 2;
                            temperature       = TimestepData[ecoregion.Index][timestep].Temp == -99.0 ? (TimestepData[ecoregion.Index][timestep].AvgMinTemp + TimestepData[ecoregion.Index][timestep].AvgMaxTemp) / 2.0 : TimestepData[ecoregion.Index][timestep].Temp;
                            precipitation     = TimestepData[ecoregion.Index][timestep].AvgPpt;
                            WindSpeedVelocity = TimestepData[ecoregion.Index][timestep].AvgWindSpeed;
                            WindAzimuth       = TimestepData[ecoregion.Index][timestep].AvgWindDirection;
                            //relativeHumidity = (TimestepData[ecoregion.Index][timestep].AvgMaxRH + TimestepData[ecoregion.Index][timestep].AvgMinRH) / 2;
                            //relativeHumidity = TimestepData[ecoregion.Index][timestep].AvgRH;
                            if (TimestepData[ecoregion.Index][timestep].AvgMinRH != -99.0)
                            {
                                relativeHumidity = (TimestepData[ecoregion.Index][timestep].AvgMinRH + TimestepData[ecoregion.Index][timestep].AvgMaxRH) / 2.0;   // if minRH exists, then estimate as the average of min and max
                            }
                            else if (TimestepData[ecoregion.Index][timestep].AvgSpecificHumidity != -99.0)
                            {
                                relativeHumidity = AnnualClimate_Daily.ConvertSHtoRH(TimestepData[ecoregion.Index][timestep].AvgSpecificHumidity, temperature);                                   // if specific humidity is present, then use it to calculate RH.
                            }
                            else
                            {
                                relativeHumidity = -99.0;
                            }


                            if (relativeHumidity > 100)
                            {
                                relativeHumidity = 100.0;
                            }

                            if (timestep != springStart) //for each day, this loop assigns yesterday's fire weather variables

                            {
                                FineFuelMoistureCode_yesterday = FineFuelMoistureCode;
                                DuffMoistureCode_yesterday     = DuffMoistureCode;
                                DroughtCode_yesterday          = DroughtCode;
                            }


                            double mo    = Calculate_mo(FineFuelMoistureCode_yesterday);
                            double rf    = Calculate_rf(precipitation);
                            double mr    = Calculate_mr(mo, rf);
                            double Ed    = Calculate_Ed(relativeHumidity, temperature);
                            double Ew    = Calculate_Ew(relativeHumidity, temperature);
                            double ko    = Calculate_ko(relativeHumidity, WindSpeedVelocity);
                            double kd    = Calculate_kd(ko, temperature);
                            double kl    = Calculate_kl(relativeHumidity, WindSpeedVelocity);
                            double kw    = Calculate_kw(kl, temperature);
                            double m     = Calculate_m(mo, Ed, kd, Ew, kw);
                            double re    = Calculate_re(precipitation);
                            double Mo    = Calculate_Mo(DuffMoistureCode_yesterday);
                            double b     = Calculate_b(DuffMoistureCode_yesterday);
                            double Mr    = Calculate_Mr(re, b, Mo);
                            double Pr    = Calculate_Pr(Mr);
                            int    month = Calculate_month(timestep);
                            double Le1   = Calculate_Le1(month);
                            double Le2   = Calculate_Le2(month);
                            double Le    = Calculate_Le(Le1, Le2);
                            double K     = Calculate_K(temperature, relativeHumidity, Le);
                            Calculate_DuffMoistureCode(precipitation, Pr, K, DuffMoistureCode_yesterday);
                            double rd = Calculate_rd(precipitation);
                            double Qo = Calculate_Qo(DroughtCode_yesterday);
                            double Qr = Calculate_Qr(Qo, rd);
                            double Dr = Calculate_Dr(Qr);
                            double Lf = Calculate_Lf(month);
                            double V  = Calculate_V(temperature, Lf);
                            Calculate_DroughtCode(precipitation, Dr, V, DroughtCode_yesterday);
                            double WindFunction_ISI             = Calculate_WindFunction_ISI(WindSpeedVelocity);
                            double FineFuelMoistureFunction_ISI = Calculate_FineFuelMoistureFunction_ISI(m);
                            double InitialSpreadIndex           = Calculate_InitialSpreadIndex(WindFunction_ISI, FineFuelMoistureFunction_ISI);
                            Calculate_BuildUpIndex(DuffMoistureCode, DroughtCode);
                            double fD = Calculate_fD(BuildUpIndex);
                            double B  = Calculate_B(InitialSpreadIndex, fD);
                            Calculate_FireWeatherIndex(B);
                            double I_scale = Calculate_I_scale(FireWeatherIndex);
                            double DSR     = Calculate_DSR(FireWeatherIndex);
                            Calculate_FineFuelMoistureCode(m);

                            TimestepData[ecoregion.Index][timestep].AvgFWI = FireWeatherIndex;
                            //Climate.Future_AllData[ecoregion.Index][timestep]..AvgFWI = FireWeatherIndex;
                        }
                        else
                        {
                            TimestepData[ecoregion.Index][timestep].AvgFWI = 0;
                        }
                    }
                }
            }
        }
        //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);
            
        }
        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 monthlyRH = 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];
                    monthlyRH += annDaily.DailyRH[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].AvgRH = monthlyRH / nDays;
            }

            return monthlyData;
        }
        //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);
        }