CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoTracker/DeDx/src/DeDxDiscriminatorProducer.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    DeDxDiscriminatorProducer
00004 // Class:      DeDxDiscriminatorProducer
00005 // 
00013 //
00014 // Original Author:  andrea
00015 //         Created:  Thu May 31 14:09:02 CEST 2007
00016 //    Code Updates:  loic Quertenmont (querten)
00017 //         Created:  Thu May 10 14:09:02 CEST 2008
00018 // $Id: DeDxDiscriminatorProducer.cc,v 1.21 2011/07/28 14:22:55 vlimant Exp $
00019 //
00020 //
00021 
00022 
00023 // system include files
00024 #include <memory>
00025 #include "DataFormats/Common/interface/ValueMap.h"
00026 #include "DataFormats/TrackReco/interface/DeDxData.h"
00027 
00028 #include "RecoTracker/DeDx/interface/DeDxDiscriminatorProducer.h"
00029 //#include "RecoTracker/DeDx/interface/DeDxTools.h"
00030 #include "DataFormats/TrackReco/interface/Track.h"
00031 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00032 
00033 #include "FWCore/Framework/interface/ESHandle.h"
00034 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00035 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00036 
00037 #include "CondFormats/DataRecord/interface/SiStripDeDxMip_3D_Rcd.h"
00038 #include "CondFormats/DataRecord/interface/SiStripDeDxElectron_3D_Rcd.h"
00039 #include "CondFormats/DataRecord/interface/SiStripDeDxProton_3D_Rcd.h"
00040 #include "CondFormats/DataRecord/interface/SiStripDeDxPion_3D_Rcd.h"
00041 #include "CondFormats/DataRecord/interface/SiStripDeDxKaon_3D_Rcd.h"
00042 
00043 
00044 #include "TFile.h"
00045 
00046 using namespace reco;
00047 using namespace std;
00048 using namespace edm;
00049 
00050 DeDxDiscriminatorProducer::DeDxDiscriminatorProducer(const edm::ParameterSet& iConfig)
00051 {
00052 
00053    produces<ValueMap<DeDxData> >();
00054 
00055    m_tracksTag = iConfig.getParameter<edm::InputTag>("tracks");
00056    m_trajTrackAssociationTag   = iConfig.getParameter<edm::InputTag>("trajectoryTrackAssociation");
00057 
00058    usePixel = iConfig.getParameter<bool>("UsePixel"); 
00059    useStrip = iConfig.getParameter<bool>("UseStrip");
00060    if(!usePixel && !useStrip)
00061    edm::LogWarning("DeDxHitsProducer") << "Pixel Hits AND Strip Hits will not be used to estimate dEdx --> BUG, Please Update the config file";
00062 
00063    Formula             = iConfig.getUntrackedParameter<unsigned>("Formula"            ,  0);
00064    Reccord             = iConfig.getUntrackedParameter<string>  ("Reccord"            , "SiStripDeDxMip_3D_Rcd");
00065    ProbabilityMode     = iConfig.getUntrackedParameter<string>  ("ProbabilityMode"    , "Accumulation");
00066 
00067 
00068    MinTrackMomentum    = iConfig.getUntrackedParameter<double>  ("minTrackMomentum"   ,  0.0);
00069    MaxTrackMomentum    = iConfig.getUntrackedParameter<double>  ("maxTrackMomentum"   ,  99999.0); 
00070    MinTrackEta         = iConfig.getUntrackedParameter<double>  ("minTrackEta"        , -5.0);
00071    MaxTrackEta         = iConfig.getUntrackedParameter<double>  ("maxTrackEta"        ,  5.0);
00072    MaxNrStrips         = iConfig.getUntrackedParameter<unsigned>("maxNrStrips"        ,  255);
00073    MinTrackHits        = iConfig.getUntrackedParameter<unsigned>("MinTrackHits"       ,  3);
00074 
00075    shapetest           = iConfig.getParameter<bool>("ShapeTest");
00076    useCalibration      = iConfig.getParameter<bool>("UseCalibration");
00077    m_calibrationPath   = iConfig.getParameter<string>("calibrationPath");
00078 
00079    Prob_ChargePath = NULL;
00080 }
00081 
00082 
00083 DeDxDiscriminatorProducer::~DeDxDiscriminatorProducer(){}
00084 
00085 // ------------ method called once each job just before starting event loop  ------------
00086 void  DeDxDiscriminatorProducer::beginRun(edm::Run & run, const edm::EventSetup& iSetup)
00087 {
00088    edm::ESHandle<PhysicsTools::Calibration::HistogramD3D> DeDxMapHandle_;    
00089    if(      strcmp(Reccord.c_str(),"SiStripDeDxMip_3D_Rcd")==0){
00090       iSetup.get<SiStripDeDxMip_3D_Rcd>() .get(DeDxMapHandle_);
00091    }else if(strcmp(Reccord.c_str(),"SiStripDeDxPion_3D_Rcd")==0){
00092       iSetup.get<SiStripDeDxPion_3D_Rcd>().get(DeDxMapHandle_);
00093    }else if(strcmp(Reccord.c_str(),"SiStripDeDxKaon_3D_Rcd")==0){
00094       iSetup.get<SiStripDeDxKaon_3D_Rcd>().get(DeDxMapHandle_);
00095    }else if(strcmp(Reccord.c_str(),"SiStripDeDxProton_3D_Rcd")==0){
00096       iSetup.get<SiStripDeDxProton_3D_Rcd>().get(DeDxMapHandle_);
00097    }else if(strcmp(Reccord.c_str(),"SiStripDeDxElectron_3D_Rcd")==0){
00098       iSetup.get<SiStripDeDxElectron_3D_Rcd>().get(DeDxMapHandle_);
00099    }else{
00100 //      printf("The reccord %s is not known by the DeDxDiscriminatorProducer\n", Reccord.c_str());
00101 //      printf("Program will exit now\n");
00102       exit(0);
00103    }
00104    DeDxMap_ = *DeDxMapHandle_.product();
00105 
00106    double xmin = DeDxMap_.rangeX().min;
00107    double xmax = DeDxMap_.rangeX().max;
00108    double ymin = DeDxMap_.rangeY().min;
00109    double ymax = DeDxMap_.rangeY().max;
00110    double zmin = DeDxMap_.rangeZ().min;
00111    double zmax = DeDxMap_.rangeZ().max;
00112 
00113    if(Prob_ChargePath)delete Prob_ChargePath;
00114    Prob_ChargePath  = new TH3D ("Prob_ChargePath"     , "Prob_ChargePath" , DeDxMap_.numberOfBinsX(), xmin, xmax, DeDxMap_.numberOfBinsY() , ymin, ymax, DeDxMap_.numberOfBinsZ(), zmin, zmax);
00115 
00116    
00117 
00118    if(strcmp(ProbabilityMode.c_str(),"Accumulation")==0){
00119 //      printf("LOOOP ON P\n");
00120       for(int i=0;i<=Prob_ChargePath->GetXaxis()->GetNbins()+1;i++){
00121 //         printf("LOOOP ON PATH\n");
00122          for(int j=0;j<=Prob_ChargePath->GetYaxis()->GetNbins()+1;j++){
00123 //            printf("LOOOP ON CHARGE\n");
00124 
00125             double Ni = 0;
00126             for(int k=0;k<=Prob_ChargePath->GetZaxis()->GetNbins()+1;k++){ Ni+=DeDxMap_.binContent(i,j,k);} 
00127 
00128             for(int k=0;k<=Prob_ChargePath->GetZaxis()->GetNbins()+1;k++){
00129                double tmp = 0;
00130                for(int l=0;l<=k;l++){ tmp+=DeDxMap_.binContent(i,j,l);}
00131 
00132                if(Ni>0){
00133                   Prob_ChargePath->SetBinContent (i, j, k, tmp/Ni);
00134 //                printf("P=%6.2f Path=%6.2f Charge%8.2f --> Prob=%8.3f\n",Prob_ChargePath->GetXaxis()->GetBinCenter(i), Prob_ChargePath->GetYaxis()->GetBinCenter(j), Prob_ChargePath->GetZaxis()->GetBinCenter(k), tmp/Ni);
00135                }else{
00136                   Prob_ChargePath->SetBinContent (i, j, k, 0);
00137                }
00138             }
00139          }
00140       }
00141    }else if(strcmp(ProbabilityMode.c_str(),"Integral")==0){
00142 //      printf("LOOOP ON P\n");
00143       for(int i=0;i<=Prob_ChargePath->GetXaxis()->GetNbins()+1;i++){
00144 //         printf("LOOOP ON PATH\n");
00145          for(int j=0;j<=Prob_ChargePath->GetYaxis()->GetNbins()+1;j++){
00146 //            printf("LOOOP ON CHARGE\n");
00147 
00148             double Ni = 0;
00149             for(int k=0;k<=Prob_ChargePath->GetZaxis()->GetNbins()+1;k++){ Ni+=DeDxMap_.binContent(i,j,k);}
00150 
00151             for(int k=0;k<=Prob_ChargePath->GetZaxis()->GetNbins()+1;k++){
00152                double tmp = DeDxMap_.binContent(i,j,k);
00153 
00154                if(Ni>0){
00155                   Prob_ChargePath->SetBinContent (i, j, k, tmp/Ni);
00156 //                  printf("P=%6.2f Path=%6.2f Charge%8.2f --> Prob=%8.3f\n",Prob_ChargePath->GetXaxis()->GetBinCenter(i), Prob_ChargePath->GetYaxis()->GetBinCenter(j), Prob_ChargePath->GetZaxis()->GetBinCenter(k), tmp/Ni);
00157                }else{
00158                   Prob_ChargePath->SetBinContent (i, j, k, 0);
00159                }
00160             }
00161          }
00162       }   
00163    }else{
00164 //      printf("The ProbabilityMode: %s is unknown\n",ProbabilityMode.c_str());
00165 //      printf("The program will stop now\n");
00166       exit(0);
00167    }
00168 
00169 
00170 
00171 /*
00172    for(int i=0;i<Prob_ChargePath->GetXaxis()->GetNbins();i++){
00173       for(int j=0;j<Prob_ChargePath->GetYaxis()->GetNbins();j++){
00174          double tmp = DeDxMap_.binContent(i,j);
00175          Prob_ChargePath->SetBinContent (i, j, tmp);
00176          printf("%i %i --> %f\n",i,j,tmp);
00177       }
00178    }
00179 */
00180 
00181 
00182 
00183    if(MODsColl.size()==0){
00184       edm::ESHandle<TrackerGeometry> tkGeom;
00185       iSetup.get<TrackerDigiGeometryRecord>().get( tkGeom );
00186       m_tracker = tkGeom.product();
00187 
00188       vector<GeomDet*> Det = tkGeom->dets();
00189       for(unsigned int i=0;i<Det.size();i++){
00190          DetId  Detid  = Det[i]->geographicalId();
00191          int    SubDet = Detid.subdetId();
00192 
00193          if( SubDet == StripSubdetector::TIB ||  SubDet == StripSubdetector::TID ||
00194              SubDet == StripSubdetector::TOB ||  SubDet == StripSubdetector::TEC  ){
00195 
00196              StripGeomDetUnit* DetUnit     = dynamic_cast<StripGeomDetUnit*> (Det[i]);
00197              if(!DetUnit)continue;
00198 
00199              const StripTopology& Topo     = DetUnit->specificTopology();
00200              unsigned int         NAPV     = Topo.nstrips()/128;
00201 
00202              double Eta     = DetUnit->position().basicVector().eta();
00203              double R       = DetUnit->position().basicVector().transverse();
00204              double Thick   = DetUnit->surface().bounds().thickness();
00205 
00206              stModInfo* MOD = new stModInfo;
00207              MOD->DetId     = Detid.rawId();
00208              MOD->SubDet    = SubDet;
00209              MOD->Eta       = Eta;
00210              MOD->R         = R;
00211              MOD->Thickness = Thick;
00212              MOD->NAPV      = NAPV;
00213              MODsColl[MOD->DetId] = MOD;
00214          }
00215       }
00216  
00217       MakeCalibrationMap();
00218    }
00219 
00220 }
00221 
00222 void  DeDxDiscriminatorProducer::endJob()
00223 {
00224    MODsColl.clear();
00225 }
00226 
00227 
00228 
00229 void DeDxDiscriminatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00230 {
00231   auto_ptr<ValueMap<DeDxData> > trackDeDxDiscrimAssociation(new ValueMap<DeDxData> );  
00232   ValueMap<DeDxData>::Filler filler(*trackDeDxDiscrimAssociation);
00233 
00234   Handle<TrajTrackAssociationCollection> trajTrackAssociationHandle;
00235   iEvent.getByLabel(m_trajTrackAssociationTag, trajTrackAssociationHandle);
00236   const TrajTrackAssociationCollection TrajToTrackMap = *trajTrackAssociationHandle.product();
00237 
00238   edm::Handle<reco::TrackCollection> trackCollectionHandle;
00239   iEvent.getByLabel(m_tracksTag,trackCollectionHandle);
00240 
00241    edm::ESHandle<TrackerGeometry> tkGeom;
00242    iSetup.get<TrackerDigiGeometryRecord>().get( tkGeom );
00243    m_tracker = tkGeom.product();
00244  
00245    std::vector<DeDxData> dEdxDiscrims( TrajToTrackMap.size() );
00246 
00247    unsigned track_index = 0;
00248    for(TrajTrackAssociationCollection::const_iterator it = TrajToTrackMap.begin(); it!=TrajToTrackMap.end(); ++it, track_index++) {
00249       dEdxDiscrims[track_index] = DeDxData(-1, -2, 0 );
00250 
00251       const Track      track = *it->val;
00252       const Trajectory traj  = *it->key;
00253 
00254       if(track.eta()  <MinTrackEta      || track.eta()>MaxTrackEta     ){continue;}
00255       if(track.p()    <MinTrackMomentum || track.p()  >MaxTrackMomentum){continue;}
00256       if(track.found()<MinTrackHits                                    ){continue;}
00257 
00258       std::vector<double> vect_probs;
00259       vector<TrajectoryMeasurement> measurements = traj.measurements();
00260 
00261       unsigned int NClusterSaturating = 0;
00262       for(vector<TrajectoryMeasurement>::const_iterator measurement_it = measurements.begin(); measurement_it!=measurements.end(); measurement_it++){
00263 
00264          TrajectoryStateOnSurface trajState = measurement_it->updatedState();
00265          if( !trajState.isValid() ) continue;
00266 
00267          const TrackingRecHit*         hit                 = (*measurement_it->recHit()).hit();
00268          const SiStripRecHit2D*        sistripsimplehit    = dynamic_cast<const SiStripRecHit2D*>(hit);
00269          const SiStripMatchedRecHit2D* sistripmatchedhit   = dynamic_cast<const SiStripMatchedRecHit2D*>(hit);
00270          const SiStripRecHit1D*        sistripsimple1dhit  = dynamic_cast<const SiStripRecHit1D*>(hit);
00271          
00272          double Prob;
00273          if(sistripsimplehit){
00274                 Prob = GetProbability((sistripsimplehit->cluster()).get(), trajState,sistripsimplehit->geographicalId());           
00275                 if(shapetest && !(DeDxTools::shapeSelection(((sistripsimplehit->cluster()).get())->amplitudes()))) Prob=-1.0;
00276                 if(Prob>=0) vect_probs.push_back(Prob);             
00277             
00278                 if(ClusterSaturatingStrip((sistripsimplehit->cluster()).get(),sistripsimplehit->geographicalId())>0)NClusterSaturating++;
00279 
00280          }else if(sistripmatchedhit){
00281                 Prob = GetProbability((sistripmatchedhit->monoHit()->cluster()).get(), trajState, sistripmatchedhit->monoHit()->geographicalId());
00282                 if(shapetest && !(DeDxTools::shapeSelection(((sistripmatchedhit->monoHit()->cluster()).get())->amplitudes()))) Prob=-1.0;
00283                 if(Prob>=0) vect_probs.push_back(Prob);
00284            
00285                 Prob = GetProbability((sistripmatchedhit->stereoHit()->cluster()).get(), trajState,sistripmatchedhit->stereoHit()->geographicalId());
00286                 if(Prob>=0) vect_probs.push_back(Prob);
00287             
00288                 if(ClusterSaturatingStrip((sistripmatchedhit->monoHit()->cluster()).get(),sistripmatchedhit->monoHit()->geographicalId())  >0)NClusterSaturating++;
00289                 if(ClusterSaturatingStrip((sistripmatchedhit->stereoHit()->cluster()).get(),sistripmatchedhit->stereoHit()->geographicalId())>0)NClusterSaturating++;
00290          }else if(sistripsimple1dhit){ 
00291                 Prob = GetProbability((sistripsimple1dhit->cluster()).get(), trajState, sistripsimple1dhit->geographicalId());
00292                 if(shapetest && !(DeDxTools::shapeSelection(((sistripsimple1dhit->cluster()).get())->amplitudes()))) Prob=-1.0;
00293                 if(Prob>=0) vect_probs.push_back(Prob);
00294                 if(ClusterSaturatingStrip((sistripsimple1dhit->cluster()).get(),sistripsimple1dhit->geographicalId())>0)NClusterSaturating++;
00295          }else{
00296          }
00297       }
00298 
00299       double estimator          = ComputeDiscriminator(vect_probs);
00300       int    size               = vect_probs.size();
00301       float  Error              = -1;
00302 
00303       //WARNING: Since the dEdX Error is not properly computed for the moment
00304       //It was decided to store the number of saturating cluster in that dataformat
00305       Error = NClusterSaturating;
00306       dEdxDiscrims[track_index] = DeDxData(estimator, Error, size );
00307 
00308 //      printf("%i --> %g\n",size,estimator);
00309    }
00310 
00311   filler.insert(trackCollectionHandle, dEdxDiscrims.begin(), dEdxDiscrims.end());
00312   filler.fill();
00313   iEvent.put(trackDeDxDiscrimAssociation);
00314 }
00315 
00316 
00317 int DeDxDiscriminatorProducer::ClusterSaturatingStrip(const SiStripCluster*   cluster,
00318                                                       const uint32_t &               detId){
00319    const vector<uint8_t>&  ampls          = cluster->amplitudes();
00320 
00321    stModInfo* MOD                         = NULL;
00322    if(useCalibration)MOD                  = MODsColl[detId];
00323 
00324    int SaturatingStrip = 0;
00325    for(unsigned int i=0;i<ampls.size();i++){
00326       int StripCharge = ampls[i];
00327       if(MOD){StripCharge = (int)(StripCharge / MOD->Gain);}
00328       if(StripCharge>=254)SaturatingStrip++;
00329    }
00330    return SaturatingStrip;
00331 }
00332 
00333 double DeDxDiscriminatorProducer::GetProbability(const SiStripCluster*   cluster, TrajectoryStateOnSurface trajState,
00334                                                  const uint32_t &               detId)
00335 {
00336    // Get All needed variables
00337    LocalVector             trackDirection = trajState.localDirection();
00338    double                  cosine         = trackDirection.z()/trackDirection.mag();
00339    const vector<uint8_t>&  ampls          = cluster->amplitudes();
00340    //   uint32_t                detId          = cluster->geographicalId();
00341    //   int                     firstStrip     = cluster->firstStrip();
00342    stModInfo* MOD                         = MODsColl[detId];
00343 
00344 
00345    // Sanity Checks
00346    if( ampls.size()>MaxNrStrips)                                                                      {return -1;}
00347 // if( DeDxDiscriminatorTools::IsSaturatingStrip  (ampls))                                            {return -1;}
00348 // if( DeDxDiscriminatorTools::IsSpanningOver2APV (firstStrip, ampls.size()))                         {return -1;}
00349 // if(!DeDxDiscriminatorTools::IsFarFromBorder    (trajState, m_tracker->idToDetUnit(DetId(detId)) )) {return -1;}
00350 
00351 
00352    // Find Probability for this given Charge and Path
00353    double charge = 0;
00354    if(useCalibration){
00355       for(unsigned int i=0;i<ampls.size();i++){
00356          int CalibratedCharge = ampls[i];
00357          CalibratedCharge = (int)(CalibratedCharge / MOD->Gain);
00358          if(CalibratedCharge>=1024){
00359             CalibratedCharge = 255;
00360          }else if(CalibratedCharge>254){
00361             CalibratedCharge = 254;
00362          }
00363          charge+=CalibratedCharge;
00364       }
00365    }else{
00366       charge = DeDxDiscriminatorTools::charge(ampls);
00367    }
00368    double path   = DeDxDiscriminatorTools::path(cosine,MOD->Thickness);
00369 
00370    int    BinX   = Prob_ChargePath->GetXaxis()->FindBin(trajState.localMomentum().mag());
00371    int    BinY   = Prob_ChargePath->GetYaxis()->FindBin(path);
00372    int    BinZ   = Prob_ChargePath->GetZaxis()->FindBin(charge/path);
00373    return Prob_ChargePath->GetBinContent(BinX,BinY,BinZ);
00374 }
00375 
00376 
00377 double DeDxDiscriminatorProducer::ComputeDiscriminator(std::vector<double>& vect_probs)
00378 {
00379    double estimator = -1;
00380    int    size      = vect_probs.size();
00381    if(size<=0)return estimator;
00382 
00383    if(Formula==0){
00384       double P = 1;
00385       for(int i=0;i<size;i++){
00386          if(vect_probs[i]<=0.0001){P *= pow(0.0001       , 1.0/size);}
00387          else                     {P *= pow(vect_probs[i], 1.0/size);}
00388       }
00389       estimator = P;
00390    }else if(Formula==1){
00391       std::sort(vect_probs.begin(), vect_probs.end(), std::less<double>() );
00392       for(int i=0;i<size;i++){if(vect_probs[i]<=0.0001)vect_probs[i] = 0.0001;    }
00393 
00394       double SumJet = 0.;
00395       for(int i=0;i<size;i++){ SumJet+= log(vect_probs[i]); }
00396 
00397       double Loginvlog=log(-SumJet);
00398       double Prob =1.;
00399       double lfact=1.;
00400 
00401       for(int l=1; l!=size; l++){
00402          lfact*=l;
00403          Prob+=exp(l*Loginvlog-log(1.*lfact));
00404       }
00405 
00406       double LogProb=log(Prob);
00407       double ProbJet=std::min(exp(std::max(LogProb+SumJet,-30.)),1.);
00408       estimator = -log10(ProbJet)/4.;
00409       estimator = 1-estimator;
00410    }else if(Formula==2){
00411       std::sort(vect_probs.begin(), vect_probs.end(), std::less<double>() );
00412       double P = 1.0/(12*size);
00413       for(int i=1;i<=size;i++){
00414          P += pow(vect_probs[i-1] - ((2.0*i-1.0)/(2.0*size)),2);
00415       }
00416       P *= (3.0/size);
00417       estimator = P;
00418    }else{
00419       std::sort(vect_probs.begin(), vect_probs.end(), std::less<double>() );
00420       double P = 1.0/(12*size);
00421       for(int i=1;i<=size;i++){
00422          P += vect_probs[i-1] * pow(vect_probs[i-1] - ((2.0*i-1.0)/(2.0*size)),2);
00423       }
00424       P *= (3.0/size);
00425       estimator = P;
00426    }
00427 
00428    return estimator;
00429 }
00430 
00431 
00432 void DeDxDiscriminatorProducer::MakeCalibrationMap(){
00433    if(!useCalibration)return;
00434 
00435 
00436    TChain* t1 = new TChain("SiStripCalib/APVGain");
00437    t1->Add(m_calibrationPath.c_str());
00438 
00439    unsigned int  tree_DetId;
00440    unsigned char tree_APVId;
00441    double        tree_Gain;
00442 
00443    t1->SetBranchAddress("DetId"             ,&tree_DetId      );
00444    t1->SetBranchAddress("APVId"             ,&tree_APVId      );
00445    t1->SetBranchAddress("Gain"              ,&tree_Gain       );
00446 
00447    for (unsigned int ientry = 0; ientry < t1->GetEntries(); ientry++) {
00448        t1->GetEntry(ientry);
00449        stModInfo* MOD  = MODsColl[tree_DetId];
00450        MOD->Gain = tree_Gain;
00451    }
00452 
00453    delete t1;
00454 
00455 }
00456 
00457 //define this as a plug-in
00458 DEFINE_FWK_MODULE(DeDxDiscriminatorProducer);