/// <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="clock">An instance of a clock model</param> /// <param name="storage">An instance of a storage service</param> /// <param name="locator">An instance of a locator service</param> /// <param name="events">An instance of an events service</param> private ReportColumn(string variableName, string columnName, IClock clock, IStorageWriter storage, ILocator locator, IEvent events) { this.variableName = variableName.Trim(); this.Name = columnName; this.locator = locator; this.clock = clock; 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) { } }
/// <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.GetObjectProperties(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 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); events.Subscribe("[Clock].EndOfSimulation", OnEndOfSimulation); fromVariable = (clock as IModel).FindByPath(fromString); toVariable = (clock as IModel).FindByPath(toString); if (fromVariable != null) { // A from variable name was specified. } else if (DateTime.TryParseExact(fromString, "d-MMM", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date) || DateTime.TryParse(fromString, out 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.TryParseExact(toString, "d-MMM", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date) || DateTime.TryParse(toString, out 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); } } }
/// <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="clock">An instance of a clock model</param> /// <param name="storage">An instance of a storage service</param> /// <param name="locator">An instance of a locator service</param> /// <param name="events">An instance of an events service</param> /// <returns>The newly created ReportColumn</returns> private ReportColumn(string aggregationFunction, string variableName, string columnName, object from, object to, IClock clock, IStorageWriter storage, ILocator locator, IEvent events) { this.aggregationFunction = aggregationFunction; this.variableName = variableName; this.Name = columnName; this.locator = locator; this.clock = clock; 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) { } events.Subscribe("[Clock].DoReportCalculations", OnDoReportCalculations); events.Subscribe("[Clock].DoDailyInitialisation", OnStartOfDay); if (from == null || string.IsNullOrEmpty(from.ToString())) { throw new Exception("No 'from' clause was specified in temporal aggregation"); } if (DateTime.TryParse(from.ToString(), out DateTime date)) { // The from date is a static, hardcoded date string. ie 1-Jan, 1/1/2012, etc. this.fromVariable = new VariableObject(date); // If the date string does not contain a year (ie 1-Jan), we ignore year and this.fromHasNoYear = !from.ToString().Contains(date.Year.ToString()); } else if (from is IVariable) { this.fromVariable = from as IVariable; } else { // Assume the string is an event name. events.Subscribe(from.ToString(), OnFromEvent); inCaptureWindow = true; } if (to == null || string.IsNullOrEmpty(to.ToString())) { throw new Exception("No 'to' clause was specified in temporal aggregation"); } if (DateTime.TryParse(to.ToString(), out date)) { // The from date is a static, hardcoded date string. ie 1-Jan, 1/1/2012, etc. this.toVariable = new VariableObject(date); // If the date string does not contain a year (ie 1-Jan), we ignore year and this.toHasNoYear = !to.ToString().Contains(date.Year.ToString()); } else if (to is IVariable) { this.toVariable = to as IVariable; } else { // Assume the string is an event name. events.Subscribe(to.ToString(), OnToEvent); } }