private static void GetUpIndInfo(Dictionary <string, Dictionary <string, string> > upInds,
                                         Dictionary <string, Dictionary <string, string> > upIndYears,
                                         ExeXml.Country country)
        {
            foreach (Dictionary <string, string> ui in upIndYears.Values) // loop over <UPIND_YEARs>
            {
                if (ui.ContainsKey(TAGS.YEAR))
                {
                    string upIndId = ui.GetOrEmpty(TAGS.UPIND_ID);

                    string sVal = ui.GetOrEmpty(TAGS.VALUE);
                    if (upIndId == string.Empty || sVal == string.Empty ||
                        !double.TryParse(EM_Helpers.AdaptDecimalSign(sVal), out double val))
                    {
                        continue;
                    }

                    string facName = null; // get the name of the factor from <UPINDs>
                    if (upInds.ContainsKey(upIndId) && upInds[upIndId].ContainsKey(TAGS.NAME))
                    {
                        facName = upInds[upIndId][TAGS.NAME];
                    }

                    // Store all uprate indices
                    if (!country.upFacs.ContainsKey(facName))   // If uprating factor name does not exist, create a new entry
                    {
                        country.upFacs.Add(facName, new ExeXml.UpIndDict());
                    }
                    country.upFacs[facName].SetYear(ui[TAGS.YEAR], val);
                }
            }
        }
Ejemplo n.º 2
0
        public static double ReadExRate(string path, string country,
                                        string sysName,            // in future perhaps 'year'
                                        string exRateDate,         // supposed to be TAGS.EXRATE_AVERAGE or TAGS.EXRATE_1stSEMESTER or
                                        Communicator communicator) //                TAGS.EXRATE_2ndSEMESTER or TAGS.EXRATE_DEFAULT
        {
            try
            {
                if (!File.Exists(path))
                {
                    return(-1);
                }

                using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
                    using (XmlReader reader = XmlReader.Create(sr))
                    {
                        // find the appropriate exchangerate for the system to run
                        foreach (var rate in XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.EXRATE,
                                                                         hasId: false, uniqueProperties: false).Values)
                        {
                            if (rate.GetOrEmpty(TAGS.EXRATE_COUNTRY).ToLower() != country.ToLower())
                            {
                                continue;
                            }

                            foreach (var prop in rate)                    // in future this could perhaps be 'if (rate.GetOrEmpty(TAGS.YEAR) == year)'
                            {
                                if (prop.Key.StartsWith(TAGS.SYS_NAME) && // (non-unique tags are stored as SysName1,SysName2,... in the Dictionary)
                                    prop.Value.ToLower() == sysName.ToLower())
                                {
                                    if (exRateDate == TAGS.EXRATE_DEFAULT)                                  // if the user didn't define a concrete date (e.g. June30) use <Default>xxx</Default>
                                    {
                                        exRateDate = rate.GetOrEmpty(TAGS.EXRATE_DEFAULT).Replace(" ", ""); // e.g. June 30 -> June30 (the former is the content of <Default>xxx</Default>, the latter the tag-name)
                                    }
                                    string sRate = EM_Helpers.AdaptDecimalSign(rate.GetOrEmpty(exRateDate));
                                    if (double.TryParse(sRate, out double exRate))
                                    {
                                        return(exRate);
                                    }

                                    ReportError(communicator, path, $"Exchange rate for {sysName} invalid" +
                                                (sRate != string.Empty ? $": {sRate}" : string.Empty));
                                    return(-1);
                                }
                            }
                        }
                    }
                return(-1); // note: -1 is also what's used in the file to indicate n/a (thus easier for the caller to just check for -1)
                            // also note: not finding must not be reported here, as the rate may not be required (actually quite likely that data/param/output are in same currency)
            }
            catch (Exception exception)
            {
                throw new Exception($"Failure reading file {path}{Environment.NewLine}{exception.Message}");
            }
        }
