예제 #1
0
        /// <summary>Add in reset management events to the APSIM spec for the specified paddock.</summary>
        /// <param name="paddock">The paddock.</param>
        /// <param name="simulation">The simulation to add the management operations to.</param>
        /// <exception cref="System.Exception">Cannot find soil water reset date</exception>
        /// <exception cref="Exception">Cannot find soil water reset date</exception>
        private static void AddResetDatesToManagement(Paddock paddock, APSIMSpecification simulation)
        {
            // Reset
            if (paddock.SoilWaterSampleDate != DateTime.MinValue)
            {
                if (paddock.SoilNitrogenSampleDate == DateTime.MinValue)
                {
                    paddock.SoilNitrogenSampleDate = paddock.SoilWaterSampleDate;
                }

                Sow sowing = YieldProphetUtility.GetCropBeingSown(paddock.Management);
                if (sowing != null && sowing.Date != DateTime.MinValue)
                {
                    List <Management> resetActions = new List <Management>();

                    // reset at sowing if the sample dates are after sowing.
                    if (paddock.SoilWaterSampleDate > sowing.Date)
                    {
                        resetActions.Add(new ResetWater()
                        {
                            Date = sowing.Date
                        });
                        resetActions.Add(new ResetSurfaceOrganicMatter()
                        {
                            Date = sowing.Date
                        });
                    }
                    if (paddock.SoilNitrogenSampleDate > sowing.Date)
                    {
                        resetActions.Add(new ResetNitrogen()
                        {
                            Date = sowing.Date
                        });
                    }

                    // reset on the sample dates.
                    resetActions.Add(new ResetWater()
                    {
                        Date = paddock.SoilWaterSampleDate
                    });
                    resetActions.Add(new ResetSurfaceOrganicMatter()
                    {
                        Date = paddock.SoilWaterSampleDate
                    });
                    resetActions.Add(new ResetNitrogen()
                    {
                        Date = paddock.SoilNitrogenSampleDate
                    });

                    simulation.Management.InsertRange(0, resetActions);
                }
            }
        }
