CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CaloDetIdAssociator.cc
Go to the documentation of this file.
1 #include "CaloDetIdAssociator.h"
4  const GlobalPoint& point2,
5  const DetId& id,
6  const double toleranceInSigmas,
7  const SteppingHelixStateInfo* initialState
8  ) const
9 {
10  const std::pair<const_iterator,const_iterator>& points = getDetIdPoints(id);
11  // fast check
12  bool xLess(false), xIn(false), xMore(false);
13  bool yLess(false), yIn(false), yMore(false);
14  bool zLess(false), zIn(false), zMore(false);
15  double xMin(point1.x()), xMax(point2.x());
16  double yMin(point1.y()), yMax(point2.y());
17  double zMin(point1.z()), zMax(point2.z());
18  if ( xMin>xMax ) std::swap(xMin,xMax);
19  if ( yMin>yMax ) std::swap(yMin,yMax);
20  if ( zMin>zMax ) std::swap(zMin,zMax);
21  for ( std::vector<GlobalPoint>::const_iterator it = points.first;
22  it != points.second; ++it ){
23  if ( it->x()<xMin ){
24  xLess = true;
25  } else {
26  if ( it->x()>xMax )
27  xMore = true;
28  else
29  xIn = true;
30  }
31  if ( it->y()<yMin ){
32  yLess = true;
33  } else {
34  if ( it->y()>yMax )
35  yMore = true;
36  else
37  yIn = true;
38  }
39  if ( it->z()<zMin ){
40  zLess = true;
41  } else {
42  if ( it->z()>zMax )
43  zMore = true;
44  else
45  zIn = true;
46  }
47  }
48  if ( ( (xLess && !xIn && !xMore) || (!xLess && !xIn && xMore) ) ||
49  ( (yLess && !yIn && !yMore) || (!yLess && !yIn && yMore) ) ||
50  ( (zLess && !zIn && !zMore) || (!zLess && !zIn && zMore) ) ) return false;
51 
52  // Define plane normal to the trajectory direction at the first point
53  GlobalVector vector = (point2-point1).unit();
54  float r21 = 0;
55  float r22 = vector.z()/sqrt(1-pow(vector.x(),2));
56  float r23 = -vector.y()/sqrt(1-pow(vector.x(),2));
57  float r31 = vector.x();
58  float r32 = vector.y();
59  float r33 = vector.z();
60  float r11 = r22*r33-r23*r32;
61  float r12 = r23*r31;
62  float r13 = -r22*r31;
63 
64  Surface::RotationType rotation(r11, r12, r13,
65  r21, r22, r23,
66  r31, r32, r33);
67  Plane::PlanePointer plane = Plane::build(point1, rotation);
68  double absoluteTolerance = -1;
69  if ( toleranceInSigmas>0 && initialState ){
70  TrajectoryStateOnSurface tsos = initialState->getStateOnSurface(*plane);
71  if ( tsos.isValid() and tsos.hasError()) {
72  LocalError localErr = tsos.localError().positionError();
73  localErr.scale(toleranceInSigmas);
74  float xx = localErr.xx();
75  float xy = localErr.xy();
76  float yy = localErr.yy();
77 
78  float denom = yy - xx;
79  float phi = 0.;
80  if(xy == 0 && denom==0) phi = M_PI_4;
81  else phi = 0.5 * atan2(2.*xy,denom); // angle of MAJOR axis
82  // Unrotate the error ellipse to get the semimajor and minor axes. Then place points on
83  // the endpoints of semiminor an seminajor axes on original(rotated) error ellipse.
84  LocalError rotErr = localErr.rotate(-phi); // xy covariance of rotErr should be zero
85  float semi1 = sqrt(rotErr.xx());
86  float semi2 = sqrt(rotErr.yy());
87  absoluteTolerance = std::max(semi1,semi2);
88  }
89  }
90 
91  // distance between the points.
92  double trajectorySegmentLength = (point2-point1).mag();
93 
94  // we need to find the angle that covers all points.
95  // if it's bigger than 180 degree, we are inside
96  // otherwise we are outside, i.e. the volume is not crossed
97  bool allBehind = true;
98  bool allTooFar = true;
99  std::vector<GlobalPoint>::const_iterator p = points.first;
100  if ( p == points.second ) {
101  edm::LogWarning("TrackAssociator") << "calo geometry for element " << id.rawId() << "is empty. Ignored";
102  return false;
103  }
104  LocalPoint localPoint = plane->toLocal(*p);
105  double minPhi = localPoint.phi();
106  double maxPhi = localPoint.phi();
107  if ( localPoint.z() < 0 )
108  allTooFar = false;
109  else {
110  allBehind = false;
111  if ( localPoint.z() < trajectorySegmentLength ) allTooFar = false;
112  }
113  ++p;
114  for (; p!=points.second; ++p){
115  localPoint = plane->toLocal(*p);
116  double localPhi = localPoint.phi();
117  if ( localPoint.z() < 0 )
118  allTooFar = false;
119  else {
120  allBehind = false;
121  if ( localPoint.z() < trajectorySegmentLength ) allTooFar = false;
122  }
123  if ( localPhi >= minPhi && localPhi <= maxPhi ) continue;
124  if ( localPhi+2*M_PI >= minPhi && localPhi+2*M_PI <= maxPhi ) continue;
125  if ( localPhi-2*M_PI >= minPhi && localPhi-2*M_PI <= maxPhi ) continue;
126  // find the closest limit
127  if ( localPhi > maxPhi ){
128  double delta1 = fabs(localPhi-maxPhi);
129  double delta2 = fabs(localPhi-2*M_PI-minPhi);
130  if ( delta1 < delta2 )
131  maxPhi = localPhi;
132  else
133  minPhi = localPhi-2*M_PI;
134  continue;
135  }
136  if ( localPhi < minPhi ){
137  double delta1 = fabs(localPhi-minPhi);
138  double delta2 = fabs(localPhi+2*M_PI-maxPhi);
139  if ( delta1 < delta2 )
140  minPhi = localPhi;
141  else
142  maxPhi = localPhi+2*M_PI;
143  continue;
144  }
145  cms::Exception("FatalError") << "Algorithm logic error - this should never happen. Problems with trajectory-volume matching.";
146  }
147  if ( allBehind ) return false;
148  if ( allTooFar ) return false;
149  if ( fabs(maxPhi-minPhi)>M_PI ) return true;
150 
151  // now if the tolerance is positive, check how far we are
152  // from the closest line segment
153  if (absoluteTolerance < 0 ) return false;
154  double distanceToClosestLineSegment = 1e9;
155  std::vector<GlobalPoint>::const_iterator i,j;
156  for ( i = points.first; i != points.second; ++i )
157  for ( j = i+1; j != points.second; ++j )
158  {
159  LocalPoint p1(plane->toLocal(*i));
160  LocalPoint p2(plane->toLocal(*j));
161  // now we deal with high school level math to get
162  // the triangle paramaters
163  double side1squared = p1.perp2();
164  double side2squared = p2.perp2();
165  double side3squared = (p2.x()-p1.x())*(p2.x()-p1.x()) + (p2.y()-p1.y())*(p2.y()-p1.y());
166  double area = fabs(p1.x()*p2.y()-p2.x()*p1.y())/2;
167  // all triangle angles must be smaller than 90 degree
168  // otherwise the projection is out of the line segment
169  if ( side1squared + side2squared > side3squared &&
170  side2squared + side3squared > side1squared &&
171  side1squared + side3squared > side1squared )
172  {
173  double h(2*area/sqrt(side3squared));
174  if ( h < distanceToClosestLineSegment ) distanceToClosestLineSegment = h;
175  }
176  else
177  {
178  if ( sqrt(side1squared) < distanceToClosestLineSegment ) distanceToClosestLineSegment = sqrt(side1squared);
179  if ( sqrt(side2squared) < distanceToClosestLineSegment ) distanceToClosestLineSegment = sqrt(side2squared);
180  }
181  }
182  if ( distanceToClosestLineSegment < absoluteTolerance ) return true;
183  return false;
184 }
185 
187 {
188  edm::ESHandle<CaloGeometry> geometryH;
189  iRecord.getRecord<CaloGeometryRecord>().get(geometryH);
190  setGeometry(geometryH.product());
191 }
192 
194 {
196  if (geometry_==0) throw cms::Exception("CaloGeometry is not set");
197 }
198 
201 }
202 
203 const std::vector<DetId>& CaloDetIdAssociator::getValidDetIds(unsigned int subDectorIndex) const
204 {
205  if ( subDectorIndex!=0 ) cms::Exception("FatalError") << "Calo sub-dectors are all handle as one sub-system, but subDetectorIndex is not zero.\n";
207 }
208 
209 std::pair<DetIdAssociator::const_iterator, DetIdAssociator::const_iterator>
211 {
213  if(! subDetGeom){
214  LogDebug("TrackAssociator") << "Cannot find sub-detector geometry for " << id.rawId() <<"\n";
215  return std::pair<const_iterator,const_iterator>(dummy_.end(),dummy_.end());
216  }
217  const CaloCellGeometry* cellGeom = subDetGeom->getGeometry(id);
218  if(! cellGeom) {
219  LogDebug("TrackAssociator") << "Cannot find CaloCell geometry for " << id.rawId() <<"\n";
220  return std::pair<const_iterator,const_iterator>(dummy_.end(),dummy_.end());
221  }
222  const CaloCellGeometry::CornersVec& cor (cellGeom->getCorners() ) ;
223  return std::pair<const_iterator,const_iterator>( cor.begin(), cor.end() ) ;
224 }
#define LogDebug(id)
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:43
int i
Definition: DBlmapReader.cc:9
float xx() const
Definition: LocalError.h:24
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
T y() const
Definition: PV3DBase.h:62
static PlanePointer build(const PositionType &pos, const RotationType &rot, MediumProperties *mp=0)
Definition: Plane.h:25
const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
LocalError positionError() const
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
virtual GlobalPoint getPosition(const DetId &id) const
float xy() const
Definition: LocalError.h:25
float yy() const
Definition: LocalError.h:26
const T & max(const T &a, const T &b)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
string unit
Definition: csvLumiCalc.py:46
TrajectoryStateOnSurface getStateOnSurface(const Surface &surf, bool returnTangentPlane=false) const
T sqrt(T t)
Definition: SSEVec.h:46
T z() const
Definition: PV3DBase.h:63
int j
Definition: DBlmapReader.cc:9
virtual void check_setup() const
const LocalTrajectoryError & localError() const
virtual std::pair< const_iterator, const_iterator > getDetIdPoints(const DetId &id) const
double p2[4]
Definition: TauolaWrapper.h:90
std::vector< GlobalPoint > dummy_
virtual void check_setup() const
const CaloGeometry * geometry_
Definition: DetId.h:20
#define M_PI
Definition: BFit3D.cc:3
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
virtual bool crossedElement(const GlobalPoint &, const GlobalPoint &, const DetId &id, const double tolerance=-1, const SteppingHelixStateInfo *=0) const
T const * product() const
Definition: ESHandle.h:62
std::vector< DetId > getValidDetIds() const
Get the list of all valid detector ids.
Definition: CaloGeometry.cc:90
double p1[4]
Definition: TauolaWrapper.h:89
virtual void setGeometry(const CaloGeometry *ptr)
LocalError rotate(float x, float y) const
Return a new LocalError, rotated by an angle defined by the direction (x,y)
Definition: LocalError.h:39
T x() const
Definition: PV3DBase.h:61
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
virtual const CornersVec & getCorners() const =0
Returns the corner points of this cell&#39;s volume.
LocalError scale(float s) const
Definition: LocalError.h:33
virtual const std::vector< DetId > & getValidDetIds(unsigned int subDetectorIndex) const
Definition: DDAxes.h:10