/// <summary> /// Run all child simulations with the given optimal values, /// and store the results in the given checkpoint name. /// </summary> /// <param name="checkpointName">Name of the checkpoint.</param> /// <param name="optimalValues">Changes to be applied to the models.</param> /// <param name="fileName">Name of the apsimx file run by the optimiser.</param> private void RunSimsWithOptimalValues(string fileName, string checkpointName, IEnumerable <CompositeFactor> optimalValues) { IDataStore storage = FindInScope <IDataStore>(); // First, clone the simulations (we don't want to change the values // of the parameters in the original file). Simulations clonedSims = FileFormat.ReadFromFile <Simulations>(fileName, out List <Exception> errors); if (errors != null && errors.Count > 0) { throw errors[0]; } // Apply the optimal values to the cloned simulations. clonedSims = EditFile.ApplyChanges(clonedSims, optimalValues); DataStore clonedStorage = clonedSims.FindChild <DataStore>(); clonedStorage.Close(); clonedStorage.CustomFileName = storage.FileName; clonedStorage.Open(); // Run the child models of the cloned CroptimizR. Runner runner = new Runner(clonedSims); errors = runner.Run(); if (errors != null && errors.Count > 0) { throw errors[0]; } storage.Writer.AddCheckpoint(checkpointName); storage.Writer.SetCheckpointShowGraphs(checkpointName, true); }
/// <summary> /// Attach inherited class additional presenters is needed /// </summary> public void AttachExtraPresenters(CLEMPresenter clemPresenter) { //UI Results try { ActivityLedgerGridView ledgerView = new ActivityLedgerGridView(clemPresenter.View as ViewBase); ReportView rv = new ReportView(clemPresenter.View as ViewBase); ViewBase reportView = new ViewBase(rv, "ApsimNG.Resources.Glade.DataStoreView.glade"); Model report = clemPresenter.Model as Model; Simulations simulations = report.FindAncestor <Simulations>(); if (simulations != null) { dataStore = simulations.FindChild <IDataStore>(); } DataStorePresenter dataStorePresenter = new DataStorePresenter(); ActivityLedgerGridPresenter activityGridPresenter = new ActivityLedgerGridPresenter(); Simulation simulation = report.FindAncestor <Simulation>(); Zone paddock = report.FindAncestor <Zone>(); if (paddock != null) { dataStorePresenter.ZoneFilter = paddock; } if (simulation != null) { if (simulation.Parent is Experiment) { dataStorePresenter.ExperimentFilter = simulation.Parent as Experiment; } else { dataStorePresenter.SimulationFilter = simulation; } } dataStorePresenter.Attach(dataStore, reportView, clemPresenter.ExplorerPresenter); activityGridPresenter.CreateHtml = (clemPresenter.Model as ReportActivitiesPerformed).CreateHTML; activityGridPresenter.ModelReport = report as Report; activityGridPresenter.ModelName = report.Name; activityGridPresenter.SimulationName = simulation.Name; activityGridPresenter.ZoneName = paddock.Name; activityGridPresenter.Attach(dataStore, ledgerView, clemPresenter.ExplorerPresenter); dataStorePresenter.tableDropDown.SelectedValue = report.Name; (clemPresenter.View as CLEMView).AddTabView("Display", ledgerView); clemPresenter.PresenterList.Add("Display", activityGridPresenter); (clemPresenter.View as CLEMView).AddTabView("Data", reportView); clemPresenter.PresenterList.Add("Data", dataStorePresenter); } catch (Exception err) { this.explorerPresenter.MainPresenter.ShowError(err); } }
/// <summary> /// Create an <see cref="ApsimServer" /> instance. /// </summary> /// <param name="file">.apsimx file to be run.</param> public ApsimServer(GlobalServerOptions options) { this.options = options; sims = FileFormat.ReadFromFile <Simulations>(options.File, e => throw e, false); sims.FindChild <Models.Storage.DataStore>().UseInMemoryDB = true; runner = new Runner(sims); jobRunner = new ServerJobRunner(); runner.Use(jobRunner); }
public void EnsureDataIsNotWrittenTwice() { Simulations sims = Utilities.GetRunnableSim(); Simulation sim = sims.FindChild <Simulation>(); Summary summary = sim.FindChild <Summary>(); // Write 2 messages to the DB during StartOfSimulation. string message1 = "message 1"; string message2 = "A slightly longer message"; string message3 = "Written in OnCompleted"; SummaryWriter writer = new SummaryWriter(); writer.AddMessage("[Clock].StartOfSimulation", message1); writer.AddMessage("[Clock].StartOfSimulation", message2); writer.AddMessage("[Simulation].Completed", message3); Structure.Add(writer, sim); Runner runner = new Runner(sims); List <Exception> errors = runner.Run(); if (errors != null && errors.Count > 0) { throw errors[0]; } IDataStore storage = sims.FindChild <IDataStore>(); DataTable messages = storage.Reader.GetData("_Messages"); // Clock will write its own "Simulation terminated normally" message. Assert.AreEqual(5, messages.Rows.Count); // The first row will be a warning caused by the lack of a // microclimate model. Assert.AreEqual(message1, messages.Rows[1][6]); Assert.AreEqual(message2, messages.Rows[2][6]); // The fourth row should not be written by SummaryWriter. Assert.AreNotEqual(writer.Name, messages.Rows[3]["ComponentName"]); // The fifth will be the "Simulation terminated normally" message. Assert.AreEqual(message3, messages.Rows[4][6]); }
/// <summary> /// Attach the model (report) and the view (IReportView) /// </summary> /// <param name="model">The report model object</param> /// <param name="view">The view object</param> /// <param name="explorerPresenter">The explorer presenter</param> public void Attach(object model, object view, ExplorerPresenter explorerPresenter) { this.report = model as Report; this.explorerPresenter = explorerPresenter; this.view = view as IReportView; this.intellisense = new IntellisensePresenter(view as ViewBase); intellisense.ItemSelected += OnIntellisenseItemSelected; this.view.VariableList.Mode = EditorType.Report; this.view.EventList.Mode = EditorType.Report; this.view.VariableList.Lines = report.VariableNames; this.view.EventList.Lines = report.EventNames; this.view.GroupByEdit.Text = report.GroupByVariableName; this.view.VariableList.ContextItemsNeeded += OnNeedVariableNames; this.view.EventList.ContextItemsNeeded += OnNeedEventNames; this.view.GroupByEdit.IntellisenseItemsNeeded += OnNeedVariableNames; this.view.VariableList.TextHasChangedByUser += OnVariableNamesChanged; this.view.EventList.TextHasChangedByUser += OnEventNamesChanged; this.view.GroupByEdit.Changed += OnGroupByChanged; this.view.SplitterChanged += OnSplitterChanged; this.view.SplitterPosition = Configuration.Settings.ReportSplitterPosition; this.explorerPresenter.CommandHistory.ModelChanged += OnModelChanged; this.view.TabChanged += OnChangeTab; Simulations simulations = report.FindAncestor <Simulations>(); if (simulations != null) { dataStore = simulations.FindChild <IDataStore>(); } //// TBI this.view.VariableList.SetSyntaxHighlighter("Report"); dataStorePresenter = new DataStorePresenter(); Simulation simulation = report.FindAncestor <Simulation>(); Experiment experiment = report.FindAncestor <Experiment>(); Zone paddock = report.FindAncestor <Zone>(); // Only show data which is in scope of this report. // E.g. data from this zone and either experiment (if applicable) or simulation. if (paddock != null) { dataStorePresenter.ZoneFilter = paddock; } if (experiment != null) { dataStorePresenter.ExperimentFilter = experiment; } else if (simulation != null) { dataStorePresenter.SimulationFilter = simulation; } dataStorePresenter.Attach(dataStore, this.view.DataStoreView, explorerPresenter); this.view.TabIndex = this.report.ActiveTabIndex; }
/// <inheritdoc/> public void AttachExtraPresenters(CLEMPresenter clemPresenter) { try { bool parentOfReport = false; Report report = clemPresenter.Model as Report; if (report is null) { report = clemPresenter.Model.FindChild <Report>(); parentOfReport = true; } rv = new ReportView(clemPresenter.View as ViewBase); ViewBase reportView = new ViewBase(rv, "ApsimNG.Resources.Glade.DataStoreView.glade"); dataStorePresenter = new DataStorePresenter(new string[] { (parentOfReport)? (clemPresenter.Model as IModel).Name:report.Name }); Simulations simulations = report.FindAncestor <Simulations>(); if (simulations != null) { dataStore = simulations.FindChild <IDataStore>(); } Simulation simulation = report.FindAncestor <Simulation>(); Experiment experiment = report.FindAncestor <Experiment>(); Zone paddock = report.FindAncestor <Zone>(); IModel zoneAnscestor = report.FindAncestor <Zone>(); // Only show data which is in scope of this report. // E.g. data from this zone and either experiment (if applicable) or simulation. if (paddock != null) { dataStorePresenter.ZoneFilter = paddock; } if (zoneAnscestor is null & experiment != null) { // allows the inner reports of the base simulation to be displayed // when an experiment is being undertaken // otherwise reports are considered child of experiment and will only display experiment results. dataStorePresenter.ExperimentFilter = experiment; } else if (simulation != null) { dataStorePresenter.SimulationFilter = simulation; } dataStorePresenter.Attach(dataStore, reportView, clemPresenter.ExplorerPresenter); // Attach the view to display data clem = clemPresenter.View as CLEMView; clem.AddTabView("Data", reportView); clemPresenter.PresenterList.Add("Data", this); }
/// <summary>Get a list of cultivars for crop.</summary> /// <param name="crop">The crop.</param> /// <returns>A list of cultivars.</returns> public static string[] GetCultivarNames(IPlant crop) { Simulations simulations = (crop as IModel).FindAncestor <Simulations>(); Replacements replacements = simulations.FindChild <Replacements>(); if (replacements == null) { return(crop.CultivarNames); } IPlant replacementCrop = replacements.FindChild((crop as IModel).Name) as IPlant; if (replacementCrop != null) { return(replacementCrop.CultivarNames); } // Check for cultivar folders under replacements. List <string> cultivarNames = crop.CultivarNames.ToList(); foreach (CultivarFolder cultivarFolder in (crop as IModel).FindAllChildren <CultivarFolder>()) { IModel replacementFolder = replacements.FindChild(cultivarFolder.Name); if (replacementFolder != null) { // If we find a matching cultivar folder under replacements, remove // all cultivar names added by this folder in the official plant // model, and add the cultivar names added by the matching cultivar // folder under replacements. foreach (IModel cultivar in cultivarFolder.FindAllDescendants <Cultivar>()) { cultivarNames.Remove(cultivar.Name); // If the cultivar has memo children, then the memo text will // be appended to the cultivar name after a vertical bar |. // Technically, there could be a cultivar x and x|y, but the UI // will prevent users from doing this, so the user would really // just be digging their own hole at this point. cultivarNames.RemoveAll(c => c.StartsWith(cultivar.Name + "|")); } foreach (Alias alias in cultivarFolder.FindAllDescendants <Alias>()) { cultivarNames.RemoveAll(c => c.StartsWith(alias.Name + "|")); } foreach (IModel cultivar in replacementFolder.FindAllDescendants <Cultivar>()) { cultivarNames.Add(cultivar.Name); } } } return(cultivarNames.ToArray()); }
/// <inheritdoc/> public void AttachExtraPresenters(CLEMPresenter clemPresenter) { try { Report report = clemPresenter.model as Report; ReportView rv = new ReportView(clemPresenter.view as ViewBase); ViewBase reportView = new ViewBase(rv, "ApsimNG.Resources.Glade.DataStoreView.glade"); DataStorePresenter dataStorePresenter = new DataStorePresenter(new string[] { report.Name }); Simulations simulations = report.FindAncestor <Simulations>(); if (simulations != null) { dataStore = simulations.FindChild <IDataStore>(); } Simulation simulation = report.FindAncestor <Simulation>(); Experiment experiment = report.FindAncestor <Experiment>(); Zone paddock = report.FindAncestor <Zone>(); // Only show data which is in scope of this report. // E.g. data from this zone and either experiment (if applicable) or simulation. if (paddock != null) { dataStorePresenter.ZoneFilter = paddock; } if (experiment != null) { dataStorePresenter.ExperimentFilter = experiment; } else if (simulation != null) { dataStorePresenter.SimulationFilter = simulation; } dataStorePresenter.Attach(dataStore, reportView, clemPresenter.explorerPresenter); // Attach the view to display data clem = clemPresenter.view as CLEMView; clem.AddTabView("Data", reportView); clemPresenter.presenterList.Add("Data", this); //clem.TabSelected += Refresh; } catch (Exception err) { clemPresenter.explorerPresenter.MainPresenter.ShowError(err); } }
/// <summary>Attach the model (report) and the view (IReportView)</summary> public void Attach(object model, object view, ExplorerPresenter explorerPresenter) { this.report = model as Report; this.explorerPresenter = explorerPresenter; this.view = view as IReportActivityLedgerView; this.explorerPresenter.CommandHistory.ModelChanged += OnModelChanged; Simulations simulations = report.FindAncestor <Simulations>(); if (simulations != null) { dataStore = simulations.FindChild <IDataStore>(); } dataStorePresenter = new DataStorePresenter(); activityGridPresenter = new ActivityLedgerGridPresenter(); Simulation simulation = report.FindAncestor <Simulation>(); Zone paddock = report.FindAncestor <Zone>(); if (paddock != null) { dataStorePresenter.ZoneFilter = paddock; } if (simulation != null) { if (simulation.Parent is Experiment) { dataStorePresenter.ExperimentFilter = simulation.Parent as Experiment; } else { dataStorePresenter.SimulationFilter = simulation; } } dataStorePresenter.Attach(dataStore, this.view.DataStoreView, explorerPresenter); activityGridPresenter.ModelName = this.report.Name; activityGridPresenter.SimulationName = simulation.Name; activityGridPresenter.ZoneName = paddock.Name; activityGridPresenter.Attach(dataStore, this.view.DisplayView, explorerPresenter); dataStorePresenter.tableDropDown.SelectedValue = this.report.Name; }
/// <summary> /// Run a command received from a given connection manager. /// </summary> /// <param name="command">Command to be run.</param> /// <param name="connection">Connection on which we received the command.</param> protected virtual void RunCommand(ICommand command, IConnectionManager connection) { try { // Clone the simulations object before running the command. var timer = Stopwatch.StartNew(); command.Run(runner, jobRunner, sims.FindChild <Models.Storage.IDataStore>()); timer.Stop(); WriteToLog($"Command ran in {timer.ElapsedMilliseconds}ms"); connection.OnCommandFinished(command); } catch (Exception err) { if (options.Verbose) { Console.Error.WriteLine(err); } connection.OnCommandFinished(command, err); } }
/// <summary>Get a list of Phase Names for life Cycle</summary> /// <param name="crop">The crop.</param> /// <returns>A list of Phase Names.</returns> private string[] GetPhaseNames(LifeCycle lifeCycle) { if (lifeCycle.LifeCyclePhaseNames.Length == 0) { Simulations simulations = (lifeCycle as IModel).FindAncestor <Simulations>(); Replacements replacements = simulations.FindChild <Replacements>(); if (replacements != null) { LifeCycle replacementLifeCycle = replacements.FindChild((lifeCycle as IModel).Name) as LifeCycle; if (replacementLifeCycle != null) { return(replacementLifeCycle.LifeCyclePhaseNames); } } } else { return(lifeCycle.LifeCyclePhaseNames); } return(new string[0]); }
/// <summary>Get a list of cultivars for crop.</summary> /// <param name="crop">The crop.</param> /// <returns>A list of cultivars.</returns> private string[] GetCultivarNames(IPlant crop) { if (crop.CultivarNames.Length == 0) { Simulations simulations = (crop as IModel).FindAncestor <Simulations>(); Replacements replacements = simulations.FindChild <Replacements>(); if (replacements != null) { IPlant replacementCrop = replacements.FindChild((crop as IModel).Name) as IPlant; if (replacementCrop != null) { return(replacementCrop.CultivarNames); } } } else { return(crop.CultivarNames); } return(new string[0]); }
public void TestEditing() { string configFile = Path.GetTempFileName(); File.WriteAllLines(configFile, new[] { // Modify an array "[Report].VariableNames = x,y,z", // Modify a date - try a few different formats. "[Clock].StartDate = 2000-01-01", "[Clock].EndDate = 2000-01-10T00:00:00", // Modify a string "[Weather].FileName = fdsa.met", @"[Weather2].FullFileName = jkl.met", // Replace a model with a model from another file. $"[Weather3] = {extFile}", $"[Weather4] = {extFile};[w2]", // Change a property of a resource model. "[Wheat].Leaf.Photosynthesis.RUE.FixedValue = 0.4", // Change a property of a manager script. "[Manager].Script.Amount = 1234", // Set an entire array. "[Physical].BD = 1, 2, 3, 4, 5", // Modify a single element of an array. "[Physical].AirDry[2] = 6", // Modify multiple elements of an array. "[Physical].LL15[3:4] = 7", }); Simulations file = EditFile.Do(fileName, configFile); var report = file.FindInScope <Models.Report>(); string[] variableNames = new[] { "x", "y", "z" }; Assert.AreEqual(variableNames, report.VariableNames); IModel sim = file.FindChild <Simulation>(); // Use an index-based lookup to locate child models. // When we replace an entire model, we want to ensure // that the replacement is inserted at the correct index. Clock clock = sim.Children[0] as Clock; Assert.AreEqual(new DateTime(2000, 1, 1), clock.StartDate); Assert.AreEqual(new DateTime(2000, 1, 10), clock.EndDate); var weather = sim.Children[3] as Models.Climate.Weather; Assert.NotNull(weather); Assert.AreEqual("Weather", weather.Name); Assert.AreEqual("fdsa.met", weather.FileName); var weather2 = sim.Children[4] as Models.Climate.Weather; Assert.NotNull(weather2); Assert.AreEqual("Weather2", weather2.Name); Assert.AreEqual(@"jkl.met", weather2.FileName); // Weather3 and Weather4 should have been // renamed to w1 and w2, respectively. var weather3 = sim.Children[5] as Models.Climate.Weather; Assert.NotNull(weather3); Assert.AreEqual("w1", weather3.Name); Assert.AreEqual("w1.met", weather3.FileName); var weather4 = sim.Children[6] as Models.Climate.Weather; Assert.NotNull(weather4); Assert.AreEqual("w2", weather4.Name); Assert.AreEqual("w2.met", weather4.FileName); // The edit file operation should have changed RUE value to 0.4. var wheat = sim.Children[2].Children[2] as Plant; var rue = wheat.Children[6].Children[4].Children[0] as Constant; Assert.AreEqual(0.4, rue.FixedValue); double amount = (double)sim.FindByPath("[Manager].Script.Amount")?.Value; Assert.AreEqual(1234, amount); Physical physical = sim.Children[2].Children[4] as Physical; Assert.AreEqual(new double[5] { 1, 2, 3, 4, 5 }, physical.BD); Assert.AreEqual(new double[5] { 0, 6, 0, 0, 0 }, physical.AirDry); Assert.AreEqual(new double[5] { 0, 0, 7, 7, 0 }, physical.LL15); }
/// <summary> /// Run the apsim server. This will block the calling thread. /// </summary> public virtual void Run() { try { WriteToLog($"Starting server..."); using (IConnectionManager conn = CreateConnection()) { while (true) { try { WriteToLog("Waiting for connections..."); conn.WaitForConnection(); WriteToLog("Client connected to server."); ICommand command; while ((command = GetCommand(conn)) != null) { WriteToLog($"Received {command}"); try { RunCommand(command, conn); } catch (IOException) { // Broken pipe is handled further down. throw; } catch (Exception error) { // Other exceptions will usually be triggered by a // problem executing the command. This shouldn't cause // the server to crash. // todo : custom exception type for comamnd failures? WriteToLog($"{command} ran with errors:"); WriteToLog(error.ToString()); } } WriteToLog($"Connection closed by client."); // If we don't want to keep the server alive we can exit now. // Otherwise we will go back and wait for another connection. if (!options.KeepAlive) { return; } conn.Disconnect(); } catch (IOException err) { WriteToLog(err.ToString()); WriteToLog("Pipe is broken. Closing connection..."); conn.Disconnect(); } } } } finally { sims?.FindChild <Models.Storage.IDataStore>()?.Close(); } }
public void TestEditing() { string configFile = Path.GetTempFileName(); File.WriteAllLines(configFile, new[] { // Modify an array "[Report].VariableNames = x,y,z", // Modify a date - try a few different formats. "[Clock].StartDate = 2000-01-01", "[Clock].EndDate = 2000-01-10T00:00:00", // Modify a string "[Weather].FileName = fdsa.met", @"[Weather2].FullFileName = jkl.met", // Replace a model with a model from another file. $"[Weather3] = {extFile}", $"[Weather4] = {extFile};[w2]", // Change a property of a resource model. "[Wheat].Leaf.Photosynthesis.RUE.FixedValue = 0.4", // Change a property of a manager script. "[Manager].Script.Amount = 1234", // Set an entire array. "[Physical].BD = 1, 2, 3, 4, 5", // Modify a single element of an array. "[Physical].AirDry[2] = 6", // Modify multiple elements of an array. "[Physical].LL15[3:4] = 7", }); string models = typeof(IModel).Assembly.Location; string args = $"{fileName} /Edit {configFile}"; var proc = new ProcessUtilities.ProcessWithRedirectedOutput(); proc.Start(models, args, Path.GetTempPath(), true, writeToConsole: true); proc.WaitForExit(); // Children of simulation are, in order: // Clock, summary, zone, Weather, Weather2, w1, w2 Assert.AreEqual(null, proc.StdOut); Assert.AreEqual(null, proc.StdErr); Simulations file = FileFormat.ReadFromFile <Simulations>(fileName, out List <Exception> errors); if (errors != null && errors.Count > 0) { throw errors[0]; } var report = file.FindInScope <Models.Report>(); string[] variableNames = new[] { "x", "y", "z" }; Assert.AreEqual(variableNames, report.VariableNames); IModel sim = file.FindChild <Simulation>(); // Use an index-based lookup to locate child models. // When we replace an entire model, we want to ensure // that the replacement is inserted at the correct index. Clock clock = sim.Children[0] as Clock; Assert.AreEqual(new DateTime(2000, 1, 1), clock.StartDate); Assert.AreEqual(new DateTime(2000, 1, 10), clock.EndDate); var weather = sim.Children[3] as Models.Climate.Weather; Assert.NotNull(weather); Assert.AreEqual("Weather", weather.Name); Assert.AreEqual("fdsa.met", weather.FileName); var weather2 = sim.Children[4] as Models.Climate.Weather; Assert.NotNull(weather2); Assert.AreEqual("Weather2", weather2.Name); Assert.AreEqual(@"jkl.met", weather2.FileName); // Weather3 and Weather4 should have been // renamed to w1 and w2, respectively. var weather3 = sim.Children[5] as Models.Climate.Weather; Assert.NotNull(weather3); Assert.AreEqual("w1", weather3.Name); Assert.AreEqual("w1.met", weather3.FileName); var weather4 = sim.Children[6] as Models.Climate.Weather; Assert.NotNull(weather4); Assert.AreEqual("w2", weather4.Name); Assert.AreEqual("w2.met", weather4.FileName); // The edit file operation should have changed RUE value to 0.4. var wheat = sim.Children[2].Children[2] as Plant; var rue = wheat.Children[6].Children[4].Children[0] as Constant; Assert.AreEqual(0.4, rue.FixedValue); double amount = (double)sim.FindByPath("[Manager].Script.Amount")?.Value; Assert.AreEqual(1234, amount); Physical physical = sim.Children[2].Children[4] as Physical; Assert.AreEqual(new double[5] { 1, 2, 3, 4, 5 }, physical.BD); Assert.AreEqual(new double[5] { 0, 6, 0, 0, 0 }, physical.AirDry); Assert.AreEqual(new double[5] { 0, 0, 7, 7, 0 }, physical.LL15); }