/// <summary>Make model substitutions if necessary.</summary> /// <param name="model">The model to make substitutions in.</param> public void MakeSubstitutions(IModel model) { IModel replacements = Apsim.Child(this, "Replacements"); if (replacements != null) { foreach (IModel replacement in replacements.Children) { foreach (IModel match in Apsim.FindAll(model)) { if (!(match is Simulation) && match.Name.Equals(replacement.Name, StringComparison.InvariantCultureIgnoreCase)) { // Do replacement. IModel newModel = Apsim.Clone(replacement); int index = match.Parent.Children.IndexOf(match as Model); match.Parent.Children.Insert(index, newModel as Model); newModel.Parent = match.Parent; match.Parent.Children.Remove(match as Model); // If we're doing substitutions for an entire Simulation, // the Loaded event will be issued later. Otherwise, issue one now if (!(model is Simulation)) { Events events = new Events(newModel); LoadedEventArgs loadedArgs = new LoadedEventArgs(); events.Publish("Loaded", new object[] { newModel, loadedArgs }); } } } } } }
/// <summary> /// Create a simulations model /// </summary> /// <param name="children">The child models</param> public static Simulations Create(IEnumerable <IModel> children) { Simulations newSimulations = new Core.Simulations(); newSimulations.Children.AddRange(children.Cast <Model>()); // Call the OnDeserialised method in each model. Events events = new Core.Events(newSimulations); object[] args = new object[] { true }; events.Publish("Deserialised", args); // Parent all models. newSimulations.Parent = null; Apsim.ParentAllChildren(newSimulations); // Call OnLoaded in all models. LoadedEventArgs loadedArgs = new LoadedEventArgs(); events.Publish("Loaded", new object[] { newSimulations, loadedArgs }); if (loadedArgs.errors.Count > 0) { newSimulations.LoadErrors = new List <Exception>(); newSimulations.LoadErrors.AddRange(loadedArgs.errors); } return(newSimulations); }
/// <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); }
/// <summary> /// Perform model substitutions, if necessary, then issue a "Loaded" event /// </summary> public void MakeSubsAndLoad(Simulation simulation) { MakeSubstitutions(simulation); // Call OnLoaded in all models. Events events = new Events(simulation); LoadedEventArgs loadedArgs = new LoadedEventArgs(); events.Publish("Loaded", new object[] { simulation, loadedArgs }); }
/// <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="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. ApsimFile.Converter.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); 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); } } else { throw new Exception("Simulations.Read() failed. Invalid simulation file.\n"); } return(simulations); }
/// <summary>Gets the next job to run</summary> public Simulation NextSimulationToRun(bool doFullFactorial = true) { if (Parent is ISimulationGenerator || hasRun) { return(null); } hasRun = true; Simulation simulationToRun; if (this.Parent == null) { simulationToRun = this; } else { Simulations simulationEngine = Apsim.Parent(this, typeof(Simulations)) as Simulations; simulationToRun = Apsim.Clone(this) as Simulation; // We are breaking.NET naming rules with our manager scripts.All our manager scripts are class // Script in the Models namespace.This is OK until we do a clone(binary serialise/deserialise). // When this happens, the serialisation engine seems to choose the first assembly it can find // that has the 'right' code.It seems that if the script c# is close to an existing assembly then // it chooses that assembly. In the attached .apsimx, it chooses the wrong temporary assembly for // SowingRule2. It chooses SowingRule assembly even though the script for the 2 manager files is // different. I'm not sure how to fix this yet. A brute force way is to recompile all manager // scripts after cloning. // https://github.com/APSIMInitiative/ApsimX/issues/2603 Events events = new Events(simulationToRun); LoadedEventArgs loadedArgs = new LoadedEventArgs(); events.Publish("Loaded", new object[] { simulationToRun, loadedArgs }); simulationEngine.MakeSubstitutions(simulationToRun); } return(simulationToRun); }