Esempio n. 1
0
        /// <summary>Documents the specified model.</summary>
        /// <param name="modelNameToDocument">The model name to document.</param>
        /// <param name="tags">The auto doc tags.</param>
        /// <param name="headingLevel">The starting heading level.</param>
        public void DocumentModel(string modelNameToDocument, List <AutoDocumentation.ITag> tags, int headingLevel)
        {
            Simulation simulation = Apsim.Find(this, typeof(Simulation)) as Simulation;

            if (simulation != null)
            {
                // Find the model of the right name.
                IModel modelToDocument = Apsim.Find(simulation, modelNameToDocument);

                // If not found then find a model of the specified type.
                if (modelToDocument == null)
                {
                    modelToDocument = Apsim.Get(simulation, "[" + modelNameToDocument + "]") as IModel;
                }

                // If still not found throw an error.
                if (modelToDocument == null)
                {
                    throw new ApsimXException(this, "Could not find a model of the name " + modelNameToDocument + ". Simulation file name must match the name of the node to document.");
                }

                // Get the path of the model (relative to parentSimulation) to document so that
                // when replacements happen below we will point to the replacement model not the
                // one passed into this method.
                string pathOfSimulation      = Apsim.FullPath(simulation) + ".";
                string pathOfModelToDocument = Apsim.FullPath(modelToDocument).Replace(pathOfSimulation, "");

                // Clone the simulation
                Simulation clonedSimulation = Apsim.Clone(simulation) as Simulation;

                // Make any substitutions.
                Simulations.MakeSubstitutions(this, new List <Simulation> {
                    clonedSimulation
                });

                // Now use the path to get the model we want to document.
                modelToDocument = Apsim.Get(clonedSimulation, pathOfModelToDocument) as IModel;

                if (modelToDocument == null)
                {
                    throw new Exception("Cannot find model to document: " + modelNameToDocument);
                }

                // resolve all links in cloned simulation.
                Links links = new Core.Links();
                links.Resolve(clonedSimulation);

                // Document the model.
                modelToDocument.Document(tags, headingLevel, 0);

                // Unresolve links.
                links.Unresolve(clonedSimulation);
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Determine the type of an object and return its name.
 /// </summary>
 /// <param name="obj">obj can be either a ModelWrapper or an IModel.</param>
 /// <returns>The name</returns>
 private string GetFullName(object obj)
 {
     if (obj is IModel)
     {
         return(Apsim.FullPath(obj as IModel));
     }
     else
     {
         return((obj as ModelWrapper).Name);
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Determine the type of an object and return its name.
 /// </summary>
 /// <param name="obj">obj can be either a ModelWrapper or an IModel.</param>
 /// <returns>The name</returns>
 private string GetFullName(object obj)
 {
     if (obj is IModel)
     {
         return(Apsim.FullPath(obj as IModel));
     }
     else
     {
         return(obj.GetType().FullName);
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Return a list of models in scope to the one specified.
        /// </summary>
        /// <param name="relativeTo">The model to base scoping rules on</param>
        public IModel[] FindAll(IModel relativeTo)
        {
            string relativeToFullPath = Apsim.FullPath(relativeTo);
            // Try the cache first.
            List <IModel> modelsInScope;

            if (cache.TryGetValue(relativeToFullPath, out modelsInScope))
            {
                return(modelsInScope.ToArray());
            }

            // The algorithm is to find the parent Zone of the specified model.
            // Then return all children of this zone recursively and then recursively
            // the direct children of the parents of the zone.
            IModel parentZone = FindScopedParentModel(relativeTo);

            if (parentZone == null)
            {
                throw new Exception("No scoping model found relative to: " + Apsim.FullPath(relativeTo));
            }

            // return all models in zone and all direct children of zones parent.
            modelsInScope = new List <IModel>();
            modelsInScope.Add(parentZone);
            modelsInScope.AddRange(Apsim.ChildrenRecursively(parentZone));
            while (parentZone.Parent != null)
            {
                parentZone = parentZone.Parent;
                modelsInScope.Add(parentZone);
                foreach (IModel child in parentZone.Children)
                {
                    if (!modelsInScope.Contains(child))
                    {
                        modelsInScope.Add(child);
                        if (!IsScopedModel(child))
                        {
                            modelsInScope.AddRange(Apsim.ChildrenRecursively(child));
                        }
                    }
                }
            }

            if (!modelsInScope.Contains(parentZone))
            {
                modelsInScope.Add(parentZone); // top level simulation
            }
            // add to cache for next time.
            cache.Add(relativeToFullPath, modelsInScope);
            return(modelsInScope.ToArray());
        }
Esempio n. 5
0
        /// <summary>Documents the specified model.</summary>
        /// <param name="modelNameToDocument">The model name to document.</param>
        /// <param name="tags">The auto doc tags.</param>
        /// <param name="headingLevel">The starting heading level.</param>
        public void DocumentModel(string modelNameToDocument, List <AutoDocumentation.ITag> tags, int headingLevel)
        {
            Simulation simulation = Apsim.Find(this, typeof(Simulation)) as Simulation;

            if (simulation != null)
            {
                // Find the model of the right name.
                IModel modelToDocument = Apsim.Find(simulation, modelNameToDocument);

                // Get the path of the model (relative to parentSimulation) to document so that
                // when replacements happen below we will point to the replacement model not the
                // one passed into this method.
                string pathOfSimulation      = Apsim.FullPath(simulation) + ".";
                string pathOfModelToDocument = Apsim.FullPath(modelToDocument).Replace(pathOfSimulation, "");

                // Clone the simulation
                Simulation clonedSimulation = Apsim.Clone(simulation) as Simulation;

                // Make any substitutions.
                MakeSubstitutions(new Simulation[] { clonedSimulation });

                // Now use the path to get the model we want to document.
                modelToDocument = Apsim.Get(clonedSimulation, pathOfModelToDocument) as IModel;

                // resolve all links in cloned simulation.
                Apsim.ResolveLinks(clonedSimulation);
                foreach (Model child in Apsim.ChildrenRecursively(clonedSimulation))
                {
                    Apsim.ResolveLinks(child);
                }

                // Document the model.
                modelToDocument.Document(tags, headingLevel, 0);

                // Unresolve links.
                Apsim.UnresolveLinks(clonedSimulation);
                foreach (Model child in Apsim.ChildrenRecursively(clonedSimulation))
                {
                    Apsim.UnresolveLinks(child);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Get all links. Useful for debugging.
        /// </summary>
        /// <returns></returns>
        public static string GetAllLinks(IModel model)
        {
            string st = string.Empty;

            st += "\r\n******" + Apsim.FullPath(model) + "******\r\n";

            // Go looking for [Link]s
            foreach (FieldInfo field in ReflectionUtilities.GetAllFields(
                         model.GetType(),
                         BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public))
            {
                var link = ReflectionUtilities.GetAttribute(field, typeof(LinkAttribute), false) as LinkAttribute;
                if (link != null)
                {
                    st += field.Name + " = ";
                    object value = field.GetValue(model);
                    if (value == null)
                    {
                        st += "null\r\n";
                    }
                    else if (value is IModel)
                    {
                        st += Apsim.FullPath(value as IModel) + "\r\n";
                    }
                    else
                    {
                        st += "??\r\n";
                    }
                }
            }

            foreach (IModel child in model.Children)
            {
                st += GetAllLinks(child);
            }

            return(st);
        }
Esempio n. 7
0
        /// <summary>Documents the specified model.</summary>
        /// <param name="modelNameToDocument">The model name to document.</param>
        /// <param name="tags">The auto doc tags.</param>
        /// <param name="headingLevel">The starting heading level.</param>
        public void DocumentModel(string modelNameToDocument, List <AutoDocumentation.ITag> tags, int headingLevel)
        {
            Simulation simulation = Apsim.Find(this, typeof(Simulation)) as Simulation;

            if (simulation != null)
            {
                // Find the model of the right name.
                IModel modelToDocument = Apsim.Find(simulation, modelNameToDocument);

                // If not found then find a model of the specified type.
                if (modelToDocument == null)
                {
                    modelToDocument = Apsim.Get(simulation, "[" + modelNameToDocument + "]") as IModel;
                }

                // If the simulation has the same name as the model we want to document, dig a bit deeper
                if (modelToDocument == simulation)
                {
                    modelToDocument = Apsim.ChildrenRecursivelyVisible(simulation).FirstOrDefault(m => m.Name.Equals(modelNameToDocument, StringComparison.OrdinalIgnoreCase));
                }

                // If still not found throw an error.
                if (modelToDocument != null)
                {
                    // Get the path of the model (relative to parentSimulation) to document so that
                    // when replacements happen below we will point to the replacement model not the
                    // one passed into this method.
                    string pathOfSimulation      = Apsim.FullPath(simulation) + ".";
                    string pathOfModelToDocument = Apsim.FullPath(modelToDocument).Replace(pathOfSimulation, "");

                    // Clone the simulation
                    Simulation clonedSimulation = Apsim.Clone(simulation) as Simulation;

                    // Make any substitutions.
                    MakeSubstitutions(clonedSimulation);

                    // Now use the path to get the model we want to document.
                    modelToDocument = Apsim.Get(clonedSimulation, pathOfModelToDocument) as IModel;

                    if (modelToDocument == null)
                    {
                        throw new Exception("Cannot find model to document: " + modelNameToDocument);
                    }

                    // resolve all links in cloned simulation.
                    Links.Resolve(clonedSimulation);

                    modelToDocument.IncludeInDocumentation = true;
                    foreach (IModel child in Apsim.ChildrenRecursively(modelToDocument))
                    {
                        child.IncludeInDocumentation = true;
                    }

                    // Document the model.
                    AutoDocumentation.DocumentModel(modelToDocument, tags, headingLevel, 0, documentAllChildren: true);

                    // Unresolve links.
                    Links.Unresolve(clonedSimulation);
                }
            }
        }
Esempio n. 8
0
        /// <summary>Compile a c# script.</summary>
        /// <param name="code">The c# code to compile.</param>
        /// <param name="model">The model owning the script.</param>
        /// <param name="referencedAssemblies">Optional referenced assemblies.</param>
        /// <returns>Compile errors or null if no errors.</returns>
        public Results Compile(string code, IModel model, IEnumerable <string> referencedAssemblies = null)
        {
            string errors = null;

            if (code != null)
            {
                // See if we have compiled the code already. If so then no need to compile again.
                var compilation = previousCompilations.Find(c => c.Code == code);

                bool newlyCompiled;
                if (compilation == null || compilation.Code != code)
                {
                    newlyCompiled = true;

                    var assemblies = GetReferenceAssemblies(referencedAssemblies, model.Name);

                    // We haven't compiled the code so do it now.
                    var result = CompileTextToAssembly(code, assemblies);
                    if (result.Errors.Count > 0)
                    {
                        // Errors were found. Add then to the return error string.
                        errors = null;
                        foreach (CompilerError err in result.Errors)
                        {
                            errors += $"Line {err.Line}: {err.ErrorText}{Environment.NewLine}";
                        }

                        // Because we have errors, remove the previous compilation if there is one.
                        if (compilation != null)
                        {
                            previousCompilations.Remove(compilation);
                        }
                        compilation = null;
                    }
                    else
                    {
                        // No errors.
                        // If we don't have a previous compilation, create one.
                        if (compilation == null)
                        {
                            compilation = new PreviousCompilation()
                            {
                                ModelFullPath = Apsim.FullPath(model)
                            };
                            previousCompilations.Add(compilation);
                        }

                        // Set the compilation properties.
                        compilation.Code             = code;
                        compilation.CompiledAssembly = result.CompiledAssembly;
                    }
                }
                else
                {
                    newlyCompiled = false;
                }

                if (compilation != null)
                {
                    // We have a compiled assembly so get the class name.
                    var regEx = new Regex(@"class\s+(\w+)\s");
                    var match = regEx.Match(code);
                    if (!match.Success)
                    {
                        throw new Exception($"Cannot find a class declaration in script:{Environment.NewLine}{code}");
                    }
                    var className = match.Groups[1].Value;

                    // Create an instance of the class and give it to the model.
                    var instanceType = compilation.CompiledAssembly.GetTypes().ToList().Find(t => t.Name == className);
                    return(new Results(compilation.CompiledAssembly, instanceType.FullName, newlyCompiled));
                }
                else
                {
                    return(new Results(errors));
                }
            }

            return(null);
        }
Esempio n. 9
0
        /// <summary>Run the simulation. Will throw on error.</summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="System.Exception">
        /// </exception>
        public void Run(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            try
            {
                StartRun();
                DoRun(sender);
                CleanupRun();
            }
            catch (ApsimXException err)
            {
                DataStore store = new DataStore(this);

                string Msg = "ERROR in file: " + FileName + "\r\n" +
                             "Simulation name: " + Name + "\r\n";
                Msg += err.Message;
                if (err.InnerException != null)
                {
                    Msg += "\r\n" + err.InnerException.Message + "\r\n" + err.InnerException.StackTrace;
                }
                else
                {
                    Msg += "\r\n" + err.StackTrace;
                }

                string modelFullPath = string.Empty;
                if (err.model != null)
                {
                    modelFullPath = Apsim.FullPath(err.model);
                }
                store.WriteMessage(Name, Clock.Today, modelFullPath, err.Message, DataStore.ErrorLevel.Error);
                store.Disconnect();
                CleanupRun();
                throw new Exception(Msg);
            }
            catch (Exception err)
            {
                DataStore store = new DataStore(this);

                string Msg = "ERROR in file: " + FileName + "\r\n" +
                             "Simulation name: " + Name + "\r\n";
                Msg += err.Message;
                if (err.InnerException != null)
                {
                    Msg += "\r\n" + err.InnerException.Message + "\r\n" + err.InnerException.StackTrace;
                }
                else
                {
                    Msg += "\r\n" + err.StackTrace;
                }

                store.WriteMessage(Name, Clock.Today, "Unknown", err.Message, DataStore.ErrorLevel.Error);
                store.Disconnect();

                CleanupRun();
                throw new Exception(Msg);
            }
            if (e != null)
            {
                e.Result = this;
            }
        }
Esempio n. 10
0
        /// <summary>Run the simulation. Will throw on error.</summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="System.Exception">
        /// </exception>
        public void Run(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            try
            {
                StartRun();
                DoRun(sender);
                CleanupRun(null);
            }
            catch (ApsimXException err)
            {
                DateTime errorDate = Clock.Today;

                string Msg = "ERROR in file: " + FileName + "\r\n" +
                             "Simulation name: " + Name + "\r\n";
                Msg += err.Message;
                if (err.InnerException != null)
                {
                    Msg += "\r\n" + err.InnerException.Message + "\r\n" + err.InnerException.StackTrace;
                }
                else
                {
                    Msg += "\r\n" + err.StackTrace;
                }

                string modelFullPath = string.Empty;
                if (err.model != null)
                {
                    modelFullPath = Apsim.FullPath(err.model);
                }

                ErrorMessage = Msg;
                ISummary summary = Apsim.Find(this, typeof(Summary)) as ISummary;
                summary.WriteMessage(this, Msg);
                CleanupRun(Msg);

                throw new Exception(Msg);
            }
            catch (Exception err)
            {
                DateTime errorDate = Clock.Today;
                string   Msg       = "ERROR in file: " + FileName + "\r\n" +
                                     "Simulation name: " + Name + "\r\n";
                Msg += err.Message;
                if (err.InnerException != null)
                {
                    Msg += "\r\n" + err.InnerException.Message + "\r\n" + err.InnerException.StackTrace;
                }
                else
                {
                    Msg += "\r\n" + err.StackTrace;
                }

                ErrorMessage = Msg;
                ISummary summary = Apsim.Find(this, typeof(Summary)) as ISummary;
                summary.WriteMessage(this, Msg);
                CleanupRun(Msg);

                throw new Exception(Msg);
            }
            if (e != null)
            {
                e.Result = this;
            }
        }