/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
DQM/CSCMonitorModule/plugins/CSCDQM_Utility.cc
415 строк
13 KB
Cms Build
Clang-Format
10 май 2019, 18:01
10 май 2019, 18:01
ee68c24
Код
Авторство
О чём код?
/* ===================================================================================== * * Filename: CSCDQM_Utility.cc * * Description: Histogram Utility code * * Version: 1.0 * Created: 04/18/2008 03:39:49 PM * Revision: none * Compiler: gcc * * Author: Valdas Rapsevicius (VR), Valdas.Rapsevicius@cern.ch * Company: CERN, CH * * ===================================================================================== */ #ifdef CSC_RENDER_PLUGIN #include "CSCDQM_Utility.h" #else #include "CSCDQM_Utility.h" #endif #include <cstdint> namespace cscdqm { /** * @brief Get CSC y-axis position from chamber string * @param cstr Chamber string * @return chamber y-axis position */ int Utility::getCSCTypeBin(const std::string& cstr) { if (cstr == "ME-4/2") return 0; if (cstr == "ME-4/1") return 1; if (cstr == "ME-3/2") return 2; if (cstr == "ME-3/1") return 3; if (cstr == "ME-2/2") return 4; if (cstr == "ME-2/1") return 5; if (cstr == "ME-1/3") return 6; if (cstr == "ME-1/2") return 7; if (cstr == "ME-1/1") return 8; if (cstr == "ME+1/1") return 9; if (cstr == "ME+1/2") return 10; if (cstr == "ME+1/3") return 11; if (cstr == "ME+2/1") return 12; if (cstr == "ME+2/2") return 13; if (cstr == "ME+3/1") return 14; if (cstr == "ME+3/2") return 15; if (cstr == "ME+4/1") return 16; if (cstr == "ME+4/2") return 17; return 0; } /** * @brief Get CSC label from CSC parameters * @param endcap Endcap number * @param station Station number * @param ring Ring number * @return chamber label */ std::string Utility::getCSCTypeLabel(int endcap, int station, int ring) { std::string label = "Unknown"; std::ostringstream st; if ((endcap > 0) && (station > 0) && (ring > 0)) { if (endcap == 1) { st << "ME+" << station << "/" << ring; label = st.str(); } else if (endcap == 2) { st << "ME-" << station << "/" << ring; label = st.str(); } else { label = "Unknown"; } } return label; } /** * @brief Break string into tokens * @param str source string to break * @param tokens pointer to result vector * @param delimiters delimiter string, default " " * @return */ int Utility::tokenize(const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters) { std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); std::string::size_type pos = str.find_first_of(delimiters, lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { tokens.push_back(str.substr(lastPos, pos - lastPos)); lastPos = str.find_first_not_of(delimiters, pos); pos = str.find_first_of(delimiters, lastPos); } return tokens.size(); } /** * @brief Split string according to delimiter * @param str String to split * @param delim Delimiter * @param results Vector to write results to * @return */ void Utility::splitString(const std::string& str, const std::string& delim, std::vector<std::string>& results) { std::string::size_type lastPos = str.find_first_not_of(delim, 0); std::string::size_type pos = str.find_first_of(delim, lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { results.push_back(str.substr(lastPos, pos - lastPos)); lastPos = str.find_first_not_of(delim, pos); pos = str.find_first_of(delim, lastPos); } } /** * @brief Trim string * @param str string to trim */ void Utility::trimString(std::string& str) { std::string::size_type pos = str.find_last_not_of(' '); if (pos != std::string::npos) { str.erase(pos + 1); pos = str.find_first_not_of(' '); if (pos != std::string::npos) { str.erase(0, pos); } } else { str.erase(str.begin(), str.end()); } } /** * @brief Match RegExp expression against string message and return result * @param re_expression RegExp expression to match * @param message value to check * @return true if message matches RegExp expression */ bool Utility::regexMatch(const TPRegexp& re_expression, const std::string& message) { TPRegexp* re = const_cast<TPRegexp*>(&re_expression); return re->MatchB(message); } /** * @brief Match RegExp expression string against string message and return result * @param expression RegExp expression in string to match * @param message value to check * @return true if message matches RegExp expression */ bool Utility::regexMatch(const std::string& expression, const std::string& message) { return regexMatch(TPRegexp(expression), message); } /** * @brief Replace string part that matches RegExp expression with some * string * @param expression RegExp expression in string to match * @param message value to check * @param replace string to replace matched part */ void Utility::regexReplace(const std::string& expression, std::string& message, const std::string replace) { Utility::regexReplace(TPRegexp(expression), message, replace); } /** * @brief Replace string part that matches RegExp expression with some * string * @param re_expression RegExp expression to match * @param message value to check * @param replace string to replace matched part */ void Utility::regexReplace(const TPRegexp& re_expression, std::string& message, const std::string replace) { TString s(message); TPRegexp* re = const_cast<TPRegexp*>(&re_expression); re->Substitute(s, replace); message = static_cast<const char*>(s); } /** * @brief Replace string part that matches RegExp expression with some * string * @param expression RegExp expression in string to match * @param message value to check * @param replace string to replace matched part * @return modified string */ std::string Utility::regexReplaceStr(const std::string& expression, const std::string& message, const std::string replace) { return regexReplaceStr(TPRegexp(expression), message, replace); } /** * @brief Replace string part that matches RegExp expression with some * string * @param re_expression RegExp expression to match * @param message value to check * @param replace string to replace matched part * @return modified string */ std::string Utility::regexReplaceStr(const TPRegexp& re_expression, const std::string& message, const std::string replace) { TString s(message); TPRegexp* re = const_cast<TPRegexp*>(&re_expression); re->Substitute(s, replace); return s.Data(); } #undef get16bits #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__BORLANDC__) || \ defined(__TURBOC__) #define get16bits(d) (*((const uint16_t*)(d))) #endif #if !defined(get16bits) #define get16bits(d) ((((uint32_t)(((const uint8_t*)(d))[1])) << 8) + (uint32_t)(((const uint8_t*)(d))[0])) #endif /** * @brief Calculate super fast hash (from http://www.azillionmonkeys.com/qed/hash.html) * @param data Source Data * @param length of data * @return hash result */ uint32_t Utility::fastHash(const char* data, int len) { uint32_t hash = len, tmp; int rem; if (len <= 0 || data == nullptr) return 0; rem = len & 3; len >>= 2; /* Main loop */ for (; len > 0; len--) { hash += get16bits(data); tmp = (get16bits(data + 2) << 11) ^ hash; hash = (hash << 16) ^ tmp; data += 2 * sizeof(uint16_t); hash += hash >> 11; } /* Handle end cases */ switch (rem) { case 3: hash += get16bits(data); hash ^= hash << 16; hash ^= data[sizeof(uint16_t)] << 18; hash += hash >> 11; break; case 2: hash += get16bits(data); hash ^= hash << 11; hash += hash >> 17; break; case 1: hash += *data; hash ^= hash << 10; hash += hash >> 1; } /* Force "avalanching" of final 127 bits */ hash ^= hash << 3; hash += hash >> 5; hash ^= hash << 4; hash += hash >> 17; hash ^= hash << 25; hash += hash >> 6; return hash; } /** * @brief Check the hypothesis that observed events (n) value is too low or too high comparing with the expected N * @param N Expected number of events * @param n Actual (observed) number of events * @param low_threshold Rate of lower boundary of tolerance (< 1) * @param high_threshold Rate of higher boundary of tolerance (> 1) * @param low_sigfail Significance threshold for low value * @param high_sigfail Significance threshold for high value * @return check outcome: 1 - observed number of events too high wrt expected * (HOT), -1 - observed number of events too low wrt expected (COLD), 0 - * observed number of events is fine wrt expected */ short Utility::checkOccupancy(const unsigned int N, const unsigned int n, const double low_threshold, const double high_threshold, const double low_sigfail, const double high_sigfail) { if (N > 0) { double eps_meas = (1.0 * n) / (1.0 * N); if (eps_meas < low_threshold) { double S = Utility::SignificanceLevelLow(N, n, low_threshold); if (S > low_sigfail) return -1; } else if (eps_meas > high_threshold) { double S = Utility::SignificanceLevelHigh(N, n); if (S > high_sigfail) return 1; } } return 0; } /** * @brief Check the hypothesis that error events (n) value above threshold comparing with the expected 0 and statistics is enough * @param N Number of total events * @param n Actual (observed) number of events errors * @param threshold Rate of tolerance (<1) * @param sigfail Significance threshold for low value * @return check result: true - error is significant, false - otherwise */ bool Utility::checkError(const unsigned int N, const unsigned int n, const double threshold, const double sigfail) { if (N > 0) { const double eps_meas = (1.0 * n) / (1.0 * N); if (eps_meas > threshold) { if (Utility::SignificanceLevelLow(N, n, threshold) > sigfail) { return true; } } } return false; } /** * @brief Calculate error significance alpha for the given number of errors * based on reference number of errors for "cold" elements: actual number of * events have to be less then the reference. * @param N Number of events * @param n Number of errors * @param eps Rate of tolerance * @return Significance level */ double Utility::SignificanceLevelLow(const unsigned int N, const unsigned int n, const double eps) { /** std::cout << "N = " << N << ", n = " << n << ", eps = " << eps << "\n"; */ double l_eps = eps; if (l_eps <= 0.0) l_eps = 0.000001; if (l_eps >= 1.0) l_eps = 0.999999; double eps_meas = (1.0 * n) / (1.0 * N); double a = 1.0, b = 1.0; if (n > 0) { for (unsigned int r = 0; r < n; r++) a = a * (eps_meas / l_eps); } if (n < N) { for (unsigned int r = 0; r < (N - n); r++) b = b * (1 - eps_meas) / (1 - l_eps); } return sqrt(2.0 * log(a * b)); } /** * @brief Calculate error significance alpha for the given number of events * based on reference number of errors for "hot" elements: actual number of * events have to be larger then the reference. * @param N number of reference events * @param n number of actual events * @return error significance */ double Utility::SignificanceLevelHigh(const unsigned int N, const unsigned int n) { if (N > n) return 0.0; /** no - n observed, ne - n expected */ double no = 1.0 * n, ne = 1.0 * N; return sqrt(2.0 * (no * (log(no / ne) - 1) + ne)); } /** * @brief Get RUI Number from DDU source ID for post LS1 configuration * @param ddu_id DDI Source ID */ int Utility::getRUIfromDDUId(unsigned ddu_id) { int rui = -1; const unsigned postLS1_map[] = {841, 842, 843, 844, 845, 846, 847, 848, 849, 831, 832, 833, 834, 835, 836, 837, 838, 839, 861, 862, 863, 864, 865, 866, 867, 868, 869, 851, 852, 853, 854, 855, 856, 857, 858, 859}; if ((ddu_id >= FEDNumbering::MINCSCDDUFEDID) && (ddu_id <= FEDNumbering::MAXCSCDDUFEDID)) { for (int i = 0; i < 36; i++) { if (ddu_id == postLS1_map[i]) { rui = i + 1; return rui; } } } else { rui = ddu_id & 0xFF; } return rui; } } // namespace cscdqm