Example #1
0
        public void Enabled(object sender, EventArgs e)
        {
            IModel model = Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as IModel;

            if (model != null)
            {
                model.Enabled = !model.Enabled;
                foreach (IModel child in Apsim.ChildrenRecursively(model))
                {
                    child.Enabled = model.Enabled;
                }
                explorerPresenter.PopulateContextMenu(explorerPresenter.CurrentNodePath);
                explorerPresenter.Refresh();
            }
        }
Example #2
0
 /// <summary>
 ///  Accepts the actual soil water uptake from the soil arbitrator.
 /// </summary>
 /// <param name="info"></param>
 public void SetSWUptake(List <Soils.Arbitrator.ZoneWaterAndN> info)
 {
     foreach (ZoneWaterAndN ZI in info)
     {
         foreach (Zone SearchZ in Apsim.ChildrenRecursively(Parent, typeof(Zone)))
         {
             Soils.Soil ThisSoil = new Soils.Soil();
             if (SearchZ.Name == ZI.Name)
             {
                 ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil;
                 ThisSoil.SoilWater.dlt_sw_dep = MathUtilities.Multiply_Value(ZI.Water, -1);;
             }
         }
     }
 }
Example #3
0
 /// <summary>Constructor</summary>
 /// <param name="zone">The zone object representing the field.</param>
 /// <param name="stockModel">The stock model.</param>
 public FieldWithForage(Zone zone, Stock stockModel)
 {
     field        = zone;
     animalGroups = stockModel.StockModel.Animals;
     foreach (IPlantDamage forage in Apsim.ChildrenRecursively(zone, typeof(IPlantDamage)))
     {
         foreach (var organ in forage.Organs)
         {
             if (organ.IsAboveGround)
             {
                 forageOrgans.Add(organ);
             }
         }
     }
 }
Example #4
0
        /// <summary>Called by the job runner when all jobs completed</summary>
        public void Completed()
        {
            Events events = new Events(simulations);

            events.Publish("EndRun", new object[] { this, new EventArgs() });

            // Optionally run the tests
            if (runTests)
            {
                foreach (Tests test in Apsim.ChildrenRecursively(simulations, typeof(Tests)))
                {
                    test.Test();
                }
            }
        }
Example #5
0
 /// <summary>Initialises this instance.</summary>
 public void Initialise()
 {
     foreach (Zone Z in Apsim.ChildrenRecursively(this.Parent, typeof(Zone)))
     {
         Soil soil = Apsim.Child(Z, typeof(Soil)) as Soil;
         if (soil != null)
         {
             ZoneWaterAndN NewZ = new ZoneWaterAndN(Z);
             NewZ.Water = soil.Water;
             NewZ.NO3N  = soil.NO3N;
             NewZ.NH4N  = soil.NH4N;
             Zones.Add(NewZ);
         }
     }
 }
