private void RunUnitLoop(HH hh, List <Person> tu) { // store the "running" variables (yem_unit, ils_earns_unit), and take the level into account foreach (StoreVar v in vars) { if (v.iteration != NOTAP) { continue; // is handled below } if (hh.GetPersonValue(varIndexCurElig, tu[0].indexInHH) <= 0) { continue; // store only for the (head of the) "currently elig" unit } List <Person> altTU = hh.GetAlternativeTU(v.level, tu, description); // on may consider performance here, but let's first get it right double levVal = v.unitLoopILPar == null?hh.GetTUValue(v.origVar.index, altTU) : v.unitLoopILPar.GetValue(hh, altTU); hh.SetPersonValue(levVal, v.storeVar.index, tu[0].indexInHH); } // store the "on demand" variables (e.g. yem_unit1) - they are stored the same way as for a normal loops (i.e. no level-stuff) foreach (StoreVar v in vars) { if (v.iteration != NOTAP && v.iteration == hh.GetPersonValue(varIndexLoopCounter, 0)) { hh.SetTUValue(hh.GetTUValue(v.origVar.index, tu), v.storeVar.index, tu); } } }
// person != null: value is requested for a specific person // person == null: value is requested for tu internal override double GetValue(HH hh, List <Person> tu, Person person = null) { if (alternativeTU != null) { tu = hh.GetAlternativeTU(alternativeTU, tu, description); } double value = getComponentValue(hh, tu, person, content); return(ApplyLimits(value, hh, tu, person)); }
// note: person is only relevant for some queries, e.g. IsMarried, IsHead, IsNtoMChild ... // but ignored by e.g. nPersInTu, IsUsedDatabase, ... // for the former applies: // person != null: value is requested for a specific person // person == null: value is taken from head internal override double GetValue(HH hh, List <Person> tu, Person person = null) { if (alternativeTU != null) { tu = hh.GetAlternativeTU(alternativeTU, tu, description); if (person != null) { person = (from p in tu where p.indexInHH == person.indexInHH select p).FirstOrDefault(); } } double val = query.GetValue(hh, tu, person == null ? tu[0] : person); return(ApplyLimits(val, hh, tu, person)); }
// person != null: value is requested for a specific person // person == null: monetary: value is requested for tu, non-monetary: value is taken from head internal override double GetValue(HH hh, List <Person> tu, Person person = null) { if (alternativeTU != null) { tu = hh.GetAlternativeTU(alternativeTU, tu, description); } double val; if (target == DefPar.PREFIX.NONE) { val = person == null && isTULevel?hh.GetTUValue(index, tu) : hh.GetPersonValue(index, person == null ? tu[0].indexInHH : person.indexInHH); } else { val = GetValueTarget(hh, tu, person); } return(ApplyLimits(val, hh, tu, person)); }
private StringBuilder ProcessHHoutput(HH hh, double convFactor) { StringBuilder hhResults = new StringBuilder(); foreach (List <Person> tu in hh.GetTUs(coParTU.name)) { if (!IsOutputElig(hh, tu)) { continue; } StringBuilder tuRow = new StringBuilder(); List <ParVarIL> orderedValues = outList.OrderBy(p => int.Parse(p.Value.description.par.order)).Select(p => p.Value).ToList(); // try to output in UI order foreach (ParVarIL parOut in orderedValues) { double value = parOut.GetValue(hh, tu); // if value is "VOID", check if you need to replace the value if (value == FunStore.UNITLOOP_VOID) { if (doReplaceUnitLoopVoidBy) { value = replaceUnitLoopVoidBy; } if (!suppressVoidMessage) { // old exec behaviour: // std::string handling = "Zero is used as default value for the not defined variables."; // if(RepVoidBy) handling = CEMUtilities::DoubleToStr(RepVoidBy) + " is used as default value for the incomelist."; // if(!CEMError::NonCritErr("Use of not yet calculated variable(s) "+VoidVar+"in incomelist '"+* iti+"'.", this, "", "", handling)) return 0; string msg = $"{description.Get()}: VOID value found in '{parOut.GetName()}' for hhid '{infoStore.GetIDHH(hh)}'"; if (doReplaceUnitLoopVoidBy) { msg += " and replaced by " + value; } infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = msg, runTimeErrorId = description.funID }); } } // if the value was not void, check if you need to apply an exchange rate else if (doExchangeConversion && parOut.isMonetary) { value *= convFactor; } // print value tuRow.Append(value.ToString(formatDecimals)); tuRow.Append("\t"); } foreach (TUInfo tuInfoGroup in tuInfoGroups) // see PrepareUnitInfoPar for description of TUInfo.getInfos { List <Person> altTU = hh.GetAlternativeTU(tuInfoGroup.tuName, tu, description); // get the status of the DefOutput-TU's head (usually one person-TU) in the UnitInfo-TU Person headInAltTU = // note: head of DefOutput-TU must be member of altTU, otherwise GetAlternativeTU is buggy (from p in altTU where p.indexInHH == tu[0].indexInHH select p).First(); foreach (Func <HH, List <Person>, Person, double> getInfo in tuInfoGroup.getInfos.Values) { tuRow.Append(getInfo(hh, altTU, headInAltTU)).Append("\t"); } } foreach (int indexStringVar in infoStore.operandAdmin.indexStringVars.Values) { string value = hh.personStringVarList[tu[0].indexInHH][indexStringVar]; // print value tuRow.Append(EncodeStringForOutput(value)); tuRow.Append("\t"); } if (tuRow.Length > 0) { tuRow.Length--; // trim trailing tab } hhResults.AppendLine(tuRow.ToString()); } return(hhResults); }