Ejemplo n.º 3
0
        private double GetAddMod(ParBase par)
        {
            string addMode = par.xmlValue.Trim(); // i.e. '+' or '-' or '+0.5' or ...

            if (addMode == "+" || addMode == "-")
            {
                addMode += "1";
            }
            if (!double.TryParse(EM_Helpers.AdaptDecimalSign(addMode), out double am))
            {
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = false, message = $"{par.description.Get()}: invalid incomelist add-mode: {addMode}"
                });
            }
            return(am);
        }
        // used in GetPolInfo and GetFunInfo to assess the <Order>
        private static double GetOrder(Dictionary <string, string> props, out string error)
        {
            double order = -1.0; error = null;

            if (!props.ContainsKey(TAGS.ORDER))
            {
                error = GenErr("not found");
            }
            else if (!double.TryParse(EM_Helpers.AdaptDecimalSign(props[TAGS.ORDER]), out order))
            {
                error = GenErr($"invalid: {props[TAGS.ORDER]}");
            }
            return(order);

            string GenErr(string what)
            {
                return($"{props.GetOrEmpty(TAGS.POL_ID)}{props.GetOrEmpty(TAGS.FUN_ID)}: <{TAGS.ORDER}> {what}");
            }
        }
        private static bool GetIndTaxInfo(Dictionary <string, Dictionary <string, string> > indTaxes,
                                          Dictionary <string, Dictionary <string, string> > indTaxYears,
                                          ExeXml.Country country)
        {
            if (string.IsNullOrEmpty(country.data.indirectTaxTableYear))
            {
                return(true);
            }
            string relevantYear = country.data.indirectTaxTableYear.Trim().ToLower();

            foreach (Dictionary <string, string> it in indTaxYears.Values) // loop over <INDTAX_YEARs>
            {
                if (it.GetOrEmpty(TAGS.YEAR) != relevantYear)
                {
                    continue;
                }

                string indTaxId = it.GetOrEmpty(TAGS.INDTAX_ID);
                string sVal     = it.GetOrEmpty(TAGS.VALUE).Trim();
                if (indTaxId == string.Empty || sVal == string.Empty || sVal == DefPar.Value.NA)
                {
                    continue;
                }

                double pct = sVal.EndsWith("%") ? 0.01 : 1;
                if (!double.TryParse(EM_Helpers.AdaptDecimalSign(sVal.Replace("%", "")), out double val))
                {
                    continue;
                }

                string indTaxName = null; // get the name of the factor from <INDTAXs>
                if (indTaxes.ContainsKey(indTaxId) && indTaxes[indTaxId].ContainsKey(TAGS.NAME))
                {
                    indTaxName = indTaxes[indTaxId][TAGS.NAME];
                }

                country.indTaxes.AddOrReplace(indTaxName, val * pct);
            }
            return(country.indTaxes.Count > 0);
        }
        private string constName = null; // only relevant if value is a constant, e.g. #_amount = $Const_A, Factor_Value = $Const_B

        internal override void CheckAndPrepare(FunBase fun)
        {
            double periodFactor = HandlePeriodFactor(out string xmlCleaned);

            // if TryParse works: a simple number ...
            if (double.TryParse(EM_Helpers.AdaptDecimalSign(xmlCleaned), out value))
            {
                value *= periodFactor; return;
            }

            // ... if not: possibly a constant
            if (infoStore.operandAdmin.Exists(xmlValue) && infoStore.operandAdmin.GetIsGlobal(xmlValue))
            {
                constName = xmlValue; // note: not necessary to us xmlCleaned, as a constant cannot have a period
            }
            else
            {
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = false, message = $"{description.Get()}: {xmlValue} is not a valid number"
                });
            }
        }
