public void InitializeWeather(IMonthlyWeather[] annualClimate, int seed)//, int lateChillingDays)
        {
            NormalRandomVar randVar  = new NormalRandomVar(0, 1);
            Random          autoRand = new Random(seed * (int)DateTime.Now.Ticks);

            for (int i = 0; i < 12; i++)
            {
                double MonthlyAvgTemp = (annualClimate[i].AvgMinTemp + annualClimate[i].AvgMaxTemp) / 2.0;
                //Console.WriteLine("TempRandNum = {0}.", randVar.GenerateNumber(autoRand));
                this.monthlyTemp[i]    = MonthlyAvgTemp + (annualClimate[i].StdDevTemp * (randVar.GenerateNumber(autoRand)));
                this.monthlyMinTemp[i] = annualClimate[i].AvgMinTemp + (annualClimate[i].StdDevTemp * (randVar.GenerateNumber(autoRand)));
                //Console.WriteLine("Month = {0}.  Mean T = {1:0.0}.", i, this.monthlyTemp[i]);
            }
            for (int i = 0; i < 12; i++)
            {
                this.monthlyPrecip[i] = annualClimate[i].AvgPpt + (annualClimate[i].StdDevPpt * (randVar.GenerateNumber(autoRand)));
                if (this.monthlyPrecip[i] < 0)
                {
                    this.monthlyPrecip[i] = 0;
                }
                //Console.WriteLine("Month = {0}.  Mean Ppt = {1:0.0}.", i, this.monthlyPrecip[i]);
            }
            this.beginGrowing      = CalculateBeginGrowingSeason(annualClimate, autoRand);
            this.endGrowing        = CalculateEndGrowingSeason(annualClimate, autoRand);
            this.growingDegreeDays = GrowSeasonDegreeDays(1968);
            this.chillingDays      = CalculateChillingDays(annualClimate, autoRand);
        }
        private static int CalculateBeginGrowingSeason(IMonthlyWeather[] annualClimate, Random autoRand)
        //Calculate Begin Growing Degree Day (Last Frost; Minimum = 0 degrees C):
        {
            NormalRandomVar randVar            = new NormalRandomVar(0, 1);
            double          lastMonthMinTemp   = annualClimate[0].AvgMinTemp;
            int             dayCnt             = 15; //the middle of February
            int             beginGrowingSeason = -1;

            for (int i = 1; i < 7; i++)  //Begin looking in February (1).  Should be safe for at least 100 years.
            {
                int    totalDays      = (DaysInMonth(i, 3) + DaysInMonth(i - 1, 3)) / 2;
                double MonthlyMinTemp = annualClimate[i].AvgMinTemp;// + (monthlyTempSD[i] * randVar.GenerateNumber());

                //Now interpolate between days:
                double degreeIncrement = System.Math.Abs(MonthlyMinTemp - lastMonthMinTemp) / (double)totalDays;
                double Tnight          = MonthlyMinTemp; //start from warmer month
                double TnightRandom    = Tnight + (annualClimate[i].StdDevTemp * (randVar.GenerateNumber(autoRand) * 2 - 1));

                for (int day = 1; day <= totalDays; day++)
                {
                    if (TnightRandom <= 0)
                    {
                        beginGrowingSeason = (dayCnt + day);
                    }
                    Tnight      += degreeIncrement; //work backwards to find last frost day.
                    TnightRandom = Tnight + (annualClimate[i].StdDevTemp * (randVar.GenerateNumber(autoRand) * 2 - 1));
                }

                lastMonthMinTemp = MonthlyMinTemp;
                dayCnt          += totalDays; //new monthly mid-point
            }
            return(beginGrowingSeason);
        }
        private static int CalculateEndGrowingSeason(IMonthlyWeather[] annualClimate, Random autoRand)
        //Calculate End Growing Degree Day (First frost; Minimum = 0 degrees C):
        {
            NormalRandomVar randVar = new NormalRandomVar(0, 1);

            //Defaults for the middle of July:
            double lastMonthTemp = annualClimate[6].AvgMinTemp;
            int    dayCnt        = 198;

            //int endGrowingSeason = 198;

            for (int i = 7; i < 12; i++)  //Begin looking in August.  Should be safe for at least 100 years.
            {
                int    totalDays      = (DaysInMonth(i, 3) + DaysInMonth(i - 1, 3)) / 2;
                double MonthlyMinTemp = annualClimate[i].AvgMinTemp;

                //Now interpolate between days:
                double degreeIncrement = System.Math.Abs(lastMonthTemp - MonthlyMinTemp) / (double)totalDays;
                double Tnight          = lastMonthTemp; //start from warmer month

                //double randomT = (2 * annualClimate[i].StdDevTemp * randVar.GenerateNumber(autoRand));
                //Console.WriteLine("Night Temp random offset = {0}.", randomT);
                double TnightRandom = Tnight + (annualClimate[i].StdDevTemp * (randVar.GenerateNumber(autoRand) * 2 - 1));

                for (int day = 1; day <= totalDays; day++)
                {
                    if (TnightRandom <= 0)
                    {
                        return(dayCnt + day);
                    }
                    Tnight      -= degreeIncrement; //work forwards to find first frost day.
                    TnightRandom = Tnight + (annualClimate[i].StdDevTemp * (randVar.GenerateNumber(autoRand) * 2 - 1));
                    //Console.WriteLine("Tnight = {0}.", TnightRandom);
                }

                lastMonthTemp = MonthlyMinTemp;
                dayCnt       += totalDays; //new monthly mid-point
            }
            return(-1);
        }
        public int CalculateChillingDays(IMonthlyWeather[] annualClimate, Random autoRand)
        // Chilling days is the number of days since November 1 with mean temperatures <= 5 C.
        // Murray et al. 1996. J Applied Ecology 26: 693-700.

        {
            NormalRandomVar randVar = new NormalRandomVar(0, 1);

            double chillDayBase = 5.00;

            // Because we only have a single year's weather, it is necessary to use current year
            // November and December as a substitute for the same months in the previous year.  This should generally
            // be a safe assumption as these months should be almost entirely chilling days.
            double lastMonthAvgTemp = (annualClimate[10].AvgMinTemp + annualClimate[10].AvgMaxTemp) / 2.0;

            int chillDays = 0;
            //int currentYear = 0;
            int dayCnt = 0;

            int[] months = new int[8] {
                10, 11, 0, 1, 2, 3, 4, 5
            };

            //Only look at 8 months assuming thermal time to budburst must occur before July 1.
            for (int i = 0; i < 8; i++)

            {
                int month = months[i];

                // First look backwards at each month mid-point.  November looks
                // back to October.
                if (month == 10)
                {
                    dayCnt = (DaysInMonth(month, 3) + DaysInMonth(9, 3)) / 2;
                }
                else
                {
                    dayCnt = (DaysInMonth(month, 3) + DaysInMonth(month - 1, 3)) / 2;
                }

                double MonthlyAvgTemp = (annualClimate[month].AvgMinTemp + annualClimate[month].AvgMaxTemp) / 2.0;

                //Now interpolate between days:
                double degreeIncrement = (double)(MonthlyAvgTemp - lastMonthAvgTemp) / (double)dayCnt;
                double TDay            = MonthlyAvgTemp; //start from warmer month
                double TDayRandom      = TDay + (annualClimate[month].StdDevTemp * (randVar.GenerateNumber(autoRand) * 2 - 1));

                for (int day = 1; day <= dayCnt; day++)
                {
                    if (month != 10 || dayCnt > (DaysInMonth(9, 3) / 2))  // Account for starting at November 1.
                    {
                        if (TDayRandom < chillDayBase)
                        {
                            chillDays++;
                        }
                    }
                    TDay      += degreeIncrement; //work backwards to find last frost day.
                    TDayRandom = TDay + (annualClimate[month].StdDevTemp * (randVar.GenerateNumber(autoRand) * 2 - 1));
                }

                lastMonthAvgTemp = MonthlyAvgTemp;
            }

            Console.WriteLine("#Chill Days={0}.", chillDays);
            return(chillDays);
        }