Belle II Software  release-08-01-10
VxdID.cc
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 
9 #include <vxd/dataobjects/VxdID.h>
10 #include <sstream>
11 
12 namespace Belle2 {
18  namespace {
24  int getPart(std::istream& in)
25  {
26  if (!in.eof()) {
27  //Get next char, if it is a dot, ignore it and get the next one
28  int next = in.get();
29  if (next == '.') next = in.get();
30  //If it is a wildcard we return 0 as id, otherwise we put it back in the stream
31  if (next == '*' or in.eof()) {
32  return 0;
33  } else {
34  in.unget();
35  }
36  //If it is the segment separator, we assume the remaining parts to be missing, so return 0
37  if (next == '#') return 0;
38 
39  //Now get the actual value out of the stream. If this fails something is wrong and it is not
40  //a valid id
41  int value(0);
42  in >> value;
43  if (in.fail() && !in.eof()) {
44  throw std::runtime_error("Failed to parse Number");
45  }
46  return value;
47  }
48  return 0;
49  }
50  }
51 
52  VxdID::VxdID(const std::string& sensor)
53  {
54  //We parse the Id from string, so set it to 0 first
55  m_id.id = 0;
56  //create a stream from the string
57  std::istringstream in(sensor);
58  try {
59  //Get all the parts
60  m_id.parts.layer = getPart(in);
61  m_id.parts.ladder = getPart(in);
62  m_id.parts.sensor = getPart(in);
63  //Check if we also have a segment specified, if so get it
64  if (in.peek() == '#') {
65  in.get();
66  m_id.parts.segment = getPart(in);
67  }
68  } catch (std::runtime_error&) {
69  //Something went wrong parsing the parts
70  m_id.id = 0;
71  throw std::invalid_argument("Could not parse VxdID: '" + sensor + "'");
72  }
73  //There is stuff left we also throw an exception as we cannot warn the user
74  //without the logging system
75  if (!in.eof()) {
76  std::string rest;
77  //Get the remainder: get everything in the stream until the next NULL
78  //character which should only occur at the end of the string.
79  getline(in, rest, '\0');
80  throw std::invalid_argument("Trailing characters after VxdID " + std::string(*this) + ": '" + rest + "'");
81  }
82  }
83 
84  VxdID::operator std::string() const
85  {
86  std::stringstream out;
87  if (m_id.parts.layer) {
88  out << m_id.parts.layer;
89  } else {
90  out << "*";
91  }
92  if (m_id.parts.ladder || m_id.parts.sensor) {
93  out << ".";
94  if (m_id.parts.ladder) {
95  out << m_id.parts.ladder;
96  } else {
97  out << "*";
98  }
99  }
100  if (m_id.parts.sensor) {
101  out << "." << m_id.parts.sensor;
102  }
103  if (m_id.parts.segment) {
104  out << "#" << m_id.parts.segment;
105  }
106  return out.str();
107  }
108 
109  std::ostream& operator<<(std::ostream& out, const VxdID& id)
110  {
111  out << ((std::string)id);
112  return out;
113  }
114 
116 }
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
union Belle2::VxdID::@299 m_id
Union to store the ID and all components in one go.
VxdID(baseType id=0)
Constructor using the unique id.
Definition: VxdID.h:63
baseType sensor
Sensor id.
Definition: VxdID.h:128
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
Abstract base class for different kinds of events.