예제 #2
0
        /// <summary>Do all soil related settings.</summary>
        /// <param name="simulation">The specification to use</param>
        /// <param name="workingFolder">The folder where files shoud be created.</param>
        private static void DoSoil(APSIMSpecification simulation, string workingFolder)
        {
            Soil soil;

            if (simulation.Soil == null)
            {
                if (simulation.SoilPath.StartsWith("<Soil"))
                {
                    // Soil and Landscape grid
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(simulation.SoilPath);
                    soil = XmlUtilities.Deserialise(doc.DocumentElement, typeof(Soil)) as Soil;
                }
                else if (simulation.SoilPath.StartsWith("http"))
                {
                    // Soil and Landscape grid
                    string xml;
                    using (var client = new WebClient())
                    {
                        xml = client.DownloadString(simulation.SoilPath);
                    }
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(xml);
                    List <XmlNode> soils = XmlUtilities.ChildNodes(doc.DocumentElement, "Soil");
                    if (soils.Count == 0)
                    {
                        throw new Exception("Cannot find soil in Soil and Landscape Grid");
                    }
                    soil = XmlUtilities.Deserialise(soils[0], typeof(Soil)) as Soil;
                }
                else
                {
                    // Apsoil web service.
                    APSOIL.Service apsoilService = new APSOIL.Service();
                    string         soilXml       = apsoilService.SoilXML(simulation.SoilPath.Replace("\r\n", ""));
                    if (soilXml == string.Empty)
                    {
                        throw new Exception("Cannot find soil: " + simulation.SoilPath);
                    }
                    soil = SoilUtilities.FromXML(soilXml);
                }
            }
            else
            {
                // Just use the soil we already have
                soil = simulation.Soil;
            }

            // Make sure we have a soil crop parameterisation. If not then try creating one
            // based on wheat.
            Sow sowing = YieldProphetUtility.GetCropBeingSown(simulation.Management);

            string[] cropNames = soil.Water.Crops.Select(c => c.Name).ToArray();
            if (cropNames.Length == 0)
            {
                throw new Exception("Cannot find any crop parameterisations in soil: " + simulation.SoilPath);
            }

            if (sowing != null && !StringUtilities.Contains(cropNames, sowing.Crop))
            {
                SoilCrop wheat = soil.Water.Crops.Find(c => c.Name.Equals("wheat", StringComparison.InvariantCultureIgnoreCase));
                if (wheat == null)
                {
                    // Use the first crop instead.
                    wheat = soil.Water.Crops[0];
                }

                SoilCrop newSoilCrop = new SoilCrop();
                newSoilCrop.Name      = sowing.Crop;
                newSoilCrop.Thickness = wheat.Thickness;
                newSoilCrop.LL        = wheat.LL;
                newSoilCrop.KL        = wheat.KL;
                newSoilCrop.XF        = wheat.XF;
                soil.Water.Crops.Add(newSoilCrop);
            }

            // Remove any initwater nodes.
            soil.InitialWater = null;

            // Transfer the simulation samples to the soil
            if (simulation.Samples != null)
            {
                soil.Samples = simulation.Samples;
            }

            if (simulation.InitTotalWater != 0)
            {
                soil.InitialWater = new InitialWater();
                soil.InitialWater.PercentMethod = InitialWater.PercentMethodEnum.FilledFromTop;

                double pawc;
                if (sowing == null || sowing.Crop == null)
                {
                    pawc = MathUtilities.Sum(PAWC.OfSoilmm(soil));
                    soil.InitialWater.RelativeTo = "LL15";
                }
                else
                {
                    SoilCrop crop = soil.Water.Crops.Find(c => c.Name.Equals(sowing.Crop, StringComparison.InvariantCultureIgnoreCase));
                    pawc = MathUtilities.Sum(PAWC.OfCropmm(soil, crop));
                    soil.InitialWater.RelativeTo = crop.Name;
                }

                soil.InitialWater.FractionFull = Convert.ToDouble(simulation.InitTotalWater) / pawc;
            }

            if (simulation.InitTotalNitrogen != 0)
            {
                // Add in a sample.
                Sample nitrogenSample = new Sample();
                nitrogenSample.Name = "NitrogenSample";
                soil.Samples.Add(nitrogenSample);
                nitrogenSample.Thickness = new double[] { 150, 150, 3000 };
                nitrogenSample.NO3Units  = Nitrogen.NUnitsEnum.kgha;
                nitrogenSample.NH4Units  = Nitrogen.NUnitsEnum.kgha;
                nitrogenSample.NO3       = new double[] { 6.0, 2.1, 0.1 };
                nitrogenSample.NH4       = new double[] { 0.5, 0.1, 0.1 };
                nitrogenSample.OC        = new double[] { double.NaN, double.NaN, double.NaN };
                nitrogenSample.EC        = new double[] { double.NaN, double.NaN, double.NaN };
                nitrogenSample.PH        = new double[] { double.NaN, double.NaN, double.NaN };

                double Scale = Convert.ToDouble(simulation.InitTotalNitrogen) / MathUtilities.Sum(nitrogenSample.NO3);
                nitrogenSample.NO3 = MathUtilities.Multiply_Value(nitrogenSample.NO3, Scale);
            }

            // Add in soil temperature. Needed for Aflatoxin risk.
            soil.SoilTemperature = new SoilTemperature();
            soil.SoilTemperature.BoundaryLayerConductance = 15;
            soil.SoilTemperature.Thickness = new double[] { 2000 };
            soil.SoilTemperature.InitialSoilTemperature = new double[] { 22 };
            if (soil.Analysis.ParticleSizeClay == null)
            {
                soil.Analysis.ParticleSizeClay = MathUtilities.CreateArrayOfValues(60, soil.Analysis.Thickness.Length);
            }
            InFillMissingValues(soil.Analysis.ParticleSizeClay);

            foreach (Sample sample in soil.Samples)
            {
                CheckSample(soil, sample, sowing);
            }

            Defaults.FillInMissingValues(soil);

            // Correct the CONA / U parameters depending on LAT/LONG
            CorrectCONAU(simulation, soil, workingFolder);

            // get rid of <soiltype> from the soil
            // this is necessary because NPD uses this field and puts in really long
            // descriptive classifications. Soiln2 bombs with an FString internal error.
            soil.SoilType = null;

            // Set the soil name to 'soil'
            soil.Name = "Soil";

            simulation.Soil = soil;
        }
