/// <summary> /// If root is a soil then make sure it has a sample or init water. /// </summary> /// <param name="root">The root node of the JSON to look at.</param> /// <returns>True if model was changed.</returns> private static bool EnsureSoilHasInitWaterAndSample(JObject root) { string rootType = JsonUtilities.Type(root, true); if (rootType != null && rootType == "Models.Soils.Soil") { JArray soilChildren = root["Children"] as JArray; if (soilChildren != null && soilChildren.Count > 0) { var initWater = soilChildren.FirstOrDefault(c => c["$type"].Value <string>().Contains(".InitWater")); var sample = soilChildren.FirstOrDefault(c => c["$type"].Value <string>().Contains(".Sample")); if (sample == null && initWater == null) { // Add in an initial water and initial conditions models. initWater = new JObject(); initWater["$type"] = "Models.Soils.InitialWater, Models"; initWater["Name"] = "Initial water"; initWater["PercentMethod"] = "FilledFromTop"; initWater["FractionFull"] = 1; initWater["DepthWetSoil"] = "NaN"; soilChildren.Add(initWater); sample = new JObject(); sample["$type"] = "Models.Soils.Sample, Models"; sample["Name"] = "Initial conditions"; sample["Thickness"] = new JArray(new double[] { 1800 }); sample["NO3"] = new JArray(new double[] { 10 }); sample["NH4"] = new JArray(new double[] { 1 }); sample["NO3Units"] = "kgha"; sample["NH4Units"] = "kgha"; sample["SWUnits"] = "Volumetric"; soilChildren.Add(sample); return(true); } } } return(false); }
private static void WriteProperty(JProperty property, JObject toObject) { string propertyName = property.Name; if (propertyName == "@Version") { propertyName = "Version"; } if (propertyName == "#text" && property.Path.Contains("Memo")) { return; // Old memo have #text, we don't want them. } if (!propertyName.StartsWith("@")) { JToken valueToken = property.Value; if (valueToken.HasValues) { if (property.First.First.First is JValue) { JValue value = property.First.First.First as JValue; string elementType = (value.Parent as JProperty).Name; JArray newArray = new JArray(); newArray.Add(new JValue(value.ToString())); toObject[propertyName] = newArray; } else if (property.First.First.First is JArray) { JArray array = property.First.First.First as JArray; string elementType = (array.Parent as JProperty).Name; JArray newArray = new JArray(); foreach (var value in array.Values()) { if (elementType == "string") { newArray.Add(new JValue(value.ToString())); } else if (elementType == "double") { newArray.Add(new JValue(double.Parse(value.ToString(), CultureInfo.InvariantCulture))); } } toObject[propertyName] = newArray; } } else { string value = valueToken.Value <string>(); int intValue; double doubleValue; bool boolValue; DateTime dateValue; if (property.Name == "Name") { if (JsonUtilities.Type(toObject) == "SoilCrop") { toObject["Name"] = GetSoilCropName(property.Value.ToString()); } else { toObject[propertyName] = value; } } else if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out intValue)) { toObject[propertyName] = intValue; } else if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) { toObject[propertyName] = doubleValue; } else if (value == "-INF") { toObject[propertyName] = double.NaN; } else if (bool.TryParse(value, out boolValue)) { toObject[propertyName] = boolValue; } else if (DateTime.TryParseExact(value, "MM/dd/yyyy hh:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateValue)) { toObject[propertyName] = dateValue.ToString("yyyy-MM-dd"); } else { toObject[propertyName] = value; } } } else if (propertyName == "@name") // Name attribute. { // SoilCrops copied from Apsim classic need to be renamed to CropNameSoil e.g. WheatSoil. if (toObject["$type"]?.ToString() == "Models.Soils.SoilCrop, Models") { toObject["Name"] = property.Value.ToString() + "Soil"; } else if (toObject["Name"] == null) { toObject["Name"] = property.Value; } } }
private static void ProcessObject(string name, JToken obj, JObject newRoot) { // Look for an array of something e.g. variable names in report. if (name == "Code") { JValue childAsValue = obj.First.First as JValue; newRoot["Code"] = childAsValue.Value.ToString(); } else if (name == "MemoText") { JValue childAsValue = obj.First.First as JValue; newRoot["Text"] = childAsValue.Value.ToString(); } else if (name.Equals("Script", StringComparison.CurrentCultureIgnoreCase)) { // manager parameters. JArray parameters = new JArray(); foreach (JProperty parameter in obj.Children()) { JObject newParameter = new JObject(); newParameter["Key"] = parameter.Name; newParameter["Value"] = parameter.Value.ToString(); parameters.Add(newParameter); } newRoot["Parameters"] = parameters; } else if (name.Equals("PaddockList", StringComparison.CurrentCultureIgnoreCase)) { // manager parameters. JArray values = new JArray(); foreach (var child in obj.Children()) { var newObject = CreateObject(child.First); values.Add(newObject); } newRoot[name] = values; } else { if (GetModelFullName(name) == null) { var modelType = GetTypeFromName(JsonUtilities.Type(newRoot)); var property = modelType?.GetProperty(name); var newObject = CreateObject(obj); // If the new obejct is NOT a JArray, and this object is supposed to be an array... if (!(newObject is JArray) && (arrayVariableNames.Contains(name) || (property != null && property.PropertyType.IsArray))) { // Should be an array of objects. if (newObject.First.First is JArray) { newObject = newObject.First.First; } else { JArray array = new JArray(); if (newObject.Count() == 1 && newObject.First is JProperty) { array.Add(newObject.First.First); } else { array.Add(newObject); } newObject = array; } } if (!(newObject is JArray) && newObject["$type"] != null && GetModelFullName(newObject["$type"].ToString()) != null) { AddNewChild(newObject, newRoot); } else if (newObject.Children().Count() == 1 && newObject.First.Path == "#text") { newRoot[name] = newObject.First.First; } else { newRoot[name] = newObject; } } else { AddNewChild(obj, newRoot); } } }
/// <summary> /// Change Factor.Specifications to Factor.Specification. Also FactorValue /// becomes CompositeFactor. /// </summary> /// <param name="root"></param> /// <param name="fileName"></param> private static void UpgradeToVersion56(JToken root, string fileName) { foreach (var factor in JsonUtilities.ChildrenRecursively(root as JObject, "Factor")) { var parent = JsonUtilities.Parent(factor); string parentModelType = JsonUtilities.Type(parent); if (parentModelType == "Factors") { var specifications = factor["Specifications"] as JArray; if (specifications != null) { if (specifications.Count > 1) { // must be a compound factor. // Change our Factor to a CompositeFactor factor["$type"] = "Models.Factorial.CompositeFactor, Models"; // Remove the Factor from it's parent. var parentChildren = parent["Children"] as JArray; parentChildren.Remove(factor); // Create a new site factor and add our CompositeFactor to the children list. var siteFactor = JsonUtilities.ChildWithName(parent as JObject, "Site") as JObject; if (siteFactor == null) { // Create a site factor siteFactor = new JObject(); siteFactor["$type"] = "Models.Factorial.Factor, Models"; siteFactor["Name"] = "Site"; JArray siteFactorChildren = new JArray(); siteFactor["Children"] = siteFactorChildren; // Add our new site factor to our models parent. parentChildren.Add(siteFactor); } (siteFactor["Children"] as JArray).Add(factor); } else { // Convert array to string. if (specifications.Count > 0) { factor["Specification"] = specifications[0].ToString(); } } } } else if (parentModelType == "Factor") { factor["$type"] = "Models.Factorial.CompositeFactor, Models"; } } foreach (var series in JsonUtilities.ChildrenRecursively(root as JObject, "Series")) { var factorToVaryColours = series["FactorToVaryColours"]; if (factorToVaryColours != null && factorToVaryColours.Value <string>() == "Simulation") { series["FactorToVaryColours"] = "SimulationName"; } var factorToVaryMarkers = series["FactorToVaryMarkers"]; if (factorToVaryMarkers != null && factorToVaryMarkers.Value <string>() == "Simulation") { series["FactorToVaryMarkers"] = "SimulationName"; } var factorToVaryLines = series["FactorToVaryLines"]; if (factorToVaryLines != null && factorToVaryLines.Value <string>() == "Simulation") { series["FactorToVaryLines"] = "SimulationName"; } } }