예제 #1
0
파일: Apsim.cs 프로젝트: jcbowden/ApsimX
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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 });
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        /// <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);
                            Events events = new Events(newModel);
                            events.Publish("Loaded", null);
                        }
                    }
                }
            }
        }
예제 #5
0
        /// <summary>Write the specified simulation set to the specified 'stream'</summary>
        /// <param name="stream">The stream.</param>
        public void Write(TextWriter stream)
        {
            object[] args = new object[] { true };

            Events events = new Events(this);

            events.Publish("Serialising", args);

            try
            {
                stream.Write(XmlUtilities.Serialise(this, true));
            }
            finally
            {
                events.Publish("Serialised", args);
            }
        }
예제 #6
0
        /// <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 });
        }
예제 #7
0
파일: Apsim.cs 프로젝트: jcbowden/ApsimX
        /// <summary>
        /// Serialize the model to a string and return the string.
        /// </summary>
        /// <param name="model">The model to serialize</param>
        /// <returns>The string version of the model</returns>
        public static string Serialise(IModel model)
        {
            Events events = new Events(model);

            // Let all models know that we're about to serialise.
            object[] args = new object[] { true };
            events.Publish("Serialising", args);

            // Do the serialisation
            StringWriter writer = new StringWriter();

            writer.Write(XmlUtilities.Serialise(model, false));

            // Let all models know that we have completed serialisation.
            events.Publish("Serialised", args);

            // Set the clipboard text.
            return(writer.ToString());
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <summary>
        /// Prepare the simulation for running.
        /// </summary>
        public void Prepare()
        {
            // Remove disabled models.
            RemoveDisabledModels(this);

            // Standardise the soil.
            var soils = FindAllDescendants <Soils.Soil>();

            foreach (Soils.Soil soil in soils)
            {
                SoilStandardiser.Standardise(soil);
            }

            // If this simulation was not created from deserialisation then we need
            // to parent all child models correctly and call OnCreated for each model.
            bool hasBeenDeserialised = Children.Count > 0 && Children[0].Parent == this;

            if (!hasBeenDeserialised)
            {
                // Parent all models.
                this.ParentAllDescendants();

                // Call OnCreated in all models.
                foreach (IModel model in FindAllDescendants().ToList())
                {
                    model.OnCreated();
                }
            }

            // Call OnPreLink in all models.
            // Note the ToList(). This is important because some models can
            // add/remove models from the simulations tree in their OnPreLink()
            // method, and FindAllDescendants() is lazy.
            FindAllDescendants().ToList().ForEach(model => model.OnPreLink());

            if (Services == null || Services.Count < 1)
            {
                var simulations = FindAncestor <Simulations>();
                if (simulations != null)
                {
                    Services = simulations.GetServices();
                }
                else
                {
                    Services = new List <object>();
                    IDataStore storage = this.FindInScope <IDataStore>();
                    if (storage != null)
                    {
                        Services.Add(this.FindInScope <IDataStore>());
                    }
                    Services.Add(new ScriptCompiler());
                }
            }

            var links  = new Links(Services);
            var events = new Events(this);

            try
            {
                // Connect all events.
                events.ConnectEvents();

                // Resolve all links
                links.Resolve(this, true);

                events.Publish("SubscribeToEvents", new object[] { this, EventArgs.Empty });
            }
            catch (Exception err)
            {
                throw new SimulationException("", err, Name, FileName);
            }
        }