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(); } }
protected override void PrepareNonCommonPar() { path = GetParBaseValueOrDefault(DefFun.DefInput, DefPar.DefInput.path); // compulsory file = GetParBaseValueOrDefault(DefFun.DefInput, DefPar.DefInput.file); // compulsory ParVar parRowMergeVar = GetUniquePar <ParVar>(DefPar.DefInput.RowMergeVar); // compulsory if (parRowMergeVar != null) { rowMergeVar = new VarSpec() { name = parRowMergeVar.name } } ; ParVar parColMergeVar = GetUniquePar <ParVar>(DefPar.DefInput.ColMergeVar); if (parColMergeVar != null) { colMergeVar = new VarSpec() { name = parColMergeVar.name } } ; ParVar parInputVar = GetUniquePar <ParVar>(DefPar.DefInput.InputVar); if (parInputVar != null) { inputVar = new VarSpec() { name = parInputVar.name } } ; if ((colMergeVar != null && inputVar == null) || (colMergeVar == null && inputVar != null)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: if {DefPar.DefInput.ColMergeVar} is defined {DefPar.DefInput.InputVar} must be defined too, and vice-versa" }); } lookUpMode = colMergeVar != null; repByEMPath = GetParBaseValueOrDefault(DefFun.DefInput, DefPar.DefInput.RepByEMPath); ignoreNRows = (int)GetParNumberValueOrDefault(DefFun.DefInput, DefPar.DefInput.IgnoreNRows); ignoreNCols = (int)GetParNumberValueOrDefault(DefFun.DefInput, DefPar.DefInput.IgnoreNCols); doRanges = GetParBoolValueOrDefault(DefFun.DefInput, DefPar.DefInput.DoRanges); parDefaultIfNoMatch = GetUniquePar <ParNumber>(DefPar.DefInput.DefaultIfNoMatch); // * * * T O D O * * * // consider parameters that allow defining and initialising variables // currently all input-variables need to be defined with DefVar or, if they are defined in variables-file, initialised with SetDefault }
protected void PrepareAgePar(FunBase fun, List <string> footnoteNumbers) // age parameters are provided by several queries { // therefore have a centralised function ... parAgeMin = fun.GetFootnotePar <ParNumber>(DefQuery.Par.AgeMin, footnoteNumbers); parAgeMax = fun.GetFootnotePar <ParNumber>(DefQuery.Par.AgeMax, footnoteNumbers); // to consider: I think age parameters are always optional // (otherwise one would need a parameter 'isOptional' and respective checks if it is false) // also see note in PrepareNMPar about getting numbers instead of just the parameters }
// currently only used by IsNtoMchild, but still make it general as future queries may make use of it protected void PrepareNMPar(FunBase fun, List <string> footnoteNumbers) { parN = fun.GetFootnotePar <ParNumber>(DefQuery.Par.N, footnoteNumbers); if (parN == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: compulsory query-parameter {DefQuery.Par.N} missing" }); } parM = fun.GetFootnotePar <ParNumber>(DefQuery.Par.M, footnoteNumbers); if (parM == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: compulsory query-parameter {DefQuery.Par.M} missing" }); } // note: getting the numbers and not just the parameters at this stage may be more efficient, but would make using // constants more difficult (actually happens) and a future change to ParFormula (for more flexibility) impossible }
/// <summary> /// try to identify parameters and, if valid, generate the respective ParXXX and put into respective lists (see above) /// </summary> private void ClassifyParameters(Dictionary <string, ExeXml.Par> xmlParList, DefinitionAdmin.Fun funDef) { int dummyGroupNumber = -9999; // this is for placeholder-parameters, see below foreach (var xmlPar in xmlParList) { Description parDescription = new Description(description, xmlPar.Value, xmlPar.Key); string xmlParName = xmlPar.Value.Name; // first check if it is an 'ordinary' parameter ... DefinitionAdmin.Par parDef = funDef.GetParDef(xmlParName); if (parDef != null) { string officialParName = funDef.GetOfficalParName(xmlParName); // is (in contrast to xmlParName) case-sensitive and // corresponds to constants as defined in Common-library // generate parameter ... ParBase par = GeneratePar(xmlPar, parDef, parDescription); // ... and put it into the list it belongs too ... if (parDef.isFootnote) // ... footnote-list { if (GetGroupNumber(xmlPar.Value, parDescription, out int dummy)) { if (!footnotePar.ContainsKey(xmlPar.Value.Group)) { footnotePar.Add(xmlPar.Value.Group, new Dictionary <string, ParBase>()); } if (!footnotePar[xmlPar.Value.Group].ContainsKey(officialParName)) { footnotePar[xmlPar.Value.Group].Add(officialParName, par); } else { ReportDoubleDef(parDescription); } } } else if (parDef.maxCount == 1) // ... unique-parameter-list { if (!uniquePar.ContainsKey(officialParName)) { uniquePar.Add(officialParName, par); if (infoStore.runConfig.warnAboutUselessGroups && !string.IsNullOrEmpty(xmlPar.Value.Group)) { ReportUselessGroup(parDescription); } } else { ReportDoubleDef(parDescription); } } else // ... non-unique-parameter-list { if (!nonUniquePar.ContainsKey(officialParName)) { nonUniquePar.Add(officialParName, new List <ParBase>()); } nonUniquePar[officialParName].Add(par); if (infoStore.runConfig.warnAboutUselessGroups && !string.IsNullOrEmpty(xmlPar.Value.Group)) { ReportUselessGroup(parDescription); } } continue; } // ... if not successuful, check if it is a group parameter ... parDef = funDef.GetGroupParDef(xmlParName, out string groupName); if (parDef != null) { if (GetGroupNumber(xmlPar.Value, parDescription, out int groupNo)) { // generate parameter ... ParBase par = GeneratePar(xmlPar, parDef, parDescription); // ... and put it into group-parameter-list if (!groupPar.ContainsKey(groupName)) { groupPar.Add(groupName, new SortedList <int, List <ParBase> >()); } if (!groupPar[groupName].ContainsKey(groupNo)) { groupPar[groupName].Add(groupNo, new List <ParBase>()); } if (parDef.maxCount > 1 || GetUniqueGroupPar <ParBase>(xmlPar.Value.Name, groupPar[groupName][groupNo]) == null) { groupPar[groupName][groupNo].Add(par); } else { ReportDoubleDef(parDescription); } } continue; } // ... if still not successful, it could still be placehoder parameter ... if (funDef.AllowsForPlaceholders()) { parDef = funDef.GetPlaceholderDef(out string phGroupName); ParBase par = GeneratePar(xmlPar, parDef, parDescription, true); if (phGroupName == null) // non-group placeholder, as e.g. in SetDefault, DefIL { if (!placeholderPar.TryAdd(xmlParName, par)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $" {parDescription.Get()}: {xmlParName} double definition (is ignored)" }); } } else // group placeholder, as e.g. in DefVar (PH, IsGlobal, IsMonetary), Uprate (PH, FactorCond) { GetGroupNumber(xmlPar.Value, parDescription, // note that this returns a dummy-group if the user didn't indicate one out int groupNo, true); // as placeholders only actually need a group if they are "further specified" (e.g. uprating-factors: factor_condition) if (!groupPar.ContainsKey(phGroupName)) { groupPar.Add(phGroupName, new SortedList <int, List <ParBase> >()); } if (!groupPar[phGroupName].ContainsKey(groupNo)) { groupPar[phGroupName].Add(groupNo, new List <ParBase>()); } groupPar[phGroupName][groupNo].Add(par); } continue; } // ... now we give up infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $" {parDescription.Get()}: unknown parameter" }); } if (infoStore.runConfig.warnAboutUselessGroups) { foreach (var groupType in groupPar) { if (groupType.Key.ToLower() == DefPar.SchedCalc.Band_XXX.ToLower()) { continue; } foreach (var group in groupType.Value) { if (group.Key >= 0 && group.Value.Count == 1) { ReportUselessGroup(group.Value[0].description); } } } } // internal function for generating parameters ParBase GeneratePar(KeyValuePair <string, ExeXml.Par> xmlPar, DefinitionAdmin.Par parDef, Description parDescription, bool isPlaceholder = false) { ParBase par; switch (parDef.valueType) { case DefPar.PAR_TYPE.FORMULA: par = new ParFormula(infoStore); break; case DefPar.PAR_TYPE.CONDITION: par = new ParCond(infoStore); break; case DefPar.PAR_TYPE.BOOLEAN: par = new ParBool(infoStore); break; case DefPar.PAR_TYPE.NUMBER: par = new ParNumber(infoStore); break; case DefPar.PAR_TYPE.TEXT: par = new ParBase(infoStore); break; case DefPar.PAR_TYPE.VAR: par = new ParVar(infoStore); break; case DefPar.PAR_TYPE.OUTVAR: par = new ParOutVar(infoStore); break; case DefPar.PAR_TYPE.IL: par = new ParIL(infoStore); break; case DefPar.PAR_TYPE.TU: par = new ParTU(infoStore); break; case DefPar.PAR_TYPE.VARorIL: par = new ParVarIL(infoStore); break; case DefPar.PAR_TYPE.CATEG: par = new ParCateg(infoStore, parDef.categValues); break; case DefPar.PAR_TYPE.PLACEHOLDER: par = new ParBase(infoStore); break; default: throw new Exception($"Not yet properly implemented parameter value type {parDef.valueType}"); } par.description = parDescription; par.xmlValue = xmlPar.Value.val; par.description.isPlaceholder = isPlaceholder; return(par); } bool GetGroupNumber(ExeXml.Par p, Description parDescription, out int groupNumber, bool allowDummy = false) { groupNumber = dummyGroupNumber++; // placeholders (e.g.uprating factors) only actually need a group if (string.IsNullOrEmpty(p.Group)) // if they are "further specified" (e.g.factor_condition) { if (allowDummy) { return(true); } infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $" {parDescription.Get()}: missing group" }); return(false); } if (int.TryParse(p.Group, out groupNumber)) { return(true); } infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $" {parDescription.Get()}: invalid group {p.Group} (must be an integer number)" }); return(false); } void ReportDoubleDef(Description parDescription) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $" {parDescription.Get()}: defined more than once" }); } void ReportUselessGroup(Description parDescription) { if (parDescription.GetFunName() != DefFun.Store) // add a special exception for Store, as it has its own reporting { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $" {parDescription.Get()}: group has no use" }); } } }
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." }); } }