private void AddFieldNameToAxisTitle(Steema.TeeChart.Axis Axis, string FieldName) { // Add the specified fieldname to the specified axis. Axis.Visible = true; if (Axis.Title.Text.Length > 0 && Axis.Title.Text[0] == '[' && FieldName != "") { string St = Axis.Title.Text; string Title = StringManip.SplitOffBracketedValue(ref St, '[', ']'); string[] FieldNames = Title.Split(",".ToCharArray()); if (FieldName != "seriesname") { bool Found = false; foreach (string F in FieldNames) { if (F.Trim().ToLower() == FieldName.ToLower()) { Found = true; } } if (!Found) { if (Title != "") { Title = Title + ", "; } Title = Title + FieldName; Axis.Title.Text = "[" + Title + "]"; } } } }
/// <summary> /// A function for reading the filenames in a patch and returning their revision number. /// </summary> public static string[] FilesInPatch(string PatchFileName, string RootDirectory) { List <string> FileNames = new List <string>(); StreamReader Patch = new StreamReader(PatchFileName); // Go looking for lines like: // --- Tests/RunAllPlant2Tests.txt (revision 1790) while (!Patch.EndOfStream) { string Line = Patch.ReadLine(); if (Line.Contains("--- ")) { Line = Line.Remove(0, 4); string FileName = Line; string BracketedValue = StringManip.SplitOffBracketedValue(ref FileName, '(', ')'); string[] RevisionBits = BracketedValue.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (RevisionBits.Length == 2) { FileName = Path.Combine(RootDirectory, FileName); FileName = FileName.Replace("/", "\\"); // get rid of yucky unix slashes. FileNames.Add(FileName); } } } Patch.Close(); return(FileNames.ToArray()); }
/// <summary> /// Transfer a single parameter value (as specified by oldnode and oldpath) to a new /// node and path. /// </summary> private static void TransferParameter(XmlNode OldNode, string OldPath, XmlNode NewNode, string NewPath) { string Value = XmlHelper.Value(OldNode, OldPath); StringManip.SplitOffBracketedValue(ref Value, '(', ')'); XmlHelper.SetValue(NewNode, NewPath, Value); }
/// <summary> /// Remove comments and units from the specified string. /// </summary> private static string RemoveComment(string Value) { int PosComment = Value.IndexOf('!'); if (PosComment != -1) { Value = Value.Remove(PosComment); } StringManip.SplitOffBracketedValue(ref Value, '(', ')'); return(Value); }
/// <summary> /// Convert the specified words to the specified column types and return their values. /// </summary> private object[] ConvertWordsToObjects(StringCollection Words, Type[] ColumnTypes) { object[] Values = new object[Words.Count]; for (int w = 0; w != Words.Count; w++) { try { Words[w] = Words[w].Trim(); if (Words[w] == "?" || Words[w] == "*" || Words[w] == "") { Values[w] = DBNull.Value; } else if (ColumnTypes[w] == typeof(DateTime)) { // Need to get a sanitised date e.g. d/M/yyyy string DateFormat = Units[w].ToLower(); DateFormat = StringManip.SplitOffBracketedValue(ref DateFormat, '(', ')'); DateFormat = DateFormat.Replace("mmm", "MMM"); DateFormat = DateFormat.Replace("mm", "m"); DateFormat = DateFormat.Replace("dd", "d"); DateFormat = DateFormat.Replace("m", "M"); if (DateFormat == "") { DateFormat = "d/M/yyyy"; } DateTime Value = DateTime.ParseExact(Words[w], DateFormat, null); Values[w] = Value; } else if (ColumnTypes[w] == typeof(System.Double)) { double Value; if (double.TryParse(Words[w], out Value)) { Values[w] = Value; } else { Values[w] = DBNull.Value; } } else { Values[w] = Words[w]; } } catch (Exception) { Values[w] = DBNull.Value; } } return(Values); }
/// <summary> /// Return the PH units from the specified row on the specified table. /// </summary> private static Analysis.PHUnitsEnum GetPHUnits(DataTable Table, int Row) { if (Table.Columns.Contains("PHCode")) { string Code = GetStringValue(Table, Row, "PHCode"); string Units = StringManip.SplitOffBracketedValue(ref Code, '(', ')'); if (Units == "CaCl2") { return(Analysis.PHUnitsEnum.CaCl2); } } return(Analysis.PHUnitsEnum.Water); }
/// <summary> /// Return the OC units from the specified row on the specified table. /// </summary> private static SoilOrganicMatter.OCUnitsEnum GetOCUnits(DataTable Table, int Row) { if (Table.Columns.Contains("OCCode")) { string Code = GetStringValue(Table, Row, "OCCode"); string Units = StringManip.SplitOffBracketedValue(ref Code, '(', ')'); if (Units == "Walkley Black %") { return(SoilOrganicMatter.OCUnitsEnum.WalkleyBlack); } } return(SoilOrganicMatter.OCUnitsEnum.Total); }
/// <summary> /// Return a list of code values for the specified variable. /// </summary> private static string[] GetCodeValues(DataTable Table, string VariableName, int NumRows, int StartRow) { if (!Table.Columns.Contains(VariableName)) { return(null); } string[] Codes = DataTableUtility.GetColumnAsStrings(Table, VariableName, NumRows, StartRow); for (int i = 0; i != Codes.Length; i++) { StringManip.SplitOffBracketedValue(ref Codes[i], '(', ')'); } Codes = APSIMChangeTool.CodeToMetaData(Codes); if (MathUtility.ValuesInArray(Codes)) { return(Codes); } return(null); }
/// <summary> /// A utility function to return true if the simulation is currently between /// the specified start and end stages. /// </summary> public bool Between(String Start, String End) { string StartFractionSt = StringManip.SplitOffBracketedValue(ref Start, '(', ')'); double StartFraction = 0; if (StartFractionSt != "") { StartFraction = Convert.ToDouble(StartFractionSt); } string EndFractionSt = StringManip.SplitOffBracketedValue(ref Start, '(', ')'); double EndFraction = 0; if (EndFractionSt != "") { EndFraction = Convert.ToDouble(EndFractionSt); } int StartPhaseIndex = Phases.IndexOf(PhaseStartingWith(Start)); int EndPhaseIndex = Phases.IndexOf(PhaseEndingWith(End)); int CurrentPhaseIndex = Phases.IndexOf(CurrentPhase); if (StartPhaseIndex == -1 || EndPhaseIndex == -1) { throw new Exception("Cannot test between stages " + Start + " " + End); } if (CurrentPhaseIndex == StartPhaseIndex) { return(CurrentPhase.FractionComplete >= StartFraction); } else if (CurrentPhaseIndex == EndPhaseIndex) { return(CurrentPhase.FractionComplete <= EndPhaseIndex); } else { return(CurrentPhaseIndex >= StartPhaseIndex && CurrentPhaseIndex <= EndPhaseIndex); } }
/// <summary> /// Update the total in the HeaderText property of the specified Column. /// </summary> /// <param name="Col"></param> private void UpdateTotal(DataGridViewColumn Col) { double Total = MathUtility.Sum(GridUtility.GetColumnAsDoubles(Grid, Col.Index)); Grid.EnableHeadersVisualStyles = false; if (Col.HeaderText.Contains("PAWC\r\n")) { int Pos = Col.HeaderText.IndexOf("\n"); Col.HeaderText = Col.HeaderText.Substring(0, Pos + 1) + Total.ToString("f1");// +" mm"; Col.HeaderCell.Style.ForeColor = Color.Red; } else if (Col.HeaderText.Contains("NO3\r\n") || Col.HeaderText.Contains("NH4\r\n")) { string headerText = Col.HeaderText; string units = "(" + StringManip.SplitOffBracketedValue(ref headerText, '(', ')') + ")"; int Pos = Col.HeaderText.IndexOf("\n"); Col.HeaderText = Col.HeaderText.Substring(0, Pos + 1) + (double.IsNaN(Total) ? string.Empty : Total.ToString("f1")) + " " + units; Col.HeaderCell.Style.ForeColor = Color.Red; } }
// -------------------------------------------------------------------- /// <summary> /// Go through all child XML nodes for the node passed in and set /// the corresponding property values in the Obj instance passed in. /// </summary> /// <param name="Obj"></param> /// <param name="Node"></param> /// <param name="HostComponent"></param> // -------------------------------------------------------------------- private void PopulateParams(Instance Obj, XmlNode Node, ApsimComponent ParentComponent) { // Look for an XmlNode param. If found then given it our current 'Node'. bool HavePassedXMLToObj = false; foreach (FactoryProperty Property in RegisteredProperties) { if ((String.Compare(Property.TypeName, "XmlNode", StringComparison.Ordinal) == 0) && (Property.OutputName.Contains(Node.Name))) { Property.SetObject(Node); HavePassedXMLToObj = true; } } // Go through all child XML nodes for the node passed in and set // the corresponding property values in the Obj instance passed in. if (!HavePassedXMLToObj) { foreach (XmlNode Child in Node.ChildNodes) { if (Child.GetType() != typeof(XmlComment)) { Type t = GetTypeOfChild(Child, Obj); if ((t != null) && (t.IsSubclassOf(typeof(Instance)) || t.IsClass)) { // Create a child instance - indirect recursion. Instance ChildInstance = CreateInstance(Child, Child, Obj, ParentComponent); Obj.Add(ChildInstance); FactoryProperty Parameter = FindProperty(Child); if (XmlHelper.Name(Child).Contains("[")) { String ArrayName = XmlHelper.Name(Child); StringManip.SplitOffBracketedValue(ref ArrayName, '[', ']'); XmlHelper.SetName(Child, ArrayName); Parameter = FindProperty(Child); if (Parameter != null) { Parameter.AddToList(ChildInstance); } else { // Parameter must be an array link to child nodes e.g. // [Link] LeafCohort[] InitialLeaves; } } else if ((Parameter != null) && (Parameter.IsParam && !Parameter.TypeName.Contains("System::"))) { Parameter.SetObject(ChildInstance.Model); } } else if (Child.Name == "Memo") { // Ignore memo fields. } else { FactoryProperty Parameter = FindProperty(Child); if (Parameter != null) { Parameter.Name = XmlHelper.Name(Child); Parameter.Set(Child); } } } } } }
/// <summary> /// Creates any classes that are of type [Link] in the model /// </summary> public void Resolve() { if (Field.Get == null) { Object ReferencedObject = null; // Load in the probe info assembly. //ProbeInfo = Assembly.LoadFile(Path.Combine(Configuration.ApsimDirectory(), "Model", "CSDotNetProxies.dll")); if (ProbeInfo == null) { ProbeInfo = Assembly.LoadFile(Path.Combine(Configuration.ApsimDirectory(), "Model", "DotNetProxies.dll")); } String TypeToFind = Field.Typ.Name; String NameToFind; if (LinkAttr.NamePath == null) { NameToFind = Field.Name; } else { NameToFind = LinkAttr.NamePath; } if (NameToFind == "My") { ReferencedObject = new ModelFramework.Component(In); } else if (IsAPSIMType(TypeToFind)) { if (LinkAttr.NamePath == null) { NameToFind = null; // default is not to use name. } string SystemName = Comp.Name.Substring(0, Math.Max(Comp.Name.LastIndexOf('.'), 0)); ReferencedObject = FindApsimObject(TypeToFind, NameToFind, SystemName, Comp); } else if (TypeToFind.Contains("[]")) { // e.g. TypeToFind == "LeafCohort[]" List <object> ReferencedObjects = new List <object>(); foreach (Instance Child in In.Children) { string ChildNameWithoutArray = Child.Name; StringManip.SplitOffBracketedValue(ref ChildNameWithoutArray, '[', ']'); if (ChildNameWithoutArray == NameToFind) { ReferencedObjects.Add(Child.Model); } } Array A = Array.CreateInstance(Field.Typ.GetElementType(), ReferencedObjects.Count) as Array; for (int i = 0; i < ReferencedObjects.Count; i++) { A.SetValue(ReferencedObjects[i], i); } ReferencedObject = A; } else { // Link is an Instance link - use name and type to find the object. ReferencedObject = FindInstanceObject(In, NameToFind, TypeToFind); } // Set the value of the [Link] field to the newly created object. if (ReferencedObject == null) { if (!LinkAttr.IsOptional) { throw new Exception("Cannot find [Link] for type: " + TypeToFind + " " + NameToFind + " in object: " + In.Name); } } else if (ReferencedObject is Instance) { Field.SetObject(((Instance)ReferencedObject).Model); } else { Field.SetObject(ReferencedObject); } } }
/// <summary> /// Return the value (using Reflection) of the specified property on the specified object. /// Returns null if not found. Examples of Names that can be found. /// Pod /// Environment.MeanT /// Organs[] /// Organs[AboveGround].Live /// Organs[AboveGround].Live.Wt /// Leaf.Leaves[Leaf.CurrentRank].CoverAbove /// Can return an Instance, an Entity or an object[] when an array specifier is present. /// </summary> public static object GetVariable(string NamePath, object RelativeTo) { Component My = null; if (RelativeTo is Component) { My = RelativeTo as Component; if ((My != null) && !NamePath.Contains("[")) { object v; My.GetObject(NamePath, out v); return(v); } } if (VarParts == null) { VarParts = new Dictionary <string, List <string> >(); } string[] Bits; //cache the list of names that are parsed here List <String> Parts; if (VarParts.TryGetValue(NamePath, out Parts)) { Bits = Parts.ToArray(); } else { Bits = StringManip.SplitStringHonouringBrackets(NamePath, '.', '[', ']'); VarParts.Add(NamePath, Bits.ToList()); } for (int i = 0; i < Bits.Length; i++) { string ArraySpecifier = ""; bool ArrayFound = Bits[i].Contains("["); if (ArrayFound) { ArraySpecifier = StringManip.SplitOffBracketedValue(ref Bits[i], '[', ']'); } object MatchingChild; if (RelativeTo is Component) { MatchingChild = (RelativeTo as Component).LinkByName(Bits[i]); // Try for a model name first. e.g. Root if (MatchingChild == null) { (RelativeTo as Component).GetObject(Bits[i], out MatchingChild); // may be a variable. e.g. Organs } } else { MatchingChild = Utility.GetValueOfFieldOrProperty(Bits[i], RelativeTo); } if (MatchingChild == null) { throw new Exception("Cannot find variable: " + NamePath); } // Look for array spec if (ArrayFound) { if (!(MatchingChild is IList)) { throw new Exception("Cannot specify an array on a non array variable. Name: " + NamePath); } IList Array = MatchingChild as IList; // First try and treat the ArraySpecifier as an integer index. // If that's not possible, then assume it is a reference to an integer variable // somewhere in the system. // If that's not possible then assume it is a type name e.g. AboveGround. int ArrayIndex; bool ok = int.TryParse(ArraySpecifier, out ArrayIndex); if (ArraySpecifier != "" && !ok && My != null) { object ArraySpec; ok = My.GetObject(ArraySpecifier, out ArraySpec); // Assume it is a simulation variable. if (ok && (ArraySpec is Int32 || ArraySpec is Double)) { ArrayIndex = Convert.ToInt32(ArraySpec); } else { ok = false; } } if (ok) { if (ArrayIndex < 0 || ArrayIndex >= Array.Count) { throw new Exception("Invalid index of " + ArrayIndex.ToString() + " found while indexing into variable: " + NamePath); } MatchingChild = Array[ArrayIndex]; } else { // Must be a type name. Go collect an array of objects of that type. List <object> ArrayOfType = new List <object>(); // Construct a name remainder. string RestOfName = null; for (int j = i + 1; j < Bits.Length; j++) { if (RestOfName != null) { RestOfName += "."; } RestOfName += Bits[j]; } foreach (object o in Array) { if (ArraySpecifier == "" || Utility.IsOfType(o.GetType(), ArraySpecifier)) { if (RestOfName == null) { ArrayOfType.Add(o); } else { object ChildObject = GetVariable(RestOfName, o); // recursion if (ChildObject != null) { ArrayOfType.Add(ChildObject); } } } } return(ArrayOfType.ToArray()); } } RelativeTo = MatchingChild; } // If we get this far then we've found a match. return(RelativeTo); }
/// <summary> /// User has changed the units. /// </summary> private void UnitsMenuItemClicked(object sender, ToolStripItemClickedEventArgs e) { if (e.ClickedItem.Text == "Set total") { string name = e.ClickedItem.Tag as string; string units = StringManip.SplitOffBracketedValue(ref name, '(', ')'); int colIndex; if (name == "NO3") { colIndex = 1; } else { colIndex = 2; } double total = MathUtility.Sum(GridUtility.GetColumnAsDoubles(Grid, colIndex)); string newTotalString = InputDialog.InputBox("Enter total " + name + " (" + units + ")", name, total.ToString("f1"), false); if (newTotalString != total.ToString("f1")) { double newTotal = Convert.ToDouble(newTotalString); // Make sure we have thickness values. string[] gridThicknessStrings = GridUtility.GetColumnAsStrings(Grid, 0); double[] gridThickness = Soil.ToThickness(gridThicknessStrings); double totalGridThickness = MathUtility.Sum(gridThickness); if (totalGridThickness == 0 || totalGridThickness == MathUtility.MissingValue || double.IsNaN(totalGridThickness)) { gridThickness = new double[1]; gridThickness[0] = MathUtility.Sum(Soil.Thickness); } double[] newValues; Sample sample = OurObject as Sample; if (total == 0 || double.IsNaN(total)) { // evenly distributed. newValues = new double[gridThickness.Length]; for (int i = 0; i < newValues.Length; i++) { newValues[i] = newTotal / newValues.Length; } } else { double scale = newTotal / total; // Need to scale the values. double[] values = GridUtility.GetColumnAsDoubles(Grid, colIndex); newValues = MathUtility.Multiply_Value(values, scale); } sample.Thickness = gridThickness; if (name == "NO3") { sample.NO3 = newValues; } else { sample.NH4 = newValues; } OnRefresh(); } } else { OnSave(); object Units = e.ClickedItem.Tag; MethodInfo UnitChangeMethod = (sender as ContextMenuStrip).Tag as MethodInfo; if (UnitChangeMethod.GetParameters().Length == 1) { UnitChangeMethod.Invoke(OurObject, new object[] { Units }); } else { UnitChangeMethod.Invoke(OurObject, new object[] { Units, Soil }); } OnRefresh(); } }
/// <summary> /// Extract the units from the specifeid column number. /// </summary> private string UnitsFromColumn(int Col) { string HeaderText = Grid.Columns[Col].HeaderText; return(StringManip.SplitOffBracketedValue(ref HeaderText, '(', ')')); }
private DataTable ProcessDepth(XmlNode Node) { // ------------------------------------------------- // The XmlNode is a GDDepth so go find a // nested source DataTable, add transpose the data // so that depth is a column and the depth variables // are also columns. // ------------------------------------------------- DataTable Data = GoFindChildDataTable(Node); if (Data == null || Data.Columns.Count == 0) { return(null); } DataTable NewData = new DataTable(); // copy profile fields from old datatable to new datatable and add new depth column. List <string> ProfileColumns = new List <string>(); NewData.Columns.Add("Date", Type.GetType("System.DateTime")); NewData.Columns.Add("Depth", Type.GetType("System.Single")); int NumLayers = 0; foreach (DataColumn Col in Data.Columns) { string ColumnName = Col.ColumnName; string ArraySpecString = StringManip.SplitOffBracketedValue(ref ColumnName, '(', ')'); int ArraySpec = 0; if (ArraySpecString != "") { ArraySpec = Convert.ToInt32(ArraySpecString); } if (ArraySpec == 1) { if (ColumnName.ToLower() != "dlayer") { ProfileColumns.Add(ColumnName); NewData.Columns.Add(ColumnName, Type.GetType("System.Single")); } } NumLayers = Math.Max(NumLayers, ArraySpec); } NewData.Columns.Add("Title", Type.GetType("System.String")); // Get a list of dates that we are to filter on. List <string> DateStrings = XmlHelper.Values(Node, "date"); DateTime[] Dates = new DateTime[DateStrings.Count]; for (int i = 0; i < DateStrings.Count; i++) { Dates[i] = DateTime.ParseExact(DateStrings[i], "d/M/yyyy", null); } for (int Row = 0; Row < Data.Rows.Count; Row++) { DateTime RowDate = DataTableUtility.GetDateFromRow(Data.Rows[Row]); if (Dates.Length == 0 || Array.IndexOf(Dates, RowDate) != -1) { double DepthSoFar = 0; for (int Layer = 1; Layer <= NumLayers; Layer++) { double PreviousDepth = DepthSoFar; DataRow NewRow = NewData.NewRow(); DepthSoFar += Convert.ToDouble(Data.Rows[Row]["dlayer(" + Layer.ToString() + ")"]); NewRow["Depth"] = (DepthSoFar + PreviousDepth) / 2; for (int Col = 0; Col < ProfileColumns.Count; Col++) { string ProfileColumnName = ProfileColumns[Col] + "(" + Layer.ToString() + ")"; if (Data.Columns.Contains(ProfileColumnName)) { NewRow[ProfileColumns[Col]] = Data.Rows[Row][ProfileColumnName]; } } NewRow["Date"] = RowDate; NewRow["Title"] = Data.Rows[Row]["Title"] + ", " + RowDate.ToShortDateString(); NewData.Rows.Add(NewRow); } } } return(NewData); }
/// <summary> /// Read in the APSIM header - headings/units and constants. /// </summary> private void ReadApsimHeader(StreamReaderRandomAccess In) { StringCollection ConstantLines = new StringCollection(); StringCollection HeadingLines = new StringCollection(); ReadApsimHeaderLines(In, ref ConstantLines, ref HeadingLines); bool TitleFound = false; foreach (string ConstantLine in ConstantLines) { string Line = ConstantLine; string Comment = StringManip.SplitOffAfterDelimiter(ref Line, "!"); Comment.Trim(); int PosEquals = Line.IndexOf('='); if (PosEquals != -1) { string Name = Line.Substring(0, PosEquals).Trim(); if (Name.ToLower() == "title") { TitleFound = true; Name = "Title"; } string Value = Line.Substring(PosEquals + 1).Trim(); string Unit = StringManip.SplitOffBracketedValue(ref Value, '(', ')'); _Constants.Add(new APSIMConstant(Name, Value, Unit, Comment)); } } if (HeadingLines.Count >= 2) { if (CSV) { HeadingLines[0] = HeadingLines[0].TrimEnd(','); HeadingLines[1] = HeadingLines[1].TrimEnd(','); Headings = new StringCollection(); Units = new StringCollection(); Headings.AddRange(HeadingLines[0].Split(",".ToCharArray())); Units.AddRange(HeadingLines[1].Split(",".ToCharArray())); for (int i = 0; i < Headings.Count; i++) { Headings[i] = Headings[i].Trim(); } for (int i = 0; i < Units.Count; i++) { Units[i] = Units[i].Trim(); } } else { Headings = StringManip.SplitStringHonouringQuotes(HeadingLines[0], " \t"); Units = StringManip.SplitStringHonouringQuotes(HeadingLines[1], " \t"); } TitleFound = TitleFound || StringManip.IndexOfCaseInsensitive(Headings, "title") != -1; if (Headings.Count != Units.Count) { throw new Exception("The number of headings and units doesn't match in file: " + _FileName); } } if (!TitleFound) { _Constants.Add(new APSIMConstant("Title", Path.GetFileNameWithoutExtension(_FileName), "", "")); } }
/// <summary> /// Called whenever the user interface wants us to refresh ourselves. /// </summary> override public void OnRefresh() { Properties.OnRefresh(); Properties.Visible = !Properties.IsEmpty; if (OurComponent.Type == "Sample") { HelpText = "These values are used to initialise the simulation. Sample date is not used by APSIM."; } else { HelpText = ""; } Grid.Columns.Clear(); OurObject = null; if (OurComponent.Type == "Sample") { OurObject = Soil.FindSample(OurComponent.Name); } else if (OurComponent.Type.StartsWith("Swim")) { PropertyInfo Property = Soil.Swim.GetType().GetProperty(OurComponent.Type); if (Property != null) { OurObject = Property.GetValue(Soil.Swim, null); } } else { PropertyInfo Property = Soil.GetType().GetProperty(OurComponent.Type); if (Property != null) { OurObject = Property.GetValue(Soil, null); } } if (OurObject == null) { throw new Exception("Cannot find a soil object named: " + OurComponent.Type); } SetupGrid(); Grid.RowCount = 30; foreach (DataGridViewColumn Col in Grid.Columns) { Col.SortMode = DataGridViewColumnSortMode.NotSortable; } Grid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); foreach (DataGridViewColumn Col in Grid.Columns) { Col.Width += 10; } if (OurComponent.Type == "Water" || OurComponent.Type == "SoilOrganicMatter") { Graph.Populate(Soil, OurComponent.Type); } else { // get a table from the grid and remove totals from no3 and nh4 columns. DataTable table = Grid.ToTable(); if (OurObject is Sample && table.Columns.Count > 2) { string name = table.Columns[1].ColumnName; string units = StringManip.SplitOffBracketedValue(ref name, '(', ')'); table.Columns[1].ColumnName = "NO3 (" + units + ")"; name = table.Columns[2].ColumnName; units = StringManip.SplitOffBracketedValue(ref name, '(', ')'); table.Columns[2].ColumnName = "NH4 (" + units + ")"; } Graph.Populate(table, OurComponent.Type, Soil); } Label.Visible = Label.Text != ""; }
static private string CreateSoilXmlFromSpreadsheet(DataTable Table, ref int Row) { // Create a new soil from the the specified table. // At end of this method, row will be pointing to the next // soil. string name = GetStringValue(Table, "Name", Row); if (name == "") { throw new Exception("Cannot find a soil name"); } XmlDocument Doc = new XmlDocument(); XmlNode SoilNode = Doc.CreateElement("Soil"); XmlHelper.SetName(SoilNode, name); Soil NewSoil = new Soil(SoilNode); NewSoil.State = GetStringValue(Table, "State", Row); NewSoil.Region = GetStringValue(Table, "Region", Row); NewSoil.NearestTown = GetStringValue(Table, "NearestTown", Row); NewSoil.Site = GetStringValue(Table, "Site", Row); NewSoil.ApsoilNumber = GetStringValue(Table, "APSoilNumber", Row); NewSoil.Classification = GetStringValue(Table, "Classification", Row); NewSoil.Latitude = MathUtility.Round(GetDoubleValue(Table, "Latitude(WGS84)", Row), 3); NewSoil.Longitude = MathUtility.Round(GetDoubleValue(Table, "Longitude(WGS84)", Row), 3); NewSoil.LocationAccuracy = GetStringValue(Table, "LocationAccuracy", Row); NewSoil.DataSource = GetStringValue(Table, "DataSource", Row); NewSoil.Comment = GetStringValue(Table, "Comments", Row); NewSoil.NaturalVegetation = GetStringValue(Table, "NaturalVegetation", Row); double SummerU = GetDoubleValue(Table, "SummerU", Row); if (SummerU != MathUtility.MissingValue) { NewSoil.SetSummerWinterUCona(GetDoubleValue(Table, "SummerU", Row), GetDoubleValue(Table, "WinterU", Row), GetDoubleValue(Table, "SummerCona", Row), GetDoubleValue(Table, "WinterCona", Row), GetStringValue(Table, "SummerDate", Row), GetStringValue(Table, "WinterDate", Row)); } else { NewSoil.SetUCona(GetDoubleValue(Table, "U", Row), GetDoubleValue(Table, "Cona", Row)); } NewSoil.Salb = GetDoubleValue(Table, "Salb", Row); NewSoil.DiffusConst = GetDoubleValue(Table, "DiffusConst", Row); NewSoil.DiffusSlope = GetDoubleValue(Table, "DiffusSlope", Row); NewSoil.CN2Bare = GetDoubleValue(Table, "CN2Bare", Row); NewSoil.CNRed = GetDoubleValue(Table, "CNRed", Row); NewSoil.CNCov = GetDoubleValue(Table, "CNCov", Row); NewSoil.RootCN = GetDoubleValue(Table, "RootCN", Row); NewSoil.RootWT = GetDoubleValue(Table, "RootWT", Row); NewSoil.SoilCN = GetDoubleValue(Table, "SoilCN", Row); NewSoil.EnrACoeff = GetDoubleValue(Table, "EnrACoeff", Row); NewSoil.EnrBCoeff = GetDoubleValue(Table, "EnrBCoeff", Row); // Work out how many layers we're dealing with. int NumLayers = 0; while (Row + NumLayers < Table.Rows.Count && name.ToLower() == Table.Rows[Row + NumLayers]["Name"].ToString().ToLower()) { NumLayers++; } // Store thickness. NewSoil.Thickness = GetDoubleValues(Table, "Thickness", NumLayers, Row, 0); // Store rest of soil layered variables. NewSoil.BD = GetDoubleValues(Table, "bd", NumLayers, Row, 3); NewSoil.Rocks = GetDoubleValues(Table, "Rocks", NumLayers, Row, 0); NewSoil.LL15 = GetDoubleValues(Table, "LL15", NumLayers, Row, 3); NewSoil.Airdry = GetDoubleValues(Table, "Airdry", NumLayers, Row, 3); NewSoil.DUL = GetDoubleValues(Table, "DUL", NumLayers, Row, 3); NewSoil.SAT = GetDoubleValues(Table, "SAT", NumLayers, Row, 3); NewSoil.Texture = GetStringValues(Table, "Texture", NumLayers, Row); NewSoil.SWCON = GetDoubleValues(Table, "SWCON", NumLayers, Row, 2); NewSoil.MWCON = GetDoubleValues(Table, "MWCON", NumLayers, Row, 2); NewSoil.FBIOM = GetDoubleValues(Table, "FBIOM", NumLayers, Row, 2); NewSoil.FINERT = GetDoubleValues(Table, "FINERT", NumLayers, Row, 1); NewSoil.KS = GetDoubleValues(Table, "KS", NumLayers, Row, 2); NewSoil.OC = GetDoubleValues(Table, "OC", NumLayers, Row, 2); NewSoil.EC = GetDoubleValues(Table, "EC", NumLayers, Row, 1); NewSoil.PH = GetDoubleValues(Table, "PH", NumLayers, Row, 1); NewSoil.CL = GetDoubleValues(Table, "CL", NumLayers, Row, 1); NewSoil.Boron = GetDoubleValues(Table, "Boron", NumLayers, Row, 1); NewSoil.CEC = GetDoubleValues(Table, "CEC", NumLayers, Row, 1); NewSoil.Ca = GetDoubleValues(Table, "Ca", NumLayers, Row, 1); NewSoil.Mg = GetDoubleValues(Table, "Mg", NumLayers, Row, 1); NewSoil.Na = GetDoubleValues(Table, "Na", NumLayers, Row, 1); NewSoil.K = GetDoubleValues(Table, "K", NumLayers, Row, 1); NewSoil.ESP = GetDoubleValues(Table, "ESP", NumLayers, Row, 1); NewSoil.Mn = GetDoubleValues(Table, "Mn", NumLayers, Row, 1); NewSoil.Al = GetDoubleValues(Table, "Al", NumLayers, Row, 1); NewSoil.ParticleSizeSand = GetDoubleValues(Table, "ParticleSizeSand", NumLayers, Row, 1); NewSoil.ParticleSizeSilt = GetDoubleValues(Table, "ParticleSizeSilt", NumLayers, Row, 1); NewSoil.ParticleSizeClay = GetDoubleValues(Table, "ParticleSizeClay", NumLayers, Row, 1); //dph NewSoil.InitialNitrogen.NO3 = GetDoubleValues(Table, "NO3", NumLayers, Row, 3); //dph NewSoil.InitialNitrogen.NH4 = GetDoubleValues(Table, "NH4", NumLayers, Row, 3); // Now get a list of all crop names. StringCollection Crops = new StringCollection(); for (int i = 0; i != Table.Columns.Count; i++) { string ColumnName = Table.Columns[i].ColumnName; if (ColumnName.Length > 2 && ColumnName.Substring(0, 3).ToLower() == "ll(") { Crops.Add(StringManip.SplitOffBracketedValue(ref ColumnName, '(', ')')); } } // Now import all crop stuff. for (int i = 0; i != Crops.Count; i++) { double[] ll = GetDoubleValues(Table, "LL(" + Crops[i] + ")", NumLayers, Row, 3); double[] kl = GetDoubleValues(Table, "KL(" + Crops[i] + ")", NumLayers, Row, 3); double[] xf = GetDoubleValues(Table, "XF(" + Crops[i] + ")", NumLayers, Row, 2); bool AllMissingValues = true; for (int j = 0; j != ll.Length && AllMissingValues; j++) { AllMissingValues = (AllMissingValues && ll[j] == MathUtility.MissingValue && kl[j] == MathUtility.MissingValue && xf[j] == MathUtility.MissingValue); } if (!AllMissingValues) { NewSoil.AddCrop(Crops[i]); NewSoil.SetCrop(Crops[i], ll, kl, xf); } } Row += NumLayers; return(NewSoil.Data.OuterXml); }