00001 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00002 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00003
00004 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00005 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00006 #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h"
00007 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00008 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixStateInfo.h"
00009 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00010
00011 #include "RecoEcal/EgammaCoreTools/interface/EcalRecHitLess.h"
00012 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgo.h"
00013
00014 #include "SUSYBSMAnalysis/HSCP/interface/BetaCalculatorECAL.h"
00015
00016 BetaCalculatorECAL::BetaCalculatorECAL(const edm::ParameterSet& iConfig) :
00017 EBRecHitCollection_ (iConfig.getParameter<edm::InputTag>("EBRecHitCollection")),
00018 EERecHitCollection_ (iConfig.getParameter<edm::InputTag>("EERecHitCollection"))
00019 {
00020 edm::ParameterSet trkParameters = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
00021 parameters_.loadParameters( trkParameters );
00022 trackAssociator_.useDefaultPropagator();
00023
00024 }
00025
00026
00027 void BetaCalculatorECAL::addInfoToCandidate(HSCParticle& candidate, edm::Handle<reco::TrackCollection>& tracks, edm::Event& iEvent, const edm::EventSetup& iSetup, HSCPCaloInfo& caloInfo) {
00028 bool setCalo = false;
00029 HSCPCaloInfo result;
00030
00031
00032 iSetup.get<DetIdAssociatorRecord>().get("EcalDetIdAssociator", ecalDetIdAssociator_);
00033
00034 iSetup.get<IdealMagneticFieldRecord>().get(bField_);
00035
00036 iSetup.get<CaloGeometryRecord>().get(theCaloGeometry_);
00037 const CaloGeometry* theGeometry = theCaloGeometry_.product();
00038
00039 edm::ESHandle<CaloTopology> pCaloTopology;
00040 iSetup.get<CaloTopologyRecord>().get(pCaloTopology);
00041 const CaloTopology* theCaloTopology = pCaloTopology.product();
00042
00043 edm::Handle<EBRecHitCollection> ebRecHits;
00044 iEvent.getByLabel(EBRecHitCollection_,ebRecHits);
00045 edm::Handle<EERecHitCollection> eeRecHits;
00046 iEvent.getByLabel(EERecHitCollection_,eeRecHits);
00047
00048
00049 reco::Track track;
00050 if(candidate.hasTrackRef())
00051 track = *(candidate.trackRef());
00052 else
00053 return;
00054
00055
00056 result.trkIsoDr=100;
00057 for(reco::TrackCollection::const_iterator ndTrack = tracks->begin(); ndTrack != tracks->end(); ++ndTrack) {
00058 double dr=sqrt(pow((track.outerEta()-ndTrack->outerEta()),2)+pow((track.outerPhi()-ndTrack->outerPhi()),2));
00059 if(dr>0.00001 && dr<result.trkIsoDr) result.trkIsoDr=dr;
00060 }
00061
00062
00063 TrackDetMatchInfo info = trackAssociator_.associate( iEvent, iSetup,
00064 trackAssociator_.getFreeTrajectoryState(iSetup, track),
00065 parameters_ );
00066
00067
00068 std::map<int,GlobalPoint> trackExitPositionMap;
00069 std::map<int,float> trackCrossedXtalCurvedMap;
00070 TrajectoryStateTransform tsTransform;
00071 FreeTrajectoryState tkInnerState = tsTransform.innerFreeState(track, &*bField_);
00072
00073 std::vector<SteppingHelixStateInfo> neckLace;
00074 neckLace = calcEcalDeposit(&tkInnerState,*ecalDetIdAssociator_);
00075
00076 double totalLengthCurved = 0.;
00077 GlobalPoint internalPointCurved(0., 0., 0.);
00078 GlobalPoint externalPointCurved(0., 0., 0.);
00079 if(neckLace.size() > 1)
00080 {
00081 getDetailedTrackLengthInXtals(trackExitPositionMap,
00082 trackCrossedXtalCurvedMap,
00083 totalLengthCurved,
00084 internalPointCurved,
00085 externalPointCurved,
00086 & (*theGeometry),
00087 & (*theCaloTopology),
00088 neckLace);
00089 }
00090 int numCrysCrossed = -1;
00091 numCrysCrossed = trackCrossedXtalCurvedMap.size();
00092
00093
00094 float sumWeightedTime = 0;
00095 float sumTimeErrorSqr = 0;
00096 float sumEnergy = 0;
00097 float sumTrackLength = 0;
00098 std::vector<EcalRecHit> crossedRecHits;
00099 EcalRecHitCollection::const_iterator thisHit;
00100
00101 std::map<int,GlobalPoint>::const_iterator trackExitMapIt = trackExitPositionMap.begin();
00102 for(std::map<int,float>::const_iterator mapIt = trackCrossedXtalCurvedMap.begin();
00103 mapIt != trackCrossedXtalCurvedMap.end(); ++mapIt)
00104 {
00105 if(DetId(mapIt->first).subdetId()==EcalBarrel)
00106 {
00107 EBDetId ebDetId(mapIt->first);
00108 thisHit = ebRecHits->find(ebDetId);
00109 if(thisHit == ebRecHits->end())
00110 {
00111
00112 continue;
00113 }
00114 const EcalRecHit hit = *thisHit;
00115
00116 if(!hit.isTimeValid())
00117 continue;
00118 uint32_t rhFlag = hit.recoFlag();
00119 if((rhFlag != EcalRecHit::kGood) && (rhFlag != EcalRecHit::kOutOfTime) && (rhFlag != EcalRecHit::kPoorCalib))
00120 continue;
00121
00122 float errorOnThis = hit.timeError();
00123 sumTrackLength+=mapIt->second;
00124 sumEnergy+=hit.energy();
00125 crossedRecHits.push_back(hit);
00126
00127
00128 result.ecalTrackLengths.push_back(mapIt->second);
00129 result.ecalTrackExitPositions.push_back(trackExitMapIt->second);
00130 result.ecalEnergies.push_back(hit.energy());
00131 result.ecalTimes.push_back(hit.time());
00132 result.ecalTimeErrors.push_back(hit.timeError());
00133 result.ecalOutOfTimeEnergies.push_back(hit.outOfTimeEnergy());
00134 result.ecalOutOfTimeChi2s.push_back(hit.outOfTimeChi2());
00135 result.ecalChi2s.push_back(hit.chi2());
00136 result.ecalDetIds.push_back(ebDetId);
00137
00138
00139
00140
00141 if(hit.isTimeErrorValid())
00142 {
00143 sumWeightedTime+=hit.time()/(errorOnThis*errorOnThis);
00144 sumTimeErrorSqr+=1/(errorOnThis*errorOnThis);
00145 }
00146 }
00147 trackExitMapIt++;
00148 }
00149
00150 if(crossedRecHits.size() > 0)
00151 {
00152 setCalo = true;
00153 sort(crossedRecHits.begin(),crossedRecHits.end(),EcalRecHitLess());
00154 result.ecalCrossedEnergy = sumEnergy;
00155 result.ecalCrysCrossed = crossedRecHits.size();
00156 result.ecalDeDx = sumEnergy/sumTrackLength;
00157
00158 result.ecal3by3dir = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 1);
00159 result.ecal5by5dir = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 2);
00160
00161 if(sumTimeErrorSqr > 0)
00162 {
00163 result.ecalTime = sumWeightedTime/sumTimeErrorSqr;
00164 result.ecalTimeError = sqrt(1/sumTimeErrorSqr);
00165 DetId maxEnergyId = crossedRecHits.begin()->id();
00166
00167 if(maxEnergyId != DetId())
00168 {
00169
00170
00171 GlobalPoint position = info.getPosition(maxEnergyId);
00172 double frontFaceR = sqrt(pow(position.x(),2)+pow(position.y(),2)+pow(position.z(),2));
00173 double muonShowerMax = frontFaceR+11.5;
00174 double gammaShowerMax = frontFaceR+6.23;
00175 double speedOfLight = 29.979;
00176 result.ecalBeta = (muonShowerMax)/(result.ecalTime*speedOfLight+gammaShowerMax);
00177 result.ecalBetaError = (speedOfLight*muonShowerMax*result.ecalTimeError)/pow(speedOfLight*result.ecalTime+gammaShowerMax,2);
00178 result.ecalInvBetaError = speedOfLight*result.ecalTimeError/muonShowerMax;
00179 }
00180
00181
00182
00183
00184
00185 }
00186 }
00187
00188 if(info.crossedHcalRecHits.size() > 0)
00189 {
00190
00191 result.hcalCrossedEnergy = info.crossedEnergy(TrackDetMatchInfo::HcalRecHits);
00192 result.hoCrossedEnergy = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
00193
00194 result.hcal3by3dir = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits, 1);
00195 result.hcal5by5dir = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits, 2);
00196 }
00197
00198 if(setCalo)
00199 caloInfo = result;
00200 }
00201
00202 std::vector<SteppingHelixStateInfo> BetaCalculatorECAL::calcEcalDeposit(const FreeTrajectoryState* tkInnerState,
00203 const DetIdAssociator& associator)
00204 {
00205
00206 double minR = associator.volume().minR () ;
00207 double minZ = associator.volume().minZ () ;
00208 double maxR = associator.volume().maxR () ;
00209 double maxZ = associator.volume().maxZ () ;
00210
00211
00212 SteppingHelixStateInfo trackOrigin(*tkInnerState);
00213
00214
00215 SteppingHelixPropagator* prop = new SteppingHelixPropagator (&*bField_, alongMomentum);
00216 prop -> setMaterialMode(false);
00217 prop -> applyRadX0Correction(true);
00218
00219
00220 CachedTrajectory neckLace;
00221 neckLace.setStateAtIP(trackOrigin);
00222 neckLace.reset_trajectory();
00223 neckLace.setPropagator(prop);
00224 neckLace.setPropagationStep(0.1);
00225 neckLace.setMinDetectorRadius(minR);
00226 neckLace.setMinDetectorLength(minZ*2.);
00227 neckLace.setMaxDetectorRadius(maxR);
00228 neckLace.setMaxDetectorLength(maxZ*2.);
00229
00230
00231 bool isPropagationSuccessful = neckLace.propagateAll(trackOrigin);
00232
00233 if (!isPropagationSuccessful)
00234 {
00235
00236
00237 return std::vector<SteppingHelixStateInfo> () ;
00238 }
00239
00240 std::vector<SteppingHelixStateInfo> complicatePoints;
00241 neckLace.getTrajectory(complicatePoints, associator.volume(), 500);
00242
00243
00244 return complicatePoints;
00245 }
00246
00247 int BetaCalculatorECAL::getDetailedTrackLengthInXtals(std::map<int,GlobalPoint>& trackExitPositionMap,
00248 std::map<int,float>& trackCrossedXtalMap,
00249 double& totalLengthCurved,
00250 GlobalPoint& internalPointCurved,
00251 GlobalPoint& externalPointCurved,
00252 const CaloGeometry* theGeometry,
00253 const CaloTopology* theTopology,
00254 const std::vector<SteppingHelixStateInfo>& neckLace)
00255 {
00256 GlobalPoint origin (0., 0., 0.);
00257 internalPointCurved = origin ;
00258 externalPointCurved = origin ;
00259
00260 bool firstPoint = false;
00261 trackCrossedXtalMap.clear();
00262
00263 const CaloSubdetectorGeometry* theBarrelSubdetGeometry = theGeometry->getSubdetectorGeometry(DetId::Ecal,1);
00264 const CaloSubdetectorGeometry* theEndcapSubdetGeometry = theGeometry->getSubdetectorGeometry(DetId::Ecal,2);
00265
00266 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = (neckLace.begin() + 1); itr != neckLace.end(); ++itr)
00267 {
00268 GlobalPoint probe_gp = (*itr).position();
00269 GlobalVector probe_gv = (*itr).momentum();
00270 std::vector<DetId> surroundingMatrix;
00271
00272 EBDetId closestBarrelDetIdToProbe = ((theBarrelSubdetGeometry -> getClosestCell(probe_gp)).rawId());
00273 EEDetId closestEndcapDetIdToProbe = ((theEndcapSubdetGeometry -> getClosestCell(probe_gp)).rawId());
00274
00275
00276 if( (closestEndcapDetIdToProbe) && (theGeometry->getSubdetectorGeometry(closestEndcapDetIdToProbe)->
00277 getGeometry(closestEndcapDetIdToProbe)->inside(probe_gp)) )
00278 {
00279 double step = ((*itr).position() - (*(itr-1)).position()).mag();
00280 GlobalPoint point = itr->position();
00281 addStepToXtal(trackExitPositionMap, trackCrossedXtalMap, closestEndcapDetIdToProbe, step, point, theEndcapSubdetGeometry);
00282 totalLengthCurved += step;
00283
00284 if (firstPoint == false)
00285 {
00286 internalPointCurved = probe_gp ;
00287 firstPoint = true ;
00288 }
00289
00290 externalPointCurved = probe_gp ;
00291 }
00292
00293 if( (closestBarrelDetIdToProbe) && (theGeometry->getSubdetectorGeometry(closestBarrelDetIdToProbe)->
00294 getGeometry(closestBarrelDetIdToProbe)->inside(probe_gp)) )
00295 {
00296 double step = ((*itr).position() - (*(itr-1)).position()).mag();
00297 GlobalPoint point = itr->position();
00298 addStepToXtal(trackExitPositionMap, trackCrossedXtalMap, closestBarrelDetIdToProbe, step, point, theBarrelSubdetGeometry);
00299 totalLengthCurved += step;
00300
00301 if (firstPoint == false)
00302 {
00303 internalPointCurved = probe_gp ;
00304 firstPoint = true ;
00305 }
00306
00307 externalPointCurved = probe_gp ;
00308 }
00309 else
00310 {
00311
00312 surroundingMatrix = theTopology->getSubdetectorTopology(closestBarrelDetIdToProbe)->getWindow(closestBarrelDetIdToProbe,3,3);
00313
00314 for( unsigned int k=0; k<surroundingMatrix.size(); ++k ) {
00315 if(theGeometry->getSubdetectorGeometry(surroundingMatrix.at(k))->getGeometry(surroundingMatrix.at(k))->inside(probe_gp))
00316 {
00317 double step = ((*itr).position() - (*(itr-1)).position()).mag();
00318 GlobalPoint point = itr->position();
00319 addStepToXtal(trackExitPositionMap, trackCrossedXtalMap, surroundingMatrix[k], step,
00320 point, theGeometry->getSubdetectorGeometry(surroundingMatrix.at(k)));
00321 totalLengthCurved += step;
00322
00323 if (firstPoint == false)
00324 {
00325 internalPointCurved = probe_gp ;
00326 firstPoint = true ;
00327 }
00328
00329 externalPointCurved = probe_gp ;
00330 }
00331 }
00332
00333
00334 surroundingMatrix.clear();
00335 }
00336 }
00337
00338 return 0;
00339 }
00340
00341 void BetaCalculatorECAL::addStepToXtal(std::map<int,GlobalPoint>& trackExitPositionMap,
00342 std::map<int,float>& trackCrossedXtalMap,
00343 DetId aDetId,
00344 float step,
00345 GlobalPoint point,
00346 const CaloSubdetectorGeometry* theSubdetGeometry)
00347 {
00348
00349 const CaloCellGeometry *cell_p = theSubdetGeometry->getGeometry(aDetId);
00350 GlobalPoint p = (dynamic_cast <const TruncatedPyramid *> (cell_p))->getPosition(23);
00351 GlobalPoint diff(point.x()-p.x(),point.y()-p.y(),point.z()-p.z());
00352
00353 std::map<int,GlobalPoint>::iterator xtal = trackExitPositionMap.find(aDetId.rawId());
00354 if (xtal!=trackExitPositionMap.end())
00355 ((*xtal).second)=diff;
00356 else
00357 trackExitPositionMap.insert(std::pair<int,GlobalPoint>(aDetId.rawId(),diff));
00358
00359 std::map<int,float>::iterator xtal2 = trackCrossedXtalMap.find(aDetId.rawId());
00360 if (xtal2!= trackCrossedXtalMap.end())
00361 ((*xtal2).second)+=step;
00362 else
00363 trackCrossedXtalMap.insert(std::pair<int,float>(aDetId.rawId(),step));
00364 }
00365
00366
00367