Belle II Software  release-05-01-25
PXDIgnoredPixelsMap.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Giulia Casarosa, Eugenio Paoloni, *
7  * Peter Kvasnicka, Tadeas Bilka *
8  * *
9  * This software is provided "as is" without any warranty. *
10  **************************************************************************/
11 
12 #include <pxd/online/PXDIgnoredPixelsMap.h>
13 #include <boost/property_tree/xml_parser.hpp>
14 #include <framework/logging/Logger.h>
15 #include <framework/utilities/FileSystem.h>
16 #include <vxd/geometry/GeoCache.h>
17 
18 using namespace Belle2;
19 using namespace std;
20 using boost::property_tree::ptree;
21 
22 
23 PXDIgnoredPixelsMap::PXDIgnoredPixelsMap(const string& xmlFilename):
24  m_Map(0), m_MapSingles(0), m_lastSensorID(0), m_lastSensorVCells(0)
25 {
26  // If the xmlFilename is empty, the user apparently doesn't want the map.
27  // So keep low-profile, don't bother.
28  if (xmlFilename == "") {
29  B2DEBUG(10, "No xml list of ignored pixels specified.");
30  return;
31  }
32  // Create an empty property tree object
33 
34  ptree propertyTree;
35 
36  // Load the XML file into the property tree. If reading fails
37  // (cannot open file, parse error), an exception is thrown.
38  string xmlFullPath = FileSystem::findFile(xmlFilename);
39 
40  if (! FileSystem::fileExists(xmlFullPath)) {
41  B2WARNING("The xml filename: " << xmlFilename << endl <<
42  "resolved to: " << xmlFullPath << endl <<
43  "by FileSystem::findFile does not exist." << endl <<
44  "PXD ignored pixels map cannot be initialized." << endl
45  );
46  return;
47  }
48 
49  try {
50  read_xml(xmlFullPath, propertyTree);
51  } catch (std::exception const& ex) {
52  B2WARNING("STD excpetion raised during xml parsing " << ex.what() << endl <<
53  "PXD ignored pixels map cannot be initialized." << endl);
54  return;
55  } catch (...) {
56  B2WARNING("Unknown excpetion raised during xml parsing "
57  "PXD ignored pixels map cannot be initialized." << endl);
58  return;
59  }
60 
61  try {
62  // traverse the xml tree: navigate through the daughters of <PXD>
63  VxdID sensorID;
64  for (ptree::value_type const& layer : propertyTree.get_child("PXD"))
65  if (layer.first == "layer") {
66  sensorID.setLayerNumber(static_cast<unsigned short>(layer.second.get<int>("<xmlattr>.n")));
67  for (ptree::value_type const& ladder : layer.second)
68  if (ladder.first == "ladder") {
69  sensorID.setLadderNumber(static_cast<unsigned short>(ladder.second.get<int>("<xmlattr>.n")));
70  for (ptree::value_type const& sensor : ladder.second)
71  if (sensor.first == "sensor") {
72  sensorID.setSensorNumber(static_cast<unsigned short>(sensor.second.get<int>("<xmlattr>.n")));
75  const VXD::SensorInfoBase& info = VXD::GeoCache::getInstance().get(sensorID);
76  for (ptree::value_type const& tag : sensor.second) {
77  if (tag.first == "pixels") {
78  auto limits = tag.second;
79  // All possible attributes, default = -1 (att not present)
80  short uStart = limits.get<short>("<xmlattr>.uStart", -1);
81  short uEnd = limits.get<short>("<xmlattr>.uEnd", -1);
82  short vStart = limits.get<short>("<xmlattr>.vStart", -1);
83  short vEnd = limits.get<short>("<xmlattr>.vEnd", -1);
84 
85  // Fill remaining range parameters
86  if (uStart != -1 && vStart != -1 && uEnd == -1 && vEnd == -1) {
87  // mask one pixel
88  uEnd = uStart;
89  vEnd = vStart;
90  } else if (uStart != -1 && vStart == -1 && uEnd == -1 && vEnd == -1) {
91  // mask column u ... all v rows
92  uEnd = uStart;
93  vStart = 0;
94  vEnd = info.getVCells() - 1;
95  } else if (uStart == -1 && vStart != -1 && uEnd == -1 && vEnd == -1) {
96  // mask row v ... all u columns
97  vEnd = vStart;
98  uStart = 0;
99  uEnd = info.getUCells() - 1;
100  } else if (uStart != -1 && vStart == -1 && uEnd != -1 && vEnd == -1) {
101  // columns from ... to ... (all rows there)
102  vStart = 0;
103  vEnd = info.getVCells() - 1;
104  } else if (uStart == -1 && vStart != -1 && uEnd == -1 && vEnd != -1) {
105  // rows from ... to ... (all columns there)
106  uStart = 0;
107  uEnd = info.getUCells() - 1;
108  } else if (uStart != -1 && vStart != -1 && uEnd != -1 && vEnd != -1) {
109  // already ok, rectangular area
110  } else {
111  // do not accept other combinations
112  continue;
113  }
114  // ensure positive and meaningfull values
115  unsigned short uS(uStart);
116  unsigned short vS(vStart);
117  unsigned short uE(uEnd);
118  unsigned short vE(vEnd);
119  if (uE >= info.getUCells()) uE = info.getUCells() - 1;
120  if (vE >= info.getVCells()) vE = info.getVCells() - 1;
121  if (vS > vE) vS = vE;
122  if (uS > uE) uS = uE;
123  // area of the masked range
124  unsigned int area = (uE - uS + 1) * (vE - vS + 1);
125  if (area == 1) {
126  // Single pixel masking:
127  // We store pixels by unique id in hash table
128  unsigned int uid = uStart * info.getVCells() + vStart;
129  // uid will be used to generate hash in unordered_set for quick access
130  singles.insert(uid);
131  } else {
132  // lambda function to decide if (u,v) is inside this range
134  [ = ](unsigned int u, unsigned int v) -> bool
135  { return (uS <= u && u <= uE && vS <= v && v <= vE); };
136  // area is used to sort ranges from largest to smallest
137  ranges.insert(std::make_pair(area, range_mask));
138  }
139  }
140  }
141  m_Map.insert(std::pair<unsigned short, PXDIgnoredPixelsMap::IgnoredPixelsRangeSet>(sensorID.getID(), ranges));
142  m_MapSingles.insert(std::pair<unsigned short, PXDIgnoredPixelsMap::IgnoredSinglePixelsSet>(sensorID.getID(), singles));
143  } // if sensor
144  } // if ladder
145  } // if sensor
146  } catch (...) {
147  B2WARNING("Unknown exception raised during map initialization! "
148  "PXD ignored pixels map may be corrupted." << endl);
149  return;
150  }
151 }
152 
153 const std::set<PXDIgnoredPixelsMap::map_pixel> PXDIgnoredPixelsMap::getIgnoredPixels(VxdID id)
154 {
155  // Merely for testing...
156  // This function is quite ineffective, but it is not supposed to be run often
157  // Also, it currently returns copy of the (possibly very big) set of masked pixels
158  std::set<PXDIgnoredPixelsMap::map_pixel> pixels;
160 
161  // This is quite slow solution but it merges duplicate maskings in the set
162  for (int pixelU = 0; pixelU < info.getUCells(); pixelU++) {
163  for (int pixelV = 0; pixelV < info.getVCells(); pixelV++) {
164  PXDIgnoredPixelsMap::map_pixel px(pixelU, pixelV);
165  if (!pixelOK(id, px))
166  pixels.insert(px);
167  }
168  }
169  return pixels;
170 }
171 
173 {
174  // If sensor id changed from last query, swich to temp maps
175  // of the new sensor. Otherwise clear temp maps, as there is nothing to mask
176  if (id != m_lastSensorID) {
177  m_lastSensorID = id;
179  auto mapIter = m_Map.find(id);
180  auto mapIterSingles = m_MapSingles.find(id);
181 
182  if (mapIter != m_Map.end())
183  m_lastIgnored = mapIter->second;
184  else
185  m_lastIgnored.clear();
186 
187  if (mapIterSingles != m_MapSingles.end())
188  m_lastIgnoredSingles = mapIterSingles->second;
189  else
190  m_lastIgnoredSingles.clear();
191 
192  if (mapIter == m_Map.end() && mapIterSingles == m_MapSingles.end()) {
193  // Sensor has no masked ranges or single pixels in the maps => pixel ok
194  return true;
195  }
196  }
197 
198  const unsigned int u = pixel.first;
199  const unsigned int v = pixel.second;
200 
201  // loop over masked ranges for the sensor
202  // (iter over multimap ordered by masked area)
203  for (auto iter = m_lastIgnored.begin(); iter != m_lastIgnored.end(); ++iter) {
204  // call the lambda function of masked range to check if pixel is inside
205  if (iter->second(u, v))
206  return false;
207  }
208  // Look if this is a single masked pixel
209  // (lookup in hash table)
211  return false;
212 
213  // Pixel not found in the mask => pixel OK
214  return true;
215 }
216 
217 
218 
219 
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::PXDIgnoredPixelsMap::PXDIgnoredPixelsMap
PXDIgnoredPixelsMap()=delete
No default constructor.
Belle2::VXD::GeoCache::get
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:141
Belle2::PXDIgnoredPixelsMap::pixel_range_test_prototype
std::function< bool(unsigned short, unsigned short) > pixel_range_test_prototype
Prototype for lambda function used to check if a pixel is in masked range.
Definition: PXDIgnoredPixelsMap.h:57
Belle2::VxdID::setLayerNumber
void setLayerNumber(baseType layer)
Set the layer id.
Definition: VxdID.h:117
Belle2::VxdID::getID
baseType getID() const
Get the unique id.
Definition: VxdID.h:104
Belle2::VXD::SensorInfoBase
Base class to provide Sensor Information for PXD and SVD.
Definition: SensorInfoBase.h:40
Belle2::PXDIgnoredPixelsMap::IgnoredPixelsRangeSet
std::multimap< unsigned int, pixel_range_test_prototype, std::greater< unsigned int > > IgnoredPixelsRangeSet
Structure to hold set of masked pixel ranges ordered from largest to smallest by their area (unsigned...
Definition: PXDIgnoredPixelsMap.h:59
Belle2::PXDIgnoredPixelsMap::m_lastIgnored
IgnoredPixelsRangeSet m_lastIgnored
Set of ignored pixel ranges for the most currently queried sensor.
Definition: PXDIgnoredPixelsMap.h:93
Belle2::PXDIgnoredPixelsMap::m_Map
std::unordered_map< unsigned short, IgnoredPixelsRangeSet > m_Map
Structure holding sets of ignored pixel ranges for all sensors by sensor id (unsigned short).
Definition: PXDIgnoredPixelsMap.h:88
Belle2::PXDIgnoredPixelsMap::m_lastIgnoredSingles
IgnoredSinglePixelsSet m_lastIgnoredSingles
Set of ignored single pixels for the most currently queried sensor.
Definition: PXDIgnoredPixelsMap.h:95
Belle2::VXD::GeoCache::getInstance
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:215
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::VXD::SensorInfoBase::getVCells
int getVCells() const
Return number of pixel/strips in v direction.
Definition: SensorInfoBase.h:225
Belle2::PXDIgnoredPixelsMap::m_lastSensorVCells
unsigned short m_lastSensorVCells
The most currently queried sensor number of V pixels (for quick pixel uid evaluation)
Definition: PXDIgnoredPixelsMap.h:100
Belle2::VxdID::setSensorNumber
void setSensorNumber(baseType sensor)
Set the sensor id.
Definition: VxdID.h:121
Belle2::PXDIgnoredPixelsMap::m_MapSingles
std::unordered_map< unsigned short, IgnoredSinglePixelsSet > m_MapSingles
Structure holding sets of ingored single pixels for all sensors by sensor id (unsigned short).
Definition: PXDIgnoredPixelsMap.h:90
Belle2::PXDIgnoredPixelsMap::getIgnoredPixels
const std::set< map_pixel > getIgnoredPixels(VxdID id)
Get the set of ignored pixels for a sensor.
Definition: PXDIgnoredPixelsMap.cc:153
Belle2::PXDIgnoredPixelsMap::pixelOK
bool pixelOK(VxdID id, map_pixel pixel)
Check whether a pixel on a given sensor is OK or not.
Definition: PXDIgnoredPixelsMap.cc:172
Belle2::FileSystem::fileExists
static bool fileExists(const std::string &filename)
Check if the file with given filename exists.
Definition: FileSystem.cc:33
Belle2::PXDIgnoredPixelsMap::IgnoredSinglePixelsSet
std::unordered_set< unsigned int > IgnoredSinglePixelsSet
Structure to hold set of masked single pixels indexed by their unique id (unsigned int),...
Definition: PXDIgnoredPixelsMap.h:61
Belle2::PXDIgnoredPixelsMap::m_lastSensorID
VxdID m_lastSensorID
The most currently queried sensor number.
Definition: PXDIgnoredPixelsMap.h:98
Belle2::PXDIgnoredPixelsMap::map_pixel
std::pair< unsigned short, unsigned short > map_pixel
Simple structure for a pixel, u = map_pixel.first, v = map_pixel.second.
Definition: PXDIgnoredPixelsMap.h:55
Belle2::VxdID::setLadderNumber
void setLadderNumber(baseType ladder)
Set the ladder id.
Definition: VxdID.h:119
Belle2::FileSystem::findFile
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
Definition: FileSystem.cc:147