CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/SUSYBSMAnalysis/HSCP/src/BetaCalculatorECAL.cc

Go to the documentation of this file.
00001 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00002 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00003 
00004 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00005 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00006 #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h"
00007 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00008 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixStateInfo.h"
00009 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00010 
00011 #include "RecoEcal/EgammaCoreTools/interface/EcalRecHitLess.h"
00012 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalSeverityLevelAlgo.h"
00013 
00014 #include "SUSYBSMAnalysis/HSCP/interface/BetaCalculatorECAL.h"
00015 
00016 BetaCalculatorECAL::BetaCalculatorECAL(const edm::ParameterSet& iConfig) :
00017   EBRecHitCollection_ (iConfig.getParameter<edm::InputTag>("EBRecHitCollection")),
00018   EERecHitCollection_ (iConfig.getParameter<edm::InputTag>("EERecHitCollection"))
00019 {
00020    edm::ParameterSet trkParameters = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
00021    parameters_.loadParameters( trkParameters ); 
00022    trackAssociator_.useDefaultPropagator();
00023 
00024 }
00025 
00026 
00027 void BetaCalculatorECAL::addInfoToCandidate(HSCParticle& candidate, edm::Handle<reco::TrackCollection>& tracks, edm::Event& iEvent, const edm::EventSetup& iSetup,  HSCPCaloInfo& caloInfo) {
00028    bool setCalo = false;
00029    HSCPCaloInfo result;
00030 
00031    // EcalDetIdAssociator
00032    iSetup.get<DetIdAssociatorRecord>().get("EcalDetIdAssociator", ecalDetIdAssociator_);
00033    // Get the Bfield
00034    iSetup.get<IdealMagneticFieldRecord>().get(bField_);
00035    // Geometry
00036    iSetup.get<CaloGeometryRecord>().get(theCaloGeometry_);
00037    const CaloGeometry* theGeometry = theCaloGeometry_.product();
00038    // Topology
00039    edm::ESHandle<CaloTopology> pCaloTopology;
00040    iSetup.get<CaloTopologyRecord>().get(pCaloTopology);
00041    const CaloTopology* theCaloTopology = pCaloTopology.product();
00042    // EcalRecHits
00043    edm::Handle<EBRecHitCollection> ebRecHits;
00044    iEvent.getByLabel(EBRecHitCollection_,ebRecHits);
00045    edm::Handle<EERecHitCollection> eeRecHits;
00046    iEvent.getByLabel(EERecHitCollection_,eeRecHits);
00047    
00048    // select the track
00049    reco::Track track;
00050    if(candidate.hasTrackRef())
00051      track = *(candidate.trackRef());
00052    else
00053      return; // in case there is no track ref, we can't do much
00054 
00055    // compute the track isolation
00056    result.trkIsoDr=100;
00057    for(reco::TrackCollection::const_iterator ndTrack = tracks->begin(); ndTrack != tracks->end(); ++ndTrack) {
00058        double dr=sqrt(pow((track.outerEta()-ndTrack->outerEta()),2)+pow((track.outerPhi()-ndTrack->outerPhi()),2));
00059        if(dr>0.00001 && dr<result.trkIsoDr) result.trkIsoDr=dr;
00060    }
00061 
00062    // use the track associator to propagate to the calo
00063    TrackDetMatchInfo info = trackAssociator_.associate( iEvent, iSetup, 
00064                                                         trackAssociator_.getFreeTrajectoryState(iSetup, track),
00065                                                         parameters_ );
00066 
00067    // do a custom propagation through Ecal
00068    std::map<int,GlobalPoint> trackExitPositionMap; // rawId to exit position (subtracting cry center)
00069    std::map<int,float> trackCrossedXtalCurvedMap; // rawId to trackLength
00070    TrajectoryStateTransform tsTransform;
00071    FreeTrajectoryState tkInnerState = tsTransform.innerFreeState(track, &*bField_);
00072    // Build set of points in Ecal (necklace) using the propagator
00073    std::vector<SteppingHelixStateInfo> neckLace;
00074    neckLace = calcEcalDeposit(&tkInnerState,*ecalDetIdAssociator_);
00075    // Initialize variables to be filled by the track-length function
00076    double totalLengthCurved = 0.;
00077    GlobalPoint internalPointCurved(0., 0., 0.);
00078    GlobalPoint externalPointCurved(0., 0., 0.);
00079    if(neckLace.size() > 1)
00080    {
00081      getDetailedTrackLengthInXtals(trackExitPositionMap,
00082          trackCrossedXtalCurvedMap,
00083          totalLengthCurved,
00084          internalPointCurved,
00085          externalPointCurved,
00086          & (*theGeometry),
00087          & (*theCaloTopology),
00088          neckLace);
00089    }
00090    int numCrysCrossed = -1;
00091    numCrysCrossed = trackCrossedXtalCurvedMap.size();
00092 
00093    // Make weighted sum of times
00094    float sumWeightedTime = 0;
00095    float sumTimeErrorSqr = 0;
00096    float sumEnergy = 0;
00097    float sumTrackLength = 0;
00098    std::vector<EcalRecHit> crossedRecHits;
00099    EcalRecHitCollection::const_iterator thisHit;
00100 
00101    std::map<int,GlobalPoint>::const_iterator trackExitMapIt = trackExitPositionMap.begin();
00102    for(std::map<int,float>::const_iterator mapIt = trackCrossedXtalCurvedMap.begin();
00103        mapIt != trackCrossedXtalCurvedMap.end(); ++mapIt)
00104    {
00105      if(DetId(mapIt->first).subdetId()==EcalBarrel)
00106      {
00107        EBDetId ebDetId(mapIt->first);
00108        thisHit = ebRecHits->find(ebDetId);
00109        if(thisHit == ebRecHits->end())
00110        {
00111          //std::cout << "\t Could not find crossedEcal detId: " << ebDetId << " in EBRecHitCollection!" << std::endl;
00112          continue;
00113        }
00114        const EcalRecHit hit = *thisHit;
00115        // Cut out badly-reconstructed hits
00116        if(!hit.isTimeValid())
00117          continue;
00118        uint32_t rhFlag = hit.recoFlag();
00119        if((rhFlag != EcalRecHit::kGood) && (rhFlag != EcalRecHit::kOutOfTime) && (rhFlag != EcalRecHit::kPoorCalib))
00120          continue;
00121 
00122        float errorOnThis = hit.timeError();
00123        sumTrackLength+=mapIt->second;
00124        sumEnergy+=hit.energy();
00125        crossedRecHits.push_back(hit);
00126 //       result.ecalSwissCrossKs.push_back(EcalSeverityLevelAlgo::spikeFromNeighbours(ebDetId,(*ebRecHits),0.2,EcalSeverityLevelAlgo::kSwissCross));
00127 //       result.ecalE1OverE9s.push_back(EcalSeverityLevelAlgo::spikeFromNeighbours(ebDetId,(*ebRecHits),0.2,EcalSeverityLevelAlgo::kE1OverE9));
00128        result.ecalTrackLengths.push_back(mapIt->second);
00129        result.ecalTrackExitPositions.push_back(trackExitMapIt->second);
00130        result.ecalEnergies.push_back(hit.energy());
00131        result.ecalTimes.push_back(hit.time());
00132        result.ecalTimeErrors.push_back(hit.timeError());
00133        result.ecalOutOfTimeEnergies.push_back(hit.outOfTimeEnergy());
00134        result.ecalOutOfTimeChi2s.push_back(hit.outOfTimeChi2());
00135        result.ecalChi2s.push_back(hit.chi2());
00136        result.ecalDetIds.push_back(ebDetId);
00137        // SIC DEBUG
00138        //std::cout << " SIC DEBUG: time error on this crossed RecHit: " << errorOnThis << " energy of hit: "
00139        //  << hit.energy() << " time of hit: " << hit.time() << " trackLength: " << mapIt->second << std::endl;
00140 
00141        if(hit.isTimeErrorValid()) // use hit time for weighted time average
00142        {
00143          sumWeightedTime+=hit.time()/(errorOnThis*errorOnThis);
00144          sumTimeErrorSqr+=1/(errorOnThis*errorOnThis);
00145        }
00146      }
00147      trackExitMapIt++;
00148    }
00149 
00150    if(crossedRecHits.size() > 0)
00151    {
00152      setCalo = true;
00153      sort(crossedRecHits.begin(),crossedRecHits.end(),EcalRecHitLess());
00154      result.ecalCrossedEnergy = sumEnergy;
00155      result.ecalCrysCrossed = crossedRecHits.size();
00156      result.ecalDeDx = sumEnergy/sumTrackLength;
00157      // replace the below w/o trackassociator quantities?
00158      result.ecal3by3dir = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 1);
00159      result.ecal5by5dir = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 2);
00160 
00161      if(sumTimeErrorSqr > 0)
00162      {
00163        result.ecalTime = sumWeightedTime/sumTimeErrorSqr;
00164        result.ecalTimeError = sqrt(1/sumTimeErrorSqr);
00165        DetId maxEnergyId = crossedRecHits.begin()->id();
00166 
00167        if(maxEnergyId != DetId()) // double check
00168        {
00169          // To get beta, we assume photon propagation time is about the same for muons and e/gamma
00170          // Since the typical path length is >> crystal length, this shouldn't be too bad
00171          GlobalPoint position = info.getPosition(maxEnergyId); // position of crystal center on front face
00172          double frontFaceR = sqrt(pow(position.x(),2)+pow(position.y(),2)+pow(position.z(),2));
00173          double muonShowerMax = frontFaceR+11.5; // assume muon "showerMax" is halfway into the crystal
00174          double gammaShowerMax = frontFaceR+6.23; // 7 X0 for e/gamma showerMax
00175          double speedOfLight = 29.979; // cm/ns
00176          result.ecalBeta = (muonShowerMax)/(result.ecalTime*speedOfLight+gammaShowerMax);
00177          result.ecalBetaError = (speedOfLight*muonShowerMax*result.ecalTimeError)/pow(speedOfLight*result.ecalTime+gammaShowerMax,2);
00178          result.ecalInvBetaError = speedOfLight*result.ecalTimeError/muonShowerMax;
00179        }
00180        // SIC debug
00181        //std::cout << "BetaCalcEcal: CrossedRecHits: " << crossedRecHits.size()
00182        //  << " ecalTime: " << result.ecalTime << " timeError: " << result.ecalTimeError
00183        //  << " ecalCrossedEnergy: " << result.ecalCrossedEnergy << " ecalBeta: " << result.ecalBeta 
00184        //  << " ecalBetaError: " << result.ecalBetaError <<  " ecalDeDx (MeV/cm): " << 1000*result.ecalDeDx << std::endl;
00185      }
00186    }
00187 
00188    if(info.crossedHcalRecHits.size() > 0)
00189    {
00190      // HCAL (not ECAL) info
00191      result.hcalCrossedEnergy = info.crossedEnergy(TrackDetMatchInfo::HcalRecHits);
00192      result.hoCrossedEnergy = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
00193      //maxEnergyId = info.findMaxDeposition(TrackDetMatchInfo::HcalRecHits);
00194      result.hcal3by3dir = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits, 1);
00195      result.hcal5by5dir = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits, 2);
00196    }
00197 
00198    if(setCalo) 
00199      caloInfo = result;
00200 }
00201 
00202 std::vector<SteppingHelixStateInfo> BetaCalculatorECAL::calcEcalDeposit(const FreeTrajectoryState* tkInnerState,
00203             const DetIdAssociator& associator)
00204 {   
00205    // Set some parameters
00206    double minR = associator.volume().minR () ;
00207    double minZ = associator.volume().minZ () ;
00208    double maxR = associator.volume().maxR () ;
00209    double maxZ = associator.volume().maxZ () ;
00210 
00211    // Define the TrackOrigin (where the propagation starts)
00212    SteppingHelixStateInfo trackOrigin(*tkInnerState);
00213 
00214    // Define Propagator
00215    SteppingHelixPropagator* prop = new SteppingHelixPropagator (&*bField_, alongMomentum);
00216    prop -> setMaterialMode(false); 
00217    prop -> applyRadX0Correction(true);
00218 
00219    // Build the necklace
00220    CachedTrajectory neckLace;
00221    neckLace.setStateAtIP(trackOrigin);
00222    neckLace.reset_trajectory();
00223    neckLace.setPropagator(prop);
00224    neckLace.setPropagationStep(0.1);
00225    neckLace.setMinDetectorRadius(minR);
00226    neckLace.setMinDetectorLength(minZ*2.);
00227    neckLace.setMaxDetectorRadius(maxR);
00228    neckLace.setMaxDetectorLength(maxZ*2.);
00229 
00230    // Propagate track
00231    bool isPropagationSuccessful = neckLace.propagateAll(trackOrigin);
00232 
00233    if (!isPropagationSuccessful)
00234    {
00235      //std::cout << ">>>>>> calcEcalDeposits::propagateAll::failed " << "<<<<<<" << std::endl;
00236      //std::cout << "innerOrigin = " << glbTrackInnerOrigin.position() << "   innerR = " << innerR << std::endl; 
00237      return std::vector<SteppingHelixStateInfo> () ;
00238    }
00239 
00240    std::vector<SteppingHelixStateInfo> complicatePoints;
00241    neckLace.getTrajectory(complicatePoints, associator.volume(), 500);
00242    //std::cerr << "necklace size = " << complicatePoints.size() << std::endl;
00243 
00244    return complicatePoints;
00245 }
00246 
00247 int BetaCalculatorECAL::getDetailedTrackLengthInXtals(std::map<int,GlobalPoint>& trackExitPositionMap,
00248    std::map<int,float>& trackCrossedXtalMap,
00249    double& totalLengthCurved,
00250    GlobalPoint& internalPointCurved,
00251    GlobalPoint& externalPointCurved,
00252    const CaloGeometry* theGeometry,
00253    const CaloTopology* theTopology,
00254    const std::vector<SteppingHelixStateInfo>& neckLace)
00255 {
00256    GlobalPoint origin (0., 0., 0.);
00257    internalPointCurved = origin ;
00258    externalPointCurved = origin ;
00259 
00260    bool firstPoint = false;
00261    trackCrossedXtalMap.clear();
00262 
00263    const CaloSubdetectorGeometry* theBarrelSubdetGeometry = theGeometry->getSubdetectorGeometry(DetId::Ecal,1);
00264    const CaloSubdetectorGeometry* theEndcapSubdetGeometry = theGeometry->getSubdetectorGeometry(DetId::Ecal,2);
00265 
00266    for(std::vector<SteppingHelixStateInfo>::const_iterator itr = (neckLace.begin() + 1); itr != neckLace.end(); ++itr)
00267    {
00268      GlobalPoint probe_gp = (*itr).position();
00269      GlobalVector probe_gv = (*itr).momentum();
00270      std::vector<DetId> surroundingMatrix;
00271 
00272      EBDetId closestBarrelDetIdToProbe = ((theBarrelSubdetGeometry -> getClosestCell(probe_gp)).rawId());
00273      EEDetId closestEndcapDetIdToProbe = ((theEndcapSubdetGeometry -> getClosestCell(probe_gp)).rawId());
00274 
00275      // check if the probe is inside the xtal
00276      if( (closestEndcapDetIdToProbe) && (theGeometry->getSubdetectorGeometry(closestEndcapDetIdToProbe)->
00277            getGeometry(closestEndcapDetIdToProbe)->inside(probe_gp)) )
00278      {
00279        double step = ((*itr).position() - (*(itr-1)).position()).mag();
00280        GlobalPoint point = itr->position();
00281        addStepToXtal(trackExitPositionMap, trackCrossedXtalMap, closestEndcapDetIdToProbe, step, point, theEndcapSubdetGeometry);
00282        totalLengthCurved += step;
00283 
00284        if (firstPoint == false)
00285        {
00286          internalPointCurved = probe_gp ;
00287          firstPoint = true ;
00288        }
00289 
00290        externalPointCurved = probe_gp ;
00291      }
00292 
00293      if( (closestBarrelDetIdToProbe) && (theGeometry->getSubdetectorGeometry(closestBarrelDetIdToProbe)->
00294            getGeometry(closestBarrelDetIdToProbe)->inside(probe_gp)) )
00295      {
00296        double step = ((*itr).position() - (*(itr-1)).position()).mag();
00297        GlobalPoint point = itr->position();
00298        addStepToXtal(trackExitPositionMap, trackCrossedXtalMap, closestBarrelDetIdToProbe, step, point, theBarrelSubdetGeometry);
00299        totalLengthCurved += step;
00300 
00301        if (firstPoint == false)
00302        {
00303          internalPointCurved = probe_gp ;
00304          firstPoint = true ;
00305        }
00306 
00307        externalPointCurved = probe_gp ;
00308      }
00309      else
00310      {
00311        // 3x3 matrix surrounding the probe
00312        surroundingMatrix = theTopology->getSubdetectorTopology(closestBarrelDetIdToProbe)->getWindow(closestBarrelDetIdToProbe,3,3);
00313 
00314        for( unsigned int k=0; k<surroundingMatrix.size(); ++k ) {
00315          if(theGeometry->getSubdetectorGeometry(surroundingMatrix.at(k))->getGeometry(surroundingMatrix.at(k))->inside(probe_gp))
00316          {
00317            double step = ((*itr).position() - (*(itr-1)).position()).mag();
00318            GlobalPoint point = itr->position();
00319            addStepToXtal(trackExitPositionMap, trackCrossedXtalMap, surroundingMatrix[k], step,
00320                point, theGeometry->getSubdetectorGeometry(surroundingMatrix.at(k)));
00321            totalLengthCurved += step;
00322 
00323            if (firstPoint == false)
00324            {
00325              internalPointCurved = probe_gp ;
00326              firstPoint = true ;
00327            }
00328 
00329            externalPointCurved = probe_gp ;
00330          }
00331        }
00332 
00333        // clear neighborhood matrix
00334        surroundingMatrix.clear();
00335      }
00336    }
00337 
00338    return 0;
00339 }
00340 
00341 void BetaCalculatorECAL::addStepToXtal(std::map<int,GlobalPoint>& trackExitPositionMap,
00342     std::map<int,float>& trackCrossedXtalMap,
00343     DetId aDetId,
00344     float step,
00345     GlobalPoint point,
00346     const CaloSubdetectorGeometry* theSubdetGeometry)
00347 {
00348 
00349   const CaloCellGeometry *cell_p = theSubdetGeometry->getGeometry(aDetId);
00350   GlobalPoint p = (dynamic_cast <const TruncatedPyramid *> (cell_p))->getPosition(23);
00351   GlobalPoint diff(point.x()-p.x(),point.y()-p.y(),point.z()-p.z());
00352 
00353   std::map<int,GlobalPoint>::iterator xtal = trackExitPositionMap.find(aDetId.rawId());
00354   if (xtal!=trackExitPositionMap.end())
00355     ((*xtal).second)=diff;
00356   else
00357     trackExitPositionMap.insert(std::pair<int,GlobalPoint>(aDetId.rawId(),diff));
00358 
00359   std::map<int,float>::iterator xtal2 = trackCrossedXtalMap.find(aDetId.rawId());
00360   if (xtal2!= trackCrossedXtalMap.end())
00361     ((*xtal2).second)+=step;
00362   else
00363     trackCrossedXtalMap.insert(std::pair<int,float>(aDetId.rawId(),step));
00364 }
00365 
00366 
00367