CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DetIdAssociator.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: TrackAssociator
4 // Class: DetIdAssociator
5 //
6 /*
7 
8  Description: <one line class summary>
9 
10  Implementation:
11  <Notes on implementation>
12 */
13 //
14 // Original Author: Dmytro Kovalskyi
15 // Created: Fri Apr 21 10:59:41 PDT 2006
16 //
17 //
18 
19 
21 #include "DetIdInfo.h"
23 #include <map>
24 
25 DetIdAssociator::DetIdAssociator(const int nPhi, const int nEta, const double etaBinSize)
26  :nPhi_(nPhi),nEta_(nEta),
27  lookupMap_(nPhi_*nEta_,std::pair<unsigned int, unsigned int>(0,0)),
28  theMapIsValid_(false),etaBinSize_(etaBinSize)
29 {
30  if (nEta_ <= 0 || nPhi_ <= 0) throw cms::Exception("FatalError") << "incorrect look-up map size. Cannot initialize such a map.";
32  minTheta_ = 2*atan(exp(-maxEta_));
33 }
34 
35 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& direction,
36  const int iN) const
37 {
38  unsigned int n = 0;
39  if (iN>0) n = iN;
40  return getDetIdsCloseToAPoint(direction,n,n,n,n);
41 }
42 
43 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& direction,
44  const unsigned int iNEtaPlus,
45  const unsigned int iNEtaMinus,
46  const unsigned int iNPhiPlus,
47  const unsigned int iNPhiMinus) const
48 {
49  std::set<DetId> set;
50  check_setup();
51  if (! theMapIsValid_ ) throw cms::Exception("FatalError") << "map is not valid.";
52  LogTrace("TrackAssociator") << "(iNEtaPlus, iNEtaMinus, iNPhiPlus, iNPhiMinus): " <<
53  iNEtaPlus << ", " << iNEtaMinus << ", " << iNPhiPlus << ", " << iNPhiMinus;
54  LogTrace("TrackAssociator") << "point (eta,phi): " << direction.eta() << "," << direction.phi();
55  int ieta = iEta(direction);
56  int iphi = iPhi(direction);
57  LogTrace("TrackAssociator") << "(ieta,iphi): " << ieta << "," << iphi << "\n";
58  if (ieta>=0 && ieta<nEta_ && iphi>=0 && iphi<nPhi_){
59  fillSet(set,ieta,iphi);
60  // dumpMapContent(ieta,iphi);
61  // check if any neighbor bin is requested
62  if (iNEtaPlus + iNEtaMinus + iNPhiPlus + iNPhiMinus >0 ){
63  LogTrace("TrackAssociator") << "Add neighbors (ieta,iphi): " << ieta << "," << iphi;
64  // eta
65  int maxIEta = ieta+iNEtaPlus;
66  int minIEta = ieta-iNEtaMinus;
67  if (maxIEta>=nEta_) maxIEta = nEta_-1;
68  if (minIEta<0) minIEta = 0;
69  // phi
70  int maxIPhi = iphi+iNPhiPlus;
71  int minIPhi = iphi-iNPhiMinus;
72  if (maxIPhi-minIPhi>=nPhi_){ // all elements in phi
73  minIPhi = 0;
74  maxIPhi = nPhi_-1;
75  }
76  if(minIPhi<0) {
77  minIPhi+=nPhi_;
78  maxIPhi+=nPhi_;
79  }
80  LogTrace("TrackAssociator") << "\tieta (min,max): " << minIEta << "," << maxIEta;
81  LogTrace("TrackAssociator") << "\tiphi (min,max): " << minIPhi << "," << maxIPhi<< "\n";
82  // dumpMapContent(minIEta,maxIEta,minIPhi,maxIPhi);
83  for (int i=minIEta;i<=maxIEta;i++)
84  for (int j=minIPhi;j<=maxIPhi;j++) {
85  if( i==ieta && j==iphi) continue; // already in the set
86  fillSet(set,i,j%nPhi_);
87  }
88  }
89 
90  }
91  return set;
92 }
93 
95  const double d) const
96 {
97  return getDetIdsCloseToAPoint(point,d,d,d,d);
98 }
99 
101  const double dThetaPlus,
102  const double dThetaMinus,
103  const double dPhiPlus,
104  const double dPhiMinus) const
105 {
106  LogTrace("TrackAssociator") << "(dThetaPlus,dThetaMinus,dPhiPlus,dPhiMinus): " <<
107  dThetaPlus << ", " << dThetaMinus << ", " << dPhiPlus << ", " << dPhiMinus;
108  unsigned int n = 0;
109  if ( dThetaPlus<0 || dThetaMinus<0 || dPhiPlus<0 || dPhiMinus<0)
110  return getDetIdsCloseToAPoint(point,n,n,n,n);
111  // check that region of interest overlaps with the look-up map
112  double maxTheta = point.theta()+dThetaPlus;
113  if (maxTheta > M_PI-minTheta_) maxTheta = M_PI-minTheta_;
114  double minTheta = point.theta()-dThetaMinus;
115  if (minTheta < minTheta_) minTheta = minTheta_;
116  if ( maxTheta < minTheta_ || minTheta > M_PI-minTheta_) return std::set<DetId>();
117 
118  // take into account non-linear dependence of eta from
119  // theta in regions with large |eta|
120  double minEta = -log(tan(maxTheta/2));
121  double maxEta = -log(tan(minTheta/2));
122  unsigned int iNEtaPlus = abs(int( ( maxEta-point.eta() )/etaBinSize_));
123  unsigned int iNEtaMinus = abs(int( ( point.eta() - minEta )/etaBinSize_));
124  unsigned int iNPhiPlus = abs(int( dPhiPlus/(2*M_PI)*nPhi_ ));
125  unsigned int iNPhiMinus = abs(int( dPhiMinus/(2*M_PI)*nPhi_ ));
126  // add one more bin in each direction to guaranty that we don't miss anything
127  return getDetIdsCloseToAPoint(point, iNEtaPlus+1, iNEtaMinus+1, iNPhiPlus+1, iNPhiMinus+1);
128 }
129 
130 
132 {
133  return int(point.eta()/etaBinSize_ + nEta_/2);
134 }
135 
137 {
138  return int((double(point.phi())+M_PI)/(2*M_PI)*nPhi_);
139 }
140 
141 
143 {
144  // the map is built in two steps to create a clean memory footprint
145  // 0) determine how many elements each bin has
146  // 1) fill the container map
147  check_setup();
148  LogTrace("TrackAssociator")<<"building map for " << name() << "\n";
149  // clear the map
150  if (nEta_ <= 0 || nPhi_ <= 0) throw cms::Exception("FatalError") << "incorrect look-up map size. Cannot build such a map.";
151  std::vector<GlobalPoint> pointBuffer;
152  std::vector<DetId> detIdBuffer;
153  unsigned int numberOfSubDetectors = getNumberOfSubdetectors();
154  unsigned totalNumberOfElementsInTheContainer(0);
155  for ( unsigned int step = 0; step < 2; ++step){
156  unsigned int numberOfDetIdsOutsideEtaRange = 0;
157  unsigned int numberOfDetIdsActive = 0;
158  LogTrace("TrackAssociator")<< "Step: " << step;
159  for ( unsigned int subDetectorIndex = 0; subDetectorIndex < numberOfSubDetectors; ++subDetectorIndex ){
160  getValidDetIds(subDetectorIndex, detIdBuffer);
161  // This std::move prevents modification
162  std::vector<DetId> const& validIds = std::move(detIdBuffer);
163  LogTrace("TrackAssociator")<< "Number of valid DetIds for subdetector: " << subDetectorIndex << " is " << validIds.size();
164  for (std::vector<DetId>::const_iterator id_itr = validIds.begin(); id_itr!=validIds.end(); id_itr++) {
165  std::pair<const_iterator,const_iterator> points = getDetIdPoints(*id_itr, pointBuffer);
166  LogTrace("TrackAssociatorVerbose")<< "Found " << points.second-points.first << " global points to describe geometry of DetId: "
167  << id_itr->rawId();
168  int etaMax(-1);
169  int etaMin(-1);
170  int phiMax(-1);
171  int phiMin(-1);
172  // this is a bit overkill, but it should be 100% proof (when debugged :)
173  for(std::vector<GlobalPoint>::const_iterator iter = points.first; iter != points.second; iter++)
174  {
175  LogTrace("TrackAssociatorVerbose")<< "\tpoint (rho,phi,z): " << iter->perp() << ", " <<
176  iter->phi() << ", " << iter->z();
177  // FIX ME: this should be a fatal error
178  if(edm::isNotFinite(iter->mag())||iter->mag()>1e5) { //Detector parts cannot be 1 km away or be NaN
179  edm::LogWarning("TrackAssociator") << "Critical error! Bad detector unit geometry:\n\tDetId:"
180  << id_itr->rawId() << "\t mag(): " << iter->mag() << "\n" << DetIdInfo::info( *id_itr,0 )
181  << "\nSkipped the element";
182  continue;
183  }
184  volume_.addActivePoint(*iter);
185  int ieta = iEta(*iter);
186  int iphi = iPhi(*iter);
187  if (ieta<0 || ieta>=nEta_) {
188  LogTrace("TrackAssociator")<<"Out of range: DetId:" << id_itr->rawId() << "\t (ieta,iphi): "
189  << ieta << "," << iphi << "\n" << "Point: " << *iter << "\t(eta,phi): " << (*iter).eta()
190  << "," << (*iter).phi() << "\n center: " << getPosition(*id_itr);
191  continue;
192  }
193  if ( phiMin<0 ) {
194  // first element
195  etaMin = ieta;
196  etaMax = ieta;
197  phiMin = iphi;
198  phiMax = iphi;
199  }else{
200  // check for discontinuity in phi
201  int deltaMin = abs(phiMin -iphi);
202  int deltaMax = abs(phiMax -iphi);
203  // assume that no single detector element has more than 3.1416 coverage in phi
204  if ( deltaMin > nPhi_/2 && phiMin < nPhi_/2 ) phiMin+= nPhi_;
205  if ( deltaMax > nPhi_/2 ) {
206  if (phiMax < nPhi_/2 )
207  phiMax+= nPhi_;
208  else
209  iphi += nPhi_;
210  }
211  assert (iphi>=0);
212  if ( etaMin > ieta) etaMin = ieta;
213  if ( etaMax < ieta) etaMax = ieta;
214  if ( phiMin > iphi) phiMin = iphi;
215  if ( phiMax < iphi) phiMax = iphi;
216  }
217  }
218  if (etaMax<0||phiMax<0||etaMin>=nEta_||phiMin>=nPhi_) {
219  LogTrace("TrackAssociatorVerbose")<<"Out of range or no geometry: DetId:" << id_itr->rawId() <<
220  "\n\teta (min,max): " << etaMin << "," << etaMax <<
221  "\n\tphi (min,max): " << phiMin << "," << phiMax <<
222  "\nTower id: " << id_itr->rawId() << "\n";
223  numberOfDetIdsOutsideEtaRange++;
224  continue;
225  }
226  numberOfDetIdsActive++;
227 
228  LogTrace("TrackAssociatorVerbose") << "DetId (ieta_min,ieta_max,iphi_min,iphi_max): " << id_itr->rawId() <<
229  ", " << etaMin << ", " << etaMax << ", " << phiMin << ", " << phiMax;
230  for(int ieta = etaMin; ieta <= etaMax; ieta++)
231  for(int iphi = phiMin; iphi <= phiMax; iphi++)
232  if ( step == 0 ){
233  lookupMap_.at(index(ieta,iphi%nPhi_)).second++;
234  totalNumberOfElementsInTheContainer++;
235  } else {
236  container_.at(lookupMap_.at(index(ieta,iphi%nPhi_)).first) = *id_itr;
237  lookupMap_.at(index(ieta,iphi%nPhi_)).first--;
238  totalNumberOfElementsInTheContainer--;
239  }
240  }
241  }
242  LogTrace("TrackAssociator") << "Number of elements outside the allowed range ( |eta|>"<<
243  nEta_/2*etaBinSize_ << "): " << numberOfDetIdsOutsideEtaRange << "\n";
244  LogTrace("TrackAssociator") << "Number of active DetId's mapped: " <<
245  numberOfDetIdsActive << "\n";
246  if ( step == 0 ){
247  // allocate
248  container_.resize(totalNumberOfElementsInTheContainer);
249  // fill the range index in the lookup map to point to the last element in the range
250  unsigned int index(0);
251  for ( std::vector<std::pair<unsigned int,unsigned int> >::iterator bin = lookupMap_.begin();
252  bin != lookupMap_.end(); ++bin )
253  {
254  if (bin->second==0) continue;
255  index += bin->second;
256  bin->first = index-1;
257  }
258  }
259  }
260  if ( totalNumberOfElementsInTheContainer != 0 )
261  throw cms::Exception("FatalError") << "Look-up map filled incorrectly. Structural problem. Get in touch with the developer.";
263  edm::LogVerbatim("TrackAssociator") << "Fiducial volume for " << name() << " (minR, maxR, minZ, maxZ): " <<
264  volume_.minR() << ", " << volume_.maxR() << ", " << volume_.minZ() << ", " << volume_.maxZ();
265  theMapIsValid_ = true;
266 }
267 
268 std::set<DetId> DetIdAssociator::getDetIdsInACone(const std::set<DetId>& inset,
269  const std::vector<GlobalPoint>& trajectory,
270  const double dR) const
271 {
272  if ( dR > 2*M_PI && dR > maxEta_ ) return inset;
273  check_setup();
274  std::set<DetId> outset;
275  for(std::set<DetId>::const_iterator id_iter = inset.begin(); id_iter != inset.end(); id_iter++)
276  for(std::vector<GlobalPoint>::const_iterator point_iter = trajectory.begin(); point_iter != trajectory.end(); point_iter++)
277  if (nearElement(*point_iter,*id_iter,dR)) {
278  outset.insert(*id_iter);
279  break;
280  }
281  return outset;
282 }
283 
284 std::vector<DetId> DetIdAssociator::getCrossedDetIds(const std::set<DetId>& inset,
285  const std::vector<GlobalPoint>& trajectory) const
286 {
287  check_setup();
288  std::vector<DetId> output;
289  std::set<DetId> ids(inset);
290  for ( unsigned int i=0; i+1 < trajectory.size(); ++i ) {
291  std::set<DetId>::const_iterator id_iter = ids.begin();
292  while ( id_iter != ids.end() ) {
293  if ( crossedElement(trajectory[i],trajectory[i+1],*id_iter) ){
294  output.push_back(*id_iter);
295  ids.erase(id_iter++);
296  }else
297  id_iter++;
298  }
299  }
300  return output;
301 }
302 
303 std::vector<DetId> DetIdAssociator::getCrossedDetIds(const std::set<DetId>& inset,
304  const std::vector<SteppingHelixStateInfo>& trajectory,
305  const double tolerance) const
306 {
307  check_setup();
308  std::vector<DetId> output;
309  std::set<DetId> ids(inset);
310  for ( unsigned int i=0; i+1 < trajectory.size(); ++i ) {
311  std::set<DetId>::const_iterator id_iter = ids.begin();
312  while ( id_iter != ids.end() ) {
313  if ( crossedElement(trajectory[i].position(),trajectory[i+1].position(),*id_iter,tolerance,&trajectory[i]) ){
314  output.push_back(*id_iter);
315  ids.erase(id_iter++);
316  }else
317  id_iter++;
318  }
319  }
320  return output;
321 }
322 
323 
324 void DetIdAssociator::dumpMapContent(int ieta, int iphi) const
325 {
326  if (! (ieta>=0 && ieta<nEta_ && iphi>=0) )
327  {
328  edm::LogWarning("TrackAssociator") << "ieta or iphi is out of range. Skipped.";
329  return;
330  }
331 
332  std::vector<GlobalPoint> pointBuffer;
333  std::set<DetId> set;
334  fillSet(set,ieta,iphi%nPhi_);
335  LogTrace("TrackAssociator") << "Map content for cell (ieta,iphi): " << ieta << ", " << iphi%nPhi_;
336  for(std::set<DetId>::const_iterator itr = set.begin(); itr!=set.end(); itr++)
337  {
338  LogTrace("TrackAssociator") << "\tDetId " << itr->rawId() << ", geometry (x,y,z,rho,eta,phi):";
339  std::pair<const_iterator,const_iterator> points = getDetIdPoints(*itr, pointBuffer);
340  for(std::vector<GlobalPoint>::const_iterator point = points.first; point != points.second; point++)
341  LogTrace("TrackAssociator") << "\t\t" << point->x() << ", " << point->y() << ", " << point->z() << ", "
342  << point->perp() << ", " << point->eta() << ", " << point->phi();
343  }
344 }
345 
346 void DetIdAssociator::dumpMapContent(int ieta_min, int ieta_max, int iphi_min, int iphi_max) const
347 {
348  for(int i=ieta_min;i<=ieta_max;i++)
349  for(int j=iphi_min;j<=iphi_max;j++)
350  dumpMapContent(i,j);
351 }
352 
354 {
355  if (! theMapIsValid_ ) throw cms::Exception("FatalError") << "map is not valid.";
356  return volume_;
357 }
358 
359 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& direction,
360  const MapRange& mapRange) const
361 {
362  return getDetIdsCloseToAPoint(direction, mapRange.dThetaPlus, mapRange.dThetaMinus,
363  mapRange.dPhiPlus, mapRange.dPhiMinus);
364 
365 }
366 
368  const DetId& id,
369  const double distance) const
370 {
371  GlobalPoint center = getPosition(id);
372  double deltaPhi(fabs(point.phi()-center.phi()));
373  if(deltaPhi>M_PI) deltaPhi = fabs(deltaPhi-M_PI*2.);
374  return (point.eta()-center.eta())*(point.eta()-center.eta()) + deltaPhi*deltaPhi < distance*distance;
375 }
376 
378 {
379  if (nEta_==0) throw cms::Exception("FatalError") << "Number of eta bins is not set.\n";
380  if (nPhi_==0) throw cms::Exception("FatalError") << "Number of phi bins is not set.\n";
381  // if (ivProp_==0) throw cms::Exception("FatalError") << "Track propagator is not defined\n";
382  if (etaBinSize_==0) throw cms::Exception("FatalError") << "Eta bin size is not set.\n";
383 }
384 
385 void DetIdAssociator::fillSet( std::set<DetId>& set, unsigned int iEta, unsigned int iPhi) const
386 {
387  unsigned int i = index(iEta,iPhi);
388  unsigned int i0 = lookupMap_.at(i).first;
389  unsigned int size = lookupMap_.at(i).second;
390  for ( i = i0; i < i0+size; ++i )
391  set.insert(container_.at(i));
392 }
393 
396 
399 
400 
401 // LocalWords: Fiducial
virtual std::set< DetId > getDetIdsInACone(const std::set< DetId > &, const std::vector< GlobalPoint > &trajectory, const double dR) const
int i
Definition: DBlmapReader.cc:9
void determinInnerDimensions()
virtual bool crossedElement(const GlobalPoint &, const GlobalPoint &, const DetId &, const double toleranceInSigmas=-1, const SteppingHelixStateInfo *=0) const
virtual void getValidDetIds(unsigned int subDetectorIndex, std::vector< DetId > &) const =0
double maxZ(bool withTolerance=true) const
FiducialVolume volume_
assert(m_qm.get())
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
virtual bool nearElement(const GlobalPoint &point, const DetId &id, const double distance) const
unsigned int index(unsigned int iEta, unsigned int iPhi) const
virtual int iEta(const GlobalPoint &) const
look-up map eta index
double maxEta
virtual std::vector< DetId > getCrossedDetIds(const std::set< DetId > &, const std::vector< GlobalPoint > &trajectory) const
std::vector< std::pair< unsigned int, unsigned int > > lookupMap_
double minZ(bool withTolerance=true) const
std::vector< DetId > container_
virtual void dumpMapContent(int, int) const
const double etaBinSize_
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
virtual int iPhi(const GlobalPoint &) const
look-up map phi index
tuple d
Definition: ztail.py:151
void fillSet(std::set< DetId > &set, unsigned int iEta, unsigned int iPhi) const
void addActivePoint(const GlobalPoint &point)
add a point that belongs to the active volume
virtual const unsigned int getNumberOfSubdetectors() const
bool isNotFinite(T x)
Definition: isFinite.h:10
virtual const char * name() const =0
def move
Definition: eostools.py:510
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
virtual void check_setup() const
#define LogTrace(id)
#define M_PI
#define TYPELOOKUP_DATA_REG(_dataclass_)
Definition: typelookup.h:96
double minR(bool withTolerance=true) const
Definition: DetId.h:18
static std::string info(const DetId &, const TrackerTopology *tTopo)
Definition: DetIdInfo.cc:29
DetIdAssociator(const int nPhi, const int nEta, const double etaBinSize)
T eta() const
Definition: PV3DBase.h:76
virtual void buildMap()
make the look-up map
virtual GlobalPoint getPosition(const DetId &) const =0
static int position[264][3]
Definition: ReadPGInfo.cc:509
const FiducialVolume & volume() const
get active detector volume
volatile std::atomic< bool > shutdown_flag false
virtual std::set< DetId > getDetIdsCloseToAPoint(const GlobalPoint &, const int iN=0) const
virtual std::pair< const_iterator, const_iterator > getDetIdPoints(const DetId &, std::vector< GlobalPoint > &) const =0
double maxR(bool withTolerance=true) const
tuple size
Write out results.
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
tuple log
Definition: cmsBatch.py:341