//============================================================================ /// <summary> /// Finds the sub-value of a TTypedValue corresponding to this specifier /// </summary> /// <param name="aValue"></param> /// <returns></returns> //============================================================================ public TDDMLValue FindValue(TTypedValue aValue) { TDDMLValue result; if ((SubSpecifier == null) || (aValue == null)) { result = (TDDMLValue)aValue; } else { if (SubSpecifier.bIsField) { result = (TDDMLValue)(SubSpecifier.FindValue(aValue.member(SubSpecifier.sName))); } else { if (SubSpecifier.bIsElement) { result = (SubSpecifier.FindValue(aValue.item((uint)SubSpecifier.iArrayIndex))); } else { result = null; } } } return(result); }
//============================================================================ /// <summary> /// Sets the fields of the typed value with the timestep values. /// </summary> /// <param name="timeValue">Ref to the typed value to be set.</param> /// <returns>A ref to the typed value that has been set.</returns> //============================================================================ public TTypedValue getTypedValue(ref TTypedValue timeValue) { timeValue.member(1).setValue((int)start.getDay()); timeValue.member(2).setValue((int)start.getSec()); timeValue.member(3).setValue((double)start.getSecPart()); timeValue.member(4).setValue((int)finish.getDay()); timeValue.member(5).setValue((int)finish.getSec()); timeValue.member(6).setValue((double)finish.getSecPart()); return(timeValue); }
//========================================================================= /// <summary> /// Writes the srcValue to destValue. /// </summary> /// <param name="srcValue">The source value.</param> /// <param name="destValue">The destination item.</param> //========================================================================= private void writeData(TTypedValue srcValue, TTypedValue destValue) { uint Idx; if (destValue.isScalar()) { if (srcValue != null) { destValue.setValue(srcValue); } else if ((destValue.baseType() >= TTypedValue.TBaseType.ITYPE_INT1) && (destValue.baseType() <= TTypedValue.TBaseType.ITYPE_DOUBLE)) { destValue.setValue(0); } else { destValue.setValue(""); } } else if (destValue.isArray()) { if (srcValue == null) { destValue.setElementCount(0); } else { destValue.setElementCount(srcValue.count()); for (Idx = 1; Idx <= srcValue.count(); Idx++) { writeData(srcValue.item(Idx), destValue.item(Idx)); } } } else // record { for (Idx = 1; Idx <= destValue.count(); Idx++) { writeData(srcValue.member(destValue.item(Idx).Name), destValue.item(Idx)); } } }
//===================================================================== /// <summary> /// Scan through the cultivar list in mvCotton.xml and find any that have /// parameters and form them into an XML document based on TSDMLValue. /// </summary> /// <returns>The cultivar list as XML.</returns> //===================================================================== private String WriteCultivars() { //create new TSDMLValue for the cultivar details TDDMLValue CultivarValues = new TDDMLValue(CULTIVARTYPE, ""); CultivarValues.setElementCount(0); uint cultivarCount = 0; XmlDocument ModelDoc = new XmlDocument(); String ComponentType = Controller.ApsimData.Find(NodePath).Type; ModelDoc.LoadXml("<Model>" + Types.Instance.ModelContents(ComponentType) + "</Model>"); foreach (XmlNode Child in ModelDoc.DocumentElement.ChildNodes) { if (XmlHelper.Attribute(Child, "cultivar").ToLower() == "yes") { if (Child.ChildNodes.Count > 0) { XmlDocument CultivarDoc = new XmlDocument(); CultivarDoc.LoadXml(Child.OuterXml); CultivarValues.setElementCount(++cultivarCount); TTypedValue arrayitem = CultivarValues.item(cultivarCount); arrayitem.member("cultivar").setValue(CultivarDoc.DocumentElement.Name); //read root tag name foreach (XmlNode param in CultivarDoc.DocumentElement.ChildNodes) //for each child of cultivardoc { if (param.NodeType == XmlNodeType.Element) { TTypedValue field = arrayitem.member(param.Name); if (field != null) { if (param.Name == "FRUDD" || param.Name == "BLTME" | param.Name == "WT") { //add array node values String arrayField = param.InnerText; if (arrayField.Contains(" ")) { string[] VariableNameBits = arrayField.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); double[] values = MathUtility.StringsToDoubles(VariableNameBits); uint count = 0; foreach (double val in values) { field.setElementCount(++count); field.item(count).setValue(val); } } } else { double val = Convert.ToDouble(param.InnerText); //these are all doubles field.setValue(val); //copy child to new doc } } else { throw new Exception("Cannot set init value for " + param.Name + " in WriteCultivars()"); } } } } } } TSDMLValue writer = new TSDMLValue("<type/>", ""); return(writer.getText(CultivarValues, 0, 2)); }
//========================================================================== /// <summary> /// /// </summary> /// <param name="eventID"></param> /// <param name="iState"></param> /// <param name="publisherID"></param> /// <param name="aParams"></param> /// <returns></returns> //========================================================================== public override int processEventState(int eventID, int iState, uint publisherID, TTypedValue aParams) { int iCondition = 0; int Idx; Boolean bError; Boolean isWriteEvent = false; //Handle any request for writing from extra events. //Because of the way TGenericReporter.writeVariables() is configured //there will only be one record written per day even if more events //are handled per day. This could be modified if required. if ((eventID == evtEXEC) || RegExtraEvents.ContainsKey(eventID)) { isWriteEvent = true; if ((eventID == evtEXEC) && RegExtraEvents.ContainsValue("post")) { isWriteEvent = false; //ignore the update_outputs event when post is registered } } if ((isWriteEvent) && (iState == stateREQS)) // "Requests" state } { if (FReporter.FileName.Length == 0) { iCondition = 1; } else { if (FFirstTime) // Only actually do anything in the { // first time step FReporter.getRequestNames(ref FRequests); for (Idx = 0; Idx <= FRequests.Count - 1; Idx++) { sendQueryInfo(FRequests[Idx], TypeSpec.KIND_OWNED, eventID); // Handled by processEntityInfo } } iCondition = 0; } } else { if ((isWriteEvent) && (iState == stateQUERY)) // "Query" state { bError = false; if (FFirstTime) { for (Idx = 0; Idx <= FRequests.Count - 1; Idx++) { if (FRequests[Idx].Length > 0) { sendError("Requested variable \"" + FRequests[Idx] + "\" not found in simulation", true); bError = true; } } if (!bError) { FReporter.beginWriting(); // Open the output file } FFirstTime = false; } if (!bError) { sendDriverRequest(drvTIME, eventID); // Request "time" plus the properties for (Idx = 0; Idx <= FRequests.Count - 1; Idx++) // identified as required by the { sendDriverRequest(drvOUT_OFS + Idx, eventID); } iCondition = 0; } } else { if ((isWriteEvent) && (iState == stateSTORE)) // "Store" state { try { FReporter.writeVariables(FTimeStep.getStart()); // Aggregate the current time step's } catch (Exception excep) // values and store outputs { String sNow = FTimeStep.getStart().asDateTimeStr(); sendError("Output error for " + sNow + ": " + excep.Message, true); } iCondition = 0; } else { if ((eventID == evtSUMMARYWRITE) && (iState == stateDOWRITE)) { if (FSummaryStream != null) { String sMessage = aParams.member("lines").asString() + "\r\n"; FSummaryStream.Write(sMessage); } iCondition = 0; } else { iCondition = base.processEventState(eventID, iState, publisherID, aParams); } } } } return(iCondition); }
//============================================================================ /// <summary> /// Initialises this timestep with the field values from the typed value. /// </summary> /// <param name="timeValue">A TTypedValue that has the correct timestep structure.</param> //============================================================================ public void Set(TTypedValue timeValue) { start.Set(timeValue.member(1).asInt(), (uint)timeValue.member(2).asInt(), timeValue.member(3).asDouble()); finish.Set(timeValue.member(4).asInt(), (uint)timeValue.member(5).asInt(), timeValue.member(6).asDouble()); }