/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
DataFormats/TrackReco/interface/HitPattern.h
1 147 строк
47 KB
Martina
update MTD hit pattern
28 май 2024, 15:54
28 май 2024, 15:54
c288718
Код
Авторство
О чём код?
// -*- C++ -*- #ifndef TrackReco_HitPattern_h #define TrackReco_HitPattern_h // // File: DataFormats/TrackReco/interface/HitPattern.h // // Marcel Vos, INFN Pisa // v1.10 2007/05/08 bellan // Zongru Wan, Kansas State University // Jean-Roch Vlimant // Kevin Burkett // Boris Mangano // // Hit pattern is the summary information of the hits associated to track in // AOD. When RecHits are no longer available, the compact hit pattern should // allow basic track selection based on the hits in various subdetectors. // The hits of a track are saved in unit16_t hitPattern[MaxHits]. // // uint16_t // +------------+---------------+---------------------------+-----------------+----------------+ // | tk/mu/mtd | sub-structure | sub-sub-structure | stereo | hit type | // +------------+---------------+---------------------------+-----------------+----------------+ // | 11-10 | 9 8 7 | 6 5 4 3 | 2 | 1 0 | bit // +------------+---------------+---------------------------+-----------------+----------------| // | tk = 1 | PXB = 1 | layer = 1-3 | | hit type = 0-3 | // | tk = 1 | PXF = 2 | disk = 1-2 | | hit type = 0-3 | // | tk = 1 | TIB = 3 | layer = 1-4 | 0=rphi,1=stereo | hit type = 0-3 | // | tk = 1 | TID = 4 | wheel = 1-3 | 0=rphi,1=stereo | hit type = 0-3 | // | tk = 1 | TOB = 5 | layer = 1-6 | 0=rphi,1=stereo | hit type = 0-3 | // | tk = 1 | TEC = 6 | wheel = 1-9 | 0=rphi,1=stereo | hit type = 0-3 | // | mu = 0 | DT = 1 | 4*(stat-1)+superlayer | | hit type = 0-3 | // | mu = 0 | CSC = 2 | 4*(stat-1)+(ring-1) | | hit type = 0-3 | // | mu = 0 | RPC = 3 | 4*(stat-1)+2*layer+region | | hit type = 0-3 | // | mu = 0 | GEM = 4 | 1xxx=st0, 0yxx=st y-1 la x| | hit type = 0-3 | // | mu = 0 | ME0 = 5 | roll | | hit type = 0-3 | // | mtd = 2 | BTL = 1 | globalReadoutUnit = 1-6 | | hit type = 0-3 | // | mtd = 2 | ETL = 2 | encodedSector = 1-14 | | hit type = 0-3 | // +------------+---------------+---------------------------+-----------------+----------------+ // // hit type, see DataFormats/TrackingRecHit/interface/TrackingRecHit.h // VALID = valid hit = 0 // MISSING = detector is good, but no rec hit found = 1 // INACTIVE = detector is off, so there was no hope = 2 // BAD = there were many bad strips within the ellipse = 3 // // It had been shown by Zongru using a 100 GeV muon sample with 5000 events // uniform in eta and phi, the average (maximum) number of tracker hits is // 13 (17) and the average (maximum) number of muon detector hits is about // 26 (50). If the number of hits of a track is larger than 80 then the extra // hits are ignored by hit pattern. The static hit pattern array might be // improved to a dynamic one in the future. // // Because of tracking with/without overlaps and with/without hit-splitting, // the final number of hits per track is pretty "variable". Compared with the // number of valid hits, the number of crossed layers with measurement should // be more robust to discriminate between good and fake track. // // Since 4-bit for sub-sub-structure is not enough to specify a muon layer, // the layer case counting methods are implemented for tracker only. This is // different from the hit counting methods which are implemented for both // tracker and muon detector. // // Given a tracker layer, specified by sub-structure and layer, the method // getTrackerLayerCase(substr, layer) groups all of the hits in the hit pattern // array for the layer together and returns one of the four cases // // crossed // layer case 0: VALID + (MISSING, OFF, BAD) ==> with measurement // layer case 1: MISSING + (OFF, BAD) ==> without measurement // layer case 2: OFF, BAD ==> totally off or bad, cannot say much // not crossed // layer case NULL_RETURN: track outside acceptance or in gap ==> null // // Given a tracker layer, specified by sub-structure and layer, the method // getTrackerMonoStereo(substr, layer) groups all of the valid hits in the hit // pattern array for the layer together and returns // // 0: neither a valid mono nor a valid stereo hit // MONO: valid mono hit // STEREO: valid stereo hit // MONO | STEREO: both // // // Given a track, here is an example usage of hit pattern // // // hit pattern of the track // const reco::HitPattern &p = track->hitPattern(); // // // loop over the hits of the track. // for (int i = 0; i < p.numberOfAllHits(HitPattern::TRACK_HITS); i++) { // uint32_t hit = p.getHitPattern(HitPattern::TRACK_HITS, i); // // // if the hit is valid and in pixel barrel, print out the layer // if (p.validHitFilter(hit) && p.pixelBarrelHitFilter(hit)){ // cout << "valid hit found in pixel barrel layer " // << p.getLayer(hit) // << endl; // } // // // expert level: printout the hit in 11-bit binary format // cout << "hit in 11-bit binary format = "; // for (int j = 10; j >= 0; j--){ // int bit = (hit >> j) & 0x1; // cout << bit; // } // cout << endl; // } // // //count the number of valid pixel barrel *** hits *** // cout << "number of of valid pixel barrel hits is " // << p.numberOfValidPixelBarrelHits() // << endl; // // //count the number of pixel barrel *** layers *** with measurement // cout << "number of of pixel barrel layers with measurement is " // << p.pixelBarrelLayersWithMeasurement() // << endl; // #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h" #include "DataFormats/SiStripDetId/interface/StripSubdetector.h" #include "DataFormats/MuonDetId/interface/MuonSubdetId.h" #include "DataFormats/ForwardDetId/interface/MTDDetId.h" #include "DataFormats/Scouting/interface/Run3ScoutingHitPatternPOD.h" #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h" #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h" #include "FWCore/Utilities/interface/Likely.h" #include <utility> #include <algorithm> #include <iostream> #include <ostream> #include <memory> class TrackerTopology; namespace test { namespace TestHitPattern { int test(); } } // namespace test namespace reco { class HitPattern { public: enum { MONO = 1, STEREO = 2 }; enum HIT_DETECTOR_TYPE { MUON_HIT = 0, TRACKER_HIT = 1, MTD_HIT = 2 }; enum HIT_TYPE { VALID = 0, MISSING = 1, INACTIVE = 2, BAD = 3 }; enum HitCategory { TRACK_HITS = 0, MISSING_INNER_HITS = 1, MISSING_OUTER_HITS = 2 }; const static unsigned short ARRAY_LENGTH = 57; const static unsigned short HIT_LENGTH = 12; const static unsigned short MaxHits = (8 * sizeof(uint16_t) * ARRAY_LENGTH) / HIT_LENGTH; static const uint32_t NULL_RETURN = 999999; static const uint16_t EMPTY_PATTERN = 0x0; static bool trackerHitFilter(uint16_t pattern); static bool muonHitFilter(uint16_t pattern); static bool timingHitFilter(uint16_t pattern); static bool validHitFilter(uint16_t pattern); static bool missingHitFilter(uint16_t pattern); static bool inactiveHitFilter(uint16_t pattern); static bool badHitFilter(uint16_t pattern); static bool pixelHitFilter(uint16_t pattern); static bool pixelBarrelHitFilter(uint16_t pattern); static bool pixelEndcapHitFilter(uint16_t pattern); static bool stripHitFilter(uint16_t pattern); static bool stripTIBHitFilter(uint16_t pattern); static bool stripTIDHitFilter(uint16_t pattern); static bool stripTOBHitFilter(uint16_t pattern); static bool stripTECHitFilter(uint16_t pattern); static bool muonDTHitFilter(uint16_t pattern); static bool muonCSCHitFilter(uint16_t pattern); static bool muonRPCHitFilter(uint16_t pattern); static bool muonGEMHitFilter(uint16_t pattern); static bool muonME0HitFilter(uint16_t pattern); static bool timingBTLHitFilter(uint16_t pattern); static bool timingETLHitFilter(uint16_t pattern); static uint32_t getHitType(uint16_t pattern); // mono (0) or stereo (1) static uint32_t getSide(uint16_t pattern); static uint32_t getLayer(uint16_t pattern); static uint32_t getSubSubStructure(uint16_t pattern); static uint32_t getSubStructure(uint16_t pattern); static uint32_t getSubDetector(uint16_t pattern); /// Muon station (1-4). Only valid for muon patterns, of course. only for patterns from muon, of course static uint16_t getMuonStation(uint16_t pattern); /// DT superlayer (1-3). Where the "hit" was a DT segment, superlayer is 0. Only valid for muon DT patterns, of course. static uint16_t getDTSuperLayer(uint16_t pattern); // only for DT patterns /// CSC ring (1-4). Only valid for muon CSC patterns, of course. static uint16_t getCSCRing(uint16_t pattern); /// RPC layer: for station 1 and 2, layer = 1(inner) or 2(outer); for station 3, 4 layer is always 0. Only valid for muon RPC patterns, of course. static uint16_t getRPCLayer(uint16_t pattern); /// RPC region: 0 = barrel, 1 = endcap. Only valid for muon RPC patterns, of course. static uint16_t getRPCregion(uint16_t pattern); /// GEM station: 1,2. Only valid for muon GEM patterns, of course. static uint16_t getGEMStation(uint16_t pattern); /// GEM layer: 1-6 for station 0, 1-2 for stations 1 and 2. Only valid for muon GEM patterns, of course. static uint16_t getGEMLayer(uint16_t pattern); /// BTL Module type: 1,2,3. Only valid for BTL patterns of course. static uint16_t getBTLModType(uint16_t pattern); /// ETL Ring: 1-12. Only valid for ETL patterns of course. static uint16_t getETLRing(uint16_t pattern); HitPattern(); ~HitPattern(); HitPattern(const HitPattern &other); HitPattern(const Run3ScoutingHitPatternPOD &other); HitPattern &operator=(const HitPattern &other); template <typename I> bool appendHits(const I &begin, const I &end, const TrackerTopology &ttopo); bool appendHit(const TrackingRecHit &hit, const TrackerTopology &ttopo); bool appendHit(const TrackingRecHitRef &ref, const TrackerTopology &ttopo); bool appendHit(const DetId &id, TrackingRecHit::Type hitType, const TrackerTopology &ttopo); bool appendHit(const uint16_t pattern, TrackingRecHit::Type hitType); /** * This is meant to be used only in cases where the an * already-packed hit information is re-interpreted in terms of * HitPattern (i.e. MiniAOD PackedCandidate, and the IO rule for * reading old versions of HitPattern) */ bool appendTrackerHit(uint16_t subdet, uint16_t layer, uint16_t stereo, TrackingRecHit::Type hitType); /** * This is meant to be used only in cases where the an * already-packed hit information is re-interpreted in terms of * HitPattern (i.e. the IO rule for reading old versions of * HitPattern) */ bool appendMuonHit(const DetId &id, TrackingRecHit::Type hitType); // get the pattern of the position-th hit uint16_t getHitPattern(HitCategory category, int position) const; void clear(); // print the pattern of the position-th hit void printHitPattern(HitCategory category, int position, std::ostream &stream) const; void print(HitCategory category, std::ostream &stream = std::cout) const; // has valid hit in PXB/PXF layer x bool hasValidHitInPixelLayer(enum PixelSubdetector::SubDetector, uint16_t layer) const; int numberOfAllHits(HitCategory category) const; // not-null int numberOfValidHits() const; // not-null, valid int numberOfAllTrackerHits(HitCategory category) const; // not-null, tracker int numberOfValidTrackerHits() const; // not-null, valid, tracker int numberOfValidPixelHits() const; // not-null, valid, pixel int numberOfValidPixelBarrelHits() const; // not-null, valid, pixel PXB int numberOfValidPixelEndcapHits() const; // not-null, valid, pixel PXF int numberOfValidStripHits() const; // not-null, valid, strip int numberOfValidStripTIBHits() const; // not-null, valid, strip TIB int numberOfValidStripTIDHits() const; // not-null, valid, strip TID int numberOfValidStripTOBHits() const; // not-null, valid, strip TOB int numberOfValidStripTECHits() const; // not-null, valid, strip TEC int numberOfLostHits(HitCategory category) const; // not-null, not valid int numberOfLostTrackerHits(HitCategory category) const; // not-null, not valid, tracker int numberOfLostPixelHits(HitCategory category) const; // not-null, not valid, pixel int numberOfLostPixelBarrelHits(HitCategory category) const; // not-null, not valid, pixel PXB int numberOfLostPixelEndcapHits(HitCategory category) const; // not-null, not valid, pixel PXF int numberOfLostStripHits(HitCategory category) const; // not-null, not valid, strip int numberOfLostStripTIBHits(HitCategory category) const; // not-null, not valid, strip TIB int numberOfLostStripTIDHits(HitCategory category) const; // not-null, not valid, strip TID int numberOfLostStripTOBHits(HitCategory category) const; // not-null, not valid, strip TOB int numberOfLostStripTECHits(HitCategory category) const; // not-null, not valid, strip TEC int numberOfTimingHits() const; // not-null timing int numberOfValidTimingHits() const; // not-null, valid, timing int numberOfValidTimingBTLHits() const; // not-null, valid, timing BTL int numberOfValidTimingETLHits() const; // not-null, valid, timing ETL int numberOfLostTimingHits() const; // not-null, not valid, timing int numberOfLostTimingBTLHits() const; // not-null, not valid, timing BTL int numberOfLostTimingETLHits() const; // not-null, not valid, timing ETL int numberOfMuonHits() const; // not-null, muon int numberOfValidMuonHits() const; // not-null, valid, muon int numberOfValidMuonDTHits() const; // not-null, valid, muon DT int numberOfValidMuonCSCHits() const; // not-null, valid, muon CSC int numberOfValidMuonRPCHits() const; // not-null, valid, muon RPC int numberOfValidMuonGEMHits() const; // not-null, valid, muon GEM int numberOfValidMuonME0Hits() const; // not-null, valid, muon ME0 int numberOfLostMuonHits() const; // not-null, not valid, muon int numberOfLostMuonDTHits() const; // not-null, not valid, muon DT int numberOfLostMuonCSCHits() const; // not-null, not valid, muon CSC int numberOfLostMuonRPCHits() const; // not-null, not valid, muon RPC int numberOfLostMuonGEMHits() const; // not-null, not valid, muon GEM int numberOfLostMuonME0Hits() const; // not-null, not valid, muon ME0 int numberOfBadHits() const; // not-null, bad (only used in Muon Ch.) int numberOfBadMuonHits() const; // not-null, bad, muon int numberOfBadMuonDTHits() const; // not-null, bad, muon DT int numberOfBadMuonCSCHits() const; // not-null, bad, muon CSC int numberOfBadMuonRPCHits() const; // not-null, bad, muon RPC int numberOfBadMuonGEMHits() const; // not-null, bad, muon GEM int numberOfBadMuonME0Hits() const; // not-null, bad, muon ME0 int numberOfInactiveHits() const; // not-null, inactive int numberOfInactiveTrackerHits() const; // not-null, inactive, tracker int numberOfInactiveTimingHits() const; // not-null, inactive, timing // count strip layers that have non-null, valid mono and stereo hits int numberOfValidStripLayersWithMonoAndStereo(uint16_t stripdet, uint16_t layer) const; int numberOfValidStripLayersWithMonoAndStereo() const; int numberOfValidTOBLayersWithMonoAndStereo(uint32_t layer = 0) const; int numberOfValidTIBLayersWithMonoAndStereo(uint32_t layer = 0) const; int numberOfValidTIDLayersWithMonoAndStereo(uint32_t layer = 0) const; int numberOfValidTECLayersWithMonoAndStereo(uint32_t layer = 0) const; uint32_t getTrackerLayerCase(HitCategory category, uint16_t substr, uint16_t layer) const; uint16_t getTrackerMonoStereo(HitCategory category, uint16_t substr, uint16_t layer) const; int trackerLayersWithMeasurementOld() const; // case 0: tracker int trackerLayersWithMeasurement() const; // case 0: tracker int pixelLayersWithMeasurementOld() const; // case 0: pixel int pixelLayersWithMeasurement() const; // case 0: pixel int stripLayersWithMeasurement() const; // case 0: strip int pixelBarrelLayersWithMeasurement() const; // case 0: pixel PXB int pixelEndcapLayersWithMeasurement() const; // case 0: pixel PXF int stripTIBLayersWithMeasurement() const; // case 0: strip TIB int stripTIDLayersWithMeasurement() const; // case 0: strip TID int stripTOBLayersWithMeasurement() const; // case 0: strip TOB int stripTECLayersWithMeasurement() const; // case 0: strip TEC int trackerLayersWithoutMeasurement(HitCategory category) const; // case 1: tracker int trackerLayersWithoutMeasurementOld(HitCategory category) const; // case 1: tracker int pixelLayersWithoutMeasurement(HitCategory category) const; // case 1: pixel int stripLayersWithoutMeasurement(HitCategory category) const; // case 1: strip int pixelBarrelLayersWithoutMeasurement(HitCategory category) const; // case 1: pixel PXB int pixelEndcapLayersWithoutMeasurement(HitCategory category) const; // case 1: pixel PXF int stripTIBLayersWithoutMeasurement(HitCategory category) const; // case 1: strip TIB int stripTIDLayersWithoutMeasurement(HitCategory category) const; // case 1: strip TID int stripTOBLayersWithoutMeasurement(HitCategory category) const; // case 1: strip TOB int stripTECLayersWithoutMeasurement(HitCategory category) const; // case 1: strip TEC int trackerLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: tracker int pixelLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: pixel int stripLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: strip int pixelBarrelLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: pixel PXB int pixelEndcapLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: pixel PXF int stripTIBLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: strip TIB int stripTIDLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: strip TID int stripTOBLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: strip TOB int stripTECLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const; // case 2: strip TEC int trackerLayersNull() const; // case NULL_RETURN: tracker int pixelLayersNull() const; // case NULL_RETURN: pixel int stripLayersNull() const; // case NULL_RETURN: strip int pixelBarrelLayersNull() const; // case NULL_RETURN: pixel PXB int pixelEndcapLayersNull() const; // case NULL_RETURN: pixel PXF int stripTIBLayersNull() const; // case NULL_RETURN: strip TIB int stripTIDLayersNull() const; // case NULL_RETURN: strip TID int stripTOBLayersNull() const; // case NULL_RETURN: strip TOB int stripTECLayersNull() const; // case NULL_RETURN: strip TEC /// subdet = 0(all), 1(DT), 2(CSC), 3(RPC) 4(GEM); hitType=-1(all), 0=valid, 3=bad int muonStations(int subdet, int hitType) const; int muonStationsWithValidHits() const; int muonStationsWithBadHits() const; int muonStationsWithAnyHits() const; int dtStationsWithValidHits() const; int dtStationsWithBadHits() const; int dtStationsWithAnyHits() const; int cscStationsWithValidHits() const; int cscStationsWithBadHits() const; int cscStationsWithAnyHits() const; int rpcStationsWithValidHits() const; int rpcStationsWithBadHits() const; int rpcStationsWithAnyHits() const; int gemStationsWithValidHits() const; int gemStationsWithBadHits() const; int gemStationsWithAnyHits() const; int me0StationsWithValidHits() const; int me0StationsWithBadHits() const; int me0StationsWithAnyHits() const; /// hitType=-1(all), 0=valid, 3=bad; 0 = no stations at all int innermostMuonStationWithHits(int hitType) const; int innermostMuonStationWithValidHits() const; int innermostMuonStationWithBadHits() const; int innermostMuonStationWithAnyHits() const; /// hitType=-1(all), 0=valid, 3=bad; 0 = no stations at all int outermostMuonStationWithHits(int hitType) const; int outermostMuonStationWithValidHits() const; int outermostMuonStationWithBadHits() const; int outermostMuonStationWithAnyHits() const; int numberOfDTStationsWithRPhiView() const; int numberOfDTStationsWithRZView() const; int numberOfDTStationsWithBothViews() const; // fill Run3ScoutingHitPatternPOD struct Run3ScoutingHitPatternPOD run3ScoutingHitPatternPOD() const; //only used by ROOT IO rule to read v12 HitPatterns static bool fillNewHitPatternWithOldHitPattern_v12(const uint16_t oldHitPattern[], uint8_t hitCount, uint8_t beginTrackHits, uint8_t endTrackHits, uint8_t beginInner, uint8_t endInner, uint8_t beginOuter, uint8_t endOuter, reco::HitPattern *newObj); private: // 3 bits for hit type const static unsigned short HitTypeOffset = 0; const static unsigned short HitTypeMask = 0x3; // 1 bit to identify the side in double-sided detectors const static unsigned short SideOffset = 2; const static unsigned short SideMask = 0x1; // 4 bits to identify the layer/disk/wheel within the substructure const static unsigned short LayerOffset = 3; const static unsigned short LayerMask = 0xF; // 3 bits to identify the tracker/muon detector substructure const static unsigned short SubstrOffset = 7; const static unsigned short SubstrMask = 0x7; // 2 bits to distinguish tracker, muon, mtd subsystems const static unsigned short SubDetectorOffset = 10; const static unsigned short SubDetectorMask = 0x3; const static unsigned short minTrackerWord = 1 << SubDetectorOffset; const static unsigned short maxTrackerWord = (2 << SubDetectorOffset) - 1; const static unsigned short minPixelWord = minTrackerWord | (1 << SubstrOffset); const static unsigned short minStripWord = minTrackerWord | (3 << SubstrOffset); // detector side for tracker modules (mono/stereo) static uint16_t isStereo(DetId i, const TrackerTopology &ttopo); static bool stripSubdetectorHitFilter(uint16_t pattern, StripSubdetector::SubDetector substructure); static uint16_t encode(const TrackingRecHit &hit, const TrackerTopology &ttopo); static uint16_t encode(const DetId &id, TrackingRecHit::Type hitType, const TrackerTopology &ttopo); static uint16_t encode(uint16_t det, uint16_t subdet, uint16_t layer, uint16_t side, TrackingRecHit::Type hitType); // generic count methods typedef bool filterType(uint16_t); template <typename F> void call(HitCategory category, filterType typeFilter, F f) const; int countHits(HitCategory category, filterType filter) const; int countTypedHits(HitCategory category, filterType typeFilter, filterType filter) const; bool insertTrackHit(const uint16_t pattern); bool insertExpectedInnerHit(const uint16_t pattern); bool insertExpectedOuterHit(const uint16_t pattern); void insertHit(const uint16_t pattern); uint16_t getHitPatternByAbsoluteIndex(int position) const; std::pair<uint8_t, uint8_t> getCategoryIndexRange(HitCategory category) const; uint16_t hitPattern[ARRAY_LENGTH]; uint8_t hitCount; uint8_t beginTrackHits; uint8_t endTrackHits; uint8_t beginInner; uint8_t endInner; uint8_t beginOuter; uint8_t endOuter; friend int ::test::TestHitPattern::test(); template <int N> friend struct PatternSet; }; inline std::pair<uint8_t, uint8_t> HitPattern::getCategoryIndexRange(HitCategory category) const { switch (category) { case TRACK_HITS: return std::pair<uint8_t, uint8_t>(beginTrackHits, endTrackHits); break; case MISSING_INNER_HITS: return std::pair<uint8_t, uint8_t>(beginInner, endInner); break; case MISSING_OUTER_HITS: return std::pair<uint8_t, uint8_t>(beginOuter, endOuter); break; } return std::pair<uint8_t, uint8_t>(-1, -1); } template <typename I> bool HitPattern::appendHits(const I &begin, const I &end, const TrackerTopology &ttopo) { for (I hit = begin; hit != end; hit++) { if UNLIKELY ((!appendHit(*hit, ttopo))) { return false; } } return true; } inline uint16_t HitPattern::getHitPattern(HitCategory category, int position) const { std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category); if UNLIKELY ((position < 0 || (position + range.first) >= range.second)) { return HitPattern::EMPTY_PATTERN; } return getHitPatternByAbsoluteIndex(range.first + position); } inline int HitPattern::countHits(HitCategory category, filterType filter) const { int count = 0; std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category); for (int i = range.first; i < range.second; ++i) { if (filter(getHitPatternByAbsoluteIndex(i))) { ++count; } } return count; } template <typename F> void HitPattern::call(HitCategory category, filterType typeFilter, F f) const { std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category); for (int i = range.first; i < range.second; i++) { uint16_t pattern = getHitPatternByAbsoluteIndex(i); // f() return false to ask to stop looping if (typeFilter(pattern) && !f(pattern)) { break; } } } inline int HitPattern::countTypedHits(HitCategory category, filterType typeFilter, filterType filter) const { int count = 0; std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category); for (int i = range.first; i < range.second; ++i) { uint16_t pattern = getHitPatternByAbsoluteIndex(i); if (typeFilter(pattern) && filter(pattern)) { ++count; } } return count; } inline bool HitPattern::pixelHitFilter(uint16_t pattern) { if UNLIKELY (!trackerHitFilter(pattern)) { return false; } uint32_t substructure = getSubStructure(pattern); return (substructure == PixelSubdetector::PixelBarrel || substructure == PixelSubdetector::PixelEndcap); } inline bool HitPattern::pixelBarrelHitFilter(uint16_t pattern) { if UNLIKELY (!trackerHitFilter(pattern)) { return false; } uint32_t substructure = getSubStructure(pattern); return (substructure == PixelSubdetector::PixelBarrel); } inline bool HitPattern::pixelEndcapHitFilter(uint16_t pattern) { if UNLIKELY (!trackerHitFilter(pattern)) { return false; } uint32_t substructure = getSubStructure(pattern); return (substructure == PixelSubdetector::PixelEndcap); } inline bool HitPattern::stripHitFilter(uint16_t pattern) { return pattern > minStripWord && pattern <= maxTrackerWord; } inline bool HitPattern::stripSubdetectorHitFilter(uint16_t pattern, StripSubdetector::SubDetector substructure) { if UNLIKELY (!trackerHitFilter(pattern)) { return false; } return substructure == getSubStructure(pattern); } inline bool HitPattern::stripTIBHitFilter(uint16_t pattern) { return stripSubdetectorHitFilter(pattern, StripSubdetector::TIB); } inline bool HitPattern::stripTIDHitFilter(uint16_t pattern) { return stripSubdetectorHitFilter(pattern, StripSubdetector::TID); } inline bool HitPattern::stripTOBHitFilter(uint16_t pattern) { return stripSubdetectorHitFilter(pattern, StripSubdetector::TOB); } inline bool HitPattern::stripTECHitFilter(uint16_t pattern) { return stripSubdetectorHitFilter(pattern, StripSubdetector::TEC); } inline bool HitPattern::muonDTHitFilter(uint16_t pattern) { if UNLIKELY (!muonHitFilter(pattern)) { return false; } uint32_t substructure = getSubStructure(pattern); return (substructure == (uint32_t)MuonSubdetId::DT); } inline bool HitPattern::muonCSCHitFilter(uint16_t pattern) { if UNLIKELY (!muonHitFilter(pattern)) { return false; } uint32_t substructure = getSubStructure(pattern); return (substructure == (uint32_t)MuonSubdetId::CSC); } inline bool HitPattern::muonRPCHitFilter(uint16_t pattern) { if UNLIKELY (!muonHitFilter(pattern)) { return false; } uint32_t substructure = getSubStructure(pattern); return (substructure == (uint32_t)MuonSubdetId::RPC); } inline bool HitPattern::muonGEMHitFilter(uint16_t pattern) { if UNLIKELY (!muonHitFilter(pattern)) { return false; } uint32_t substructure = getSubStructure(pattern); return (substructure == (uint32_t)MuonSubdetId::GEM); } inline bool HitPattern::muonME0HitFilter(uint16_t pattern) { if UNLIKELY (!muonHitFilter(pattern)) return false; uint16_t substructure = getSubStructure(pattern); return (substructure == (uint16_t)MuonSubdetId::ME0); } inline bool HitPattern::trackerHitFilter(uint16_t pattern) { return pattern > minTrackerWord && pattern <= maxTrackerWord; } inline bool HitPattern::muonHitFilter(uint16_t pattern) { if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) { return false; } return (((pattern >> SubDetectorOffset) & SubDetectorMask) == 0); } inline bool HitPattern::timingBTLHitFilter(uint16_t pattern) { if UNLIKELY (!timingHitFilter(pattern)) return false; uint16_t substructure = getSubStructure(pattern); return (substructure == (uint16_t)MTDDetId::BTL); } inline bool HitPattern::timingETLHitFilter(uint16_t pattern) { if UNLIKELY (!timingHitFilter(pattern)) return false; uint16_t substructure = getSubStructure(pattern); return (substructure == (uint16_t)MTDDetId::ETL); } inline bool HitPattern::timingHitFilter(uint16_t pattern) { if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) { return false; } return (((pattern >> SubDetectorOffset) & SubDetectorMask) == 2); } inline uint32_t HitPattern::getSubStructure(uint16_t pattern) { if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) { return NULL_RETURN; } return ((pattern >> SubstrOffset) & SubstrMask); } inline uint32_t HitPattern::getLayer(uint16_t pattern) { return HitPattern::getSubSubStructure(pattern); } inline uint32_t HitPattern::getSubSubStructure(uint16_t pattern) { if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) { return NULL_RETURN; } return ((pattern >> LayerOffset) & LayerMask); } inline uint32_t HitPattern::getSubDetector(uint16_t pattern) { if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) { return NULL_RETURN; } return ((pattern >> SubDetectorOffset) & SubDetectorMask); } inline uint32_t HitPattern::getSide(uint16_t pattern) { if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) { return NULL_RETURN; } return (pattern >> SideOffset) & SideMask; } inline uint32_t HitPattern::getHitType(uint16_t pattern) { if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) { return NULL_RETURN; } return ((pattern >> HitTypeOffset) & HitTypeMask); } inline uint16_t HitPattern::getMuonStation(uint16_t pattern) { return muonGEMHitFilter(pattern) ? getGEMStation(pattern) : (getSubSubStructure(pattern) >> 2) + 1; } inline uint16_t HitPattern::getDTSuperLayer(uint16_t pattern) { return (getSubSubStructure(pattern) & 3); } inline uint16_t HitPattern::getCSCRing(uint16_t pattern) { return (getSubSubStructure(pattern) & 3) + 1; } inline uint16_t HitPattern::getRPCLayer(uint16_t pattern) { uint16_t subSubStructure = getSubSubStructure(pattern); uint16_t stat = subSubStructure >> 2; if LIKELY (stat <= 1) { return ((subSubStructure >> 1) & 1) + 1; } return 0; } inline uint16_t HitPattern::getRPCregion(uint16_t pattern) { return getSubSubStructure(pattern) & 1; } ////////////////////////////// GEM inline uint16_t HitPattern::getGEMStation(uint16_t pattern) { uint16_t sss = getSubSubStructure(pattern); if (sss & 0b1000) return 0; return (sss >> 2) + 1; } /// MTD inline uint16_t HitPattern::getBTLModType(uint16_t pattern) { return getSubSubStructure(pattern); } inline uint16_t HitPattern::getETLRing(uint16_t pattern) { return getSubSubStructure(pattern); } inline uint16_t HitPattern::getGEMLayer(uint16_t pattern) { uint16_t sss = getSubSubStructure(pattern); if (sss & 0b1000) return (sss & 0b0111) + 1; return (sss & 0b11) + 1; } inline bool HitPattern::validHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::VALID; } inline bool HitPattern::missingHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::MISSING; } inline bool HitPattern::inactiveHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::INACTIVE; } inline bool HitPattern::badHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::BAD; } inline int HitPattern::numberOfAllHits(HitCategory category) const { std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category); return range.second - range.first; } inline int HitPattern::numberOfAllTrackerHits(HitCategory category) const { return countHits(category, trackerHitFilter); } inline int HitPattern::numberOfMuonHits() const { return countHits(TRACK_HITS, muonHitFilter); } inline int HitPattern::numberOfTimingHits() const { return countHits(TRACK_HITS, timingHitFilter); } inline int HitPattern::numberOfValidHits() const { return countHits(TRACK_HITS, validHitFilter); } inline int HitPattern::numberOfValidTrackerHits() const { return countTypedHits(TRACK_HITS, validHitFilter, trackerHitFilter); } inline int HitPattern::numberOfValidMuonHits() const { return countTypedHits(TRACK_HITS, validHitFilter, muonHitFilter); } inline int HitPattern::numberOfValidTimingHits() const { return countTypedHits(TRACK_HITS, validHitFilter, timingHitFilter); } inline int HitPattern::numberOfValidPixelHits() const { return countTypedHits(TRACK_HITS, validHitFilter, pixelHitFilter); } inline int HitPattern::numberOfValidPixelBarrelHits() const { return countTypedHits(TRACK_HITS, validHitFilter, pixelBarrelHitFilter); } inline int HitPattern::numberOfValidPixelEndcapHits() const { return countTypedHits(TRACK_HITS, validHitFilter, pixelEndcapHitFilter); } inline int HitPattern::numberOfValidStripHits() const { return countTypedHits(TRACK_HITS, validHitFilter, stripHitFilter); } inline int HitPattern::numberOfValidStripTIBHits() const { return countTypedHits(TRACK_HITS, validHitFilter, stripTIBHitFilter); } inline int HitPattern::numberOfValidStripTIDHits() const { return countTypedHits(TRACK_HITS, validHitFilter, stripTIDHitFilter); } inline int HitPattern::numberOfValidStripTOBHits() const { return countTypedHits(TRACK_HITS, validHitFilter, stripTOBHitFilter); } inline int HitPattern::numberOfValidStripTECHits() const { return countTypedHits(TRACK_HITS, validHitFilter, stripTECHitFilter); } inline int HitPattern::numberOfValidMuonDTHits() const { return countTypedHits(TRACK_HITS, validHitFilter, muonDTHitFilter); } inline int HitPattern::numberOfValidMuonCSCHits() const { return countTypedHits(TRACK_HITS, validHitFilter, muonCSCHitFilter); } inline int HitPattern::numberOfValidMuonRPCHits() const { return countTypedHits(TRACK_HITS, validHitFilter, muonRPCHitFilter); } inline int HitPattern::numberOfValidMuonGEMHits() const { return countTypedHits(TRACK_HITS, validHitFilter, muonGEMHitFilter); } inline int HitPattern::numberOfValidMuonME0Hits() const { return countTypedHits(TRACK_HITS, validHitFilter, muonME0HitFilter); } inline int HitPattern::numberOfValidTimingBTLHits() const { return countTypedHits(TRACK_HITS, validHitFilter, timingBTLHitFilter); } inline int HitPattern::numberOfValidTimingETLHits() const { return countTypedHits(TRACK_HITS, validHitFilter, timingETLHitFilter); } inline int HitPattern::numberOfLostHits(HitCategory category) const { return countHits(category, missingHitFilter); } inline int HitPattern::numberOfLostTrackerHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, trackerHitFilter); } inline int HitPattern::numberOfLostMuonHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, muonHitFilter); } inline int HitPattern::numberOfLostTimingHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, timingHitFilter); } inline int HitPattern::numberOfLostTimingBTLHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, timingBTLHitFilter); } inline int HitPattern::numberOfLostTimingETLHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, timingETLHitFilter); } inline int HitPattern::numberOfLostPixelHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, pixelHitFilter); } inline int HitPattern::numberOfLostPixelBarrelHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, pixelBarrelHitFilter); } inline int HitPattern::numberOfLostPixelEndcapHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, pixelEndcapHitFilter); } inline int HitPattern::numberOfLostStripHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, stripHitFilter); } inline int HitPattern::numberOfLostStripTIBHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, stripTIBHitFilter); } inline int HitPattern::numberOfLostStripTIDHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, stripTIDHitFilter); } inline int HitPattern::numberOfLostStripTOBHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, stripTOBHitFilter); } inline int HitPattern::numberOfLostStripTECHits(HitCategory category) const { return countTypedHits(category, missingHitFilter, stripTECHitFilter); } inline int HitPattern::numberOfLostMuonDTHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, muonDTHitFilter); } inline int HitPattern::numberOfLostMuonCSCHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, muonCSCHitFilter); } inline int HitPattern::numberOfLostMuonRPCHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, muonRPCHitFilter); } inline int HitPattern::numberOfLostMuonGEMHits() const { return countTypedHits(TRACK_HITS, missingHitFilter, muonGEMHitFilter); } inline int HitPattern::numberOfLostMuonME0Hits() const { return countTypedHits(TRACK_HITS, missingHitFilter, muonME0HitFilter); } inline int HitPattern::numberOfBadHits() const { return countHits(TRACK_HITS, badHitFilter); } inline int HitPattern::numberOfBadMuonHits() const { return countTypedHits(TRACK_HITS, inactiveHitFilter, muonHitFilter); } inline int HitPattern::numberOfBadMuonDTHits() const { return countTypedHits(TRACK_HITS, inactiveHitFilter, muonDTHitFilter); } inline int HitPattern::numberOfBadMuonCSCHits() const { return countTypedHits(TRACK_HITS, inactiveHitFilter, muonCSCHitFilter); } inline int HitPattern::numberOfBadMuonRPCHits() const { return countTypedHits(TRACK_HITS, inactiveHitFilter, muonRPCHitFilter); } inline int HitPattern::numberOfBadMuonGEMHits() const { return countTypedHits(TRACK_HITS, inactiveHitFilter, muonGEMHitFilter); } inline int HitPattern::numberOfBadMuonME0Hits() const { return countTypedHits(TRACK_HITS, inactiveHitFilter, muonME0HitFilter); } inline int HitPattern::numberOfInactiveHits() const { return countHits(TRACK_HITS, inactiveHitFilter); } inline int HitPattern::numberOfInactiveTrackerHits() const { return countTypedHits(TRACK_HITS, inactiveHitFilter, trackerHitFilter); } inline int HitPattern::trackerLayersWithMeasurementOld() const { return pixelLayersWithMeasurement() + stripLayersWithMeasurement(); } inline int HitPattern::pixelLayersWithMeasurementOld() const { return pixelBarrelLayersWithMeasurement() + pixelEndcapLayersWithMeasurement(); } inline int HitPattern::stripLayersWithMeasurement() const { return stripTIBLayersWithMeasurement() + stripTIDLayersWithMeasurement() + stripTOBLayersWithMeasurement() + stripTECLayersWithMeasurement(); } inline int HitPattern::trackerLayersWithoutMeasurementOld(HitCategory category) const { return pixelLayersWithoutMeasurement(category) + stripLayersWithoutMeasurement(category); } inline int HitPattern::pixelLayersWithoutMeasurement(HitCategory category) const { return pixelBarrelLayersWithoutMeasurement(category) + pixelEndcapLayersWithoutMeasurement(category); } inline int HitPattern::stripLayersWithoutMeasurement(HitCategory category) const { return stripTIBLayersWithoutMeasurement(category) + stripTIDLayersWithoutMeasurement(category) + stripTOBLayersWithoutMeasurement(category) + stripTECLayersWithoutMeasurement(category); } inline int HitPattern::trackerLayersTotallyOffOrBad(HitCategory category) const { return pixelLayersTotallyOffOrBad(category) + stripLayersTotallyOffOrBad(category); } inline int HitPattern::pixelLayersTotallyOffOrBad(HitCategory category) const { return pixelBarrelLayersTotallyOffOrBad(category) + pixelEndcapLayersTotallyOffOrBad(category); } inline int HitPattern::stripLayersTotallyOffOrBad(HitCategory category) const { return stripTIBLayersTotallyOffOrBad(category) + stripTIDLayersTotallyOffOrBad(category) + stripTOBLayersTotallyOffOrBad(category) + stripTECLayersTotallyOffOrBad(category); } inline int HitPattern::trackerLayersNull() const { return pixelLayersNull() + stripLayersNull(); } inline int HitPattern::pixelLayersNull() const { return pixelBarrelLayersNull() + pixelEndcapLayersNull(); } inline int HitPattern::stripLayersNull() const { return stripTIBLayersNull() + stripTIDLayersNull() + stripTOBLayersNull() + stripTECLayersNull(); } inline int HitPattern::muonStationsWithValidHits() const { return muonStations(0, 0); } inline int HitPattern::muonStationsWithBadHits() const { return muonStations(0, 3); } inline int HitPattern::muonStationsWithAnyHits() const { return muonStations(0, -1); } inline int HitPattern::dtStationsWithValidHits() const { return muonStations(1, 0); } inline int HitPattern::dtStationsWithBadHits() const { return muonStations(1, 3); } inline int HitPattern::dtStationsWithAnyHits() const { return muonStations(1, -1); } inline int HitPattern::cscStationsWithValidHits() const { return muonStations(2, 0); } inline int HitPattern::cscStationsWithBadHits() const { return muonStations(2, 3); } inline int HitPattern::cscStationsWithAnyHits() const { return muonStations(2, -1); } inline int HitPattern::rpcStationsWithValidHits() const { return muonStations(3, 0); } inline int HitPattern::rpcStationsWithBadHits() const { return muonStations(3, 3); } inline int HitPattern::rpcStationsWithAnyHits() const { return muonStations(3, -1); } inline int HitPattern::gemStationsWithValidHits() const { return muonStations(4, 0); } inline int HitPattern::gemStationsWithBadHits() const { return muonStations(4, 3); } inline int HitPattern::gemStationsWithAnyHits() const { return muonStations(4, -1); } inline int HitPattern::me0StationsWithValidHits() const { return muonStations(5, 0); } inline int HitPattern::me0StationsWithBadHits() const { return muonStations(5, 3); } inline int HitPattern::me0StationsWithAnyHits() const { return muonStations(5, -1); } inline int HitPattern::innermostMuonStationWithValidHits() const { return innermostMuonStationWithHits(0); } inline int HitPattern::innermostMuonStationWithBadHits() const { return innermostMuonStationWithHits(3); } inline int HitPattern::innermostMuonStationWithAnyHits() const { return innermostMuonStationWithHits(-1); } inline int HitPattern::outermostMuonStationWithValidHits() const { return outermostMuonStationWithHits(0); } inline int HitPattern::outermostMuonStationWithBadHits() const { return outermostMuonStationWithHits(3); } inline int HitPattern::outermostMuonStationWithAnyHits() const { return outermostMuonStationWithHits(-1); } template <int N = HitPattern::MaxHits> struct PatternSet { static constexpr int MaxHits = N; unsigned char hit[N]; unsigned char nhit; unsigned char const *begin() const { return hit; } unsigned char const *end() const { return hit + nhit; } unsigned char *begin() { return hit; } unsigned char *end() { return hit + nhit; } int size() const { return nhit; } unsigned char operator[](int i) const { return hit[i]; } PatternSet() : nhit(0) {} PatternSet(HitPattern::HitCategory category, HitPattern const &hp) { fill(category, hp); } void fill(HitPattern::HitCategory category, HitPattern const &hp) { int lhit = 0; auto unpack = [&lhit, this](uint16_t pattern) -> bool { unsigned char p = 255 & (pattern >> 3); hit[lhit++] = p; // bouble sort if (lhit > 1) { for (auto h = hit + lhit - 1; h != hit; --h) { if ((*(h - 1)) <= p) { break; } (*h) = *(h - 1); *(h - 1) = p; } } return lhit < MaxHits; }; hp.call(category, HitPattern::validHitFilter, unpack); nhit = lhit; } }; template <int N> inline PatternSet<N> commonHits(PatternSet<N> const &p1, PatternSet<N> const &p2) { PatternSet<N> comm; comm.nhit = std::set_intersection(p1.begin(), p1.end(), p2.begin(), p2.end(), comm.begin()) - comm.begin(); return comm; } } // namespace reco #endif