00001 #include "RecoTauTag/RecoTau/interface/TCTauAlgorithm.h"
00002
00003 #include "DataFormats/TrackReco/interface/Track.h"
00004 #include "DataFormats/VertexReco/interface/Vertex.h"
00005 #include "RecoTauTag/TauTagTools/interface/TauTagTools.h"
00006 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00007
00008 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00009
00010 #include "Math/VectorUtil.h"
00011 using namespace ROOT::Math;
00012
00013 using namespace reco;
00014
00015 TCTauAlgorithm::TCTauAlgorithm(){
00016 init();
00017 }
00018
00019 TCTauAlgorithm::TCTauAlgorithm(const edm::ParameterSet& iConfig){
00020 init();
00021 inputConfig(iConfig);
00022 }
00023
00024 TCTauAlgorithm::~TCTauAlgorithm(){}
00025
00026 void TCTauAlgorithm::init(){
00027
00028 event = 0;
00029 setup = 0;
00030
00031 trackAssociator = new TrackDetectorAssociator();
00032 trackAssociator->useDefaultPropagator();
00033
00034 all = 0;
00035 passed = 0;
00036 prongs = -1;
00037 algoComponentUsed = 0;
00038 }
00039
00040 void TCTauAlgorithm::inputConfig(const edm::ParameterSet& iConfig){
00041
00042 etCaloOverTrackMin = iConfig.getParameter<double>("EtCaloOverTrackMin");
00043 etCaloOverTrackMax = iConfig.getParameter<double>("EtCaloOverTrackMax");
00044 etHcalOverTrackMin = iConfig.getParameter<double>("EtHcalOverTrackMin");
00045 etHcalOverTrackMax = iConfig.getParameter<double>("EtHcalOverTrackMax");
00046
00047 signalCone = iConfig.getParameter<double>("SignalConeSize");
00048 ecalCone = iConfig.getParameter<double>("EcalConeSize");
00049
00050 EcalRecHitsEB_input= iConfig.getParameter<edm::InputTag>("EBRecHitCollection");
00051 EcalRecHitsEE_input= iConfig.getParameter<edm::InputTag>("EERecHitCollection");
00052 HBHERecHits_input = iConfig.getParameter<edm::InputTag>("HBHERecHitCollection");
00053 HORecHits_input = iConfig.getParameter<edm::InputTag>("HORecHitCollection");
00054 HFRecHits_input = iConfig.getParameter<edm::InputTag>("HFRecHitCollection");
00055
00056 edm::ParameterSet pset = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
00057 trackAssociatorParameters.loadParameters( pset );
00058
00059 dropCaloJets = iConfig.getUntrackedParameter<bool>("DropCaloJets",false);
00060 dropRejected = iConfig.getUntrackedParameter<bool>("DropRejectedJets",true);
00061 }
00062
00063
00064 double TCTauAlgorithm::efficiency(){
00065 return double(passed)/all;
00066 }
00067
00068 int TCTauAlgorithm::statistics(){
00069 return passed;
00070 }
00071
00072 int TCTauAlgorithm::allTauCandidates(){
00073 return all;
00074 }
00075
00076 int TCTauAlgorithm::algoComponent(){
00077 return algoComponentUsed;
00078 }
00079
00080 void TCTauAlgorithm::eventSetup(const edm::Event& iEvent,const edm::EventSetup& iSetup){
00081
00082 event = &iEvent;
00083 setup = &iSetup;
00084
00085 edm::ESHandle<TransientTrackBuilder> builder;
00086 iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",builder);
00087 transientTrackBuilder = builder.product();
00088
00089
00090 edm::ESHandle<CaloGeometry> geometry;
00091 iSetup.get<CaloGeometryRecord>().get(geometry);
00092
00093
00094 EB = geometry->getSubdetectorGeometry(DetId::Ecal,EcalBarrel);
00095 EE = geometry->getSubdetectorGeometry(DetId::Ecal,EcalEndcap);
00096 HB = geometry->getSubdetectorGeometry(DetId::Hcal,HcalBarrel);
00097 HE = geometry->getSubdetectorGeometry(DetId::Hcal,HcalEndcap);
00098 HO = geometry->getSubdetectorGeometry(DetId::Hcal,HcalOuter);
00099 HF = geometry->getSubdetectorGeometry(DetId::Hcal,HcalForward);
00100
00101
00102 iEvent.getByLabel( EcalRecHitsEB_input, EBRecHits );
00103 iEvent.getByLabel( EcalRecHitsEE_input, EERecHits );
00104
00105 iEvent.getByLabel( HBHERecHits_input, HBHERecHits );
00106 iEvent.getByLabel( HORecHits_input, HORecHits );
00107 iEvent.getByLabel( HFRecHits_input, HFRecHits );
00108 }
00109
00110
00111 math::XYZTLorentzVector TCTauAlgorithm::recalculateEnergy(const reco::CaloTau& jet){
00112
00113 const TrackRef& leadTk = jet.leadTrack();
00114
00115 const TrackRefVector associatedTracks = jet.caloTauTagInfoRef()->Tracks();
00116
00117 const CaloJet* cJet = jet.caloTauTagInfoRef()->calojetRef().get();
00118 CaloJet caloJet = *cJet;
00119 caloJet.setP4(jet.p4());
00120
00121 return recalculateEnergy(caloJet,leadTk,associatedTracks);
00122 }
00123
00124 math::XYZTLorentzVector TCTauAlgorithm::recalculateEnergy(const reco::CaloJet& caloJet,const TrackRef& leadTk,const TrackRefVector& associatedTracks){
00125
00126 all++;
00127
00128 math::XYZTLorentzVector p4(0,0,0,0);
00129 algoComponentUsed = TCAlgoUndetermined;
00130
00131
00132 p4 = caloJet.p4();
00133
00134 if(leadTk.isNull()) return p4;
00135
00136 XYZVector momentum(0,0,0);
00137 int prongCounter = 0;
00138 edm::RefVector<TrackCollection>::const_iterator iTrack;
00139 for(iTrack = associatedTracks.begin(); iTrack!= associatedTracks.end(); ++iTrack){
00140 double DR = ROOT::Math::VectorUtil::DeltaR(leadTk->momentum(),(*iTrack)->momentum());
00141 if(DR < signalCone) {
00142 momentum+=(*iTrack)->momentum();
00143 prongCounter++;
00144 }
00145 }
00146 if(momentum.Rho() == 0) return p4;
00147
00148 XYZVector ltrackEcalHitPoint = trackEcalHitPoint(*leadTk);
00149
00150 if(! (ltrackEcalHitPoint.Rho() > 0 && ltrackEcalHitPoint.Rho() < 9999) ) return p4;
00151
00152 std::pair<XYZVector,XYZVector> caloClusters = getClusterEnergy(caloJet,ltrackEcalHitPoint,signalCone);
00153 XYZVector EcalCluster = caloClusters.first;
00154 XYZVector HcalCluster = caloClusters.second;
00155
00156 double eCaloOverTrack = (EcalCluster.R()+HcalCluster.R()-momentum.R())/momentum.R();
00157
00158 std::pair<XYZVector,XYZVector> caloClustersPhoton = getClusterEnergy(caloJet,ltrackEcalHitPoint,ecalCone);
00159 XYZVector EcalClusterPhoton = caloClustersPhoton.first;
00160
00161 math::XYZTLorentzVector p4photons(0,0,0,EcalClusterPhoton.R() - EcalCluster.R());
00162
00163 if( eCaloOverTrack > etCaloOverTrackMin && eCaloOverTrack < etCaloOverTrackMax ) {
00164
00165 double eHcalOverTrack = (HcalCluster.R()-momentum.R())/momentum.R();
00166
00167 if ( eHcalOverTrack > etHcalOverTrackMin && eHcalOverTrack < etHcalOverTrackMax ) {
00168 p4.SetXYZT(EcalCluster.X() + momentum.X(),
00169 EcalCluster.Y() + momentum.Y(),
00170 EcalCluster.Z() + momentum.Z(),
00171 EcalCluster.R() + momentum.R());
00172 p4 += p4photons;
00173 algoComponentUsed = TCAlgoMomentumECAL;
00174 }else{
00175 p4.SetXYZT(momentum.X(),
00176 momentum.Y(),
00177 momentum.Z(),
00178 momentum.R());
00179 algoComponentUsed = TCAlgoMomentum;
00180 }
00181 }
00182 if( eCaloOverTrack > etCaloOverTrackMax ) {
00183 double eHcalOverTrack = (HcalCluster.R()-momentum.R())/momentum.R();
00184
00185 if ( eHcalOverTrack > etHcalOverTrackMin && eHcalOverTrack < etHcalOverTrackMax ) {
00186 p4.SetXYZT(EcalCluster.X() + momentum.X(),
00187 EcalCluster.Y() + momentum.Y(),
00188 EcalCluster.Z() + momentum.Z(),
00189 EcalCluster.R() + momentum.R());
00190 p4 += p4photons;
00191 algoComponentUsed = TCAlgoMomentumECAL;
00192 }
00193 if ( eHcalOverTrack < etHcalOverTrackMin ) {
00194 if(!dropCaloJets) p4.SetXYZT(caloJet.px(),caloJet.py(),caloJet.pz(),caloJet.energy());
00195 else p4.SetXYZT(0,0,0,0);
00196 algoComponentUsed = TCAlgoCaloJet;
00197 }
00198 if ( eHcalOverTrack > etHcalOverTrackMax ) {
00199 algoComponentUsed = TCAlgoHadronicJet;
00200 if(!dropRejected) p4.SetXYZT(caloJet.px(),caloJet.py(),caloJet.pz(),caloJet.energy());
00201 else p4.SetXYZT(0,0,0,0);
00202 }
00203 }
00204 if( eCaloOverTrack < etCaloOverTrackMin ) {
00205 algoComponentUsed = TCAlgoTrackProblem;
00206 if(!dropRejected) p4.SetXYZT(caloJet.px(),caloJet.py(),caloJet.pz(),caloJet.energy());
00207 }
00208
00209 if(p4.Et() > 0) passed++;
00210
00211 return p4;
00212 }
00213
00214
00215 XYZVector TCTauAlgorithm::trackEcalHitPoint(const TransientTrack& transientTrack,const CaloJet& caloJet){
00216
00217
00218 GlobalPoint ecalHitPosition(0,0,0);
00219
00220 double maxTowerEt = 0;
00221 std::vector<CaloTowerPtr> towers = caloJet.getCaloConstituents();
00222 for(std::vector<CaloTowerPtr>::const_iterator iTower = towers.begin();
00223 iTower!= towers.end(); ++iTower){
00224 if((*iTower)->et() > maxTowerEt){
00225 maxTowerEt = (*iTower)->et();
00226 ecalHitPosition = (*iTower)->emPosition();
00227 }
00228 }
00229
00230
00231 XYZVector ecalHitPoint(0,0,0);
00232
00233 try{
00234 GlobalPoint trackEcalHitPoint = transientTrack.stateOnSurface(ecalHitPosition).globalPosition();
00235
00236 ecalHitPoint.SetXYZ(trackEcalHitPoint.x(),
00237 trackEcalHitPoint.y(),
00238 trackEcalHitPoint.z());
00239 }catch(...) {;}
00240
00241 return ecalHitPoint;
00242 }
00243
00244 XYZVector TCTauAlgorithm::trackEcalHitPoint(const Track& track){
00245
00246 const FreeTrajectoryState fts = trackAssociator->getFreeTrajectoryState(*setup,track);
00247 TrackDetMatchInfo info = trackAssociator->associate(*event, *setup, fts, trackAssociatorParameters);
00248 if( info.isGoodEcal != 0 ) {
00249 return XYZVector(info.trkGlobPosAtEcal.x(),info.trkGlobPosAtEcal.y(),info.trkGlobPosAtEcal.z());
00250 }
00251 return XYZVector(0,0,0);
00252 }
00253
00254 std::pair<XYZVector,XYZVector> TCTauAlgorithm::getClusterEnergy(const CaloJet& caloJet,XYZVector& trackEcalHitPoint,double cone){
00255
00256 XYZVector ecalCluster(0,0,0);
00257 XYZVector hcalCluster(0,0,0);
00258
00259 std::vector<CaloTowerPtr> towers = caloJet.getCaloConstituents();
00260
00261 for(std::vector<CaloTowerPtr>::const_iterator iTower = towers.begin();
00262 iTower!= towers.end(); ++iTower){
00263 std::vector<XYZVector> ECALCells;
00264 std::vector<XYZVector> HCALCells;
00265
00266 size_t numRecHits = (**iTower).constituentsSize();
00267
00268
00269 for(size_t j = 0; j < numRecHits; j++) {
00270 DetId recHitDetID = (**iTower).constituent(j);
00271
00272 if( recHitDetID.det() == DetId::Ecal ){
00273 if( recHitDetID.subdetId() == 1 ){
00274 EBDetId ecalID = recHitDetID;
00275 EBRecHitCollection::const_iterator theRecHit = EBRecHits->find(ecalID);
00276 if(theRecHit != EBRecHits->end()){
00277 DetId id = theRecHit->detid();
00278 const CaloCellGeometry* this_cell = EB->getGeometry(id);
00279 double energy = theRecHit->energy();
00280 ECALCells.push_back(getCellMomentum(this_cell,energy));
00281 }
00282 }
00283 if( recHitDetID.subdetId() == 2 ){
00284 EEDetId ecalID = recHitDetID;
00285 EERecHitCollection::const_iterator theRecHit = EERecHits->find(ecalID);
00286 if(theRecHit != EERecHits->end()){
00287 DetId id = theRecHit->detid();
00288 const CaloCellGeometry* this_cell = EE->getGeometry(id);
00289 double energy = theRecHit->energy();
00290 ECALCells.push_back(getCellMomentum(this_cell,energy));
00291 }
00292 }
00293 }
00294 if( recHitDetID.det() == DetId::Hcal ){
00295 HcalDetId hcalID = recHitDetID;
00296 if( recHitDetID.subdetId() == HcalBarrel ){
00297
00298
00299 HBHERecHitCollection::const_iterator theRecHit=HBHERecHits->find(hcalID);
00300 if(theRecHit != HBHERecHits->end()){
00301 DetId id = theRecHit->detid();
00302 const CaloCellGeometry* this_cell = HB->getGeometry(id);
00303 double energy = theRecHit->energy();
00304 HCALCells.push_back(getCellMomentum(this_cell,energy));
00305 }
00306
00307 }
00308 if( recHitDetID.subdetId() == HcalEndcap ){
00309
00310
00311 HBHERecHitCollection::const_iterator theRecHit=HBHERecHits->find(hcalID);
00312 if(theRecHit != HBHERecHits->end()){
00313 DetId id = theRecHit->detid();
00314 const CaloCellGeometry* this_cell = HE->getGeometry(id);
00315 double energy = theRecHit->energy();
00316 HCALCells.push_back(getCellMomentum(this_cell,energy));
00317 }
00318
00319 }
00320 if( recHitDetID.subdetId() == HcalOuter ){
00321 HORecHitCollection::const_iterator theRecHit=HORecHits->find(hcalID);
00322 if(theRecHit != HORecHits->end()){
00323 DetId id = theRecHit->detid();
00324 const CaloCellGeometry* this_cell = HO->getGeometry(id);
00325 double energy = theRecHit->energy();
00326 HCALCells.push_back(getCellMomentum(this_cell,energy));
00327 }
00328 }
00329 if( recHitDetID.subdetId() == HcalForward ){
00330 HFRecHitCollection::const_iterator theRecHit=HFRecHits->find(hcalID);
00331 if(theRecHit != HFRecHits->end()){
00332 DetId id = theRecHit->detid();
00333 const CaloCellGeometry* this_cell = HF->getGeometry(id);
00334 double energy = theRecHit->energy();
00335 HCALCells.push_back(getCellMomentum(this_cell,energy));
00336 }
00337 }
00338 }
00339 }
00340
00341 std::vector<XYZVector>::const_iterator i;
00342 for(i = ECALCells.begin(); i != ECALCells.end(); ++i) {
00343 double DR = ROOT::Math::VectorUtil::DeltaR(trackEcalHitPoint,*i);
00344 if( DR < cone ) ecalCluster += *i;
00345 }
00346 for(i = HCALCells.begin(); i != HCALCells.end(); ++i) {
00347 double DR = ROOT::Math::VectorUtil::DeltaR(trackEcalHitPoint,*i);
00348 if( DR < cone ) hcalCluster += *i;
00349 }
00350 }
00351 return std::pair<XYZVector,XYZVector> (ecalCluster,hcalCluster);
00352 }
00353
00354 XYZVector TCTauAlgorithm::getCellMomentum(const CaloCellGeometry* cell,double& energy){
00355 XYZVector momentum(0,0,0);
00356 if(cell){
00357 GlobalPoint hitPosition = cell->getPosition();
00358
00359 double phi = hitPosition.phi();
00360 double theta = hitPosition.theta();
00361 if(theta > 3.14159) theta = 2*3.14159 - theta;
00362 double px = energy * sin(theta)*cos(phi);
00363 double py = energy * sin(theta)*sin(phi);
00364 double pz = energy * cos(theta);
00365
00366 momentum = XYZVector(px,py,pz);
00367 }
00368 return momentum;
00369 }