/// <summary>Adds a new model (as specified by the xml node) to the specified parent.</summary> /// <param name="parent">The parent to add the model to</param> /// <param name="node">The XML representing the new model</param> /// <returns>The newly created model.</returns> public static IModel Add(IModel parent, XmlNode node) { IModel modelToAdd = XmlUtilities.Deserialise(node, Assembly.GetExecutingAssembly()) as Model; // Get all child models List <IModel> modelsToNotify = Apsim.ChildrenRecursively(modelToAdd); // Call deserialised in all models. object[] args = new object[] { true }; CallEventHandler(modelToAdd, "Deserialised", args); foreach (IModel modelToNotify in modelsToNotify) { CallEventHandler(modelToNotify, "Deserialised", args); } // Corrently parent all models. modelToAdd.Parent = parent; Apsim.ParentAllChildren(modelToAdd); parent.Children.Add(modelToAdd as Model); // Ensure the model name is valid. Apsim.EnsureNameIsUnique(modelToAdd); // Call OnLoaded Apsim.CallEventHandler(modelToAdd, "Loaded", null); foreach (IModel child in modelsToNotify) { Apsim.CallEventHandler(child, "Loaded", null); } Locator(parent).Clear(); return(modelToAdd); }
/// <summary>Create a simulations object by reading the specified filename</summary> /// <param name="node">The node.</param> /// <returns></returns> /// <exception cref="System.Exception">Simulations.Read() failed. Invalid simulation file.\n</exception> public static Simulations Read(XmlNode node) { // Run the converter. APSIMFileConverter.ConvertToLatestVersion(node, null); // Deserialise Simulations simulations = XmlUtilities.Deserialise(node, Assembly.GetExecutingAssembly()) as Simulations; if (simulations != null) { // Set the filename simulations.SetFileNameInAllSimulations(); // Call the OnSerialised method in each model. object[] args = new object[] { true }; Events events = new Events(simulations); events.Publish("Deserialised", args); // Parent all models. simulations.Parent = null; Apsim.ParentAllChildren(simulations); events.Publish("Loaded", null); } else { throw new Exception("Simulations.Read() failed. Invalid simulation file.\n"); } return(simulations); }
/// <summary>Adds a new model (as specified by the xml node) to the specified parent.</summary> /// <param name="parent">The parent to add the model to</param> /// <param name="node">The XML representing the new model</param> /// <returns>The newly created model.</returns> public static IModel Add(IModel parent, XmlNode node) { IModel modelToAdd = XmlUtilities.Deserialise(node, Assembly.GetExecutingAssembly()) as Model; // Call deserialised Events events = new Events(modelToAdd); object[] args = new object[] { true }; events.Publish("Deserialised", args); // Correctly parent all models. Add(parent, modelToAdd); // Ensure the model name is valid. Apsim.EnsureNameIsUnique(modelToAdd); // Call OnLoaded LoadedEventArgs loadedArgs = new LoadedEventArgs(); events.Publish("Loaded", new object[] { modelToAdd, loadedArgs }); Locator(parent).Clear(); return(modelToAdd); }
/// <summary>Create a simulations object by reading the specified filename</summary> /// <param name="FileName">Name of the file.</param> /// <returns></returns> /// <exception cref="System.Exception">Simulations.Read() failed. Invalid simulation file.\n</exception> public static Simulations Read(string FileName) { // Run the converter. ApsimFile.Converter.ConvertToLatestVersion(FileName); // Deserialise Simulations simulations = XmlUtilities.Deserialise(FileName, Assembly.GetExecutingAssembly()) as Simulations; if (simulations != null) { // Set the filename simulations.FileName = FileName; simulations.SetFileNameInAllSimulations(); // Call the OnDeserialised method in each model. Events events = new Core.Events(simulations); object[] args = new object[] { true }; events.Publish("Deserialised", args); // Parent all models. simulations.Parent = null; Apsim.ParentAllChildren(simulations); // Call OnLoaded in all models. LoadedEventArgs loadedArgs = new LoadedEventArgs(); events.Publish("Loaded", new object[] { simulations, loadedArgs }); if (loadedArgs.errors.Count > 0) { simulations.LoadErrors = new List <Exception>(); simulations.LoadErrors.AddRange(loadedArgs.errors); } } return(simulations); }
public void APSIMFileReader_EnsureReadingStandardToolboxWorks() { string toolboxFileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "..", "..", "..", "ApsimNG", "Resources", "Toolboxes", "StandardToolbox.apsimx"); XmlDocument toolboxdoc = new XmlDocument(); toolboxdoc.Load(toolboxFileName); // Create instance of reader. XmlReader reader1 = new Models.Core.ApsimFile.Reader(toolboxdoc.DocumentElement); reader1.Read(); Assembly modelsAssembly = null; foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { if (!a.IsDynamic && Path.GetFileName(a.Location) == "Models.exe") { modelsAssembly = a; } } ModelWrapper wrapper = XmlUtilities.Deserialise(reader1, modelsAssembly) as ModelWrapper; Assert.AreEqual(wrapper.Children.Count, 8); }
/// <summary>Create a simulations object by reading the specified filename</summary> /// <param name="node">The node.</param> /// <returns></returns> /// <exception cref="System.Exception">Simulations.Read() failed. Invalid simulation file.\n</exception> public static Simulations Read(XmlNode node) { // Run the converter. Converter.ConvertToLatestVersion(node); // Deserialise Simulations simulations = XmlUtilities.Deserialise(node, Assembly.GetExecutingAssembly()) as Simulations; if (simulations != null) { // Set the filename simulations.SetFileNameInAllSimulations(); // Call the OnSerialised method in each model. object[] args = new object[] { true }; foreach (Model model in Apsim.ChildrenRecursively(simulations)) { Apsim.CallEventHandler(model, "Deserialised", args); } // Parent all models. simulations.Parent = null; Apsim.ParentAllChildren(simulations); CallOnLoaded(simulations); } else { throw new Exception("Simulations.Read() failed. Invalid simulation file.\n"); } return(simulations); }
public static Models.Graph.Graph CreateGraphFromResource(string resourceName) { string graphXmL = UserInterface.Properties.Resources.ResourceManager.GetString(resourceName); if (graphXmL != null) { XmlDocument doc = new XmlDocument(); doc.LoadXml(graphXmL); return(XmlUtilities.Deserialise(doc.DocumentElement, Assembly.GetExecutingAssembly()) as Models.Graph.Graph); } return(null); }
/// <summary>Create a simulations object by reading the specified filename</summary> /// <param name="FileName">Name of the file.</param> /// <returns></returns> /// <exception cref="System.Exception">Simulations.Read() failed. Invalid simulation file.\n</exception> public static Simulations Read(string FileName) { // Run the converter. Converter.ConvertToLatestVersion(FileName); // Deserialise Simulations simulations = XmlUtilities.Deserialise(FileName, Assembly.GetExecutingAssembly()) as Simulations; if (simulations != null) { // Set the filename simulations.FileName = FileName; simulations.SetFileNameInAllSimulations(); // Call the OnDeserialised method in each model. object[] args = new object[] { true }; foreach (Model model in Apsim.ChildrenRecursively(simulations)) { Apsim.CallEventHandler(model, "Deserialised", args); } // Parent all models. simulations.Parent = null; Apsim.ParentAllChildren(simulations); // Call OnLoaded in all models. simulations.LoadErrors = new List <Exception>(); foreach (Model child in Apsim.ChildrenRecursively(simulations)) { try { Apsim.CallEventHandler(child, "Loaded", null); } catch (ApsimXException err) { simulations.LoadErrors.Add(err); } catch (Exception err) { err.Source = child.Name; simulations.LoadErrors.Add(err); } } } else { throw new Exception("Simulations.Read() failed. Invalid simulation file.\n"); } return(simulations); }
public static Models.Graph.Graph CreateGraphFromResource(string resourceName) { string graphXmL = UserInterface.Properties.Resources.ResourceManager.GetString(resourceName); if (graphXmL != null) { XmlDocument doc = new XmlDocument(); doc.LoadXml(graphXmL); Models.Graph.Graph graph = XmlUtilities.Deserialise(doc.DocumentElement, typeof(Models.Graph.Graph)) as Models.Graph.Graph; Apsim.ParentAllChildren(graph); return(graph); } return(null); }
/// <summary>Create a simulations object by reading the specified filename</summary> /// <param name="FileName">Name of the file.</param> /// <returns></returns> /// <exception cref="System.Exception">Simulations.Read() failed. Invalid simulation file.\n</exception> public static Simulations Read(string FileName) { if (!File.Exists(FileName)) { throw new Exception("Cannot read file: " + FileName + ". File does not exist."); } // Run the converter. Stream inStream = ApsimFile.Converter.ConvertToLatestVersion(FileName); // Deserialise Simulations simulations = XmlUtilities.Deserialise(inStream, Assembly.GetExecutingAssembly()) as Simulations; if (simulations.Version > ApsimFile.Converter.LatestVersion) { throw new Exception("This file has previously been opened with a more recent version of Apsim. Please upgrade to a newer version to open this file."); } inStream.Close(); if (simulations != null) { // Set the filename simulations.FileName = FileName; simulations.SetFileNameInAllSimulations(); // Call the OnDeserialised method in each model. Events events = new Core.Events(simulations); object[] args = new object[] { true }; events.Publish("Deserialised", args); // Parent all models. simulations.Parent = null; Apsim.ParentAllChildren(simulations); // Call OnLoaded in all models. LoadedEventArgs loadedArgs = new LoadedEventArgs(); events.Publish("Loaded", new object[] { simulations, loadedArgs }); if (loadedArgs.errors.Count > 0) { simulations.LoadErrors = new List <Exception>(); simulations.LoadErrors.AddRange(loadedArgs.errors); } } return(simulations); }
/// <summary>Create a simulations object by reading the specified filename</summary> /// <param name="s">The stream to read from.</param> public ModelWrapper Read(Stream s) { XmlReader reader = new APSIMFileReader(s); reader.Read(); Assembly modelsAssembly = null; foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { if (!a.IsDynamic && Path.GetFileName(a.Location) == "Models.exe") { modelsAssembly = a; } } return(XmlUtilities.Deserialise(reader, modelsAssembly) as ModelWrapper); }
/// <summary>Create a simulations object by reading the specified filename</summary> /// <param name="node">XML node to read from.</param> public ModelWrapper Read(XmlNode node) { APSIMFileConverter.ConvertToLatestVersion(node); XmlReader reader = new APSIMFileReader(node); reader.Read(); Assembly modelsAssembly = null; foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { if (!a.IsDynamic && Path.GetFileName(a.Location) == "Models.exe") { modelsAssembly = a; } } return(XmlUtilities.Deserialise(reader, modelsAssembly) as ModelWrapper); }
protected void OnDeserialised(bool xmlSerialisation) { if (xmlSerialisation) { // lookup the resource get the xml and then deserialise to a model. if (ResourceName != null && ResourceName != "") { string xml = Properties.Resources.ResourceManager.GetString(ResourceName); if (xml != null) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); Model ModelFromResource = XmlUtilities.Deserialise(doc.DocumentElement, Assembly.GetExecutingAssembly()) as Model; Children.AddRange(ModelFromResource.Children); CopyPropertiesFrom(ModelFromResource); SetNotVisible(ModelFromResource); } } } }
/// <summary>Converts the paddock XML.</summary> /// <param name="paddock">The paddock.</param> /// <exception cref="System.Exception">Bad paddock name: + name</exception> private static Paddock CreateSimulationSpec(XmlNode paddock, string baseFolder) { Paddock simulation = new Paddock(); string name = XmlUtilities.NameAttr(paddock); string delimiter = "^"; int posCaret = name.IndexOf(delimiter); if (posCaret == -1) { throw new Exception("Bad paddock name: " + name); } string remainder = StringUtilities.SplitOffAfterDelimiter(ref name, delimiter); string growerName; string paddockName = StringUtilities.SplitOffAfterDelimiter(ref remainder, delimiter); if (paddockName == string.Empty) { growerName = name; paddockName = remainder; } else { growerName = remainder; } // Give the paddock a name. string fullName = string.Format("{0}^{1}^{2}", GetDate(paddock, "SowDateFull").Year, growerName, paddockName); simulation.Name = fullName; // Set the report date. simulation.NowDate = GetDate(paddock.ParentNode, "TodayDateFull"); if (simulation.NowDate == DateTime.MinValue) { simulation.NowDate = DateTime.Now; } // Store any rainfall data in the simulation. string rainfallSource = GetString(paddock, "RainfallSource"); if (rainfallSource != "Weather station") { string rainFileName = GetString(paddock, "RainfallFilename"); if (rainFileName != string.Empty) { string fullFileName = Path.Combine(baseFolder, rainFileName); if (!File.Exists(fullFileName)) { throw new Exception("Cannot find file: " + fullFileName); } simulation.ObservedData = ApsimTextFile.ToTable(fullFileName); simulation.ObservedData.TableName = rainfallSource; if (simulation.ObservedData.Rows.Count == 0) { simulation.ObservedData = null; } } } // Set the reset dates simulation.SoilWaterSampleDate = GetDate(paddock, "ResetDateFull"); simulation.SoilNitrogenSampleDate = GetDate(paddock, "SoilNitrogenSampleDateFull"); simulation.StationNumber = GetInteger(paddock, "StationNumber"); simulation.StationName = GetString(paddock, "StationName"); // Create a sowing management Sow sowing = new Sow(); simulation.Management.Add(sowing); sowing.Date = GetDate(paddock, "SowDateFull"); sowing.EmergenceDate = GetDate(paddock, "EmergenceDateFull"); sowing.Crop = GetString(paddock, "Crop"); sowing.Cultivar = GetString(paddock, "Cultivar"); sowing.SkipRow = GetString(paddock, "SkipRow"); sowing.SowingDensity = GetInteger(paddock, "SowingDensity"); sowing.MaxRootDepth = GetInteger(paddock, "MaxRootDepth") * 10; // cm to mm sowing.BedWidth = GetInteger(paddock, "BedWidth"); sowing.BedRowSpacing = GetDouble(paddock, "BedRowSpacing"); // Make sure we have a stubbletype simulation.StubbleType = GetString(paddock, "StubbleType"); if (simulation.StubbleType == string.Empty || simulation.StubbleType == "None") { simulation.StubbleType = "Wheat"; } simulation.StubbleMass = GetDouble(paddock, "StubbleMass"); simulation.Slope = GetDouble(paddock, "Slope"); simulation.SlopeLength = GetDouble(paddock, "SlopeLength"); simulation.UseEC = GetBoolean(paddock, "UseEC"); // Fertilise nodes. List <XmlNode> fertiliserNodes = XmlUtilities.ChildNodes(paddock, "Fertilise"); for (int f = 0; f < fertiliserNodes.Count; f++) { Fertilise fertilise = new Fertilise(); simulation.Management.Add(fertilise); fertilise.Date = GetDate(fertiliserNodes[f], "FertDateFull"); fertilise.Amount = GetDouble(fertiliserNodes[f], "FertAmount"); } // Irrigate nodes. List <XmlNode> irrigateNodes = XmlUtilities.ChildNodes(paddock, "Irrigate"); for (int i = 0; i < irrigateNodes.Count; i++) { Irrigate irrigate = new Irrigate(); simulation.Management.Add(irrigate); irrigate.Date = GetDate(irrigateNodes[i], "IrrigateDateFull"); irrigate.Amount = GetDouble(irrigateNodes[i], "IrrigateAmount"); irrigate.Efficiency = GetDouble(irrigateNodes[i], "IrrigateEfficiency"); } // Tillage nodes. foreach (XmlNode tillageNode in XmlUtilities.ChildNodes(paddock, "Tillage")) { Tillage tillage = new Tillage(); simulation.Management.Add(tillage); tillage.Date = GetDate(tillageNode, "TillageDateFull"); string disturbance = GetString(tillageNode, "Disturbance"); if (disturbance == "Low") { tillage.Disturbance = Tillage.DisturbanceEnum.Low; } else if (disturbance == "Medium") { tillage.Disturbance = Tillage.DisturbanceEnum.Medium; } else { tillage.Disturbance = Tillage.DisturbanceEnum.High; } } // Stubble removed nodes. foreach (XmlNode stubbleRemovedNode in XmlUtilities.ChildNodes(paddock, "StubbleRemoved")) { StubbleRemoved stubbleRemoved = new StubbleRemoved(); simulation.Management.Add(stubbleRemoved); stubbleRemoved.Date = GetDate(stubbleRemovedNode, "StubbleRemovedDateFull"); stubbleRemoved.Percent = GetDouble(stubbleRemovedNode, "StubbleRemovedAmount"); } // Look for a soil node. XmlNode soilNode = XmlUtilities.FindByType(paddock, "Soil"); if (soilNode != null) { string testValue = XmlUtilities.Value(soilNode, "Water/Layer/Thickness"); if (testValue != string.Empty) { // old format. soilNode = ConvertSoilNode.Upgrade(soilNode); } } // Fix up soil sample variables. Sample sample1 = new Sample { Name = "Sample1", Thickness = GetArray(paddock, "Sample1Thickness"), SW = GetArray(paddock, "SW") }; if (sample1.SW == null) { // Really old way of doing samples - they are stored under soil. List <XmlNode> sampleNodes = XmlUtilities.ChildNodes(soilNode, "Sample"); if (sampleNodes.Count > 0) { sample1 = XmlUtilities.Deserialise(sampleNodes[0], typeof(Sample)) as Sample; } } else { sample1.NO3 = GetArray(paddock, "NO3"); sample1.NH4 = GetArray(paddock, "NH4"); } Sample sample2 = null; double[] sample2Thickness = GetArray(paddock, "Sample2Thickness"); if (sample2Thickness == null) { // Really old way of doing samples - they are stored under soil. List <XmlNode> sampleNodes = XmlUtilities.ChildNodes(soilNode, "Sample"); if (sampleNodes.Count > 1) { sample2 = XmlUtilities.Deserialise(sampleNodes[1], typeof(Sample)) as Sample; } } else { sample2 = sample1; if (!MathUtilities.AreEqual(sample2Thickness, sample1.Thickness)) { sample2 = new Sample { Name = "Sample2" }; } sample2.OC = GetArray(paddock, "OC"); sample2.EC = GetArray(paddock, "EC"); sample2.PH = GetArray(paddock, "PH"); sample2.CL = GetArray(paddock, "CL"); sample2.OCUnits = SoilOrganicMatter.OCUnitsEnum.WalkleyBlack; sample2.PHUnits = Analysis.PHUnitsEnum.CaCl2; } // Make sure we have NH4 values. if (sample1.NH4 == null && sample1.NO3 != null) { string[] defaultValues = StringUtilities.CreateStringArray("0.1", sample1.NO3.Length); sample1.NH4 = MathUtilities.StringsToDoubles(defaultValues); } RemoveNullFieldsFromSample(sample1); if (sample2 != null) { RemoveNullFieldsFromSample(sample2); } // Fix up <WaterFormat> string waterFormatString = GetString(paddock, "WaterFormat"); if (waterFormatString.Contains("Gravimetric")) { sample1.SWUnits = Sample.SWUnitsEnum.Gravimetric; } else { sample1.SWUnits = Sample.SWUnitsEnum.Volumetric; } if (MathUtilities.ValuesInArray(sample1.Thickness)) { simulation.Samples.Add(sample1); } if (sample2 != null && MathUtilities.ValuesInArray(sample2.Thickness) && sample2 != sample1) { simulation.Samples.Add(sample2); } // Check for InitTotalWater & InitTotalNitrogen simulation.InitTotalWater = GetDouble(paddock, "InitTotalWater"); simulation.InitTotalNitrogen = GetDouble(paddock, "InitTotalNitrogen"); // Check to see if we need to convert the soil structure. simulation.SoilPath = GetString(paddock, "SoilName"); if (soilNode != null) { // See if there is a 'SWUnits' value. If found then copy it into // <WaterFormat> string waterFormat = XmlUtilities.Value(paddock, "WaterFormat"); if (waterFormat == string.Empty) { int sampleNumber = 0; foreach (XmlNode soilSample in XmlUtilities.ChildNodes(soilNode, "Sample")) { string swUnits = XmlUtilities.Value(soilSample, "SWUnits"); if (swUnits != string.Empty) { XmlUtilities.SetValue(paddock, "WaterFormat", swUnits); } // Also make sure we don't have 2 samples with the same name. string sampleName = "Sample" + (sampleNumber + 1).ToString(); XmlUtilities.SetAttribute(soilSample, "name", sampleName); sampleNumber++; } } simulation.Soil = SoilUtilities.FromXML(soilNode.OuterXml); if (simulation.Samples != null) { simulation.Soil.Samples = simulation.Samples; } } return(simulation); }
/// <summary> /// Pastes the contents of the clipboard. /// </summary> /// <param name="xml">The XML document text</param> /// <param name="parentPath">Path to the parent</param> public void Add(string xml, string parentPath) { try { XmlDocument document = new XmlDocument(); try { document.LoadXml(xml); } catch (XmlException) { MainPresenter.ShowMessage("Invalid XML. Are you sure you're trying to paste an APSIM model?", Simulation.ErrorLevel.Error); } object newModel = XmlUtilities.Deserialise(document.DocumentElement, this.ApsimXFile.GetType().Assembly); // See if the presenter is happy with this model being added. Model parentModel = Apsim.Get(this.ApsimXFile, parentPath) as Model; AllowDropArgs allowDropArgs = new AllowDropArgs(); allowDropArgs.NodePath = parentPath; allowDropArgs.DragObject = new DragObject() { NodePath = null, ModelType = newModel.GetType(), Xml = this.GetClipboardText() }; this.OnAllowDrop(null, allowDropArgs); // If it is happy then issue an AddModelCommand. if (allowDropArgs.Allow) { // If the model xml is a soil object then try and convert from old // APSIM format to new. if (document.DocumentElement.Name == "Soil" && XmlUtilities.Attribute(document.DocumentElement, "Name") != string.Empty) { XmlDocument newDoc = new XmlDocument(); newDoc.AppendChild(newDoc.CreateElement("D")); APSIMImporter importer = new APSIMImporter(); importer.ImportSoil(document.DocumentElement, newDoc.DocumentElement, newDoc.DocumentElement); XmlNode soilNode = XmlUtilities.FindByType(newDoc.DocumentElement, "Soil"); if (soilNode != null && XmlUtilities.FindByType(soilNode, "Sample") == null && XmlUtilities.FindByType(soilNode, "InitialWater") == null) { // Add in an initial water and initial conditions models. XmlNode initialWater = soilNode.AppendChild(soilNode.OwnerDocument.CreateElement("InitialWater")); XmlUtilities.SetValue(initialWater, "Name", "Initial water"); XmlUtilities.SetValue(initialWater, "PercentMethod", "FilledFromTop"); XmlUtilities.SetValue(initialWater, "FractionFull", "1"); XmlUtilities.SetValue(initialWater, "DepthWetSoil", "NaN"); XmlNode initialConditions = soilNode.AppendChild(soilNode.OwnerDocument.CreateElement("Sample")); XmlUtilities.SetValue(initialConditions, "Name", "Initial conditions"); XmlUtilities.SetValue(initialConditions, "Thickness/double", "1800"); XmlUtilities.SetValue(initialConditions, "NO3/double", "10"); XmlUtilities.SetValue(initialConditions, "NH4/double", "1"); XmlUtilities.SetValue(initialConditions, "NO3Units", "kgha"); XmlUtilities.SetValue(initialConditions, "NH4Units", "kgha"); XmlUtilities.SetValue(initialConditions, "SWUnits", "Volumetric"); } document.LoadXml(newDoc.DocumentElement.InnerXml); } IModel child = XmlUtilities.Deserialise(document.DocumentElement, this.ApsimXFile.GetType().Assembly) as IModel; AddModelCommand command = new AddModelCommand(parentModel, document.DocumentElement, this.GetNodeDescription(child), this.view); this.CommandHistory.Add(command, true); } } catch (Exception exception) { this.MainPresenter.ShowMessage(exception.Message, Simulation.ErrorLevel.Error); } }
/// <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; }
/// <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()); } }