Beispiel #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);
                }
            }
        }
Beispiel #2
0
        /// <summary>Factory method for creating a YieldProphet object from a file.</summary>
        /// <param name="fileName">The filename of the xml file</param>
        /// <returns>The newly created object.</returns>
        public static YieldProphet YieldProphetFromFile(string fileName)
        {
            if (Path.GetExtension(fileName) == ".zip")
            {
                return(YieldProphetFromZip(fileName));
            }
            else
            {
                StreamReader reader = new StreamReader(fileName);
                string       xml    = reader.ReadToEnd();
                reader.Close();

                return(YieldProphetUtility.YieldProphetFromXML(xml, Path.GetDirectoryName(fileName)));
            }
        }
Beispiel #3
0
        /// <summary>
        /// Creates a instance of a yield prophet spec from a zip file.
        /// </summary>
        /// <param name="zipFileName">The name of the .zip file.</param>
        /// <returns>The newly create yieldprophet object.</returns>
        private static YieldProphet YieldProphetFromZip(string zipFileName)
        {
            YieldProphet yieldProphet;

            string tempFolder = Path.GetTempFileName();

            File.Delete(tempFolder);
            Directory.CreateDirectory(tempFolder);
            FileStream reader = File.OpenRead(zipFileName);

            try
            {
                string[] fileNames = ZipUtilities.UnZipFiles(reader, tempFolder, null);

                string fileName = Path.Combine(tempFolder, "YieldProphet.xml");
                if (!File.Exists(fileName))
                {
                    // Look for first XML file.
                    foreach (string file in fileNames)
                    {
                        if (file.Contains(".xml"))
                        {
                            fileName = file;
                            break;
                        }
                    }
                }

                yieldProphet            = YieldProphetUtility.YieldProphetFromFile(fileName);
                yieldProphet.ReportName = Path.GetFileNameWithoutExtension(fileName);
            }
            finally
            {
                reader.Close();
            }
            Directory.Delete(tempFolder, true);
            return(yieldProphet);
        }
Beispiel #4
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;
        }
Beispiel #5
0
        /// <summary>
        /// Create a one year APSIM simulation for the specified yield prophet specification
        /// and paddock
        /// </summary>
        /// <param name="simulation">The specification to use</param>
        /// <param name="workingFolder">The folder where files shoud be created.</param>
        /// <param name="usingAPSIMx">Write APSIMx files?</param>
        /// <returns>The XML node of the APSIM simulation.</returns>
        private static XmlNode CreateSimulationXML(APSIMSpecification simulation, string workingFolder, bool usingAPSIMx)
        {
            IAPSIMFileWriter apsimWriter;

            if (usingAPSIMx)
            {
                apsimWriter = new APSIMxFileWriter();
            }
            else
            {
                apsimWriter = new APSIMFileWriter();
            }

            // Name the paddock.
            apsimWriter.NameSimulation(simulation.Name);

            // Set the clock start and end dates.
            apsimWriter.SetStartEndDate(simulation.StartDate, simulation.EndDate);

            // Set the report date.
            apsimWriter.SetReportDate(simulation.NowDate);

            // Set the weather file
            apsimWriter.SetWeatherFile(simulation.WeatherFileName);

            // Set the stubble
            apsimWriter.SetStubble(simulation.StubbleType, simulation.StubbleMass, YieldProphetUtility.GetStubbleCNRatio(simulation.StubbleType));

            // Set NUnlimited
            if (simulation.NUnlimited)
            {
                apsimWriter.SetNUnlimited();
            }

            // Set NUnlimited from today
            if (simulation.NUnlimitedFromToday)
            {
                apsimWriter.SetNUnlimitedFromToday();
            }

            if (simulation.WriteDepthFile)
            {
                apsimWriter.WriteDepthFile();
            }

            if (simulation.Next10DaysDry)
            {
                apsimWriter.Next10DaysDry();
            }

            apsimWriter.SetErosion(simulation.Slope, simulation.SlopeLength);

            // Do soil stuff.
            DoSoil(simulation, workingFolder);
            apsimWriter.SetSoil(simulation.Soil);

            // Loop through all management actions and create an operations list
            foreach (Management management in simulation.Management)
            {
                if (management is Sow)
                {
                    apsimWriter.AddSowingOperation(management as Sow, simulation.UseEC);
                }
                else if (management is Fertilise)
                {
                    apsimWriter.AddFertilseOperation(management as Fertilise);
                }
                else if (management is Irrigate)
                {
                    apsimWriter.AddIrrigateOperation(management as Irrigate);
                }
                else if (management is Tillage)
                {
                    apsimWriter.AddTillageOperation(management as Tillage);
                }
                else if (management is StubbleRemoved)
                {
                    apsimWriter.AddStubbleRemovedOperation(management as StubbleRemoved);
                }
                else if (management is ResetWater)
                {
                    apsimWriter.AddResetWaterOperation(management as ResetWater);
                }
                else if (management is ResetNitrogen)
                {
                    apsimWriter.AddResetNitrogenOperation(management as ResetNitrogen);
                }
                else if (management is ResetSurfaceOrganicMatter)
                {
                    apsimWriter.AddSurfaceOrganicMatterOperation(management as ResetSurfaceOrganicMatter);
                }
            }

            // Set Daily output
            if (simulation.DailyOutput)
            {
                apsimWriter.SetDailyOutput();
            }

            // Set Monthly output
            if (simulation.MonthlyOutput)
            {
                apsimWriter.SetMonthlyOutput();
            }

            // Set Yearly output
            if (simulation.YearlyOutput)
            {
                apsimWriter.SetYearlyOutput();
            }

            return(apsimWriter.ToXML());
        }
