Belle II Software  release-08-01-10
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 
19 namespace 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 
54  static auto isValidSector(const uint8_t sector) noexcept -> bool
55  {
56  return std::find(m_gValidSectors.begin(), m_gValidSectors.end(), sector) !=
57  m_gValidSectors.end();
58  }
59 
60  public:
68  ModuleID_t(const int8_t sector = '0', const int channel = 0) noexcept
69  : m_ID((sector << m_gMemberSize) | channel) {}
70 
76  explicit ModuleID_t(const uint16_t id) noexcept : m_ID(id) {}
77 
82  inline auto isValidID() const noexcept -> bool
83  {
84  return ModuleID_t::isValidSector(this->getSector()) &&
86  }
87 
93  inline auto getSector() const noexcept -> int8_t
94  {
95  return ((m_ID >> m_gMemberSize) & m_gMemberMask);
96  }
97 
103  inline auto getChannel() const noexcept -> int8_t
104  {
105  return (m_ID & m_gMemberMask);
106  }
107 
114  inline auto getNumbering() const noexcept -> int
115  {
116  return (this->getSector() - m_gValidSectors.front()) * m_gMaxChannel +
117  this->getChannel();
118  }
119 
125  friend inline auto operator<<(std::ostream& rStream, const ModuleID_t id)
126  -> std::ostream&
127  {
128  rStream << id.getSector() << static_cast<int>(id.getChannel());
129  return rStream;
130  }
131 
136  inline auto operator==(const ModuleID_t& rOther) const noexcept -> bool
137  {
138  return m_ID == rOther.m_ID;
139  }
140 
145  inline auto operator!=(const ModuleID_t& rOther) const noexcept -> bool
146  {
147  return m_ID != rOther.m_ID;
148  }
149 
154  inline auto operator<(const ModuleID_t& rOther) const noexcept -> bool
155  {
156  return m_ID < rOther.m_ID;
157  }
158 
163  inline auto operator<=(const ModuleID_t& rOther) const noexcept -> bool
164  {
165  return m_ID <= rOther.m_ID;
166  }
167 
172  inline auto operator>(const ModuleID_t& rOther) const noexcept -> bool
173  {
174  return m_ID > rOther.m_ID;
175  }
176 
181  inline auto operator>=(const ModuleID_t& rOther) const noexcept -> bool
182  {
183  return m_ID >= rOther.m_ID;
184  }
185 
190  inline auto operator++() noexcept -> ModuleID_t&
191  {
192  m_ID = this->getChannel() >= m_gMaxChannel
193  ? (((this->getSector() + 1) << m_gMemberSize) | 1)
194  : m_ID + 1;
195  return *this;
196  }
197 
202  inline auto operator++(int)noexcept -> ModuleID_t
203  {
204  auto tmp = ModuleID_t(m_ID);
205  this->operator++();
206  return tmp;
207  }
208 
209  private:
213  static constexpr auto m_gMemberSize = sizeof(int8_t) * 8;
217  static constexpr auto m_gMemberMask = 0xff;
218 
222  uint16_t m_ID;
223  };
224  constexpr std::array<uint8_t, 4> ModuleID_t::m_gValidSectors;
225 
226  namespace PrivateHelperClasses {
227 // helper classes for the defined conversions
228 
232  template <typename Desired_t> struct TokenCast;
233 
237  template <> struct TokenCast<int> {
243  inline auto isValidChar(const unsigned char character) const noexcept
244  -> bool
245  {
246  return std::isdigit(character);
247  }
248 
257  inline auto operator()(const std::string& rToken) const -> int
258  {
259  return std::stoi(rToken);
260  }
261  };
262 
269  template <> struct TokenCast<double> {
275  inline auto isValidChar(const unsigned char character) const noexcept
276  -> bool
277  {
278  return std::isdigit(character) || (static_cast<unsigned char>('.') == character);
279  }
280 
289  inline auto operator()(const std::string& rToken) const -> double
290  {
291  return std::stod(rToken);
292  }
293  };
294 
298  template <> struct TokenCast<ModuleID_t> {
304  inline auto isValidChar(const unsigned char character) const noexcept
305  -> bool
306  {
307  return std::isdigit(character) || ModuleID_t::isValidSector(character);
308  }
309 
318  inline auto operator()(const std::string& rToken) const -> ModuleID_t
319  {
320  const auto begin =
321  std::find_if(rToken.begin(), rToken.end(),
322  [](const char c) { return !std::isspace(c); });
323  const auto end = std::find_if(begin, rToken.end(),
324  [](const char c) { return std::isspace(c); });
325 
326  if ((begin + 1 == end) || !std::all_of(begin, end, [this](const char c) {
327  return this->isValidChar(c);
328  }))
329  throw std::invalid_argument("Invalid argiment for module cast, got: '" +
330  rToken + "'!");
331 
332  const auto chID = std::stoi(std::string(begin + 1, end));
333  if (ModuleID_t::isValidSector(*begin) && ModuleID_t::isValidChannel(chID))
334  return ModuleID_t(*begin, chID);
335 
336  throw std::out_of_range("Module ID out of range. got: '" + rToken + "' !");
337  }
338  };
339  } // end namespace PrivateHelperClasses
340 
347  public:
351  static const std::string m_gRangeOperator;
352 
353  public:
365  template <typename T>
366  static inline auto convert(const std::string& rLine, const char delim = ' ')
367  -> std::vector<T>
368  {
369  const auto cast = PrivateHelperClasses::TokenCast<T>();
370  // check if line only contains white space, numbers and delimiter char.
371  if (!std::all_of(rLine.begin(), rLine.end(),
372  [&cast, delim](const unsigned char c) {
373  return std::isdigit(c) || std::isspace(c) ||
374  (c == delim) || cast.isValidChar(c);
375  }))
376  throw std::runtime_error("Detected invalid character in '" + rLine +
377  "'!");
378 
379  auto iss = std::istringstream(rLine);
380  auto retval = std::vector<T>();
381  auto token = std::string();
382 
383  // convert string to number and add it to vector...
384  while (std::getline(iss, token, delim))
385  try {
386  retval.emplace_back(cast(token));
387  } catch (const std::invalid_argument& rErr) {
388  throw std::runtime_error("Invalid token, got:'" + token + "'! " +
389  rErr.what());
390  } catch (const std::out_of_range& rErr) {
391  // if the values exceeds the requested type
392  throw std::runtime_error("Conversion out of range, got: '" + token +
393  "'! " + rErr.what());
394  }
395 
396  return retval;
397  }
398 
409  template <typename T>
410  static inline auto parse(const std::string& rLine, const char delim = ' ')
411  -> std::string
412  {
413  auto out = std::stringstream();
414  auto iss = std::istringstream(rLine);
415  auto token = std::string();
416 
417  if (!std::getline(iss, token, delim))
418  return std::string();
419 
420  if (std::search(token.begin(), token.end(), m_gRangeOperator.begin(),
421  m_gRangeOperator.end()) != token.end()) {
422  StringToVector::expand<T>(out, delim, token);
423  } else {
424  out << token;
425  }
426 
427  // convert string to number and add it to vector...
428  while (std::getline(iss, token, delim))
429  try {
430  if (std::search(token.begin(), token.end(), m_gRangeOperator.begin(),
431  m_gRangeOperator.end()) != token.end()) {
432  out << ',';
433  StringToVector::expand<T>(out, delim, token);
434  } else {
435  out << delim << token;
436  }
437  } catch (const std::invalid_argument& rErr) {
438  throw std::runtime_error("Invalid token, got:'" + token + "'! " +
439  rErr.what());
440  } catch (const std::out_of_range& rErr) {
441  // if the values exceeds the requested type
442  throw std::runtime_error("Conversion out of range, got: '" + token +
443  "'! " + rErr.what());
444  }
445  return out.str();
446  }
447 
448  private:
458  template <typename T>
459  static inline auto expand(std::ostream& rStream, const char delim,
460  const std::string& rToken) -> std::ostream&
461  {
462  auto itPos = std::search(rToken.begin(), rToken.end(),
463  m_gRangeOperator.begin(), m_gRangeOperator.end());
464  const auto cast = PrivateHelperClasses::TokenCast<T>();
465  auto lhs = cast(std::string(rToken.begin(), itPos));
466  std::advance(itPos, m_gRangeOperator.size());
467  auto rhs = cast(std::string(itPos, rToken.end()));
468 
469  if (lhs >= rhs)
470  throw std::runtime_error(
471  "Invalid expansion! lhs ist greater then rhs, got: '" + rToken +
472  "'!");
473 
474  rStream << lhs;
475  for (++lhs; lhs <= rhs; ++lhs)
476  rStream << delim << lhs;
477  return rStream;
478  }
479  };
480  const std::string StringToVector::m_gRangeOperator("~");
481 
491  auto getDeadCutList(const char chipID, const std::string& line)
492  -> std::vector<int>
493  {
494  auto ids = StringToVector::convert<int>(line, ','); // can throw
495  for (auto& rID : ids)
496  rID = ModuleID_t(chipID, rID).getNumbering();
497 
498  return ids;
499  }
500 
512  std::string& remove_nondigit(std::string& s)
513  {
514  // changed to unsigned char see documention of std::isdigit in <cctype>
515  s.erase(remove_if(s.begin(), s.end(),
516  [](const unsigned char& c) { return !std::isdigit(c); }),
517  s.end());
518  return s;
519  }
520 
528  std::string& remove_chars_if_not(std::string& s, const std::string& allowed)
529  {
530  s.erase(remove_if(s.begin(), s.end(),
531  [&allowed](const char& c) {
532  return allowed.find(c) == std::string::npos;
533  }),
534  s.end());
535  return s;
536  }
537 
538  } // end namepace ARICHTools
540 } // 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.
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