Belle II Software development
ARICHDatabaseTools.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <algorithm>
11#include <sstream>
12
13#include <array>
14#include <cctype>
15#include <cstdint>
16#include <string>
17#include <vector>
18
19namespace Belle2 {
24 namespace ARICHTools {
25
30 class ModuleID_t {
31 public:
32 // range definitions
36 static constexpr auto m_gValidSectors =
37 std::array<uint8_t, 4>( {{'A', 'B', 'C', 'D'}});
38
42 static constexpr auto m_gMaxChannel = int8_t {36};
43
49 static constexpr auto isValidChannel(const int channel) noexcept -> bool
50 {
51 return (channel >= 0) && (channel <= m_gMaxChannel);
52 }
53
59 static auto isValidSector(const uint8_t sector) noexcept -> bool
60 {
61 return std::find(m_gValidSectors.begin(), m_gValidSectors.end(), sector) !=
62 m_gValidSectors.end();
63 }
64
65 public:
73 ModuleID_t(const int8_t sector = '0', const int channel = 0) noexcept
74 : m_ID((sector << m_gMemberSize) | channel) {}
75
81 explicit ModuleID_t(const uint16_t id) noexcept : m_ID(id) {}
82
87 inline auto isValidID() const noexcept -> bool
88 {
89 return ModuleID_t::isValidSector(this->getSector()) &&
91 }
92
98 inline auto getSector() const noexcept -> int8_t
99 {
100 return ((m_ID >> m_gMemberSize) & m_gMemberMask);
101 }
102
108 inline auto getChannel() const noexcept -> int8_t
109 {
110 return (m_ID & m_gMemberMask);
111 }
112
119 inline auto getNumbering() const noexcept -> int
120 {
121 return (this->getSector() - m_gValidSectors.front()) * m_gMaxChannel +
122 this->getChannel();
123 }
124
130 friend inline auto operator<<(std::ostream& rStream, const ModuleID_t id)
131 -> std::ostream&
132 {
133 rStream << id.getSector() << static_cast<int>(id.getChannel());
134 return rStream;
135 }
136
141 inline auto operator==(const ModuleID_t& rOther) const noexcept -> bool
142 {
143 return m_ID == rOther.m_ID;
144 }
145
150 inline auto operator!=(const ModuleID_t& rOther) const noexcept -> bool
151 {
152 return m_ID != rOther.m_ID;
153 }
154
159 inline auto operator<(const ModuleID_t& rOther) const noexcept -> bool
160 {
161 return m_ID < rOther.m_ID;
162 }
163
168 inline auto operator<=(const ModuleID_t& rOther) const noexcept -> bool
169 {
170 return m_ID <= rOther.m_ID;
171 }
172
177 inline auto operator>(const ModuleID_t& rOther) const noexcept -> bool
178 {
179 return m_ID > rOther.m_ID;
180 }
181
186 inline auto operator>=(const ModuleID_t& rOther) const noexcept -> bool
187 {
188 return m_ID >= rOther.m_ID;
189 }
190
195 inline auto operator++() noexcept -> ModuleID_t&
196 {
197 m_ID = this->getChannel() >= m_gMaxChannel
198 ? (((this->getSector() + 1) << m_gMemberSize) | 1)
199 : m_ID + 1;
200 return *this;
201 }
202
207 inline auto operator++(int)noexcept -> ModuleID_t
208 {
209 auto tmp = ModuleID_t(m_ID);
210 this->operator++();
211 return tmp;
212 }
213
214 private:
218 static constexpr auto m_gMemberSize = sizeof(int8_t) * 8;
222 static constexpr auto m_gMemberMask = 0xff;
223
227 uint16_t m_ID;
228 };
229 constexpr std::array<uint8_t, 4> ModuleID_t::m_gValidSectors;
230
231 namespace PrivateHelperClasses {
232// helper classes for the defined conversions
233
237 template <typename Desired_t> struct TokenCast;
238
242 template <> struct TokenCast<int> {
248 inline auto isValidChar(const unsigned char character) const noexcept
249 -> bool
250 {
251 return std::isdigit(character);
252 }
253
262 inline auto operator()(const std::string& rToken) const -> int
263 {
264 return std::stoi(rToken);
265 }
266 };
267
274 template <> struct TokenCast<double> {
280 inline auto isValidChar(const unsigned char character) const noexcept
281 -> bool
282 {
283 return std::isdigit(character) || (static_cast<unsigned char>('.') == character);
284 }
285
294 inline auto operator()(const std::string& rToken) const -> double
295 {
296 return std::stod(rToken);
297 }
298 };
299
303 template <> struct TokenCast<ModuleID_t> {
309 inline auto isValidChar(const unsigned char character) const noexcept
310 -> bool
311 {
312 return std::isdigit(character) || ModuleID_t::isValidSector(character);
313 }
314
323 inline auto operator()(const std::string& rToken) const -> ModuleID_t
324 {
325 const auto begin =
326 std::find_if(rToken.begin(), rToken.end(),
327 [](const char c) { return !std::isspace(c); });
328 const auto end = std::find_if(begin, rToken.end(),
329 [](const char c) { return std::isspace(c); });
330
331 if ((begin + 1 == end) || !std::all_of(begin, end, [this](const char c) {
332 return this->isValidChar(c);
333 }))
334 throw std::invalid_argument("Invalid argiment for module cast, got: '" +
335 rToken + "'!");
336
337 const auto chID = std::stoi(std::string(begin + 1, end));
339 return ModuleID_t(*begin, chID);
340
341 throw std::out_of_range("Module ID out of range. got: '" + rToken + "' !");
342 }
343 };
344 } // end namespace PrivateHelperClasses
345
352 public:
356 static const std::string m_gRangeOperator;
357
358 public:
370 template <typename T>
371 static inline auto convert(const std::string& rLine, const char delim = ' ')
372 -> std::vector<T>
373 {
374 const auto cast = PrivateHelperClasses::TokenCast<T>();
375 // check if line only contains white space, numbers and delimiter char.
376 if (!std::all_of(rLine.begin(), rLine.end(),
377 [&cast, delim](const unsigned char c) {
378 return std::isdigit(c) || std::isspace(c) ||
379 (c == delim) || cast.isValidChar(c);
380 }))
381 throw std::runtime_error("Detected invalid character in '" + rLine +
382 "'!");
383
384 auto iss = std::istringstream(rLine);
385 auto retval = std::vector<T>();
386 auto token = std::string();
387
388 // convert string to number and add it to vector...
389 while (std::getline(iss, token, delim))
390 try {
391 retval.emplace_back(cast(token));
392 } catch (const std::invalid_argument& rErr) {
393 throw std::runtime_error("Invalid token, got:'" + token + "'! " +
394 rErr.what());
395 } catch (const std::out_of_range& rErr) {
396 // if the values exceeds the requested type
397 throw std::runtime_error("Conversion out of range, got: '" + token +
398 "'! " + rErr.what());
399 }
400
401 return retval;
402 }
403
414 template <typename T>
415 static inline auto parse(const std::string& rLine, const char delim = ' ')
416 -> std::string
417 {
418 auto out = std::stringstream();
419 auto iss = std::istringstream(rLine);
420 auto token = std::string();
421
422 if (!std::getline(iss, token, delim))
423 return std::string();
424
425 if (std::search(token.begin(), token.end(), m_gRangeOperator.begin(),
426 m_gRangeOperator.end()) != token.end()) {
427 StringToVector::expand<T>(out, delim, token);
428 } else {
429 out << token;
430 }
431
432 // convert string to number and add it to vector...
433 while (std::getline(iss, token, delim))
434 try {
435 if (std::search(token.begin(), token.end(), m_gRangeOperator.begin(),
436 m_gRangeOperator.end()) != token.end()) {
437 out << ',';
438 StringToVector::expand<T>(out, delim, token);
439 } else {
440 out << delim << token;
441 }
442 } catch (const std::invalid_argument& rErr) {
443 throw std::runtime_error("Invalid token, got:'" + token + "'! " +
444 rErr.what());
445 } catch (const std::out_of_range& rErr) {
446 // if the values exceeds the requested type
447 throw std::runtime_error("Conversion out of range, got: '" + token +
448 "'! " + rErr.what());
449 }
450 return out.str();
451 }
452
453 private:
463 template <typename T>
464 static inline auto expand(std::ostream& rStream, const char delim,
465 const std::string& rToken) -> std::ostream&
466 {
467 auto itPos = std::search(rToken.begin(), rToken.end(),
468 m_gRangeOperator.begin(), m_gRangeOperator.end());
469 const auto cast = PrivateHelperClasses::TokenCast<T>();
470 auto lhs = cast(std::string(rToken.begin(), itPos));
471 std::advance(itPos, m_gRangeOperator.size());
472 auto rhs = cast(std::string(itPos, rToken.end()));
473
474 if (lhs >= rhs)
475 throw std::runtime_error(
476 "Invalid expansion! lhs ist greater then rhs, got: '" + rToken +
477 "'!");
478
479 rStream << lhs;
480 for (++lhs; lhs <= rhs; ++lhs)
481 rStream << delim << lhs;
482 return rStream;
483 }
484 };
485 const std::string StringToVector::m_gRangeOperator("~");
486
496 auto getDeadCutList(const char chipID, const std::string& line)
497 -> std::vector<int>
498 {
499 auto ids = StringToVector::convert<int>(line, ','); // can throw
500 for (auto& rID : ids)
501 rID = ModuleID_t(chipID, rID).getNumbering();
502
503 return ids;
504 }
505
517 std::string& remove_nondigit(std::string& s)
518 {
519 // changed to unsigned char see documention of std::isdigit in <cctype>
520 s.erase(remove_if(s.begin(), s.end(),
521 [](const unsigned char& c) { return !std::isdigit(c); }),
522 s.end());
523 return s;
524 }
525
533 std::string& remove_chars_if_not(std::string& s, const std::string& allowed)
534 {
535 s.erase(remove_if(s.begin(), s.end(),
536 [&allowed](const char& c) {
537 return allowed.find(c) == std::string::npos;
538 }),
539 s.end());
540 return s;
541 }
542
543 } // end namepace ARICHTools
545} // end namepace Belle2
The ModuleID_t class is a intermediate object generated to contain configurations in a sorted fashion...
static constexpr auto isValidChannel(const int channel) noexcept -> bool
isValidChannel defines the range of valid channels.
auto getSector() const noexcept -> int8_t
getSector returns the definded sectors.
ModuleID_t(const int8_t sector='0', const int channel=0) noexcept
ModuleID_t is the default ctor that construct an id out of a sector id and channel number.
ModuleID_t(const uint16_t id) noexcept
ModuleID_t used to construct from a given integer that has a valid module ID.
auto operator<=(const ModuleID_t &rOther) const noexcept -> bool
comparison operator<=
auto operator>=(const ModuleID_t &rOther) const noexcept -> bool
comparison operator>=
auto isValidID() const noexcept -> bool
isValidID check is constructed id is valid
static constexpr auto m_gMemberSize
m_gMemberSize size of each sub ids
uint16_t m_ID
m_ID contains the unique sector and channel ids.
static auto isValidSector(const uint8_t sector) noexcept -> bool
isValidSector checks whether a given sector is valid.
auto operator==(const ModuleID_t &rOther) const noexcept -> bool
comparison operator==
static constexpr auto m_gMaxChannel
m_gMaxChannel number of maximum channel starting from 0
auto operator!=(const ModuleID_t &rOther) const noexcept -> bool
comparison operator!=
auto operator++() noexcept -> ModuleID_t &
precrement operator ++X
auto getChannel() const noexcept -> int8_t
getChannel return the defined channel
static constexpr auto m_gMemberMask
m_gMemberMask is a mask to get the desired sub id info.
auto operator>(const ModuleID_t &rOther) const noexcept -> bool
comparison operator>
static constexpr auto m_gValidSectors
m_gValidSectors is a array containing allowed sector ids
auto operator++(int) noexcept -> ModuleID_t
postcrement operator X++
friend auto operator<<(std::ostream &rStream, const ModuleID_t id) -> std::ostream &
operator << to print the id using any std::ostream implementation...
auto getNumbering() const noexcept -> int
getNumbering returns the channel number Ax = 1+x; Bx = 36 + x; Cx = 72 + x; Dx = 108 + x; Note: an in...
auto operator<(const ModuleID_t &rOther) const noexcept -> bool
comparison operator<
The StringToVector class converts a given string to the std::vector<T>.
static auto convert(const std::string &rLine, const char delim=' ') -> std::vector< T >
convert<T> converts the given string in to a std::vector<T> elements seperated by the given delimiter
static const std::string m_gRangeOperator
m_gRangeOperator is a std::wstring containing the range symbold
static auto expand(std::ostream &rStream, const char delim, const std::string &rToken) -> std::ostream &
expand<T> applies the given range and fills the given std::ostream with each element in range seperat...
static auto parse(const std::string &rLine, const char delim=' ') -> std::string
parse<T> expands the given string and evaluats defined operators.
Abstract base class for different kinds of events.
auto isValidChar(const unsigned char character) const noexcept -> bool
isValidChar defines characters that are allowed for the convertion
auto operator()(const std::string &rToken) const -> ModuleID_t
operator () converts given token to an integer.
auto operator()(const std::string &rToken) const -> double
operator () converts given token to an integer.
auto isValidChar(const unsigned char character) const noexcept -> bool
isValidChar defines characters that are allowed for the convertion
auto operator()(const std::string &rToken) const -> int
operator () converts given token to an integer.
auto isValidChar(const unsigned char character) const noexcept -> bool
isValidChar defines characters that are allowed for the convertion