Go to the documentation of this file.00001 #include "CaloDetIdAssociator.h"
00002 #include "DataFormats/GeometrySurface/interface/Plane.h"
00003 bool CaloDetIdAssociator::crossedElement(const GlobalPoint& point1,
00004 const GlobalPoint& point2,
00005 const DetId& id,
00006 const double toleranceInSigmas,
00007 const SteppingHelixStateInfo* initialState
00008 ) const
00009 {
00010 const std::pair<const_iterator,const_iterator>& points = getDetIdPoints(id);
00011
00012 bool xLess(false), xIn(false), xMore(false);
00013 bool yLess(false), yIn(false), yMore(false);
00014 bool zLess(false), zIn(false), zMore(false);
00015 double xMin(point1.x()), xMax(point2.x());
00016 double yMin(point1.y()), yMax(point2.y());
00017 double zMin(point1.z()), zMax(point2.z());
00018 if ( xMin>xMax ) std::swap(xMin,xMax);
00019 if ( yMin>yMax ) std::swap(yMin,yMax);
00020 if ( zMin>zMax ) std::swap(zMin,zMax);
00021 for ( std::vector<GlobalPoint>::const_iterator it = points.first;
00022 it != points.second; ++it ){
00023 if ( it->x()<xMin ){
00024 xLess = true;
00025 } else {
00026 if ( it->x()>xMax )
00027 xMore = true;
00028 else
00029 xIn = true;
00030 }
00031 if ( it->y()<yMin ){
00032 yLess = true;
00033 } else {
00034 if ( it->y()>yMax )
00035 yMore = true;
00036 else
00037 yIn = true;
00038 }
00039 if ( it->z()<zMin ){
00040 zLess = true;
00041 } else {
00042 if ( it->z()>zMax )
00043 zMore = true;
00044 else
00045 zIn = true;
00046 }
00047 }
00048 if ( ( (xLess && !xIn && !xMore) || (!xLess && !xIn && xMore) ) ||
00049 ( (yLess && !yIn && !yMore) || (!yLess && !yIn && yMore) ) ||
00050 ( (zLess && !zIn && !zMore) || (!zLess && !zIn && zMore) ) ) return false;
00051
00052
00053 GlobalVector vector = (point2-point1).unit();
00054 float r21 = 0;
00055 float r22 = vector.z()/sqrt(1-pow(vector.x(),2));
00056 float r23 = -vector.y()/sqrt(1-pow(vector.x(),2));
00057 float r31 = vector.x();
00058 float r32 = vector.y();
00059 float r33 = vector.z();
00060 float r11 = r22*r33-r23*r32;
00061 float r12 = r23*r31;
00062 float r13 = -r22*r31;
00063
00064 Surface::RotationType rotation(r11, r12, r13,
00065 r21, r22, r23,
00066 r31, r32, r33);
00067 Plane::PlanePointer plane = Plane::build(point1, rotation);
00068 double absoluteTolerance = -1;
00069 if ( toleranceInSigmas>0 && initialState ){
00070 TrajectoryStateOnSurface tsos = initialState->getStateOnSurface(*plane);
00071 if ( tsos.isValid() and tsos.hasError()) {
00072 LocalError localErr = tsos.localError().positionError();
00073 localErr.scale(toleranceInSigmas);
00074 float xx = localErr.xx();
00075 float xy = localErr.xy();
00076 float yy = localErr.yy();
00077
00078 float denom = yy - xx;
00079 float phi = 0.;
00080 if(xy == 0 && denom==0) phi = M_PI_4;
00081 else phi = 0.5 * atan2(2.*xy,denom);
00082
00083
00084 LocalError rotErr = localErr.rotate(-phi);
00085 float semi1 = sqrt(rotErr.xx());
00086 float semi2 = sqrt(rotErr.yy());
00087 absoluteTolerance = std::max(semi1,semi2);
00088 }
00089 }
00090
00091
00092 double trajectorySegmentLength = (point2-point1).mag();
00093
00094
00095
00096
00097 bool allBehind = true;
00098 bool allTooFar = true;
00099 std::vector<GlobalPoint>::const_iterator p = points.first;
00100 if ( p == points.second ) {
00101 edm::LogWarning("TrackAssociator") << "calo geometry for element " << id.rawId() << "is empty. Ignored";
00102 return false;
00103 }
00104 LocalPoint localPoint = plane->toLocal(*p);
00105 double minPhi = localPoint.phi();
00106 double maxPhi = localPoint.phi();
00107 if ( localPoint.z() < 0 )
00108 allTooFar = false;
00109 else {
00110 allBehind = false;
00111 if ( localPoint.z() < trajectorySegmentLength ) allTooFar = false;
00112 }
00113 ++p;
00114 for (; p!=points.second; ++p){
00115 localPoint = plane->toLocal(*p);
00116 double localPhi = localPoint.phi();
00117 if ( localPoint.z() < 0 )
00118 allTooFar = false;
00119 else {
00120 allBehind = false;
00121 if ( localPoint.z() < trajectorySegmentLength ) allTooFar = false;
00122 }
00123 if ( localPhi >= minPhi && localPhi <= maxPhi ) continue;
00124 if ( localPhi+2*M_PI >= minPhi && localPhi+2*M_PI <= maxPhi ) continue;
00125 if ( localPhi-2*M_PI >= minPhi && localPhi-2*M_PI <= maxPhi ) continue;
00126
00127 if ( localPhi > maxPhi ){
00128 double delta1 = fabs(localPhi-maxPhi);
00129 double delta2 = fabs(localPhi-2*M_PI-minPhi);
00130 if ( delta1 < delta2 )
00131 maxPhi = localPhi;
00132 else
00133 minPhi = localPhi-2*M_PI;
00134 continue;
00135 }
00136 if ( localPhi < minPhi ){
00137 double delta1 = fabs(localPhi-minPhi);
00138 double delta2 = fabs(localPhi+2*M_PI-maxPhi);
00139 if ( delta1 < delta2 )
00140 minPhi = localPhi;
00141 else
00142 maxPhi = localPhi+2*M_PI;
00143 continue;
00144 }
00145 cms::Exception("FatalError") << "Algorithm logic error - this should never happen. Problems with trajectory-volume matching.";
00146 }
00147 if ( allBehind ) return false;
00148 if ( allTooFar ) return false;
00149 if ( fabs(maxPhi-minPhi)>M_PI ) return true;
00150
00151
00152
00153 if (absoluteTolerance < 0 ) return false;
00154 double distanceToClosestLineSegment = 1e9;
00155 std::vector<GlobalPoint>::const_iterator i,j;
00156 for ( i = points.first; i != points.second; ++i )
00157 for ( j = i+1; j != points.second; ++j )
00158 {
00159 LocalPoint p1(plane->toLocal(*i));
00160 LocalPoint p2(plane->toLocal(*j));
00161
00162
00163 double side1squared = p1.perp2();
00164 double side2squared = p2.perp2();
00165 double side3squared = (p2.x()-p1.x())*(p2.x()-p1.x()) + (p2.y()-p1.y())*(p2.y()-p1.y());
00166 double area = fabs(p1.x()*p2.y()-p2.x()*p1.y())/2;
00167
00168
00169 if ( side1squared + side2squared > side3squared &&
00170 side2squared + side3squared > side1squared &&
00171 side1squared + side3squared > side1squared )
00172 {
00173 double h(2*area/sqrt(side3squared));
00174 if ( h < distanceToClosestLineSegment ) distanceToClosestLineSegment = h;
00175 }
00176 else
00177 {
00178 if ( sqrt(side1squared) < distanceToClosestLineSegment ) distanceToClosestLineSegment = sqrt(side1squared);
00179 if ( sqrt(side2squared) < distanceToClosestLineSegment ) distanceToClosestLineSegment = sqrt(side2squared);
00180 }
00181 }
00182 if ( distanceToClosestLineSegment < absoluteTolerance ) return true;
00183 return false;
00184 }
00185
00186 void CaloDetIdAssociator::setGeometry(const DetIdAssociatorRecord& iRecord)
00187 {
00188 edm::ESHandle<CaloGeometry> geometryH;
00189 iRecord.getRecord<CaloGeometryRecord>().get(geometryH);
00190 setGeometry(geometryH.product());
00191 }
00192
00193 void CaloDetIdAssociator::check_setup() const
00194 {
00195 DetIdAssociator::check_setup();
00196 if (geometry_==0) throw cms::Exception("CaloGeometry is not set");
00197 }
00198
00199 GlobalPoint CaloDetIdAssociator::getPosition(const DetId& id) const {
00200 return geometry_->getSubdetectorGeometry(id)->getGeometry(id)->getPosition();
00201 }
00202
00203 const std::vector<DetId>& CaloDetIdAssociator::getValidDetIds(unsigned int subDectorIndex) const
00204 {
00205 if ( subDectorIndex!=0 ) cms::Exception("FatalError") << "Calo sub-dectors are all handle as one sub-system, but subDetectorIndex is not zero.\n";
00206 return geometry_->getValidDetIds(DetId::Calo, 1);
00207 }
00208
00209 std::pair<DetIdAssociator::const_iterator, DetIdAssociator::const_iterator>
00210 CaloDetIdAssociator::getDetIdPoints(const DetId& id) const
00211 {
00212 const CaloSubdetectorGeometry* subDetGeom = geometry_->getSubdetectorGeometry(id);
00213 if(! subDetGeom){
00214 LogDebug("TrackAssociator") << "Cannot find sub-detector geometry for " << id.rawId() <<"\n";
00215 return std::pair<const_iterator,const_iterator>(dummy_.end(),dummy_.end());
00216 }
00217 const CaloCellGeometry* cellGeom = subDetGeom->getGeometry(id);
00218 if(! cellGeom) {
00219 LogDebug("TrackAssociator") << "Cannot find CaloCell geometry for " << id.rawId() <<"\n";
00220 return std::pair<const_iterator,const_iterator>(dummy_.end(),dummy_.end());
00221 }
00222 const CaloCellGeometry::CornersVec& cor (cellGeom->getCorners() ) ;
00223 return std::pair<const_iterator,const_iterator>( cor.begin(), cor.end() ) ;
00224 }