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 // $Id: DetIdAssociator.cc,v 1.26 2011/04/07 09:18:47 innocent Exp $
17 //
18 //
19 
20 
22 #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),ivProp_(0)
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  unsigned int numberOfSubDetectors = getNumberOfSubdetectors();
152  unsigned totalNumberOfElementsInTheContainer(0);
153  for ( unsigned int step = 0; step < 2; ++step){
154  unsigned int numberOfDetIdsOutsideEtaRange = 0;
155  unsigned int numberOfDetIdsActive = 0;
156  LogTrace("TrackAssociator")<< "Step: " << step;
157  for ( unsigned int subDetectorIndex = 0; subDetectorIndex < numberOfSubDetectors; ++subDetectorIndex ){
158  const std::vector<DetId>& validIds = getValidDetIds(subDetectorIndex);
159  LogTrace("TrackAssociator")<< "Number of valid DetIds for subdetector: " << subDetectorIndex << " is " << validIds.size();
160  for (std::vector<DetId>::const_iterator id_itr = validIds.begin(); id_itr!=validIds.end(); id_itr++) {
161  std::pair<const_iterator,const_iterator> points = getDetIdPoints(*id_itr);
162  LogTrace("TrackAssociatorVerbose")<< "Found " << points.second-points.first << " global points to describe geometry of DetId: "
163  << id_itr->rawId();
164  int etaMax(-1);
165  int etaMin(-1);
166  int phiMax(-1);
167  int phiMin(-1);
168  // this is a bit overkill, but it should be 100% proof (when debugged :)
169  for(std::vector<GlobalPoint>::const_iterator iter = points.first; iter != points.second; iter++)
170  {
171  LogTrace("TrackAssociatorVerbose")<< "\tpoint (rho,phi,z): " << iter->perp() << ", " <<
172  iter->phi() << ", " << iter->z();
173  // FIX ME: this should be a fatal error
174  if(std::isnan(iter->mag())||iter->mag()>1e5) { //Detector parts cannot be 1 km away or be NaN
175  edm::LogWarning("TrackAssociator") << "Critical error! Bad detector unit geometry:\n\tDetId:"
176  << id_itr->rawId() << "\t mag(): " << iter->mag() << "\n" << DetIdInfo::info( *id_itr )
177  << "\nSkipped the element";
178  continue;
179  }
180  volume_.addActivePoint(*iter);
181  int ieta = iEta(*iter);
182  int iphi = iPhi(*iter);
183  if (ieta<0 || ieta>=nEta_) {
184  LogTrace("TrackAssociator")<<"Out of range: DetId:" << id_itr->rawId() << "\t (ieta,iphi): "
185  << ieta << "," << iphi << "\n" << "Point: " << *iter << "\t(eta,phi): " << (*iter).eta()
186  << "," << (*iter).phi() << "\n center: " << getPosition(*id_itr);
187  continue;
188  }
189  if ( phiMin<0 ) {
190  // first element
191  etaMin = ieta;
192  etaMax = ieta;
193  phiMin = iphi;
194  phiMax = iphi;
195  }else{
196  // check for discontinuity in phi
197  int deltaMin = abs(phiMin -iphi);
198  int deltaMax = abs(phiMax -iphi);
199  // assume that no single detector element has more than 3.1416 coverage in phi
200  if ( deltaMin > nPhi_/2 && phiMin < nPhi_/2 ) phiMin+= nPhi_;
201  if ( deltaMax > nPhi_/2 ) {
202  if (phiMax < nPhi_/2 )
203  phiMax+= nPhi_;
204  else
205  iphi += nPhi_;
206  }
207  assert (iphi>=0);
208  if ( etaMin > ieta) etaMin = ieta;
209  if ( etaMax < ieta) etaMax = ieta;
210  if ( phiMin > iphi) phiMin = iphi;
211  if ( phiMax < iphi) phiMax = iphi;
212  }
213  }
214  if (etaMax<0||phiMax<0||etaMin>=nEta_||phiMin>=nPhi_) {
215  LogTrace("TrackAssociatorVerbose")<<"Out of range or no geometry: DetId:" << id_itr->rawId() <<
216  "\n\teta (min,max): " << etaMin << "," << etaMax <<
217  "\n\tphi (min,max): " << phiMin << "," << phiMax <<
218  "\nTower id: " << id_itr->rawId() << "\n";
219  numberOfDetIdsOutsideEtaRange++;
220  continue;
221  }
222  numberOfDetIdsActive++;
223 
224  LogTrace("TrackAssociatorVerbose") << "DetId (ieta_min,ieta_max,iphi_min,iphi_max): " << id_itr->rawId() <<
225  ", " << etaMin << ", " << etaMax << ", " << phiMin << ", " << phiMax;
226  for(int ieta = etaMin; ieta <= etaMax; ieta++)
227  for(int iphi = phiMin; iphi <= phiMax; iphi++)
228  if ( step == 0 ){
229  lookupMap_.at(index(ieta,iphi%nPhi_)).second++;
230  totalNumberOfElementsInTheContainer++;
231  } else {
232  container_.at(lookupMap_.at(index(ieta,iphi%nPhi_)).first) = *id_itr;
233  lookupMap_.at(index(ieta,iphi%nPhi_)).first--;
234  totalNumberOfElementsInTheContainer--;
235  }
236  }
237  }
238  LogTrace("TrackAssociator") << "Number of elements outside the allowed range ( |eta|>"<<
239  nEta_/2*etaBinSize_ << "): " << numberOfDetIdsOutsideEtaRange << "\n";
240  LogTrace("TrackAssociator") << "Number of active DetId's mapped: " <<
241  numberOfDetIdsActive << "\n";
242  if ( step == 0 ){
243  // allocate
244  container_.resize(totalNumberOfElementsInTheContainer);
245  // fill the range index in the lookup map to point to the last element in the range
246  unsigned int index(0);
247  for ( std::vector<std::pair<unsigned int,unsigned int> >::iterator bin = lookupMap_.begin();
248  bin != lookupMap_.end(); ++bin )
249  {
250  if (bin->second==0) continue;
251  index += bin->second;
252  bin->first = index-1;
253  }
254  }
255  }
256  if ( totalNumberOfElementsInTheContainer != 0 )
257  throw cms::Exception("FatalError") << "Look-up map filled incorrectly. Structural problem. Get in touch with the developer.";
259  edm::LogVerbatim("TrackAssociator") << "Fiducial volume for " << name() << " (minR, maxR, minZ, maxZ): " <<
260  volume_.minR() << ", " << volume_.maxR() << ", " << volume_.minZ() << ", " << volume_.maxZ();
261  theMapIsValid_ = true;
262 }
263 
264 std::set<DetId> DetIdAssociator::getDetIdsInACone(const std::set<DetId>& inset,
265  const std::vector<GlobalPoint>& trajectory,
266  const double dR) const
267 {
268  if ( dR > 2*M_PI && dR > maxEta_ ) return inset;
269  check_setup();
270  std::set<DetId> outset;
271  for(std::set<DetId>::const_iterator id_iter = inset.begin(); id_iter != inset.end(); id_iter++)
272  for(std::vector<GlobalPoint>::const_iterator point_iter = trajectory.begin(); point_iter != trajectory.end(); point_iter++)
273  if (nearElement(*point_iter,*id_iter,dR)) {
274  outset.insert(*id_iter);
275  break;
276  }
277  return outset;
278 }
279 
280 std::vector<DetId> DetIdAssociator::getCrossedDetIds(const std::set<DetId>& inset,
281  const std::vector<GlobalPoint>& trajectory) const
282 {
283  check_setup();
284  std::vector<DetId> output;
285  std::set<DetId> ids(inset);
286  for ( unsigned int i=0; i+1 < trajectory.size(); ++i ) {
287  std::set<DetId>::const_iterator id_iter = ids.begin();
288  while ( id_iter != ids.end() ) {
289  if ( crossedElement(trajectory[i],trajectory[i+1],*id_iter) ){
290  output.push_back(*id_iter);
291  ids.erase(id_iter++);
292  }else
293  id_iter++;
294  }
295  }
296  return output;
297 }
298 
299 std::vector<DetId> DetIdAssociator::getCrossedDetIds(const std::set<DetId>& inset,
300  const std::vector<SteppingHelixStateInfo>& trajectory,
301  const double tolerance) const
302 {
303  check_setup();
304  std::vector<DetId> output;
305  std::set<DetId> ids(inset);
306  for ( unsigned int i=0; i+1 < trajectory.size(); ++i ) {
307  std::set<DetId>::const_iterator id_iter = ids.begin();
308  while ( id_iter != ids.end() ) {
309  if ( crossedElement(trajectory[i].position(),trajectory[i+1].position(),*id_iter,tolerance,&trajectory[i]) ){
310  output.push_back(*id_iter);
311  ids.erase(id_iter++);
312  }else
313  id_iter++;
314  }
315  }
316  return output;
317 }
318 
319 
320 void DetIdAssociator::dumpMapContent(int ieta, int iphi) const
321 {
322  if (! (ieta>=0 && ieta<nEta_ && iphi>=0) )
323  {
324  edm::LogWarning("TrackAssociator") << "ieta or iphi is out of range. Skipped.";
325  return;
326  }
327 
328  std::set<DetId> set;
329  fillSet(set,ieta,iphi%nPhi_);
330  LogTrace("TrackAssociator") << "Map content for cell (ieta,iphi): " << ieta << ", " << iphi%nPhi_;
331  for(std::set<DetId>::const_iterator itr = set.begin(); itr!=set.end(); itr++)
332  {
333  LogTrace("TrackAssociator") << "\tDetId " << itr->rawId() << ", geometry (x,y,z,rho,eta,phi):";
334  std::pair<const_iterator,const_iterator> points = getDetIdPoints(*itr);
335  for(std::vector<GlobalPoint>::const_iterator point = points.first; point != points.second; point++)
336  LogTrace("TrackAssociator") << "\t\t" << point->x() << ", " << point->y() << ", " << point->z() << ", "
337  << point->perp() << ", " << point->eta() << ", " << point->phi();
338  }
339 }
340 
341 void DetIdAssociator::dumpMapContent(int ieta_min, int ieta_max, int iphi_min, int iphi_max) const
342 {
343  for(int i=ieta_min;i<=ieta_max;i++)
344  for(int j=iphi_min;j<=iphi_max;j++)
345  dumpMapContent(i,j);
346 }
347 
349 {
350  if (! theMapIsValid_ ) throw cms::Exception("FatalError") << "map is not valid.";
351  return volume_;
352 }
353 
354 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& direction,
355  const MapRange& mapRange) const
356 {
357  return getDetIdsCloseToAPoint(direction, mapRange.dThetaPlus, mapRange.dThetaMinus,
358  mapRange.dPhiPlus, mapRange.dPhiMinus);
359 
360 }
361 
363  const DetId& id,
364  const double distance) const
365 {
366  GlobalPoint center = getPosition(id);
367  double deltaPhi(fabs(point.phi()-center.phi()));
368  if(deltaPhi>M_PI) deltaPhi = fabs(deltaPhi-M_PI*2.);
369  return (point.eta()-center.eta())*(point.eta()-center.eta()) + deltaPhi*deltaPhi < distance*distance;
370 }
371 
373 {
374  if (nEta_==0) throw cms::Exception("FatalError") << "Number of eta bins is not set.\n";
375  if (nPhi_==0) throw cms::Exception("FatalError") << "Number of phi bins is not set.\n";
376  // if (ivProp_==0) throw cms::Exception("FatalError") << "Track propagator is not defined\n";
377  if (etaBinSize_==0) throw cms::Exception("FatalError") << "Eta bin size is not set.\n";
378 }
379 
380 void DetIdAssociator::fillSet( std::set<DetId>& set, unsigned int iEta, unsigned int iPhi) const
381 {
382  unsigned int i = index(iEta,iPhi);
383  unsigned int i0 = lookupMap_.at(i).first;
384  unsigned int size = lookupMap_.at(i).second;
385  for ( i = i0; i < i0+size; ++i )
386  set.insert(container_.at(i));
387 }
388 
391 
394 
395 
396 // 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
list step
Definition: launcher.py:15
double maxZ(bool withTolerance=true) const
FiducialVolume volume_
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
virtual bool nearElement(const GlobalPoint &point, const DetId &id, const double distance) const
#define abs(x)
Definition: mlp_lapack.h:159
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:74
virtual int iPhi(const GlobalPoint &) const
look-up map phi index
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
virtual const char * name() const =0
bool isnan(float x)
Definition: math.h:13
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
int j
Definition: DBlmapReader.cc:9
virtual void check_setup() const
static std::string info(const DetId &)
Definition: DetIdInfo.cc:28
#define LogTrace(id)
#define TYPELOOKUP_DATA_REG(_dataclass_)
Definition: typelookup.h:97
double minR(bool withTolerance=true) const
Definition: DetId.h:20
#define M_PI
Definition: BFit3D.cc:3
virtual const std::vector< DetId > & getValidDetIds(unsigned int subDetectorIndex) const =0
DetIdAssociator(const int nPhi, const int nEta, const double etaBinSize)
T eta() const
Definition: PV3DBase.h:75
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
virtual std::set< DetId > getDetIdsCloseToAPoint(const GlobalPoint &, const int iN=0) const
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
virtual std::pair< const_iterator, const_iterator > getDetIdPoints(const DetId &) const =0
void set(const std::string &name, int value)
set the flag, with a run-time name