// ------------------------------------------------------------ // Read in all crop parameters from all crop sections in // specified file // ------------------------------------------------------------ static private void ReadCropSections(string SectionBit, string FileName, Soil NewSoil) { string[] Sections = ApsimFile.IniFile.INIReadAllSections(FileName); foreach (string Section in Sections) { if (ApsimFile.IniFile.INIRead(FileName, Section, "ll") != "") { // get the crop name StringCollection SectionBits = StringManip.SplitStringHonouringQuotes(Section, "."); if (SectionBits.Count == 3 && SectionBits[0].ToLower() == SectionBit.ToLower()) { string CropName = SectionBits[1]; NewSoil.AddCrop(CropName); double[] ll; string LLValue = GetStringValue(FileName, Section, "ll"); if (LLValue.ToLower() == "#ll") { ll = NewSoil.LL15; } else { ll = GetDoubleValues(FileName, Section, "ll"); } NewSoil.SetCrop(CropName, ll, GetDoubleValues(FileName, Section, "kl"), GetDoubleValues(FileName, Section, "xf")); } } } }
/// <summary> /// Import from specified par file and returns valid soil XML file. /// </summary> static public string Import(string FileName) { if (!File.Exists(FileName)) { throw new Exception("Cannot import file " + FileName + ". File doesn't exist"); } string[] Sections = IniFile.INIReadAllSections(FileName); // import all water sections. string XmlForAllSoils = ""; foreach (string Section in Sections) { if (GetStringValue(FileName, Section, "dlayer") != "") { StringCollection SectionBits = StringManip.SplitStringHonouringQuotes(Section, "."); if (SectionBits.Count == 3) { if (SectionBits[1].ToLower() == "soilwat2") { string SoilName = SectionBits[0]; Soil NewSoil = new Soil(); NewSoil.Name = SoilName; // Add in a soil sample node. Sample NewSample = new Sample(); NewSample.Thickness = new double[] { 100 }; NewSample.SW = new double[] { 0 }; NewSample.NO3 = new double[] { 0 }; NewSample.NH4 = new double[] { 0 }; NewSoil.Samples.Add(NewSample); // Add in a phosphorus node. NewSoil.Phosphorus = new Phosphorus(); NewSoil.Phosphorus.Thickness = new double[] { 100 }; NewSoil.Phosphorus.LabileP = new double[] { 5 }; NewSoil.Phosphorus.Sorption = new double[] { 50 }; NewSoil.Phosphorus.BandedP = new double[] { 0 }; NewSoil.Phosphorus.RockP = new double[] { 0 }; double[] Thickness = ReadWaterSection(SoilName, FileName, NewSoil); NewSoil.Water.Thickness = Thickness; ReadNitrogenSection(SoilName, FileName, NewSoil, Thickness); ReadCropSections(SoilName, FileName, NewSoil, Thickness); ReadPhosphorusSection(SoilName, FileName, NewSoil, Thickness); XmlForAllSoils += NewSoil.ToXml(); } } } } return(XmlForAllSoils); }
// ------------------------------------------------------------ // Resolve the specified macro to a name and return its value. // NB It looks in a '*variables' section. // ------------------------------------------------------------ static private string ResolveVariableMacro(string FileName, string MacroName) { string MacroLine = ApsimFile.IniFile.INIRead(FileName, "*variables", MacroName); StringManip.SplitOffAfterDelimiter(ref MacroLine, "!"); if (MacroLine == "") { throw new Exception("Cannot resolve macro: " + MacroName + " in file:" + FileName); } StringCollection MacroBits = StringManip.SplitStringHonouringQuotes(MacroLine, " "); if (MacroBits.Count != 3) { throw new Exception("Invalid variables line: " + MacroLine); } return(MacroBits[1]); }
/// <summary> /// Return the next line in the file as a collection of words. /// </summary> private bool GetNextLine(StreamReaderRandomAccess In, ref StringCollection Words) { if (In.EndOfStream) { return(false); } string Line = In.ReadLine(); if (Line == null || Line.Length == 0) { return(false); } if (Line.IndexOf("!") > 0) //used to ignore "!" in a row { Line = Line.Substring(0, Line.IndexOf("!") - 1); } if (CSV) { Words.Clear(); Line = Line.TrimEnd(','); Words.AddRange(Line.Split(",".ToCharArray())); } else { Words = StringManip.SplitStringHonouringQuotes(Line, " \t"); } if (Words.Count != Headings.Count) { throw new Exception("Invalid number of values on line: " + Line + "\r\nin file: " + _FileName); } // Remove leading / trailing double quote chars. for (int i = 0; i < Words.Count; i++) { Words[i] = Words[i].Trim("\"".ToCharArray()); } return(true); }
// ---------------------------- // Import from specified par file. // ---------------------------- static public void ImportParFile(string FileName, BaseController Apsoil) { Cursor.Current = Cursors.WaitCursor; if (!File.Exists(FileName)) { throw new Exception("Cannot import file " + FileName + ". File doesn't exist"); } string[] Sections = ApsimFile.IniFile.INIReadAllSections(FileName); // import all water sections. string XmlForAllSoils = ""; foreach (string Section in Sections) { if (GetStringValue(FileName, Section, "dlayer") != "") { StringCollection SectionBits = StringManip.SplitStringHonouringQuotes(Section, "."); if (SectionBits.Count == 3) { if (SectionBits[1].ToLower() == "soilwat2") { string SoilName = SectionBits[0]; XmlDocument Doc = new XmlDocument(); Doc.AppendChild(XmlHelper.CreateNode(Doc, "soil", SoilName)); Soil NewSoil = new Soil(Doc.DocumentElement); ReadWaterSection(SoilName, FileName, NewSoil); ReadNitrogenSection(SoilName, FileName, NewSoil); ReadCropSections(SoilName, FileName, NewSoil); ReadPhosphorusSection(SoilName, FileName, NewSoil); XmlForAllSoils += NewSoil.Data.OuterXml; } } } } if (XmlForAllSoils != "") { Apsoil.Selection.Add(XmlForAllSoils); } Cursor.Current = Cursors.Default; }
static private double[] GetDoubleValues(string FileName, string SectionName, string Key) { // ---------------------------------------------------------- // Get string value from specified table for specified field. // ---------------------------------------------------------- string Value = IniFile.INIRead(FileName, SectionName, Key); StringManip.SplitOffAfterDelimiter(ref Value, "!"); StringManip.SplitOffAfterDelimiter(ref Value, "("); Value = Value.Replace("\t", " "); if (Value == "") { return(new double[0]); } else { StringCollection Values = StringManip.SplitStringHonouringQuotes(Value, " "); double[] ReturnValues = new double[Values.Count]; for (int i = 0; i != Values.Count; i++) { if (Values[i].StartsWith("$")) { Values[i] = ResolveVariableMacro(FileName, Values[i]); } try { ReturnValues[i] = Convert.ToDouble(Values[i]); } catch (Exception) { throw new Exception("Cannot convert value to a floating point number" + ". Filename: " + FileName + ". Section: " + SectionName + ". Key: " + Key); } } return(ReturnValues); } }
static private string ResolveVariableMacro(string FileName, string MacroName) { // ------------------------------------------------------------ // Resolve the specified macro to a name and return its value. // NB It looks in a '*variables' section. // ------------------------------------------------------------ string MacroLine = IniFile.INIRead(FileName, "*variables", MacroName); StringManip.SplitOffAfterDelimiter(ref MacroLine, "!"); if (MacroLine == "") { throw new Exception("Cannot resolve macro: " + MacroName + " in file:" + FileName); } StringCollection MacroBits = StringManip.SplitStringHonouringQuotes(MacroLine, " "); if (MacroBits.Count != 3) { throw new Exception("Invalid variables line: " + MacroLine); } return(MacroBits[1]); }
/// <summary> /// Read in all crop parameters from all crop sections. /// </summary> static private void ReadCropSections(string SectionBit, string FileName, Soil NewSoil, double[] Thickness) { string[] Sections = IniFile.INIReadAllSections(FileName); foreach (string Section in Sections) { if (IniFile.INIRead(FileName, Section, "ll") != "") { // get the crop name StringCollection SectionBits = StringManip.SplitStringHonouringQuotes(Section, "."); if (SectionBits.Count == 3 && SectionBits[0].ToLower() == SectionBit.ToLower()) { string CropName = SectionBits[1]; double[] ll; string LLValue = GetStringValue(FileName, Section, "ll"); if (LLValue.ToLower() == "#ll") { ll = NewSoil.Water.LL15; } else { ll = GetDoubleValues(FileName, Section, "ll"); } CropName = CropName.Replace(" ", ""); SoilCrop NewCrop = new SoilCrop(); NewCrop.Name = CropName; NewCrop.Thickness = NewSoil.Water.Thickness; NewCrop.LL = ll; NewCrop.KL = GetDoubleValues(FileName, Section, "kl"); NewCrop.XF = GetDoubleValues(FileName, Section, "xf"); NewSoil.Water.Crops.Add(NewCrop); } } } }
/// <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> /// Parses an argument on the command line /// </summary> /// <returns>The number of arguments used (1 or 2)</returns> /// eg. /// Apsim.exe xyz.apsim /// Apsim.exe abc.apsim def.apsim ... xyz.apsim /// Apsim.exe @filename (reads arguments from file) /// Apsim.exe abc.apsim Simulation=/xml/path/to/sim /// Apsim.exe abc.apsim Simulation=/xml/path/to/simin/first_file def.apsim Simulation=/xml/path/to/sim/in/second_file /// Apsim.exe abc.apsim Simulation=@filename (reads paths to simulations from file) /// // Parse static private int parseArg(ref List <RunApsim.apsimRunFileSims> allRuns, ref Dictionary <string, string> Macros, string arg1, string arg2) { arg1 = arg1.Replace("\"", ""); arg2 = arg2.Replace("\"", ""); //Console.WriteLine("parsearg: arg1=" + arg1 + ", arg2=" + arg2); if (Directory.Exists(arg1)) // we've been given a directory name, not a file name; find everything in it. { List <string> fileList = new List <string>(); Utility.FindFiles(arg1, "*", ref fileList); for (int j = 0; j < fileList.Count; j++) { parseArg(ref allRuns, ref Macros, Path.GetFullPath(fileList[j]), ""); } } else { string dirName = Path.GetDirectoryName(arg1); if (String.IsNullOrEmpty(dirName)) { dirName = Directory.GetCurrentDirectory(); } if (Directory.Exists(dirName)) { List <string> fileList = new List <string>(); Utility.FindFiles(dirName, Path.GetFileName(arg1), ref fileList); if (fileList.Count == 0 && arg1.IndexOf('=') > 0) { // A "name = value" pair int pos = arg1.IndexOf('='); if (pos > 0) { Macros.Add(arg1.Substring(0, pos), arg1.Substring(pos + 1)); } } else if (fileList.Count == 0 && arg1[0] == '@') { // A filename to read from System.IO.StreamReader file = new System.IO.StreamReader(arg1.Substring(1)); string line; while ((line = file.ReadLine()) != null) { StringCollection args = CSGeneral.StringManip.SplitStringHonouringQuotes(line, " "); if (args.Count > 0) { parseArg(ref allRuns, ref Macros, args[0], (args.Count > 1) ? args[1] : ""); } } file.Close(); } else if (fileList.Count == 1 && arg2.IndexOf('=') > 0 && arg2.Substring(0, arg2.IndexOf('=')) == "Simulation") { // A single file, and a simulation argument int pos = arg2.IndexOf('='); List <string> simPaths = new List <string>(); string simPath = arg2.Substring(pos + 1); if (simPath[0] != '@') { simPaths.Add(StringManip.SplitStringHonouringQuotes(simPath, " ")[0]); } else { // "Simulation=@filename" - read paths from a file System.IO.StreamReader file = new System.IO.StreamReader(simPath.Substring(1)); string line; while ((line = file.ReadLine()) != null) { simPaths.Add(StringManip.SplitStringHonouringQuotes(line, " ")[0]); } file.Close(); } allRuns.Add(new RunApsim.apsimRunFileSims { fileName = fileList[0], simulationPaths = simPaths }); return(2); // The 2nd argument was used here. } else if (fileList.Count == 1 && (Path.GetExtension(fileList[0]).ToLower() == ".apsim" || Path.GetExtension(fileList[0]).ToLower() == ".sim")) { allRuns.Add(new RunApsim.apsimRunFileSims { fileName = fileList[0], simulationPaths = new List <string>() }); } else if (fileList.Count > 1) { // more than one file for (int j = 0; j < fileList.Count; j++) { parseArg(ref allRuns, ref Macros, Path.GetFullPath(fileList[j]), ""); } } else { throw new Exception("Cant make sense of '" + arg1 + "'."); } } } return(1); }
//--------------------------------------------------------------- // Evaluate the specified IF macro. Return true if it equates // to true. //--------------------------------------------------------------- bool EvaluateIf(string IfMacro) { StringCollection s = StringManip.SplitStringHonouringQuotes(IfMacro, " "); if (s.Count == 0) { return(false); } if (s.Count == 1 && s[0] == "\"\"") { return(false); } if (s.Count == 1) { return(s[0].IndexOf('[') == -1 || s[0].IndexOf(']') == -1); } if (s.Count == 2) { return(true); } // if (s.Count != 3) // throw new Exception("Badly formatted if statement: " + IfMacro); char[] operators = { '<', '>' }; string lhs = s[0]; string op = s[1]; string rhs = s[2]; lhs.Trim(); rhs.Trim(); if (op == "=") { if (rhs == "\"\"") { return(lhs.IndexOf('[') != -1 && lhs.IndexOf(']') != -1); } return(StringManip.StringsAreEqual(lhs, rhs)); } else if (op == "<>") { return(!StringManip.StringsAreEqual(lhs, rhs)); } else if (op == "!=") { return(!StringManip.StringsAreEqual(lhs, rhs)); } else if (op.IndexOfAny(operators) == -1) { return(s.Count >= 1); } else { double lhsValue, rhsValue; try { lhsValue = Convert.ToDouble(lhs); rhsValue = Convert.ToDouble(rhs); } catch (Exception) { return(false); } if (op == "<") { return(lhsValue < rhsValue); } else if (op == "<=") { return(lhsValue <= rhsValue); } else if (op == ">") { return(lhsValue > rhsValue); } else if (op == ">=") { return(lhsValue >= rhsValue); } else { throw new Exception("Unknown if macro operator: " + op); } } }
public void Go(string CommandLine) { Args = StringManip.SplitStringHonouringQuotes(CommandLine, " "); this.Show(); Application.Run(this); }
/// <summary> /// Read the next object from the input stream and store under the /// specified parent XML node. /// </summary> private XmlNode ReadObjectIntoXml(StreamReader In, XmlNode ParentNode, string ObjName) { XmlNode ObjNode = null; if (ParentNode is XmlDocument) { ObjNode = ParentNode.AppendChild(((XmlDocument)ParentNode).CreateElement(ObjName)); } else { ObjNode = ParentNode.AppendChild(ParentNode.OwnerDocument.CreateElement(ObjName)); } // Next line should be a { if (In.ReadLine().Trim() != "{") { throw new Exception("Was expecting a { character"); } string Line = In.ReadLine().Trim(); while (Line != "}") { StringCollection LineBits = StringManip.SplitStringHonouringQuotes(Line, "="); if (LineBits.Count == 2) // keyword = value { // Strip off a leading and trailing " chars. LineBits[0] = LineBits[0]; LineBits[1] = LineBits[1]; XmlHelper.SetValue(ObjNode, LineBits[0], LineBits[1]); } else if (LineBits.Count == 1 && Line.Contains(':')) // object ref { String[] ObjectBits = Line.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (ObjectBits.Length != 2) { throw new Exception("Unknown type of line: " + Line); } XmlNode ChildNode = ReadObjectIntoXml(In, ObjNode, "Object"); string ChildObjName = ObjectBits[0].Replace("\"", "").Replace("{", "").Replace("}", ""); string ID = ObjectBits[1].Replace("\"", "").Replace("{", "").Replace("}", ""); int IDNum; if (Int32.TryParse(ID.Substring(1), out IDNum)) { LastID = Math.Max(LastID, IDNum); } XmlHelper.SetAttribute(ChildNode, "name", ChildObjName); XmlHelper.SetAttribute(ChildNode, "id", ID); } else { string ChildObjName = Line.Replace("\"", ""); ReadObjectIntoXml(In, ObjNode, ChildObjName); } Line = In.ReadLine().Trim(); } return(ObjNode); }