Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:20

0001 
0002 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
0003 
0004 #include <climits>
0005 
0006 using namespace reco;
0007 
0008 ElectronSeed::ElectronSeed()
0009     : TrajectorySeed(),
0010       ctfTrack_(),
0011       caloCluster_(),
0012       hitInfo_(),
0013       nrLayersAlongTraj_(0),
0014       isEcalDriven_(false),
0015       isTrackerDriven_(false)
0016 
0017 {}
0018 
0019 ElectronSeed::ElectronSeed(const TrajectorySeed& seed)
0020     : TrajectorySeed(seed),
0021       ctfTrack_(),
0022       caloCluster_(),
0023       hitInfo_(),
0024       nrLayersAlongTraj_(0),
0025       isEcalDriven_(false),
0026       isTrackerDriven_(false) {}
0027 
0028 ElectronSeed::ElectronSeed(PTrajectoryStateOnDet& pts, RecHitContainer& rh, PropagationDirection& dir)
0029     : TrajectorySeed(pts, rh, dir),
0030       ctfTrack_(),
0031       caloCluster_(),
0032       hitInfo_(),
0033       nrLayersAlongTraj_(0),
0034       isEcalDriven_(false),
0035       isTrackerDriven_(false) {}
0036 
0037 ElectronSeed::~ElectronSeed() = default;
0038 
0039 void ElectronSeed::setCtfTrack(const CtfTrackRef& ctfTrack) {
0040   ctfTrack_ = ctfTrack;
0041   isTrackerDriven_ = true;
0042 }
0043 
0044 //the hit mask tells us which hits were used in the seed
0045 //typically all are used at the HLT but this could change in the future
0046 //RECO only uses some of them
0047 unsigned int ElectronSeed::hitsMask() const {
0048   int mask = 0;
0049   for (size_t hitNr = 0; hitNr < nHits(); hitNr++) {
0050     int bitNr = 0x1 << hitNr;
0051     int hitDetId = (recHits().begin() + hitNr)->geographicalId().rawId();
0052     auto detIdMatcher = [hitDetId](const ElectronSeed::PMVars& var) { return hitDetId == var.detId; };
0053     if (std::find_if(hitInfo_.begin(), hitInfo_.end(), detIdMatcher) != hitInfo_.end()) {
0054       mask |= bitNr;
0055     }
0056   }
0057   return mask;
0058 }
0059 
0060 void ElectronSeed::initTwoHitSeed(const unsigned char hitMask) {
0061   hitInfo_.resize(2);
0062 
0063   std::vector<unsigned int> hitNrs = hitNrsFromMask(hitMask);
0064   if (hitNrs.size() != 2) {
0065     throw cms::Exception("LogicError")
0066         << "in ElectronSeed::" << __FUNCTION__ << "," << __LINE__ << ": number of hits in hit mask is " << hitNrs.size()
0067         << "\n"
0068         << "pre-2017 pixel upgrade ecalDriven ElectronSeeds should have exactly 2 hits\n "
0069         << "mask " << static_cast<unsigned int>(hitMask) << std::endl;
0070   }
0071   if (hitNrs[0] >= nHits() || hitNrs[1] >= nHits()) {
0072     throw cms::Exception("LogicError") << "in ElectronSeed::" << __FUNCTION__ << "," << __LINE__ << ": hits are "
0073                                        << hitNrs[0] << " and  " << hitNrs[1] << " while number of hits are " << nHits()
0074                                        << "\n"
0075                                        << "this means there was a bug in storing or creating the electron seeds "
0076                                        << "mask " << static_cast<unsigned int>(hitMask) << std::endl;
0077   }
0078   for (size_t hitNr = 0; hitNr < hitInfo_.size(); hitNr++) {
0079     auto& info = hitInfo_[hitNr];
0080     info.setDPhi(std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity());
0081     info.setDRZ(std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity());
0082     info.setDet((recHits().begin() + hitNrs[hitNr])->geographicalId(), -1);
0083   }
0084 }
0085 
0086 void ElectronSeed::setNegAttributes(float dRZ2, float dPhi2, float dRZ1, float dPhi1) {
0087   if (hitInfo_.size() != 2) {
0088     throw cms::Exception("LogicError")
0089         << "ElectronSeed::setNegAttributes should only operate on seeds with exactly two hits. This is because it is a "
0090            "legacy function to preverse backwards compatiblity and should not be used on new code which matches "
0091            "variable number of hits";
0092   }
0093   hitInfo_[0].dRZNeg = dRZ1;
0094   hitInfo_[1].dRZNeg = dRZ2;
0095   hitInfo_[0].dPhiNeg = dPhi1;
0096   hitInfo_[1].dPhiNeg = dPhi2;
0097 }
0098 
0099 void ElectronSeed::setPosAttributes(float dRZ2, float dPhi2, float dRZ1, float dPhi1) {
0100   if (hitInfo_.size() != 2) {
0101     throw cms::Exception("LogicError")
0102         << "ElectronSeed::setPosAttributes should only operate on seeds with exactly two hits. This is because it is a "
0103            "legacy function to preverse backwards compatiblity and should not be used on new code which matches "
0104            "variable number of hits";
0105   }
0106   hitInfo_[0].dRZPos = dRZ1;
0107   hitInfo_[1].dRZPos = dRZ2;
0108   hitInfo_[0].dPhiPos = dPhi1;
0109   hitInfo_[1].dPhiPos = dPhi2;
0110 }
0111 
0112 std::vector<unsigned int> ElectronSeed::hitNrsFromMask(unsigned int hitMask) {
0113   std::vector<unsigned int> hitNrs;
0114   for (size_t bitNr = 0; bitNr < sizeof(hitMask) * CHAR_BIT; bitNr++) {
0115     char bit = 0x1 << bitNr;
0116     if ((hitMask & bit) != 0)
0117       hitNrs.push_back(bitNr);
0118   }
0119   return hitNrs;
0120 }
0121 
0122 std::vector<ElectronSeed::PMVars> ElectronSeed::createHitInfo(const float dPhi1Pos,
0123                                                               const float dPhi1Neg,
0124                                                               const float dRZ1Pos,
0125                                                               const float dRZ1Neg,
0126                                                               const float dPhi2Pos,
0127                                                               const float dPhi2Neg,
0128                                                               const float dRZ2Pos,
0129                                                               const float dRZ2Neg,
0130                                                               const char hitMask,
0131                                                               TrajectorySeed::RecHitRange const& recHits) {
0132   if (hitMask == 0)
0133     return std::vector<ElectronSeed::PMVars>();  //was trackerDriven so no matched hits
0134 
0135   size_t nrRecHits = std::distance(recHits.begin(), recHits.end());
0136   std::vector<unsigned int> hitNrs = hitNrsFromMask(hitMask);
0137 
0138   if (hitNrs.size() != 2) {
0139     throw cms::Exception("LogicError") << "in ElectronSeed::" << __FUNCTION__ << "," << __LINE__
0140                                        << ": number of hits in hit mask is " << nrRecHits << "\n"
0141                                        << "pre-2017 pixel upgrade ecalDriven ElectronSeeds should have exactly 2 hits\n"
0142                                        << "mask " << static_cast<unsigned int>(hitMask) << std::endl;
0143   }
0144   if (hitNrs[0] >= nrRecHits || hitNrs[1] >= nrRecHits) {
0145     throw cms::Exception("LogicError") << "in ElectronSeed::" << __FUNCTION__ << "," << __LINE__ << ": hits are "
0146                                        << hitNrs[0] << " and " << hitNrs[1] << " while number of hits are " << nrRecHits
0147                                        << "\n"
0148                                        << "this means there was a bug in storing or creating the electron seeds "
0149                                        << "mask " << static_cast<unsigned int>(hitMask) << std::endl;
0150   }
0151 
0152   std::vector<PMVars> hitInfo(2);
0153   hitInfo[0].setDPhi(dPhi1Pos, dPhi1Neg);
0154   hitInfo[0].setDRZ(dRZ1Pos, dRZ1Neg);
0155   hitInfo[0].setDet(
0156       (recHits.begin() + hitNrs[0])->geographicalId(),
0157       -1);  //getting the layer information needs tracker topo, hence why its stored in the first as its a pain to access
0158   hitInfo[1].setDPhi(dPhi2Pos, dPhi2Neg);
0159   hitInfo[1].setDRZ(dRZ2Pos, dRZ2Neg);
0160   hitInfo[1].setDet(
0161       (recHits.begin() + hitNrs[1])->geographicalId(),
0162       -1);  //getting the layer information needs tracker topo, hence why its stored in the first as its a pain to access
0163   return hitInfo;
0164 }
0165 
0166 ElectronSeed::PMVars::PMVars()
0167     : dRZPos(std::numeric_limits<float>::infinity()),
0168       dRZNeg(std::numeric_limits<float>::infinity()),
0169       dPhiPos(std::numeric_limits<float>::infinity()),
0170       dPhiNeg(std::numeric_limits<float>::infinity()),
0171       detId(0),
0172       layerOrDiskNr(-1) {}
0173 
0174 void ElectronSeed::PMVars::setDPhi(float pos, float neg) {
0175   dPhiPos = pos;
0176   dPhiNeg = neg;
0177 }
0178 
0179 void ElectronSeed::PMVars::setDRZ(float pos, float neg) {
0180   dRZPos = pos;
0181   dRZNeg = neg;
0182 }
0183 
0184 void ElectronSeed::PMVars::setDet(int iDetId, int iLayerOrDiskNr) {
0185   detId = iDetId;
0186   layerOrDiskNr = iLayerOrDiskNr;
0187 }