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"
             });
         }
     }
 }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#6
0
        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();
            }
        }
示例#7
0
        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
        }
示例#8
0
        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
        }
示例#9
0
        // 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
        }
示例#10
0
        /// <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"
                    });
                }
            }
        }
示例#12
0
        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."
                });
            }
        }