Beispiel #6
0
        /// <summary>Initialise job manager</summary>
        private void Initialise(bool createSims = true)
        {
            Errors = new List <string>();
            try
            {
                // Create a working directory.
                WorkingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                Directory.CreateDirectory(WorkingDirectory);

                // Create a YieldProphet object if xml was provided
                string fileBaseToWrite = "YieldProphet";
                if (specXMLToRun != null)
                {
                    if (specXMLToRun.Contains("<YieldProphet>"))
                    {
                        specToRun      = YieldProphetUtility.YieldProphetFromXML(specXMLToRun, WorkingDirectory);
                        allSimulations = YieldProphetToAPSIM.ToAPSIM(specToRun);
                        if (specToRun.ReportName != null)
                        {
                            fileBaseToWrite = specToRun.ReportName;
                        }
                    }
                    else
                    {
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(specXMLToRun);
                        allSimulations = XmlUtilities.Deserialise(doc.DocumentElement, typeof(List <APSIMSpecification>)) as List <APSIMSpecification>;
                    }
                }
                else if (specToRun != null)
                {
                    allSimulations = YieldProphetToAPSIM.ToAPSIM(specToRun);
                }

                // Create all the files needed to run APSIM.
                string fileToWrite;
                if (environment.APSIMxBuildNumber > 0)
                {
                    fileToWrite = fileBaseToWrite + ".apsimx";
                }
                else
                {
                    fileToWrite = fileBaseToWrite + ".apsim";
                }
                string apsimFileName = APSIMFiles.Create(allSimulations, WorkingDirectory, fileToWrite);

                // Save YieldProphet.xml to working folder.
                if (specToRun != null)
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(YieldProphetUtility.YieldProphetToXML(specToRun));
                    doc.Save(Path.Combine(WorkingDirectory, fileBaseToWrite + ".xml"));
                }

                if (createSims)
                {
                    // Setup the runtime environment.
                    binFolder = SetupRunTimeEnvironment(environment);

                    // Go find APSIM executable
                    if (environment.APSIMxBuildNumber > 0)
                    {
                        jobsToRun = GetJobToRunAPSIMX(apsimFileName, binFolder);
                    }
                    else
                    {
                        jobsToRun = GetJobToRunAPSIMClassic(apsimFileName, binFolder);
                    }
                }

                // Copy all errors to our errors list.
                foreach (var sim in allSimulations.FindAll(sim => sim.ErrorMessage != null))
                {
                    Errors.Add(sim.ErrorMessage);
                }
            }
            catch (Exception err)
            {
                Errors.Add(err.ToString());
            }
        }
Beispiel #7
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);
        }