/// <summary> /// Make sure the child nodes of JToken are the same as for the original XML document. /// Do this recursively. /// </summary> /// <param name="jsonNode">The JSON node.</param> /// <param name="xmlNode">The XML node.</param> private static void ReorderChildren(JToken jsonNode, XmlNode xmlNode) { if (jsonNode["Children"] != null) { JArray newArray = new JArray(); // Some simulations can have a 2 child models with same name. List <string> childNamesDone = new List <string>(); JArray children = jsonNode["Children"] as JArray; foreach (var childXmlNode in XmlUtilities.ChildNodes(xmlNode, null)) { string childXmlName = XmlUtilities.Value(childXmlNode, "Name"); if (!childNamesDone.Contains(childXmlName)) { if (childXmlName == string.Empty) { string nameAttribute = XmlUtilities.NameAttr(childXmlNode); if (nameAttribute != null) { childXmlName = nameAttribute; } else if (GetModelFullName(childXmlNode.Name) != null) { childXmlName = childXmlNode.Name; } } if (childXmlName != string.Empty || GetTypeFromName(childXmlNode.Name) != null) { int i = 1; foreach (var childJsonNode in children.Where(c => !(c is JArray) && c["Name"].ToString().Equals(childXmlName, StringComparison.InvariantCultureIgnoreCase) || (c["$type"].ToString().Contains("SoilCrop") && c["Name"].ToString().Equals(GetSoilCropName(childXmlName), StringComparison.InvariantCultureIgnoreCase)))) { bool alreadyAdded = newArray.FirstOrDefault(c => c["Name"].ToString() == childXmlName) != null; if (childJsonNode != null) { if (alreadyAdded) { string name = childJsonNode["Name"].ToString(); string newName = name + i.ToString(); childJsonNode["Name"] = newName; i++; } ReorderChildren(childJsonNode, childXmlNode); newArray.Add(childJsonNode); } } childNamesDone.Add(childXmlName); } } } jsonNode["Children"] = newArray; } }
private static void DocumentNode(StreamWriter OutputFile, XmlNode N, int NextLevel, Model parentModel) { if (N.Name == "Name") { return; } if (XmlUtilities.Attribute(N, "shortcut") != "") { OutputFile.WriteLine("<p>" + XmlUtilities.Value(N, "Name") + " uses the same value as " + XmlUtilities.Attribute(N, "shortcut")); } else if (N.Name == "Constant") { OutputFile.WriteLine(Header(XmlUtilities.Value(N, "Name"), NextLevel, XmlUtilities.Value(N.ParentNode, "Name"))); WriteDescriptionForTypeName(OutputFile, N, parentModel); TryDocumentMemo(OutputFile, N, NextLevel); OutputFile.WriteLine("<p>Value = " + XmlUtilities.Value(N, "Value") + "</p>"); } else if (XmlUtilities.ChildNodes(N, "").Count == 0) { WriteDescriptionForTypeName(OutputFile, N, parentModel); DocumentProperty(OutputFile, N, NextLevel); } else if (XmlUtilities.ChildNodes(N, "XYPairs").Count > 0) { CreateGraph(OutputFile, XmlUtilities.ChildNodes(N, "XYPairs")[0], NextLevel, parentModel); } else if (XmlUtilities.Type(N) == "TemperatureFunction") { DocumentTemperatureFunction(OutputFile, N, NextLevel, parentModel); } //else if (XmlUtilities.Type(N) == "GenericPhase") // DocumentFixedPhase(OutputFile, N, NextLevel); // else if (XmlUtilities.Type(N) == "PhaseLookupValue") // DocumentPhaseLookupValue(OutputFile, N, NextLevel); else if (XmlUtilities.Type(N) == "ChillingPhase") { ChillingPhaseFunction(OutputFile, N, NextLevel); } else if (N.Name == "Memo") { DocumentMemo(OutputFile, N, NextLevel); } else { string childName = XmlUtilities.Value(N, "Name"); Model childModel = null; if (parentModel != null) { childModel = Apsim.Child(parentModel, childName) as Model; } DocumentNodeAndChildren(OutputFile, N, NextLevel, childModel); } }
/// <summary> /// Read a parameter set and append to the json array. /// </summary> /// <param name="parameterNode">The XML parameter node to convert.</param> private void ReadPRM(XmlNode parameterNode) { Add(new GenotypeWrapper(parameterNode)); // recurse through child parameter sets. foreach (var child in XmlUtilities.ChildNodes(parameterNode, "set")) { ReadPRM(child); } }
/// <summary>Upgrades to version 2.</summary> /// <remarks> /// Converts: /// <Cultivar> /// <Alias>Cultivar1</Alias> /// <Alias>Cultivar2</Alias> /// </Cultivar> /// to: /// <Cultivar> /// <Alias> /// <Name>Cultivar1</Name> /// </Alias> /// <Alias> /// <Name>Cultivar2</Name> /// </Alias> /// </Cultivar> /// </remarks> /// <param name="node">The node to upgrade.</param> /// <param name="fileName">The name of the .apsimx file</param> private static void UpgradeToVersion2(XmlNode node, string fileName) { foreach (XmlNode cultivarNode in XmlUtilities.FindAllRecursivelyByType(node, "Cultivar")) { List <string> aliases = XmlUtilities.Values(cultivarNode, "Alias"); // Delete all alias children. foreach (XmlNode alias in XmlUtilities.ChildNodes(cultivarNode, "Alias")) { alias.ParentNode.RemoveChild(alias); } foreach (string alias in aliases) { XmlNode aliasNode = cultivarNode.AppendChild(cultivarNode.OwnerDocument.CreateElement("Alias")); XmlUtilities.SetValue(aliasNode, "Name", alias); } } }
/// <summary>Converts the old Yield Prophet XML to new XML format capable of deserialisation</summary> /// <param name="yieldProphetXML">The old Yield Prophet XML</param> /// <returns>The new Yield Prophet XML</returns> public static YieldProphet YieldProphetFromXML(XmlNode node, string baseFolder) { List <Paddock> simulations = new List <Paddock>(); List <XmlNode> paddocks = XmlUtilities.ChildNodes(node, "Paddock"); for (int p = 0; p < paddocks.Count; p++) { try { Paddock paddock = CreateSimulationSpec(paddocks[p], baseFolder); simulations.Add(paddock); } catch (Exception err) { string name = XmlUtilities.Value(paddocks[p], "Name"); throw new Exception(err.Message + "\r\nPaddock name: " + name); } } YieldProphet simulationsSpec = new YieldProphet { Paddock = simulations }; // Some top level simulation metadata. string reportDescription = XmlUtilities.Value(node, "ReportDescription"); if (reportDescription != "") { simulationsSpec.ReportName = reportDescription; } string reportType = XmlUtilities.Value(node, "ReportType"); if (reportType != string.Empty) { throw new Exception("Not sure what to do with a ReportType of " + reportType); } return(simulationsSpec); }
static void DocumentNodeAndChildren(StreamWriter OutputFile, XmlNode N, int Level, Model parentModel) { string paramTable = ""; string Indent = new string(' ', Level * 3); if (N.Name.Contains("Leaf") || N.Name.Contains("Root")) //Nodes to add parameter doc to { paramTable = DocumentParams(OutputFile, N); } OutputFile.WriteLine(Header(XmlUtilities.Value(N, "Name"), Level, XmlUtilities.Value(N.ParentNode, "Name"))); WriteDescriptionForTypeName(OutputFile, N, parentModel); OutputFile.WriteLine(ClassDescription(N)); OutputFile.WriteLine("<blockquote>"); OutputFile.WriteLine(paramTable); foreach (XmlNode CN in XmlUtilities.ChildNodes(N, "")) { DocumentNode(OutputFile, CN, Level + 1, parentModel); } OutputFile.WriteLine("</blockquote>"); }
/// <summary>Do all soil related settings.</summary> /// <param name="simulation">The specification to use</param> /// <param name="workingFolder">The folder where files shoud be created.</param> private static void DoSoil(APSIMSpecification simulation, string workingFolder) { Soil soil; if (simulation.Soil == null) { if (simulation.SoilPath.StartsWith("<Soil")) { // Soil and Landscape grid XmlDocument doc = new XmlDocument(); doc.LoadXml(simulation.SoilPath); soil = XmlUtilities.Deserialise(doc.DocumentElement, typeof(Soil)) as Soil; } else if (simulation.SoilPath.StartsWith("http")) { // Soil and Landscape grid string xml; using (var client = new WebClient()) { xml = client.DownloadString(simulation.SoilPath); } XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); List <XmlNode> soils = XmlUtilities.ChildNodes(doc.DocumentElement, "Soil"); if (soils.Count == 0) { throw new Exception("Cannot find soil in Soil and Landscape Grid"); } soil = XmlUtilities.Deserialise(soils[0], typeof(Soil)) as Soil; } else { // Apsoil web service. APSOIL.Service apsoilService = new APSOIL.Service(); string soilXml = apsoilService.SoilXML(simulation.SoilPath.Replace("\r\n", "")); if (soilXml == string.Empty) { throw new Exception("Cannot find soil: " + simulation.SoilPath); } soil = SoilUtilities.FromXML(soilXml); } } else { // Just use the soil we already have soil = simulation.Soil; } // Make sure we have a soil crop parameterisation. If not then try creating one // based on wheat. Sow sowing = YieldProphetUtility.GetCropBeingSown(simulation.Management); string[] cropNames = soil.Water.Crops.Select(c => c.Name).ToArray(); if (cropNames.Length == 0) { throw new Exception("Cannot find any crop parameterisations in soil: " + simulation.SoilPath); } if (sowing != null && !StringUtilities.Contains(cropNames, sowing.Crop)) { SoilCrop wheat = soil.Water.Crops.Find(c => c.Name.Equals("wheat", StringComparison.InvariantCultureIgnoreCase)); if (wheat == null) { // Use the first crop instead. wheat = soil.Water.Crops[0]; } SoilCrop newSoilCrop = new SoilCrop(); newSoilCrop.Name = sowing.Crop; newSoilCrop.Thickness = wheat.Thickness; newSoilCrop.LL = wheat.LL; newSoilCrop.KL = wheat.KL; newSoilCrop.XF = wheat.XF; soil.Water.Crops.Add(newSoilCrop); } // Remove any initwater nodes. soil.InitialWater = null; // Transfer the simulation samples to the soil if (simulation.Samples != null) { soil.Samples = simulation.Samples; } if (simulation.InitTotalWater != 0) { soil.InitialWater = new InitialWater(); soil.InitialWater.PercentMethod = InitialWater.PercentMethodEnum.FilledFromTop; double pawc; if (sowing == null || sowing.Crop == null) { pawc = MathUtilities.Sum(PAWC.OfSoilmm(soil)); soil.InitialWater.RelativeTo = "LL15"; } else { SoilCrop crop = soil.Water.Crops.Find(c => c.Name.Equals(sowing.Crop, StringComparison.InvariantCultureIgnoreCase)); pawc = MathUtilities.Sum(PAWC.OfCropmm(soil, crop)); soil.InitialWater.RelativeTo = crop.Name; } soil.InitialWater.FractionFull = Convert.ToDouble(simulation.InitTotalWater) / pawc; } if (simulation.InitTotalNitrogen != 0) { // Add in a sample. Sample nitrogenSample = new Sample(); nitrogenSample.Name = "NitrogenSample"; soil.Samples.Add(nitrogenSample); nitrogenSample.Thickness = new double[] { 150, 150, 3000 }; nitrogenSample.NO3Units = Nitrogen.NUnitsEnum.kgha; nitrogenSample.NH4Units = Nitrogen.NUnitsEnum.kgha; nitrogenSample.NO3 = new double[] { 6.0, 2.1, 0.1 }; nitrogenSample.NH4 = new double[] { 0.5, 0.1, 0.1 }; nitrogenSample.OC = new double[] { double.NaN, double.NaN, double.NaN }; nitrogenSample.EC = new double[] { double.NaN, double.NaN, double.NaN }; nitrogenSample.PH = new double[] { double.NaN, double.NaN, double.NaN }; double Scale = Convert.ToDouble(simulation.InitTotalNitrogen) / MathUtilities.Sum(nitrogenSample.NO3); nitrogenSample.NO3 = MathUtilities.Multiply_Value(nitrogenSample.NO3, Scale); } // Add in soil temperature. Needed for Aflatoxin risk. soil.SoilTemperature = new SoilTemperature(); soil.SoilTemperature.BoundaryLayerConductance = 15; soil.SoilTemperature.Thickness = new double[] { 2000 }; soil.SoilTemperature.InitialSoilTemperature = new double[] { 22 }; if (soil.Analysis.ParticleSizeClay == null) { soil.Analysis.ParticleSizeClay = MathUtilities.CreateArrayOfValues(60, soil.Analysis.Thickness.Length); } InFillMissingValues(soil.Analysis.ParticleSizeClay); foreach (Sample sample in soil.Samples) { CheckSample(soil, sample, sowing); } Defaults.FillInMissingValues(soil); // Correct the CONA / U parameters depending on LAT/LONG CorrectCONAU(simulation, soil, workingFolder); // get rid of <soiltype> from the soil // this is necessary because NPD uses this field and puts in really long // descriptive classifications. Soiln2 bombs with an FString internal error. soil.SoilType = null; // Set the soil name to 'soil' soil.Name = "Soil"; simulation.Soil = soil; }
/// <summary>Converts the paddock XML.</summary> /// <param name="paddock">The paddock.</param> /// <exception cref="System.Exception">Bad paddock name: + name</exception> private static Paddock CreateSimulationSpec(XmlNode paddock, string baseFolder) { Paddock simulation = new Paddock(); string name = XmlUtilities.NameAttr(paddock); string delimiter = "^"; int posCaret = name.IndexOf(delimiter); if (posCaret == -1) { throw new Exception("Bad paddock name: " + name); } string remainder = StringUtilities.SplitOffAfterDelimiter(ref name, delimiter); string growerName; string paddockName = StringUtilities.SplitOffAfterDelimiter(ref remainder, delimiter); if (paddockName == string.Empty) { growerName = name; paddockName = remainder; } else { growerName = remainder; } // Give the paddock a name. string fullName = string.Format("{0}^{1}^{2}", GetDate(paddock, "SowDateFull").Year, growerName, paddockName); simulation.Name = fullName; // Set the report date. simulation.NowDate = GetDate(paddock.ParentNode, "TodayDateFull"); if (simulation.NowDate == DateTime.MinValue) { simulation.NowDate = DateTime.Now; } // Store any rainfall data in the simulation. string rainfallSource = GetString(paddock, "RainfallSource"); if (rainfallSource != "Weather station") { string rainFileName = GetString(paddock, "RainfallFilename"); if (rainFileName != string.Empty) { string fullFileName = Path.Combine(baseFolder, rainFileName); if (!File.Exists(fullFileName)) { throw new Exception("Cannot find file: " + fullFileName); } simulation.ObservedData = ApsimTextFile.ToTable(fullFileName); simulation.ObservedData.TableName = rainfallSource; if (simulation.ObservedData.Rows.Count == 0) { simulation.ObservedData = null; } } } // Set the reset dates simulation.SoilWaterSampleDate = GetDate(paddock, "ResetDateFull"); simulation.SoilNitrogenSampleDate = GetDate(paddock, "SoilNitrogenSampleDateFull"); simulation.StationNumber = GetInteger(paddock, "StationNumber"); simulation.StationName = GetString(paddock, "StationName"); // Create a sowing management Sow sowing = new Sow(); simulation.Management.Add(sowing); sowing.Date = GetDate(paddock, "SowDateFull"); sowing.EmergenceDate = GetDate(paddock, "EmergenceDateFull"); sowing.Crop = GetString(paddock, "Crop"); sowing.Cultivar = GetString(paddock, "Cultivar"); sowing.SkipRow = GetString(paddock, "SkipRow"); sowing.SowingDensity = GetInteger(paddock, "SowingDensity"); sowing.MaxRootDepth = GetInteger(paddock, "MaxRootDepth") * 10; // cm to mm sowing.BedWidth = GetInteger(paddock, "BedWidth"); sowing.BedRowSpacing = GetDouble(paddock, "BedRowSpacing"); // Make sure we have a stubbletype simulation.StubbleType = GetString(paddock, "StubbleType"); if (simulation.StubbleType == string.Empty || simulation.StubbleType == "None") { simulation.StubbleType = "Wheat"; } simulation.StubbleMass = GetDouble(paddock, "StubbleMass"); simulation.Slope = GetDouble(paddock, "Slope"); simulation.SlopeLength = GetDouble(paddock, "SlopeLength"); simulation.UseEC = GetBoolean(paddock, "UseEC"); // Fertilise nodes. List <XmlNode> fertiliserNodes = XmlUtilities.ChildNodes(paddock, "Fertilise"); for (int f = 0; f < fertiliserNodes.Count; f++) { Fertilise fertilise = new Fertilise(); simulation.Management.Add(fertilise); fertilise.Date = GetDate(fertiliserNodes[f], "FertDateFull"); fertilise.Amount = GetDouble(fertiliserNodes[f], "FertAmount"); } // Irrigate nodes. List <XmlNode> irrigateNodes = XmlUtilities.ChildNodes(paddock, "Irrigate"); for (int i = 0; i < irrigateNodes.Count; i++) { Irrigate irrigate = new Irrigate(); simulation.Management.Add(irrigate); irrigate.Date = GetDate(irrigateNodes[i], "IrrigateDateFull"); irrigate.Amount = GetDouble(irrigateNodes[i], "IrrigateAmount"); irrigate.Efficiency = GetDouble(irrigateNodes[i], "IrrigateEfficiency"); } // Tillage nodes. foreach (XmlNode tillageNode in XmlUtilities.ChildNodes(paddock, "Tillage")) { Tillage tillage = new Tillage(); simulation.Management.Add(tillage); tillage.Date = GetDate(tillageNode, "TillageDateFull"); string disturbance = GetString(tillageNode, "Disturbance"); if (disturbance == "Low") { tillage.Disturbance = Tillage.DisturbanceEnum.Low; } else if (disturbance == "Medium") { tillage.Disturbance = Tillage.DisturbanceEnum.Medium; } else { tillage.Disturbance = Tillage.DisturbanceEnum.High; } } // Stubble removed nodes. foreach (XmlNode stubbleRemovedNode in XmlUtilities.ChildNodes(paddock, "StubbleRemoved")) { StubbleRemoved stubbleRemoved = new StubbleRemoved(); simulation.Management.Add(stubbleRemoved); stubbleRemoved.Date = GetDate(stubbleRemovedNode, "StubbleRemovedDateFull"); stubbleRemoved.Percent = GetDouble(stubbleRemovedNode, "StubbleRemovedAmount"); } // Look for a soil node. XmlNode soilNode = XmlUtilities.FindByType(paddock, "Soil"); if (soilNode != null) { string testValue = XmlUtilities.Value(soilNode, "Water/Layer/Thickness"); if (testValue != string.Empty) { // old format. soilNode = ConvertSoilNode.Upgrade(soilNode); } } // Fix up soil sample variables. Sample sample1 = new Sample { Name = "Sample1", Thickness = GetArray(paddock, "Sample1Thickness"), SW = GetArray(paddock, "SW") }; if (sample1.SW == null) { // Really old way of doing samples - they are stored under soil. List <XmlNode> sampleNodes = XmlUtilities.ChildNodes(soilNode, "Sample"); if (sampleNodes.Count > 0) { sample1 = XmlUtilities.Deserialise(sampleNodes[0], typeof(Sample)) as Sample; } } else { sample1.NO3 = GetArray(paddock, "NO3"); sample1.NH4 = GetArray(paddock, "NH4"); } Sample sample2 = null; double[] sample2Thickness = GetArray(paddock, "Sample2Thickness"); if (sample2Thickness == null) { // Really old way of doing samples - they are stored under soil. List <XmlNode> sampleNodes = XmlUtilities.ChildNodes(soilNode, "Sample"); if (sampleNodes.Count > 1) { sample2 = XmlUtilities.Deserialise(sampleNodes[1], typeof(Sample)) as Sample; } } else { sample2 = sample1; if (!MathUtilities.AreEqual(sample2Thickness, sample1.Thickness)) { sample2 = new Sample { Name = "Sample2" }; } sample2.OC = GetArray(paddock, "OC"); sample2.EC = GetArray(paddock, "EC"); sample2.PH = GetArray(paddock, "PH"); sample2.CL = GetArray(paddock, "CL"); sample2.OCUnits = SoilOrganicMatter.OCUnitsEnum.WalkleyBlack; sample2.PHUnits = Analysis.PHUnitsEnum.CaCl2; } // Make sure we have NH4 values. if (sample1.NH4 == null && sample1.NO3 != null) { string[] defaultValues = StringUtilities.CreateStringArray("0.1", sample1.NO3.Length); sample1.NH4 = MathUtilities.StringsToDoubles(defaultValues); } RemoveNullFieldsFromSample(sample1); if (sample2 != null) { RemoveNullFieldsFromSample(sample2); } // Fix up <WaterFormat> string waterFormatString = GetString(paddock, "WaterFormat"); if (waterFormatString.Contains("Gravimetric")) { sample1.SWUnits = Sample.SWUnitsEnum.Gravimetric; } else { sample1.SWUnits = Sample.SWUnitsEnum.Volumetric; } if (MathUtilities.ValuesInArray(sample1.Thickness)) { simulation.Samples.Add(sample1); } if (sample2 != null && MathUtilities.ValuesInArray(sample2.Thickness) && sample2 != sample1) { simulation.Samples.Add(sample2); } // Check for InitTotalWater & InitTotalNitrogen simulation.InitTotalWater = GetDouble(paddock, "InitTotalWater"); simulation.InitTotalNitrogen = GetDouble(paddock, "InitTotalNitrogen"); // Check to see if we need to convert the soil structure. simulation.SoilPath = GetString(paddock, "SoilName"); if (soilNode != null) { // See if there is a 'SWUnits' value. If found then copy it into // <WaterFormat> string waterFormat = XmlUtilities.Value(paddock, "WaterFormat"); if (waterFormat == string.Empty) { int sampleNumber = 0; foreach (XmlNode soilSample in XmlUtilities.ChildNodes(soilNode, "Sample")) { string swUnits = XmlUtilities.Value(soilSample, "SWUnits"); if (swUnits != string.Empty) { XmlUtilities.SetValue(paddock, "WaterFormat", swUnits); } // Also make sure we don't have 2 samples with the same name. string sampleName = "Sample" + (sampleNumber + 1).ToString(); XmlUtilities.SetAttribute(soilSample, "name", sampleName); sampleNumber++; } } simulation.Soil = SoilUtilities.FromXML(soilNode.OuterXml); if (simulation.Samples != null) { simulation.Soil.Samples = simulation.Samples; } } return(simulation); }
/// <summary>Called to start the job.</summary> /// <param name="workingFolder">Folder to work on</param> public DataSet PerformCleanup(string workingFolder) { // Delete the .sim files. string[] simFiles = Directory.GetFiles(workingFolder, "*.sim"); foreach (string simFile in simFiles) { File.Delete(simFile); } bool longtermOutputsFound = false; DataSet dataSet = new DataSet("ReportData"); // Cleanup longterm out and sum files. They are named XXX_01 Yearly.out // where XXX is the name of the simulation. foreach (string apsimFileName in Directory.GetFiles(workingFolder, "*.apsim")) { List <XmlNode> simulationNodes = new List <XmlNode>(); XmlDocument doc = new XmlDocument(); doc.Load(apsimFileName); XmlUtilities.FindAllRecursivelyByType(doc.DocumentElement, "simulation", ref simulationNodes); // Concatenate summary files. foreach (XmlNode simNode in simulationNodes) { string simName = XmlUtilities.NameAttr(simNode); string[] sumFiles = Directory.GetFiles(workingFolder, simName + "_*.sum"); if (sumFiles.Length > 0) { longtermOutputsFound = true; ConcatenateSummaryFiles(sumFiles, simName + ".sum", dataSet); } } // Concatenate output files. SortedSet <string> outputTypes = new SortedSet <string>(); foreach (XmlNode simNode in simulationNodes) { string simulationName = XmlUtilities.NameAttr(simNode); foreach (string outputType in Directory.GetFiles(workingFolder, simulationName + "_*1*.out")) { string outputFileType = Path.GetFileNameWithoutExtension(outputType.Replace(simulationName, "")); outputFileType = " " + StringUtilities.SplitOffAfterDelimiter(ref outputFileType, " "); outputTypes.Add(outputFileType); } } foreach (XmlNode simNode in simulationNodes) { string simName = XmlUtilities.NameAttr(simNode); foreach (string outputFileType in outputTypes) { string wildcard = simName + "_*" + outputFileType + ".out"; string[] outFiles = Directory.GetFiles(workingFolder, wildcard); string fileNameToWrite = simName + outputFileType + ".csv"; ConcatenateOutputFiles(outFiles, fileNameToWrite, outputFileType); } } } if (!longtermOutputsFound) { // By now the longterm .out and .sum files have been concatenated. Assume // all simulations are the same; get the different types of reports for each simulation // and concatenate. string[] apsimFiles = Directory.GetFiles(workingFolder, "*.apsim"); if (apsimFiles.Length == 0) { apsimFiles = Directory.GetFiles(workingFolder, "*.apsimx"); } string apsimFileName1 = apsimFiles[0]; string[] allSumFiles = Directory.GetFiles(workingFolder, "*.sum"); ConcatenateSummaryFiles(allSumFiles, Path.ChangeExtension(apsimFileName1, ".sum"), dataSet); XmlDocument doc1 = new XmlDocument(); doc1.Load(apsimFileName1); foreach (XmlNode simulationNode in XmlUtilities.ChildNodes(doc1.DocumentElement, "simulation")) { if (simulationNode != null) { string simulationName = XmlUtilities.NameAttr(simulationNode); string[] outFileTypes = Directory.GetFiles(workingFolder, simulationName + "*.out"); if (outFileTypes.Length == 0) { outFileTypes = Directory.GetFiles(workingFolder, simulationName + "*.csv"); } foreach (string outputfileName in outFileTypes) { string outputFileType = Path.GetFileNameWithoutExtension(outputfileName.Replace(simulationName, "")); string wildcard = "*" + outputFileType + Path.GetExtension(outputfileName); string[] outFiles = Directory.GetFiles(workingFolder, wildcard); string fileNameToWrite = Path.GetFileNameWithoutExtension(apsimFileName1) + outputFileType + ".csv"; ConcatenateOutputFiles(outFiles, fileNameToWrite, outputFileType); } } } } // zip up the met files. string[] metFiles = Directory.GetFiles(workingFolder, "*.met"); ZipFiles(metFiles, Path.Combine(workingFolder, "MetFiles.zip")); // Get all outputs foreach (string dbFileName in Directory.GetFiles(workingFolder, "*.db")) { GetDataFromDB(dbFileName, dataSet); } foreach (string outFileName in Directory.GetFiles(workingFolder, "*.csv")) { try { dataSet.Tables.Add(ApsimTextFile.ToTable(outFileName)); } catch (Exception) { // Sometimes .out files are empty - not an error. } } foreach (string outFileName in Directory.GetFiles(workingFolder, "*.out")) { try { dataSet.Tables.Add(ApsimTextFile.ToTable(outFileName)); } catch (Exception) { // Sometimes .out files are empty - not an error. } } // Clean the table names (no spaces or underscores) foreach (DataTable table in dataSet.Tables) { string tableName = table.TableName.Replace(" ", ""); tableName = tableName.Replace("_", ""); table.TableName = tableName; } return(dataSet); }
public static int Go(string DocFileName, Model parentModel) { string xml = XmlUtilities.Serialise(parentModel, true); XmlDocument XML = new XmlDocument(); XML.LoadXml(xml); int Code; string SavedDirectory = Directory.GetCurrentDirectory(); try { if (Path.GetDirectoryName(DocFileName) != "") { Directory.SetCurrentDirectory(Path.GetDirectoryName(DocFileName)); } string cssText = Properties.Resources.ResourceManager.GetString("Plant2"); StreamWriter css = new StreamWriter("Plant2.css"); css.WriteLine(cssText); css.Close(); StreamWriter OutputFile = new StreamWriter(DocFileName); OutputFile.WriteLine("<html>"); OutputFile.WriteLine("<head>"); OutputFile.WriteLine("<meta http-equiv=\"content-type\""); OutputFile.WriteLine("content=\"text/html; charset=ISO-8859-1\">"); OutputFile.WriteLine("<link rel=\"stylesheet\" type=\"text/css\" href=\"Plant2.css\" >"); OutputFile.WriteLine("</head>"); OutputFile.WriteLine("<body>"); string TitleText = "The APSIM " + XmlUtilities.Value(XML.DocumentElement, "Name") + " Module"; OutputFile.WriteLine(Title(TitleText)); OutputFile.WriteLine(Center(Header(TitleText, 1))); XmlNode image = XmlUtilities.FindByType(XML.DocumentElement, "MetaData"); List <XmlNode> children = XmlUtilities.ChildNodes(image, ""); OutputFile.WriteLine("<h2>Validation</h2>"); OutputFile.WriteLine("<A HREF=\"Index.html\">Model validation can be found here.<A>"); OutputFile.WriteLine("<table style=\"text-align: left; width: 100%;\" border=\"1\" cellpadding=\"2\"\ncellspacing=\"2\">\n<tbody>\n<tr>\n<td id=\"toc\"style=\"vertical-align: top;\">"); OutputFile.WriteLine("<A NAME=\"toc\"></A>"); OutputFile.WriteLine("<h2>Model Documentation</h2><br>"); //ToC added after the rest of the file is created. See CreateTOC() OutputFile.WriteLine("</td>\n<td>"); foreach (XmlNode n in children) { if (n.Name.Contains("Image")) { string s = n.InnerText; s = s.Replace("%apsim%", "..\\.."); OutputFile.WriteLine("<img src = \"{0}\" />", s); } } OutputFile.WriteLine("</td></tbody></table>"); //XmlNode PlantNode = XmlUtilities.FindByType(XML.DocumentElement, "Model/Plant"); DocumentNodeAndChildren(OutputFile, XML.DocumentElement, 2, parentModel); DocumentVariables(OutputFile, parentModel); OutputFile.WriteLine("</body>"); OutputFile.WriteLine("</html>"); OutputFile.Close(); //insert TOC StreamReader inFile = new StreamReader(DocFileName); StreamReader fullFile = new StreamReader(DocFileName); string fullText = fullFile.ReadToEnd(); string fileText = CreateTOC(inFile, fullText); inFile.Close(); fullFile.Close(); StreamWriter outFile = new StreamWriter(DocFileName); outFile.WriteLine(fileText); outFile.Close(); //end insert Directory.SetCurrentDirectory(SavedDirectory); Code = 0; } catch (Exception E) { Console.WriteLine(E.Message); Code = 1; } if (SavedDirectory != "") { Directory.SetCurrentDirectory(SavedDirectory); } return(Code); }