Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-13 03:23:34

0001 // -*- C++ -*-
0002 
0003 #ifndef TrackReco_HitPattern_h
0004 #define TrackReco_HitPattern_h
0005 
0006 //
0007 // File: DataFormats/TrackReco/interface/HitPattern.h
0008 //
0009 // Marcel Vos, INFN Pisa
0010 // v1.10 2007/05/08 bellan
0011 // Zongru Wan, Kansas State University
0012 // Jean-Roch Vlimant
0013 // Kevin Burkett
0014 // Boris Mangano
0015 //
0016 // Hit pattern is the summary information of the hits associated to track in
0017 // AOD.  When RecHits are no longer available, the compact hit pattern should
0018 // allow basic track selection based on the hits in various subdetectors.
0019 // The hits of a track are saved in unit16_t hitPattern[MaxHits].
0020 //
0021 //                                            uint16_t
0022 // +------------+---------------+---------------------------+-----------------+----------------+
0023 // |  tk/mu/mtd | sub-structure |     sub-sub-structure     |     stereo      |    hit type    |
0024 // +------------+---------------+---------------------------+-----------------+----------------+
0025 // |    11-10   | 9   8    7    |  6     5     4     3      |        2        |    1        0  |  bit
0026 // +------------+---------------+---------------------------+-----------------+----------------|
0027 // | tk  = 1    |    PXB = 1    | layer = 1-3               |                 | hit type = 0-3 |
0028 // | tk  = 1    |    PXF = 2    | disk  = 1-2               |                 | hit type = 0-3 |
0029 // | tk  = 1    |    TIB = 3    | layer = 1-4               | 0=rphi,1=stereo | hit type = 0-3 |
0030 // | tk  = 1    |    TID = 4    | wheel = 1-3               | 0=rphi,1=stereo | hit type = 0-3 |
0031 // | tk  = 1    |    TOB = 5    | layer = 1-6               | 0=rphi,1=stereo | hit type = 0-3 |
0032 // | tk  = 1    |    TEC = 6    | wheel = 1-9               | 0=rphi,1=stereo | hit type = 0-3 |
0033 // | mu  = 0    |    DT  = 1    | 4*(stat-1)+superlayer     |                 | hit type = 0-3 |
0034 // | mu  = 0    |    CSC = 2    | 4*(stat-1)+(ring-1)       |                 | hit type = 0-3 |
0035 // | mu  = 0    |    RPC = 3    | 4*(stat-1)+2*layer+region |                 | hit type = 0-3 |
0036 // | mu  = 0    |    GEM = 4    | 1xxx=st0, 0yxx=st y-1 la x|                 | hit type = 0-3 |
0037 // | mu  = 0    |    ME0 = 5    | roll                      |                 | hit type = 0-3 |
0038 // | mtd = 2    |    BTL = 1    | globalReadoutUnit = 1-6   |                 | hit type = 0-3 |
0039 // | mtd = 2    |    ETL = 2    | encodedSector = 1-14      |                 | hit type = 0-3 |
0040 // +------------+---------------+---------------------------+-----------------+----------------+
0041 //
0042 //  hit type, see DataFormats/TrackingRecHit/interface/TrackingRecHit.h
0043 //      VALID    = valid hit                                     = 0
0044 //      MISSING  = detector is good, but no rec hit found        = 1
0045 //      INACTIVE = detector is off, so there was no hope         = 2
0046 //      BAD      = there were many bad strips within the ellipse = 3
0047 //
0048 // It had been shown by Zongru using a 100 GeV muon sample with 5000 events
0049 // uniform in eta and phi, the average (maximum) number of tracker hits is
0050 // 13 (17) and the average (maximum) number of muon detector hits is about
0051 // 26 (50). If the number of hits of a track is larger than 80 then the extra
0052 // hits are ignored by hit pattern. The static hit pattern array might be
0053 // improved to a dynamic one in the future.
0054 //
0055 // Because of tracking with/without overlaps and with/without hit-splitting,
0056 // the final number of hits per track is pretty "variable". Compared with the
0057 // number of valid hits, the number of crossed layers with measurement should
0058 // be more robust to discriminate between good and fake track.
0059 //
0060 // Since 4-bit for sub-sub-structure is not enough to specify a muon layer,
0061 // the layer case counting methods are implemented for tracker only. This is
0062 // different from the hit counting methods which are implemented for both
0063 // tracker and muon detector.
0064 //
0065 // Given a tracker layer, specified by sub-structure and layer, the method
0066 // getTrackerLayerCase(substr, layer) groups all of the hits in the hit pattern
0067 // array for the layer together and returns one of the four cases
0068 //
0069 //     crossed
0070 //        layer case 0: VALID + (MISSING, OFF, BAD) ==> with measurement
0071 //        layer case 1: MISSING + (OFF, BAD) ==> without measurement
0072 //        layer case 2: OFF, BAD ==> totally off or bad, cannot say much
0073 //     not crossed
0074 //        layer case NULL_RETURN: track outside acceptance or in gap ==> null
0075 //
0076 // Given a tracker layer, specified by sub-structure and layer, the method
0077 // getTrackerMonoStereo(substr, layer) groups all of the valid hits in the hit
0078 // pattern array for the layer together and returns
0079 //
0080 //              0: neither a valid mono nor a valid stereo hit
0081 //           MONO: valid mono hit
0082 //         STEREO: valid stereo hit
0083 //  MONO | STEREO: both
0084 //
0085 //
0086 // Given a track, here is an example usage of hit pattern
0087 //
0088 //     // hit pattern of the track
0089 //    const reco::HitPattern &p = track->hitPattern();
0090 //
0091 //     // loop over the hits of the track.
0092 //    for (int i = 0; i < p.numberOfAllHits(HitPattern::TRACK_HITS); i++) {
0093 //        uint32_t hit = p.getHitPattern(HitPattern::TRACK_HITS, i);
0094 //
0095 //        // if the hit is valid and in pixel barrel, print out the layer
0096 //        if (p.validHitFilter(hit) && p.pixelBarrelHitFilter(hit)){
0097 //            cout << "valid hit found in pixel barrel layer "
0098 //                 << p.getLayer(hit)
0099 //                 << endl;
0100 //        }
0101 //
0102 //        // expert level: printout the hit in 11-bit binary format
0103 //        cout << "hit in 11-bit binary format = ";
0104 //        for (int j = 10; j >= 0; j--){
0105 //            int bit = (hit >> j) & 0x1;
0106 //            cout << bit;
0107 //        }
0108 //        cout << endl;
0109 //    }
0110 //
0111 //    //count the number of valid pixel barrel *** hits ***
0112 //    cout << "number of of valid pixel barrel hits is "
0113 //         << p.numberOfValidPixelBarrelHits()
0114 //         << endl;
0115 //
0116 //    //count the number of pixel barrel *** layers *** with measurement
0117 //    cout << "number of of pixel barrel layers with measurement is "
0118 //         << p.pixelBarrelLayersWithMeasurement()
0119 //         << endl;
0120 //
0121 
0122 #include "DataFormats/DetId/interface/DetId.h"
0123 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0124 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0125 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
0126 #include "DataFormats/ForwardDetId/interface/MTDDetId.h"
0127 #include "DataFormats/Scouting/interface/Run3ScoutingHitPatternPOD.h"
0128 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
0129 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
0130 #include "FWCore/Utilities/interface/Likely.h"
0131 
0132 #include <utility>
0133 #include <algorithm>
0134 #include <iostream>
0135 #include <ostream>
0136 #include <memory>
0137 
0138 class TrackerTopology;
0139 
0140 namespace test {
0141   namespace TestHitPattern {
0142     int test();
0143   }
0144 }  // namespace test
0145 
0146 namespace reco {
0147 
0148   class HitPattern {
0149   public:
0150     enum { MONO = 1, STEREO = 2 };
0151 
0152     enum HIT_DETECTOR_TYPE { MUON_HIT = 0, TRACKER_HIT = 1, MTD_HIT = 2 };
0153 
0154     enum HIT_TYPE { VALID = 0, MISSING = 1, INACTIVE = 2, BAD = 3 };
0155 
0156     enum HitCategory { TRACK_HITS = 0, MISSING_INNER_HITS = 1, MISSING_OUTER_HITS = 2 };
0157     const static unsigned short ARRAY_LENGTH = 57;
0158     const static unsigned short HIT_LENGTH = 12;
0159     const static unsigned short MaxHits = (8 * sizeof(uint16_t) * ARRAY_LENGTH) / HIT_LENGTH;
0160 
0161     static const uint32_t NULL_RETURN = 999999;
0162     static const uint16_t EMPTY_PATTERN = 0x0;
0163 
0164     static bool trackerHitFilter(uint16_t pattern);
0165     static bool muonHitFilter(uint16_t pattern);
0166     static bool timingHitFilter(uint16_t pattern);
0167 
0168     static bool validHitFilter(uint16_t pattern);
0169     static bool missingHitFilter(uint16_t pattern);
0170     static bool inactiveHitFilter(uint16_t pattern);
0171     static bool badHitFilter(uint16_t pattern);
0172 
0173     static bool pixelHitFilter(uint16_t pattern);
0174     static bool pixelBarrelHitFilter(uint16_t pattern);
0175     static bool pixelEndcapHitFilter(uint16_t pattern);
0176     static bool stripHitFilter(uint16_t pattern);
0177     static bool stripTIBHitFilter(uint16_t pattern);
0178     static bool stripTIDHitFilter(uint16_t pattern);
0179     static bool stripTOBHitFilter(uint16_t pattern);
0180     static bool stripTECHitFilter(uint16_t pattern);
0181 
0182     static bool muonDTHitFilter(uint16_t pattern);
0183     static bool muonCSCHitFilter(uint16_t pattern);
0184     static bool muonRPCHitFilter(uint16_t pattern);
0185     static bool muonGEMHitFilter(uint16_t pattern);
0186     static bool muonME0HitFilter(uint16_t pattern);
0187 
0188     static bool timingBTLHitFilter(uint16_t pattern);
0189     static bool timingETLHitFilter(uint16_t pattern);
0190 
0191     static uint32_t getHitType(uint16_t pattern);
0192 
0193     // mono (0) or stereo (1)
0194     static uint32_t getSide(uint16_t pattern);
0195     static uint32_t getLayer(uint16_t pattern);
0196     static uint32_t getSubSubStructure(uint16_t pattern);
0197     static uint32_t getSubStructure(uint16_t pattern);
0198     static uint32_t getSubDetector(uint16_t pattern);
0199 
0200     /// Muon station (1-4). Only valid for muon patterns, of course. only for patterns from muon, of course
0201     static uint16_t getMuonStation(uint16_t pattern);
0202 
0203     /// DT superlayer (1-3). Where the "hit" was a DT segment, superlayer is 0. Only valid for muon DT patterns, of course.
0204     static uint16_t getDTSuperLayer(uint16_t pattern);  // only for DT patterns
0205 
0206     /// CSC ring (1-4). Only valid for muon CSC patterns, of course.
0207     static uint16_t getCSCRing(uint16_t pattern);
0208 
0209     /// 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.
0210     static uint16_t getRPCLayer(uint16_t pattern);
0211 
0212     /// RPC region: 0 = barrel, 1 = endcap. Only valid for muon RPC patterns, of course.
0213     static uint16_t getRPCregion(uint16_t pattern);
0214 
0215     /// GEM station: 1,2. Only valid for muon GEM patterns, of course.
0216     static uint16_t getGEMStation(uint16_t pattern);
0217 
0218     /// GEM layer: 1-6 for station 0, 1-2 for stations 1 and 2. Only valid for muon GEM patterns, of course.
0219     static uint16_t getGEMLayer(uint16_t pattern);
0220 
0221     /// BTL Module type: 1,2,3. Only valid for BTL patterns of course.
0222     static uint16_t getBTLModType(uint16_t pattern);
0223 
0224     /// ETL Ring: 1-12. Only valid for ETL patterns of course.
0225     static uint16_t getETLRing(uint16_t pattern);
0226 
0227     HitPattern();
0228 
0229     ~HitPattern();
0230 
0231     HitPattern(const HitPattern &other);
0232 
0233     HitPattern(const Run3ScoutingHitPatternPOD &other);
0234 
0235     HitPattern &operator=(const HitPattern &other);
0236 
0237     template <typename I>
0238     bool appendHits(const I &begin, const I &end, const TrackerTopology &ttopo);
0239     bool appendHit(const TrackingRecHit &hit, const TrackerTopology &ttopo);
0240     bool appendHit(const TrackingRecHitRef &ref, const TrackerTopology &ttopo);
0241     bool appendHit(const DetId &id, TrackingRecHit::Type hitType, const TrackerTopology &ttopo);
0242     bool appendHit(const uint16_t pattern, TrackingRecHit::Type hitType);
0243 
0244     /**
0245      * This is meant to be used only in cases where the an
0246      * already-packed hit information is re-interpreted in terms of
0247      * HitPattern (i.e. MiniAOD PackedCandidate, and the IO rule for
0248      * reading old versions of HitPattern)
0249      */
0250     bool appendTrackerHit(uint16_t subdet, uint16_t layer, uint16_t stereo, TrackingRecHit::Type hitType);
0251 
0252     /**
0253      * This is meant to be used only in cases where the an
0254      * already-packed hit information is re-interpreted in terms of
0255      * HitPattern (i.e. the IO rule for reading old versions of
0256      * HitPattern)
0257      */
0258     bool appendMuonHit(const DetId &id, TrackingRecHit::Type hitType);
0259 
0260     // get the pattern of the position-th hit
0261     uint16_t getHitPattern(HitCategory category, int position) const;
0262 
0263     void clear();
0264 
0265     // print the pattern of the position-th hit
0266     void printHitPattern(HitCategory category, int position, std::ostream &stream) const;
0267     void print(HitCategory category, std::ostream &stream = std::cout) const;
0268 
0269     // has valid hit in PXB/PXF layer x
0270     bool hasValidHitInPixelLayer(enum PixelSubdetector::SubDetector, uint16_t layer) const;
0271 
0272     int numberOfAllHits(HitCategory category) const;  // not-null
0273     int numberOfValidHits() const;                    // not-null, valid
0274 
0275     int numberOfAllTrackerHits(HitCategory category) const;  // not-null, tracker
0276     int numberOfValidTrackerHits() const;                    // not-null, valid, tracker
0277     int numberOfValidPixelHits() const;                      // not-null, valid, pixel
0278     int numberOfValidPixelBarrelHits() const;                // not-null, valid, pixel PXB
0279     int numberOfValidPixelEndcapHits() const;                // not-null, valid, pixel PXF
0280     int numberOfValidStripHits() const;                      // not-null, valid, strip
0281     int numberOfValidStripTIBHits() const;                   // not-null, valid, strip TIB
0282     int numberOfValidStripTIDHits() const;                   // not-null, valid, strip TID
0283     int numberOfValidStripTOBHits() const;                   // not-null, valid, strip TOB
0284     int numberOfValidStripTECHits() const;                   // not-null, valid, strip TEC
0285 
0286     int numberOfLostHits(HitCategory category) const;             // not-null, not valid
0287     int numberOfLostTrackerHits(HitCategory category) const;      // not-null, not valid, tracker
0288     int numberOfLostPixelHits(HitCategory category) const;        // not-null, not valid, pixel
0289     int numberOfLostPixelBarrelHits(HitCategory category) const;  // not-null, not valid, pixel PXB
0290     int numberOfLostPixelEndcapHits(HitCategory category) const;  // not-null, not valid, pixel PXF
0291     int numberOfLostStripHits(HitCategory category) const;        // not-null, not valid, strip
0292     int numberOfLostStripTIBHits(HitCategory category) const;     // not-null, not valid, strip TIB
0293     int numberOfLostStripTIDHits(HitCategory category) const;     // not-null, not valid, strip TID
0294     int numberOfLostStripTOBHits(HitCategory category) const;     // not-null, not valid, strip TOB
0295     int numberOfLostStripTECHits(HitCategory category) const;     // not-null, not valid, strip TEC
0296 
0297     int numberOfTimingHits() const;          // not-null timing
0298     int numberOfValidTimingHits() const;     // not-null, valid, timing
0299     int numberOfValidTimingBTLHits() const;  // not-null, valid, timing BTL
0300     int numberOfValidTimingETLHits() const;  // not-null, valid, timing ETL
0301 
0302     int numberOfLostTimingHits() const;     // not-null, not valid, timing
0303     int numberOfLostTimingBTLHits() const;  // not-null, not valid, timing BTL
0304     int numberOfLostTimingETLHits() const;  // not-null, not valid, timing ETL
0305 
0306     int numberOfMuonHits() const;          // not-null, muon
0307     int numberOfValidMuonHits() const;     // not-null, valid, muon
0308     int numberOfValidMuonDTHits() const;   // not-null, valid, muon DT
0309     int numberOfValidMuonCSCHits() const;  // not-null, valid, muon CSC
0310     int numberOfValidMuonRPCHits() const;  // not-null, valid, muon RPC
0311     int numberOfValidMuonGEMHits() const;  // not-null, valid, muon GEM
0312     int numberOfValidMuonME0Hits() const;  // not-null, valid, muon ME0
0313 
0314     int numberOfLostMuonHits() const;     // not-null, not valid, muon
0315     int numberOfLostMuonDTHits() const;   // not-null, not valid, muon DT
0316     int numberOfLostMuonCSCHits() const;  // not-null, not valid, muon CSC
0317     int numberOfLostMuonRPCHits() const;  // not-null, not valid, muon RPC
0318     int numberOfLostMuonGEMHits() const;  // not-null, not valid, muon GEM
0319     int numberOfLostMuonME0Hits() const;  // not-null, not valid, muon ME0
0320 
0321     int numberOfBadHits() const;         // not-null, bad (only used in Muon Ch.)
0322     int numberOfBadMuonHits() const;     // not-null, bad, muon
0323     int numberOfBadMuonDTHits() const;   // not-null, bad, muon DT
0324     int numberOfBadMuonCSCHits() const;  // not-null, bad, muon CSC
0325     int numberOfBadMuonRPCHits() const;  // not-null, bad, muon RPC
0326     int numberOfBadMuonGEMHits() const;  // not-null, bad, muon GEM
0327     int numberOfBadMuonME0Hits() const;  // not-null, bad, muon ME0
0328 
0329     int numberOfInactiveHits() const;         // not-null, inactive
0330     int numberOfInactiveTrackerHits() const;  // not-null, inactive, tracker
0331     int numberOfInactiveTimingHits() const;   // not-null, inactive, timing
0332 
0333     // count strip layers that have non-null, valid mono and stereo hits
0334     int numberOfValidStripLayersWithMonoAndStereo(uint16_t stripdet, uint16_t layer) const;
0335     int numberOfValidStripLayersWithMonoAndStereo() const;
0336     int numberOfValidTOBLayersWithMonoAndStereo(uint32_t layer = 0) const;
0337     int numberOfValidTIBLayersWithMonoAndStereo(uint32_t layer = 0) const;
0338     int numberOfValidTIDLayersWithMonoAndStereo(uint32_t layer = 0) const;
0339     int numberOfValidTECLayersWithMonoAndStereo(uint32_t layer = 0) const;
0340 
0341     uint32_t getTrackerLayerCase(HitCategory category, uint16_t substr, uint16_t layer) const;
0342     uint16_t getTrackerMonoStereo(HitCategory category, uint16_t substr, uint16_t layer) const;
0343 
0344     int trackerLayersWithMeasurementOld() const;   // case 0: tracker
0345     int trackerLayersWithMeasurement() const;      // case 0: tracker
0346     int pixelLayersWithMeasurementOld() const;     // case 0: pixel
0347     int pixelLayersWithMeasurement() const;        // case 0: pixel
0348     int stripLayersWithMeasurement() const;        // case 0: strip
0349     int pixelBarrelLayersWithMeasurement() const;  // case 0: pixel PXB
0350     int pixelEndcapLayersWithMeasurement() const;  // case 0: pixel PXF
0351     int stripTIBLayersWithMeasurement() const;     // case 0: strip TIB
0352     int stripTIDLayersWithMeasurement() const;     // case 0: strip TID
0353     int stripTOBLayersWithMeasurement() const;     // case 0: strip TOB
0354     int stripTECLayersWithMeasurement() const;     // case 0: strip TEC
0355 
0356     int trackerLayersWithoutMeasurement(HitCategory category) const;      // case 1: tracker
0357     int trackerLayersWithoutMeasurementOld(HitCategory category) const;   // case 1: tracker
0358     int pixelLayersWithoutMeasurement(HitCategory category) const;        // case 1: pixel
0359     int stripLayersWithoutMeasurement(HitCategory category) const;        // case 1: strip
0360     int pixelBarrelLayersWithoutMeasurement(HitCategory category) const;  // case 1: pixel PXB
0361     int pixelEndcapLayersWithoutMeasurement(HitCategory category) const;  // case 1: pixel PXF
0362     int stripTIBLayersWithoutMeasurement(HitCategory category) const;     // case 1: strip TIB
0363     int stripTIDLayersWithoutMeasurement(HitCategory category) const;     // case 1: strip TID
0364     int stripTOBLayersWithoutMeasurement(HitCategory category) const;     // case 1: strip TOB
0365     int stripTECLayersWithoutMeasurement(HitCategory category) const;     // case 1: strip TEC
0366 
0367     int trackerLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;      // case 2: tracker
0368     int pixelLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;        // case 2: pixel
0369     int stripLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;        // case 2: strip
0370     int pixelBarrelLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;  // case 2: pixel PXB
0371     int pixelEndcapLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;  // case 2: pixel PXF
0372     int stripTIBLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;     // case 2: strip TIB
0373     int stripTIDLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;     // case 2: strip TID
0374     int stripTOBLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;     // case 2: strip TOB
0375     int stripTECLayersTotallyOffOrBad(HitCategory category = TRACK_HITS) const;     // case 2: strip TEC
0376 
0377     int trackerLayersNull() const;      // case NULL_RETURN: tracker
0378     int pixelLayersNull() const;        // case NULL_RETURN: pixel
0379     int stripLayersNull() const;        // case NULL_RETURN: strip
0380     int pixelBarrelLayersNull() const;  // case NULL_RETURN: pixel PXB
0381     int pixelEndcapLayersNull() const;  // case NULL_RETURN: pixel PXF
0382     int stripTIBLayersNull() const;     // case NULL_RETURN: strip TIB
0383     int stripTIDLayersNull() const;     // case NULL_RETURN: strip TID
0384     int stripTOBLayersNull() const;     // case NULL_RETURN: strip TOB
0385     int stripTECLayersNull() const;     // case NULL_RETURN: strip TEC
0386 
0387     /// subdet = 0(all), 1(DT), 2(CSC), 3(RPC) 4(GEM); hitType=-1(all), 0=valid, 3=bad
0388     int muonStations(int subdet, int hitType) const;
0389 
0390     int muonStationsWithValidHits() const;
0391     int muonStationsWithBadHits() const;
0392     int muonStationsWithAnyHits() const;
0393 
0394     int dtStationsWithValidHits() const;
0395     int dtStationsWithBadHits() const;
0396     int dtStationsWithAnyHits() const;
0397 
0398     int cscStationsWithValidHits() const;
0399     int cscStationsWithBadHits() const;
0400     int cscStationsWithAnyHits() const;
0401 
0402     int rpcStationsWithValidHits() const;
0403     int rpcStationsWithBadHits() const;
0404     int rpcStationsWithAnyHits() const;
0405 
0406     int gemStationsWithValidHits() const;
0407     int gemStationsWithBadHits() const;
0408     int gemStationsWithAnyHits() const;
0409 
0410     int me0StationsWithValidHits() const;
0411     int me0StationsWithBadHits() const;
0412     int me0StationsWithAnyHits() const;
0413 
0414     /// hitType=-1(all), 0=valid, 3=bad; 0 = no stations at all
0415     int innermostMuonStationWithHits(int hitType) const;
0416     int innermostMuonStationWithValidHits() const;
0417     int innermostMuonStationWithBadHits() const;
0418     int innermostMuonStationWithAnyHits() const;
0419 
0420     /// hitType=-1(all), 0=valid, 3=bad; 0 = no stations at all
0421     int outermostMuonStationWithHits(int hitType) const;
0422     int outermostMuonStationWithValidHits() const;
0423     int outermostMuonStationWithBadHits() const;
0424     int outermostMuonStationWithAnyHits() const;
0425 
0426     int numberOfDTStationsWithRPhiView() const;
0427     int numberOfDTStationsWithRZView() const;
0428     int numberOfDTStationsWithBothViews() const;
0429 
0430     // fill Run3ScoutingHitPatternPOD struct
0431     Run3ScoutingHitPatternPOD run3ScoutingHitPatternPOD() const;
0432 
0433     //only used by ROOT IO rule to read v12 HitPatterns
0434     static bool fillNewHitPatternWithOldHitPattern_v12(const uint16_t oldHitPattern[],
0435                                                        uint8_t hitCount,
0436                                                        uint8_t beginTrackHits,
0437                                                        uint8_t endTrackHits,
0438                                                        uint8_t beginInner,
0439                                                        uint8_t endInner,
0440                                                        uint8_t beginOuter,
0441                                                        uint8_t endOuter,
0442                                                        reco::HitPattern *newObj);
0443 
0444   private:
0445     // 3 bits for hit type
0446     const static unsigned short HitTypeOffset = 0;
0447     const static unsigned short HitTypeMask = 0x3;
0448 
0449     // 1 bit to identify the side in double-sided detectors
0450     const static unsigned short SideOffset = 2;
0451     const static unsigned short SideMask = 0x1;
0452 
0453     // 4 bits to identify the layer/disk/wheel within the substructure
0454     const static unsigned short LayerOffset = 3;
0455     const static unsigned short LayerMask = 0xF;
0456 
0457     // 3 bits to identify the tracker/muon detector substructure
0458     const static unsigned short SubstrOffset = 7;
0459     const static unsigned short SubstrMask = 0x7;
0460 
0461     // 2 bits to distinguish tracker, muon, mtd subsystems
0462     const static unsigned short SubDetectorOffset = 10;
0463     const static unsigned short SubDetectorMask = 0x3;
0464 
0465     const static unsigned short minTrackerWord = 1 << SubDetectorOffset;
0466     const static unsigned short maxTrackerWord = (2 << SubDetectorOffset) - 1;
0467     const static unsigned short minPixelWord = minTrackerWord | (1 << SubstrOffset);
0468     const static unsigned short minStripWord = minTrackerWord | (3 << SubstrOffset);
0469 
0470     // detector side for tracker modules (mono/stereo)
0471     static uint16_t isStereo(DetId i, const TrackerTopology &ttopo);
0472     static bool stripSubdetectorHitFilter(uint16_t pattern, StripSubdetector::SubDetector substructure);
0473 
0474     static uint16_t encode(const TrackingRecHit &hit, const TrackerTopology &ttopo);
0475     static uint16_t encode(const DetId &id, TrackingRecHit::Type hitType, const TrackerTopology &ttopo);
0476     static uint16_t encode(uint16_t det, uint16_t subdet, uint16_t layer, uint16_t side, TrackingRecHit::Type hitType);
0477 
0478     // generic count methods
0479     typedef bool filterType(uint16_t);
0480 
0481     template <typename F>
0482     void call(HitCategory category, filterType typeFilter, F f) const;
0483 
0484     int countHits(HitCategory category, filterType filter) const;
0485     int countTypedHits(HitCategory category, filterType typeFilter, filterType filter) const;
0486 
0487     bool insertTrackHit(const uint16_t pattern);
0488     bool insertExpectedInnerHit(const uint16_t pattern);
0489     bool insertExpectedOuterHit(const uint16_t pattern);
0490     void insertHit(const uint16_t pattern);
0491 
0492     uint16_t getHitPatternByAbsoluteIndex(int position) const;
0493 
0494     std::pair<uint8_t, uint8_t> getCategoryIndexRange(HitCategory category) const;
0495 
0496     uint16_t hitPattern[ARRAY_LENGTH];
0497     uint8_t hitCount;
0498 
0499     uint8_t beginTrackHits;
0500     uint8_t endTrackHits;
0501     uint8_t beginInner;
0502     uint8_t endInner;
0503     uint8_t beginOuter;
0504     uint8_t endOuter;
0505 
0506     friend int ::test::TestHitPattern::test();
0507 
0508     template <int N>
0509     friend struct PatternSet;
0510   };
0511 
0512   inline std::pair<uint8_t, uint8_t> HitPattern::getCategoryIndexRange(HitCategory category) const {
0513     switch (category) {
0514       case TRACK_HITS:
0515         return std::pair<uint8_t, uint8_t>(beginTrackHits, endTrackHits);
0516         break;
0517       case MISSING_INNER_HITS:
0518         return std::pair<uint8_t, uint8_t>(beginInner, endInner);
0519         break;
0520       case MISSING_OUTER_HITS:
0521         return std::pair<uint8_t, uint8_t>(beginOuter, endOuter);
0522         break;
0523     }
0524     return std::pair<uint8_t, uint8_t>(-1, -1);
0525   }
0526 
0527   template <typename I>
0528   bool HitPattern::appendHits(const I &begin, const I &end, const TrackerTopology &ttopo) {
0529     for (I hit = begin; hit != end; hit++) {
0530       if UNLIKELY ((!appendHit(*hit, ttopo))) {
0531         return false;
0532       }
0533     }
0534     return true;
0535   }
0536 
0537   inline uint16_t HitPattern::getHitPattern(HitCategory category, int position) const {
0538     std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category);
0539     if UNLIKELY ((position < 0 || (position + range.first) >= range.second)) {
0540       return HitPattern::EMPTY_PATTERN;
0541     }
0542 
0543     return getHitPatternByAbsoluteIndex(range.first + position);
0544   }
0545 
0546   inline int HitPattern::countHits(HitCategory category, filterType filter) const {
0547     int count = 0;
0548     std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category);
0549     for (int i = range.first; i < range.second; ++i) {
0550       if (filter(getHitPatternByAbsoluteIndex(i))) {
0551         ++count;
0552       }
0553     }
0554     return count;
0555   }
0556 
0557   template <typename F>
0558   void HitPattern::call(HitCategory category, filterType typeFilter, F f) const {
0559     std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category);
0560     for (int i = range.first; i < range.second; i++) {
0561       uint16_t pattern = getHitPatternByAbsoluteIndex(i);
0562       // f() return false to ask to stop looping
0563       if (typeFilter(pattern) && !f(pattern)) {
0564         break;
0565       }
0566     }
0567   }
0568 
0569   inline int HitPattern::countTypedHits(HitCategory category, filterType typeFilter, filterType filter) const {
0570     int count = 0;
0571     std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category);
0572     for (int i = range.first; i < range.second; ++i) {
0573       uint16_t pattern = getHitPatternByAbsoluteIndex(i);
0574       if (typeFilter(pattern) && filter(pattern)) {
0575         ++count;
0576       }
0577     }
0578     return count;
0579   }
0580 
0581   inline bool HitPattern::pixelHitFilter(uint16_t pattern) {
0582     if UNLIKELY (!trackerHitFilter(pattern)) {
0583       return false;
0584     }
0585 
0586     uint32_t substructure = getSubStructure(pattern);
0587     return (substructure == PixelSubdetector::PixelBarrel || substructure == PixelSubdetector::PixelEndcap);
0588   }
0589 
0590   inline bool HitPattern::pixelBarrelHitFilter(uint16_t pattern) {
0591     if UNLIKELY (!trackerHitFilter(pattern)) {
0592       return false;
0593     }
0594 
0595     uint32_t substructure = getSubStructure(pattern);
0596     return (substructure == PixelSubdetector::PixelBarrel);
0597   }
0598 
0599   inline bool HitPattern::pixelEndcapHitFilter(uint16_t pattern) {
0600     if UNLIKELY (!trackerHitFilter(pattern)) {
0601       return false;
0602     }
0603 
0604     uint32_t substructure = getSubStructure(pattern);
0605     return (substructure == PixelSubdetector::PixelEndcap);
0606   }
0607 
0608   inline bool HitPattern::stripHitFilter(uint16_t pattern) {
0609     return pattern > minStripWord && pattern <= maxTrackerWord;
0610   }
0611 
0612   inline bool HitPattern::stripSubdetectorHitFilter(uint16_t pattern, StripSubdetector::SubDetector substructure) {
0613     if UNLIKELY (!trackerHitFilter(pattern)) {
0614       return false;
0615     }
0616 
0617     return substructure == getSubStructure(pattern);
0618   }
0619 
0620   inline bool HitPattern::stripTIBHitFilter(uint16_t pattern) {
0621     return stripSubdetectorHitFilter(pattern, StripSubdetector::TIB);
0622   }
0623 
0624   inline bool HitPattern::stripTIDHitFilter(uint16_t pattern) {
0625     return stripSubdetectorHitFilter(pattern, StripSubdetector::TID);
0626   }
0627 
0628   inline bool HitPattern::stripTOBHitFilter(uint16_t pattern) {
0629     return stripSubdetectorHitFilter(pattern, StripSubdetector::TOB);
0630   }
0631 
0632   inline bool HitPattern::stripTECHitFilter(uint16_t pattern) {
0633     return stripSubdetectorHitFilter(pattern, StripSubdetector::TEC);
0634   }
0635 
0636   inline bool HitPattern::muonDTHitFilter(uint16_t pattern) {
0637     if UNLIKELY (!muonHitFilter(pattern)) {
0638       return false;
0639     }
0640 
0641     uint32_t substructure = getSubStructure(pattern);
0642     return (substructure == (uint32_t)MuonSubdetId::DT);
0643   }
0644 
0645   inline bool HitPattern::muonCSCHitFilter(uint16_t pattern) {
0646     if UNLIKELY (!muonHitFilter(pattern)) {
0647       return false;
0648     }
0649 
0650     uint32_t substructure = getSubStructure(pattern);
0651     return (substructure == (uint32_t)MuonSubdetId::CSC);
0652   }
0653 
0654   inline bool HitPattern::muonRPCHitFilter(uint16_t pattern) {
0655     if UNLIKELY (!muonHitFilter(pattern)) {
0656       return false;
0657     }
0658 
0659     uint32_t substructure = getSubStructure(pattern);
0660     return (substructure == (uint32_t)MuonSubdetId::RPC);
0661   }
0662 
0663   inline bool HitPattern::muonGEMHitFilter(uint16_t pattern) {
0664     if UNLIKELY (!muonHitFilter(pattern)) {
0665       return false;
0666     }
0667 
0668     uint32_t substructure = getSubStructure(pattern);
0669     return (substructure == (uint32_t)MuonSubdetId::GEM);
0670   }
0671 
0672   inline bool HitPattern::muonME0HitFilter(uint16_t pattern) {
0673     if UNLIKELY (!muonHitFilter(pattern))
0674       return false;
0675     uint16_t substructure = getSubStructure(pattern);
0676     return (substructure == (uint16_t)MuonSubdetId::ME0);
0677   }
0678 
0679   inline bool HitPattern::trackerHitFilter(uint16_t pattern) {
0680     return pattern > minTrackerWord && pattern <= maxTrackerWord;
0681   }
0682 
0683   inline bool HitPattern::muonHitFilter(uint16_t pattern) {
0684     if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) {
0685       return false;
0686     }
0687 
0688     return (((pattern >> SubDetectorOffset) & SubDetectorMask) == 0);
0689   }
0690 
0691   inline bool HitPattern::timingBTLHitFilter(uint16_t pattern) {
0692     if UNLIKELY (!timingHitFilter(pattern))
0693       return false;
0694     uint16_t substructure = getSubStructure(pattern);
0695     return (substructure == (uint16_t)MTDDetId::BTL);
0696   }
0697 
0698   inline bool HitPattern::timingETLHitFilter(uint16_t pattern) {
0699     if UNLIKELY (!timingHitFilter(pattern))
0700       return false;
0701     uint16_t substructure = getSubStructure(pattern);
0702     return (substructure == (uint16_t)MTDDetId::ETL);
0703   }
0704 
0705   inline bool HitPattern::timingHitFilter(uint16_t pattern) {
0706     if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) {
0707       return false;
0708     }
0709 
0710     return (((pattern >> SubDetectorOffset) & SubDetectorMask) == 2);
0711   }
0712 
0713   inline uint32_t HitPattern::getSubStructure(uint16_t pattern) {
0714     if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) {
0715       return NULL_RETURN;
0716     }
0717 
0718     return ((pattern >> SubstrOffset) & SubstrMask);
0719   }
0720 
0721   inline uint32_t HitPattern::getLayer(uint16_t pattern) { return HitPattern::getSubSubStructure(pattern); }
0722 
0723   inline uint32_t HitPattern::getSubSubStructure(uint16_t pattern) {
0724     if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) {
0725       return NULL_RETURN;
0726     }
0727 
0728     return ((pattern >> LayerOffset) & LayerMask);
0729   }
0730 
0731   inline uint32_t HitPattern::getSubDetector(uint16_t pattern) {
0732     if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) {
0733       return NULL_RETURN;
0734     }
0735 
0736     return ((pattern >> SubDetectorOffset) & SubDetectorMask);
0737   }
0738 
0739   inline uint32_t HitPattern::getSide(uint16_t pattern) {
0740     if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) {
0741       return NULL_RETURN;
0742     }
0743 
0744     return (pattern >> SideOffset) & SideMask;
0745   }
0746 
0747   inline uint32_t HitPattern::getHitType(uint16_t pattern) {
0748     if UNLIKELY (pattern == HitPattern::EMPTY_PATTERN) {
0749       return NULL_RETURN;
0750     }
0751 
0752     return ((pattern >> HitTypeOffset) & HitTypeMask);
0753   }
0754 
0755   inline uint16_t HitPattern::getMuonStation(uint16_t pattern) {
0756     return muonGEMHitFilter(pattern) ? getGEMStation(pattern) : (getSubSubStructure(pattern) >> 2) + 1;
0757   }
0758 
0759   inline uint16_t HitPattern::getDTSuperLayer(uint16_t pattern) { return (getSubSubStructure(pattern) & 3); }
0760 
0761   inline uint16_t HitPattern::getCSCRing(uint16_t pattern) { return (getSubSubStructure(pattern) & 3) + 1; }
0762 
0763   inline uint16_t HitPattern::getRPCLayer(uint16_t pattern) {
0764     uint16_t subSubStructure = getSubSubStructure(pattern);
0765     uint16_t stat = subSubStructure >> 2;
0766 
0767     if LIKELY (stat <= 1) {
0768       return ((subSubStructure >> 1) & 1) + 1;
0769     }
0770 
0771     return 0;
0772   }
0773 
0774   inline uint16_t HitPattern::getRPCregion(uint16_t pattern) { return getSubSubStructure(pattern) & 1; }
0775 
0776   ////////////////////////////// GEM
0777   inline uint16_t HitPattern::getGEMStation(uint16_t pattern) {
0778     uint16_t sss = getSubSubStructure(pattern);
0779     if (sss & 0b1000)
0780       return 0;
0781     return (sss >> 2) + 1;
0782   }
0783 
0784   /// MTD
0785   inline uint16_t HitPattern::getBTLModType(uint16_t pattern) { return getSubSubStructure(pattern); }
0786 
0787   inline uint16_t HitPattern::getETLRing(uint16_t pattern) { return getSubSubStructure(pattern); }
0788 
0789   inline uint16_t HitPattern::getGEMLayer(uint16_t pattern) {
0790     uint16_t sss = getSubSubStructure(pattern);
0791     if (sss & 0b1000)
0792       return (sss & 0b0111) + 1;
0793     return (sss & 0b11) + 1;
0794   }
0795 
0796   inline bool HitPattern::validHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::VALID; }
0797 
0798   inline bool HitPattern::missingHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::MISSING; }
0799 
0800   inline bool HitPattern::inactiveHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::INACTIVE; }
0801 
0802   inline bool HitPattern::badHitFilter(uint16_t pattern) { return getHitType(pattern) == HitPattern::BAD; }
0803 
0804   inline int HitPattern::numberOfAllHits(HitCategory category) const {
0805     std::pair<uint8_t, uint8_t> range = getCategoryIndexRange(category);
0806     return range.second - range.first;
0807   }
0808 
0809   inline int HitPattern::numberOfAllTrackerHits(HitCategory category) const {
0810     return countHits(category, trackerHitFilter);
0811   }
0812 
0813   inline int HitPattern::numberOfMuonHits() const { return countHits(TRACK_HITS, muonHitFilter); }
0814 
0815   inline int HitPattern::numberOfTimingHits() const { return countHits(TRACK_HITS, timingHitFilter); }
0816 
0817   inline int HitPattern::numberOfValidHits() const { return countHits(TRACK_HITS, validHitFilter); }
0818 
0819   inline int HitPattern::numberOfValidTrackerHits() const {
0820     return countTypedHits(TRACK_HITS, validHitFilter, trackerHitFilter);
0821   }
0822 
0823   inline int HitPattern::numberOfValidMuonHits() const {
0824     return countTypedHits(TRACK_HITS, validHitFilter, muonHitFilter);
0825   }
0826 
0827   inline int HitPattern::numberOfValidTimingHits() const {
0828     return countTypedHits(TRACK_HITS, validHitFilter, timingHitFilter);
0829   }
0830 
0831   inline int HitPattern::numberOfValidPixelHits() const {
0832     return countTypedHits(TRACK_HITS, validHitFilter, pixelHitFilter);
0833   }
0834 
0835   inline int HitPattern::numberOfValidPixelBarrelHits() const {
0836     return countTypedHits(TRACK_HITS, validHitFilter, pixelBarrelHitFilter);
0837   }
0838 
0839   inline int HitPattern::numberOfValidPixelEndcapHits() const {
0840     return countTypedHits(TRACK_HITS, validHitFilter, pixelEndcapHitFilter);
0841   }
0842 
0843   inline int HitPattern::numberOfValidStripHits() const {
0844     return countTypedHits(TRACK_HITS, validHitFilter, stripHitFilter);
0845   }
0846 
0847   inline int HitPattern::numberOfValidStripTIBHits() const {
0848     return countTypedHits(TRACK_HITS, validHitFilter, stripTIBHitFilter);
0849   }
0850 
0851   inline int HitPattern::numberOfValidStripTIDHits() const {
0852     return countTypedHits(TRACK_HITS, validHitFilter, stripTIDHitFilter);
0853   }
0854 
0855   inline int HitPattern::numberOfValidStripTOBHits() const {
0856     return countTypedHits(TRACK_HITS, validHitFilter, stripTOBHitFilter);
0857   }
0858 
0859   inline int HitPattern::numberOfValidStripTECHits() const {
0860     return countTypedHits(TRACK_HITS, validHitFilter, stripTECHitFilter);
0861   }
0862 
0863   inline int HitPattern::numberOfValidMuonDTHits() const {
0864     return countTypedHits(TRACK_HITS, validHitFilter, muonDTHitFilter);
0865   }
0866 
0867   inline int HitPattern::numberOfValidMuonCSCHits() const {
0868     return countTypedHits(TRACK_HITS, validHitFilter, muonCSCHitFilter);
0869   }
0870 
0871   inline int HitPattern::numberOfValidMuonRPCHits() const {
0872     return countTypedHits(TRACK_HITS, validHitFilter, muonRPCHitFilter);
0873   }
0874 
0875   inline int HitPattern::numberOfValidMuonGEMHits() const {
0876     return countTypedHits(TRACK_HITS, validHitFilter, muonGEMHitFilter);
0877   }
0878 
0879   inline int HitPattern::numberOfValidMuonME0Hits() const {
0880     return countTypedHits(TRACK_HITS, validHitFilter, muonME0HitFilter);
0881   }
0882 
0883   inline int HitPattern::numberOfValidTimingBTLHits() const {
0884     return countTypedHits(TRACK_HITS, validHitFilter, timingBTLHitFilter);
0885   }
0886 
0887   inline int HitPattern::numberOfValidTimingETLHits() const {
0888     return countTypedHits(TRACK_HITS, validHitFilter, timingETLHitFilter);
0889   }
0890 
0891   inline int HitPattern::numberOfLostHits(HitCategory category) const { return countHits(category, missingHitFilter); }
0892 
0893   inline int HitPattern::numberOfLostTrackerHits(HitCategory category) const {
0894     return countTypedHits(category, missingHitFilter, trackerHitFilter);
0895   }
0896 
0897   inline int HitPattern::numberOfLostMuonHits() const {
0898     return countTypedHits(TRACK_HITS, missingHitFilter, muonHitFilter);
0899   }
0900 
0901   inline int HitPattern::numberOfLostTimingHits() const {
0902     return countTypedHits(TRACK_HITS, missingHitFilter, timingHitFilter);
0903   }
0904 
0905   inline int HitPattern::numberOfLostTimingBTLHits() const {
0906     return countTypedHits(TRACK_HITS, missingHitFilter, timingBTLHitFilter);
0907   }
0908 
0909   inline int HitPattern::numberOfLostTimingETLHits() const {
0910     return countTypedHits(TRACK_HITS, missingHitFilter, timingETLHitFilter);
0911   }
0912 
0913   inline int HitPattern::numberOfLostPixelHits(HitCategory category) const {
0914     return countTypedHits(category, missingHitFilter, pixelHitFilter);
0915   }
0916 
0917   inline int HitPattern::numberOfLostPixelBarrelHits(HitCategory category) const {
0918     return countTypedHits(category, missingHitFilter, pixelBarrelHitFilter);
0919   }
0920 
0921   inline int HitPattern::numberOfLostPixelEndcapHits(HitCategory category) const {
0922     return countTypedHits(category, missingHitFilter, pixelEndcapHitFilter);
0923   }
0924 
0925   inline int HitPattern::numberOfLostStripHits(HitCategory category) const {
0926     return countTypedHits(category, missingHitFilter, stripHitFilter);
0927   }
0928 
0929   inline int HitPattern::numberOfLostStripTIBHits(HitCategory category) const {
0930     return countTypedHits(category, missingHitFilter, stripTIBHitFilter);
0931   }
0932 
0933   inline int HitPattern::numberOfLostStripTIDHits(HitCategory category) const {
0934     return countTypedHits(category, missingHitFilter, stripTIDHitFilter);
0935   }
0936 
0937   inline int HitPattern::numberOfLostStripTOBHits(HitCategory category) const {
0938     return countTypedHits(category, missingHitFilter, stripTOBHitFilter);
0939   }
0940 
0941   inline int HitPattern::numberOfLostStripTECHits(HitCategory category) const {
0942     return countTypedHits(category, missingHitFilter, stripTECHitFilter);
0943   }
0944 
0945   inline int HitPattern::numberOfLostMuonDTHits() const {
0946     return countTypedHits(TRACK_HITS, missingHitFilter, muonDTHitFilter);
0947   }
0948 
0949   inline int HitPattern::numberOfLostMuonCSCHits() const {
0950     return countTypedHits(TRACK_HITS, missingHitFilter, muonCSCHitFilter);
0951   }
0952 
0953   inline int HitPattern::numberOfLostMuonRPCHits() const {
0954     return countTypedHits(TRACK_HITS, missingHitFilter, muonRPCHitFilter);
0955   }
0956 
0957   inline int HitPattern::numberOfLostMuonGEMHits() const {
0958     return countTypedHits(TRACK_HITS, missingHitFilter, muonGEMHitFilter);
0959   }
0960 
0961   inline int HitPattern::numberOfLostMuonME0Hits() const {
0962     return countTypedHits(TRACK_HITS, missingHitFilter, muonME0HitFilter);
0963   }
0964 
0965   inline int HitPattern::numberOfBadHits() const { return countHits(TRACK_HITS, badHitFilter); }
0966 
0967   inline int HitPattern::numberOfBadMuonHits() const {
0968     return countTypedHits(TRACK_HITS, inactiveHitFilter, muonHitFilter);
0969   }
0970 
0971   inline int HitPattern::numberOfBadMuonDTHits() const {
0972     return countTypedHits(TRACK_HITS, inactiveHitFilter, muonDTHitFilter);
0973   }
0974 
0975   inline int HitPattern::numberOfBadMuonCSCHits() const {
0976     return countTypedHits(TRACK_HITS, inactiveHitFilter, muonCSCHitFilter);
0977   }
0978 
0979   inline int HitPattern::numberOfBadMuonRPCHits() const {
0980     return countTypedHits(TRACK_HITS, inactiveHitFilter, muonRPCHitFilter);
0981   }
0982 
0983   inline int HitPattern::numberOfBadMuonGEMHits() const {
0984     return countTypedHits(TRACK_HITS, inactiveHitFilter, muonGEMHitFilter);
0985   }
0986 
0987   inline int HitPattern::numberOfBadMuonME0Hits() const {
0988     return countTypedHits(TRACK_HITS, inactiveHitFilter, muonME0HitFilter);
0989   }
0990 
0991   inline int HitPattern::numberOfInactiveHits() const { return countHits(TRACK_HITS, inactiveHitFilter); }
0992 
0993   inline int HitPattern::numberOfInactiveTrackerHits() const {
0994     return countTypedHits(TRACK_HITS, inactiveHitFilter, trackerHitFilter);
0995   }
0996 
0997   inline int HitPattern::trackerLayersWithMeasurementOld() const {
0998     return pixelLayersWithMeasurement() + stripLayersWithMeasurement();
0999   }
1000 
1001   inline int HitPattern::pixelLayersWithMeasurementOld() const {
1002     return pixelBarrelLayersWithMeasurement() + pixelEndcapLayersWithMeasurement();
1003   }
1004 
1005   inline int HitPattern::stripLayersWithMeasurement() const {
1006     return stripTIBLayersWithMeasurement() + stripTIDLayersWithMeasurement() + stripTOBLayersWithMeasurement() +
1007            stripTECLayersWithMeasurement();
1008   }
1009 
1010   inline int HitPattern::trackerLayersWithoutMeasurementOld(HitCategory category) const {
1011     return pixelLayersWithoutMeasurement(category) + stripLayersWithoutMeasurement(category);
1012   }
1013 
1014   inline int HitPattern::pixelLayersWithoutMeasurement(HitCategory category) const {
1015     return pixelBarrelLayersWithoutMeasurement(category) + pixelEndcapLayersWithoutMeasurement(category);
1016   }
1017 
1018   inline int HitPattern::stripLayersWithoutMeasurement(HitCategory category) const {
1019     return stripTIBLayersWithoutMeasurement(category) + stripTIDLayersWithoutMeasurement(category) +
1020            stripTOBLayersWithoutMeasurement(category) + stripTECLayersWithoutMeasurement(category);
1021   }
1022 
1023   inline int HitPattern::trackerLayersTotallyOffOrBad(HitCategory category) const {
1024     return pixelLayersTotallyOffOrBad(category) + stripLayersTotallyOffOrBad(category);
1025   }
1026 
1027   inline int HitPattern::pixelLayersTotallyOffOrBad(HitCategory category) const {
1028     return pixelBarrelLayersTotallyOffOrBad(category) + pixelEndcapLayersTotallyOffOrBad(category);
1029   }
1030 
1031   inline int HitPattern::stripLayersTotallyOffOrBad(HitCategory category) const {
1032     return stripTIBLayersTotallyOffOrBad(category) + stripTIDLayersTotallyOffOrBad(category) +
1033            stripTOBLayersTotallyOffOrBad(category) + stripTECLayersTotallyOffOrBad(category);
1034   }
1035 
1036   inline int HitPattern::trackerLayersNull() const { return pixelLayersNull() + stripLayersNull(); }
1037 
1038   inline int HitPattern::pixelLayersNull() const { return pixelBarrelLayersNull() + pixelEndcapLayersNull(); }
1039 
1040   inline int HitPattern::stripLayersNull() const {
1041     return stripTIBLayersNull() + stripTIDLayersNull() + stripTOBLayersNull() + stripTECLayersNull();
1042   }
1043 
1044   inline int HitPattern::muonStationsWithValidHits() const { return muonStations(0, 0); }
1045 
1046   inline int HitPattern::muonStationsWithBadHits() const { return muonStations(0, 3); }
1047 
1048   inline int HitPattern::muonStationsWithAnyHits() const { return muonStations(0, -1); }
1049 
1050   inline int HitPattern::dtStationsWithValidHits() const { return muonStations(1, 0); }
1051 
1052   inline int HitPattern::dtStationsWithBadHits() const { return muonStations(1, 3); }
1053 
1054   inline int HitPattern::dtStationsWithAnyHits() const { return muonStations(1, -1); }
1055 
1056   inline int HitPattern::cscStationsWithValidHits() const { return muonStations(2, 0); }
1057 
1058   inline int HitPattern::cscStationsWithBadHits() const { return muonStations(2, 3); }
1059 
1060   inline int HitPattern::cscStationsWithAnyHits() const { return muonStations(2, -1); }
1061 
1062   inline int HitPattern::rpcStationsWithValidHits() const { return muonStations(3, 0); }
1063 
1064   inline int HitPattern::rpcStationsWithBadHits() const { return muonStations(3, 3); }
1065 
1066   inline int HitPattern::rpcStationsWithAnyHits() const { return muonStations(3, -1); }
1067 
1068   inline int HitPattern::gemStationsWithValidHits() const { return muonStations(4, 0); }
1069 
1070   inline int HitPattern::gemStationsWithBadHits() const { return muonStations(4, 3); }
1071 
1072   inline int HitPattern::gemStationsWithAnyHits() const { return muonStations(4, -1); }
1073 
1074   inline int HitPattern::me0StationsWithValidHits() const { return muonStations(5, 0); }
1075 
1076   inline int HitPattern::me0StationsWithBadHits() const { return muonStations(5, 3); }
1077 
1078   inline int HitPattern::me0StationsWithAnyHits() const { return muonStations(5, -1); }
1079 
1080   inline int HitPattern::innermostMuonStationWithValidHits() const { return innermostMuonStationWithHits(0); }
1081 
1082   inline int HitPattern::innermostMuonStationWithBadHits() const { return innermostMuonStationWithHits(3); }
1083 
1084   inline int HitPattern::innermostMuonStationWithAnyHits() const { return innermostMuonStationWithHits(-1); }
1085 
1086   inline int HitPattern::outermostMuonStationWithValidHits() const { return outermostMuonStationWithHits(0); }
1087 
1088   inline int HitPattern::outermostMuonStationWithBadHits() const { return outermostMuonStationWithHits(3); }
1089 
1090   inline int HitPattern::outermostMuonStationWithAnyHits() const { return outermostMuonStationWithHits(-1); }
1091 
1092   template <int N = HitPattern::MaxHits>
1093   struct PatternSet {
1094     static constexpr int MaxHits = N;
1095     unsigned char hit[N];
1096     unsigned char nhit;
1097 
1098     unsigned char const *begin() const { return hit; }
1099 
1100     unsigned char const *end() const { return hit + nhit; }
1101 
1102     unsigned char *begin() { return hit; }
1103 
1104     unsigned char *end() { return hit + nhit; }
1105 
1106     int size() const { return nhit; }
1107 
1108     unsigned char operator[](int i) const { return hit[i]; }
1109 
1110     PatternSet() : nhit(0) {}
1111 
1112     PatternSet(HitPattern::HitCategory category, HitPattern const &hp) { fill(category, hp); }
1113 
1114     void fill(HitPattern::HitCategory category, HitPattern const &hp) {
1115       int lhit = 0;
1116       auto unpack = [&lhit, this](uint16_t pattern) -> bool {
1117         unsigned char p = 255 & (pattern >> 3);
1118         hit[lhit++] = p;
1119 
1120         // bouble sort
1121         if (lhit > 1) {
1122           for (auto h = hit + lhit - 1; h != hit; --h) {
1123             if ((*(h - 1)) <= p) {
1124               break;
1125             }
1126             (*h) = *(h - 1);
1127             *(h - 1) = p;
1128           }
1129         }
1130         return lhit < MaxHits;
1131       };
1132 
1133       hp.call(category, HitPattern::validHitFilter, unpack);
1134       nhit = lhit;
1135     }
1136   };
1137 
1138   template <int N>
1139   inline PatternSet<N> commonHits(PatternSet<N> const &p1, PatternSet<N> const &p2) {
1140     PatternSet<N> comm;
1141     comm.nhit = std::set_intersection(p1.begin(), p1.end(), p2.begin(), p2.end(), comm.begin()) - comm.begin();
1142     return comm;
1143   }
1144 
1145 }  // namespace reco
1146 
1147 #endif