CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MeasurementTrackerEventProducer.cc
Go to the documentation of this file.
2 
6 
11 
12 #include <algorithm>
13 
15  : measurementTrackerToken_(
16  esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("measurementTracker")))),
17  switchOffPixelsIfEmpty_(iConfig.getParameter<bool>("switchOffPixelsIfEmpty")) {
18  std::vector<edm::InputTag> inactivePixelDetectorTags(
19  iConfig.getParameter<std::vector<edm::InputTag>>("inactivePixelDetectorLabels"));
20  for (auto& t : inactivePixelDetectorTags)
21  theInactivePixelDetectorLabels.push_back(consumes<DetIdCollection>(t));
22 
23  std::vector<edm::InputTag> badPixelFEDChannelCollectionTags =
24  iConfig.getParameter<std::vector<edm::InputTag>>("badPixelFEDChannelCollectionLabels");
25  if (!badPixelFEDChannelCollectionTags.empty()) {
26  for (auto& t : badPixelFEDChannelCollectionTags)
27  theBadPixelFEDChannelsLabels.push_back(consumes<PixelFEDChannelCollection>(t));
28  pixelCablingMapToken_ = esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("pixelCablingMapLabel")));
29  }
30 
31  std::vector<edm::InputTag> inactiveStripDetectorTags(
32  iConfig.getParameter<std::vector<edm::InputTag>>("inactiveStripDetectorLabels"));
33  for (auto& t : inactiveStripDetectorTags)
34  theInactiveStripDetectorLabels.push_back(consumes<DetIdCollection>(t));
35 
36  //the measurement tracking is set to skip clusters, the other option is set from outside
37  edm::InputTag skip = iConfig.getParameter<edm::InputTag>("skipClusters");
38  selfUpdateSkipClusters_ = !(skip == edm::InputTag(""));
39  LogDebug("MeasurementTracker") << "skipping clusters: " << selfUpdateSkipClusters_;
40  isPhase2_ = false;
41  useVectorHits_ = false;
42 
43  if (!iConfig.getParameter<std::string>("stripClusterProducer").empty()) {
44  theStripClusterLabel = consumes<edmNew::DetSetVector<SiStripCluster>>(
45  edm::InputTag(iConfig.getParameter<std::string>("stripClusterProducer")));
46  if (selfUpdateSkipClusters_)
47  theStripClusterMask = consumes<edm::ContainerMask<edmNew::DetSetVector<SiStripCluster>>>(
48  iConfig.getParameter<edm::InputTag>("skipClusters"));
49  }
50  if (!iConfig.getParameter<std::string>("pixelClusterProducer").empty()) {
51  thePixelClusterLabel = consumes<edmNew::DetSetVector<SiPixelCluster>>(
52  edm::InputTag(iConfig.getParameter<std::string>("pixelClusterProducer")));
53  if (selfUpdateSkipClusters_)
54  thePixelClusterMask = consumes<edm::ContainerMask<edmNew::DetSetVector<SiPixelCluster>>>(
55  iConfig.getParameter<edm::InputTag>("skipClusters"));
56  }
57  if (!iConfig.getParameter<std::string>("Phase2TrackerCluster1DProducer").empty()) {
58  thePh2OTClusterLabel = consumes<edmNew::DetSetVector<Phase2TrackerCluster1D>>(
59  edm::InputTag(iConfig.getParameter<std::string>("Phase2TrackerCluster1DProducer")));
60  isPhase2_ = true;
61  }
62  if (!(iConfig.getParameter<edm::InputTag>("vectorHits") == edm::InputTag("") ||
63  iConfig.getParameter<edm::InputTag>("vectorHitsRej") == edm::InputTag(""))) {
64  thePh2OTVectorHitsLabel = consumes<VectorHitCollection>(iConfig.getParameter<edm::InputTag>("vectorHits"));
65  thePh2OTVectorHitsRejLabel = consumes<VectorHitCollection>(iConfig.getParameter<edm::InputTag>("vectorHitsRej"));
66  isPhase2_ = true;
67  useVectorHits_ = true;
68  }
69 
70  produces<MeasurementTrackerEvent>();
71 }
72 
75 
76  desc.add<std::string>("measurementTracker", "");
77  desc.add<edm::InputTag>("skipClusters", edm::InputTag());
78  desc.add<std::string>("pixelClusterProducer", "siPixelClusters");
79  desc.add<std::string>("stripClusterProducer", "siStripClusters");
80  desc.add<std::string>("Phase2TrackerCluster1DProducer", "");
81  desc.add<edm::InputTag>("vectorHits", edm::InputTag(""));
82  desc.add<edm::InputTag>("vectorHitsRej", edm::InputTag(""));
83 
84  desc.add<std::vector<edm::InputTag>>("inactivePixelDetectorLabels",
85  std::vector<edm::InputTag>{{edm::InputTag("siPixelDigis")}})
86  ->setComment("One or more DetIdCollections of modules to mask on the fly for a given event");
87  desc.add<std::vector<edm::InputTag>>("badPixelFEDChannelCollectionLabels", std::vector<edm::InputTag>())
88  ->setComment("One or more PixelFEDChannelCollections of modules+ROCs to mask on the fly for a given event");
89  desc.add<std::string>("pixelCablingMapLabel", "");
90 
91  desc.add<std::vector<edm::InputTag>>("inactiveStripDetectorLabels",
92  std::vector<edm::InputTag>{{edm::InputTag("siStripDigis")}})
93  ->setComment("One or more DetIdCollections of modules to mask on the fly for a given event");
94 
95  desc.add<bool>("switchOffPixelsIfEmpty", true)->setComment("let's keep it like this, for cosmics");
96 
97  descriptions.add("measurementTrackerEventDefault", desc);
98 }
99 
102 
103  // create new data structures from templates
104  auto stripData = std::make_unique<StMeasurementDetSet>(measurementTracker.stripDetConditions());
105  auto pixelData = std::make_unique<PxMeasurementDetSet>(measurementTracker.pixelDetConditions());
106  auto phase2OTData = std::make_unique<Phase2OTMeasurementDetSet>(measurementTracker.phase2DetConditions());
107 
108  std::vector<bool> stripClustersToSkip;
109  std::vector<bool> pixelClustersToSkip;
110  std::vector<bool> phase2ClustersToSkip;
111  // fill them
112  updateStrips(iEvent, *stripData, stripClustersToSkip);
113  updatePixels(iEvent,
114  *pixelData,
115  pixelClustersToSkip,
116  dynamic_cast<const TrackerGeometry&>(*(measurementTracker.geomTracker())),
117  iSetup);
118  updatePhase2OT(iEvent, *phase2OTData);
119  updateStacks(iEvent, *phase2OTData);
120 
121  // put into MTE
122  // put into event
123  //
124 
125  const VectorHitCollection* phase2OTVectorHits = useVectorHits_ ? &iEvent.get(thePh2OTVectorHitsLabel) : nullptr;
126  const VectorHitCollection* phase2OTVectorHitsRej = useVectorHits_ ? &iEvent.get(thePh2OTVectorHitsRejLabel) : nullptr;
127  iEvent.put(std::make_unique<MeasurementTrackerEvent>(measurementTracker,
128  stripData.release(),
129  pixelData.release(),
130  phase2OTData.release(),
131  phase2OTVectorHits,
132  phase2OTVectorHitsRej,
133  stripClustersToSkip,
134  pixelClustersToSkip,
135  phase2ClustersToSkip));
136 }
137 
139  PxMeasurementDetSet& thePxDets,
140  std::vector<bool>& pixelClustersToSkip,
141  const TrackerGeometry& trackerGeom,
142  const edm::EventSetup& iSetup) const {
143  // start by clearinng everything
144  thePxDets.setEmpty();
145 
146  std::vector<uint32_t> rawInactiveDetIds;
147  if (!theInactivePixelDetectorLabels.empty()) {
150  if (event.getByToken(tk, detIds)) {
151  rawInactiveDetIds.insert(rawInactiveDetIds.end(), detIds->begin(), detIds->end());
152  } else {
153  static std::atomic<bool> iFailedAlready{false};
154  bool expected = false;
155  if (iFailedAlready.compare_exchange_strong(expected, true, std::memory_order_acq_rel)) {
156  edm::LogError("MissingProduct")
157  << "I fail to get the list of inactive pixel modules, because of 4.2/4.4 event content change.";
158  }
159  }
160  }
161  if (!rawInactiveDetIds.empty())
162  std::sort(rawInactiveDetIds.begin(), rawInactiveDetIds.end());
163  // mark as inactive if in rawInactiveDetIds
164  int i = 0, endDet = thePxDets.size();
165  unsigned int idp = 0;
166  for (auto id : rawInactiveDetIds) {
167  if (id == idp)
168  continue; // skip multiple id
169  idp = id;
170  i = thePxDets.find(id, i);
171  assert(i != endDet && id == thePxDets.id(i));
172  thePxDets.setActiveThisEvent(i, false);
173  }
174  }
175 
176  if (!theBadPixelFEDChannelsLabels.empty()) {
177  auto const& cablingMap = iSetup.getData(pixelCablingMapToken_);
178 
179  edm::Handle<PixelFEDChannelCollection> pixelFEDChannelCollectionHandle;
181  if (!event.getByToken(tk, pixelFEDChannelCollectionHandle))
182  continue;
183  int i = 0;
184  for (const auto& disabledChannels : *pixelFEDChannelCollectionHandle) {
186  for (const auto& ch : disabledChannels) {
187  const sipixelobjects::PixelROC *roc_first = nullptr, *roc_last = nullptr;
188  sipixelobjects::CablingPathToDetUnit path = {ch.fed, ch.link, 0};
189  // PixelFEDChannelCollection addresses the ROCs by their 'idInDetUnit' (from 0 to 15), ROCs also know their on 'idInDetUnit',
190  // however the cabling map uses a numbering [1,numberOfROCs], see sipixelobjects::PixelFEDLink::roc(unsigned int id), not necessarily sorted in the same direction.
191  // PixelFEDChannelCollection MUST be filled such that ch.roc_first (ch.roc_last) correspond to the lowest (highest) 'idInDetUnit' in the channel
192  for (path.roc = 1; path.roc <= (ch.roc_last - ch.roc_first) + 1; path.roc++) {
193  const sipixelobjects::PixelROC* roc = cablingMap.findItem(path);
194  if (roc == nullptr)
195  continue;
196  assert(roc->rawId() == disabledChannels.detId());
197  if (roc->idInDetUnit() == ch.roc_first)
198  roc_first = roc;
199  if (roc->idInDetUnit() == ch.roc_last)
200  roc_last = roc;
201  }
202  if (roc_first == nullptr || roc_last == nullptr) {
203  edm::LogError("PixelFEDChannelCollection")
204  << "Do not find either roc_first or roc_last in the cabling map.";
205  continue;
206  }
207  const PixelGeomDetUnit* theGeomDet =
208  dynamic_cast<const PixelGeomDetUnit*>(trackerGeom.idToDet(roc_first->rawId()));
209  PixelTopology const* topology = &(theGeomDet->specificTopology());
211  topology->rowsperroc() / 2, topology->colsperroc() / 2}; //corresponding to center of ROC row, col
213  LocalPoint lp1 = topology->localPosition(MeasurementPoint(global.row, global.col));
214  global = roc_last->toGlobal(sipixelobjects::LocalPixel(local));
215  LocalPoint lp2 = topology->localPosition(MeasurementPoint(global.row, global.col));
216  LocalPoint ll(std::min(lp1.x(), lp2.x()), std::min(lp1.y(), lp2.y()), std::min(lp1.z(), lp2.z()));
217  LocalPoint ur(std::max(lp1.x(), lp2.x()), std::max(lp1.y(), lp2.y()), std::max(lp1.z(), lp2.z()));
218  positions.push_back(std::make_pair(ll, ur));
219  } // loop on channels
220  if (!positions.empty()) {
221  i = thePxDets.find(disabledChannels.detId(), i);
222  assert(i != thePxDets.size() && thePxDets.id(i) == disabledChannels.detId());
223  thePxDets.addBadFEDChannelPositions(i, positions);
224  }
225  } // loop on DetId-s
226  } // loop on labels
227  } // if collection labels are populated
228 
229  // Pixel Clusters
230  if (thePixelClusterLabel.isUninitialized()) { //clusters have not been produced
232  thePxDets.setActiveThisEvent(false);
233  }
234  } else {
236  if (event.getByToken(thePixelClusterLabel, pixelClusters)) {
237  const edmNew::DetSetVector<SiPixelCluster>* pixelCollection = pixelClusters.product();
238 
239  if (switchOffPixelsIfEmpty_ && pixelCollection->empty()) {
240  thePxDets.setActiveThisEvent(false);
241  } else {
242  //std::cout <<"updatePixels "<<pixelCollection->dataSize()<<std::endl;
243  pixelClustersToSkip.resize(pixelCollection->dataSize());
244  std::fill(pixelClustersToSkip.begin(), pixelClustersToSkip.end(), false);
245 
248  //and get the collection of pixel ref to skip
249  event.getByToken(thePixelClusterMask, pixelClusterMask);
250  LogDebug("MeasurementTracker") << "getting pxl refs to skip";
251  if (pixelClusterMask.failedToGet())
252  edm::LogError("MeasurementTracker") << "not getting the pixel clusters to skip";
253  if (pixelClusterMask->refProd().id() != pixelClusters.id()) {
254  edm::LogError("ProductIdMismatch")
255  << "The pixel masking does not point to the proper collection of clusters: "
256  << pixelClusterMask->refProd().id() << "!=" << pixelClusters.id();
257  }
258  pixelClusterMask->copyMaskTo(pixelClustersToSkip);
259  }
260 
261  // FIXME: should check if lower_bound is better
262  int i = 0, endDet = thePxDets.size();
263  for (edmNew::DetSetVector<SiPixelCluster>::const_iterator it = pixelCollection->begin(),
264  ed = pixelCollection->end();
265  it != ed;
266  ++it) {
268  unsigned int id = set.id();
269  while (id != thePxDets.id(i)) {
270  ++i;
271  if (endDet == i)
272  throw "we have a problem!!!!";
273  }
274  // push cluster range in det
275  if (thePxDets.isActive(i)) {
276  thePxDets.update(i, set);
277  }
278  }
279  }
280  } else {
282  labelsForToken(thePixelClusterLabel, labels);
283  edm::LogWarning("MeasurementTrackerEventProducer")
284  << "input pixel clusters collection " << labels.module << " is not valid";
285  }
286  }
287 }
288 
290  StMeasurementDetSet& theStDets,
291  std::vector<bool>& stripClustersToSkip) const {
292  typedef edmNew::DetSet<SiStripCluster> StripDetSet;
293 
294  std::vector<uint32_t> rawInactiveDetIds;
295  getInactiveStrips(event, rawInactiveDetIds);
296 
297  // Strip Clusters
298  //first clear all of them
299  theStDets.setEmpty();
300 
302  return; //clusters have not been produced
303 
304  const int endDet = theStDets.size();
305 
306  // mark as inactive if in rawInactiveDetIds
307  int i = 0;
308  unsigned int idp = 0;
309  for (auto id : rawInactiveDetIds) {
310  if (id == idp)
311  continue; // skip multiple id
312  idp = id;
313  i = theStDets.find(id, i);
314  assert(i != endDet && id == theStDets.id(i));
315  theStDets.setActiveThisEvent(i, false);
316  }
317 
318  //========= actually load cluster =============
319  {
321  if (event.getByToken(theStripClusterLabel, clusterHandle)) {
322  const edmNew::DetSetVector<SiStripCluster>* clusterCollection = clusterHandle.product();
323 
326  //and get the collection of pixel ref to skip
327  LogDebug("MeasurementTracker") << "getting strp refs to skip";
328  event.getByToken(theStripClusterMask, stripClusterMask);
329  if (stripClusterMask.failedToGet())
330  edm::LogError("MeasurementTracker") << "not getting the strip clusters to skip";
331  if (stripClusterMask->refProd().id() != clusterHandle.id()) {
332  edm::LogError("ProductIdMismatch")
333  << "The strip masking does not point to the proper collection of clusters: "
334  << stripClusterMask->refProd().id() << "!=" << clusterHandle.id();
335  }
336  stripClusterMask->copyMaskTo(stripClustersToSkip);
337  }
338 
339  theStDets.handle() = clusterHandle;
340  int i = 0;
341  // cluster and det and in order (both) and unique so let's use set intersection
342  for (auto j = 0U; j < (*clusterCollection).size(); ++j) {
343  unsigned int id = (*clusterCollection).id(j);
344  while (id != theStDets.id(i)) { // eventually change to lower_bound
345  ++i;
346  if (endDet == i)
347  throw "we have a problem in strips!!!!";
348  }
349 
350  // push cluster range in det
351  if (theStDets.isActive(i))
352  theStDets.update(i, j);
353  }
354  } else {
356  labelsForToken(theStripClusterLabel, labels);
357  edm::LogWarning("MeasurementTrackerEventProducer")
358  << "input strip cluster collection " << labels.module << " is not valid";
359  }
360  }
361 }
362 
363 //FIXME: just a temporary solution for phase2!
365  Phase2OTMeasurementDetSet& thePh2OTDets) const {
366  thePh2OTDets.setEmpty();
367 
368  // Phase2OT Clusters
369  if (isPhase2_) {
370  if (thePh2OTClusterLabel.isUninitialized()) { //clusters have not been produced
371  thePh2OTDets.setActiveThisEvent(false);
372  } else {
374  if (event.getByToken(thePh2OTClusterLabel, phase2OTClusters)) {
375  const edmNew::DetSetVector<Phase2TrackerCluster1D>* phase2OTCollection = phase2OTClusters.product();
376 
377  int i = 0, endDet = thePh2OTDets.size();
379  ed = phase2OTCollection->end();
380  it != ed;
381  ++it) {
383  unsigned int id = set.id();
384  while (id != thePh2OTDets.id(i)) {
385  ++i;
386  if (endDet == i)
387  throw "we have a problem!!!!";
388  }
389  // push cluster range in det
390  if (thePh2OTDets.isActive(i)) {
391  thePh2OTDets.update(i, set);
392  }
393  }
394  } else {
396  labelsForToken(thePh2OTClusterLabel, labels);
397  edm::LogWarning("MeasurementTrackerEventProducer")
398  << "input Phase2TrackerCluster1D collection " << labels.module << " is not valid";
399  }
400  }
401  }
402  return;
403 }
404 
406  std::vector<uint32_t>& rawInactiveDetIds) const {
407  if (!theInactiveStripDetectorLabels.empty()) {
410  if (event.getByToken(tk, detIds)) {
411  rawInactiveDetIds.insert(rawInactiveDetIds.end(), detIds->begin(), detIds->end());
412  }
413  }
414  if (!rawInactiveDetIds.empty())
415  std::sort(rawInactiveDetIds.begin(), rawInactiveDetIds.end());
416  }
417 }
418 
std::vector< std::pair< LocalPoint, LocalPoint > > BadFEDChannelPositions
void setComment(std::string const &value)
const_iterator end(bool update=false) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
size_type dataSize() const
std::vector< edm::EDGetTokenT< DetIdCollection > > theInactiveStripDetectorLabels
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
uint16_t *__restrict__ id
ProductID id() const
Definition: HandleBase.cc:29
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
tuple measurementTracker
virtual int rowsperroc() const =0
constexpr bool isUninitialized() const noexcept
Definition: EDGetToken.h:99
edm::ESGetToken< SiPixelFedCablingMap, SiPixelFedCablingMapRcd > pixelCablingMapToken_
MeasurementTrackerEventProducer(const edm::ParameterSet &iConfig)
T y() const
Definition: PV3DBase.h:60
void updateStrips(const edm::Event &, StMeasurementDetSet &theStDets, std::vector< bool > &stripClustersToSkip) const
void update(int i, const StripDetset &detSet)
edm::EDGetTokenT< edmNew::DetSetVector< Phase2TrackerCluster1D > > thePh2OTClusterLabel
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const edm::Handle< edmNew::DetSetVector< SiPixelCluster > > & handle() const
Log< level::Error, false > LogError
assert(be >=bs)
identify pixel inside single ROC
Definition: LocalPixel.h:7
global coordinates (row and column in DetUnit, as in PixelDigi)
Definition: GlobalPixel.h:6
unsigned int id(int i) const
unsigned int id(int i) const
bool getData(T &iHolder) const
Definition: EventSetup.h:122
int find(unsigned int jd, int i=0) const
std::vector< edm::EDGetTokenT< PixelFEDChannelCollection > > theBadPixelFEDChannelsLabels
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
int iEvent
Definition: GenABIO.cc:224
void setActiveThisEvent(int i, bool active)
Turn on/off the module for reconstruction for one events. This per-event flag is cleared by any call ...
virtual int colsperroc() const =0
void updatePhase2OT(const edm::Event &, Phase2OTMeasurementDetSet &thePh2OTDets) const
const edm::Handle< edmNew::DetSetVector< Phase2TrackerCluster1D > > & handle() const
bool isActive(int i) const
T z() const
Definition: PV3DBase.h:61
unsigned int idInDetUnit() const
id of this ROC in DetUnit etermined by token path
Definition: PixelROC.h:37
uint32_t rawId() const
return the DetUnit to which this ROC belongs to.
Definition: PixelROC.h:34
void getInactiveStrips(const edm::Event &event, std::vector< uint32_t > &rawInactiveDetIds) const
edm::EDGetTokenT< VectorHitCollection > thePh2OTVectorHitsRejLabel
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:346
void updateStacks(const edm::Event &, Phase2OTMeasurementDetSet &theStDets) const
void update(int i, const PixelDetSet &detSet)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void addBadFEDChannelPositions(int i, BadFEDChannelPositions &positions)
char const * module
Definition: ProductLabels.h:5
const TrackerGeomDet * idToDet(DetId) const override
void produce(edm::Event &, const edm::EventSetup &) override
boost::transform_iterator< IterHelp, const_IdIter > const_iterator
bool failedToGet() const
Definition: HandleBase.h:72
void fill(std::map< std::string, TH1 * > &h, const std::string &s, double x)
T const * product() const
Definition: Handle.h:70
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
edm::EDGetTokenT< edm::ContainerMask< edmNew::DetSetVector< SiPixelCluster > > > thePixelClusterMask
row and collumn in ROC representation
Definition: LocalPixel.h:13
void add(std::string const &label, ParameterSetDescription const &psetDescription)
bool isActive(int i) const
void updatePixels(const edm::Event &, PxMeasurementDetSet &thePxDets, std::vector< bool > &pixelClustersToSkip, const TrackerGeometry &trackerGeom, const edm::EventSetup &iSetup) const
edm::ESGetToken< MeasurementTracker, CkfComponentsRecord > measurementTrackerToken_
void setActiveThisEvent(bool active)
edm::EDGetTokenT< edmNew::DetSetVector< SiStripCluster > > theStripClusterLabel
id_type id() const
Definition: DetSetNew.h:64
edm::EDGetTokenT< VectorHitCollection > thePh2OTVectorHitsLabel
int find(unsigned int jd, int i=0) const
void setActiveThisEvent(bool active)
edm::Handle< edmNew::DetSetVector< SiStripCluster > > & handle()
Log< level::Warning, false > LogWarning
unsigned int id(int i) const
void update(int i, const Phase2DetSet &detSet)
T x() const
Definition: PV3DBase.h:59
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
edm::EDGetTokenT< edmNew::DetSetVector< SiPixelCluster > > thePixelClusterLabel
edm::EDGetTokenT< edm::ContainerMask< edmNew::DetSetVector< SiStripCluster > > > theStripClusterMask
const_iterator begin(bool update=false) const
std::vector< edm::EDGetTokenT< DetIdCollection > > theInactivePixelDetectorLabels
GlobalPixel toGlobal(const LocalPixel &loc) const
Definition: PixelROC.h:55
#define LogDebug(id)