Ejemplo n.º 7
0
        public static ExeXml.UpIndDict ReadHICP(string path, string country, string sysYear, string dataYear, Communicator communicator)
        {
            try
            {
                ExeXml.UpIndDict HICP = new ExeXml.UpIndDict();
                if (!File.Exists(path))
                {
                    return(HICP);
                }

                using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
                    using (XmlReader reader = XmlReader.Create(sr))
                    {
                        // find the appropriate HICP for the respective data- and system-year
                        foreach (var rate in XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.HICP, hasId: false).Values)
                        {
                            if (rate.GetOrEmpty(TAGS.EXRATE_COUNTRY).ToLower() != country.ToLower())
                            {
                                continue;
                            }

                            string year = rate.GetOrEmpty(TAGS.YEAR);

                            string shicp = EM_Helpers.AdaptDecimalSign(rate.GetOrEmpty(TAGS.VALUE));
                            if (double.TryParse(shicp, out double hicp))
                            {
                                HICP.SetYear(year, hicp);
                            }
                        }
                    }
                return(HICP); // note: not finding must not be reported here, as the HICP may not be required
            }
            catch (Exception exception)
            {
                throw new Exception($"Failure reading file {path}{Environment.NewLine}{exception.Message}");
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// read data from file and create the complete list of variables for each person (HH.personVarList),
        /// i.e. also for non-data variables (simulated, created by DefVar, loop-counters, ...)
        /// note that HHAdmin and OperandAmin need to "talk" a bit here:
        /// e.g. OperandAdmin tells HHAdmin what to read (incl. vars that may be provided by SetDefault); HHAdmin reports back what he read
        /// </summary>
        internal void GenerateData()
        {
            string path = GetDataPath(infoStore);

            try // note: maybe the extra try/catch is disputable (i.e. one could rely on general try/catch as all other functions instead)
            {   // but IO-problems seem more likely and serious and this may help to better locate the error
                IEnumerable <string> inputLines = null;
                if (!string.IsNullOrEmpty(infoStore.runConfig.inputPassword))
                {
                    byte[] allBytes = File.ReadAllBytes(path);
                    allBytes = EM_Crypt.EM_Crypt.SimpleDecryptWithPassword(allBytes, infoStore.runConfig.inputPassword);
                    if (allBytes == null)
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = false, message = $"Wrong decryption password!"
                        });
                        return;
                    }
                    inputLines = System.Text.Encoding.Default.GetString(allBytes).Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                }
                else
                {
                    inputLines = File.ReadLines(path);
                }

                // first split header line to get the column-indices of the variables to read
                Dictionary <string, int> varColumn       = new Dictionary <string, int>();
                Dictionary <string, int> stringVarColumn = new Dictionary <string, int>();

                // check if all variables exist
                List <string> missing = new List <string>(); string missingStringVar = string.Empty;
                foreach (var readVar in infoStore.operandAdmin.GetVarsToRead()) // the numeric (i.e. usual) variables
                {
                    if (infoStore.allDataVariables.Contains(readVar))           // data contains the variable
                    {
                        varColumn.Add(readVar, infoStore.allDataVariables.IndexOf(readVar));
                        infoStore.operandAdmin.SetProvidedBySetDefault(readVar, false); // "inform" any possible SetDefault that
                    }                                                                   // it does not have to provide a value
                    else // data does not contain the variable
                    {
                        if (!infoStore.operandAdmin.IsProvidedByDefault(readVar, infoStore.country.data.useCommonDefault))
                        {
                            missing.Add(readVar);
                        }
                        // else will be initialised by SetDefault
                    }
                }
                foreach (string stringVar in infoStore.operandAdmin.indexStringVars.Keys) // possible (rather unusual) string variables
                {
                    if (infoStore.allDataVariables.Contains(stringVar))
                    {
                        stringVarColumn.Add(stringVar, infoStore.allDataVariables.IndexOf(stringVar));
                    }
                    else
                    {
                        missingStringVar += stringVar + ", ";
                    }
                }

                if (missingStringVar != string.Empty)
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true,
                        message   = $"{path}: String-variable(s) {missingStringVar.TrimEnd(new char[] { ',', ' ' })} not found (thus cannot be outputted)"
                    });
                }

                // get non-data variables from the OperandAdmin, i.e. simulated vars, vars generated by DefVar, by default, loop-counters, ...
                // as they also need to be added to the persons' variables list, see below
                List <string> nonDataVars = infoStore.operandAdmin.GetPersonVarsNotRead();

                if (missing.Count > 0)
                {
                    string sMissing = string.Empty;  foreach (string m in missing)
                    {
                        nonDataVars.Add(m); sMissing += m + ", ";
                    }
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true,
                        message   = $"{path}: Variable(s) {sMissing.TrimEnd(new char[] { ',', ' ' })} not found (zero is used as default)"
                    });
                }

                // assess the column-index of the idHH variable
                string IDHH = DefVarName.IDHH;
                int    indexIDHH; if (varColumn.ContainsKey(IDHH))
                {
                    indexIDHH = indexIDHH = varColumn[IDHH];
                }
                else
                {
                    throw new Exception($"Variable {IDHH} not found");
                }

                double?firstHH = infoStore.runConfig.firstHH, lastHH = infoStore.runConfig.lastHH;
                double nHHOnly = infoStore.runConfig.nHHOnly, nHHRead = 0;

                // generate the (complete) variables-list for each person in each HH
                hhs = new List <HH>(); Dictionary <string, HH> indexReadHH = new Dictionary <string, HH>();
                foreach (string inputLine in inputLines.Skip(1))
                {
                    if (inputLine == string.Empty)
                    {
                        continue;
                    }
                    string[] splitInputLine = inputLine.Split('\t');
                    HH       currentHH;
                    if (!indexReadHH.ContainsKey(splitInputLine[indexIDHH]))
                    {
                        currentHH = new HH(infoStore);

                        if (firstHH != null && double.TryParse(splitInputLine[indexIDHH], out double fhhid) && fhhid < firstHH)
                        {
                            continue;
                        }
                        if (lastHH != null && double.TryParse(splitInputLine[indexIDHH], out double lhhid) && lhhid > lastHH)
                        {
                            break;
                        }
                        if (++nHHRead > nHHOnly)
                        {
                            break;
                        }

                        hhs.Add(currentHH); indexReadHH.Add(splitInputLine[indexIDHH], currentHH);
                    }
                    else
                    {
                        currentHH = indexReadHH[splitInputLine[indexIDHH]];
                    }

                    // first get (numeric) data variables for the person ...
                    List <double> onePersonsVariables = new List <double>(varColumn.Count);
                    foreach (var vc in varColumn.Values)
                    {
                        if (!double.TryParse(EM_Helpers.AdaptDecimalSign(splitInputLine[vc]), out double number))
                        {
                            throw new Exception($"Variable {(from v in varColumn where v.Value == vc select v.Key).FirstOrDefault()}: failed converting '{splitInputLine[vc]}' to number");
                        }
                        onePersonsVariables.Add(number);
                    }

                    // ... then add 0 for each non-data variable ...
                    for (int ndv = 0; ndv < nonDataVars.Count; ++ndv)
                    {
                        onePersonsVariables.Add(0);
                    }

                    // ... finally get (rather unusual) non-numeric data variables
                    List <string> onePersonsStringVariables = new List <string>(stringVarColumn.Count);
                    foreach (var svc in stringVarColumn.Values)
                    {
                        onePersonsStringVariables.Add(splitInputLine[svc]);
                    }

                    currentHH.personVarList.Add(onePersonsVariables);
                    currentHH.personStringVarList.Add(onePersonsStringVariables);
                }

                if (hhs.Count == 0)
                {
                    throw new Exception("No housholds could be read");
                }

                // "inform" the OperandAdmin about the final variable-index in the HH.personVarList
                int c = 0; Dictionary <string, int> varIndex = new Dictionary <string, int>(), stringVarIndex = new Dictionary <string, int>();
                foreach (var vi in varColumn)
                {
                    varIndex.Add(vi.Key, c++);
                }
                foreach (string v in nonDataVars)
                {
                    varIndex.Add(v, c++);
                }
                c = 0; foreach (var vi in stringVarColumn)
                {
                    stringVarIndex.Add(vi.Key, c++);
                }
                infoStore.operandAdmin.SetVarIndex(varIndex, stringVarIndex);

                // each HH has a dummy individual TU (for usage by spine-functions which do not have a TAX_UNIT parameter
                // (see CreateDummyTU-function for further comments)
                infoStore.indexTUs.Add(DUMMY_INDIVIDUAL_TU, null);
                foreach (HH hh in hhs)
                {
                    CreateDummyTU(hh);
                }

