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