CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DQMOffline/JetMET/src/JPTJetAnalyzer.cc

Go to the documentation of this file.
00001 #include "DQMOffline/JetMET/interface/JPTJetAnalyzer.h"
00002 #include "DQMServices/Core/interface/MonitorElement.h"
00003 #include "DQMServices/Core/interface/DQMStore.h"
00004 #include "DataFormats/TrackReco/interface/Track.h"
00005 #include "DataFormats/JetReco/interface/CaloJet.h"
00006 #include "FWCore/Framework/interface/Event.h"
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "DataFormats/Common/interface/Handle.h"
00011 #include "FWCore/Framework/interface/ESHandle.h"
00012 #include "DataFormats/Math/interface/deltaR.h"
00013 #include "RecoJets/JetAssociationAlgorithms/interface/JetTracksAssociationDRCalo.h"
00014 #include "DataFormats/Math/interface/Point3D.h"
00015 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00016 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00017 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00018 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
00019 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
00020 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h"
00021 #include "DataFormats/TrackingRecHit/interface/InvalidTrackingRecHit.h"
00022 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
00023 #include "DataFormats/DetId/interface/DetId.h"
00024 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
00025 #include "CalibFormats/SiStripObjects/interface/SiStripQuality.h"
00026 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
00027 #include "CalibFormats/SiStripObjects/interface/SiStripGain.h"
00028 #include "CalibTracker/Records/interface/SiStripQualityRcd.h"
00029 #include "CondFormats/DataRecord/interface/SiStripNoisesRcd.h"
00030 #include "CalibTracker/Records/interface/SiStripGainRcd.h"
00031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00032 #include "RecoJets/JetProducers/interface/JetIDHelper.h"
00033 #include <cmath>
00034 #include <string>
00035 #include <memory>
00036 #include <vector>
00037 
00038 namespace jptJetAnalysis {
00039   
00040   // Helpper class to propagate tracks to the calo surface using the same implementation as the JetTrackAssociator
00041   class TrackPropagatorToCalo
00042   {
00043    public:
00044     TrackPropagatorToCalo();
00045     void update(const edm::EventSetup& eventSetup);
00046     math::XYZPoint impactPoint(const reco::Track& track) const;
00047    private:
00048     const MagneticField* magneticField_;
00049     const Propagator* propagator_;
00050     uint32_t magneticFieldCacheId_;
00051     uint32_t propagatorCacheId_;
00052   };
00053   
00054   // Helpper class to calculate strip signal to noise and manage the necessary ES objects
00055   class StripSignalOverNoiseCalculator
00056   {
00057    public:
00058     StripSignalOverNoiseCalculator(const std::string& theQualityLabel = std::string(""));
00059     void update(const edm::EventSetup& eventSetup);
00060     double signalOverNoise(const SiStripCluster& cluster) const;
00061     double operator () (const SiStripCluster& cluster) const
00062       { return signalOverNoise(cluster); }
00063    private:
00064     const std::string qualityLabel_;
00065     const SiStripQuality* quality_;
00066     const SiStripNoises* noise_;
00067     const SiStripGain* gain_;
00068     uint32_t qualityCacheId_;
00069     uint32_t noiseCacheId_;
00070     uint32_t gainCacheId_;
00071   };
00072   
00073 }
00074 
00075 const char* JPTJetAnalyzer::messageLoggerCatregory = "JetPlusTrackDQM";
00076 
00077 JPTJetAnalyzer::JPTJetAnalyzer(const edm::ParameterSet& config)
00078   : histogramPath_(config.getParameter<std::string>("HistogramPath")),
00079     verbose_(config.getUntrackedParameter<bool>("PrintDebugMessages",false)),
00080     writeDQMStore_(config.getUntrackedParameter<bool>("WriteDQMStore")),
00081     dqmStoreFileName_(),
00082     n90HitsMin_(config.getParameter<int>("n90HitsMin")),
00083     fHPDMax_(config.getParameter<double>("fHPDMax")),
00084     resEMFMin_(config.getParameter<double>("resEMFMin")),
00085     correctedPtMin_(config.getParameter<double>("correctedPtThreshold")),
00086     trackPropagator_(new jptJetAnalysis::TrackPropagatorToCalo),
00087     sOverNCalculator_(new jptJetAnalysis::StripSignalOverNoiseCalculator),
00088     jetID_(new reco::helper::JetIDHelper(config.getParameter<edm::ParameterSet>("JetIDParams")))
00089 {
00090   //print config to debug log
00091   std::ostringstream debugStream;
00092   if (verbose_) {
00093     debugStream << "Configuration for JPTJetAnalyzer: " << std::endl
00094                 << "\tHistogramPath: " << histogramPath_ << std::endl
00095                 << "\tPrintDebugMessages? " << (verbose_ ? "yes" : "no") << std::endl;
00096   }
00097   if (writeDQMStore_) {
00098     dqmStoreFileName_ = config.getUntrackedParameter<std::string>("DQMStoreFileName");
00099   }
00100   
00101   //don't generate debug mesages if debug is disabled
00102   std::ostringstream* pDebugStream = (verbose_ ? &debugStream : NULL);
00103   
00104   //get histogram configuration
00105   getConfigForHistogram("E",config,pDebugStream);
00106   getConfigForHistogram("Et",config,pDebugStream);
00107   getConfigForHistogram("P",config,pDebugStream);
00108   getConfigForHistogram("Mass",config,pDebugStream);
00109   getConfigForHistogram("Pt",config,pDebugStream);
00110   getConfigForHistogram("Pt1",config,pDebugStream);
00111   getConfigForHistogram("Pt2",config,pDebugStream);
00112   getConfigForHistogram("Pt3",config,pDebugStream);
00113   getConfigForHistogram("Px",config,pDebugStream);
00114   getConfigForHistogram("Py",config,pDebugStream);
00115   getConfigForHistogram("Pz",config,pDebugStream);
00116   getConfigForHistogram("Eta",config,pDebugStream);
00117   getConfigForHistogram("Phi",config,pDebugStream);
00118   getConfigForHistogram("deltaEta",config,pDebugStream);
00119   getConfigForHistogram("deltaPhi",config,pDebugStream);
00120   getConfigForHistogram("PhiVsEta",config,pDebugStream);
00121   getConfigForHistogram("N90Hits",config,pDebugStream);
00122   getConfigForHistogram("fHPD",config,pDebugStream);
00123   getConfigForHistogram("ResEMF",config,pDebugStream);
00124   getConfigForHistogram("fRBX",config,pDebugStream);
00125   getConfigForHistogram("TrackSiStripHitStoN",config,pDebugStream);
00126   getConfigForHistogram("InCaloTrackDirectionJetDR",config,pDebugStream);
00127   getConfigForHistogram("OutCaloTrackDirectionJetDR",config,pDebugStream);
00128   getConfigForHistogram("InVertexTrackImpactPointJetDR",config,pDebugStream);
00129   getConfigForHistogram("OutVertexTrackImpactPointJetDR",config,pDebugStream);
00130   getConfigForHistogram("PtFractionInCone",config,pDebugStream);
00131   getConfigForHistogram("PtFractionInConeVsJetRawEt",config,pDebugStream);
00132   getConfigForHistogram("PtFractionInConeVsJetEta",config,pDebugStream);
00133   getConfigForHistogram("nTracks",config,pDebugStream);
00134   getConfigForHistogram("nTracksVsJetEt",config,pDebugStream);
00135   getConfigForHistogram("nTracksVsJetEta",config,pDebugStream);
00136   getConfigForHistogram("CorrFactor",config,pDebugStream);
00137   getConfigForHistogram("CorrFactorVsJetEt",config,pDebugStream);
00138   getConfigForHistogram("CorrFactorVsJetEta",config,pDebugStream);
00139   getConfigForHistogram("ZSPCorrFactor",config,pDebugStream);
00140   getConfigForHistogram("ZSPCorrFactorVsJetEt",config,pDebugStream);
00141   getConfigForHistogram("ZSPCorrFactorVsJetEta",config,pDebugStream);
00142   getConfigForHistogram("JPTCorrFactor",config,pDebugStream);
00143   getConfigForHistogram("JPTCorrFactorVsJetEt",config,pDebugStream);
00144   getConfigForHistogram("JPTCorrFactorVsJetEta",config,pDebugStream);
00145   getConfigForTrackHistograms("AllPions",config,pDebugStream);
00146   getConfigForTrackHistograms("InCaloInVertexPions",config,pDebugStream);
00147   getConfigForTrackHistograms("InCaloOutVertexPions",config,pDebugStream);
00148   getConfigForTrackHistograms("OutCaloInVertexPions",config,pDebugStream);
00149   getConfigForTrackHistograms("AllMuons",config,pDebugStream);
00150   getConfigForTrackHistograms("InCaloInVertexMuons",config,pDebugStream);
00151   getConfigForTrackHistograms("InCaloOutVertexMuons",config,pDebugStream);
00152   getConfigForTrackHistograms("OutCaloInVertexMuons",config,pDebugStream); 
00153   getConfigForTrackHistograms("AllElectrons",config,pDebugStream);
00154   getConfigForTrackHistograms("InCaloInVertexElectrons",config,pDebugStream);
00155   getConfigForTrackHistograms("InCaloOutVertexElectrons",config,pDebugStream);
00156   getConfigForTrackHistograms("OutCaloInVertexElectrons",config,pDebugStream);
00157   
00158   if (verbose_) LogTrace(messageLoggerCatregory) << debugStream.str();
00159 }
00160 
00161 JPTJetAnalyzer::~JPTJetAnalyzer()
00162 {}
00163 
00164 void JPTJetAnalyzer::beginJob(DQMStore* dqmStore)
00165 {
00166   dqm_ = dqmStore;
00167   //book histograms
00168   dqmStore->setCurrentFolder(histogramPath_);
00169   bookHistograms(dqmStore);
00170 }
00171 
00172 
00173 void JPTJetAnalyzer::analyze(const edm::Event& event, const edm::EventSetup& eventSetup, const reco::JPTJetCollection& jptJets)
00174 {
00175   double pt1 = 0;
00176   double pt2 = 0;
00177   double pt3 = 0;
00178   for (reco::JPTJetCollection::const_iterator iJet = jptJets.begin(); iJet != jptJets.end(); ++iJet) {
00179     analyze(event,eventSetup,*iJet,pt1,pt2,pt3);
00180   }
00181   if (pt1) fillHistogram(JetPt1_,pt1);
00182   if (pt2) fillHistogram(JetPt2_,pt2);
00183   if (pt3) fillHistogram(JetPt3_,pt3);
00184 }
00185 
00186 void JPTJetAnalyzer::analyze(const edm::Event& event, const edm::EventSetup& eventSetup, const reco::JPTJet& jptJet, double& pt1, double& pt2, double& pt3)
00187 {
00188   
00189   //update the track propagator and strip noise calculator
00190   trackPropagator_->update(eventSetup);
00191   sOverNCalculator_->update(eventSetup);
00192   
00193   //make corrected jets
00194   const double factorZSP = jptJet.getZSPCor();
00195   const reco::Jet& rawJet = *jptJet.getCaloJetRef();
00196   const double factorZSPJPT = jptJet.energy()/rawJet.energy();
00197   
00198   //check jet is correctable by JPT
00199   if ( fabs(rawJet.eta()) > 2.1) return;
00200   
00201   //get consitiuents of jet
00202   const reco::TrackRefVector& pionsInVertexInCalo = jptJet.getPionsInVertexInCalo();
00203   const reco::TrackRefVector& pionsInVertexOutCalo = jptJet.getPionsInVertexOutCalo();
00204   const reco::TrackRefVector& pionsOutVertexInCalo = jptJet.getPionsOutVertexInCalo();
00205   const reco::TrackRefVector& muonsInVertexInCalo = jptJet.getMuonsInVertexInCalo();
00206   const reco::TrackRefVector& muonsInVertexOutCalo = jptJet.getMuonsInVertexOutCalo();
00207   const reco::TrackRefVector& muonsOutVertexInCalo = jptJet.getMuonsOutVertexInCalo();
00208   const reco::TrackRefVector& electronsInVertexInCalo = jptJet.getElecsInVertexInCalo();
00209   const reco::TrackRefVector& electronsInVertexOutCalo = jptJet.getElecsInVertexOutCalo();
00210   const reco::TrackRefVector& electronsOutVertexInCalo = jptJet.getElecsOutVertexInCalo();
00211   
00212   //check pt against highest values
00213   const double pt = jptJet.pt();
00214   if (pt > pt1) {
00215     pt3 = pt2;
00216     pt2 = pt1;
00217     pt1 = pt;
00218   } else if (pt > pt2) {
00219     pt3 = pt2;
00220     pt2 = pt;
00221   } else if (pt > pt3) {
00222     pt3 = pt;
00223   }
00224   
00225   //fill histograms
00226   try {
00227     const reco::CaloJet& rawCaloJet = dynamic_cast<const reco::CaloJet&>(rawJet);
00228     jetID_->calculate(event,rawCaloJet);
00229   } catch (const std::bad_cast&) {
00230     edm::LogError(messageLoggerCatregory) << "Failed to cast raw jet to CaloJet. JPT Jet does not appear to have been built from a CaloJet. "
00231                                           << "Histograms not filled. ";
00232     return;
00233   }
00234   const bool idPassed = ( (jetID_->n90Hits() >= n90HitsMin_) && (jetID_->fHPD() < fHPDMax_) && (jetID_->restrictedEMF() >= resEMFMin_) );
00235   fillHistogram(JetN90Hits_,jetID_->n90Hits());
00236   fillHistogram(JetfHPD_,jetID_->fHPD());
00237   fillHistogram(JetResEMF_,jetID_->restrictedEMF());
00238   fillHistogram(JetfRBX_,jetID_->fRBX());
00239   if (idPassed) {
00240     const double deltaEta = jptJet.eta() - rawJet.eta();
00241     const double deltaPhi = jptJet.phi() - rawJet.phi();
00242     if (jptJet.pt() > correctedPtMin_) {
00243       fillHistogram(JetE_,jptJet.energy());
00244       fillHistogram(JetEt_,jptJet.et());
00245       fillHistogram(JetP_,jptJet.p());
00246       fillHistogram(JetMass_,jptJet.mass());
00247       fillHistogram(JetPt_,jptJet.pt());
00248       fillHistogram(JetPx_,jptJet.px());
00249       fillHistogram(JetPy_,jptJet.py());
00250       fillHistogram(JetPz_,jptJet.pz());
00251 
00252       fillHistogram(JetEta_,jptJet.eta());
00253       fillHistogram(JetPhi_,jptJet.phi());
00254       fillHistogram(JetDeltaEta_,deltaEta);
00255       fillHistogram(JetDeltaPhi_,deltaPhi);
00256       fillHistogram(JetPhiVsEta_,jptJet.phi(),jptJet.eta());
00257       const uint16_t totalTracks = jptJet.chargedMultiplicity();
00258       fillHistogram(NTracksPerJetHisto_,totalTracks);
00259       fillHistogram(NTracksPerJetVsJetEtHisto_,rawJet.et(),totalTracks);
00260       fillHistogram(NTracksPerJetVsJetEtaHisto_,rawJet.eta(),totalTracks);
00261       fillHistogram(CorrFactorHisto_,factorZSPJPT);
00262       fillHistogram(CorrFactorVsJetEtHisto_,rawJet.et(),factorZSPJPT);
00263       fillHistogram(CorrFactorVsJetEtaHisto_,rawJet.eta(),factorZSPJPT);
00264       fillHistogram(ZSPCorrFactorHisto_,factorZSP);
00265       fillHistogram(ZSPCorrFactorVsJetEtHisto_,rawJet.et(),factorZSP);
00266       fillHistogram(ZSPCorrFactorVsJetEtaHisto_,rawJet.eta(),factorZSP);
00267       const double factorJPT = factorZSPJPT / factorZSP;
00268       fillHistogram(JPTCorrFactorHisto_,factorJPT);
00269       fillHistogram(JPTCorrFactorVsJetEtHisto_,rawJet.et(),factorJPT);
00270       fillHistogram(JPTCorrFactorVsJetEtaHisto_,rawJet.eta(),factorJPT);
00271       const double ptFractionInCone = findPtFractionInCone(pionsInVertexInCalo,pionsInVertexOutCalo);
00272       fillHistogram(PtFractionInConeHisto_,ptFractionInCone);
00273       fillHistogram(PtFractionInConeVsJetRawEtHisto_,rawJet.et(),ptFractionInCone);
00274       fillHistogram(PtFractionInConeVsJetEtaHisto_,rawJet.eta(),ptFractionInCone);
00275       //fill track level histograms
00276       fillTrackHistograms(allPionHistograms_,inCaloInVertexPionHistograms_,inCaloOutVertexPionHistograms_,outCaloInVertexPionHistograms_,
00277                           pionsInVertexInCalo,pionsOutVertexInCalo,pionsInVertexOutCalo,rawJet);
00278       fillTrackHistograms(allMuonHistograms_,inCaloInVertexMuonHistograms_,inCaloOutVertexMuonHistograms_,outCaloInVertexMuonHistograms_,
00279                           muonsInVertexInCalo,muonsOutVertexInCalo,muonsInVertexOutCalo,rawJet);
00280       fillTrackHistograms(allElectronHistograms_,inCaloInVertexElectronHistograms_,inCaloOutVertexElectronHistograms_,outCaloInVertexElectronHistograms_,
00281                           electronsInVertexInCalo,electronsOutVertexInCalo,electronsInVertexOutCalo,rawJet);
00282     }
00283   }
00284 }
00285 
00286 void JPTJetAnalyzer::endJob()
00287 {
00288   if(writeDQMStore_) dqm_->save(dqmStoreFileName_);
00289 }
00290 
00291 void JPTJetAnalyzer::getConfigForHistogram(const std::string& configName, const edm::ParameterSet& psetContainingConfigPSet,
00292                                            std::ostringstream* pDebugStream)
00293 {
00294   const std::string psetName = configName+std::string("HistogramConfig");
00295   if (!psetContainingConfigPSet.exists(psetName)) {
00296     edm::LogWarning(messageLoggerCatregory) << "Histogram " << configName << " config not found" << std::endl;
00297     histogramConfig_[configName] = HistogramConfig();
00298   } else {
00299     if (pDebugStream) {
00300       (*pDebugStream) << "Histogram " << configName << " config found and loaded" << std::endl;
00301     }
00302     const edm::ParameterSet& pset = psetContainingConfigPSet.getParameter<edm::ParameterSet>(psetName);
00303     const bool enabled = (pset.exists("Enabled") ? pset.getParameter<bool>("Enabled") : true);
00304     if (!enabled) {
00305       histogramConfig_[configName] = HistogramConfig();
00306       if (pDebugStream) {
00307         (*pDebugStream) << "\tHistogram: " << configName << " Disabled" << std::endl;
00308       }
00309     } else {
00310       const unsigned int nBins = (pset.exists("NBins") ? pset.getParameter<unsigned int>("NBins") : 0);
00311       const double min = (pset.exists("Min") ? pset.getParameter<double>("Min") : 0);
00312       const double max = (pset.exists("Max") ? pset.getParameter<double>("Max") : 0);
00313       const unsigned int nBinsY = (pset.exists("NBinsY") ? pset.getParameter<unsigned int>("NBinsY") : 0);
00314       const double minY = (pset.exists("MinY") ? pset.getParameter<double>("MinY") : 0);
00315       const double maxY = (pset.exists("MaxY") ? pset.getParameter<double>("MaxY") : 0);
00316       if (nBins) {
00317         if (pDebugStream) {
00318           (*pDebugStream) << "\tHistogram: " << configName << "\tEnabled"
00319                           << "\tNBins: " << nBins << "\tMin: " << min << "\tMax: " << max;
00320           if (nBinsY) (*pDebugStream) << "\tNBinsY: " << nBinsY << "\tMinY: " << minY << "\tMaxY: " << maxY;
00321           (*pDebugStream) << std::endl;
00322         }
00323         if (nBinsY) {
00324           histogramConfig_[configName] = HistogramConfig(nBins,min,max,nBinsY,minY,maxY);
00325         } else {
00326           histogramConfig_[configName] = HistogramConfig(nBins,min,max);
00327         }
00328       }
00329     }
00330   }
00331 }
00332 
00333 void JPTJetAnalyzer::getConfigForTrackHistograms(const std::string& tag, const edm::ParameterSet& psetContainingConfigPSet,
00334                                                   std::ostringstream* pDebugStream)
00335 {
00336   getConfigForHistogram("n"+tag+"TracksPerJet",psetContainingConfigPSet,pDebugStream);
00337   getConfigForHistogram(tag+"TrackPt",psetContainingConfigPSet,pDebugStream);
00338   getConfigForHistogram(tag+"TrackPhi",psetContainingConfigPSet,pDebugStream);
00339   getConfigForHistogram(tag+"TrackEta",psetContainingConfigPSet,pDebugStream);
00340   getConfigForHistogram(tag+"TrackNHits",psetContainingConfigPSet,pDebugStream);
00341   getConfigForHistogram(tag+"TrackNLayers",psetContainingConfigPSet,pDebugStream);
00342   getConfigForHistogram(tag+"TrackNLayers",psetContainingConfigPSet,pDebugStream);
00343   getConfigForHistogram(tag+"TrackPtVsEta",psetContainingConfigPSet,pDebugStream);
00344   getConfigForHistogram(tag+"TrackDz",psetContainingConfigPSet,pDebugStream);
00345   getConfigForHistogram(tag+"TrackDxy",psetContainingConfigPSet,pDebugStream);
00346 }
00347 
00348 MonitorElement* JPTJetAnalyzer::bookHistogram(const std::string& name, const std::string& title, const std::string& xAxisTitle, DQMStore* dqm)
00349 {
00350   std::map<std::string,HistogramConfig>::const_iterator configIterator = histogramConfig_.find(name);
00351   if (configIterator == histogramConfig_.end()) {
00352     edm::LogWarning(messageLoggerCatregory) << "Trying to book histogram with name " << name << " when no config was not retrieved from ParameterSet";
00353     return NULL;
00354   }
00355   const HistogramConfig& histoConfig = (*configIterator).second;
00356   if (histoConfig.enabled) {
00357     MonitorElement* histo = dqm->book1D(name,title,histoConfig.nBins,histoConfig.min,histoConfig.max);
00358     histo->setAxisTitle(xAxisTitle,1);
00359     return histo;
00360   } else {
00361     return NULL;
00362   }
00363 }
00364 
00365 MonitorElement* JPTJetAnalyzer::book2DHistogram(const std::string& name, const std::string& title,
00366                                                 const std::string& xAxisTitle, const std::string& yAxisTitle, DQMStore* dqm)
00367 {
00368   std::map<std::string,HistogramConfig>::const_iterator configIterator = histogramConfig_.find(name);
00369   if (configIterator == histogramConfig_.end()) {
00370     edm::LogWarning(messageLoggerCatregory) << "Trying to book histogram with name " << name << " when no config was not retrieved from ParameterSet";
00371     return NULL;
00372   }
00373   const HistogramConfig& histoConfig = (*configIterator).second;
00374   if (histoConfig.enabled) {
00375     MonitorElement* histo = dqm->book2D(name,title,histoConfig.nBins,histoConfig.min,histoConfig.max,histoConfig.nBinsY,histoConfig.minY,histoConfig.maxY);
00376     histo->setAxisTitle(xAxisTitle,1);
00377     histo->setAxisTitle(yAxisTitle,2);
00378     return histo;
00379   } else {
00380     return NULL;
00381   }
00382 }
00383 
00384 MonitorElement* JPTJetAnalyzer::bookProfile(const std::string& name, const std::string& title,
00385                                             const std::string& xAxisTitle, const std::string& yAxisTitle, DQMStore* dqm)
00386 {
00387   std::map<std::string,HistogramConfig>::const_iterator configIterator = histogramConfig_.find(name);
00388   if (configIterator == histogramConfig_.end()) {
00389     edm::LogWarning(messageLoggerCatregory) << "Trying to book histogram with name " << name << " when no config was not retrieved from ParameterSet";
00390     return NULL;
00391   }
00392   const HistogramConfig& histoConfig = (*configIterator).second;
00393   if (histoConfig.enabled) {
00394     TProfile* underlyingRootObject = new TProfile(name.c_str(),title.c_str(),histoConfig.nBins,histoConfig.min,histoConfig.max);
00395     MonitorElement* histo = dqm->bookProfile(name,underlyingRootObject);
00396     histo->setAxisTitle(xAxisTitle,1);
00397     histo->setAxisTitle(yAxisTitle,2);
00398     return histo;
00399   } else {
00400     return NULL;
00401   }
00402 }
00403 
00404 void JPTJetAnalyzer::bookHistograms(DQMStore* dqm)
00405 {
00406   JetE_        = bookHistogram("E","Corrected Jet Energy","E /GeV",dqm);
00407   JetEt_       = bookHistogram("Et","Corrected Jet E_{T}","E_{T} /GeV",dqm);
00408   JetP_        = bookHistogram("P","Corrected Jet Momentum","p /GeV/c",dqm);
00409   JetMass_     = bookHistogram("Mass","Jet mass","Mass /GeV/c^{2}",dqm);
00410   JetPt_       = bookHistogram("Pt","Jet p_{T}","p_{T} /GeV/c",dqm);
00411   JetPt1_      = bookHistogram("Pt1","1st Jet p_{T}","p_{T} /GeV/c",dqm);
00412   JetPt2_      = bookHistogram("Pt2","2nd Jet p_{T}","p_{T} /GeV/c",dqm);
00413   JetPt3_      = bookHistogram("Pt3","3rd Jet p_{T}","p_{T} /GeV/c",dqm);
00414   JetPx_       = bookHistogram("Px","Jet p_{X}","p_{X} /GeV/c",dqm);
00415   JetPy_       = bookHistogram("Py","Jet p_{Y}","p_{Y} /GeV/c",dqm);
00416   JetPz_       = bookHistogram("Pz","Jet p_{Z}","p_{Z} /GeV/c",dqm);
00417   JetEta_      = bookHistogram("Eta","Jet #eta","#eta",dqm);
00418   JetPhi_      = bookHistogram("Phi","Jet #phi","#phi",dqm);
00419   JetDeltaEta_ = bookHistogram("deltaEta","Change in #eta","#Delta #eta",dqm);
00420   JetDeltaPhi_ = bookHistogram("deltaPhi","Change in #phi","#Delta #phi",dqm);
00421   JetPhiVsEta_ = book2DHistogram("PhiVsEta","Corrected jet #phi vs #eta","jet #phi","jet #eta",dqm);
00422   JetN90Hits_  = bookHistogram("N90Hits","Jet N90Hits","N90 Hits",dqm);
00423   JetfHPD_     = bookHistogram("fHPD","Jet fHPD","fHPD",dqm);
00424   JetResEMF_   = bookHistogram("ResEMF","Jet restricted EM fraction","restricted EMF",dqm);
00425   JetfRBX_     = bookHistogram("fRBX","Jet fRBX","fRBX",dqm);
00426   
00427   TrackSiStripHitStoNHisto_            = bookHistogram("TrackSiStripHitStoN","Signal to noise of track SiStrip hits","S/N",dqm);
00428   InCaloTrackDirectionJetDRHisto_      = bookHistogram("InCaloTrackDirectionJetDR",
00429                                                        "#Delta R between track direrction at vertex and jet axis (track in cone at calo)","#Delta R",dqm);
00430   OutCaloTrackDirectionJetDRHisto_     = bookHistogram("OutCaloTrackDirectionJetDR",
00431                                                        "#Delta R between track direrction at vertex and jet axis (track out of cone at calo)","#Delta R",dqm);
00432   InVertexTrackImpactPointJetDRHisto_  = bookHistogram("InVertexTrackImpactPointJetDR",
00433                                                        "#Delta R between track impact point on calo and jet axis (track in cone at vertex)","#Delta R",dqm);
00434   OutVertexTrackImpactPointJetDRHisto_ = bookHistogram("OutVertexTrackImpactPointJetDR",
00435                                                        "#Delta R between track impact point on calo and jet axis (track out of cone at vertex)","#Delta R",dqm);
00436   
00437   NTracksPerJetHisto_         = bookHistogram("nTracks","Number of tracks for correction per jet","n tracks",dqm);
00438   NTracksPerJetVsJetEtHisto_  = bookProfile("nTracksVsJetEt","Number of tracks for correction per jet vs jet raw E_{T}","Jet raw E_{T} /GeV","n Tracks",dqm);
00439   NTracksPerJetVsJetEtaHisto_ = bookProfile("nTracksVsJetEta","Number of tracks for correction per jet vs jet #eta","Jet #eta","n Tracks",dqm);
00440   
00441   PtFractionInConeHisto_           = bookHistogram("PtFractionInCone","#frac{p_{T}^{in-cone}}{p_{T}^{in-cone}+p_{T}^{out-of-cone}}",
00442                                                  "#frac{p_{T}^{in-cone}}{p_{T}^{in-cone}+p_{T}^{out-of-cone}}",dqm);
00443   PtFractionInConeVsJetRawEtHisto_ = bookProfile("PtFractionInConeVsJetRawEt","#frac{p_{T}^{in-cone}}{p_{T}^{in-cone}+p_{T}^{out-of-cone}} vs jet raw E_{T}",
00444                                                  "Jet raw E_{T} / GeV","#frac{p_{T}^{in-cone}}{p_{T}^{in-cone}+p_{T}^{out-of-cone}}",dqm);
00445   PtFractionInConeVsJetEtaHisto_   = bookProfile("PtFractionInConeVsJetEta","#frac{p_{T}^{in-cone}}{p_{T}^{in-cone}+p_{T}^{out-of-cone}} vs jet #eta",
00446                                                  "Jet #eta","#frac{p_{T}^{in-cone}}{p_{T}^{in-cone}+p_{T}^{out-of-cone}}",dqm);
00447   
00448   CorrFactorHisto_            = bookHistogram("CorrFactor","Correction factor","Correction factor",dqm);
00449   CorrFactorVsJetEtHisto_     = bookProfile("CorrFactorVsJetEt","Correction factor vs jet raw E_{T}","Jet raw E_{T}","#frac{E_{T}^{corr}}{E_{T}^{raw}}",dqm);
00450   CorrFactorVsJetEtaHisto_    = bookProfile("CorrFactorVsJetEta","Correction factor vs jet #eta","Jet #eta","#frac{E_{T}^{corr}}{E_{T}^{raw}}",dqm);
00451   ZSPCorrFactorHisto_         = bookHistogram("ZSPCorrFactor","Correction factor from ZSP step","Correction factor",dqm);
00452   ZSPCorrFactorVsJetEtHisto_  = bookProfile("ZSPCorrFactorVsJetEt","Correction factor from ZSP step vs jet raw E_{T}",
00453                                             "Jet raw E_{T}","#frac{E_{T}^{corr}}{E_{T}^{raw}}",dqm);
00454   ZSPCorrFactorVsJetEtaHisto_ = bookProfile("ZSPCorrFactorVsJetEta","Correction factor from ZSP step vs jet #eta",
00455                                             "Jet #eta","#frac{E_{T}^{corr}}{E_{T}^{raw}}",dqm);
00456   JPTCorrFactorHisto_         = bookHistogram("JPTCorrFactor","Correction factor from JPT step","Correction factor",dqm);
00457   JPTCorrFactorVsJetEtHisto_  = bookProfile("JPTCorrFactorVsJetEt","Correction factor from JPT step vs jet raw E_{T}",
00458                                             "Jet raw E_{T}","#frac{E_{T}^{corr}}{E_{T}^{raw}}",dqm);
00459   JPTCorrFactorVsJetEtaHisto_ = bookProfile("JPTCorrFactorVsJetEta","Correction factor from JPT step vs jet #eta",
00460                                             "Jet #eta","#frac{E_{T}^{corr}}{E_{T}^{raw}}",dqm);
00461 
00462 
00463   
00464   bookTrackHistograms(&allPionHistograms_,"AllPions","pion",NULL,NULL,dqm);
00465   bookTrackHistograms(&inCaloInVertexPionHistograms_,"InCaloInVertexPions","pions in cone at calo and vertex",
00466                       InCaloTrackDirectionJetDRHisto_,InVertexTrackImpactPointJetDRHisto_,dqm);
00467   bookTrackHistograms(&inCaloOutVertexPionHistograms_,"InCaloOutVertexPions","pions in cone at calo but out at vertex",
00468                       InCaloTrackDirectionJetDRHisto_,OutVertexTrackImpactPointJetDRHisto_,dqm);
00469   bookTrackHistograms(&outCaloInVertexPionHistograms_,"OutCaloInVertexPions","pions out of cone at calo but in at vertex",
00470                       OutCaloTrackDirectionJetDRHisto_,InVertexTrackImpactPointJetDRHisto_,dqm);
00471   
00472   bookTrackHistograms(&allMuonHistograms_,"AllMuons","muon",NULL,NULL,dqm);
00473   bookTrackHistograms(&inCaloInVertexMuonHistograms_,"InCaloInVertexMuons","muons in cone at calo and vertex",
00474                       InCaloTrackDirectionJetDRHisto_,InVertexTrackImpactPointJetDRHisto_,dqm);
00475   bookTrackHistograms(&inCaloOutVertexMuonHistograms_,"InCaloOutVertexMuons","muons in cone at calo but out at vertex",
00476                       InCaloTrackDirectionJetDRHisto_,OutVertexTrackImpactPointJetDRHisto_,dqm);
00477   bookTrackHistograms(&outCaloInVertexMuonHistograms_,"OutCaloInVertexMuons","muons out of cone at calo but in at vertex",
00478                       OutCaloTrackDirectionJetDRHisto_,InVertexTrackImpactPointJetDRHisto_,dqm);
00479   
00480   bookTrackHistograms(&allElectronHistograms_,"AllElectrons","electron",NULL,NULL,dqm);
00481   bookTrackHistograms(&inCaloInVertexElectronHistograms_,"InCaloInVertexElectrons","electrons in cone at calo and vertex",
00482                       InCaloTrackDirectionJetDRHisto_,InVertexTrackImpactPointJetDRHisto_,dqm);
00483   bookTrackHistograms(&inCaloOutVertexElectronHistograms_,"InCaloOutVertexElectrons","electrons in cone at calo but out at vertex",
00484                       InCaloTrackDirectionJetDRHisto_,OutVertexTrackImpactPointJetDRHisto_,dqm);
00485   bookTrackHistograms(&outCaloInVertexElectronHistograms_,"OutCaloInVertexElectrons","electrons out of cone at calo but in at vertex",
00486                       OutCaloTrackDirectionJetDRHisto_,InVertexTrackImpactPointJetDRHisto_,dqm);
00487 }
00488 
00489 void JPTJetAnalyzer::bookTrackHistograms(TrackHistograms* histos, const std::string& tag, const std::string& titleTag,
00490                                          MonitorElement* trackDirectionJetDRHisto, MonitorElement* trackImpactPointJetDRHisto, DQMStore* dqm)
00491 {
00492   histos->nTracksHisto = bookHistogram("n"+tag+"TracksPerJet","Number of "+titleTag+" tracks per jet","n Tracks",dqm);
00493   histos->ptHisto = bookHistogram(tag+"TrackPt",titleTag+" p_{T}","p_{T} /GeV/c",dqm);
00494   histos->phiHisto = bookHistogram(tag+"TrackPhi",titleTag+" track #phi","#phi",dqm);
00495   histos->etaHisto = bookHistogram(tag+"TrackEta",titleTag+" track #eta","#eta",dqm);
00496   histos->nHitsHisto = bookHistogram(tag+"TrackNHits",titleTag+" track N hits","N hits",dqm);
00497   histos->nLayersHisto = bookHistogram(tag+"TrackNLayers",titleTag+" track N layers with hits","N layers",dqm);
00498   histos->ptVsEtaHisto = bookProfile(tag+"TrackPtVsEta",titleTag+" track p_{T} vs #eta","#eta","p_{T} /GeV/c",dqm);
00499   histos->dzHisto = bookHistogram(tag+"TrackDz",titleTag+" track dz","dz /cm",dqm);
00500   histos->dxyHisto = bookHistogram(tag+"TrackDxy",titleTag+" track dxy","dxy /cm",dqm);
00501   histos->trackDirectionJetDRHisto = trackDirectionJetDRHisto;
00502   histos->trackImpactPointJetDRHisto = trackImpactPointJetDRHisto;
00503 }
00504 
00505 void JPTJetAnalyzer::fillTrackHistograms(TrackHistograms& allTracksHistos, TrackHistograms& inCaloInVertexHistos,
00506                                          TrackHistograms& inCaloOutVertexHistos, TrackHistograms& outCaloInVertexHistos,
00507                                          const reco::TrackRefVector& inVertexInCalo,
00508                                          const reco::TrackRefVector& outVertexInCalo,
00509                                          const reco::TrackRefVector& inVertexOutCalo,
00510                                          const reco::Jet& rawJet)
00511 {
00512   fillTrackHistograms(allTracksHistos,inVertexInCalo,rawJet);
00513   fillTrackHistograms(allTracksHistos,outVertexInCalo,rawJet);
00514   fillTrackHistograms(allTracksHistos,inVertexOutCalo,rawJet);
00515   fillHistogram(allTracksHistos.nTracksHisto,inVertexInCalo.size()+outVertexInCalo.size()+inVertexOutCalo.size());
00516   fillSiStripSoNForTracks(inVertexInCalo);
00517   fillSiStripSoNForTracks(outVertexInCalo);
00518   fillSiStripSoNForTracks(inVertexOutCalo);
00519   fillTrackHistograms(inCaloInVertexHistos,inVertexInCalo,rawJet);
00520   fillHistogram(inCaloInVertexHistos.nTracksHisto,inVertexInCalo.size());
00521   fillTrackHistograms(inCaloOutVertexHistos,outVertexInCalo,rawJet);
00522   fillHistogram(inCaloOutVertexHistos.nTracksHisto,outVertexInCalo.size());
00523   fillTrackHistograms(outCaloInVertexHistos,inVertexOutCalo,rawJet);
00524   fillHistogram(outCaloInVertexHistos.nTracksHisto,inVertexOutCalo.size());
00525 }
00526 
00527 void JPTJetAnalyzer::fillTrackHistograms(TrackHistograms& histos, const reco::TrackRefVector& tracks, const reco::Jet& rawJet)
00528 {
00529   const reco::TrackRefVector::const_iterator tracksEnd = tracks.end();
00530   for (reco::TrackRefVector::const_iterator iTrack = tracks.begin(); iTrack != tracksEnd; ++iTrack) {
00531     const reco::Track& track = **iTrack;
00532     const double pt = track.pt();
00533     const double phi = track.phi();
00534     const double eta = track.eta();
00535     const unsigned int nHits = track.found();
00536     const unsigned int nLayers = track.hitPattern().trackerLayersWithMeasurement();
00537     const double dz = track.dz();
00538     const double dxy = track.dxy();
00539     fillHistogram(histos.ptHisto,pt);
00540     fillHistogram(histos.phiHisto,phi);
00541     fillHistogram(histos.etaHisto,eta);
00542     fillHistogram(histos.nHitsHisto,nHits);
00543     fillHistogram(histos.nLayersHisto,nLayers);
00544     fillHistogram(histos.ptVsEtaHisto,eta,pt);
00545     fillHistogram(histos.dzHisto,dz);
00546     fillHistogram(histos.dxyHisto,dxy);
00547     const double trackDirectionJetDR = deltaR(rawJet,track);
00548     fillHistogram(histos.trackDirectionJetDRHisto,trackDirectionJetDR);
00549     const double impactPointJetDR = deltaR(rawJet,trackPropagator_->impactPoint(track));
00550     fillHistogram(histos.trackImpactPointJetDRHisto,impactPointJetDR);
00551   }
00552 }
00553 
00554 void JPTJetAnalyzer::fillSiStripSoNForTracks(const reco::TrackRefVector& tracks)
00555 {
00556   const reco::TrackRefVector::const_iterator tracksEnd = tracks.end();
00557   for (reco::TrackRefVector::const_iterator iTrack = tracks.begin(); iTrack != tracksEnd; ++iTrack) {
00558     const trackingRecHit_iterator trackRecHitsEnd = (*iTrack)->recHitsEnd();
00559     for (trackingRecHit_iterator iHit = (*iTrack)->recHitsBegin(); iHit != trackRecHitsEnd; ++iHit) {
00560       fillSiStripHitSoN(**iHit);
00561     }
00562   }
00563 }
00564 
00565 void JPTJetAnalyzer::fillSiStripHitSoN(const TrackingRecHit& hit)
00566 {
00567   //check it is an SiStrip hit
00568   DetId detId(hit.geographicalId());
00569   if (!( (detId.det() == DetId::Tracker) &&
00570         ( (detId.subdetId() == SiStripDetId::TIB) ||
00571           (detId.subdetId() == SiStripDetId::TID) ||
00572           (detId.subdetId() == SiStripDetId::TOB) ||
00573           (detId.subdetId() == SiStripDetId::TEC)
00574         )
00575      )) return;
00576   //try to determine the type of the hit
00577   const TrackingRecHit* pHit = &hit;
00578   const SiStripRecHit2D* pRecHit2D = dynamic_cast<const SiStripRecHit2D*>(pHit);
00579   const SiStripMatchedRecHit2D* pMatchedRecHit2D = dynamic_cast<const SiStripMatchedRecHit2D*>(pHit);
00580   const ProjectedSiStripRecHit2D* pProjctedRecHit2D = dynamic_cast<const ProjectedSiStripRecHit2D*>(pHit);
00581   const InvalidTrackingRecHit* pInvalidHit = dynamic_cast<const InvalidTrackingRecHit*>(pHit);
00582   //fill signal to noise for appropriate hit
00583   if (pMatchedRecHit2D) {
00584     fillSiStripHitSoNForSingleHit(*pMatchedRecHit2D->monoHit());
00585     fillSiStripHitSoNForSingleHit(*pMatchedRecHit2D->stereoHit());
00586   } else if (pProjctedRecHit2D) {
00587     fillSiStripHitSoNForSingleHit(pProjctedRecHit2D->originalHit());
00588   } else if (pRecHit2D) {
00589     fillSiStripHitSoNForSingleHit(*pRecHit2D);
00590   } else if (pInvalidHit) {
00591     return;
00592   } else {
00593     edm::LogInfo(messageLoggerCatregory) << "Hit on det ID " << hit.geographicalId().rawId() << " cannot be converted to a strip hit";
00594   }
00595 }
00596 
00597 void JPTJetAnalyzer::fillSiStripHitSoNForSingleHit(const SiStripRecHit2D& hit)
00598 {
00599   //get the cluster
00600   const SiStripCluster* cluster = NULL;
00601   const SiStripRecHit2D::ClusterRegionalRef& regionalClusterRef = hit.cluster_regional();
00602   const SiStripRecHit2D::ClusterRef& normalClusterRef = hit.cluster();
00603   if (regionalClusterRef.isNonnull()) {
00604     cluster = &*regionalClusterRef;
00605   } else if (normalClusterRef.isNonnull()) {
00606     cluster = &*normalClusterRef;
00607   } else {
00608     edm::LogError(messageLoggerCatregory) << "Unable to get cluster from SiStripRecHit2D with det ID " << hit.geographicalId().rawId();
00609     return;
00610   }
00611   //calculate signal to noise for cluster
00612   const double sOverN = (*sOverNCalculator_)(*cluster);
00613   //fill histogram
00614   fillHistogram(TrackSiStripHitStoNHisto_,sOverN);
00615 }
00616 
00617 double JPTJetAnalyzer::findPtFractionInCone(const reco::TrackRefVector& inConeTracks, const reco::TrackRefVector& outOfConeTracks)
00618 {
00619   double totalPt = 0;
00620   double inConePt = 0;
00621   const reco::TrackRefVector::const_iterator inConeTracksEnd = inConeTracks.end();
00622   for (reco::TrackRefVector::const_iterator iInConeTrack = inConeTracks.begin(); iInConeTrack != inConeTracksEnd; ++iInConeTrack) {
00623     const double pt = (*iInConeTrack)->pt();
00624     totalPt += pt;
00625     inConePt += pt;
00626   }
00627   const reco::TrackRefVector::const_iterator outOfConeTracksEnd = outOfConeTracks.end();
00628   for (reco::TrackRefVector::const_iterator iOutOfConeTrack = outOfConeTracks.begin(); iOutOfConeTrack != outOfConeTracksEnd; ++iOutOfConeTrack) {
00629     const double pt = (*iOutOfConeTrack)->pt();
00630     totalPt += pt;
00631   }
00632   if (totalPt) return inConePt/totalPt;
00633   //return 0 if there are no tracks at all
00634   else return 0;
00635 }
00636 
00637 
00638 
00639 JPTJetAnalyzer::HistogramConfig::HistogramConfig()
00640   : enabled(false),
00641     nBins(0),
00642     min(0),
00643     max(0),
00644     nBinsY(0),
00645     minY(0),
00646     maxY(0)
00647 {}
00648 
00649 JPTJetAnalyzer::HistogramConfig::HistogramConfig(const unsigned int theNBins, const double theMin, const double theMax)
00650   : enabled(true),
00651     nBins(theNBins),
00652     min(theMin),
00653     max(theMax),
00654     nBinsY(0),
00655     minY(0),
00656     maxY(0)
00657 {}
00658 
00659 JPTJetAnalyzer::HistogramConfig::HistogramConfig(const unsigned int theNBinsX, const double theMinX, const double theMaxX,
00660                                                  const unsigned int theNBinsY, const double theMinY, const double theMaxY)
00661   : enabled(true),
00662     nBins(theNBinsX),
00663     min(theMinX),
00664     max(theMaxX),
00665     nBinsY(theNBinsY),
00666     minY(theMinY),
00667     maxY(theMaxY)
00668 {}
00669 
00670 JPTJetAnalyzer::TrackHistograms::TrackHistograms()
00671   : ptHisto(NULL),
00672     phiHisto(NULL),
00673     etaHisto(NULL),
00674     nHitsHisto(NULL),
00675     nLayersHisto(NULL),
00676     ptVsEtaHisto(NULL),
00677     dzHisto(NULL),
00678     dxyHisto(NULL),
00679     trackDirectionJetDRHisto(NULL),
00680     trackImpactPointJetDRHisto(NULL)
00681 {}
00682 
00683 JPTJetAnalyzer::TrackHistograms::TrackHistograms(MonitorElement* theNTracksHisto,
00684                                                  MonitorElement* thePtHisto, MonitorElement* thePhiHisto, MonitorElement* theEtaHisto,
00685                                                  MonitorElement* theNHitsHisto, MonitorElement* theNLayersHisto, MonitorElement* thePtVsEtaHisto,
00686                                                  MonitorElement* theDzHisto, MonitorElement* theDxyHisto,
00687                                                  MonitorElement* theTrackDirectionJetDRHisto, MonitorElement* theTrackImpactPointJetDRHisto)
00688   : nTracksHisto(theNTracksHisto),
00689     ptHisto(thePtHisto),
00690     phiHisto(thePhiHisto),
00691     etaHisto(theEtaHisto),
00692     nHitsHisto(theNHitsHisto),
00693     nLayersHisto(theNLayersHisto),
00694     ptVsEtaHisto(thePtVsEtaHisto),
00695     dzHisto(theDzHisto),
00696     dxyHisto(theDxyHisto),
00697     trackDirectionJetDRHisto(theTrackDirectionJetDRHisto),
00698     trackImpactPointJetDRHisto(theTrackImpactPointJetDRHisto)
00699 {}
00700 
00701 namespace jptJetAnalysis {
00702   
00703   TrackPropagatorToCalo::TrackPropagatorToCalo()
00704     : magneticField_(NULL),
00705       propagator_(NULL),
00706       magneticFieldCacheId_(0),
00707       propagatorCacheId_(0)
00708     {}
00709   
00710   void TrackPropagatorToCalo::update(const edm::EventSetup& eventSetup)
00711   {
00712     //update magnetic filed if necessary
00713     const IdealMagneticFieldRecord& magneticFieldRecord = eventSetup.get<IdealMagneticFieldRecord>();
00714     const uint32_t newMagneticFieldCacheId = magneticFieldRecord.cacheIdentifier();
00715     if ((newMagneticFieldCacheId != magneticFieldCacheId_) || !magneticField_) {
00716       edm::ESHandle<MagneticField> magneticFieldHandle;
00717       magneticFieldRecord.get(magneticFieldHandle);
00718       magneticField_ = magneticFieldHandle.product();
00719       magneticFieldCacheId_ = newMagneticFieldCacheId;
00720     }
00721     //update propagator if necessary
00722     const TrackingComponentsRecord& trackingComponentsRecord = eventSetup.get<TrackingComponentsRecord>();
00723     const uint32_t newPropagatorCacheId = trackingComponentsRecord.cacheIdentifier();
00724     if ((propagatorCacheId_ != newPropagatorCacheId) || !propagator_) {
00725       edm::ESHandle<Propagator> propagatorHandle;
00726       trackingComponentsRecord.get("SteppingHelixPropagatorAlong",propagatorHandle);
00727       propagator_ = propagatorHandle.product();
00728       propagatorCacheId_ = newPropagatorCacheId;
00729     }
00730   }
00731   
00732   inline math::XYZPoint TrackPropagatorToCalo::impactPoint(const reco::Track& track) const
00733   {
00734     return JetTracksAssociationDRCalo::propagateTrackToCalorimeter(track,*magneticField_,*propagator_);
00735   }
00736   
00737   StripSignalOverNoiseCalculator::StripSignalOverNoiseCalculator(const std::string& theQualityLabel)
00738     : qualityLabel_(theQualityLabel),
00739       quality_(NULL),
00740       noise_(NULL),
00741       gain_(NULL),
00742       qualityCacheId_(0),
00743       noiseCacheId_(0),
00744       gainCacheId_(0)
00745     {}
00746   
00747   void StripSignalOverNoiseCalculator::update(const edm::EventSetup& eventSetup)
00748   {
00749     //update the quality if necessary
00750     const SiStripQualityRcd& qualityRecord = eventSetup.get<SiStripQualityRcd>();
00751     const uint32_t newQualityCacheId = qualityRecord.cacheIdentifier();
00752     if ((newQualityCacheId != qualityCacheId_) || !quality_) {
00753       edm::ESHandle<SiStripQuality> qualityHandle;
00754       qualityRecord.get(qualityLabel_,qualityHandle);
00755       quality_ = qualityHandle.product();
00756       qualityCacheId_ = newQualityCacheId;
00757     }
00758     //update the noise if necessary
00759     const SiStripNoisesRcd& noiseRecord = eventSetup.get<SiStripNoisesRcd>();
00760     const uint32_t newNoiseCacheId = noiseRecord.cacheIdentifier();
00761     if ((newNoiseCacheId != noiseCacheId_) || !noise_) {
00762       edm::ESHandle<SiStripNoises> noiseHandle;
00763       noiseRecord.get(noiseHandle);
00764       noise_ = noiseHandle.product();
00765       noiseCacheId_ = newNoiseCacheId;
00766     }
00767     //update the gain if necessary
00768     const SiStripGainRcd& gainRecord = eventSetup.get<SiStripGainRcd>();
00769     const uint32_t newGainCacheId = gainRecord.cacheIdentifier();
00770     if ((newGainCacheId != gainCacheId_) || !gain_) {
00771       edm::ESHandle<SiStripGain> gainHandle;
00772       gainRecord.get(gainHandle);
00773       gain_ = gainHandle.product();
00774       gainCacheId_ = newGainCacheId;
00775     }
00776   }
00777   
00778   double StripSignalOverNoiseCalculator::signalOverNoise(const SiStripCluster& cluster) const
00779   {
00780     const uint32_t detId = cluster.geographicalId();
00781     const uint16_t firstStrip = cluster.firstStrip();
00782     const SiStripQuality::Range& qualityRange = quality_->getRange(detId);
00783     const SiStripNoises::Range& noiseRange = noise_->getRange(detId);
00784     const SiStripApvGain::Range& gainRange = gain_->getRange(detId);
00785     double signal = 0;
00786     double noise2 = 0;
00787     unsigned int nNonZeroStrips = 0;
00788     const std::vector<uint8_t>& clusterAmplitudes = cluster.amplitudes();
00789     const std::vector<uint8_t>::const_iterator clusterAmplitudesEnd = clusterAmplitudes.end();
00790     const std::vector<uint8_t>::const_iterator clusterAmplitudesBegin = clusterAmplitudes.begin();
00791     for (std::vector<uint8_t>::const_iterator iAmp = clusterAmplitudesBegin; iAmp != clusterAmplitudesEnd; ++iAmp) {
00792       const uint8_t adc = *iAmp;
00793       const uint16_t strip = iAmp-clusterAmplitudesBegin+firstStrip;
00794       const bool stripBad = quality_->IsStripBad(qualityRange,strip);
00795       const double noise = noise_->getNoise(strip,noiseRange);
00796       const double gain = gain_->getStripGain(strip,gainRange);
00797       signal += adc;
00798       if (adc) ++nNonZeroStrips;
00799       const double noiseContrib = (stripBad ? 0 : noise/gain);
00800       noise2 += noiseContrib*noiseContrib;
00801     }
00802     const double noise = sqrt(noise2/nNonZeroStrips);
00803     if (noise) return signal/noise;
00804     else return 0;
00805   }
00806   
00807 }