#if OLD_EXE_COMPARISON
                SimulateOldExeRand();
#endif
            }
            catch (Exception exception)
            {
                throw new Exception($"Failed reading file {path}{Environment.NewLine}{exception.Message}");
            }
        }
Ejemplo n.º 9
0
        private bool Read_LookUpMode(string fullPath, out Dictionary <double, List <double> > rows, out List <double> cols)
        {
            rows = new Dictionary <double, List <double> >(); cols = new List <double>();
            try
            {
                var inputLines = File.ReadLines(fullPath).Skip(ignoreNRows);
                foreach (string cv in inputLines.First().Split('\t').Skip(ignoreNCols + 1)) // first column must contain row-identifiers
                {
                    if (!double.TryParse(EM_Helpers.AdaptDecimalSign(cv), out double colValue))
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true,
                            message   = $"{description.Get()}: {cv} is not a valid number - input is canceled"
                        });
                        return(false);
                    }
                    if (cols.Contains(colValue))
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true,
                            message   = $"{description.Get()}: colum identifier is not unique ({colValue}) - input is canceled"
                        });
                        return(false);
                    }
                    cols.Add(colValue);
                }
                if (cols.Count == 0)
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true,
                        message   = $"{description.Get()}: data contains no columns - input is canceled"
                    });
                    return(false);
                }

                string idErr1 = Guid.NewGuid().ToString();
                foreach (string inputLine in inputLines.Skip(1))
                {
                    if (inputLine == string.Empty)
                    {
                        continue;
                    }
                    var splitInputLine = inputLine.Split('\t').Skip(ignoreNCols);

                    if (splitInputLine.Count() < cols.Count + 1)
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true, runTimeErrorId = idErr1,
                            message   = $"{description.Get()}: too short line is ignored: ({(inputLine.Length > 20 ? inputLine.Substring(0, 20) : inputLine)})"
                        });
                        continue;
                    }

                    double rowIdentifier = 0; List <double> rowValues = new List <double>();
                    for (int c = 0; c < splitInputLine.Count(); ++c)
                    {
                        if (!double.TryParse(EM_Helpers.AdaptDecimalSign(splitInputLine.ElementAt(c)), out double value))
                        {
                            infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                            {
                                isWarning = true,
                                message   = $"{description.Get()}: {splitInputLine.ElementAt(c)} is not a valid number - input is canceled"
                            });
                            return(false);
                        }
                        if (c == 0)
                        {
                            rowIdentifier = value;
                        }
                        else
                        {
                            rowValues.Add(value);
                        }
                    }
                    if (rows.ContainsKey(rowIdentifier))
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true,
                            message   = $"{description.Get()}: row identifier is not unique ({rowIdentifier}) - input is canceled"
                        });
                        return(false);
                    }
                    rows.Add(rowIdentifier, rowValues);
                }

                if (rows.Count == 0)
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true,
                        message   = $"{description.Get()}: data contains no rows - input is canceled"
                    });
                    return(false);
                }

                if (lookUpMode)
                {
                    if (!CheckAsc(cols, "column ranges") || !CheckAsc(rows.Keys.ToList(), "row ranges"))
                    {
                        return(false);
                    }
                }

                return(true);

                bool CheckAsc(List <double> vals, string what)
                {
                    double prev = double.MinValue;

                    foreach (double c in vals)
                    {
                        if (c < prev)
                        {
                            infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                            {
                                isWarning = true,
                                message   = $"{description.Get()}: {what} are not ascending ({prev} > {c}) - input is canceled"
                            });
                            return(false);
                        }
                        prev = c;
                    }
                    return(true);
                }
            }
            catch (Exception exception)
            {
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = true,
                    message   = $"{description.Get()}: {exception.Message} - input is canceled"
                });
                return(false);
            }
        }
