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