File indexing completed on 2024-04-06 12:02:18
0001 #ifndef CondFormats_JetMETObjects_Utilities_h
0002 #define CondFormats_JetMETObjects_Utilities_h
0003
0004 #ifdef STANDALONE
0005 #include <stdexcept>
0006 #else
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #endif
0009
0010 #include <cstdlib>
0011 #include <sstream>
0012 #include <string>
0013 #include <vector>
0014 #include <tuple>
0015 #include <cmath>
0016 #include <utility>
0017
0018 namespace std {
0019
0020 template <typename Type, unsigned N, unsigned Last>
0021 struct tuple_printer {
0022 static void print(std::ostream& out, const Type& value) {
0023 out << std::get<N>(value) << ", ";
0024 tuple_printer<Type, N + 1, Last>::print(out, value);
0025 }
0026 };
0027 template <typename Type, unsigned N>
0028 struct tuple_printer<Type, N, N> {
0029 static void print(std::ostream& out, const Type& value) { out << std::get<N>(value); }
0030 };
0031 template <typename... Types>
0032 std::ostream& operator<<(std::ostream& out, const std::tuple<Types...>& value) {
0033 out << "(";
0034 tuple_printer<std::tuple<Types...>, 0, sizeof...(Types) - 1>::print(out, value);
0035 out << ")";
0036 return out;
0037 }
0038
0039
0040 template <size_t... n>
0041 struct ct_integers_list {
0042 template <size_t m>
0043 struct push_back {
0044 typedef ct_integers_list<n..., m> type;
0045 };
0046 };
0047 template <size_t max>
0048 struct ct_iota_1 {
0049 typedef typename ct_iota_1<max - 1>::type::template push_back<max>::type type;
0050 };
0051 template <>
0052 struct ct_iota_1<0> {
0053 typedef ct_integers_list<> type;
0054 };
0055
0056
0057
0058 template <size_t... indices, typename Tuple>
0059 auto tuple_subset(const Tuple& tpl, ct_integers_list<indices...>)
0060 -> decltype(std::make_tuple(std::get<indices>(tpl)...)) {
0061 return std::make_tuple(std::get<indices>(tpl)...);
0062
0063
0064 }
0065 template <typename Head, typename... Tail>
0066 std::tuple<Tail...> tuple_tail(const std::tuple<Head, Tail...>& tpl) {
0067 return tuple_subset(tpl, typename ct_iota_1<sizeof...(Tail)>::type());
0068
0069
0070 }
0071
0072
0073 template <typename Head, typename... ndims>
0074 struct hash_specialization {
0075 typedef std::tuple<Head, ndims...> argument_type;
0076 typedef std::size_t result_type;
0077 result_type operator()(const argument_type& t) const {
0078 const uint32_t& b = reinterpret_cast<const uint32_t&>(std::get<0>(t));
0079
0080 const uint32_t& more = hash_specialization<ndims...>()(tuple_tail(t));
0081 return b ^ more;
0082 }
0083 };
0084
0085 template <>
0086 struct hash_specialization<float> {
0087 typedef std::tuple<float> argument_type;
0088 typedef std::size_t result_type;
0089 result_type operator()(const argument_type& t) const {
0090 const uint32_t& b = reinterpret_cast<const uint32_t&>(std::get<0>(t));
0091 return static_cast<result_type>(b);
0092 }
0093 };
0094
0095 template <typename Head, typename... ndims>
0096 struct hash<std::tuple<Head, ndims...>> {
0097 typedef std::tuple<Head, ndims...> argument_type;
0098 typedef std::size_t result_type;
0099 result_type operator()(const argument_type& t) const { return hash_specialization<Head, ndims...>()(t); }
0100 };
0101 template <>
0102 struct hash<std::tuple<>> {
0103 typedef std::tuple<> argument_type;
0104 typedef std::size_t result_type;
0105 result_type operator()(const argument_type& t) const { return -1; }
0106 };
0107 }
0108
0109 namespace {
0110 inline void handleError(const std::string& fClass, const std::string& fMessage) {
0111 #ifdef STANDALONE
0112 std::stringstream sserr;
0113 sserr << fClass << " ERROR: " << fMessage;
0114 throw std::runtime_error(sserr.str());
0115 #else
0116 edm::LogError(fClass) << fMessage;
0117 #endif
0118 }
0119
0120 inline float getFloat(const std::string& token) {
0121 char* endptr;
0122 float result = strtod(token.c_str(), &endptr);
0123 if (endptr == token.c_str()) {
0124 std::stringstream sserr;
0125 sserr << "can't convert token " << token << " to float value";
0126 handleError("getFloat", sserr.str());
0127 }
0128 return result;
0129 }
0130
0131 inline unsigned getUnsigned(const std::string& token) {
0132 char* endptr;
0133 unsigned result = strtoul(token.c_str(), &endptr, 0);
0134 if (endptr == token.c_str()) {
0135 std::stringstream sserr;
0136 sserr << "can't convert token " << token << " to unsigned value";
0137 handleError("getUnsigned", sserr.str());
0138 }
0139 return result;
0140 }
0141 inline long int getSigned(const std::string& token) {
0142 char* endptr;
0143 unsigned result = strtol(token.c_str(), &endptr, 0);
0144 if (endptr == token.c_str()) {
0145 std::stringstream sserr;
0146 sserr << "can't convert token " << token << " to signed value";
0147 handleError("getSigned", sserr.str());
0148 }
0149 return result;
0150 }
0151
0152 inline std::string getSection(const std::string& token) {
0153 size_t iFirst = token.find('[');
0154 size_t iLast = token.find(']');
0155 if (iFirst != std::string::npos && iLast != std::string::npos && iFirst < iLast)
0156 return std::string(token, iFirst + 1, iLast - iFirst - 1);
0157 return "";
0158 }
0159
0160 inline std::vector<std::string> getTokens(const std::string& fLine) {
0161 std::vector<std::string> tokens;
0162 std::string currentToken;
0163 for (unsigned ipos = 0; ipos < fLine.length(); ++ipos) {
0164 char c = fLine[ipos];
0165 if (c == '#')
0166 break;
0167 else if (c == ' ') {
0168 if (!currentToken.empty()) {
0169 tokens.push_back(currentToken);
0170 currentToken.clear();
0171 }
0172 } else
0173 currentToken += c;
0174 }
0175 if (!currentToken.empty())
0176 tokens.push_back(currentToken);
0177 return tokens;
0178 }
0179
0180 inline std::string getDefinitions(const std::string& token) {
0181 size_t iFirst = token.find('{');
0182 size_t iLast = token.find('}');
0183 if (iFirst != std::string::npos && iLast != std::string::npos && iFirst < iLast)
0184 return std::string(token, iFirst + 1, iLast - iFirst - 1);
0185 return "";
0186 }
0187
0188 inline float quadraticInterpolation(float fZ, const float fX[3], const float fY[3]) {
0189
0190
0191 float D[4], a[3];
0192 D[0] = fX[0] * fX[1] * (fX[0] - fX[1]) + fX[1] * fX[2] * (fX[1] - fX[2]) + fX[2] * fX[0] * (fX[2] - fX[0]);
0193 D[3] = fY[0] * (fX[1] - fX[2]) + fY[1] * (fX[2] - fX[0]) + fY[2] * (fX[0] - fX[1]);
0194 D[2] = fY[0] * (pow(fX[2], 2) - pow(fX[1], 2)) + fY[1] * (pow(fX[0], 2) - pow(fX[2], 2)) +
0195 fY[2] * (pow(fX[1], 2) - pow(fX[0], 2));
0196 D[1] = fY[0] * fX[1] * fX[2] * (fX[1] - fX[2]) + fY[1] * fX[0] * fX[2] * (fX[2] - fX[0]) +
0197 fY[2] * fX[0] * fX[1] * (fX[0] - fX[1]);
0198 if (D[0] != 0) {
0199 a[0] = D[1] / D[0];
0200 a[1] = D[2] / D[0];
0201 a[2] = D[3] / D[0];
0202 } else {
0203 a[0] = 0.0;
0204 a[1] = 0.0;
0205 a[2] = 0.0;
0206 }
0207 float r = a[0] + fZ * (a[1] + fZ * a[2]);
0208 return r;
0209 }
0210
0211
0212
0213
0214 template <typename , typename >
0215 struct join_tuples {};
0216 template <typename... LEFT, typename... RIGHT>
0217 struct join_tuples<std::tuple<LEFT...>, std::tuple<RIGHT...>> {
0218 typedef std::tuple<LEFT..., RIGHT...> type;
0219 };
0220 template <typename T, unsigned N>
0221 struct generate_tuple_type {
0222 typedef typename generate_tuple_type<T, N / 2>::type left;
0223 typedef typename generate_tuple_type<T, N / 2 + N % 2>::type right;
0224 typedef typename join_tuples<left, right>::type type;
0225 };
0226 template <typename T>
0227 struct generate_tuple_type<T, 1> {
0228 typedef std::tuple<T> type;
0229 };
0230 template <typename T>
0231 struct generate_tuple_type<T, 0> {
0232 typedef std::tuple<> type;
0233 };
0234
0235
0236
0237 template <class T>
0238 using Invoke = typename T::type;
0239
0240 template <unsigned...>
0241 struct seq {
0242 using type = seq;
0243 };
0244
0245 template <class S1, class S2>
0246 struct concat;
0247
0248 template <unsigned... I1, unsigned... I2>
0249 struct concat<seq<I1...>, seq<I2...>> : seq<I1..., (sizeof...(I1) + I2)...> {};
0250
0251 template <class S1, class S2>
0252 using Concat = Invoke<concat<S1, S2>>;
0253
0254 template <unsigned N>
0255 struct gen_seq;
0256 template <unsigned N>
0257 using GenSeq = Invoke<gen_seq<N>>;
0258
0259 template <unsigned N>
0260 struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> {};
0261
0262 template <>
0263 struct gen_seq<0> : seq<> {};
0264 template <>
0265 struct gen_seq<1> : seq<0> {};
0266
0267
0268 template <typename F, unsigned... Is>
0269 auto gen_tuple_impl(F func, seq<Is...>) -> decltype(std::make_tuple(func(Is)...)) {
0270 return std::make_tuple(func(Is)...);
0271 }
0272 template <unsigned N, typename F>
0273 auto gen_tuple(F func) -> decltype(gen_tuple_impl(func, GenSeq<N>())) {
0274 return gen_tuple_impl(func, GenSeq<N>());
0275 }
0276 }
0277 #endif