/// <summary> /// Creates a base AusFarm simulation spec from the Farm4Prophet spec. /// </summary> /// <param name="paddock">The farm paddock</param> /// <returns>The created AusFarm spec</returns> private static AusFarmSpec CreateBaseSimulation(FarmSystem farm) { FarmSystem copyOfFarm = farm; AusFarmSpec runnableSim = new AusFarmSpec(); runnableSim.Name = "BaseSim"; runnableSim.StartDate = DateTime.MaxValue; //=========================================================== // May be appropriate here to decide which simulation template // will be used based on the requirement for crops and animals. //=========================================================== runnableSim.SimTemplateType = farm.SimTemplateType; /* sample dates used to initialise the run times? if (farm.SoilWaterSampleDate < runnableSim.StartDate) runnableSim.StartDate = farm.SoilWaterSampleDate; if (farm.SoilNitrogenSampleDate != DateTime.MinValue && farm.SoilNitrogenSampleDate < runnableSim.StartDate) runnableSim.StartDate = farm.SoilNitrogenSampleDate; */ //if (sow != null && sow.Date < shortSimulation.StartDate) // shortSimulation.StartDate = sow.Date; if (farm.StartSeasonDate < runnableSim.StartDate) runnableSim.StartDate = farm.StartSeasonDate; runnableSim.OnFarmSoilTypes.AddRange(copyOfFarm.OnFarmSoilTypes); runnableSim.OnFarmPaddocks.AddRange(copyOfFarm.OnFarmPaddocks); runnableSim.LiveStock = copyOfFarm.LiveStock; runnableSim.StationNumber = copyOfFarm.StationNumber; runnableSim.CroppingRegion = copyOfFarm.CroppingRegion; return runnableSim; }
/// <summary> /// Create simulation specifications. /// </summary> /// <param name="f4Prophet">The farm 4 prophet specification</param> /// <returns>A list of AusFarm specs. </returns> private static List <AusFarmSpec> SimulationRuns(Farm4Prophet f4Prophet) { List <AusFarmSpec> ausfarmSpecs = new List <AusFarmSpec>(); foreach (FarmSystem farm in f4Prophet.FarmList) { AusFarmSpec simulation = CreateBaseSimulation(farm); simulation.Name = farm.Name; simulation.Area = farm.Area; simulation.StartDate = farm.StartSeasonDate; simulation.EndDate = simulation.StartDate.AddMonths(farm.RunLength); simulation.ReportName = farm.ReportName; ausfarmSpecs.Add(simulation); } return(ausfarmSpecs); }
/// <summary> /// Creates a base AusFarm simulation spec from the Farm4Prophet spec. /// </summary> /// <param name="paddock">The farm paddock</param> /// <returns>The created AusFarm spec</returns> private static AusFarmSpec CreateBaseSimulation(FarmSystem farm) { FarmSystem copyOfFarm = farm; AusFarmSpec runnableSim = new AusFarmSpec(); runnableSim.Name = "BaseSim"; runnableSim.StartDate = DateTime.MaxValue; //=========================================================== // May be appropriate here to decide which simulation template // will be used based on the requirement for crops and animals. //=========================================================== runnableSim.SimTemplateType = farm.SimTemplateType; /* sample dates used to initialise the run times? * if (farm.SoilWaterSampleDate < runnableSim.StartDate) * runnableSim.StartDate = farm.SoilWaterSampleDate; * if (farm.SoilNitrogenSampleDate != DateTime.MinValue && * farm.SoilNitrogenSampleDate < runnableSim.StartDate) * runnableSim.StartDate = farm.SoilNitrogenSampleDate; */ //if (sow != null && sow.Date < shortSimulation.StartDate) // shortSimulation.StartDate = sow.Date; if (farm.StartSeasonDate < runnableSim.StartDate) { runnableSim.StartDate = farm.StartSeasonDate; } runnableSim.OnFarmSoilTypes.AddRange(copyOfFarm.OnFarmSoilTypes); runnableSim.OnFarmPaddocks.AddRange(copyOfFarm.OnFarmPaddocks); runnableSim.LiveStock = copyOfFarm.LiveStock; runnableSim.StationNumber = copyOfFarm.StationNumber; runnableSim.CroppingRegion = copyOfFarm.CroppingRegion; return(runnableSim); }
/// <summary>Creates the weather files for all simulations.</summary> /// <param name="simulations">The simulations.</param> /// <param name="workingFolder">The working folder to create the files in.</param> /// <param name="ausfarmNode"></param> private static void CreateWeatherFileForSimulation(AusFarmSpec simulation, string workingFolder) { // Write the .met file for the simulation DateTime earliestStartDate = DateTime.MaxValue; DateTime latestEndDate = DateTime.MinValue; DateTime nowDate = DateTime.MaxValue; DataTable observedData = null; int stationNumber = 0; stationNumber = simulation.StationNumber; if (simulation.StartDate < earliestStartDate) earliestStartDate = simulation.StartDate; if (simulation.EndDate > latestEndDate) latestEndDate = simulation.EndDate; // Create the weather files. FMetFile = Path.Combine(workingFolder, stationNumber.ToString()) + ".met"; // Create a weather file. Weather.Data weatherFile = Weather.ExtractDataFromSILO(stationNumber, earliestStartDate, nowDate); Weather.OverlayData(observedData, weatherFile.Table); Weather.WriteWeatherFile(weatherFile.Table, FMetFile, weatherFile.Latitude, weatherFile.Longitude, weatherFile.TAV, weatherFile.AMP); // ensure that the run period doesn't exceed the data retrieved if (simulation.EndDate > weatherFile.LastDate) simulation.EndDate = weatherFile.LastDate; // calculate the rain deciles from April from the year of the start of the simulation. // this could be improved to use more than a few decades of weather. simulation.RainDeciles = new double[12, 10]; // 12 months, 10 deciles DateTime accumStartDate = new DateTime(simulation.StartDate.Year, 4, 1); if (simulation.StartDate > accumStartDate) // ensure that the start date for decile accum exists in the weather accumStartDate.AddYears(1); simulation.RainDeciles = Weather.CalculateRainDeciles(stationNumber, accumStartDate, simulation.EndDate); }
/// <summary> /// Retrieves soil types from ApSoil /// Configures any missing crop ll, kl values /// </summary> /// <param name="simulation"></param> /// <param name="apsoilService"></param> /// <returns></returns> public static void DoSoils(AusFarmSpec simulation) { APSOIL.Service apsoilService = null; Soil soil; for (int i = 0; i < simulation.OnFarmSoilTypes.Count; i++) { FarmSoilType soilType = simulation.OnFarmSoilTypes[i]; soil = soilType.SoilDescr; if (soil == null) { // Look for a <SoilName> and if found go get the soil from the Apsoil web service. if (apsoilService == null) apsoilService = new APSOIL.Service(); string soilXml = apsoilService.SoilXML(soilType.SoilPath); if (soilXml == string.Empty) throw new Exception("Cannot find soil: " + soilType.SoilPath); soil = SoilUtilities.FromXML(soilXml); } // Other crop types not listed here will have their ll, kll, xf values calculated later // Remove any initwater nodes. soil.InitialWater = null; foreach (Sample sample in soil.Samples) CheckSample(soil, sample); // 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 = ""; // Set the soil name to 'soil' //soil.Name = "Soil"; soilType.SoilDescr = soil; //store the changed description } }
/// <summary> /// Create a one year APSIM simulation for the specified yield prophet specification /// and paddock /// </summary> /// <param name="paddock">The paddock.</param> /// <param name="todayDate">The today date.</param> /// <param name="apsoilService">The apsoil service.</param> /// <returns>The XML node of the APSIM simulation.</returns> private static XmlNode CreateSimulationXML(AusFarmSpec simulation, string workingFolder) { AusFarmFileWriter ausfarmWriter; // determine which type of simulation this is based on stock, paddocks, crops if ((simulation.LiveStock.Flocks.Count == 0) && (simulation.LiveStock.TradeLambCount == 0)) { ausfarmWriter = new AusFarmFileWriter(SimulationType.stCropOnly); simulation.SimTemplateType = SimulationType.stCropOnly; // ensure that the simulation type is alway correct } else { if (simulation.LiveStock.Flocks.Count == 1) { ausfarmWriter = new AusFarmFileWriter(SimulationType.stSingleFlock); simulation.SimTemplateType = SimulationType.stSingleFlock; // ensure that the simulation type is alway correct } else if (simulation.LiveStock.Flocks.Count == 2) { ausfarmWriter = new AusFarmFileWriter(SimulationType.stDualFlock); simulation.SimTemplateType = SimulationType.stDualFlock; // ensure that the simulation type is alway correct } else throw new Exception(); } // Name the simulation ausfarmWriter.NameSimulation(simulation.Name); // Set the clock start and end dates. ausfarmWriter.SetStartEndDate(simulation.StartDate, simulation.EndDate); //set the path for output files ausfarmWriter.OutputPath(workingFolder); ausfarmWriter.ReportName(simulation.ReportName); // Set the weather file ausfarmWriter.SetWeatherFile(FMetFile); ausfarmWriter.SetRainDeciles(simulation.RainDeciles); ausfarmWriter.SetCroppingRegion(simulation.CroppingRegion); ausfarmWriter.SetArea(simulation.Area); for (int i = 0; i < simulation.OnFarmSoilTypes.Count; i++) { ausfarmWriter.SetCropRotation(i + 1, simulation.OnFarmSoilTypes[i].CropRotationList); } // Do soil stuff. DoSoils(simulation); ausfarmWriter.SetSoils(simulation); if (simulation.SimTemplateType != SimulationType.stCropOnly) { // Set the Livestock data ausfarmWriter.WriteStockEnterprises(simulation.LiveStock); } return ausfarmWriter.ToXML(); }
/// <summary>Create a .sdml file for the job</summary> /// <param name="AusFarmSpec">The specification to use</param> /// <returns>The root XML node for the file</returns> private static XmlNode CreateAusFarmFile(AusFarmSpec simulation, string workingFolder) { XmlDocument doc = new XmlDocument(); try { XmlNode simulationXML = CreateSimulationXML(simulation, workingFolder); if (simulationXML != null) doc.AppendChild(doc.ImportNode(simulationXML, true)); } catch (Exception err) { throw new Exception(err.Message + "\r\nSimulation name: " + simulation.Name); } return doc.DocumentElement; }