Ejemplo n.º 10
0
        private bool Read_InputMode(string fullPath, out Dictionary <double, List <double> > inputContent, out Dictionary <int, int> indexMatches)
        {
            inputContent = new Dictionary <double, List <double> >(); indexMatches = new Dictionary <int, int>();
            try
            {
                var           inputLines = File.ReadLines(fullPath).Skip(ignoreNRows);
                List <string> headers    = new List <string>(); foreach (string v in inputLines.First().ToLower().Split('\t').Skip(ignoreNCols))
                {
                    headers.Add(v.Trim());
                }

                int indexMergeVar = -1; Dictionary <int, int> tempIndexMatches = new Dictionary <int, int>();
                for (int iInputCol = 0; iInputCol < headers.Count; ++iInputCol)
                {
                    string varName = headers[iInputCol];
                    if (infoStore.operandAdmin.Exists(varName))
                    {
                        int iData = infoStore.operandAdmin.GetIndexInPersonVarList(varName);
                        if (iData >= 0)
                        {
                            if (iData == rowMergeVar.index)
                            {
                                indexMergeVar = iInputCol;
                            }
                            else
                            {
                                tempIndexMatches.Add(iData, iInputCol);
                            }
                            continue;
                        }
                    }
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true,
                        message   = $"{description.Get()}: {varName} is not the name of an existing variable ({varName} is not inputted)"
                    });
                }

                if (indexMergeVar == -1)
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true,
                        message   = $"{description.Get()}: merge-variable {rowMergeVar.name} not found in input data - input is canceled"
                    });
                    return(false);
                }

                if (tempIndexMatches.Count == 0)
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true,
                        message   = $"{description.Get()}: no (valid) variables for input found - input is canceled"
                    });
                    return(false);
                }

                string idErr1 = Guid.NewGuid().ToString(), idErr2 = Guid.NewGuid().ToString(), idErr3 = Guid.NewGuid().ToString(), idErr4 = Guid.NewGuid().ToString();
                foreach (string inputLine in inputLines.Skip(1))
                {
                    if (inputLine == string.Empty)
                    {
                        continue;
                    }
                    var splitInputLine = inputLine.Split('\t').Skip(ignoreNCols);

                    if (splitInputLine.Count() < headers.Count)
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true, runTimeErrorId = idErr1,
                            message   = $"{description.Get()}: too short line is ignored: ({(inputLine.Length > 20 ? inputLine.Substring(0, 20) : inputLine)})"
                        });
                        continue;
                    }

                    string strValMergeVar = splitInputLine.ElementAt(indexMergeVar);
                    if (!double.TryParse(EM_Helpers.AdaptDecimalSign(strValMergeVar), out double valMergeVar))
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true, runTimeErrorId = idErr2,
                            message   = $"{description.Get()}: value of {rowMergeVar.name} {strValMergeVar} is not a valid number - line is ignored"
                        });
                        continue;
                    }

                    if (inputContent.ContainsKey(valMergeVar))
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true, runTimeErrorId = idErr3,
                            message   = $"{description.Get()}: {rowMergeVar.name} is not unique ({valMergeVar}) - only first value is taken into account"
                        });
                        continue;
                    }

                    List <double> valOtherVar = new List <double>(tempIndexMatches.Count);
                    foreach (int im in tempIndexMatches.Values)
                    {
                        if (!double.TryParse(EM_Helpers.AdaptDecimalSign(splitInputLine.ElementAt(im)), out double number))
                        {
                            infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                            {
                                isWarning = true, runTimeErrorId = idErr4,
                                message   = $"{description.Get()}: {splitInputLine.ElementAt(im)} is not a valid number - 0 is used as default"
                            });
                            number = 0;
                        }
                        valOtherVar.Add(number);
                    }
                    inputContent.Add(valMergeVar, valOtherVar);
                }

                // example: input-row: inputVar1, mergeVar, inputVar2, ...
                //          tempIndexMatches = {27, 0}, {88, 2} // the first value is a phantasie-value for the index in the data-array
                //          indexMatches = {27, 0}, {88, 1}
                foreach (var im in tempIndexMatches)
                {
                    indexMatches.Add(im.Key, im.Value > indexMergeVar ? im.Value - 1 : im.Value);
                }

                return(true);
            }
            catch (Exception exception)
            {
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = true,
                    message   = $"{description.Get()}: {exception.Message} - input is canceled"
                });
                return(false);
            }
        }
        private Dictionary <double, double> GetFactors(Dictionary <string, double> internalFactorDefs, ParBase parFac)
        {
            Dictionary <double, double> allFactors = new Dictionary <double, double>();
            string upFactorS = parFac.xmlValue; // xmlValue contains the uprating instruction,

            // which may be a number (e.g. 1.4) or the name of a factor (e.g. $f_cpi)
            if (!double.TryParse(EM_Helpers.AdaptDecimalSign(upFactorS), out double upFactor)) // first try if a number ...
            {
                if (internalFactorDefs.ContainsKey(upFactorS))                                 // ... then try if a factor defined by Factor_Name/Factor_Value
                {
                    allFactors.Add(UpVar.ALLYEARS, internalFactorDefs[upFactorS]);
                }
                else if (infoStore.country.upFacs.ContainsKey(upFactorS)) // ... then try if a factor-name defined in dialog
                {
                    if (infoStore.country.upFacs[upFactorS].Get(infoStore.country.sys.year, out double sysInd))
                    {
                        if (sysInd == 0 && !zeroFactorSysCollector.Contains(upFactorS))
                        {
                            zeroFactorSysCollector.Add(upFactorS);
                        }
                        if (isDBYearVarUsed)
                        {
                            // Calculate the uprating factors
                            foreach (KeyValuePair <string, double> facs in infoStore.country.upFacs[upFactorS].GetAll())
                            {
                                if (double.TryParse(facs.Key, out double yr))
                                {
                                    if (facs.Value == 0 && !zeroFactorDataCollector.Contains(facs.Key))
                                    {
                                        zeroFactorDataCollector.Add(facs.Key);
                                    }
                                    allFactors.Add(yr, sysInd / facs.Value);
                                }
                                else
                                {
                                    // This should only happen if a year cannot be parsed - This should NEVER happen!
                                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                                    {
                                        isWarning = false,
                                        message   = $"{parFac.description.Get()}: invalid year '{facs.Key}' found in uprating factors!"
                                    });
                                    return(allFactors);
                                }
                            }
                        }
                        else
                        {
                            if (infoStore.country.upFacs[upFactorS].Get(infoStore.country.data.year, out double dbInd))
                            {
                                if (dbInd == 0 && !zeroFactorDataCollector.Contains(upFactorS))
                                {
                                    zeroFactorDataCollector.Add(upFactorS);
                                }
                                allFactors.Add(UpVar.ALLYEARS, sysInd / dbInd);
                            }
                            else
                            {
                                // Or keep 1 and return warning if any indices are missing
                                string dataInfo = string.IsNullOrEmpty(infoStore.country.data.year)
                                    ? $": income-year is missing for '{infoStore.country.data.Name}'"
                                    : $" for data year '{infoStore.country.data.year}'";
                                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                                {
                                    isWarning = true,
                                    message   = $"{parFac.description.Get()}: insufficient definition of uprating-factor '{parFac.xmlValue}'{dataInfo} (1 is used as default)"
                                });
                            }
                        }
                    }
                    else
                    {
                        // Or keep 1 and return warning if any indices are missing
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = true,
                            message   = $"{parFac.description.Get()}: insufficient definition of uprating-factor '{parFac.xmlValue}' for system year '{infoStore.country.sys.year}' (1 is used as default)"
                        });
                    }
                }
                else
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = false,
                        message   = $"{parFac.description.Get()}: unknown factor {parFac.xmlValue}"
                    });
                }
            }
            else
            {
                allFactors.Add(UpVar.ALLYEARS, upFactor);
            }
            return(allFactors);
        }