Ejemplo n.º 1
0
        /// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary>
        /// <param name="tags">The list of tags to add to.</param>
        /// <param name="headingLevel">The level (e.g. H2) of the headings.</param>
        /// <param name="indent">The level of indentation 1, 2, 3 etc.</param>
        public void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent)
        {
            if (IncludeInDocumentation)
            {
                // add a heading.
                tags.Add(new AutoDocumentation.Heading(Name, headingLevel));

                // write memos.
                foreach (IModel memo in Apsim.Children(this, typeof(Memo)))
                {
                    AutoDocumentation.DocumentModel(memo, tags, headingLevel + 1, indent);
                }

                // add graph and table.
                if (XYPairs != null)
                {
                    IVariable xProperty = Apsim.GetVariableObject(this, XProperty);
                    string    xName     = XProperty;
                    if (xProperty != null && xProperty.UnitsLabel != string.Empty)
                    {
                        xName += " " + xProperty.UnitsLabel;
                    }

                    tags.Add(new AutoDocumentation.Paragraph("<i>" + Name + "</i> is calculated as a function of <i>" + StringUtilities.RemoveTrailingString(XProperty, ".Value()") + "</i>", indent));

                    tags.Add(new AutoDocumentation.GraphAndTable(XYPairs, string.Empty, xName, LookForYAxisTitle(this), indent));
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Apply commands.
        /// </summary>
        /// <param name="model">The underlying model to apply the commands to</param>
        public void Apply(Model model)
        {
            if (this.Commands != null)
            {
                foreach (string command in this.Commands)
                {
                    string propertyName  = command;
                    string propertyValue = StringUtilities.SplitOffAfterDelimiter(ref propertyName, "=");

                    propertyName  = propertyName.TrimEnd();
                    propertyValue = propertyValue.TrimEnd();

                    if (propertyName != string.Empty && propertyValue != string.Empty)
                    {
                        IVariable property = Apsim.GetVariableObject(model, propertyName) as IVariable;
                        if (property != null)
                        {
                            this.oldPropertyValues.Add(property.Value);
                            property.Value = propertyValue;
                            this.properties.Add(property);
                        }
                        else
                        {
                            throw new ApsimXException(this, "While applying cultivar '" + Name + "', could not find property name '" + propertyName + "'");
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Look for an x axis title and units.
        /// </summary>
        /// <returns>The x axis title or null if not found.</returns>
        private string LookForXAxisTitle()
        {
            // See if parent has an XProperty property
            PropertyInfo xProperty = xYPairs.Parent.GetType().GetProperty("XProperty");

            if (xProperty != null)
            {
                string    propertyName = xProperty.GetValue(xYPairs.Parent, null).ToString();
                IVariable variable     = Apsim.GetVariableObject(xYPairs, propertyName);
                if (variable != null && variable.UnitsLabel != null)
                {
                    return(propertyName + " " + variable.UnitsLabel);
                }

                return(propertyName);
            }
            else if (xYPairs.Parent is AirTemperatureFunction)
            {
                return("Mean air temperature (oC)");
            }
            else if (xYPairs.Parent is SoilTemperatureWeightedFunction)
            {
                return("Weighted soil temperature (oC)");
            }
            else if (xYPairs.Parent is WeightedTemperatureFunction)
            {
                return("Weighted air temperature (oC)");
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Constructor for a plain report variable.
        /// </summary>
        /// <param name="variableName">The name of the APSIM variable to retrieve</param>
        /// <param name="columnName">The column name to write to the output</param>
        /// <param name="frequenciesFromReport">Reporting frequencies</param>
        /// <param name="parentModel">The parent model</param>
        private ReportColumn(string variableName, string columnName, string[] frequenciesFromReport, IModel parentModel)
        {
            Values            = new List <object>();
            this.variableName = variableName;
            this.Name         = columnName;
            this.parentModel  = parentModel;
            this.reportingFrequencies.AddRange(frequenciesFromReport);
            this.clock = Apsim.Find(parentModel, typeof(Clock)) as Clock;

            try
            {
                IVariable var = Apsim.GetVariableObject(parentModel, variableName);
                if (var != null)
                {
                    Units = var.UnitsLabel;
                }
            }
            // Exceptions may arise when we are setting up at the start of simulation, since some of the other model
            // components might not be fully initialized. If that's the case, we just fail silently and don't
            // worry about determining units of measurement.
            catch (Exception) { }

            foreach (string frequency in this.reportingFrequencies)
            {
                Apsim.Subscribe(parentModel, frequency, this.OnReportFrequency);
            }
        }
Ejemplo n.º 5
0
        /// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary>
        /// <param name="tags">The list of tags to add to.</param>
        /// <param name="headingLevel">The level (e.g. H2) of the headings.</param>
        /// <param name="indent">The level of indentation 1, 2, 3 etc.</param>
        public override void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent)
        {
            // add a heading.
            tags.Add(new AutoDocumentation.Heading(Name, headingLevel));

            // add graph and table.
            if (XYPairs != null)
            {
                IVariable xProperty = Apsim.GetVariableObject(this, XProperty);
                string    xName     = XProperty;
                if (xProperty != null && xProperty.Units != string.Empty)
                {
                    xName += " (" + xProperty.Units + ")";
                }

                tags.Add(new AutoDocumentation.Paragraph("<i>" + Name + "</i> is calculated as a function of <i>" + xName + "</i>", indent));

                // write memos.
                foreach (IModel memo in Apsim.Children(this, typeof(Memo)))
                {
                    memo.Document(tags, -1, indent);
                }

                tags.Add(new AutoDocumentation.GraphAndTable(XYPairs, string.Empty, xName, Name, indent));
            }
        }
Ejemplo n.º 6
0
        public static ReportColumn Create(string descriptor, IClock clock, IStorageWriter storage, ILocator locator, IEvent events)
        {
            string columnName = StringUtilities.RemoveWordAfter(ref descriptor, "as");
            object to         = StringUtilities.RemoveWordAfter(ref descriptor, "to");
            object from       = StringUtilities.RemoveWordAfter(ref descriptor, "from");

            if (clock is IModel)
            {
                if (from != null)
                {
                    IVariable fromValue = Apsim.GetVariableObject(clock as IModel, from.ToString());
                    if (fromValue != null)
                    {
                        from = fromValue;
                    }
                }
                if (to != null)
                {
                    IVariable toValue = Apsim.GetVariableObject(clock as IModel, to.ToString());
                    if (toValue != null)
                    {
                        to = toValue;
                    }
                }
            }
            string aggregationFunction = StringUtilities.RemoveWordBefore(ref descriptor, "of");

            string variableName = descriptor;  // variable name is what is left over.

            // specify a column heading if alias was not specified.
            if (columnName == null)
            {
                // Look for an array specification. The aim is to encode the starting
                // index of the array into the column name. e.g.
                // for a variableName of [2:4], columnName = [2]
                // for a variableName of [3:], columnName = [3]
                // for a variableName of [:5], columnNamne = [0]

                Regex regex = new Regex("\\[([0-9]):*[0-9]*\\]");

                columnName = regex.Replace(variableName.Replace("[:", "[1:"), "($1)");

                // strip off square brackets.
                columnName = columnName.Replace("[", string.Empty).Replace("]", string.Empty);

                // change any curly brackets back to squares.
                // columnName = columnName.Replace("{", "[").Replace("}", "]");
            }

            if (aggregationFunction != null)
            {
                return(new ReportColumn(aggregationFunction, variableName, columnName, from, to, clock, storage, locator, events));
            }
            else
            {
                return(new ReportColumn(variableName, columnName, clock, storage, locator, events));
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Create and return a new Output object for member
        /// </summary>
        /// <param name="typeToDocument">The type of object to inspect.</param>
        /// <param name="typeofProperties">The type of properties to include in the return table.</param>
        private List <IVariable> GetParameters(object objectToDocument)
        {
            var parameters = new List <IVariable>();

            foreach (var parameterName in parameterNames)
            {
                var parameter = Apsim.GetVariableObject(objectToDocument as IModel, parameterName);
                if (parameter != null)
                {
                    parameters.Add(parameter);
                }
            }

            return(parameters);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Constructor for an aggregated column.
        /// </summary>
        /// <param name="aggregationFunction">The aggregation function</param>
        /// <param name="variableName">The name of the APSIM variable to retrieve</param>
        /// <param name="columnName">The column name to write to the output</param>
        /// <param name="from">The beginning of the capture window</param>
        /// <param name="to">The end of the capture window</param>
        /// <param name="frequenciesFromReport">Reporting frequencies</param>
        /// <param name="parentModel">The parent model</param>
        /// <returns>The newly created ReportColumn</returns>
        private ReportColumn(string aggregationFunction, string variableName, string columnName, string from, string to, string[] frequenciesFromReport, IModel parentModel)
        {
            Values = new List <object>();

            this.aggregationFunction = aggregationFunction;
            this.variableName        = variableName;
            this.Name            = columnName;
            this.parentModel     = parentModel;
            this.inCaptureWindow = false;
            this.reportingFrequencies.AddRange(frequenciesFromReport);
            this.clock = Apsim.Find(parentModel, typeof(Clock)) as Clock;

            try
            {
                IVariable var = Apsim.GetVariableObject(parentModel, variableName);
                if (var != null)
                {
                    Units = var.UnitsLabel;
                }
            }
            catch (Exception) { }

            Apsim.Subscribe(parentModel, "[Clock].StartOfDay", this.OnStartOfDay);
            Apsim.Subscribe(parentModel, "[Clock].DoReportCalculations", this.OnEndOfDay);

            if (DateTime.TryParse(from, out this.fromDate))
            {
                this.fromHasNoYear = !from.Contains(this.fromDate.Year.ToString());
            }
            else
            {
                Apsim.Subscribe(parentModel, from, this.OnBeginCapture);
            }

            if (DateTime.TryParse(to, out this.toDate))
            {
                this.toHasNoYear = !to.Contains(this.toDate.Year.ToString());
            }
            else
            {
                Apsim.Subscribe(parentModel, to, this.OnEndCapture);
            }

            foreach (string frequency in this.reportingFrequencies)
            {
                Apsim.Subscribe(parentModel, frequency, this.OnReportFrequency);
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Edits a single apsimx file according to the changes specified in the config file.
        /// </summary>
        /// <param name="apsimxFileName">Path to an .apsimx file.</param>
        /// <param name="factors">Factors to apply to the file.</param>
        private static void EditFile(string apsimxFileName, List <CompositeFactor> factors)
        {
            Simulations file = FileFormat.ReadFromFile <Simulations>(fileName, out List <Exception> errors);

            if (errors != null && errors.Count > 0)
            {
                throw new Exception($"Error reading file ${apsimxFileName}: {errors[0].ToString()}");
            }

            foreach (CompositeFactor factor in factors)
            {
                IVariable variable = Apsim.GetVariableObject(file, factor.Paths[0]);
                variable.Value = ReflectionUtilities.StringToObject(variable.DataType, factor.Values[0].ToString());
            }
            file.Write(apsimxFileName);
        }
Ejemplo n.º 10
0
        public static ReportColumn Create(string descriptor, IClock clock, IStorageWriter storage, ILocator locator, IEvent events)
        {
            string columnName = RemoveWordAfter(ref descriptor, "as");
            object to         = RemoveWordAfter(ref descriptor, "to");
            object from       = RemoveWordAfter(ref descriptor, "from");

            if (clock is IModel)
            {
                if (from != null)
                {
                    IVariable fromValue = Apsim.GetVariableObject(clock as IModel, from.ToString());
                    if (fromValue != null)
                    {
                        from = fromValue;
                    }
                }
                if (to != null)
                {
                    IVariable toValue = Apsim.GetVariableObject(clock as IModel, to.ToString());
                    if (toValue != null)
                    {
                        to = toValue;
                    }
                }
            }
            string aggregationFunction = RemoveWordBefore(ref descriptor, "of");

            string variableName = descriptor;  // variable name is what is left over.

            // specify a column heading if alias was not specified.
            if (columnName == null)
            {
                columnName = variableName.Replace("[", string.Empty).Replace("]", string.Empty);
            }

            if (aggregationFunction != null)
            {
                return(new ReportColumn(aggregationFunction, variableName, columnName, from, to, clock, storage, locator, events));
            }
            else
            {
                return(new ReportColumn(variableName, columnName, clock, storage, locator, events));
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Apply commands.
        /// </summary>
        /// <param name="model">The underlying model to apply the commands to</param>
        public void Apply(Model model)
        {
            if (this.Commands != null)
            {
                foreach (string command in this.Commands)
                {
                    string propertyName  = command;
                    string propertyValue = StringUtilities.SplitOffAfterDelimiter(ref propertyName, "=");

                    propertyName  = propertyName.TrimEnd();
                    propertyValue = propertyValue.TrimEnd();

                    if (propertyName != string.Empty && propertyValue != string.Empty)
                    {
                        IVariable property = Apsim.GetVariableObject(model, propertyName) as IVariable;
                        if (property == null)
                        {
                            throw new Exception("Cannot find cultivar property: " + propertyName);
                        }
                        if (property.GetType() != null)
                        {
                            object oldValue = property.Value;
                            if (oldValue is string || oldValue.GetType().IsArray || !oldValue.GetType().IsClass)
                            {
                                this.oldPropertyValues.Add(oldValue);
                                property.Value = propertyValue;
                                this.properties.Add(property);
                            }
                            else
                            {
                                throw new ApsimXException(this, "Invalid type for setting cultivar parameter: " + propertyName +
                                                          ". Must be a built-in type e.g. double");
                            }
                        }
                        else
                        {
                            throw new ApsimXException(this, "While applying cultivar '" + Name + "', could not find property name '" + propertyName + "'");
                        }
                    }
                }
            }
        }
Ejemplo n.º 12
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;
                }
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Edits a single apsimx file according to the changes specified in the config file.
        /// </summary>
        /// <param name="apsimxFileName">Path to an .apsimx file.</param>
        /// <param name="factors">Factors to apply to the file.</param>
        private static void EditFile(string apsimxFileName, List <CompositeFactor> factors)
        {
            Simulations file = FileFormat.ReadFromFile <Simulations>(fileName, out List <Exception> errors);

            if (errors != null && errors.Count > 0)
            {
                throw new Exception($"Error reading file ${apsimxFileName}: {errors[0].ToString()}");
            }

            foreach (CompositeFactor factor in factors)
            {
                IVariable variable = Apsim.GetVariableObject(file, factor.Paths[0]);
                if (variable == null)
                {
                    throw new Exception($"Invalid path: {factor.Paths[0]}");
                }

                string value = factor.Values[0].ToString();
                string absolutePath;
                try
                {
                    absolutePath = PathUtilities.GetAbsolutePath(value, Directory.GetCurrentDirectory());
                }
                catch
                {
                    absolutePath = null;
                }

                string[] parts = value.Split(';');
                if (parts != null && parts.Length == 2)
                {
                    string fileName         = parts[0];
                    string absoluteFileName = PathUtilities.GetAbsolutePath(fileName, Directory.GetCurrentDirectory());
                    string modelPath        = parts[1];

                    if (File.Exists(fileName))
                    {
                        ReplaceModelFromFile(file, factor.Paths[0], fileName, modelPath);
                    }
                    else if (File.Exists(absoluteFileName))
                    {
                        ReplaceModelFromFile(file, factor.Paths[0], absoluteFileName, modelPath);
                    }
                    else
                    {
                        variable.Value = ReflectionUtilities.StringToObject(variable.DataType, value);
                    }
                }
                else if (File.Exists(value) && variable.Value is IModel)
                {
                    ReplaceModelFromFile(file, factor.Paths[0], value, null);
                }
                else if (File.Exists(absolutePath) && variable.Value is IModel)
                {
                    ReplaceModelFromFile(file, factor.Paths[0], absolutePath, null);
                }
                else
                {
                    variable.Value = ReflectionUtilities.StringToObject(variable.DataType, value);
                }
            }
            file.Write(apsimxFileName);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Initialise the column instance.
        /// </summary>
        /// <param name="aggFunction">The aggregation function.</param>
        /// <param name="varName">The name of the variable to get from APSIM.</param>
        /// <param name="on">The collection event.</param>
        /// <param name="alias">The alias.</param>
        /// <param name="from">The from variable.</param>
        /// <param name="to">The to variable.</param>
        private void Initialise(string aggFunction, string varName, string on, string alias,
                                string from, string to)
        {
            aggregationFunction = aggFunction;
            variableName        = varName;
            fromString          = from;
            toString            = to;
            Name = alias;

            // specify a column heading if alias was not specified.
            if (string.IsNullOrEmpty(Name))
            {
                // Look for an array specification. The aim is to encode the starting
                // index of the array into the column name. e.g.
                // for a variableName of [2:4], columnName = [2]
                // for a variableName of [3:], columnName = [3]
                // for a variableName of [:5], columnNamne = [0]

                Regex regex = new Regex("\\[([0-9]):*[0-9]*\\]");

                Name = regex.Replace(variableName.Replace("[:", "[1:"), "($1)");

                // strip off square brackets.
                Name = Name.Replace("[", string.Empty).Replace("]", string.Empty);
            }

            // Try and get units.
            try
            {
                IVariable var = locator.GetObject(variableName);
                if (var != null)
                {
                    Units = var.UnitsLabel;
                    if (Units != null && Units.StartsWith("(") && Units.EndsWith(")"))
                    {
                        Units = Units.Substring(1, Units.Length - 2);
                    }
                }
            }
            catch (Exception)
            {
            }

            if (string.IsNullOrEmpty(fromString))
            {
                inCaptureWindow = true;
            }
            else
            {
                // temporarly aggregated variable
                // subscribe to the capture event
                var collectionEventName = "[Clock].DoReportCalculations";
                if (!string.IsNullOrEmpty(on))
                {
                    collectionEventName = on;
                }
                events.Subscribe(collectionEventName, OnDoReportCalculations);

                // subscribe to the start of day event so that we can determine if we're in the capture window.
                events.Subscribe("[Clock].DoDailyInitialisation", OnStartOfDay);

                fromVariable = Apsim.GetVariableObject(clock as IModel, fromString);
                toVariable   = Apsim.GetVariableObject(clock as IModel, toString);
                if (fromVariable != null)
                {
                    // A from variable name  was specified.
                }
                else if (DateTime.TryParse(fromString, out DateTime date))
                {
                    // The from date is a static, hardcoded date string. ie 1-Jan, 1/1/2012, etc.
                    fromVariable = new VariableObject(date);

                    // If the date string does not contain a year (ie 1-Jan), we ignore year and
                    fromHasNoYear = !fromString.Contains(date.Year.ToString());
                }
                else
                {
                    // Assume the string is an event name.
                    events.Subscribe(fromString, OnFromEvent);
                    inCaptureWindow = true;
                }

                if (toVariable != null)
                {
                    // A to variable name  was specified.
                }
                else if (DateTime.TryParse(toString, out DateTime date))
                {
                    // The from date is a static, hardcoded date string. ie 1-Jan, 1/1/2012, etc.
                    toVariable = new VariableObject(date);

                    // If the date string does not contain a year (ie 1-Jan), we ignore year and
                    toHasNoYear = !toString.Contains(date.Year.ToString());
                }
                else
                {
                    // Assume the string is an event name.
                    events.Subscribe(toString, OnToEvent);
                }
            }
        }