Example #6
0
        /// <summary>Perform the actual replacement.</summary>
        /// <param name="simulation">The simulation to perform the replacements on.</param>
        public void Replace(IModel simulation)
        {
            if (path == null)
            {
                // Temporarily remove DataStore because we don't want to do any
                // replacements under DataStore.
                var dataStore = simulation.Children.Find(model => model is DataStore);
                if (dataStore != null)
                {
                    simulation.Children.Remove(dataStore);
                }

                // Do replacements.
                foreach (IModel match in Apsim.ChildrenRecursively(simulation))
                {
                    if (match.Name.Equals(replacement.Name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        ReplaceModel(match);
                    }
                }

                // Reinstate DataStore.
                if (dataStore != null)
                {
                    simulation.Children.Add(dataStore);
                }
            }
            else
            {
                IModel match = Apsim.Get(simulation, path) as IModel;
                if (match == null)
                {
                    throw new Exception("Cannot find a model on path: " + path);
                }
                ReplaceModel(match);

                // In a multi-paddock context, we want to attempt to
                // replace the model in all paddocks.
                foreach (IModel paddock in Apsim.ChildrenRecursively(simulation, typeof(Zone)))
                {
                    match = Apsim.Get(paddock, path) as IModel;
                    if (match != null)
                    {
                        ReplaceModel(match);
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// Convert the simulation decription to a simulation.
        /// path.
        /// </summary>
        public Simulation ToSimulation()
        {
            try
            {
                AddReplacements();

                Simulation newSimulation;
                if (doClone)
                {
                    newSimulation = Apsim.Clone(baseSimulation) as Simulation;
                }
                else
                {
                    newSimulation = baseSimulation;
                }

                if (string.IsNullOrWhiteSpace(Name))
                {
                    newSimulation.Name = baseSimulation.Name;
                }
                else
                {
                    newSimulation.Name = Name;
                }

                newSimulation.Parent = null;
                Apsim.ParentAllChildren(newSimulation);
                replacementsToApply.ForEach(r => r.Replace(newSimulation));

                // Give the simulation the descriptors.
                newSimulation.Descriptors = Descriptors;
                newSimulation.Services    = GetServices();

                // Standardise the soil.
                var soils = Apsim.ChildrenRecursively(newSimulation, typeof(Soils.Soil));
                foreach (Soils.Soil soil in soils)
                {
                    SoilStandardiser.Standardise(soil);
                }

                return(newSimulation);
            }
            catch (Exception err)
            {
                var message = "Error in file: " + baseSimulation.FileName + " Simulation: " + Name;
                throw new Exception(message, err);
            }
        }
Example #8
0
        /// <summary>
        /// Replace a model with a model from another file.
        /// </summary>
        /// <param name="topLevel">The top-level model of the file being modified.</param>
        /// <param name="modelToReplace">Path to the model which is to be replaced.</param>
        /// <param name="replacementFile">Path of the .apsimx file containing the model which will be inserted.</param>
        /// <param name="replacementPath">Path to the model in replacementFile which will be used to replace a model in topLevel.</param>
        private static void ReplaceModelFromFile(Simulations topLevel, string modelToReplace, string replacementFile, string replacementPath)
        {
            IModel toBeReplaced = Apsim.Get(topLevel, modelToReplace) as IModel;

            if (toBeReplaced == null)
            {
                throw new Exception($"Unable to find model which is to be replaced ({modelToReplace}) in file {topLevel.FileName}");
            }

            IModel extFile = FileFormat.ReadFromFile <IModel>(replacementFile, out List <Exception> errors);

            if (errors?.Count > 0)
            {
                throw new Exception($"Error reading replacement file {replacementFile}", errors[0]);
            }

            IModel replacement;

            if (string.IsNullOrEmpty(replacementPath))
            {
                replacement = Apsim.ChildrenRecursively(extFile, toBeReplaced.GetType()).FirstOrDefault();
                if (replacement == null)
                {
                    throw new Exception($"Unable to find replacement model of type {toBeReplaced.GetType().Name} in file {replacementFile}");
                }
            }
            else
            {
                replacement = Apsim.Get(extFile, replacementPath) as IModel;
                if (replacement == null)
                {
                    throw new Exception($"Unable to find model at path {replacementPath} in file {replacementFile}");
                }
            }

            IModel parent = toBeReplaced.Parent;
            int    index  = parent.Children.IndexOf((Model)toBeReplaced);

            parent.Children.Remove((Model)toBeReplaced);

            // Need to call Structure.Add to add the model to the parent.
            Structure.Add(replacement, parent);

            // Move the new model to the index in the list at which the
            // old model previously resided.
            parent.Children.Remove((Model)replacement);
            parent.Children.Insert(index, (Model)replacement);
        }
Example #9
0
        /// <summary>
        /// Return all simulation names generated by all descendant models as a
        /// comma-separated string.
        /// </summary>
        private string GetSimulationNames()
        {
            List <string> simulationNames = new List <string>();

            foreach (ISimulationDescriptionGenerator generator in Apsim.ChildrenRecursively(this, typeof(ISimulationDescriptionGenerator)))
            {
                if (!(generator is Simulation sim && sim.Parent is ISimulationDescriptionGenerator))
                {
                    simulationNames.AddRange(generator.GenerateSimulationDescriptions().Select(s => $"'{s.Name}'"));
                }
            }

            string csv = string.Join(", ", simulationNames);

            return($"c({csv})");
        }
Example #10
0
        /// <summary>
        /// Build a list of simulation / zone pairs from the specified simulation
        /// </summary>
        /// <param name="model">This can be either a simulation or a zone</param>
        /// <returns>A list of simulation / zone pairs</returns>
        private List <SimulationZone> BuildListFromSimulation(IModel model)
        {
            IModel simulation = Apsim.Parent(model, typeof(Simulation));
            List <SimulationZone> simulationZonePairs = new List <SimulationZone>();

            foreach (Zone zone in Apsim.ChildrenRecursively(model, typeof(Zone)))
            {
                simulationZonePairs.Add(new SimulationZone(simulation.Name, zone.Name));
            }

            if (typeof(Zone).IsAssignableFrom(model.GetType()))
            {
                simulationZonePairs.Add(new SimulationZone(simulation.Name, model.Name));
            }
            return(simulationZonePairs);
        }
Example #11
0
        /// <summary>Perform the actual replacement.</summary>
        private void ReplaceModel(IModel match)
        {
            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;
            newModel.Name   = match.Name;
            match.Parent.Children.Remove(match as Model);

            newModel.Parent.OnCreated();
            foreach (var model in Apsim.ChildrenRecursively(newModel.Parent))
            {
                model.OnCreated();
            }
        }
Example #12
0
        /// <summary>Adds a new model (as specified by the string argument) to the specified parent.</summary>
        /// <param name="parent">The parent to add the model to</param>
        /// <param name="st">The string representing the new model</param>
        /// <returns>The newly created model.</returns>
        public static IModel Add(string st, IModel parent)
        {
            List <Exception> creationExceptions;
            IModel           modelToAdd = FileFormat.ReadFromString <IModel>(st, out creationExceptions);

            // Correctly parent all models.
            Add(modelToAdd, parent);

            // Ensure the model name is valid.
            EnsureNameIsUnique(modelToAdd);

            // Call OnCreated
            Apsim.ChildrenRecursively(modelToAdd).ForEach(m => m.OnCreated());

            return(modelToAdd);
        }
Example #13
0
        /// <summary>Determine the list of jobs to run</summary>
        /// <param name="relativeTo">Model to use to find jobs to run</param>
        private void GetListOfModelsToRun(IModel relativeTo)
        {
            AllSimulationNames      = new List <string>();
            SimulationNamesBeingRun = new List <string>();

            // get a list of all simulation names.
            List <IJobGenerator> allModels = Apsim.ChildrenRecursively(simulations, typeof(IJobGenerator)).Cast <IJobGenerator>().ToList();

            allModels.ForEach(model => AllSimulationNames.AddRange(model.GetSimulationNames()));

            // Get a list of all models we're going to run.
            modelsToRun = Apsim.ChildrenRecursively(relativeTo, typeof(IJobGenerator)).Cast <IJobGenerator>().ToList();

            // For each model, get a list of simulation names.
            modelsToRun.ForEach(model => SimulationNamesBeingRun.AddRange(model.GetSimulationNames()));
        }
        /// <summary>
        /// Finds all array properties with a description attribute of
        /// a given model and all child models of type SoilCrop.
        /// </summary>
        /// <param name="model">Model to examine.</param>
        private List <VariableProperty> FindAllProperties(IModel model)
        {
            List <VariableProperty> properties = new List <VariableProperty>();

            // When user clicks on a SoilCrop, there is no thickness column. In this
            // situation get thickness column from parent model.
            if (this.model is SoilCrop)
            {
                Physical water = model.Parent as Physical;
                if (water == null)
                {
                    // Parent model is not a Physical model. This can happen if the soil
                    // crop is a factor or under replacements. If under replacements, all
                    // bets are off. Otherwise, we find an ancestor which is a simulation
                    // generator (experiment, simulation, morris, etc.) and search for
                    // a physical node somewhere under the simulation generator.
                    IModel parent = Apsim.Parent(model, typeof(ISimulationDescriptionGenerator));
                    if (parent != null)
                    {
                        water = Apsim.ChildrenRecursively(parent, typeof(Physical)).FirstOrDefault() as Physical;
                    }
                }
                if (water != null)
                {
                    PropertyInfo depth = water.GetType().GetProperty("Depth");
                    properties.Add(new VariableProperty(water, depth));
                }
            }

            // Get all properties of the model which have a description attribute.
            foreach (PropertyInfo property in model.GetType().GetProperties())
            {
                Attribute description = ReflectionUtilities.GetAttribute(property, typeof(DescriptionAttribute), false);
                if (property.PropertyType.IsArray && description != null)
                {
                    properties.Add(new VariableProperty(model, property));
                }
            }

            // Get properties of all child models of type SoilCrop.
            foreach (SoilCrop crop in Apsim.Children(model, typeof(SoilCrop)))
            {
                properties.AddRange(FindAllProperties(crop));
            }

            return(properties);
        }
Example #15
0
            /// <summary>Move to next simulation</summary>
            bool IEnumerator.MoveNext()
            {
                currentSimulation = null;

                if (simulationDescriptionsToRun.Count > 0)
                {
                    // Determine if there are any simulation descriptions that need
                    // converting to a simulation and then run.
                    currentSimulation          = simulationDescriptionsToRun[0].ToSimulation(simulations);
                    currentSimulation.FileName = fileName;
                    IClock simClock = (IClock)Apsim.ChildrenRecursively(currentSimulation).Find(m => typeof(IClock).IsAssignableFrom(m.GetType()));
                    simClocks.Add(simClock);

                    simulationDescriptionsToRun.RemoveAt(0);
                }
                return(currentSimulation != null);
            }
Example #16
0
 public void ShowPageOfGraphs(object sender, EventArgs e)
 {
     try
     {
         Folder folder = Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as Folder;
         folder.ShowPageOfGraphs = !folder.ShowPageOfGraphs;
         foreach (Folder child in Apsim.ChildrenRecursively(folder, typeof(Folder)))
         {
             child.ShowPageOfGraphs = folder.ShowPageOfGraphs;
         }
         explorerPresenter.PopulateContextMenu(explorerPresenter.CurrentNodePath);
     }
     catch (Exception err)
     {
         explorerPresenter.MainPresenter.ShowError(err);
     }
 }
Example #17
0
        private void OnDoInitialSummary(object sender, EventArgs e)
        {
            if (CaptureSummaryText)
            {
                CreateInitialConditionsTable();
            }


            //Do checks on the soil to make sure there are no problems with the initial parameterisation.

            List <IModel> soils = Apsim.ChildrenRecursively(simulation, typeof(Soil));

            foreach (Soil soil in soils)
            {
                SoilChecker.Check(soil);
            }
        }
Example #18
0
        /// <summary>
        /// Return true if duplications were found.
        /// </summary>
        /// <returns></returns>
        private bool DuplicatesFound()
        {
            List <IModel> allSims     = Apsim.ChildrenRecursively(simulations, typeof(Simulation));
            List <string> allSimNames = allSims.Select(s => s.Name).ToList();
            var           duplicates  = allSimNames
                                        .GroupBy(i => i)
                                        .Where(g => g.Count() > 1)
                                        .Select(g => g.Key);

            if (duplicates.ToList().Count > 0)
            {
                string errorMessage = "Duplicate simulation names found " + StringUtilities.BuildString(duplicates.ToArray(), ", ");
                explorerPresenter.ShowMessage(errorMessage, Models.DataStore.ErrorLevel.Error);
                return(true);
            }
            return(false);
        }
Example #19
0
        /// <summary>Add statistics</summary>
        /// <param name="tags">Document tags to add to.</param>
        private void AddStatistics(List <AutoDocumentation.ITag> tags)
        {
            IModel dataStore = Apsim.Child(ExplorerPresenter.ApsimXFile, "DataStore");

            if (dataStore != null)
            {
                List <IModel> tests = Apsim.ChildrenRecursively(dataStore, typeof(Tests));
                if (tests.Count > 0)
                {
                    tags.Add(new AutoDocumentation.Heading("Statistics", 2));
                }

                foreach (Tests test in tests)
                {
                    test.Document(tags, 3, 0);
                }
            }
        }
Example #20
0
        public void IncludeInDocumentation(object sender, EventArgs e)
        {
            try
            {
                IModel model = Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as IModel;
                model.IncludeInDocumentation = !model.IncludeInDocumentation; // toggle switch

                foreach (IModel child in Apsim.ChildrenRecursively(model))
                {
                    child.IncludeInDocumentation = model.IncludeInDocumentation;
                }
                explorerPresenter.PopulateContextMenu(explorerPresenter.CurrentNodePath);
            }
            catch (Exception err)
            {
                explorerPresenter.MainPresenter.ShowMessage(err.ToString(), Models.DataStore.ErrorLevel.Error);
            }
        }
Example #21
0
        /// <summary>Create a simulations object by reading the specified filename</summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="creationExceptions">A list of exceptions created during creation of the models.</param>
        public static T ReadFromFile <T>(string fileName, out List <Exception> creationExceptions) where T : IModel
        {
            if (!File.Exists(fileName))
            {
                throw new Exception("Cannot read file: " + fileName + ". File does not exist.");
            }

            string contents = File.ReadAllText(fileName);
            T      newModel = ReadFromString <T>(contents, out creationExceptions, fileName);

            // Set the filename
            if (newModel is Simulations)
            {
                (newModel as Simulations).FileName = fileName;
            }
            Apsim.ChildrenRecursively(newModel, typeof(Simulation)).ForEach(m => (m as Simulation).FileName = fileName);
            return(newModel);
        }
Example #22
0
        /// <summary>
        /// Adds a model as a child to a parent model. Will throw if not allowed.
        /// </summary>
        /// <param name="modelToAdd">The model to add.</param>
        /// <param name="parent">The parent model to add it to.</param>
        public static void Add(IModel modelToAdd, IModel parent)
        {
            if (parent.ReadOnly)
            {
                throw new Exception(string.Format("Unable to modify {0} - it is read-only.", parent.Name));
            }

            modelToAdd.Parent = parent;
            Apsim.ParentAllChildren(modelToAdd);
            parent.Children.Add(modelToAdd as Model);

            // Ensure the model name is valid.
            EnsureNameIsUnique(modelToAdd);

            // Call OnCreated
            modelToAdd.OnCreated();
            Apsim.ChildrenRecursively(modelToAdd).ForEach(m => m.OnCreated());
        }
Example #23
0
        /// <summary>
        /// Run all simulations.
        /// </summary>
        /// <param name="runType">How should the simulations be run?</param>
        /// <param name="wait">Wait until all simulations are complete?</param>
        /// <param name="verbose">Produce verbose output?</param>
        /// <param name="numberOfProcessors">Number of CPU processes to use. -1 indicates all processes.</param>
        /// <param name="runTests">Run all test models?</param>
        /// <returns>A list of exception or null if no exceptions thrown.</returns>
        public List <Exception> Run(RunTypeEnum runType, bool wait = true, bool verbose = false, int numberOfProcessors = -1, bool runTests = false)
        {
            errors.Clear();

            Apsim.ParentAllChildren(rootModel);
            Apsim.ChildrenRecursively(rootModel).ForEach(m => m.OnCreated());
            IJobManager jobManager = Models.Core.Runners.Runner.ForSimulations(rootModel, relativeTo, false);
            IJobRunner  jobRunner  = new JobRunnerSync();

            jobRunner.JobCompleted += OnJobCompleded;
            jobRunner.Run(jobManager, wait: true);
            jobRunner.JobCompleted -= OnJobCompleded;

            var storage = Apsim.Find(rootModel, typeof(IDataStore)) as IDataStore;

            storage.Writer.Stop();

            return(errors);
        }
Example #24
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            this.InitialiseHerd(true, true);

            // check GrazeFoodStoreExists
            grazeStore = "";
            if (GrazeFoodStoreName != null && !GrazeFoodStoreName.StartsWith("Not specified"))
            {
                grazeStore = GrazeFoodStoreName.Split('.').Last();
            }
            else
            {
                var ah = Apsim.Find(this, typeof(ActivitiesHolder));
                if (Apsim.ChildrenRecursively(ah, typeof(PastureActivityManage)).Count() != 0)
                {
                    Summary.WriteWarning(this, String.Format("Individuals weaned by [a={0}] will be placed in [Not specified - general yards] while a managed pasture is available. These animals will not graze until mustered and will require feeding while in yards.\nSolution: Set the [GrazeFoodStore to place weaners in] located in the properties.", this.Name));
                }
            }
        }
Example #25
0
 public void ShowModelStructure(object sender, EventArgs e)
 {
     try
     {
         IModel model = Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as IModel;
         if (model != null)
         {
             foreach (IModel child in Apsim.ChildrenRecursively(model))
             {
                 child.IsHidden = !child.IsHidden;
             }
             explorerPresenter.PopulateContextMenu(explorerPresenter.CurrentNodePath);
             explorerPresenter.Refresh();
         }
     }
     catch (Exception err)
     {
         explorerPresenter.MainPresenter.ShowError(err);
     }
 }
Example #26
0
        /// <summary>Perform the actual replacement.</summary>
        /// <param name="simulation">The simulation to perform the replacements on.</param>
        public void Replace(IModel simulation)
        {
            if (path == null)
            {
                throw new Exception("No path specified for property replacement.");
            }

            Apsim.Set(simulation, path, replacement);

            // In a multi-paddock context, we want to attempt to
            // change the property value in all paddocks.
            foreach (Zone paddock in Apsim.ChildrenRecursively(simulation, typeof(Zone)))
            {
                IVariable variable = Apsim.GetVariableObject(paddock, path);
                if (variable != null)
                {
                    variable.Value = replacement;
                }
            }
        }
Example #27
0
        /// <summary>Perform the actual replacement.</summary>
        private void ReplaceModel(IModel match)
        {
            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;
            newModel.Name    = match.Name;
            newModel.Enabled = match.Enabled;
            match.Parent.Children.Remove(match as Model);

            // Don't call newModel.Parent.OnCreated(), because if we're replacing
            // a child of a resource model, the resource model's OnCreated event
            // will make it reread the resource string and replace this child with
            // the 'official' child from the resource.
            foreach (var model in Apsim.ChildrenRecursively(newModel.Parent))
            {
                model.OnCreated();
            }
        }
Example #28
0
        /// <summary>Find and return a list of duplicate simulation names.</summary>
        private List <string> FindDuplicateSimulationNames()
        {
            if (rootModel == null)
            {
                return(new List <string>());
            }

            List <IModel> allSims = Apsim.ChildrenRecursively(rootModel, typeof(ISimulationDescriptionGenerator));

            List <string> dupes = new List <string>();

            foreach (var simType in allSims.GroupBy(s => s.GetType()))
            {
                dupes.AddRange(simType.Select(s => s.Name)
                               .GroupBy(i => i)
                               .Where(g => g.Count() > 1)
                               .Select(g => g.Key));
            }

            return(dupes);
        }
Example #29
0
        private void OnDoInitialSummary(object sender, EventArgs e)
        {
            if (CaptureSummaryText)
            {
                CreateInitialConditionsTable();
            }


            //Do checks on the soil to make sure there are no problems with the initial parameterisation.

            var soils = Apsim.ChildrenRecursively(simulation, typeof(Soils.Soil));

            foreach (Soils.Soil soil in soils)
            {
                string errorMessages = SoilChecker.Check(soil);
                if (!string.IsNullOrEmpty(errorMessages))
                {
                    WriteWarning(soil, errorMessages);
                }
            }
        }
Example #30
0
        /// <summary>Return the index of next job to run or -1 if nothing to run.</summary>
        /// <returns>Job to run or null if no more jobs to run</returns>
        public IRunnable GetNextJobToRun()
        {
            // First time through there. Get a list of things to run.
            if (simulationEnumerator == null)
            {
                // Send event telling all models that we're about to begin running.
                Events events = new Events(simulations);
                events.Publish("BeginRun", null);

                Runner.SimulationEnumerator enumerator = new Runner.SimulationEnumerator(modelSelectedByUser);
                simulationEnumerator    = enumerator;
                SimulationNamesBeingRun = enumerator.SimulationNamesBeingRun;

                // Send event telling all models that we're about to begin running.
                Dictionary <string, string> simAndFolderNames = new Dictionary <string, string>();
                foreach (ISimulationGenerator simulation in Apsim.ChildrenRecursively(simulations, typeof(ISimulationGenerator)).Cast <ISimulationGenerator>())
                {
                    string folderName = Apsim.Parent(simulation as IModel, typeof(Folder)).Name;
                    foreach (string simulationName in simulation.GetSimulationNames())
                    {
                        if (simAndFolderNames.ContainsKey(simulationName))
                        {
                            throw new Exception(string.Format("Duplicate simulation names found: {0} in simulation {1}", simulationName, (simulation as IModel).Name));
                        }
                        simAndFolderNames.Add(simulationName, folderName);
                    }
                }
                events.Publish("RunCommencing", new object[] { simAndFolderNames, SimulationNamesBeingRun });
            }

            // If we didn't find anything to run then return null to tell job runner to exit.
            if (simulationEnumerator.MoveNext())
            {
                return(new RunSimulation(simulations, simulationEnumerator.Current, false));
            }
            else
            {
                return(null);
            }
        }