CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/CalibTracker/SiStripHitEfficiency/src/HitEff.cc

Go to the documentation of this file.
00001 
00002 // Package:          CalibTracker/SiStripHitEfficiency
00003 // Class:            HitEff
00004 // Original Author:  Keith Ulmer--University of Colorado
00005 //                   keith.ulmer@colorado.edu
00006 //
00008 
00009 // system include files
00010 #include <memory>
00011 #include <string>
00012 #include <iostream>
00013 
00014 #include "FWCore/Framework/interface/Frameworkfwd.h"
00015 #include "FWCore/Framework/interface/EDAnalyzer.h"
00016 #include "FWCore/Framework/interface/Event.h"
00017 #include "FWCore/Framework/interface/MakerMacros.h"
00018 
00019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00020 #include "CalibTracker/SiStripHitEfficiency/interface/HitEff.h"
00021 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00022 #include "DataFormats/Common/interface/Handle.h"
00023 #include "FWCore/Framework/interface/ESHandle.h"
00024 #include "FWCore/Framework/interface/EventSetup.h"
00025 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00026 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00027 #include "DataFormats/GeometryVector/interface/LocalVector.h"
00028 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00029 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00030 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
00031 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00032 #include "DataFormats/TrackReco/interface/Track.h"
00033 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00034 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00035 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00036 #include "TrackingTools/Records/interface/TransientRecHitRecord.h" 
00037 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00038 #include "CalibTracker/SiStripHitEfficiency/interface/TrajectoryAtInvalidHit.h"
00039 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00040 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00041 #include "RecoLocalTracker/ClusterParameterEstimator/interface/StripClusterParameterEstimator.h"
00042 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00043 #include "DataFormats/TrackReco/interface/DeDxData.h"
00044 #include "DataFormats/DetId/interface/DetIdCollection.h"
00045 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00046 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
00047 
00048 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00049 #include "AnalysisDataFormats/SiStripClusterInfo/interface/SiStripClusterInfo.h"
00050 #include "CalibTracker/Records/interface/SiStripDetCablingRcd.h"
00051 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
00052 #include "CalibTracker/Records/interface/SiStripQualityRcd.h"
00053 #include "CalibFormats/SiStripObjects/interface/SiStripQuality.h"
00054 #include "DataFormats/SiStripDetId/interface/SiStripSubStructure.h"
00055 #include "Geometry/TrackerGeometryBuilder/interface/GluedGeomDet.h"
00056 #include "DataFormats/Common/interface/DetSetVector.h"
00057 #include "DataFormats/Common/interface/DetSetVectorNew.h"
00058 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h" 
00059 
00060 #include "DataFormats/MuonReco/interface/Muon.h"
00061 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00062 
00063 
00064 #include "TMath.h"
00065 #include "TH1F.h"
00066 
00067 //
00068 // constructors and destructor
00069 //
00070 
00071 using namespace std;
00072 HitEff::HitEff(const edm::ParameterSet& conf) : 
00073   conf_(conf)
00074 {
00075   layers =conf_.getParameter<int>("Layer");
00076   DEBUG = conf_.getParameter<bool>("Debug");
00077 }
00078 
00079 // Virtual destructor needed.
00080 HitEff::~HitEff() { }
00081 
00082 void HitEff::beginJob(){
00083 
00084   edm::Service<TFileService> fs;
00085 
00086   traj = fs->make<TTree>("traj","tree of trajectory positions");
00087   traj->Branch("TrajGlbX",&TrajGlbX,"TrajGlbX/F");
00088   traj->Branch("TrajGlbY",&TrajGlbY,"TrajGlbY/F");
00089   traj->Branch("TrajGlbZ",&TrajGlbZ,"TrajGlbZ/F");
00090   traj->Branch("TrajLocX",&TrajLocX,"TrajLocX/F");
00091   traj->Branch("TrajLocY",&TrajLocY,"TrajLocY/F");
00092   traj->Branch("TrajLocErrX",&TrajLocErrX,"TrajLocErrX/F");
00093   traj->Branch("TrajLocErrY",&TrajLocErrY,"TrajLocErrY/F");
00094   traj->Branch("TrajLocAngleX",&TrajLocAngleX,"TrajLocAngleX/F");
00095   traj->Branch("TrajLocAngleY",&TrajLocAngleY,"TrajLocAngleY/F");
00096   traj->Branch("ClusterLocX",&ClusterLocX,"ClusterLocX/F");
00097   traj->Branch("ClusterLocY",&ClusterLocY,"ClusterLocY/F");
00098   traj->Branch("ClusterLocErrX",&ClusterLocErrX,"ClusterLocErrX/F");
00099   traj->Branch("ClusterLocErrY",&ClusterLocErrY,"ClusterLocErrY/F");
00100   traj->Branch("ClusterStoN",&ClusterStoN,"ClusterStoN/F");
00101   traj->Branch("ResX",&ResX,"ResX/F");
00102   traj->Branch("ResXSig",&ResXSig,"ResXSig/F");
00103   traj->Branch("ModIsBad",&ModIsBad,"ModIsBad/i");
00104   traj->Branch("SiStripQualBad",&SiStripQualBad,"SiStripQualBad/i");
00105   traj->Branch("withinAcceptance",&withinAcceptance,"withinAcceptance/O");
00106   traj->Branch("nHits",&nHits,"nHits/I");
00107   traj->Branch("nLostHits",&nLostHits,"nLostHits/I");
00108   traj->Branch("chi2",&chi2,"chi2/F");
00109   traj->Branch("p",&p,"p/F");
00110   traj->Branch("pT",&pT,"pT/F");
00111   traj->Branch("trajHitValid", &trajHitValid, "trajHitValid/i");
00112   traj->Branch("Id",&Id,"Id/i");
00113   traj->Branch("run",&run,"run/i");
00114   traj->Branch("event",&event,"event/i");
00115   traj->Branch("layer",&whatlayer,"layer/i");
00116   traj->Branch("timeDT",&timeDT,"timeDT/F");
00117   traj->Branch("timeDTErr",&timeDTErr,"timeDTErr/F");
00118   traj->Branch("timeDTDOF",&timeDTDOF,"timeDTDOF/I");
00119   traj->Branch("timeECAL",&timeECAL,"timeECAL/F");
00120   traj->Branch("dedx",&dedx,"dedx/F");
00121   traj->Branch("dedxNOM",&dedxNOM,"dedxNOM/I"); 
00122   traj->Branch("tquality",&tquality,"tquality/I");
00123   traj->Branch("istep",&istep,"istep/I");
00124   traj->Branch("bunchx",&bunchx,"bunchx/I");
00125 
00126   events = 0;
00127   EventTrackCKF = 0;
00128   
00129 }
00130 
00131 
00132 void HitEff::analyze(const edm::Event& e, const edm::EventSetup& es){
00133   //Retrieve tracker topology from geometry
00134   edm::ESHandle<TrackerTopology> tTopoHandle;
00135   es.get<IdealGeometryRecord>().get(tTopoHandle);
00136   const TrackerTopology* const tTopo = tTopoHandle.product();
00137 
00138   //  bool DEBUG = false;
00139 
00140   if (DEBUG)  cout << "beginning analyze from HitEff" << endl;
00141 
00142   using namespace edm;
00143   using namespace reco;
00144   // Step A: Get Inputs 
00145 
00146   int run_nr = e.id().run();
00147   int ev_nr = e.id().event();
00148   int bunch_nr = e.bunchCrossing();
00149 
00150   //CombinatoriaTrack
00151   edm::Handle<reco::TrackCollection> trackCollectionCKF;
00152   edm::InputTag TkTagCKF = conf_.getParameter<edm::InputTag>("combinatorialTracks");
00153   e.getByLabel(TkTagCKF,trackCollectionCKF);
00154   
00155   edm::Handle<std::vector<Trajectory> > TrajectoryCollectionCKF;
00156   edm::InputTag TkTrajCKF = conf_.getParameter<edm::InputTag>("trajectories");
00157   e.getByLabel(TkTrajCKF,TrajectoryCollectionCKF);
00158   
00159   // Clusters
00160   // get the SiStripClusters from the event
00161   edm::Handle< edmNew::DetSetVector<SiStripCluster> > theClusters;
00162   e.getByLabel("siStripClusters", theClusters);
00163 
00164   //get tracker geometry
00165   edm::ESHandle<TrackerGeometry> tracker;
00166   es.get<TrackerDigiGeometryRecord>().get(tracker);
00167   const TrackerGeometry * tkgeom=&(* tracker);
00168 
00169   //get Cluster Parameter Estimator
00170   //std::string cpe = conf_.getParameter<std::string>("StripCPE");
00171   edm::ESHandle<StripClusterParameterEstimator> parameterestimator;
00172   es.get<TkStripCPERecord>().get("StripCPEfromTrackAngle", parameterestimator); 
00173   const StripClusterParameterEstimator &stripcpe(*parameterestimator);
00174 
00175   // get the SiStripQuality records
00176   edm::ESHandle<SiStripQuality> SiStripQuality_;
00177   try {
00178     es.get<SiStripQualityRcd>().get("forCluster",SiStripQuality_);
00179   }
00180   catch (...) {
00181     es.get<SiStripQualityRcd>().get(SiStripQuality_);
00182   }
00183   
00184   edm::ESHandle<MagneticField> magFieldHandle;
00185   es.get<IdealMagneticFieldRecord>().get(magFieldHandle);
00186   const MagneticField* magField_ = magFieldHandle.product();
00187 
00188   // get the list of module IDs with FED-detected errors
00189   edm::Handle< DetIdCollection > fedErrorIds;
00190   e.getByLabel("siStripDigis", fedErrorIds );
00191 
00192   ESHandle<MeasurementTracker> measurementTrackerHandle;
00193   es.get<CkfComponentsRecord>().get(measurementTrackerHandle);
00194 
00195   edm::ESHandle<Chi2MeasurementEstimatorBase> est;
00196   es.get<TrackingComponentsRecord>().get("Chi2",est);
00197 
00198   edm::ESHandle<Propagator> prop;
00199   es.get<TrackingComponentsRecord>().get("PropagatorWithMaterial",prop);
00200   const Propagator* thePropagator = prop.product();
00201 
00202   events++;
00203   
00204   // *************** SiStripCluster Collection
00205   const edmNew::DetSetVector<SiStripCluster>& input = *theClusters;
00206 
00207   //go through clusters to write out global position of good clusters for the layer understudy for comparison
00208   // Loop through clusters just to print out locations
00209   // Commented out to avoid discussion, should really be deleted.
00210   /*
00211   for (edmNew::DetSetVector<SiStripCluster>::const_iterator DSViter = input.begin(); DSViter != input.end(); DSViter++) {
00212     // DSViter is a vector of SiStripClusters located on a single module
00213     unsigned int ClusterId = DSViter->id();
00214     DetId ClusterDetId(ClusterId);
00215     const StripGeomDetUnit * stripdet=(const StripGeomDetUnit*)tkgeom->idToDetUnit(ClusterDetId);
00216     
00217     edmNew::DetSet<SiStripCluster>::const_iterator begin=DSViter->begin();
00218     edmNew::DetSet<SiStripCluster>::const_iterator end  =DSViter->end();
00219     for(edmNew::DetSet<SiStripCluster>::const_iterator iter=begin;iter!=end;++iter) {
00220       //iter is a single SiStripCluster
00221       StripClusterParameterEstimator::LocalValues parameters=stripcpe.localParameters(*iter,*stripdet);
00222       
00223       const Surface* surface;
00224       surface = &(tracker->idToDet(ClusterDetId)->surface());
00225       LocalPoint lp = parameters.first;
00226       GlobalPoint gp = surface->toGlobal(lp);
00227       unsigned int layer = checkLayer(ClusterId, tTopo);
00228             if(DEBUG) cout << "Found hit in cluster collection layer = " << layer << " with id = " << ClusterId << "   local X position = " << lp.x() << " +- " << sqrt(parameters.second.xx()) << "   matched/stereo/rphi = " << ((ClusterId & 0x3)==0) << "/" << ((ClusterId & 0x3)==1) << "/" << ((ClusterId & 0x3)==2) << endl;
00229     }
00230   }
00231   */
00232   
00233   // Tracking 
00234   const   reco::TrackCollection *tracksCKF=trackCollectionCKF.product();
00235   if (DEBUG)  cout << "number ckf tracks found = " << tracksCKF->size() << endl;
00236   //if (tracksCKF->size() == 1 ){
00237   if (tracksCKF->size() > 0 && tracksCKF->size()<100) {
00238     if (DEBUG)    cout << "starting checking good event with < 100 tracks" << endl;
00239 
00240     EventTrackCKF++;  
00241 
00242     /*
00243 
00244     //get dEdx info if available
00245     Handle<ValueMap<DeDxData> >          dEdxUncalibHandle;
00246     if (e.getByLabel("dedxMedianCTF", dEdxUncalibHandle)) {
00247       const ValueMap<DeDxData> dEdxTrackUncalib = *dEdxUncalibHandle.product();
00248       
00249       reco::TrackRef itTrack  = reco::TrackRef( trackCollectionCKF, 0 );
00250       dedx = dEdxTrackUncalib[itTrack].dEdx();
00251       dedxNOM  = dEdxTrackUncalib[itTrack].numberOfMeasurements();
00252     } else {
00253       dedx = -999.0; dedxNOM = -999;
00254     }
00255 
00256     */
00257 
00258     //get muon and ecal timing info if available
00259     Handle<MuonCollection> muH;
00260     if(e.getByLabel("muonsWitht0Correction",muH)){
00261       const MuonCollection & muonsT0  =  *muH.product();
00262       if(muonsT0.size()!=0) {
00263         MuonTime mt0 = muonsT0[0].time();
00264         timeDT = mt0.timeAtIpInOut; 
00265         timeDTErr = mt0.timeAtIpInOutErr;
00266         timeDTDOF = mt0.nDof;
00267         
00268         bool hasCaloEnergyInfo = muonsT0[0].isEnergyValid();
00269         if (hasCaloEnergyInfo) timeECAL = muonsT0[0].calEnergy().ecal_time;
00270       }
00271     } else {
00272       timeDT = -999.0; timeDTErr = -999.0; timeDTDOF = -999; timeECAL = -999.0;
00273     }
00274 
00275     // actually should do a loop over all the tracks in the event here
00276 
00277     for (vector<Trajectory>::const_iterator itraj = TrajectoryCollectionCKF.product()->begin();
00278          itraj != TrajectoryCollectionCKF.product()->end();
00279          itraj++) {
00280 
00281       // for each track, fill some variables such as number of hits and momentum
00282       nHits = itraj->foundHits();
00283       nLostHits = itraj->lostHits();
00284       chi2 = (itraj->chiSquared()/itraj->ndof());
00285       pT = sqrt( ( itraj->lastMeasurement().updatedState().globalMomentum().x() *
00286                    itraj->lastMeasurement().updatedState().globalMomentum().x()) +
00287                  ( itraj->lastMeasurement().updatedState().globalMomentum().y() *
00288                    itraj->lastMeasurement().updatedState().globalMomentum().y()) );
00289       p = itraj->lastMeasurement().updatedState().globalMomentum().mag();
00290       
00291       //Put in code to check track quality
00292       
00293       
00294       std::vector<TrajectoryMeasurement> TMeas=itraj->measurements();
00295       vector<TrajectoryMeasurement>::iterator itm;
00296       double xloc = 0.;
00297       double yloc = 0.;
00298       double xErr = 0.;
00299       double yErr = 0.;
00300       double angleX = -999.;
00301       double angleY = -999.;
00302       double xglob,yglob,zglob;
00303       
00304       for (itm=TMeas.begin();itm!=TMeas.end();itm++){
00305         ConstReferenceCountingPointer<TransientTrackingRecHit> theInHit;
00306         theInHit = (*itm).recHit();
00307         
00308         if(DEBUG) cout << "theInHit is valid = " << theInHit->isValid() << endl;
00309         
00310         unsigned int iidd = theInHit->geographicalId().rawId();
00311         
00312         unsigned int TKlayers = checkLayer(iidd, tTopo);
00313         if (DEBUG)      cout << "TKlayer from trajectory: " << TKlayers << "  from module = " << iidd <<  "   matched/stereo/rphi = " << ((iidd & 0x3)==0) << "/" << ((iidd & 0x3)==1) << "/" << ((iidd & 0x3)==2) << endl;
00314 
00315         // If Trajectory measurement from TOB 6 or TEC 9, skip it because it's always valid they are filled later
00316         if ( TKlayers == 10 || TKlayers == 22 ) {
00317           if (DEBUG) cout << "skipping original TM for TOB 6 or TEC 9" << endl;
00318           continue;
00319         }
00320 
00321         // Make vector of TrajectoryAtInvalidHits to hold the trajectories
00322         std::vector<TrajectoryAtInvalidHit> TMs;
00323         
00324         // Make AnalyticalPropagator to use in TAVH constructor
00325         AnalyticalPropagator propagator(magField_,anyDirection); 
00326         
00327         // for double sided layers check both sensors--if no hit was found on either sensor surface,
00328         // the trajectory measurements only have one invalid hit entry on the matched surface
00329         // so get the TrajectoryAtInvalidHit for both surfaces and include them in the study
00330         if (isDoubleSided(iidd, tTopo) &&  ((iidd & 0x3)==0) ) {
00331           // do hit eff check twice--once for each sensor
00332           //add a TM for each surface
00333           TMs.push_back(TrajectoryAtInvalidHit(*itm, tTopo, tkgeom, propagator, 1));
00334           TMs.push_back(TrajectoryAtInvalidHit(*itm, tTopo, tkgeom, propagator, 2));
00335         } else if ( isDoubleSided(iidd, tTopo) && (!check2DPartner(iidd, TMeas)) ) {
00336           // if only one hit was found the trajectory measurement is on that sensor surface, and the other surface from
00337           // the matched layer should be added to the study as well
00338           TMs.push_back(TrajectoryAtInvalidHit(*itm, tTopo, tkgeom, propagator, 1));
00339           TMs.push_back(TrajectoryAtInvalidHit(*itm, tTopo, tkgeom, propagator, 2));
00340           if (DEBUG) cout << " found a hit with a missing partner" << endl;
00341         } else {
00342           //only add one TM for the single surface and the other will be added in the next iteration
00343           TMs.push_back(TrajectoryAtInvalidHit(*itm, tTopo, tkgeom, propagator));
00344         }
00345 
00347         //Now check for tracks at TOB6 and TEC9
00348 
00349         // to make sure we only propagate on the last TOB5 hit check the next entry isn't also in TOB5
00350         // to avoid bias, make sure the TOB5 hit is valid (an invalid hit on TOB5 could only exist with a valid hit on TOB6)
00351 
00352         bool isValid = theInHit->isValid();
00353         bool isLast = (itm==(TMeas.end()-1));
00354         bool isLastTOB5 = true;
00355         if (!isLast) {
00356           if ( checkLayer((++itm)->recHit()->geographicalId().rawId(), tTopo) == 9 ) isLastTOB5 = false;
00357           else isLastTOB5 = true;
00358           --itm;
00359         }
00360         
00361         if ( TKlayers==9 && isValid && isLastTOB5 ) {
00362           //      if ( TKlayers==9 && itm==TMeas.rbegin()) {
00363         //        if ( TKlayers==9 && (itm==TMeas.back()) ) {     // to check for only the last entry in the trajectory for propagation
00364           std::vector< BarrelDetLayer*> barrelTOBLayers = measurementTrackerHandle->geometricSearchTracker()->tobLayers() ;
00365           const DetLayer* tob6 = barrelTOBLayers[barrelTOBLayers.size()-1];
00366           const MeasurementEstimator* estimator = est.product();
00367           const LayerMeasurements* theLayerMeasurements = new LayerMeasurements(&*measurementTrackerHandle);
00368           const TrajectoryStateOnSurface tsosTOB5 = itm->updatedState();
00369           vector<TrajectoryMeasurement> tmp = theLayerMeasurements->measurements(*tob6, tsosTOB5, *thePropagator, *estimator);
00370           
00371           if ( !tmp.empty()) {
00372             if (DEBUG) cout << "size of TM from propagation = " << tmp.size() << endl;
00373 
00374             // take the last of the TMs, which is always an invalid hit
00375             // if no detId is available, ie detId==0, then no compatible layer was crossed
00376             // otherwise, use that TM for the efficiency measurement
00377             TrajectoryMeasurement tob6TM(tmp.back());
00378             ConstReferenceCountingPointer<TransientTrackingRecHit> tob6Hit;
00379             tob6Hit = tob6TM.recHit();
00380             
00381             if (tob6Hit->geographicalId().rawId()!=0) {
00382               if (DEBUG) cout << "tob6 hit actually being added to TM vector" << endl;
00383               TMs.push_back(TrajectoryAtInvalidHit(tob6TM, tTopo, tkgeom, propagator));
00384             }
00385           }
00386         }
00387 
00388         bool isLastTEC8 = true;
00389         if (!isLast) {
00390           if ( checkLayer((++itm)->recHit()->geographicalId().rawId(), tTopo) == 21 ) isLastTEC8 = false;
00391           else isLastTEC8 = true;
00392           --itm;
00393         }
00394         
00395         if ( TKlayers==21 && isValid && isLastTEC8 ) {
00396           
00397           std::vector< ForwardDetLayer*> posTecLayers = measurementTrackerHandle->geometricSearchTracker()->posTecLayers() ;
00398           const DetLayer* tec9pos = posTecLayers[posTecLayers.size()-1];
00399           std::vector< ForwardDetLayer*> negTecLayers = measurementTrackerHandle->geometricSearchTracker()->negTecLayers() ;
00400           const DetLayer* tec9neg = negTecLayers[negTecLayers.size()-1];
00401           
00402           const MeasurementEstimator* estimator = est.product();
00403           const LayerMeasurements* theLayerMeasurements = new LayerMeasurements(&*measurementTrackerHandle);
00404           const TrajectoryStateOnSurface tsosTEC9 = itm->updatedState();
00405           
00406           // check if track on positive or negative z
00407           if (!iidd ==  StripSubdetector::TEC) cout << "there is a problem with TEC 9 extrapolation" << endl;
00408           
00409           //cout << " tec9 id = " << iidd << " and side = " << tTopo->tecSide(iidd) << endl;
00410           vector<TrajectoryMeasurement> tmp;
00411           if ( tTopo->tecSide(iidd) == 1 ) {
00412             tmp = theLayerMeasurements->measurements(*tec9neg, tsosTEC9, *thePropagator, *estimator);
00413             //cout << "on negative side" << endl;
00414           }
00415           if ( tTopo->tecSide(iidd) == 2 ) {
00416             tmp = theLayerMeasurements->measurements(*tec9pos, tsosTEC9, *thePropagator, *estimator);
00417             //cout << "on positive side" << endl;
00418           }
00419 
00420           if ( !tmp.empty()) {
00421             // take the last of the TMs, which is always an invalid hit
00422             // if no detId is available, ie detId==0, then no compatible layer was crossed
00423             // otherwise, use that TM for the efficiency measurement
00424             TrajectoryMeasurement tec9TM(tmp.back());
00425             ConstReferenceCountingPointer<TransientTrackingRecHit> tec9Hit;
00426             tec9Hit = tec9TM.recHit();
00427             
00428             unsigned int tec9id = tec9Hit->geographicalId().rawId();
00429             if (DEBUG) cout << "tec9id = " << tec9id << " is Double sided = " <<  isDoubleSided(tec9id, tTopo) << "  and 0x3 = " << (tec9id & 0x3) << endl;
00430             
00431             if (tec9Hit->geographicalId().rawId()!=0) {
00432               if (DEBUG) cout << "tec9 hit actually being added to TM vector" << endl;
00433               // in tec the hit can be single or doubled sided. whenever the invalid hit at the end of vector of TMs is
00434               // double sided it is always on the matched surface, so we need to split it into the true sensor surfaces
00435               if (isDoubleSided(tec9id, tTopo)) {
00436                 TMs.push_back(TrajectoryAtInvalidHit(tec9TM, tTopo, tkgeom, propagator, 1));
00437                 TMs.push_back(TrajectoryAtInvalidHit(tec9TM, tTopo, tkgeom, propagator, 2));
00438               } else 
00439                 TMs.push_back(TrajectoryAtInvalidHit(tec9TM, tTopo, tkgeom, propagator));
00440             }
00441           } //else cout << "tec9 tmp empty" << endl;
00442         }
00443         
00445         
00446         // Modules Constraints
00447 
00448         for(std::vector<TrajectoryAtInvalidHit>::const_iterator TM=TMs.begin();TM!=TMs.end();++TM) {
00449           
00450           // --> Get trajectory from combinatedState 
00451           iidd = TM->monodet_id();
00452           if (DEBUG) cout << "setting iidd = " << iidd << " before checking efficiency and ";
00453           
00454           xloc = TM->localX();
00455           yloc = TM->localY();
00456           
00457           xErr =  TM->localErrorX();
00458           yErr =  TM->localErrorY();
00459           
00460           angleX = atan( TM->localDxDz() );
00461           angleY = atan( TM->localDyDz() );
00462           
00463           xglob = TM->globalX();
00464           yglob = TM->globalY();
00465           zglob = TM->globalZ();
00466           withinAcceptance = TM->withinAcceptance();
00467           
00468           trajHitValid = TM->validHit();
00469 
00470           // reget layer from iidd here, to account for TOB 6 and TEC 9 TKlayers being off
00471           TKlayers = checkLayer(iidd, tTopo);
00472 
00473           if ( (layers == TKlayers) || (layers == 0) ) {   // Look at the layer not used to reconstruct the track
00474             whatlayer = TKlayers;
00475             if (DEBUG)    cout << "Looking at layer under study" << endl;
00476             TrajGlbX = 0.0; TrajGlbY = 0.0; TrajGlbZ = 0.0; ModIsBad = 2; Id = 0; SiStripQualBad = 0; 
00477             run = 0; event = 0; TrajLocX = 0.0; TrajLocY = 0.0; TrajLocErrX = 0.0; TrajLocErrY = 0.0; 
00478             TrajLocAngleX = -999.0; TrajLocAngleY = -999.0;     ResX = 0.0; ResXSig = 0.0;
00479             ClusterLocX = 0.0; ClusterLocY = 0.0; ClusterLocErrX = 0.0; ClusterLocErrY = 0.0; ClusterStoN = 0.0;
00480             bunchx = 0;
00481             
00482             // RPhi RecHit Efficiency 
00483             
00484             if (input.size() > 0 ) {  
00485               if (DEBUG) cout << "Checking clusters with size = " << input.size() << endl;
00486               int nClusters = 0;
00487               std::vector< std::vector<float> > VCluster_info; //fill with X residual, X residual pull, local X, sig(X), local Y, sig(Y), StoN
00488               for (edmNew::DetSetVector<SiStripCluster>::const_iterator DSViter = input.begin(); DSViter != input.end(); DSViter++) {
00489                 // DSViter is a vector of SiStripClusters located on a single module
00490                 //if (DEBUG)      cout << "the ID from the DSViter = " << DSViter->id() << endl; 
00491                 unsigned int ClusterId = DSViter->id();
00492                 if (ClusterId == iidd) {
00493                   if (DEBUG) cout << "found  (ClusterId == iidd) with ClusterId = " << ClusterId << " and iidd = " << iidd << endl;
00494                   DetId ClusterDetId(ClusterId);
00495                   const StripGeomDetUnit * stripdet=(const StripGeomDetUnit*)tkgeom->idToDetUnit(ClusterDetId);
00496                   
00497                   for(edmNew::DetSet<SiStripCluster>::const_iterator iter=DSViter->begin();iter!=DSViter->end();++iter) {
00498                     //iter is a single SiStripCluster
00499                     StripClusterParameterEstimator::LocalValues parameters=stripcpe.localParameters(*iter,*stripdet);
00500                     float res = (parameters.first.x() - xloc);
00501                     float sigma = checkConsistency(parameters , xloc, xErr);
00502                     // The consistency is probably more accurately measured with the Chi2MeasurementEstimator. To use it
00503                     // you need a TransientTrackingRecHit instead of the cluster
00504                     //theEstimator=       new Chi2MeasurementEstimator(30);
00505                     //const Chi2MeasurementEstimator *theEstimator(100);
00506                     //theEstimator->estimate(TM->tsos(), TransientTrackingRecHit);
00507                     
00508                     SiStripClusterInfo clusterInfo = SiStripClusterInfo(*iter, es, ClusterId);  
00509                     // signal to noise from SiStripClusterInfo not working in 225. I'll fix this after the interface
00510                     // redesign in 300 -ku
00511                     //float cluster_info[7] = {res, sigma, parameters.first.x(), sqrt(parameters.second.xx()), parameters.first.y(), sqrt(parameters.second.yy()), signal_to_noise};
00512                     std::vector< float > cluster_info;
00513                     cluster_info.push_back(res); 
00514                     cluster_info.push_back(sigma);
00515                     cluster_info.push_back(parameters.first.x()); 
00516                     cluster_info.push_back(sqrt(parameters.second.xx()));
00517                     cluster_info.push_back(parameters.first.y());
00518                     cluster_info.push_back(sqrt(parameters.second.yy()));
00519                     cluster_info.push_back( clusterInfo.signalOverNoise() );
00520                     //cluster_info.push_back( clusterInfo.getSignalOverNoise() );
00521                     VCluster_info.push_back(cluster_info);
00522                     nClusters++;
00523                     if (DEBUG) cout << "Have ID match. residual = " << VCluster_info.back()[0] << "  res sigma = " << VCluster_info.back()[1] << endl;
00524                     if (DEBUG) cout << "trajectory measurement compatability estimate = " << (*itm).estimate() << endl;
00525                     if (DEBUG) cout << "hit position = " << parameters.first.x() << "  hit error = " << sqrt(parameters.second.xx()) << "  trajectory position = " << xloc << "  traj error = " << xErr << endl;
00526                   }
00527                 }
00528               }
00529               float FinalResSig = 1000.0;
00530               float FinalCluster[7]= {1000.0, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0};
00531               if (nClusters > 0) {
00532                 if (DEBUG) cout << "found clusters > 0" << endl;
00533                 if (nClusters > 1) {
00534                   //get the smallest one
00535                   vector< vector<float> >::iterator ires;
00536                   for (ires=VCluster_info.begin(); ires!=VCluster_info.end(); ires++){
00537                     if ( abs((*ires)[1]) < abs(FinalResSig)) {
00538                       FinalResSig = (*ires)[1];
00539                       for (unsigned int i = 0; i<ires->size(); i++) {
00540                         if (DEBUG) cout << "filling final cluster. i = " << i << " before fill FinalCluster[i]=" << FinalCluster[i] << " and (*ires)[i] =" << (*ires)[i] << endl;
00541                         FinalCluster[i] = (*ires)[i];
00542                         if (DEBUG) cout << "filling final cluster. i = " << i << " after fill FinalCluster[i]=" << FinalCluster[i] << " and (*ires)[i] =" << (*ires)[i] << endl;
00543                       }
00544                     }
00545                     if (DEBUG) cout << "iresidual = " << (*ires)[0] << "  isigma = " << (*ires)[1] << "  and FinalRes = " << FinalCluster[0] << endl;
00546                   }
00547                 }
00548                 else {
00549                   FinalResSig = VCluster_info.at(0)[1];
00550                   for (unsigned int i = 0; i<VCluster_info.at(0).size(); i++) {
00551                     FinalCluster[i] = VCluster_info.at(0)[i];
00552                   }
00553                 }
00554                 nClusters=0;
00555                 VCluster_info.clear();
00556               }
00557               
00558               if (DEBUG) cout << "Final residual in X = " << FinalCluster[0] << "+-" << (FinalCluster[0]/FinalResSig) << endl;
00559               if (DEBUG) cout << "Checking location of trajectory: abs(yloc) = " << abs(yloc) << "  abs(xloc) = " << abs(xloc) << endl;
00560               if (DEBUG) cout << "Checking location of cluster hit: yloc = " << FinalCluster[4] << "+-" << FinalCluster[5] << "  xloc = " << FinalCluster[2] << "+-" << FinalCluster[3] << endl;
00561               if (DEBUG) cout << "Final cluster signal to noise = " << FinalCluster[6] << endl;
00562               
00563               float exclusionWidth = 0.4;
00564               float TOBexclusion = 0.0;
00565               float TECexRing5 = -0.89;
00566               float TECexRing6 = -0.56;
00567               float TECexRing7 = 0.60;
00568               //Added by Chris Edelmaier to do TEC bonding exclusion
00569               int subdetector = ((iidd>>25) & 0x7);            
00570               int ringnumber = ((iidd>>5) & 0x7);
00571               
00572               //New TOB and TEC bonding region exclusion zone
00573               if((TKlayers >= 5 && TKlayers < 11)||((subdetector == 6)&&( (ringnumber >= 5)&&(ringnumber <=7) ))) {
00574                 //There are only 2 cases that we need to exclude for
00575                 float highzone = 0.0;
00576                 float lowzone = 0.0;
00577                 float higherr = yloc + 5.0*yErr;
00578                 float lowerr = yloc - 5.0*yErr;
00579                 if(TKlayers >= 5 && TKlayers < 11) {
00580                   //TOB zone
00581                   highzone = TOBexclusion + exclusionWidth;
00582                   lowzone = TOBexclusion - exclusionWidth;
00583                 } else if (ringnumber == 5) {
00584                   //TEC ring 5
00585                   highzone = TECexRing5 + exclusionWidth;
00586                   lowzone = TECexRing5 - exclusionWidth;
00587                 } else if (ringnumber == 6) {
00588                   //TEC ring 6
00589                   highzone = TECexRing6 + exclusionWidth;
00590                   lowzone = TECexRing6 - exclusionWidth;
00591                 } else if (ringnumber == 7) {
00592                   //TEC ring 7
00593                   highzone = TECexRing7 + exclusionWidth;
00594                   lowzone = TECexRing7 - exclusionWidth;
00595                 }
00596                 //Now that we have our exclusion region, we just have to properly identify it
00597                 if((highzone <= higherr)&&(highzone >= lowerr)) withinAcceptance = false;
00598                 if((lowzone >= lowerr)&&(lowzone <= higherr)) withinAcceptance = false;
00599                 if((higherr <= highzone)&&(higherr >= lowzone)) withinAcceptance = false;
00600                 if((lowerr >= lowzone)&&(lowerr <= highzone)) withinAcceptance = false;
00601               }
00602               
00603               // fill ntuple varibles
00604               //get global position from module id number iidd
00605               TrajGlbX = xglob;
00606               TrajGlbY = yglob;
00607               TrajGlbZ = zglob;   
00608               Id = iidd;
00609               run = run_nr;
00610               event = ev_nr;
00611               bunchx = bunch_nr;
00612               //if ( SiStripQuality_->IsModuleBad(iidd) ) {
00613               if ( SiStripQuality_->getBadApvs(iidd)!=0 ) {
00614                 SiStripQualBad = 1; 
00615                 if(DEBUG) cout << "strip is bad from SiStripQuality" << endl;
00616               } else {
00617                 SiStripQualBad = 0; 
00618                 if(DEBUG) cout << "strip is good from SiStripQuality" << endl;
00619               }
00620 
00621               //check for FED-detected errors and include those in SiStripQualBad
00622               for (unsigned int ii=0;ii< fedErrorIds->size();ii++) {
00623                 if (iidd == (*fedErrorIds)[ii].rawId() )
00624                   SiStripQualBad = 1;
00625               }
00626               
00627               TrajLocX = xloc;
00628               TrajLocY = yloc;
00629               TrajLocErrX = xErr;
00630               TrajLocErrY = yErr;
00631               TrajLocAngleX = angleX;
00632               TrajLocAngleY = angleY;
00633               ResX = FinalCluster[0];
00634               ResXSig = FinalResSig;
00635               if (FinalResSig != FinalCluster[1]) if (DEBUG) cout << "Problem with best cluster selection because FinalResSig = " << FinalResSig << " and FinalCluster[1] = " << FinalCluster[1] << endl;
00636               ClusterLocX = FinalCluster[2];
00637               ClusterLocY = FinalCluster[4];
00638               ClusterLocErrX = FinalCluster[3];
00639               ClusterLocErrY = FinalCluster[5];
00640               ClusterStoN = FinalCluster[6];
00641               
00642               if (DEBUG)              cout << "before check good" << endl;
00643               
00644               if ( FinalResSig < 999.0) {  //could make requirement on track/hit consistency, but for
00645                 //now take anything with a hit on the module
00646                 if (DEBUG) cout << "hit being counted as good " << FinalCluster[0] << " FinalRecHit " << 
00647                   iidd << "   TKlayers  "  <<  TKlayers  << " xloc " <<  xloc << " yloc  " << yloc << " module " << iidd << 
00648                   "   matched/stereo/rphi = " << ((iidd & 0x3)==0) << "/" << ((iidd & 0x3)==1) << "/" << ((iidd & 0x3)==2) << endl;
00649                 ModIsBad = 0;
00650                 traj->Fill();
00651               }
00652               else {
00653                 if (DEBUG)  cout << "hit being counted as bad   ######### Invalid RPhi FinalResX " << FinalCluster[0] << " FinalRecHit " << 
00654                   iidd << "   TKlayers  "  <<  TKlayers  << " xloc " <<  xloc << " yloc  " << yloc << " module " << iidd << 
00655                   "   matched/stereo/rphi = " << ((iidd & 0x3)==0) << "/" << ((iidd & 0x3)==1) << "/" << ((iidd & 0x3)==2) << endl;
00656                 ModIsBad = 1;
00657                 traj->Fill();
00658                 
00659                 if (DEBUG) cout << " RPhi Error " << sqrt(xErr*xErr + yErr*yErr) << " ErrorX " << xErr << " yErr " <<  yErr <<  endl;
00660               } if (DEBUG) cout << "after good location check" << endl;
00661             } if (DEBUG) cout << "after list of clusters" << endl;
00662           } if (DEBUG) cout << "After layers=TKLayers if" << endl;
00663         } if (DEBUG) cout << "After looping over TrajAtValidHit list" << endl;
00664       } if (DEBUG) cout << "end TMeasurement loop" << endl;
00665     } if (DEBUG) cout << "end of trajectories loop" << endl;
00666   }
00667 }
00668 
00669 void HitEff::endJob(){
00670   traj->GetDirectory()->cd();
00671   traj->Write();  
00672   
00673   if (DEBUG) cout << " Events Analysed             " <<  events          << endl;
00674   if (DEBUG) cout << " Number Of Tracked events    " <<  EventTrackCKF   << endl;
00675 }
00676 
00677 double HitEff::checkConsistency(const StripClusterParameterEstimator::LocalValues& parameters, double xx, double xerr) {
00678   double error = sqrt(parameters.second.xx() + xerr*xerr);
00679   double separation = abs(parameters.first.x() - xx);
00680   double consistency = separation/error;
00681   return consistency;
00682 }
00683 
00684 bool HitEff::isDoubleSided(unsigned int iidd, const TrackerTopology* tTopo) const {
00685   StripSubdetector strip=StripSubdetector(iidd);
00686   unsigned int subid=strip.subdetId();
00687   unsigned int layer = 0;
00688   if (subid ==  StripSubdetector::TIB) { 
00689     
00690     layer = tTopo->tibLayer(iidd);
00691     if (layer == 1 || layer == 2) return true;
00692     else return false;
00693   }
00694   else if (subid ==  StripSubdetector::TOB) { 
00695     
00696     layer = tTopo->tobLayer(iidd) + 4 ; 
00697     if (layer == 5 || layer == 6) return true;
00698     else return false;
00699   }
00700   else if (subid ==  StripSubdetector::TID) { 
00701     
00702     layer = tTopo->tidRing(iidd) + 10;
00703     if (layer == 11 || layer == 12) return true;
00704     else return false;
00705   }
00706   else if (subid ==  StripSubdetector::TEC) { 
00707     
00708     layer = tTopo->tecRing(iidd) + 13 ; 
00709     if (layer == 14 || layer == 15 || layer == 18) return true;
00710     else return false;
00711   }
00712   else
00713     return false;
00714 }
00715 
00716 bool HitEff::check2DPartner(unsigned int iidd, const std::vector<TrajectoryMeasurement>& traj) {
00717   unsigned int partner_iidd = 0;
00718   bool found2DPartner = false;
00719   // first get the id of the other detector
00720   if ((iidd & 0x3)==1) partner_iidd = iidd+1;
00721   if ((iidd & 0x3)==2) partner_iidd = iidd-1;
00722   // next look in the trajectory measurements for a measurement from that detector
00723   // loop through trajectory measurements to find the partner_iidd
00724   for (std::vector<TrajectoryMeasurement>::const_iterator iTM=traj.begin(); iTM!=traj.end(); ++iTM) {
00725     if (iTM->recHit()->geographicalId().rawId()==partner_iidd) {
00726       found2DPartner = true;
00727     }
00728   }
00729   return found2DPartner;
00730 }
00731 
00732 unsigned int HitEff::checkLayer( unsigned int iidd, const TrackerTopology* tTopo) {
00733   StripSubdetector strip=StripSubdetector(iidd);
00734   unsigned int subid=strip.subdetId();
00735   if (subid ==  StripSubdetector::TIB) { 
00736     
00737     return tTopo->tibLayer(iidd);
00738   }
00739   if (subid ==  StripSubdetector::TOB) { 
00740     
00741     return tTopo->tobLayer(iidd) + 4 ; 
00742   }
00743   if (subid ==  StripSubdetector::TID) { 
00744     
00745     return tTopo->tidWheel(iidd) + 10;
00746   }
00747   if (subid ==  StripSubdetector::TEC) { 
00748     
00749     return tTopo->tecWheel(iidd) + 13 ; 
00750   }
00751   return 0;
00752 }
00753 
00754 //define this as a plug-in
00755 DEFINE_FWK_MODULE(HitEff);