protected void PrepareRoundPar() { ParNumber parRound = GetUniquePar <ParNumber>(DefPar.Common.Round_to); if (parRound != null) { roundBase = parRound.GetValue(); roundTo = ROUND.TO; } else { parRound = GetUniquePar <ParNumber>(DefPar.Common.Round_Down); if (parRound != null) { roundBase = parRound.GetValue(); roundTo = ROUND.DOWN; } else { parRound = GetUniquePar <ParNumber>(DefPar.Common.Round_Up); if (parRound != null) { roundBase = parRound.GetValue(); roundTo = ROUND.UP; } } } }
private void PrepareIterationPar() { // assess parameters which define the number of iterations breakCond = GetUniquePar <ParCond>(DefPar.Loop.BreakCond); if (breakCond == null) { ParNumber parIt = GetUniquePar <ParNumber>(DefPar.Loop.Num_Iterations); if (parIt != null) { nIterations = (int)parIt.GetValue(); } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: neither parameter {DefPar.Loop.Num_Iterations} nor {DefPar.Loop.BreakCond} defined" }); } } else { if (!breakCond.IsGlobal()) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{breakCond.description.Get()}: condition is supposed to be global but contains personal/household related operands" }); } } }
protected override void PrepareNonCommonPar() { ParNumber parSeed = GetUniquePar <ParNumber>(DefPar.RandSeed.Seed); seed = parSeed != null ? (int)parSeed.GetValue() : DefinitionAdmin.GetParDefault <int>(DefFun.RandSeed, DefPar.RandSeed.Seed); }
internal void SetParScaleFactor() { // it is important to set infoStore.parScaleFactor already here, to be ready for the actual scaling, which is done in ParBase.GetPeriods: // this function is called in FunBase.TakePar, immediately after FunBase.ClassifyParameters // ClassifyParameters generates e.g. formulas (ParFormula), which call ParBase.GetPeriods in the constructor // that means each function after the very Scale-function will be affected by the scaling ParNumber parFactorPar = GetUniquePar <ParNumber>(DefPar.Scale.FactorParameter); if (parFactorPar == null) { return; } // as all the preparing is not yet done, we cannot rely on the "normal automatic" handling, but need to pre-handle here, e.g. the run-condition coParRunCond = GetUniquePar <ParCond>(DefPar.Common.Run_Cond); if (coParRunCond != null) { coParRunCond.CheckAndPrepare(this); if (!IsRunCondMet()) { return; } } parFactorPar.CheckAndPrepare(this); double factorPar = parFactorPar.GetValue(); infoStore.parScaleFactor = factorPar; }
private Dictionary <string, double> GetInternalFactorDefs() { // this is a somewhat simplified implementation, as I think it's an outdated concept and not used (and as such not worth the effort): // in the old executable the value of the factor can be a constant (and therewith also an uprating factor defined in the dialog) Dictionary <string, double> facDefs = new Dictionary <string, double>(StringComparer.OrdinalIgnoreCase); foreach (var group in GetParGroups(DefPar.Uprate.GROUP_FACTOR_DEF).Values) { ParBase pName = GetUniqueGroupPar <ParBase>(DefPar.Uprate.Factor_Name, group); ParNumber pNum = GetUniqueGroupPar <ParNumber>(DefPar.Uprate.Factor_Value, group); if (pName == null || pNum == null) { continue; // error (compulsory param missing ...) is issued in the general check } if (facDefs.ContainsKey(pName.xmlValue)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{description.Get()}: double definition of {DefPar.Uprate.Factor_Name} {pName.xmlValue}" }); } else { facDefs.Add(pName.xmlValue, pNum.GetValue()); // as said above, ignore the possibility of a constant } } return(facDefs); }
protected override void PrepareNonCommonPar() { ParBase parFileName = GetUniquePar <ParBase>(DefPar.DefOutput.File); if (parFileName != null) // if null the programme is stopped after reading parameters (missing compulsory parameter) { fileName = Path.Combine(infoStore.runConfig.pathOutput, parFileName.xmlValue); if (!fileName.ToLower().EndsWith(".txt")) { fileName += ".txt"; } if (infoStore.runConfig.stdOutputFilenameSuffix != string.Empty) // e.g. uk_2017_std -> uk_2017_BTAoff { AdaptFileNameForNonStdExtensionSwitches(infoStore.runConfig.stdOutputFilenameSuffix); } if (infoStore.runConfig.outFileDate != string.Empty) // e.g. hu_2017_std.txt -> hu_2017_std_201805301954.txt { fileName = fileName.Insert(fileName.Length - 4, "_" + infoStore.runConfig.outFileDate); } // * * * T O D O * * * // check at this point if file is ready for writting, i.e. valid file-name, not used by another file, ... // to avoid running the whole thing and then cannot write (probably requires try-catch on attempt to open) // also if the file is available, lock it now? } // in future probably replaced by Scale function, but currently still needed, in particular for PET ParFormula parMultipleMonetaryBy = GetUniquePar <ParFormula>(DefPar.DefOutput.MultiplyMonetaryBy); if (parMultipleMonetaryBy != null) { multiplyMonetaryBy = parMultipleMonetaryBy.GetGlobalValue(); } PrepareVarILPar(); PrepareDefILPar(); PrepareUnitInfoPar(); append = GetParBoolValueOrDefault(DefFun.DefOutput, DefPar.DefOutput.Append); suppressVoidMessage = GetParBoolValueOrDefault(DefFun.DefOutput, DefPar.DefOutput.Suppress_Void_Message); nDecimals = (int)GetParNumberValueOrDefault(DefFun.DefOutput, DefPar.DefOutput.nDecimals); formatDecimals = "0."; for (int i = 0; i < nDecimals; i++) { formatDecimals += "#"; } parWho = GetUniquePar <ParCateg>(DefPar.Common.Who_Must_Be_Elig); parEligVar = GetUniquePar <ParVar>(DefPar.Common.Elig_Var); ParNumber parReplaceUnitLoopVoidBy = GetUniquePar <ParNumber>(DefPar.DefOutput.Replace_Void_By); if (parReplaceUnitLoopVoidBy != null) { doReplaceUnitLoopVoidBy = true; replaceUnitLoopVoidBy = parReplaceUnitLoopVoidBy.GetValue(); } }
private void DoFunWork_InputMode(string fullPath) { if (!Read_InputMode(fullPath, out Dictionary <double, List <double> > inputContent, // key: value of merge var (e.g. idPerson), value: values of other variables out Dictionary <int, int> indexMatches)) // key: index of variable in data-array, value: index of variable in inputContent.value { return; } double noMatchVal = 0; if (parDefaultIfNoMatch != null) { noMatchVal = parDefaultIfNoMatch.GetValue(); } foreach (HH hh in infoStore.hhAdmin.hhs) { for (int indexPerson = 0; indexPerson < hh.GetPersonCount(); ++indexPerson) { double mergeVal = hh.GetPersonValue(rowMergeVar.index, indexPerson); List <double> inputValues = null; if (inputContent.ContainsKey(mergeVal)) { inputValues = inputContent[mergeVal]; } else if (parDefaultIfNoMatch == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, runTimeErrorId = description.funID, message = $"{description.Get()}: no match found for {DefVarName.IDPERSON} {infoStore.GetIDPerson(hh, indexPerson)} ({rowMergeVar.name}={mergeVal}), zero is used as default" }); } foreach (var indexMatch in indexMatches) { double value = inputValues == null ? noMatchVal : inputValues[indexMatch.Value]; hh.SetPersonValue(value, indexMatch.Key, indexPerson); } } } }
protected void GetAgeLimits(out double ageMin, out double ageMax) { ageMin = parAgeMin == null ? DefinitionAdmin.NEG_INFINITE : parAgeMin.GetValue(); ageMax = parAgeMax == null ? DefinitionAdmin.POS_INFINITE : parAgeMax.GetValue(); }
protected override void PrepareNonCommonPar() { ParBase parPostLoop = GetUniquePar <ParBase>(DefPar.Restore.PostLoop); ParBase parPostFix = GetUniquePar <ParBase>(DefPar.Restore.PostFix); if (parPostLoop == null && parPostFix == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: neither {DefPar.Restore.PostFix} nor {DefPar.Restore.PostLoop} defined" }); return; } if (parPostLoop != null && parPostFix != null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: unclear specification - both {DefPar.Restore.PostFix} and {DefPar.Restore.PostLoop} defined" }); return; } string post = parPostLoop == null ? parPostFix.xmlValue : parPostLoop.xmlValue; if (!infoStore.operandAdmin.indexStoreFuns.ContainsKey(post)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: no related Store-function ({post}) found" }); return; } relatedStore = infoStore.operandAdmin.indexStoreFuns[post]; switch (relatedStore.storeType) { case FunStore.STORETYPE.UNITLOOP: infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: restoring UnitLoop values is not possible" }); return; case FunStore.STORETYPE.FIX: if (parPostFix == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{parPostLoop.description.Get()}: related Store-function concerns {DefPar.Store.PostFix}" }); return; } break; case FunStore.STORETYPE.LOOP: if (parPostLoop == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{parPostFix.description.Get()}: related Store-function concerns {DefPar.Store.PostLoop}" }); return; } break; } if (parPostLoop != null) { ParNumber parIteration = GetUniquePar <ParNumber>(DefPar.Restore.Iteration); if (parIteration != null) { loopIteration = parIteration.GetValue(); if (!EM_Helpers.IsNonNegInteger(loopIteration, false)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{parIteration.description.Get()}: must be a non-negative integer" }); } else { relatedStore.RegisterOperands((int)loopIteration); // see description in FunStore } } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: parameter {DefPar.Restore.Iteration} missing" }); } } }
protected override void PrepareNonCommonPar() { ParNumber parFactorVar = GetUniquePar <ParNumber>(DefPar.Scale.FactorVariables); factorVar = parFactorVar == null ? 1.0 : parFactorVar.GetValue(); }
protected override void PrepareNonCommonPar() { if (GetParGroups(DefPar.SchedCalc.Band_XXX).Count < 1) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: SchedCalc must have at least one band" }); return; } foreach (KeyValuePair <int, List <ParBase> > bandParList in GetParGroups(DefPar.SchedCalc.Band_XXX)) { Band band = new Band(); // Prepare the Band Limits band.band = bandParList.Key; band.pLowLim = GetUniqueGroupPar <ParFormula>(DefPar.SchedCalc.Band_LowLim, bandParList.Value); if (band.pLowLim != null) // if there is a lowLim { if (band.pLowLim.IsGlobal(true)) { band.lowLim = band.pLowLim.GetGlobalValue(); band.pLowLim = null; } else { doRunTimeLimCheck = true; } } band.pUpLim = GetUniqueGroupPar <ParFormula>(DefPar.SchedCalc.Band_UpLim, bandParList.Value); if (band.pUpLim != null) // if there is a lowLim { if (band.pUpLim.IsGlobal(true)) { band.upLim = band.pUpLim.GetGlobalValue(); band.pUpLim = null; } else { doRunTimeLimCheck = true; } } // Prepare the Band Rate/Amount band.pRate = GetUniqueGroupPar <ParFormula>(DefPar.SchedCalc.Band_Rate, bandParList.Value); band.pAmount = GetUniqueGroupPar <ParFormula>(DefPar.SchedCalc.Band_Amount, bandParList.Value); if (band.pRate != null && band.pAmount != null) // Rate and Amount cannot co-exist { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: Rate and Amount cannot co-exist in group {band.band}" }); } if (band.pRate == null && band.pAmount == null) // Rate and Amount cannot both be missing { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: Rate and Amount cannot both be missing in group {band.band}" }); } if (band.pRate != null) { if (band.pRate.IsGlobal(true)) { band.rate = band.pRate.GetGlobalValue(); band.pRate = null; } else { doRunTimeRateCheck = true; } } if (band.pAmount != null) { if (band.pAmount.IsGlobal(true)) { band.amount = band.pAmount.GetGlobalValue(); band.pAmount = null; } else { doRunTimeRateCheck = true; } } bands.Add(band); } // check that all required limits exist for (int i = 1; i < bands.Count; i++) { // if both limits are missing then produce an error if (bands[i - 1].upLim == double.MaxValue && bands[i - 1].pUpLim == null && bands[i].lowLim == double.MinValue && bands[i].pLowLim == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: Band {bands[i - 1].band}: insufficient definition of upper limit. Use parameters 'band_uplim' or 'band_lowlim'(+1)." }); } // if both limits are there, then produce an error else if ((bands[i - 1].upLim != double.MaxValue || bands[i - 1].pUpLim != null) && (bands[i].lowLim != double.MinValue || bands[i].pLowLim != null)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: Double definition of upper limit as 'Band_UpLim {bands[i - 1].band}' and 'Band_LowLim {bands[i].band}'." }); } // else, make sure that the upper limit always exist (copy from Group+1 lower limit if required) else if (bands[i - 1].upLim == double.MaxValue && bands[i - 1].pUpLim == null) { if (bands[i].pLowLim == null) { bands[i - 1].upLim = bands[i].lowLim; // copy the litteral limit if it exists } else { bands[i - 1].pUpLim = bands[i].pLowLim; // else copy the parameter to be run at run-time } } } // if possible, check that limits are also in order if (!doRunTimeLimCheck) { CheckGroupLimits(bands); } // prepare the other parameters basePar = GetUniquePar <ParFormula>(DefPar.SchedCalc.Base); if (basePar == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: Missing required parameter Base" }); } ParBool doAverageRatesPar = GetUniquePar <ParBool>(DefPar.SchedCalc.Do_Average_Rates); doAverageRates = doAverageRatesPar != null && doAverageRatesPar.GetBoolValue(); ParBool simpleProgPar = GetUniquePar <ParBool>(DefPar.SchedCalc.Simple_Prog); simpleProg = simpleProgPar != null && simpleProgPar.GetBoolValue(); quotientPar = GetUniquePar <ParFormula>(DefPar.SchedCalc.Quotient); if (quotientPar != null) { if (quotientPar.IsGlobal(true)) { quotient = quotientPar.GetGlobalValue(); quotientPar = null; } } baseThresholdPar = GetUniquePar <ParFormula>(DefPar.SchedCalc.BaseThreshold); if (baseThresholdPar != null) { if (baseThresholdPar.IsGlobal(true)) { baseThreshold = baseThresholdPar.GetGlobalValue(); baseThresholdPar = null; } } ParNumber roundBasePar = GetUniquePar <ParNumber>(DefPar.SchedCalc.Round_Base); if (roundBasePar != null) { roundBase = roundBasePar.GetValue(); } }
protected override void PrepareNonCommonPar() { if (!IsRunCondMet()) { return; } infoStore.applicableUprateFunctions.Add(description); // to allow for checking if there is no/more than one applicable Uprate // get the "function-internal" (rather outdated) factor definitions, i.e. those defined by parameters Factor_Name/Factor_Value Dictionary <string, double> internalFactorDefs = GetInternalFactorDefs(); // check if DBYearVar exists and handle accordingly ParVar parDBYearVarPar = GetUniquePar <ParVar>(DefPar.Uprate.DBYearVar); isDBYearVarUsed = parDBYearVarPar != null && parDBYearVarPar.name != DefPar.Value.NA; if (isDBYearVarUsed) { if (parDBYearVarPar.name.Trim() != string.Empty) { infoStore.operandAdmin.CheckRegistration(name: parDBYearVarPar.name.Trim(), isOutVar: false, warnIfNotInit: false, description: parDBYearVarPar.description); if (!infoStore.operandAdmin.GetVarExistsInPersonVarList(parDBYearVarPar.name)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{parDBYearVarPar.description.Get()}: Parameter {DefPar.Uprate.DBYearVar} was used with value '{parDBYearVarPar.name}', but this variable is not defined" }); } else { DBYearVar = parDBYearVarPar.name; } } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{this.description.Get()}: Parameter {DefPar.Uprate.DBYearVar} was used and left empty" }); } } // (1) "NORMAL" VARIABLES: // an uprating-group consists of the variable to uprate (e.g. yem=$f_cpi) and optionally of a condition (e.g. Factor_Cond={dgn=0}) foreach (var group in GetParGroups(DefPar.Uprate.GROUP_MAIN).Values) { // optional condition parameter ParCond parCond = GetUniqueGroupPar <ParCond>(DefPar.Uprate.Factor_Condition, group); // compulsory var-name/factor-parameter (e.g. yem (in policy-column) / $f_cpi (in system-column)) // usually this will be one placeholder-parameter but it is possible that one condition applies to several variables List <ParBase> listParMain = GetPlaceholderGroupPar <ParBase>(group); if (listParMain.Count == 0) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{parCond.description.Get()}: loose condition {parCond.xmlValue}" }); continue; } foreach (ParBase parMain in listParMain) { string upVarName = parMain.description.GetParName(); // get the name of the variable to uprate (e.g. yem) // check for double uprating, but take care of conditions, e.g. twice yem-uprating without condition -> warning, yem-uprating different for men and women -> ok bool exists = ExistsUpVar(upVarName, out bool conditioned); if (exists && (!conditioned || parCond == null)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{parMain.description.Get()}: double uprating of variable {upVarName}" }); } Dictionary <double, double> upFactors = GetFactors(internalFactorDefs, parMain); upVars.Add(new UpVar() { varSpec = new VarSpec() { name = upVarName }, factors = upFactors, parCondition = parCond }); // the main purpose of this registration is to ensure the variable exists (an error is issued if not) // in fact uprated variables are likely to be registered by usage (why uprate a variable that is not used?) // (it could still be that an uprated but otherwise unused variable should be in the output and would not if VarGroup is used) infoStore.operandAdmin.CheckRegistration(name: upVarName, isOutVar: false, warnIfNotInit: false, description: parMain.description); } } // check for double conditioned uprating foreach (UpVar condUpVar in from cuv in upVars where cuv.parCondition != null select cuv) { if ((from cuv in upVars where upVars.IndexOf(cuv) > upVars.IndexOf(condUpVar) && cuv.varSpec.name.ToLower() == condUpVar.varSpec.name.ToLower() && cuv.parCondition != null && cuv.parCondition.description.GetParGroup() == condUpVar.parCondition.description.GetParGroup() select cuv).Count() > 0) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{condUpVar.parCondition.description.Get()}: double uprating of variable {condUpVar.varSpec.name}" }); } } // (2) AGGREGATE VARIABLES: // the group consists of AggVar_Name (the agg-var to uprate) and a list of AggVar_Part (the vars summing up to the agg-var) // and optionally of AggVar_Tolerance (a tolerance for the check if part-vars actually sum up to agg-var) foreach (var group in GetParGroups(DefPar.Uprate.GROUP_AGG).Values) { ParVar parName = GetUniqueGroupPar <ParVar>(DefPar.Uprate.AggVar_Name, group); if (parName == null) { continue; // error is issued by general checking } if (ExistsUpVar(parName.name, out bool dummy)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{parName.description.Get()}: double uprating of variable {parName.name} (aggregate and normally)" }); } ParNumber parTol = GetUniqueGroupPar <ParNumber>(DefPar.Uprate.AggVar_Tolerance, group); AggUpVar aggUpVar = new AggUpVar() { varSpec = new VarSpec() { name = parName.name } }; if (parTol != null) { aggUpVar.tolerance = parTol.GetValue(); } foreach (ParVar parPart in GetNonUniqueGroupPar <ParVar>(DefPar.Uprate.AggVar_Part, group)) { aggUpVar.parts.Add(new VarSpec() { name = parPart.name }); } if (aggUpVar.parts.Count > 0) { aggUpVars.Add(aggUpVar); } } // (3) VARIABLES DEFINED BY REGULAR EXPRESSION (e.g. for updating expenditure variables) foreach (var group in GetParGroups(DefPar.Uprate.GROUP_REGEXP).Values) { ParBase parDef = GetUniqueGroupPar <ParBase>(DefPar.Uprate.RegExp_Def, group); ParBase parFactor = GetUniqueGroupPar <ParBase>(DefPar.Uprate.RegExp_Factor, group); if (parDef == null || parFactor == null) { continue; } upRegExp.Add(parDef.xmlValue, GetFactors(internalFactorDefs, parFactor)); } // get default factor ... ParBase parDefFac = GetUniquePar <ParBase>(DefPar.Uprate.Def_Factor); if (parDefFac != null) { defaultFactor = GetFactors(internalFactorDefs, parDefFac); } // ... and the optional parameter WarnIfNoFactor warnIfNoFactor = GetParBoolValueOrDefault(DefFun.Uprate, DefPar.Uprate.WarnIfNoFactor); // ... and the optional parameter WarnIfNonMonetary warnIfNonMonetary = GetParBoolValueOrDefault(DefFun.Uprate, DefPar.Uprate.WarnIfNonMonetary); if (zeroFactorSysCollector.Count > 0) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{description.Get()}: uprating-index for system year is 0 for {string.Join(", ", zeroFactorSysCollector)}, resulting in uprating concerned variables by 0." }); } if (zeroFactorDataCollector.Count > 0) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{description.Get()}: uprating-index for data year is 0 for {string.Join(", ", zeroFactorDataCollector)}, resulting in setting concerned variables to NaN." }); } }