CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DataFormats/TrackReco/interface/HitPattern.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef TrackReco_HitPattern_h
00003 #define TrackReco_HitPattern_h
00004 
00005 //
00006 // File: DataFormats/TrackReco/interface/HitPattern.h
00007 //
00008 // Marcel Vos, INFN Pisa
00009 // v1.10 2007/05/08 bellan
00010 // Zongru Wan, Kansas State University
00011 // Jean-Roch Vlimant
00012 // Kevin Burkett
00013 // Boris Mangano
00014 //
00015 // Hit pattern is the summary information of the hits associated to track in
00016 // AOD.  When RecHits are no longer available, the compact hit pattern should
00017 // allow basic track selection based on the hits in various subdetectors.  The
00018 // hits of a track are saved in unit32_t hitPattern_[28], initialized as
00019 // 0x00000000, ..., 0x00000000.  Set one hit with 10 bits
00020 //
00021 //      +-----+-----+-----+-----+-----+-----+-----+-----+----------------+-----+-----+
00022 //      |tk/mu|  sub-structure  |   sub-sub-structure   |     stereo     |  hit type |
00023 //      +-----+-----+-----+-----+-----+-----+-----+-----+----------------+-----+-----+
00024 //  ... | 10  |   9    8     7  |   6    5     4     3  |        2       |  1     0  | bit
00025 //
00026 //      |tk = 1      PXB = 1            layer = 1-3                       hit type = 0-3
00027 //      |tk = 1      PXF = 2            disk  = 1-2                       hit type = 0-3
00028 //      |tk = 1      TIB = 3            layer = 1-4      0=rphi,1=stereo  hit type = 0-3
00029 //      |tk = 1      TID = 4            wheel = 1-3      0=rphi,1=stereo  hit type = 0-3
00030 //      |tk = 1      TOB = 5            layer = 1-6      0=rphi,1=stereo  hit type = 0-3
00031 //      |tk = 1      TEC = 6            wheel = 1-9      0=rphi,1=stereo  hit type = 0-3
00032 //      |mu = 0      DT  = 1            4*(stat-1)+superlayer             hit type = 0-3
00033 //      |mu = 0      CSC = 2            4*(stat-1)+(ring-1)               hit type = 0-3
00034 //      |mu = 0      RPC = 3            4*(stat-1)+2*layer+region         hit type = 0-3
00035 //
00036 //      hit type, see DataFormats/TrackingRecHit/interface/TrackingRecHit.h
00037 //      valid    = valid hit                                     = 0
00038 //      missing  = detector is good, but no rec hit found        = 1
00039 //      inactive = detector is off, so there was no hope         = 2
00040 //      bad      = there were many bad strips within the ellipse = 3
00041 //
00042 // The maximum number of hits = 32*28/11 = 81.  It had been shown by Zongru
00043 // using a 100 GeV muon sample with 5000 events uniform in eta and phi, the 
00044 // average (maximum) number of tracker hits is 13 (17) and the average 
00045 // (maximum) number of muon detector hits is about 26 (50).  If the number of 
00046 // hits of a track is larger than 80 then the extra hits are ignored by hit 
00047 // pattern.  The static hit pattern array might be improved to a dynamic one
00048 // in the future.
00049 //
00050 // Because of tracking with/without overlaps and with/without hit-splitting, 
00051 // the final number of hits per track is pretty "variable".  Compared with the
00052 // number of valid hits, the number of crossed layers with measurement should
00053 // be more robust to discriminate between good and fake track.
00054 //
00055 // Since 4-bit for sub-sub-structure is not enough to specify a muon layer,
00056 // the layer case counting methods are implemented for tracker only.  This is
00057 // different from the hit counting methods which are implemented for both 
00058 // tracker and muon detector.
00059 //
00060 // Given a tracker layer, specified by sub-structure and layer, the method
00061 // getTrackerLayerCase(substr, layer) groups all of the hits in the hit pattern
00062 // array for the layer together and returns one of the four cases
00063 //
00064 //      crossed
00065 //        layer case 0: valid + (missing, off, bad) ==> with measurement
00066 //        layer case 1: missing + (off, bad) ==> without measurement
00067 //        layer case 2: off, bad ==> totally off or bad, cannot say much
00068 //      not crossed
00069 //        layer case 999999: track outside acceptance or in gap ==> null
00070 //
00071 // Given a tracker layer, specified by sub-structure and layer, the method
00072 // getTrackerMonoStereo(substr, layer) groups all of the valid hits in the hit
00073 // pattern array for the layer together and returns 
00074 //
00075 //      0:              neither a valid mono nor a valid stereo hit
00076 //      MONO:           valid mono hit
00077 //      STEREO:         valid stereo hit
00078 //      MONO | STEREO:  both
00079 //
00080 // Given a track, here is an example usage of hit pattern
00081 //
00082 //      // hit pattern of the track
00083 //      const reco::HitPattern& p = track->hitPattern();
00084 //
00085 //      // loop over the hits of the track
00086 //      for (int i=0; i<p.numberOfHits(); i++) {
00087 //        uint32_t hit = p.getHitPattern(i);
00088 //
00089 //        // if the hit is valid and in pixel barrel, print out the layer
00090 //        if (p.validHitFilter(hit) && p.pixelBarrelHitFilter(hit))
00091 //          std::cout << "valid hit found in pixel barrel layer "
00092 //                    << p.getLayer(hit) << std::endl;
00093 //
00094 //        // expert level: printout the hit in 10-bit binary format
00095 //        std::cout << "hit in 10-bit binary format = "; 
00096 //        for (int j=9; j>=0; j--) {
00097 //          int bit = (hit >> j) & 0x1;
00098 //          std::cout << bit;
00099 //        }
00100 //        std::cout << std::endl;
00101 //      }
00102 //
00103 //      // count the number of valid pixel barrel *** hits ***
00104 //      std::cout << "number of of valid pixel barrel hits is "
00105 //                << p.numberOfValidPixelBarrelHits() << std::endl;
00106 //
00107 //      // count the number of pixel barrel *** layers *** with measurement
00108 //      std::cout << "number of of pixel barrel layers with measurement is "
00109 //                << p.pixelBarrelLayersWithMeasurement() << std::endl;
00110 //
00111 #include "DataFormats/DetId/interface/DetId.h"
00112 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00113 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00114 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00115 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
00116 #include "FWCore/Utilities/interface/GCC11Compatibility.h"
00117 #include <algorithm>
00118 #include <ostream>
00119 
00120 
00121 namespace reco {
00122   class HitPattern {
00123   public:
00124     enum { MONO = 1, STEREO = 2 };
00125 
00126    // number of 32 bit integers to store the full pattern
00127     const static unsigned short PatternSize = 25;
00128 
00129     // number of bits used for each hit
00130     const static unsigned short HitSize = 11;    
00131  
00132     static const int MaxHits = (PatternSize * 32) / HitSize;
00133 
00134     // default constructor
00135     // init hit pattern array as 0x00000000, ..., 0x00000000
00136     HitPattern() { for (int i=0; i<PatternSize; i++) hitPattern_[i] = 0; }
00137 
00138     // constructor from iterator (begin, end) pair
00139     template<typename I>
00140     HitPattern(const I & begin, const I & end) { set(begin, end); }
00141 
00142     // constructor from hit collection
00143     template<typename C>
00144     HitPattern(const C & c) { set(c); }
00145 
00146     // set pattern from iterator (begin, end) pair
00147     // init hit pattern array as 0x00000000, ..., 0x00000000
00148     // loop over the hits and set hit pattern
00149     template<typename I>
00150     void set(const I & begin, const I & end) {
00151       for (int i=0; i<PatternSize; i++) hitPattern_[i] = 0;
00152       unsigned int counter = 0;
00153       for (I hit=begin; hit!=end && counter<32*PatternSize/HitSize;
00154            hit++, counter++)
00155         set(*hit, counter);
00156     }
00157 
00158 
00159     // generic count methods
00160     typedef bool filterType(unsigned int);
00161     int countHits(filterType filter) const {
00162       int count = 0;
00163       for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00164         uint32_t pattern = getHitPattern(i);
00165         if (pattern == 0) break;
00166         if (filter(pattern)) ++count;
00167       }
00168       return count;
00169     }
00170 
00171     int countTypedHits(filterType typeFilter, filterType filter) const {
00172       int count = 0;
00173       for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00174         uint32_t pattern = getHitPattern(i);
00175         if (pattern == 0) break;
00176         if (typeFilter(pattern)&&filter(pattern)) ++count;
00177       }
00178       return count;
00179     }
00180 
00181     template<typename F>
00182     void call(filterType typeFilter, F f) const {
00183      for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00184         uint32_t pattern = getHitPattern(i);
00185         if (pattern == 0) break;
00186         // f() return false to ask to stop looping 
00187         if (typeFilter(pattern) && !f(pattern) ) break;
00188      }
00189     }
00190 
00191     // print the pattern of the position-th hit
00192     void printHitPattern (int position, std::ostream &stream) const;
00193     void print (std::ostream &stream = std::cout) const;
00194 
00195     // set the pattern of the i-th hit
00196     void set(const TrackingRecHit &hit, unsigned int i){setHitPattern(i, encode(hit,i));}
00197     
00198     // append a hit to the hit pattern
00199     void appendHit(const TrackingRecHit & hit);
00200 
00201     // get the pattern of the position-th hit
00202     uint32_t getHitPattern(int position) const; 
00203 
00204     static bool trackerHitFilter(uint32_t pattern); // tracker hit
00205     static bool muonHitFilter(uint32_t pattern);    // muon hit
00206 
00207     static uint32_t getSubStructure(uint32_t pattern);  // sub-structure
00208     static bool pixelHitFilter(uint32_t pattern);       // pixel
00209     static bool pixelBarrelHitFilter(uint32_t pattern); // pixel barrel
00210     static bool pixelEndcapHitFilter(uint32_t pattern); // pixel endcap
00211     static bool stripHitFilter(uint32_t pattern);       // strip 
00212     static bool stripTIBHitFilter(uint32_t pattern);    // strip TIB
00213     static bool stripTIDHitFilter(uint32_t pattern);    // strip TID
00214     static bool stripTOBHitFilter(uint32_t pattern);    // strip TOB
00215     static bool stripTECHitFilter(uint32_t pattern);    // strip TEC
00216     static bool muonDTHitFilter(uint32_t pattern);      // muon DT
00217     static bool muonCSCHitFilter(uint32_t pattern);     // muon CSC
00218     static bool muonRPCHitFilter(uint32_t pattern);     // muon RPC
00219 
00220     static uint32_t getLayer(uint32_t pattern); // sub-sub-structure
00221     static uint32_t getSubSubStructure(uint32_t pattern); // sub-sub-structure
00222 
00224     static uint32_t getMuonStation(uint32_t pattern);  // only for patterns from muon, of course
00226     static uint32_t getDTSuperLayer(uint32_t pattern); // only for DT patterns
00228     static uint32_t getCSCRing(uint32_t pattern) ; 
00230     static uint32_t getRPCLayer(uint32_t pattern) ; 
00232     static uint32_t getRPCregion(uint32_t pattern);
00233 
00234     static uint32_t getHitType(uint32_t pattern);   // hit type
00235     static bool validHitFilter(uint32_t pattern);   // hit type 0 = valid
00236     static bool type_1_HitFilter(uint32_t pattern); // hit type 1
00237     static bool type_2_HitFilter(uint32_t pattern); // hit type 2
00238     static bool type_3_HitFilter(uint32_t pattern); // hit type 3
00239 
00240     static uint32_t getSide (uint32_t pattern);         // mono (0) or stereo (1)
00241 
00242     bool hasValidHitInFirstPixelBarrel() const; // has valid hit in PXB layer 1
00243     bool hasValidHitInFirstPixelEndcap() const; // has valid hit in PXF layer 1
00244 
00245     int numberOfHits() const;                 // not-null
00246     int numberOfValidHits() const;            // not-null, valid
00247     int numberOfValidTrackerHits() const;     // not-null, valid, tracker
00248     int numberOfValidMuonHits() const;        // not-null, valid, muon
00249     int numberOfValidPixelHits() const;       // not-null, valid, pixel
00250     int numberOfValidPixelBarrelHits() const; // not-null, valid, pixel PXB
00251     int numberOfValidPixelEndcapHits() const; // not-null, valid, pixel PXF
00252     int numberOfValidStripHits() const;       // not-null, valid, strip
00253     int numberOfValidStripTIBHits() const;    // not-null, valid, strip TIB
00254     int numberOfValidStripTIDHits() const;    // not-null, valid, strip TID
00255     int numberOfValidStripTOBHits() const;    // not-null, valid, strip TOB
00256     int numberOfValidStripTECHits() const;    // not-null, valid, strip TEC
00257     int numberOfValidMuonDTHits() const;      // not-null, valid, muon DT
00258     int numberOfValidMuonCSCHits() const;     // not-null, valid, muon CSC
00259     int numberOfValidMuonRPCHits() const;     // not-null, valid, muon RPC
00260     int numberOfLostHits() const;             // not-null, not valid
00261     int numberOfLostTrackerHits() const;      // not-null, not valid, tracker
00262     int numberOfLostMuonHits() const;         // not-null, not valid, muon
00263     int numberOfLostPixelHits() const;        // not-null, not valid, pixel
00264     int numberOfLostPixelBarrelHits() const;  // not-null, not valid, pixel PXB
00265     int numberOfLostPixelEndcapHits() const;  // not-null, not valid, pixel PXF
00266     int numberOfLostStripHits() const;        // not-null, not valid, strip
00267     int numberOfLostStripTIBHits() const;     // not-null, not valid, strip TIB
00268     int numberOfLostStripTIDHits() const;     // not-null, not valid, strip TID
00269     int numberOfLostStripTOBHits() const;     // not-null, not valid, strip TOB
00270     int numberOfLostStripTECHits() const;     // not-null, not valid, strip TEC
00271     int numberOfLostMuonDTHits() const;       // not-null, not valid, muon DT
00272     int numberOfLostMuonCSCHits() const;      // not-null, not valid, muon CSC
00273     int numberOfLostMuonRPCHits() const;      // not-null, not valid, muon RPC
00274     int numberOfBadHits() const;              // not-null, bad (only used in Muon Ch.)
00275     int numberOfBadMuonHits() const;          // not-null, bad, muon
00276     int numberOfBadMuonDTHits() const;        // not-null, bad, muon DT
00277     int numberOfBadMuonCSCHits() const;       // not-null, bad, muon CSC
00278     int numberOfBadMuonRPCHits() const;       // not-null, bad, muon RPC
00279     int numberOfInactiveHits() const;         // not-null, inactive
00280     int numberOfInactiveTrackerHits() const;  // not-null, inactive, tracker
00281 
00282 
00283     int numberOfValidStripLayersWithMonoAndStereo () 
00284       const; // count strip layers that have non-null, valid mono and stereo hits
00285 
00286     uint32_t getTrackerLayerCase(uint32_t substr, uint32_t layer) const;
00287     uint32_t getTrackerMonoStereo (uint32_t substr, uint32_t layer) const;
00288 
00289     int trackerLayersWithMeasurement() const;        // case 0: tracker
00290     int pixelLayersWithMeasurement() const;          // case 0: pixel
00291     int stripLayersWithMeasurement() const;          // case 0: strip
00292     int pixelBarrelLayersWithMeasurement() const;    // case 0: pixel PXB
00293     int pixelEndcapLayersWithMeasurement() const;    // case 0: pixel PXF
00294     int stripTIBLayersWithMeasurement() const;       // case 0: strip TIB
00295     int stripTIDLayersWithMeasurement() const;       // case 0: strip TID
00296     int stripTOBLayersWithMeasurement() const;       // case 0: strip TOB
00297     int stripTECLayersWithMeasurement() const;       // case 0: strip TEC
00298     int trackerLayersWithoutMeasurement() const;     // case 1: tracker
00299     int pixelLayersWithoutMeasurement() const;       // case 1: pixel
00300     int stripLayersWithoutMeasurement() const;       // case 1: strip
00301     int pixelBarrelLayersWithoutMeasurement() const; // case 1: pixel PXB
00302     int pixelEndcapLayersWithoutMeasurement() const; // case 1: pixel PXF
00303     int stripTIBLayersWithoutMeasurement() const;    // case 1: strip TIB
00304     int stripTIDLayersWithoutMeasurement() const;    // case 1: strip TID
00305     int stripTOBLayersWithoutMeasurement() const;    // case 1: strip TOB
00306     int stripTECLayersWithoutMeasurement() const;    // case 1: strip TEC
00307     int trackerLayersTotallyOffOrBad() const;        // case 2: tracker
00308     int pixelLayersTotallyOffOrBad() const;          // case 2: pixel
00309     int stripLayersTotallyOffOrBad() const;          // case 2: strip
00310     int pixelBarrelLayersTotallyOffOrBad() const;    // case 2: pixel PXB
00311     int pixelEndcapLayersTotallyOffOrBad() const;    // case 2: pixel PXF
00312     int stripTIBLayersTotallyOffOrBad() const;       // case 2: strip TIB
00313     int stripTIDLayersTotallyOffOrBad() const;       // case 2: strip TID
00314     int stripTOBLayersTotallyOffOrBad() const;       // case 2: strip TOB
00315     int stripTECLayersTotallyOffOrBad() const;       // case 2: strip TEC
00316     int trackerLayersNull() const;                   // case 999999: tracker
00317     int pixelLayersNull() const;                     // case 999999: pixel
00318     int stripLayersNull() const;                     // case 999999: strip
00319     int pixelBarrelLayersNull() const;               // case 999999: pixel PXB
00320     int pixelEndcapLayersNull() const;               // case 999999: pixel PXF
00321     int stripTIBLayersNull() const;                  // case 999999: strip TIB
00322     int stripTIDLayersNull() const;                  // case 999999: strip TID
00323     int stripTOBLayersNull() const;                  // case 999999: strip TOB
00324     int stripTECLayersNull() const;                  // case 999999: strip TEC
00325 
00326 
00327 
00329     int muonStations(int subdet, int hitType) const ;
00330 
00331     int muonStationsWithValidHits() const ;
00332     int muonStationsWithBadHits() const ;
00333     int muonStationsWithAnyHits() const ;
00334     int dtStationsWithValidHits() const ;
00335     int dtStationsWithBadHits() const ;
00336     int dtStationsWithAnyHits() const ;
00337     int cscStationsWithValidHits() const ;
00338     int cscStationsWithBadHits() const ;
00339     int cscStationsWithAnyHits() const ;
00340     int rpcStationsWithValidHits() const ;
00341     int rpcStationsWithBadHits() const ;
00342     int rpcStationsWithAnyHits() const ;
00343 
00345     int innermostMuonStationWithHits(int hitType) const ;
00346     int innermostMuonStationWithValidHits() const ;
00347     int innermostMuonStationWithBadHits() const ;
00348     int innermostMuonStationWithAnyHits() const ;
00349 
00351     int outermostMuonStationWithHits(int hitType) const ;
00352     int outermostMuonStationWithValidHits() const ;
00353     int outermostMuonStationWithBadHits() const ;
00354     int outermostMuonStationWithAnyHits() const ;
00355 
00356     int numberOfDTStationsWithRPhiView() const ;
00357     int numberOfDTStationsWithRZView() const ;
00358     int numberOfDTStationsWithBothViews() const ;
00359   private:
00360 
00361  
00362     // 1 bit to distinguish tracker and muon subsystems
00363     const static unsigned short SubDetectorOffset = 10; 
00364     const static unsigned short SubDetectorMask = 0x1;
00365 
00366     // 3 bits to identify the tracker/muon detector substructure
00367     const static unsigned short SubstrOffset = 7; 
00368     const static unsigned short SubstrMask = 0x7;
00369 
00370     // 4 bits to identify the layer/disk/wheel within the substructure
00371     const static unsigned short LayerOffset = 3; 
00372     const static unsigned short LayerMask = 0xF;
00373 
00374     // 1 bit to identify the side in double-sided detectors
00375     const static unsigned short SideOffset = 2;
00376     const static unsigned short SideMask = 0x1;
00377 
00378     // 2 bits for hit type
00379     const static unsigned short HitTypeOffset = 0;
00380     const static unsigned short HitTypeMask = 0x3;
00381 
00382     // full hit pattern information is packed in PatternSize 32 bit words
00383     uint32_t hitPattern_[ PatternSize ]; 
00384 
00385     // set pattern for position-th hit
00386     void setHitPattern(int position, uint32_t pattern);
00387 
00388     // set pattern for i-th hit passing a reference
00389     void set(const TrackingRecHitRef & ref, unsigned int i) { set(* ref, i); }
00390 
00391     // detector side for tracker modules (mono/stereo)
00392     static uint32_t isStereo (DetId);
00393 
00394     // encoder for pattern
00395     uint32_t encode(const TrackingRecHit &,unsigned int);
00396   };
00397 
00398   // inline function
00399 
00400   inline bool HitPattern::pixelHitFilter(uint32_t pattern) { 
00401     if  unlikely(!trackerHitFilter(pattern)) return false;
00402     uint32_t substructure = getSubStructure(pattern);
00403     if (substructure == PixelSubdetector::PixelBarrel || 
00404         substructure == PixelSubdetector::PixelEndcap) return true; 
00405     return false;
00406   }
00407   
00408   inline bool HitPattern::pixelBarrelHitFilter(uint32_t pattern) { 
00409     if  unlikely(!trackerHitFilter(pattern)) return false;
00410     uint32_t substructure = getSubStructure(pattern);
00411     if (substructure == PixelSubdetector::PixelBarrel) return true; 
00412     return false;
00413   }
00414   
00415   inline bool HitPattern::pixelEndcapHitFilter(uint32_t pattern) { 
00416     if  unlikely(!trackerHitFilter(pattern)) return false;
00417     uint32_t substructure = getSubStructure(pattern);
00418     if (substructure == PixelSubdetector::PixelEndcap) return true; 
00419     return false;
00420   }
00421   
00422   inline bool HitPattern::stripHitFilter(uint32_t pattern) { 
00423     if  unlikely(!trackerHitFilter(pattern)) return false;
00424     uint32_t substructure = getSubStructure(pattern);
00425     if (substructure == StripSubdetector::TIB ||
00426         substructure == StripSubdetector::TID ||
00427         substructure == StripSubdetector::TOB ||
00428         substructure == StripSubdetector::TEC) return true; 
00429     return false;
00430   }
00431   
00432   inline bool HitPattern::stripTIBHitFilter(uint32_t pattern) { 
00433     if  unlikely(!trackerHitFilter(pattern)) return false;
00434     uint32_t substructure = getSubStructure(pattern);
00435     if (substructure == StripSubdetector::TIB) return true; 
00436     return false;
00437   }
00438   
00439   inline bool HitPattern::stripTIDHitFilter(uint32_t pattern) { 
00440     if  unlikely(!trackerHitFilter(pattern)) return false;
00441     uint32_t substructure = getSubStructure(pattern);
00442     if (substructure == StripSubdetector::TID) return true; 
00443     return false;
00444   }
00445   
00446   inline bool HitPattern::stripTOBHitFilter(uint32_t pattern) { 
00447     if  unlikely(!trackerHitFilter(pattern)) return false;
00448     uint32_t substructure = getSubStructure(pattern);
00449     if (substructure == StripSubdetector::TOB) return true; 
00450     return false;
00451   }
00452   
00453   inline bool HitPattern::stripTECHitFilter(uint32_t pattern) { 
00454     if  unlikely(!trackerHitFilter(pattern)) return false;
00455     uint32_t substructure = getSubStructure(pattern);
00456     if (substructure == StripSubdetector::TEC) return true; 
00457     return false;
00458   }
00459   
00460   inline bool HitPattern::muonDTHitFilter(uint32_t pattern) { 
00461     if  unlikely(!muonHitFilter(pattern)) return false;
00462     uint32_t substructure = getSubStructure(pattern);
00463     if (substructure == (uint32_t) MuonSubdetId::DT) return true; 
00464     return false;
00465   }
00466   
00467   inline bool HitPattern::muonCSCHitFilter(uint32_t pattern) { 
00468     if  unlikely(!muonHitFilter(pattern)) return false;
00469     uint32_t substructure = getSubStructure(pattern);
00470     if (substructure == (uint32_t) MuonSubdetId::CSC) return true; 
00471     return false;
00472   }
00473 
00474   inline bool HitPattern::muonRPCHitFilter(uint32_t pattern) { 
00475     if  unlikely(!muonHitFilter(pattern)) return false;
00476     uint32_t substructure = getSubStructure(pattern);
00477     if (substructure == (uint32_t) MuonSubdetId::RPC) return true; 
00478     return false;
00479   }
00480   
00481   
00482   inline bool HitPattern::trackerHitFilter(uint32_t pattern) {
00483     if  unlikely(pattern == 0) return false;
00484     if (((pattern>>SubDetectorOffset) & SubDetectorMask) == 1) return true;
00485     return false;
00486   }
00487   
00488   inline bool HitPattern::muonHitFilter(uint32_t pattern) {
00489     if  unlikely(pattern == 0) return false;
00490     if (((pattern>>SubDetectorOffset) & SubDetectorMask) == 0) return true; 
00491     return false;
00492   }
00493 
00494 
00495   inline uint32_t HitPattern::getSubStructure(uint32_t pattern) {
00496     if  unlikely(pattern == 0) return 999999;
00497     return ((pattern >> SubstrOffset) & SubstrMask);
00498   }
00499   
00500   
00501   inline uint32_t HitPattern::getLayer(uint32_t pattern) {
00502     if  unlikely(pattern == 0) return 999999;
00503     return ((pattern>>LayerOffset) & LayerMask);
00504   }
00505   
00506   inline uint32_t HitPattern::getSubSubStructure(uint32_t pattern) {
00507     if  unlikely(pattern == 0) return 999999;
00508     return ((pattern>>LayerOffset) & LayerMask);
00509   }
00510   
00511   
00512   inline uint32_t HitPattern::getSide (uint32_t pattern)  {
00513     if  unlikely(pattern == 0) return 999999;
00514     return (pattern >> SideOffset) & SideMask;
00515   }
00516   
00517   inline uint32_t HitPattern::getHitType( uint32_t pattern ) {
00518     if  unlikely(pattern == 0) return 999999;
00519     return ((pattern>>HitTypeOffset) & HitTypeMask);
00520   }
00521   
00522   inline uint32_t HitPattern::getMuonStation(uint32_t pattern) {
00523     return (getSubSubStructure(pattern)>>2) + 1;
00524   }
00525   
00526   inline uint32_t HitPattern::getDTSuperLayer(uint32_t pattern) {
00527     return (getSubSubStructure(pattern) & 3);
00528   }
00529   
00530   inline uint32_t HitPattern::getCSCRing(uint32_t pattern) {
00531     return (getSubSubStructure(pattern) & 3) + 1;
00532   }
00533   
00534   inline uint32_t HitPattern::getRPCLayer(uint32_t pattern) {
00535     uint32_t sss = getSubSubStructure(pattern), stat = sss >> 2;
00536     if likely(stat <= 1) return ((sss >> 1) & 1) + 1;
00537     return 0;
00538   }
00539   
00540   inline uint32_t HitPattern::getRPCregion(uint32_t pattern) {
00541     return getSubSubStructure(pattern) & 1;
00542   }
00543   
00544   
00545   inline bool  HitPattern::validHitFilter(uint32_t pattern) {
00546     if (getHitType(pattern) == 0) return true; 
00547     return false;
00548   }
00549   
00550   inline bool  HitPattern::type_1_HitFilter(uint32_t pattern) {
00551     if (getHitType(pattern) == 1) return true; 
00552     return false;
00553   }
00554   
00555   inline bool  HitPattern::type_2_HitFilter(uint32_t pattern) {
00556     if (getHitType(pattern) == 2) return true; 
00557     return false;
00558   }
00559   
00560   inline bool  HitPattern::type_3_HitFilter(uint32_t pattern) {
00561     if (getHitType(pattern) == 3) return true; 
00562     return false;
00563   }
00564   
00565 
00566   // count methods
00567 
00568 // valid
00569 
00570 inline int HitPattern::numberOfValidHits() const {
00571   return countHits(validHitFilter);
00572 }
00573 
00574 inline int HitPattern::numberOfValidTrackerHits() const {
00575   return countTypedHits(validHitFilter, trackerHitFilter);
00576 }
00577 
00578 inline int HitPattern::numberOfValidMuonHits() const {
00579   return countTypedHits(validHitFilter, muonHitFilter);
00580 }
00581 
00582 inline int HitPattern::numberOfValidPixelHits() const {
00583   return countTypedHits(validHitFilter, pixelHitFilter);
00584 }
00585 
00586 inline int HitPattern::numberOfValidPixelBarrelHits() const {
00587   return countTypedHits(validHitFilter, pixelBarrelHitFilter);
00588 }
00589 
00590 inline int HitPattern::numberOfValidPixelEndcapHits() const {
00591   return countTypedHits(validHitFilter, pixelEndcapHitFilter);
00592 }
00593 
00594 inline int HitPattern::numberOfValidStripHits() const {
00595   return countTypedHits(validHitFilter, stripHitFilter);
00596 }
00597 
00598 inline int HitPattern::numberOfValidStripTIBHits() const {
00599   return countTypedHits(validHitFilter, stripTIBHitFilter);
00600 }
00601 
00602 inline int HitPattern::numberOfValidStripTIDHits() const {
00603   return countTypedHits(validHitFilter, stripTIDHitFilter);
00604 }
00605 
00606 inline int HitPattern::numberOfValidStripTOBHits() const {
00607   return countTypedHits(validHitFilter, stripTOBHitFilter);
00608 }
00609 
00610 inline int HitPattern::numberOfValidStripTECHits() const {
00611   return countTypedHits(validHitFilter, stripTECHitFilter);
00612 }
00613 
00614 inline int HitPattern::numberOfValidMuonDTHits() const {
00615   return countTypedHits(validHitFilter, muonDTHitFilter);
00616 }
00617 
00618 inline int HitPattern::numberOfValidMuonCSCHits() const {
00619   return countTypedHits(validHitFilter, muonCSCHitFilter);
00620 }
00621 
00622 inline int HitPattern::numberOfValidMuonRPCHits() const {
00623   return countTypedHits(validHitFilter, muonRPCHitFilter);
00624 }
00625 
00626 // lost
00627 inline int HitPattern::numberOfLostHits() const {
00628   return countHits(type_1_HitFilter);
00629 }
00630 
00631 inline int HitPattern::numberOfLostTrackerHits() const {
00632   return countTypedHits(type_1_HitFilter, trackerHitFilter);
00633 }
00634 
00635 inline int HitPattern::numberOfLostMuonHits() const {
00636   return countTypedHits(type_1_HitFilter, muonHitFilter);
00637 }
00638 
00639 inline int HitPattern::numberOfLostPixelHits() const {
00640   return countTypedHits(type_1_HitFilter, pixelHitFilter);
00641 }
00642 
00643 inline int HitPattern::numberOfLostPixelBarrelHits() const {
00644   return countTypedHits(type_1_HitFilter, pixelBarrelHitFilter);
00645 }
00646 
00647 inline int HitPattern::numberOfLostPixelEndcapHits() const {
00648   return countTypedHits(type_1_HitFilter, pixelEndcapHitFilter);
00649 }
00650 
00651 inline int HitPattern::numberOfLostStripHits() const {
00652   return countTypedHits(type_1_HitFilter, stripHitFilter);
00653 }
00654 
00655 inline int HitPattern::numberOfLostStripTIBHits() const {
00656   return countTypedHits(type_1_HitFilter, stripTIBHitFilter);
00657 }
00658 
00659 inline int HitPattern::numberOfLostStripTIDHits() const {
00660   return countTypedHits(type_1_HitFilter, stripTIDHitFilter);
00661 }
00662 
00663 inline int HitPattern::numberOfLostStripTOBHits() const {
00664   return countTypedHits(type_1_HitFilter, stripTOBHitFilter);
00665 }
00666 
00667 inline int HitPattern::numberOfLostStripTECHits() const {
00668   return countTypedHits(type_1_HitFilter, stripTECHitFilter);
00669 }
00670 
00671 inline int HitPattern::numberOfLostMuonDTHits() const {
00672   return countTypedHits(type_1_HitFilter, muonDTHitFilter);
00673 }
00674 
00675 inline int HitPattern::numberOfLostMuonCSCHits() const {
00676   return countTypedHits(type_1_HitFilter, muonCSCHitFilter);
00677 }
00678 
00679 inline int HitPattern::numberOfLostMuonRPCHits() const {
00680   return countTypedHits(type_1_HitFilter, muonRPCHitFilter);
00681 }
00682 
00683 
00684 // bad
00685 inline int HitPattern::numberOfBadHits() const {
00686   return countHits(type_3_HitFilter);
00687 }
00688 
00689 inline int HitPattern::numberOfBadMuonHits() const {
00690   return countTypedHits(type_2_HitFilter, muonHitFilter);
00691 }
00692 
00693 inline int HitPattern::numberOfBadMuonDTHits() const {
00694   return countTypedHits(type_2_HitFilter, muonDTHitFilter);
00695 }
00696 
00697 inline int HitPattern::numberOfBadMuonCSCHits() const {
00698   return countTypedHits(type_2_HitFilter, muonCSCHitFilter);
00699 }
00700 
00701 inline int HitPattern::numberOfBadMuonRPCHits() const {
00702   return countTypedHits(type_2_HitFilter, muonRPCHitFilter);
00703 }
00704 
00705 
00706 // inactive
00707 inline int HitPattern::numberOfInactiveHits() const {
00708   return countHits(type_2_HitFilter);
00709 }
00710 
00711 inline int HitPattern::numberOfInactiveTrackerHits() const {
00712   return countTypedHits(type_2_HitFilter, trackerHitFilter);
00713 }
00714 
00715 
00716 
00717 
00718 
00719 
00720   
00721   inline int HitPattern::trackerLayersWithMeasurement() const {
00722     return pixelLayersWithMeasurement() + 
00723       stripLayersWithMeasurement();
00724   }
00725   
00726   inline int HitPattern::pixelLayersWithMeasurement() const {
00727     return pixelBarrelLayersWithMeasurement() +
00728       pixelEndcapLayersWithMeasurement();
00729   }
00730   
00731   inline int HitPattern::stripLayersWithMeasurement() const {
00732     return stripTIBLayersWithMeasurement() + 
00733       stripTIDLayersWithMeasurement() +
00734       stripTOBLayersWithMeasurement() + 
00735       stripTECLayersWithMeasurement();
00736   }
00737   
00738 
00739   inline int HitPattern::trackerLayersWithoutMeasurement() const {
00740     return pixelLayersWithoutMeasurement() + 
00741       stripLayersWithoutMeasurement();
00742   }
00743   
00744   inline int HitPattern::pixelLayersWithoutMeasurement() const {
00745     return pixelBarrelLayersWithoutMeasurement() +
00746       pixelEndcapLayersWithoutMeasurement();
00747   }
00748   
00749   inline int HitPattern::stripLayersWithoutMeasurement() const {
00750     return stripTIBLayersWithoutMeasurement() + 
00751       stripTIDLayersWithoutMeasurement() +
00752       stripTOBLayersWithoutMeasurement() + 
00753       stripTECLayersWithoutMeasurement();
00754   }
00755 
00756 
00757   inline int HitPattern::trackerLayersTotallyOffOrBad() const {
00758     return pixelLayersTotallyOffOrBad() + 
00759       stripLayersTotallyOffOrBad();
00760   }
00761   
00762   inline int HitPattern::pixelLayersTotallyOffOrBad() const {
00763     return pixelBarrelLayersTotallyOffOrBad() +
00764       pixelEndcapLayersTotallyOffOrBad();
00765   }
00766   
00767   inline int HitPattern::stripLayersTotallyOffOrBad() const {
00768     return stripTIBLayersTotallyOffOrBad() + 
00769       stripTIDLayersTotallyOffOrBad() +
00770       stripTOBLayersTotallyOffOrBad() + 
00771       stripTECLayersTotallyOffOrBad();
00772   }
00773   
00774   inline int HitPattern::trackerLayersNull() const {
00775     return pixelLayersNull() + 
00776       stripLayersNull();
00777   }
00778   
00779   inline int HitPattern::pixelLayersNull() const {
00780     return pixelBarrelLayersNull() +
00781       pixelEndcapLayersNull();
00782   }
00783   
00784   inline int HitPattern::stripLayersNull() const {
00785     return stripTIBLayersNull() + 
00786       stripTIDLayersNull() +
00787       stripTOBLayersNull() + 
00788       stripTECLayersNull();
00789   }
00790   
00791 
00792   inline int HitPattern::muonStationsWithValidHits() const { return muonStations(0, 0); }
00793   inline int HitPattern::muonStationsWithBadHits()   const { return muonStations(0, 3); }
00794   inline int HitPattern::muonStationsWithAnyHits()   const { return muonStations(0,-1); }
00795   inline int HitPattern::dtStationsWithValidHits()   const { return muonStations(1, 0); }
00796   inline int HitPattern::dtStationsWithBadHits()     const { return muonStations(1, 3); }
00797   inline int HitPattern::dtStationsWithAnyHits()     const { return muonStations(1,-1); }
00798   inline int HitPattern::cscStationsWithValidHits()  const { return muonStations(2, 0); }
00799   inline int HitPattern::cscStationsWithBadHits()    const { return muonStations(2, 3); }
00800   inline int HitPattern::cscStationsWithAnyHits()    const { return muonStations(2,-1); }
00801   inline int HitPattern::rpcStationsWithValidHits()  const { return muonStations(3, 0); }
00802   inline int HitPattern::rpcStationsWithBadHits()    const { return muonStations(3, 3); }
00803   inline int HitPattern::rpcStationsWithAnyHits()    const { return muonStations(3,-1); }
00804   
00805   inline int HitPattern::innermostMuonStationWithValidHits() const { return innermostMuonStationWithHits(0);  }
00806   inline int HitPattern::innermostMuonStationWithBadHits()   const { return innermostMuonStationWithHits(3);  }
00807   inline int HitPattern::innermostMuonStationWithAnyHits()   const { return innermostMuonStationWithHits(-1); }
00808   inline int HitPattern::outermostMuonStationWithValidHits() const { return outermostMuonStationWithHits(0);  }
00809   inline int HitPattern::outermostMuonStationWithBadHits()   const { return outermostMuonStationWithHits(3);  }
00810   inline int HitPattern::outermostMuonStationWithAnyHits()   const { return outermostMuonStationWithHits(-1); }
00811 
00812 #ifndef CMS_NOCXX11 // cint....
00813 
00814   template<int N=reco::HitPattern::MaxHits>
00815   struct PatternSet {
00816     static constexpr int MaxHits=N;
00817     unsigned char hit[N];
00818     unsigned char nhit;
00819   
00820     unsigned char const * begin() const { return hit;}
00821     unsigned char const * end() const { return hit+nhit;}
00822     unsigned char  * begin()  { return hit;}
00823     unsigned char  * end()  { return hit+nhit;}
00824     int size() const { return nhit;}
00825     unsigned char operator[](int i) const{ return hit[i];}
00826     
00827     PatternSet(): nhit(0){}
00828     PatternSet(reco::HitPattern const & hp) {
00829       fill(hp);
00830     }
00831     
00832     void fill(reco::HitPattern const & hp) {
00833       int lhit=0;
00834       auto unpack =[&lhit,this](uint32_t pattern) -> bool {
00835         unsigned char p = 255&(pattern>>3);
00836         hit[lhit++]= p;
00837         
00838         // bouble sort
00839         if (lhit>1)
00840           for (auto h=hit+lhit-1; h!=hit; --h) {
00841             if ( (*(h-1)) <= p) break; // { (*h)=p;break;}
00842             (*h)=*(h-1);  *(h-1)=p;
00843         }
00844         return lhit<MaxHits;
00845       };
00846       hp.call(reco::HitPattern::validHitFilter,unpack);
00847       nhit=lhit;
00848     }
00849   };
00850 
00851   template<int N>
00852   inline PatternSet<N> commonHits(PatternSet<N> const & p1, PatternSet<N> const & p2) {
00853     PatternSet<N> comm;
00854     comm.nhit = std::set_intersection(p1.begin(),p1.end(),p2.begin(),p2.end(),comm.begin())-comm.begin();
00855     return comm;
00856 }
00857 #endif // gcc11
00858 
00859 } // namespace reco
00860 
00861 #endif