예제 #3
0
        /// <summary>Creates a base APSIM simulation spec for the Yield Prophet spec.</summary>
        /// <param name="yieldProphet">The yield prophet specification.</param>
        /// <returns>The created APSIM simulation spec.</returns>
        private static APSIMSpecification CreateBaseSimulation(Paddock paddock)
        {
            Paddock copyOfPaddock = paddock; // XmlUtilities.Clone(paddock) as JobsService.Paddock;

            copyOfPaddock.ObservedData = paddock.ObservedData;

            APSIMSpecification shortSimulation = new APSIMSpecification();

            shortSimulation.Name            = "Base";
            shortSimulation.WeatherFileName = shortSimulation.Name + ".met";

            // Start date of simulation should be the earliest of ResetDate, SowDate and StartSeasonDate
            Sow sow = YieldProphetUtility.GetCropBeingSown(paddock.Management);

            if (sow == null)
            {
                throw new Exception("No sowing specified for paddock: " + paddock.Name);
            }

            if (sow.Date == DateTime.MinValue)
            {
                throw new Exception("No sowing DATE specified for paddock: " + paddock.Name);
            }

            if (sow.Crop == null || sow.Crop == "" || sow.Crop == "None")
            {
                throw new Exception("No sowing CROP specified for paddock: " + paddock.Name);
            }

            shortSimulation.StartDate = DateTime.MaxValue;
            if (paddock.SoilWaterSampleDate != DateTime.MinValue &&
                paddock.SoilWaterSampleDate < shortSimulation.StartDate)
            {
                shortSimulation.StartDate = paddock.SoilWaterSampleDate;
            }
            if (paddock.SoilNitrogenSampleDate != DateTime.MinValue &&
                paddock.SoilNitrogenSampleDate < shortSimulation.StartDate)
            {
                shortSimulation.StartDate = paddock.SoilNitrogenSampleDate;
            }
            if (sow != null && sow.Date < shortSimulation.StartDate && sow.Date != DateTime.MinValue)
            {
                shortSimulation.StartDate = sow.Date;
            }
            if (paddock.StartSeasonDate < shortSimulation.StartDate)
            {
                shortSimulation.StartDate = paddock.StartSeasonDate;
            }

            if (paddock.LongtermStartYear == 0)
            {
                shortSimulation.LongtermStartYear = 1957;
            }
            else
            {
                shortSimulation.LongtermStartYear = paddock.LongtermStartYear;
            }

            if (paddock.RunType == Paddock.RunTypeEnum.SingleSeason)
            {
                shortSimulation.EndDate = copyOfPaddock.NowDate.AddDays(-1);
                if ((shortSimulation.EndDate - shortSimulation.StartDate).Days > 360)
                {
                    shortSimulation.EndDate = shortSimulation.StartDate.AddDays(360);
                }
            }
            else if (paddock.RunType == Paddock.RunTypeEnum.LongTermPatched)
            {
                shortSimulation.EndDate = shortSimulation.StartDate.AddDays(360);
            }
            else if (paddock.RunType == Paddock.RunTypeEnum.LongTerm)
            {
                // Sow opp reports.
                shortSimulation.StartDate = new DateTime(shortSimulation.LongtermStartYear, 1, 1);
                shortSimulation.EndDate   = copyOfPaddock.NowDate.AddDays(-1);
            }
            shortSimulation.NowDate = copyOfPaddock.NowDate.AddDays(-1);
            if (shortSimulation.NowDate == DateTime.MinValue)
            {
                shortSimulation.NowDate = DateTime.Now;
            }
            shortSimulation.DailyOutput   = paddock.DailyOutput;
            shortSimulation.MonthlyOutput = paddock.MonthlyOutput;
            shortSimulation.YearlyOutput  = paddock.YearlyOutput;
            shortSimulation.ObservedData  = copyOfPaddock.ObservedData;
            shortSimulation.Soil          = copyOfPaddock.Soil;
            shortSimulation.SoilPath      = copyOfPaddock.SoilPath;
            shortSimulation.Samples       = new List <APSIM.Shared.Soils.Sample>();
            shortSimulation.Samples.AddRange(copyOfPaddock.Samples);
            shortSimulation.InitTotalWater    = copyOfPaddock.InitTotalWater;
            shortSimulation.InitTotalNitrogen = copyOfPaddock.InitTotalNitrogen;
            shortSimulation.StationNumber     = copyOfPaddock.StationNumber;
            shortSimulation.StubbleMass       = copyOfPaddock.StubbleMass;
            shortSimulation.StubbleType       = copyOfPaddock.StubbleType;
            shortSimulation.Management        = new List <Management>();
            shortSimulation.Management.AddRange(copyOfPaddock.Management);
            shortSimulation.UseEC          = paddock.UseEC;
            shortSimulation.WriteDepthFile = false;
            if (paddock.RunType == Paddock.RunTypeEnum.LongTermPatched)
            {
                shortSimulation.RunType = APSIMSpecification.RunTypeEnum.LongTermPatched;
            }
            else
            {
                shortSimulation.RunType = APSIMSpecification.RunTypeEnum.Normal;
            }
            shortSimulation.DecileDate          = paddock.StartSeasonDate;
            shortSimulation.NUnlimited          = paddock.NUnlimited;
            shortSimulation.NUnlimitedFromToday = paddock.NUnlimitedFromToday;
            shortSimulation.WriteDepthFile      = paddock.WriteDepthFile;
            shortSimulation.Next10DaysDry       = paddock.Next10DaysDry;
            AddResetDatesToManagement(copyOfPaddock, shortSimulation);

            // Do a stable sort on management actions.
            shortSimulation.Management = shortSimulation.Management.OrderBy(m => m.Date).ToList();

            if (paddock.RunType == Paddock.RunTypeEnum.LongTerm)
            {
                foreach (Management man in shortSimulation.Management)
                {
                    man.IsEveryYear = true;
                }
            }
            return(shortSimulation);
        }