/** * ParamTable.cc * * Created on: 10 oct. 2014 * Author: AKKA */ #include "ParamTable.hh" #include "Parameter.hh" #include "ParamData.hh" #include "ParamInfo.hh" #include "ParamMgr.hh" #include "Process.hh" #include using namespace log4cxx; namespace AMDA { namespace Info { #define PUSHINFO(infoMap, key, value) if(!value.empty())infoMap.push_back(std::pair(key,value)) LoggerPtr ParamTable::_logger(Logger::getLogger("AMDA-Kernel.ParamTable")); ParamTable::ParamTable(const char *paramId) : _paramId(paramId), _tableName(""), _tableUnits(""), _variable("false") { } ParamTable::~ParamTable() { } std::string ParamTable::getTableParamKeyForInfo(ParameterManager* /*parameterManager*/) { return ""; } /* * @brief Get param id */ std::string ParamTable::getParamId(void) { return _paramId; } /* * @brief Set name of the table */ void ParamTable::setName(std::string name) { _tableName = name; } /* * @brief Get name of the table */ std::string ParamTable::getName(ParameterManager* parameterManager) { if (_tableName.empty() && _variable) { std::string paramKeyForInfo = getTableParamKeyForInfo(parameterManager); if (!paramKeyForInfo.empty()) { std::string tableParam = getTableParamByKey(parameterManager, paramKeyForInfo); AMDA::Info::ParamInfoSPtr paramTableInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(tableParam); if (paramTableInfo != nullptr) return paramTableInfo->getName(); } } return _tableName; } /* * @brief Set units */ void ParamTable::setUnits(std::string units) { _tableUnits = units; } /* * @brief Get units of the table */ std::string ParamTable::getUnits(ParameterManager* parameterManager) { if (_tableName.empty() && _variable) { std::string paramKeyForInfo = getTableParamKeyForInfo(parameterManager); if (!paramKeyForInfo.empty()) { std::string tableParam = getTableParamByKey(parameterManager, paramKeyForInfo); AMDA::Info::ParamInfoSPtr paramTableInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(tableParam); if (paramTableInfo != nullptr) return paramTableInfo->getUnits(); } } return _tableUnits; } /* * @brief Set isVariable attribute */ void ParamTable::setIsVariable(bool isVariable) { _variable = isVariable; } /* * @brief Get if it's a variable table */ bool ParamTable::isVariable(ParameterManager* /*parameterManager*/) { return _variable; } /* * @brief Set isVariable attribute */ void ParamTable::setIsFullVariable(bool isFullVariable) { _fullVariable = isFullVariable; } /* * @brief Get if it's a variable table */ bool ParamTable::isFullVariable(ParameterManager* /*parameterManager*/) { return _fullVariable; } void ParamTable::addRelatedParams(ParameterManager *parameterManager, std::string paramId, std::listrelatedParams){ AMDA::Info::ParamInfoSPtr paramInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(paramId); if(paramInfo == NULL) return; const std::vector& paramLinkedParams = paramInfo->getLinkedParamList(); if(paramLinkedParams.empty()) return; for (auto pId : paramLinkedParams){ relatedParams.push_back(pId); addRelatedParams(parameterManager, paramId, relatedParams); } return; } void ParamTable::addTableParam(std::string key, std::string name) { _tableParams[key] = name; } std::string ParamTable::getTableParamByKey(ParameterManager* /*parameterManager*/, std::string key) { return _tableParams[key]; } std::map& ParamTable::getTableParams(ParameterManager* /*parameterManager*/) { return _tableParams; } std::vector ParamTable::getConstantTableParamValuesByKey(ParameterManager *parameterManager, std::string key) { std::vector paramValues; ParameterSPtr tmpParam = parameterManager->getParameter(_paramId); if (tmpParam == nullptr) return paramValues; AMDA::Parameters::Parameter::InfoList lInfoList = tmpParam->getInfoList(); if (_tableParams.find(key) == _tableParams.end()) return paramValues; std::string tableParamName = _tableParams[key]; if (lInfoList.find(tableParamName) == lInfoList.end()) return paramValues; paramValues = *lInfoList[tableParamName].get(); return paramValues; } std::vector ParamTable::getVariableTableParamValuesByKey(ParameterManager* /*parameterManager*/, std::map>*paramsTableData, std::string key) { std::vector paramValues; if (paramsTableData == NULL) return paramValues; if (paramsTableData->find(key) == paramsTableData->end()) return paramValues; return (*paramsTableData)[key]; } std::vector ParamTable::getTableParamValuesByKey(ParameterManager *parameterManager, std::map>*paramsTableData, std::string key) { if (_variable) return getVariableTableParamValuesByKey(parameterManager, paramsTableData, key); else return getConstantTableParamValuesByKey(parameterManager, key); } void ParamTable::addTableInfo(ParameterManager *parameterManager, int dim, std::vector>&infoMap) { std::stringstream tableDim; tableDim << dim; std::stringstream infoKey; infoKey.str(""); infoKey << PARAMETER_TABLE << "[" << tableDim.str() << "]"; PUSHINFO(infoMap, infoKey.str(), this->getName(parameterManager)); infoKey.str(""); infoKey << PARAMETER_TABLE_UNITS << "[" << tableDim.str() << "]"; PUSHINFO(infoMap, infoKey.str(), this->getUnits(parameterManager)); if (this->isVariable(parameterManager)) { this->addVariableTableInfo(parameterManager, dim, infoMap); } else { //build min and max values list std::stringstream tableMinValues; std::stringstream tableMaxValues; for (int i = 0; i< this->getSize(parameterManager); ++i) { if (i > 0) { tableMinValues << ","; tableMaxValues << ","; } AMDA::Info::t_TableBound bound = this->getBound(parameterManager, i); tableMinValues << bound.min; tableMaxValues << bound.max; } infoKey.str(""); infoKey << PARAMETER_TABLE_MINVAL << "[" << tableDim.str() << "]"; PUSHINFO(infoMap, infoKey.str(), tableMinValues.str()); infoKey.str(""); infoKey << PARAMETER_TABLE_MAXVAL << "[" << tableDim.str() << "]"; PUSHINFO(infoMap, infoKey.str(), tableMaxValues.str()); } } void ParamTable::addSemiVariableTableInfo(ParameterManager* parameterManager, int dim, std::string paramId, std::string tabKey, std::vector>&infoMap) { AMDA::Parameters::ParameterSPtr pParam = parameterManager->getParameter(paramId); Process* lProcess = dynamic_cast (pParam->getDataWriterTemplate().get()); if (lProcess != NULL) { AMDA::Parameters::SemiVariableTable semiVariableTable = lProcess ->getSemiVariableTable(); std::list::iterator it; it = std::find(_printedTables.begin(), _printedTables.end(), paramId); if (!semiVariableTable.tabHeader.empty() && it == _printedTables.end()) { std::stringstream head; head.str(""); head << "mode" << " "; for (auto h : semiVariableTable.tabHeader) { head << h << " "; } PUSHINFO(infoMap, "", head.str()); // recuperer les centres bool variableSizes = false; //unsigned int nModes = semiVariableTable.tabValues.size(); unsigned int index =0; unsigned nValues = 0; for (auto tabValues : semiVariableTable.tabValues) { if (index == 0) nValues = tabValues.second.size(); if (tabValues.second.size() != nValues) variableSizes = true; ++index; } if (variableSizes || !semiVariableTable.calculateBounds) { std::ostringstream values; for (auto tabValues : semiVariableTable.tabValues) { values << tabValues.first << " "; for (unsigned int i = 0; i < nValues; i++) { if (i < tabValues.second.size()) { values << std::to_string(tabValues.second[i]) << " "; } else { values << "NAN "; } } PUSHINFO(infoMap, "", values.str()); values.str(""); } } else { std::vector energyVec; std::map> paramsTableData; std::map> semiVariableTableData; int nMode=0; for (auto tabValues : semiVariableTable.tabValues) { paramsTableData[tabKey] = tabValues.second; for (unsigned int j = 0; j < nValues; ++j) { t_TableBound bound = getBound(parameterManager, j , ¶msTableData); if(bound.min != j/2 && bound.max !=j/2+1){ semiVariableTableData[nMode].push_back(bound.min); semiVariableTableData[nMode + 1].push_back(bound.max); } } nMode +=2; } int l = 0; int k = 0; for (auto v : semiVariableTableData) { std::ostringstream values; std::string born; (l % 2 == 0) ? born = " Min " : born = " Max "; values << std::to_string(k) << born; // Convert all doubles to string "," std::copy(v.second.begin(), v.second.end(), std::ostream_iterator(values, " ")); PUSHINFO(infoMap, "", values.str()); values.str(""); if (l % 2 != 0) k++; l++; } } _printedTables.push_back(paramId); } } AMDA::Info::ParamInfoSPtr paramInfo = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(paramId); const std::vector& paramLinkedParams = paramInfo->getLinkedParamList(); for (auto pId : paramLinkedParams) addSemiVariableTableInfo(parameterManager, dim, pId, tabKey, infoMap); return; } void ParamTable::addVariableTableInfo(ParameterManager * parameterManager, int dim, std::vector>&tableInfo) { std::map& tableParams = this->getTableParams(parameterManager); if (!tableParams.empty()) { std::stringstream infoKey; int i = 0; for (auto tableParam : tableParams) { infoKey.str(""); infoKey << VARIABLE_PARAMETER_TABLE << tableParam.first << "[" << i << "]"; PUSHINFO(tableInfo, infoKey.str(), tableParam.second); AMDA::Parameters::ParameterSPtr variableTableParam = parameterManager->getParameter(tableParam.second); addSemiVariableTableInfo(parameterManager, dim, tableParam.second, tableParam.first, tableInfo); i++; } } } std::string ParamBoundsTable::_boundsParamKey = "TABLEPARAM_BOUNDS"; ParamBoundsTable::ParamBoundsTable(const char *paramId) : ParamTable(paramId) { } std::string ParamBoundsTable::getTableParamKeyForInfo(ParameterManager* /*parameterManager*/) { return ParamBoundsTable::_boundsParamKey; } /* * @brief Get size of the table */ int ParamBoundsTable::getSize(ParameterManager *parameterManager) { if (!_variable) { std::vector boundsValues = getConstantTableParamValuesByKey(parameterManager, ParamBoundsTable::_boundsParamKey); return boundsValues.size() - 1; } else { return 0; } } /* * @brief Get a bounds for a specified index */ t_TableBound ParamBoundsTable::getBound(ParameterManager *parameterManager, unsigned int index, std::map>*paramsTableData) { t_TableBound bound; bound.index = index; std::vector boundsValues = getTableParamValuesByKey(parameterManager, paramsTableData, ParamBoundsTable::_boundsParamKey); if (boundsValues.empty() || (index >= boundsValues.size() - 1)) { LOG4CXX_ERROR(_logger, "Index " << index << " outside of table definition => Cannot get real bound"); bound.min = index; bound.max = index + 1; return bound; } bound.min = std::min(boundsValues[index], boundsValues[index + 1]); bound.max = std::max(boundsValues[index], boundsValues[index + 1]); return bound; } std::string ParamCenterTable::_centersParamKey = "TABLEPARAM_CENTERS"; ParamCenterTable::ParamCenterTable(const char *paramId, double size) : ParamTable(paramId), _size(size) { } std::string ParamCenterTable::getTableParamKeyForInfo(ParameterManager* /*parameterManager*/) { return ParamCenterTable::_centersParamKey; } /* * @brief Get size of the table */ int ParamCenterTable::getSize(ParameterManager *parameterManager) { if (!_variable) { std::vector centersValues = getConstantTableParamValuesByKey(parameterManager, ParamCenterTable::_centersParamKey); return centersValues.size(); } else { return 0; } } /* * @brief Get a bound for a specified index */ t_TableBound ParamCenterTable::getBound(ParameterManager *parameterManager, unsigned int index, std::map>*paramsTableData) { t_TableBound bound; bound.index = index; std::vector centersValues = getTableParamValuesByKey(parameterManager, paramsTableData, ParamCenterTable::_centersParamKey); if (index >= centersValues.size()) { LOG4CXX_ERROR(_logger, "Index " << index << " outside of table definition => Cannot get real bound"); bound.min = index; bound.max = index + 1; return bound; } if (!std::isnan(centersValues[index])) { bound.min = centersValues[index] - _size / 2.; bound.max = centersValues[index] + _size / 2.; } else { bound.min = NAN; bound.max = NAN; } return bound; } std::string ParamCenterWidthTable::_centersParamKey = "TABLEPARAM_CENTERS"; std::string ParamCenterWidthTable::_widthsParamKey = "TABLEPARAM_WIDTHS"; ParamCenterWidthTable::ParamCenterWidthTable(const char *paramId) : ParamTable(paramId) { } std::string ParamCenterWidthTable::getTableParamKeyForInfo(ParameterManager* /*parameterManager*/) { return ParamCenterWidthTable::_centersParamKey; } /* * @brief Get size of the table */ int ParamCenterWidthTable::getSize(ParameterManager *parameterManager) { if (!_variable) { std::vector centersValues = getConstantTableParamValuesByKey(parameterManager, ParamCenterWidthTable::_centersParamKey); return centersValues.size(); } else { return 0; } } /* * @brief Get a bound for a specified index */ t_TableBound ParamCenterWidthTable::getBound(ParameterManager *parameterManager, unsigned int index, std::map>*paramsTableData) { t_TableBound bound; bound.index = index; std::vector centersValues = getTableParamValuesByKey(parameterManager, paramsTableData, ParamCenterWidthTable::_centersParamKey); std::vector widthsValues = getTableParamValuesByKey(parameterManager, paramsTableData, ParamCenterWidthTable::_widthsParamKey); if ((index >= centersValues.size()) || (index >= widthsValues.size())) { LOG4CXX_ERROR(_logger, "Index " << index << " outside of table definition => Cannot get real bound"); bound.min = index; bound.max = index + 1; return bound; } if (!std::isnan(centersValues[index]) && !std::isnan(widthsValues[index])) { bound.min = centersValues[index] - widthsValues[index] / 2.; bound.max = centersValues[index] + widthsValues[index] / 2.; } else { bound.min = NAN; bound.max = NAN; } return bound; } std::string ParamCenterAutoTable::_centersParamKey = "TABLEPARAM_CENTERS"; ParamCenterAutoTable::ParamCenterAutoTable(const char *paramId, bool log) : ParamTable(paramId), _log(log) { } std::string ParamCenterAutoTable::getTableParamKeyForInfo(ParameterManager* /*parameterManager*/) { return ParamCenterAutoTable::_centersParamKey; } /* * @brief Get size of the table */ int ParamCenterAutoTable::getSize(ParameterManager *parameterManager) { if (!_variable) { std::vector centersValues = getConstantTableParamValuesByKey(parameterManager, ParamCenterAutoTable::_centersParamKey); return centersValues.size(); } else { return 0; } } /* * @brief Get a bound for a specified index */ t_TableBound ParamCenterAutoTable::getBound(ParameterManager *parameterManager, unsigned int index, std::map>*paramsTableData) { t_TableBound bound; bound.index = index; std::vector centersValues = getTableParamValuesByKey(parameterManager, paramsTableData, ParamCenterAutoTable::_centersParamKey); if (index >= centersValues.size()) { LOG4CXX_ERROR(_logger, "Index " << index << " outside of table definition => Cannot get real bound"); bound.min = index; bound.max = index + 1; return bound; } //Compute bounds if (centersValues.size() <= 1) { LOG4CXX_ERROR(_logger, "Table dimension too small to compute bound"); bound.min = index; bound.max = index + 1; return bound; } double minus = 0.; double plus = 0.; if (index == 0) { if (!std::isnan(centersValues[1]) && !std::isnan(centersValues[0])) { if (_log) plus = (log10(centersValues[1]) - log10(centersValues[0])) / 2.; else plus = (centersValues[1] - centersValues[0]) / 2.; } else plus = NAN; minus = plus; } else if (index == centersValues.size() - 1) { if (!std::isnan(centersValues[centersValues.size() - 1]) && !std::isnan(centersValues[centersValues.size() - 2])) { if (_log) minus = (log10(centersValues[centersValues.size() - 1]) - log10(centersValues[centersValues.size() - 2])) / 2.; else minus = (centersValues[centersValues.size() - 1] - centersValues[centersValues.size() - 2]) / 2.; } else minus = NAN; plus = minus; } else { if (_log) { if (!std::isnan(centersValues[index]) && !std::isnan(centersValues[index - 1]) && (centersValues[index] > 0) && (centersValues[index - 1] > 0)) minus = (log10(centersValues[index]) - log10(centersValues[index - 1])) / 2.; else minus = NAN; if (!std::isnan(centersValues[index + 1]) && !std::isnan(centersValues[index]) && (centersValues[index + 1] > 0) && (centersValues[index] > 0)) plus = (log10(centersValues[index + 1]) - log10(centersValues[index])) / 2.; else plus = NAN; } else { if (!std::isnan(centersValues[index]) && !std::isnan(centersValues[index - 1])) minus = (centersValues[index] - centersValues[index - 1]) / 2.; else minus = NAN; if (!std::isnan(centersValues[index + 1]) && !std::isnan(centersValues[index])) plus = (centersValues[index + 1] - centersValues[index]) / 2.; else plus = NAN; } } if (_log) { if (!std::isnan(minus)) bound.min = exp(log10(centersValues[index]) - minus); else bound.min = NAN; if (!std::isnan(plus)) bound.max = exp(log10(centersValues[index]) + plus); else bound.max = NAN; } else { if (!std::isnan(minus)) bound.min = centersValues[index] - minus; else bound.min = NAN; if (!std::isnan(plus)) bound.max = centersValues[index] + plus; else bound.max = NAN; } if (bound.min > bound.max) { double temp = bound.max; bound.max = bound.min; bound.min = temp; } return bound; } std::string ParamMinMaxTable::_minParamKey = "TABLEPARAM_MIN"; std::string ParamMinMaxTable::_maxParamKey = "TABLEPARAM_MAX"; ParamMinMaxTable::ParamMinMaxTable(const char *paramId) : ParamTable(paramId) { } /* * @brief Get size of the table */ int ParamMinMaxTable::getSize(ParameterManager *parameterManager) { if (!_variable) { std::vector minValues = getConstantTableParamValuesByKey(parameterManager, ParamMinMaxTable::_minParamKey); return minValues.size(); } else { return 0; } } /* * @brief Get bound for a specified index */ t_TableBound ParamMinMaxTable::getBound(ParameterManager *parameterManager, unsigned int index, std::map>*paramsTableData) { t_TableBound bound; bound.index = index; std::vector minValues = getTableParamValuesByKey(parameterManager, paramsTableData, ParamMinMaxTable::_minParamKey); std::vector maxValues = getTableParamValuesByKey(parameterManager, paramsTableData, ParamMinMaxTable::_maxParamKey); if ((index >= minValues.size()) || (index >= maxValues.size())) { LOG4CXX_ERROR(_logger, "Index " << index << " outside of table definition => Cannot get real bound"); bound.min = index; bound.max = index + 1; return bound; } bound.min = std::min(minValues[index], maxValues[index]); bound.max = std::max(minValues[index], maxValues[index]); return bound; } LinkTable::LinkTable(const char *paramId, const char* originParamId) : ParamTable(paramId), _originParamId(originParamId), _originTableDim(0) { } ParamTable* LinkTable::getOriginParamTable(ParameterManager* parameterManager) { if (parameterManager == NULL) { return NULL; } ParameterSPtr tmpParam = parameterManager->getParameter(_originParamId); if (tmpParam == nullptr) { return NULL; } ParamInfoSPtr paramInfo = ParamMgr::getInstance()->getParamInfoFromId(tmpParam->getInfoId()); if (paramInfo == nullptr) { return NULL; } boost::shared_ptr tableSPtr = paramInfo->getTable(_originTableDim); if (tableSPtr == nullptr) { return NULL; } return tableSPtr.get(); } std::string LinkTable::getTableParamKeyForInfo(ParameterManager* parameterManager) { std::string res = ""; ParamTable* table = getOriginParamTable(parameterManager); if (table != NULL) { res = table->getTableParamKeyForInfo(parameterManager); } return res; } std::string LinkTable::getName(ParameterManager* parameterManager) { std::string res = ""; ParamTable* table = getOriginParamTable(parameterManager); if (table != NULL) { res = table->getName(parameterManager); } return res; } std::string LinkTable::getUnits(ParameterManager* parameterManager) { std::string res = ""; ParamTable* table = getOriginParamTable(parameterManager); if (table != NULL) { res = table->getUnits(parameterManager); } return res; } bool LinkTable::isVariable(ParameterManager* parameterManager) { bool res = false; ParamTable* table = getOriginParamTable(parameterManager); if (table != NULL) { res = table->isVariable(parameterManager); } return res; } bool LinkTable::isFullVariable(ParameterManager* parameterManager) { bool res = false; ParamTable* table = getOriginParamTable(parameterManager); if (table != NULL) { res = table->isFullVariable(parameterManager); } return res; } std::map& LinkTable::getTableParams(ParameterManager* parameterManager) { ParamTable* table = getOriginParamTable(parameterManager); if (table == NULL) { return _emptyTableParam; } return table->getTableParams(parameterManager); } int LinkTable::getSize(ParameterManager *parameterManager) { ParamTable* table = getOriginParamTable(parameterManager); if (table == NULL) { return 0; } return table->getSize(parameterManager); } t_TableBound LinkTable::getBound(ParameterManager *parameterManager, unsigned int index, std::map>*paramsTableData) { t_TableBound res; ParamTable* table = getOriginParamTable(parameterManager); if (table == NULL) { res.index = index; res.min = index; res.max = index + 1; } else { res = table->getBound(parameterManager, index, paramsTableData); } return res; } } /* namespace Info */ } /* namespace AMDA */