/// <summary> /// Constructor /// </summary> /// <param name="simulations">The top level simulations object.</param> /// <param name="simulation">The simulation object clicked on.</param> /// <param name="presenter">The explorer presenter.</param> public RunCommand(Simulations simulations, Model simulation, ExplorerPresenter presenter) { this.simulations = simulations; this.modelClicked = simulation; this.explorerPresenter = presenter; jobManager = new JobManager(); jobManager.AllJobsCompleted += OnComplete; }
/// <summary>Write the specified simulation set to the specified filename</summary> /// <param name="model">The model to write.</param> /// <param name="fileName">Name of the file.</param> public void WriteFile(Simulations model, string fileName) { //string tempFileName = Path.Combine(Path.GetTempPath(), Path.GetFileName(fileName)); //StreamWriter writer = new StreamWriter(tempFileName); //writer.Write(WriteXML(model)); //writer.Close(); //// If we get this far without an exception then copy the tempfilename over our filename, //// creating a backup (.bak) in the process. //string bakFileName = fileName + ".bak"; //File.Delete(bakFileName); //if (File.Exists(fileName)) // File.Move(fileName, bakFileName); //File.Move(tempFileName, fileName); }
/// <summary>Determine the list of jobs to run</summary> private void FindListOfModelsToRun() { // Get a list of all models we're going to run. modelsToRun = Apsim.ChildrenRecursively(relativeTo, typeof(ISimulationGenerator)).Cast <ISimulationGenerator>().ToList(); if (relativeTo is ISimulationGenerator) { modelsToRun.Add(relativeTo as ISimulationGenerator); } // For each model, resolve any links. Simulations sims = Apsim.Parent(relativeTo, typeof(Simulations)) as Simulations; modelsToRun.ForEach(model => sims.Links.Resolve(model)); // For each model, get a list of simulation names. SimulationNamesBeingRun = new List <string>(); modelsToRun.ForEach(model => SimulationNamesBeingRun.AddRange(model.GetSimulationNames(false))); }
/// <summary> /// Clears the cached scoping values for the simulation /// We need to do this when models have been added or deleted, /// as the cache will then be incorrect /// </summary> /// <param name="model"></param> public static void ClearCaches(IModel model) { Simulation simulation = model as Simulation ?? model.FindAncestor<Simulation>(); if (simulation != null && simulation.Scope != null) { simulation.ClearCaches(); } else { // If the model didn't have a Simulation object as an ancestor, then it's likely to // have a Simulations object as one. If so, the Simulations links may need to be updated. Simulations simulations = model.FindAncestor<Simulations>(); if (simulations != null) { simulations.ClearLinks(); } } }
/// <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; 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>Gets the next job to run</summary> public Simulation NextSimulationToRun() { 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; simulationEngine.MakeSubstitutions(simulationToRun); } return(simulationToRun); }
/// <summary>Gets the next job to run</summary> public IRunnable NextJobToRun() { if (Parent is IJobGenerator || 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; simulationEngine.MakeSubstitutions(simulationToRun); } return(new RunSimulation(simulationToRun, doClone: false)); }
/// <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); }
/// <summary>Constructor</summary> /// <param name="model">The model to run.</param> /// <param name="simulations">simulations object.</param> public RunOrganiser(Simulations simulations, Model model) { this.simulations = simulations; this.model = model; }
/// <summary>Runs the specified simulations.</summary> /// <param name="model">Simulations to run.</param> /// <param name="simulations">Simulations model.</param> /// <param name="runTests">Run the test nodes?</param> /// <returns>A runnable job or null if nothing to run.</returns> public static JobManager.IRunnable ForSimulations(Simulations simulations, Model model, bool runTests) { return new RunOrganiser(simulations, model, runTests); }
/// <summary>Remove all simulations from the database that don't exist in 'simulationsToKeep'</summary> /// <param name="simulationsToKeep">The simulations to keep.</param> /// <param name="simulationNamesToBeRun">The simulation names about to be run.</param> public void RemoveUnwantedSimulations(Simulations simulationsToKeep, List<string> simulationNamesToBeRun) { Open(forWriting: true); string[] simulationNamesToKeep = simulationsToKeep.FindAllSimulationNames(); // Tell SQLite that we're beginning a transaction. Connection.ExecuteNonQuery("BEGIN"); try { // Make sure that the list of simulations in 'simulationsToKeep' are in the // Simulations table. string[] simulationNames = this.SimulationNames; string sql = string.Empty; foreach (string simulationNameToKeep in simulationNamesToKeep) { if (!StringUtilities.Contains(simulationNames, simulationNameToKeep)) { if (sql != string.Empty) sql += "),("; sql += "'" + simulationNameToKeep + "'"; } } if (sql != string.Empty) RunQueryWithNoReturnData("INSERT INTO [Simulations] (Name) VALUES (" + sql + ")"); // Get a list of simulation IDs that we are to delete. List<int> idsToDelete = new List<int>(); foreach (string simulationNameInDB in SimulationNames) if (!simulationNamesToKeep.Contains(simulationNameInDB)) { idsToDelete.Add(GetSimulationID(simulationNameInDB)); } // create an SQL WHERE clause with all IDs string idString = ""; for (int i = 0; i < idsToDelete.Count; i++) { if (i > 0) idString += " OR "; idString += "ID = " + idsToDelete[i].ToString(); } if (idString != string.Empty) RunQueryWithNoReturnData("DELETE FROM Simulations WHERE " + idString); // Now add to IDs to delete the simulations IDs of the simulations we are // about to run i.e. remove the rows that we are about to regenerate. idsToDelete.Clear(); foreach (string simulationNameToBeRun in simulationNamesToBeRun) idsToDelete.Add(GetSimulationID(simulationNameToBeRun)); idString = ""; for (int i = 0; i < idsToDelete.Count; i++) { if (i > 0) idString += " OR "; idString += "SimulationID = " + idsToDelete[i].ToString(); } foreach (string tableName in TableNames) { // delete this simulation RunQueryWithNoReturnData("DELETE FROM " + tableName + " WHERE " + idString); } } finally { // Tell SQLite that we're ending a transaction. Connection.ExecuteNonQuery("END"); } }
/// <summary>Make model substitutions if necessary.</summary> /// <param name="simulations">The simulations to make substitutions in.</param> /// <param name="parentSimulations">Parent simulations object</param> public static void MakeSubstitutions(Simulations parentSimulations, List<Simulation> simulations) { IModel replacements = Apsim.Child(parentSimulations, "Replacements"); if (replacements != null) { foreach (IModel replacement in replacements.Children) { foreach (Simulation simulation in simulations) { foreach (IModel match in Apsim.FindAll(simulation, replacement.GetType())) { if (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); CallOnLoaded(newModel); } } } } } }
/// <summary>Runs the specified simulations.</summary> /// <param name="model">Simulations to run.</param> /// <param name="simulations">Simulations model.</param> /// <param name="runTests">Run the test nodes?</param> /// <returns>A runnable job or null if nothing to run.</returns> public static RunOrganiser ForSimulations(Simulations simulations, IModel model, bool runTests) { return(new RunOrganiser(simulations, model, runTests)); }
/// <summary>Create a new tab.</summary> /// <param name="name">Name of the simulation</param> /// <param name="simulations">The simulations object to add to tab.</param> /// <param name="onLeftTabControl">If true a tab will be added to the left hand tab control.</param> private ExplorerPresenter CreateNewTab(string name, Simulations simulations, bool onLeftTabControl) { ExplorerView explorerView = new ExplorerView(null); ExplorerPresenter presenter = new ExplorerPresenter(this); if (onLeftTabControl) presenters1.Add(presenter); else presenters2.Add(presenter); XmlDocument doc = new XmlDocument(); presenter.Attach(simulations, explorerView, null); this.view.AddTab(name, new Gtk.Image(null, "ApsimNG.Resources.apsim logo32.png"), explorerView.MainWidget, onLeftTabControl); // restore the simulation tree width on the form if (simulations.ExplorerWidth == 0) presenter.TreeWidth = 250; else presenter.TreeWidth = simulations.ExplorerWidth; return presenter; }
public void Initialise() { string tempFolder = Path.Combine(Path.GetTempPath(), "UnitTests"); Directory.CreateDirectory(tempFolder); Directory.SetCurrentDirectory(tempFolder); FileStream oldfile = new FileStream("Continuous_Wheat.apsim", FileMode.Create); oldfile.Write(UnitTests.Properties.Resources.Continuous_Wheat, 0, UnitTests.Properties.Resources.Continuous_Wheat.Length); oldfile.Close(); FileStream f = new FileStream("Test.apsimx", FileMode.Create); f.Write(UnitTests.Properties.Resources.TestFile, 0, UnitTests.Properties.Resources.TestFile.Length); f.Close(); FileStream w = new FileStream("Goondiwindi.met", FileMode.Create); w.Write(UnitTests.Properties.Resources.Goondiwindi, 0, UnitTests.Properties.Resources.Goondiwindi.Length); w.Close(); this.simulations = Simulations.Read("Test.apsimx"); string sqliteSourceFileName = this.FindSqlite3DLL(); string sqliteFileName = Path.Combine(Directory.GetCurrentDirectory(), "sqlite3.dll"); if (!File.Exists(sqliteFileName)) { File.Copy(sqliteSourceFileName, sqliteFileName); } this.simulation = this.simulations.Children[0] as Simulation; this.simulation.StartRun(); }
/// <summary> /// Constructor /// </summary> /// <param name="sims"></param> public Checkpoints(Simulations sims) { simulations = sims; }
/// <summary>Remove all simulations from the database that don't exist in 'simulationsToKeep'</summary> /// <param name="simulationsToKeep">The simulations to keep.</param> public void RemoveUnwantedSimulations(Simulations simulationsToKeep) { Open(forWriting: true); string[] simulationNamesToKeep = simulationsToKeep.FindAllSimulationNames(); // Make sure that the list of simulations in 'simulationsToKeep' are in the // Simulations table. string[] simulationNames = this.SimulationNames; foreach (string simulationNameToKeep in simulationNamesToKeep) { if (!StringUtilities.Contains(simulationNames, simulationNameToKeep)) { RunQueryWithNoReturnData("INSERT INTO [Simulations] (Name) VALUES ('" + simulationNameToKeep + "')"); } } // Get a list of simulation IDs that we are to delete. List<int> idsToDelete = new List<int>(); foreach (string simulationNameInDB in SimulationNames) if (!simulationNamesToKeep.Contains(simulationNameInDB)) { idsToDelete.Add(GetSimulationID(simulationNameInDB)); } if (idsToDelete.Count == 0) return; // create an SQL WHERE clause with all IDs string idString = ""; for (int i = 0; i < idsToDelete.Count; i++) { if (i > 0) idString += " OR "; idString += "ID = " + idsToDelete[i].ToString(); } RunQueryWithNoReturnData("DELETE FROM Simulations WHERE " + idString); idString = ""; for (int i = 0; i < idsToDelete.Count; i++) { if (i > 0) idString += " OR "; idString += "SimulationID = " + idsToDelete[i].ToString(); } foreach (string tableName in TableNames) { // delete this simulation RunQueryWithNoReturnData("DELETE FROM " + tableName + " WHERE " + idString); } }
/// <summary>Constructor</summary> /// <param name="model">The simulations object to save</param> public SaveApsimJob(Simulations simulations) { this.simulations = simulations; }
/// <summary>Runs the specified simulations.</summary> /// <param name="model">Simulations to run.</param> /// <param name="simulations">Simulations model.</param> /// <returns>A runnable job or null if nothing to run.</returns> public static JobManager.IRunnable ForSimulations(Simulations simulations, Model model) { return(new RunOrganiser(simulations, model)); }
/// <summary>Run the jobs.</summary> /// <param name="sender"></param> /// <param name="e"></param> public void Run(object sender, System.ComponentModel.DoWorkEventArgs e) { JobManager jobManager = e.Argument as JobManager; List <JobManager.IRunnable> jobs = new List <JobManager.IRunnable>(); DataStore store = Apsim.Child(simulations, typeof(DataStore)) as DataStore; Simulation[] simulationsToRun; if (model is Simulations) { // As we are going to run all simulations, we can delete all tables in the DataStore. This // will clean up order of columns in the tables and removed unused ones. store.DeleteAllTables(); simulationsToRun = Simulations.FindAllSimulationsToRun(simulations); } else { store.RemoveUnwantedSimulations(simulations); if (model is Simulation) { if (model.Parent == null) { // model is already a cloned simulation, probably from user running a single // simulation from an experiment. simulationsToRun = new Simulation[1] { model as Simulation }; } else { simulationsToRun = new Simulation[1] { Apsim.Clone(model as Simulation) as Simulation }; Simulations.CallOnLoaded(simulationsToRun[0]); } } else { simulationsToRun = Simulations.FindAllSimulationsToRun(model); } } store.Disconnect(); simulations.MakeSubstitutions(simulationsToRun); foreach (Simulation simulation in simulationsToRun) { jobs.Add(simulation); jobManager.AddJob(simulation); } // Wait until all our jobs are all finished. while (AreSomeJobsRunning(jobs)) { Thread.Sleep(200); } // Collect all error messages. foreach (Simulation job in simulationsToRun) { if (job.ErrorMessage != null) { ErrorMessage += job.ErrorMessage + Environment.NewLine; } } // <summary>Call the all completed event in all models.</summary> object[] args = new object[] { this, new EventArgs() }; foreach (Model childModel in Apsim.ChildrenRecursively(simulations)) { try { Apsim.CallEventHandler(childModel, "AllCompleted", args); } catch (Exception err) { ErrorMessage += "Error in file: " + simulations.FileName + Environment.NewLine; ErrorMessage += err.ToString() + Environment.NewLine + Environment.NewLine; } } if (ErrorMessage != null) { throw new Exception(ErrorMessage); } }