CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DataFormats/TrackReco/src/HitPattern.cc

Go to the documentation of this file.
00001 #include "DataFormats/TrackReco/interface/HitPattern.h"
00002 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00003 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00004 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00005 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00006 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00007 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00008 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00009 #include "DataFormats/MuonDetId/interface/DTLayerId.h"
00010 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00011 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
00012 using namespace reco;
00013 
00014 void HitPattern::set(const TrackingRecHit & hit, unsigned int i) {
00015   // ignore the rec hit if the number of hit is larger than the max
00016   if (i >= 32 * PatternSize / HitSize) return;
00017 
00018   // get rec hit det id and rec hit type
00019   DetId id = hit.geographicalId();
00020   uint32_t detid = id.det();
00021   uint32_t hitType = (uint32_t) hit.getType();
00022 
00023   // init pattern of this hit to 0
00024   uint32_t pattern = 0;
00025 
00026   // adding tracker/muon detector bit
00027   pattern += ((detid)&SubDetectorMask)<<SubDetectorOffset;
00028   
00029   // adding substructure (PXB,PXF,TIB,TID,TOB,TEC, or DT,CSC,RPC) bits 
00030   uint32_t subdet = id.subdetId();
00031   pattern += ((subdet)&SubstrMask)<<SubstrOffset;
00032   
00033   // adding layer/disk/wheel bits
00034   uint32_t layer = 0;
00035   if (detid == DetId::Tracker) {
00036     if (subdet == PixelSubdetector::PixelBarrel) 
00037       layer = PXBDetId(id).layer();
00038     else if (subdet == PixelSubdetector::PixelEndcap)
00039       layer = PXFDetId(id).disk();
00040     else if (subdet == StripSubdetector::TIB)
00041       layer = TIBDetId(id).layer();
00042     else if (subdet == StripSubdetector::TID)
00043       layer = TIDDetId(id).wheel();
00044     else if (subdet == StripSubdetector::TOB)
00045       layer = TOBDetId(id).layer();
00046     else if (subdet == StripSubdetector::TEC)
00047       layer = TECDetId(id).wheel();
00048   } else if (detid == DetId::Muon) {
00049     if (subdet == (uint32_t) MuonSubdetId::DT) 
00050       layer = ((DTLayerId(id.rawId()).station()-1)<<2) + (DTLayerId(id.rawId()).superLayer()-1);
00051     else if (subdet == (uint32_t) MuonSubdetId::CSC)
00052       layer = ((CSCDetId(id.rawId()).station()-1)<<2) +  (CSCDetId(id.rawId()).ring()-1);
00053     else if (subdet == (uint32_t) MuonSubdetId::RPC) {
00054       RPCDetId rpcid(id.rawId());
00055       layer = ((rpcid.station()-1)<<2) + abs(rpcid.region());
00056       if (rpcid.station() <= 2) layer += 2*(rpcid.layer()-1);
00057     }
00058   }
00059   pattern += (layer&LayerMask)<<LayerOffset;
00060 
00061   // adding mono/stereo bit
00062   uint32_t side = 0;
00063   if (detid == DetId::Tracker) {
00064        side = isStereo(id);
00065   } else if (detid == DetId::Muon) {
00066        side = 0;
00067   }
00068   pattern += (side&SideMask)<<SideOffset;
00069 
00070   // adding hit type bits
00071   pattern += (hitType&HitTypeMask)<<HitTypeOffset;
00072 
00073   // set pattern for i-th hit
00074   setHitPattern(i, pattern);
00075 }
00076 
00077 void HitPattern::setHitPattern(int position, uint32_t pattern) {
00078   int offset = position * HitSize;
00079   for (int i=0; i<HitSize; i++) {
00080     int pos = offset + i;
00081     uint32_t bit = (pattern >> i) & 0x1;
00082     hitPattern_[pos / 32] += bit << ((offset + i) % 32); 
00083   }
00084 }
00085 
00086 uint32_t HitPattern::getHitPattern(int position) const {
00087 /* Note: you are not taking a consecutive sequence of HitSize bits starting from position*HitSize
00088          as the bit order in the words are reversed. 
00089          e.g. if position = 0 you take the lowest 10 bits of the first word.
00090     
00091          I hope this can clarify what is the memory layout of such thing
00092 
00093  straight 01234567890123456789012345678901 | 23456789012345678901234567890123 | 4567
00094  (global) 0         1         2         3  | 3       4         5         6    | 6  
00095  words    [--------------0---------------] | [--------------1---------------] | [---   
00096  word     01234567890123456789012345678901 | 01234567890123456789012345678901 | 0123
00097   (str)   0         1         2         3  | 0         1         2         3  | 0
00098           [--------------0---------------] | [--------------1---------------] | [---   
00099  word     10987654321098765432109876543210 | 10987654321098765432109876543210 | 1098
00100   (rev)   32         21        10        0 | 32         21        10        0 | 32  
00101  reverse  10987654321098765432109876543210 | 32109876543210987654321098765432 | 5432
00102           32         21        10        0 | 6  65        54        43      3   9
00103 
00104          ugly enough, but it's not my fault, I was not even in CMS at that time   [gpetrucc] */
00105   uint16_t bitEndOffset = (position+1) * HitSize;
00106   uint8_t secondWord   = (bitEndOffset >> 5);
00107   uint8_t secondWordBits = bitEndOffset & (32-1); // that is, bitEndOffset % 32
00108   if (secondWordBits >= HitSize) { // full block is in this word
00109       uint8_t lowBitsToTrash = secondWordBits - HitSize;
00110       uint32_t myResult = (hitPattern_[secondWord] >> lowBitsToTrash) & ((1 << HitSize)-1);
00111       return myResult;
00112   } else {
00113       uint8_t  firstWordBits   = HitSize - secondWordBits;
00114       uint32_t firstWordBlock  = hitPattern_[secondWord-1] >> (32-firstWordBits);
00115       uint32_t secondWordBlock = hitPattern_[secondWord] & ((1<<secondWordBits)-1);
00116       uint32_t myResult = firstWordBlock + (secondWordBlock << firstWordBits);
00117       return myResult;
00118   }
00119 }
00120 
00121 bool HitPattern::trackerHitFilter(uint32_t pattern) const {
00122   if (pattern == 0) return false;
00123   if (((pattern>>SubDetectorOffset) & SubDetectorMask) == 1) return true;
00124   return false;
00125 }
00126 
00127 bool HitPattern::muonHitFilter(uint32_t pattern) const {
00128   if (pattern == 0) return false;
00129   if (((pattern>>SubDetectorOffset) & SubDetectorMask) == 0) return true; 
00130   return false;
00131 }
00132 
00133 uint32_t HitPattern::getSubStructure(uint32_t pattern) const {
00134   if (pattern == 0) return 999999;
00135   return ((pattern >> SubstrOffset) & SubstrMask);
00136 }
00137 
00138 bool HitPattern::pixelHitFilter(uint32_t pattern) const { 
00139   if (!trackerHitFilter(pattern)) return false;
00140   uint32_t substructure = getSubStructure(pattern);
00141   if (substructure == PixelSubdetector::PixelBarrel || 
00142       substructure == PixelSubdetector::PixelEndcap) return true; 
00143   return false;
00144 }
00145 
00146 bool HitPattern::pixelBarrelHitFilter(uint32_t pattern) const { 
00147   if (!trackerHitFilter(pattern)) return false;
00148   uint32_t substructure = getSubStructure(pattern);
00149   if (substructure == PixelSubdetector::PixelBarrel) return true; 
00150   return false;
00151 }
00152 
00153 bool HitPattern::pixelEndcapHitFilter(uint32_t pattern) const { 
00154   if (!trackerHitFilter(pattern)) return false;
00155   uint32_t substructure = getSubStructure(pattern);
00156   if (substructure == PixelSubdetector::PixelEndcap) return true; 
00157   return false;
00158 }
00159 
00160 bool HitPattern::stripHitFilter(uint32_t pattern) const { 
00161   if (!trackerHitFilter(pattern)) return false;
00162   uint32_t substructure = getSubStructure(pattern);
00163   if (substructure == StripSubdetector::TIB ||
00164       substructure == StripSubdetector::TID ||
00165       substructure == StripSubdetector::TOB ||
00166       substructure == StripSubdetector::TEC) return true; 
00167   return false;
00168 }
00169 
00170 bool HitPattern::stripTIBHitFilter(uint32_t pattern) const { 
00171   if (!trackerHitFilter(pattern)) return false;
00172   uint32_t substructure = getSubStructure(pattern);
00173   if (substructure == StripSubdetector::TIB) return true; 
00174   return false;
00175 }
00176 
00177 bool HitPattern::stripTIDHitFilter(uint32_t pattern) const { 
00178   if (!trackerHitFilter(pattern)) return false;
00179   uint32_t substructure = getSubStructure(pattern);
00180   if (substructure == StripSubdetector::TID) return true; 
00181   return false;
00182 }
00183 
00184 bool HitPattern::stripTOBHitFilter(uint32_t pattern) const { 
00185   if (!trackerHitFilter(pattern)) return false;
00186   uint32_t substructure = getSubStructure(pattern);
00187   if (substructure == StripSubdetector::TOB) return true; 
00188   return false;
00189 }
00190 
00191 bool HitPattern::stripTECHitFilter(uint32_t pattern) const { 
00192   if (!trackerHitFilter(pattern)) return false;
00193   uint32_t substructure = getSubStructure(pattern);
00194   if (substructure == StripSubdetector::TEC) return true; 
00195   return false;
00196 }
00197 
00198 bool HitPattern::muonDTHitFilter(uint32_t pattern) const { 
00199   if (!muonHitFilter(pattern)) return false;
00200   uint32_t substructure = getSubStructure(pattern);
00201   if (substructure == (uint32_t) MuonSubdetId::DT) return true; 
00202   return false;
00203 }
00204 
00205 bool HitPattern::muonCSCHitFilter(uint32_t pattern) const { 
00206   if (!muonHitFilter(pattern)) return false;
00207   uint32_t substructure = getSubStructure(pattern);
00208   if (substructure == (uint32_t) MuonSubdetId::CSC) return true; 
00209   return false;
00210 }
00211 
00212 bool HitPattern::muonRPCHitFilter(uint32_t pattern) const { 
00213   if (!muonHitFilter(pattern)) return false;
00214   uint32_t substructure = getSubStructure(pattern);
00215   if (substructure == (uint32_t) MuonSubdetId::RPC) return true; 
00216   return false;
00217 }
00218 
00219 uint32_t HitPattern::getLayer(uint32_t pattern) const {
00220   if (pattern == 0) return 999999;
00221   return ((pattern>>LayerOffset) & LayerMask);
00222 }
00223 
00224 uint32_t HitPattern::getSubSubStructure(uint32_t pattern) const {
00225   if (pattern == 0) return 999999;
00226   return ((pattern>>LayerOffset) & LayerMask);
00227 }
00228 
00229 
00230 uint32_t HitPattern::getSide (uint32_t pattern) 
00231 {
00232      if (pattern == 0) return 999999;
00233      return (pattern >> SideOffset) & SideMask;
00234 }
00235 
00236 uint32_t HitPattern::getHitType( uint32_t pattern ) const {
00237   if (pattern == 0) return 999999;
00238   return ((pattern>>HitTypeOffset) & HitTypeMask);
00239 }
00240 
00241 uint32_t HitPattern::getMuonStation(uint32_t pattern) const {
00242   return (getSubSubStructure(pattern)>>2) + 1;
00243 }
00244 
00245 uint32_t HitPattern::getDTSuperLayer(uint32_t pattern) const {
00246   return (getSubSubStructure(pattern) & 3) + 1;
00247 }
00248 
00249 uint32_t HitPattern::getCSCRing(uint32_t pattern) const {
00250   return (getSubSubStructure(pattern) & 3) + 1;
00251 }
00252 
00253 uint32_t HitPattern::getRPCLayer(uint32_t pattern) const {
00254     uint32_t sss = getSubSubStructure(pattern), stat = sss >> 2;
00255     if (stat <= 1) return ((sss >> 1) & 1) + 1;
00256     else return 0;
00257 }
00258 
00259 uint32_t HitPattern::getRPCregion(uint32_t pattern) const {
00260     return getSubSubStructure(pattern) & 1;
00261 }
00262 
00263 
00264 bool HitPattern::validHitFilter(uint32_t pattern) const {
00265   if (getHitType(pattern) == 0) return true; 
00266   return false;
00267 }
00268 
00269 bool HitPattern::type_1_HitFilter(uint32_t pattern) const {
00270   if (getHitType(pattern) == 1) return true; 
00271   return false;
00272 }
00273 
00274 bool HitPattern::type_2_HitFilter(uint32_t pattern) const {
00275   if (getHitType(pattern) == 2) return true; 
00276   return false;
00277 }
00278 
00279 bool HitPattern::type_3_HitFilter(uint32_t pattern) const {
00280   if (getHitType(pattern) == 3) return true; 
00281   return false;
00282 }
00283 
00284 bool HitPattern::hasValidHitInFirstPixelBarrel() const {
00285   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00286     uint32_t pattern = getHitPattern(i);
00287     if (pixelBarrelHitFilter(pattern)) {
00288       if (getLayer(pattern) == 1) {
00289         if (validHitFilter(pattern)) {
00290           return true;
00291         }
00292       }
00293     }
00294   }
00295   return false;
00296 }
00297 
00298 bool HitPattern::hasValidHitInFirstPixelEndcap() const {
00299   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00300     uint32_t pattern = getHitPattern(i);
00301     if (pixelEndcapHitFilter(pattern)) {
00302       if (getLayer(pattern) == 1) {
00303         if (validHitFilter(pattern)) {
00304           return true;
00305         }
00306       }
00307     }
00308   }
00309   return false;
00310 }
00311 
00312 int HitPattern::numberOfHits() const {
00313   int count = 0;
00314   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00315     uint32_t pattern = getHitPattern(i);
00316     if (pattern != 0) count++;
00317   }
00318   return count;
00319 }
00320 
00321 int HitPattern::numberOfValidHits() const {
00322   int count = 0;
00323   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00324     uint32_t pattern = getHitPattern(i);
00325     if (pattern == 0) break;
00326     //if (pattern != 0) {
00327       if (validHitFilter(pattern)) count++;
00328     //}
00329   }
00330   return count;
00331 }
00332 
00333 int HitPattern::numberOfValidTrackerHits() const {
00334   int count = 0;
00335   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00336     uint32_t pattern = getHitPattern(i);
00337     if (pattern != 0) {
00338       if (validHitFilter(pattern)) {
00339         if (trackerHitFilter(pattern)) count++;
00340       }
00341     }
00342   }
00343   return count;
00344 }
00345 
00346 int HitPattern::numberOfValidMuonHits() const {
00347   int count = 0;
00348   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00349     uint32_t pattern = getHitPattern(i);
00350     if (pattern != 0) {
00351       if (validHitFilter(pattern)) {
00352         if (muonHitFilter(pattern)) count++;
00353       }
00354     }
00355   }
00356   return count;
00357 }
00358 
00359 int HitPattern::numberOfValidPixelHits() const {
00360   int count = 0;
00361   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00362     uint32_t pattern = getHitPattern(i);
00363     if (pattern != 0) {
00364       if (validHitFilter(pattern)) {
00365         if (pixelHitFilter(pattern)) count++;
00366       }
00367     }
00368   }
00369   return count;
00370 }
00371 
00372 int HitPattern::numberOfValidPixelBarrelHits() const {
00373   int count = 0;
00374   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00375     uint32_t pattern = getHitPattern(i);
00376     if (pattern != 0) {
00377       if (validHitFilter(pattern)) {
00378         if (pixelBarrelHitFilter(pattern)) count++;
00379       }
00380     }
00381   }
00382   return count;
00383 }
00384 
00385 int HitPattern::numberOfValidPixelEndcapHits() const {
00386   int count = 0;
00387   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00388     uint32_t pattern = getHitPattern(i);
00389     if (pattern != 0) {
00390       if (validHitFilter(pattern)) {
00391         if (pixelEndcapHitFilter(pattern)) count++;
00392       }
00393     }
00394   }
00395   return count;
00396 }
00397 
00398 int HitPattern::numberOfValidStripHits() const {
00399   int count = 0;
00400   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00401     uint32_t pattern = getHitPattern(i);
00402     if (pattern != 0) {
00403       if (validHitFilter(pattern)) {
00404         if (stripHitFilter(pattern)) count++;
00405       }
00406     }
00407   }
00408   return count;
00409 }
00410 
00411 int HitPattern::numberOfValidStripTIBHits() const {
00412   int count = 0;
00413   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00414     uint32_t pattern = getHitPattern(i);
00415     if (pattern != 0) {
00416       if (validHitFilter(pattern)) {
00417         if (stripTIBHitFilter(pattern)) count++;
00418       }
00419     }
00420   }
00421   return count;
00422 }
00423 
00424 int HitPattern::numberOfValidStripTIDHits() const {
00425   int count = 0;
00426   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00427     uint32_t pattern = getHitPattern(i);
00428     if (pattern != 0) {
00429       if (validHitFilter(pattern)) {
00430         if (stripTIDHitFilter(pattern)) count++;
00431       }
00432     }
00433   }
00434   return count;
00435 }
00436 
00437 int HitPattern::numberOfValidStripTOBHits() const {
00438   int count = 0;
00439   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00440     uint32_t pattern = getHitPattern(i);
00441     if (pattern != 0) {
00442       if (validHitFilter(pattern)) {
00443         if (stripTOBHitFilter(pattern)) count++;
00444       }
00445     }
00446   }
00447   return count;
00448 }
00449 
00450 int HitPattern::numberOfValidStripTECHits() const {
00451   int count = 0;
00452   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00453     uint32_t pattern = getHitPattern(i);
00454     if (pattern != 0) {
00455       if (validHitFilter(pattern)) {
00456         if (stripTECHitFilter(pattern)) count++;
00457       }
00458     }
00459   }
00460   return count;
00461 }
00462 
00463 int HitPattern::numberOfValidMuonDTHits() const {
00464   int count = 0;
00465   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00466     uint32_t pattern = getHitPattern(i);
00467     if (pattern != 0) {
00468       if (validHitFilter(pattern)) {
00469         if (muonDTHitFilter(pattern)) count++;
00470       }
00471     }
00472   }
00473   return count;
00474 }
00475 
00476 int HitPattern::numberOfValidMuonCSCHits() const {
00477   int count = 0;
00478   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00479     uint32_t pattern = getHitPattern(i);
00480     if (pattern != 0) {
00481       if (validHitFilter(pattern)) {
00482         if (muonCSCHitFilter(pattern)) count++;
00483       }
00484     }
00485   }
00486   return count;
00487 }
00488 
00489 int HitPattern::numberOfValidMuonRPCHits() const {
00490   int count = 0;
00491   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00492     uint32_t pattern = getHitPattern(i);
00493     if (pattern != 0) {
00494       if (validHitFilter(pattern)) {
00495         if (muonRPCHitFilter(pattern)) count++;
00496       }
00497     }
00498   }
00499   return count;
00500 }
00501 
00502 int HitPattern::numberOfLostHits() const {
00503   int count = 0;
00504   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00505     uint32_t pattern = getHitPattern(i);
00506     if (pattern != 0) {
00507       if (type_1_HitFilter(pattern)) count++;
00508     }
00509   }
00510   return count;
00511 }
00512 
00513 int HitPattern::numberOfLostTrackerHits() const {
00514   int count = 0;
00515   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00516     uint32_t pattern = getHitPattern(i);
00517     if (pattern != 0) {
00518       if (type_1_HitFilter(pattern)) {
00519         if (trackerHitFilter(pattern)) count++;
00520       }
00521     }
00522   }
00523   return count;
00524 }
00525 
00526 int HitPattern::numberOfLostMuonHits() const {
00527   int count = 0;
00528   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00529     uint32_t pattern = getHitPattern(i);
00530     if (pattern != 0) {
00531       if (type_1_HitFilter(pattern)) {
00532         if (muonHitFilter(pattern)) count++;
00533       }
00534     }
00535   }
00536   return count;
00537 }
00538 
00539 int HitPattern::numberOfLostPixelHits() const {
00540   int count = 0;
00541   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00542     uint32_t pattern = getHitPattern(i);
00543     if (pattern != 0) {
00544       if (type_1_HitFilter(pattern)) {
00545         if (pixelHitFilter(pattern)) count++;
00546       }
00547     }
00548   }
00549   return count;
00550 }
00551 
00552 int HitPattern::numberOfLostPixelBarrelHits() const {
00553   int count = 0;
00554   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00555     uint32_t pattern = getHitPattern(i);
00556     if (pattern != 0) {
00557       if (type_1_HitFilter(pattern)) {
00558         if (pixelBarrelHitFilter(pattern)) count++;
00559       }
00560     }
00561   }
00562   return count;
00563 }
00564 
00565 int HitPattern::numberOfLostPixelEndcapHits() const {
00566   int count = 0;
00567   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00568     uint32_t pattern = getHitPattern(i);
00569     if (pattern != 0) {
00570       if (type_1_HitFilter(pattern)) {
00571         if (pixelEndcapHitFilter(pattern)) count++;
00572       }
00573     }
00574   }
00575   return count;
00576 }
00577 
00578 int HitPattern::numberOfLostStripHits() const {
00579   int count = 0;
00580   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00581     uint32_t pattern = getHitPattern(i);
00582     if (pattern != 0) {
00583       if (type_1_HitFilter(pattern)) {
00584         if (stripHitFilter(pattern)) count++;
00585       }
00586     }
00587   }
00588   return count;
00589 }
00590 
00591 int HitPattern::numberOfLostStripTIBHits() const {
00592   int count = 0;
00593   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00594     uint32_t pattern = getHitPattern(i);
00595     if (pattern != 0) {
00596       if (type_1_HitFilter(pattern)) {
00597         if (stripTIBHitFilter(pattern)) count++;
00598       }
00599     }
00600   }
00601   return count;
00602 }
00603 
00604 int HitPattern::numberOfLostStripTIDHits() const {
00605   int count = 0;
00606   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00607     uint32_t pattern = getHitPattern(i);
00608     if (pattern != 0) {
00609       if (type_1_HitFilter(pattern)) {
00610         if (stripTIDHitFilter(pattern)) count++;
00611       }
00612     }
00613   }
00614   return count;
00615 }
00616 
00617 int HitPattern::numberOfLostStripTOBHits() const {
00618   int count = 0;
00619   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00620     uint32_t pattern = getHitPattern(i);
00621     if (pattern != 0) {
00622       if (type_1_HitFilter(pattern)) {
00623         if (stripTOBHitFilter(pattern)) count++;
00624       }
00625     }
00626   }
00627   return count;
00628 }
00629 
00630 int HitPattern::numberOfLostStripTECHits() const {
00631   int count = 0;
00632   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00633     uint32_t pattern = getHitPattern(i);
00634     if (pattern != 0) {
00635       if (type_1_HitFilter(pattern)) {
00636         if (stripTECHitFilter(pattern)) count++;
00637       }
00638     }
00639   }
00640   return count;
00641 }
00642 
00643 int HitPattern::numberOfLostMuonDTHits() const {
00644   int count = 0;
00645   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00646     uint32_t pattern = getHitPattern(i);
00647     if (pattern != 0) {
00648       if (type_1_HitFilter(pattern)) {
00649         if (muonDTHitFilter(pattern)) count++;
00650       }
00651     }
00652   }
00653   return count;
00654 }
00655 
00656 int HitPattern::numberOfLostMuonCSCHits() const {
00657   int count = 0;
00658   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00659     uint32_t pattern = getHitPattern(i);
00660     if (pattern != 0) {
00661       if (type_1_HitFilter(pattern)) {
00662         if (muonCSCHitFilter(pattern)) count++;
00663       }
00664     }
00665   }
00666   return count;
00667 }
00668 
00669 int HitPattern::numberOfLostMuonRPCHits() const {
00670   int count = 0;
00671   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00672     uint32_t pattern = getHitPattern(i);
00673     if (pattern != 0) {
00674       if (type_1_HitFilter(pattern)) {
00675         if (muonRPCHitFilter(pattern)) count++;
00676       }
00677     }
00678   }
00679   return count;
00680 }
00681 
00682 int HitPattern::numberOfBadHits() const {
00683   int count = 0;
00684   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00685     uint32_t pattern = getHitPattern(i);
00686     if (pattern != 0) {
00687       if (type_3_HitFilter(pattern)) count++;
00688     }
00689   }
00690   return count;
00691 }
00692 
00693 int HitPattern::numberOfBadMuonHits() const {
00694   int count = 0;
00695   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00696     uint32_t pattern = getHitPattern(i);
00697     if (pattern != 0) {
00698       if (type_3_HitFilter(pattern)) {
00699         if (muonHitFilter(pattern)) count++;
00700       }
00701     }
00702   }
00703   return count;
00704 }
00705 
00706 int HitPattern::numberOfBadMuonDTHits() const {
00707   int count = 0;
00708   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00709     uint32_t pattern = getHitPattern(i);
00710     if (pattern != 0) {
00711       if (type_3_HitFilter(pattern)) {
00712         if (muonDTHitFilter(pattern)) count++;
00713       }
00714     }
00715   }
00716   return count;
00717 }
00718 
00719 int HitPattern::numberOfBadMuonCSCHits() const {
00720   int count = 0;
00721   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00722     uint32_t pattern = getHitPattern(i);
00723     if (pattern != 0) {
00724       if (type_3_HitFilter(pattern)) {
00725         if (muonCSCHitFilter(pattern)) count++;
00726       }
00727     }
00728   }
00729   return count;
00730 }
00731 
00732 int HitPattern::numberOfBadMuonRPCHits() const {
00733   int count = 0;
00734   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
00735     uint32_t pattern = getHitPattern(i);
00736     if (pattern != 0) {
00737       if (type_3_HitFilter(pattern)) {
00738         if (muonRPCHitFilter(pattern)) count++;
00739       }
00740     }
00741   }
00742   return count;
00743 }
00744 
00745 int HitPattern::numberOfValidStripLayersWithMonoAndStereo () const 
00746 {
00747      static const int nHits = (PatternSize * 32) / HitSize;
00748      bool hasMono[SubstrMask + 1][LayerMask + 1];
00749      //     printf("sizeof(hasMono) = %d\n", sizeof(hasMono));
00750      memset(hasMono, 0, sizeof(hasMono));
00751      bool hasStereo[SubstrMask + 1][LayerMask + 1];
00752      memset(hasStereo, 0, sizeof(hasStereo));
00753      // mark which layers have mono/stereo hits
00754      for (int i = 0; i < nHits; i++) {
00755           uint32_t pattern = getHitPattern(i);
00756           if (pattern != 0) {
00757                if (validHitFilter(pattern) && stripHitFilter(pattern)) {
00758                     switch (getSide(pattern)) {
00759                     case 0: // mono
00760                          hasMono[getSubStructure(pattern)][getLayer(pattern)] 
00761                               = true;
00762                          break;
00763                     case 1: // stereo
00764                          hasStereo[getSubStructure(pattern)][getLayer(pattern)]
00765                               = true;
00766                          break;
00767                     default:
00768                          break;
00769                     }
00770                }
00771           }
00772      }
00773      // count how many layers have mono and stereo hits
00774      int count = 0;
00775      for (int i = 0; i < SubstrMask + 1; ++i) 
00776           for (int j = 0; j < LayerMask + 1; ++j)
00777                if (hasMono[i][j] && hasStereo[i][j])
00778                     count++;
00779      return count;
00780 }
00781 
00782 uint32_t HitPattern::getTrackerLayerCase(uint32_t substr, uint32_t layer) const
00783 {
00784   uint32_t tk_substr_layer = 
00785     (1 << SubDetectorOffset) +
00786     ((substr & SubstrMask) << SubstrOffset) +
00787     ((layer & LayerMask) << LayerOffset);
00788 
00789   uint32_t mask =
00790     (SubDetectorMask << SubDetectorOffset) +
00791     (SubstrMask << SubstrOffset) +
00792     (LayerMask << LayerOffset);
00793 
00794   // crossed
00795   //   layer case 0: valid + (missing, off, bad) ==> with measurement
00796   //   layer case 1: missing + (off, bad) ==> without measurement
00797   //   layer case 2: off, bad ==> totally off or bad, cannot say much
00798   // not crossed
00799   //   layer case 999999: track outside acceptance or in gap ==> null
00800 
00801   uint32_t layerCase = 999999;
00802   for (int i=0; i<(PatternSize * 32) / HitSize; i++)
00803   {
00804     uint32_t pattern = getHitPattern(i);
00805     if (pattern == 0) break;
00806     if ((pattern & mask) == tk_substr_layer)
00807     {
00808       uint32_t hitType = (pattern >> HitTypeOffset) & HitTypeMask; // 0,1,2,3
00809       if (hitType < layerCase)
00810       {
00811         layerCase = hitType;
00812         if (hitType == 3) layerCase = 2;
00813       }
00814     }
00815   }
00816   return layerCase;
00817 }
00818 
00819 uint32_t HitPattern::getTrackerMonoStereo (uint32_t substr, uint32_t layer) const
00820 {
00821   uint32_t tk_substr_layer = 
00822     (1 << SubDetectorOffset) +
00823     ((substr & SubstrMask) << SubstrOffset) +
00824     ((layer & LayerMask) << LayerOffset);
00825 
00826   uint32_t mask =
00827     (SubDetectorMask << SubDetectorOffset) +
00828     (SubstrMask << SubstrOffset) +
00829     (LayerMask << LayerOffset);
00830 
00831   //    0:              neither a valid mono nor a valid stereo hit
00832   //    MONO:           valid mono hit
00833   //    STEREO:         valid stereo hit
00834   //    MONO | STEREO:  both
00835   uint32_t monoStereo = 0;
00836   for (int i=0; i<(PatternSize * 32) / HitSize; i++)
00837   {
00838     uint32_t pattern = getHitPattern(i);
00839     if (pattern == 0) break;
00840     if ((pattern & mask) == tk_substr_layer)
00841     {
00842       uint32_t hitType = (pattern >> HitTypeOffset) & HitTypeMask; // 0,1,2,3
00843       if (hitType == 0) { // valid hit
00844            switch (getSide(pattern)) {
00845            case 0: // mono
00846                 monoStereo |= MONO;
00847                 break;
00848            case 1: // stereo
00849                 monoStereo |= STEREO;
00850                 break;
00851            default:
00852                 break;
00853            }
00854       }
00855     }
00856   }
00857   return monoStereo;
00858 }
00859 
00860 int HitPattern::trackerLayersWithMeasurement() const {
00861   return pixelLayersWithMeasurement() + 
00862          stripLayersWithMeasurement();
00863 }
00864 
00865 int HitPattern::pixelLayersWithMeasurement() const {
00866   return pixelBarrelLayersWithMeasurement() +
00867          pixelEndcapLayersWithMeasurement();
00868 }
00869 
00870 int HitPattern::stripLayersWithMeasurement() const {
00871   return stripTIBLayersWithMeasurement() + 
00872          stripTIDLayersWithMeasurement() +
00873          stripTOBLayersWithMeasurement() + 
00874          stripTECLayersWithMeasurement();
00875 }
00876 
00877 int HitPattern::pixelBarrelLayersWithMeasurement() const {
00878   int count = 0;
00879   uint32_t substr = PixelSubdetector::PixelBarrel;
00880   for (uint32_t layer=1; layer<=3; layer++) {
00881     if (getTrackerLayerCase(substr, layer) == 0) count++;
00882   }
00883   return count;
00884 }
00885 
00886 int HitPattern::pixelEndcapLayersWithMeasurement() const {
00887   int count = 0;
00888   uint32_t substr = PixelSubdetector::PixelEndcap;
00889   for (uint32_t layer=1; layer<=2; layer++) {
00890     if (getTrackerLayerCase(substr, layer) == 0) count++;
00891   }
00892   return count;
00893 }
00894 
00895 int HitPattern::stripTIBLayersWithMeasurement() const {
00896   int count = 0;
00897   uint32_t substr = StripSubdetector::TIB;
00898   for (uint32_t layer=1; layer<=4; layer++) {
00899     if (getTrackerLayerCase(substr, layer) == 0) count++;
00900   }
00901   return count;
00902 }
00903 
00904 int HitPattern::stripTIDLayersWithMeasurement() const {
00905   int count = 0;
00906   uint32_t substr = StripSubdetector::TID;
00907   for (uint32_t layer=1; layer<=3; layer++) {
00908     if (getTrackerLayerCase(substr, layer) == 0) count++;
00909   }
00910   return count;
00911 }
00912 
00913 int HitPattern::stripTOBLayersWithMeasurement() const {
00914   int count = 0;
00915   uint32_t substr = StripSubdetector::TOB;
00916   for (uint32_t layer=1; layer<=6; layer++) {
00917     if (getTrackerLayerCase(substr, layer) == 0) count++;
00918   }
00919   return count;
00920 }
00921 
00922 int HitPattern::stripTECLayersWithMeasurement() const {
00923   int count = 0;
00924   uint32_t substr = StripSubdetector::TEC;
00925   for (uint32_t layer=1; layer<=9; layer++) {
00926     if (getTrackerLayerCase(substr, layer) == 0) count++;
00927   }
00928   return count;
00929 }
00930 
00931 int HitPattern::trackerLayersWithoutMeasurement() const {
00932   return pixelLayersWithoutMeasurement() + 
00933          stripLayersWithoutMeasurement();
00934 }
00935 
00936 int HitPattern::pixelLayersWithoutMeasurement() const {
00937   return pixelBarrelLayersWithoutMeasurement() +
00938          pixelEndcapLayersWithoutMeasurement();
00939 }
00940 
00941 int HitPattern::stripLayersWithoutMeasurement() const {
00942   return stripTIBLayersWithoutMeasurement() + 
00943          stripTIDLayersWithoutMeasurement() +
00944          stripTOBLayersWithoutMeasurement() + 
00945          stripTECLayersWithoutMeasurement();
00946 }
00947 
00948 int HitPattern::pixelBarrelLayersWithoutMeasurement() const {
00949   int count = 0;
00950   uint32_t substr = PixelSubdetector::PixelBarrel;
00951   for (uint32_t layer=1; layer<=3; layer++) {
00952     if (getTrackerLayerCase(substr, layer) == 1) count++;
00953   }
00954   return count;
00955 }
00956 
00957 int HitPattern::pixelEndcapLayersWithoutMeasurement() const {
00958   int count = 0;
00959   uint32_t substr = PixelSubdetector::PixelEndcap;
00960   for (uint32_t layer=1; layer<=2; layer++) {
00961     if (getTrackerLayerCase(substr, layer) == 1) count++;
00962   }
00963   return count;
00964 }
00965 
00966 int HitPattern::stripTIBLayersWithoutMeasurement() const {
00967   int count = 0;
00968   uint32_t substr = StripSubdetector::TIB;
00969   for (uint32_t layer=1; layer<=4; layer++) {
00970     if (getTrackerLayerCase(substr, layer) == 1) count++;
00971   }
00972   return count;
00973 }
00974 
00975 int HitPattern::stripTIDLayersWithoutMeasurement() const {
00976   int count = 0;
00977   uint32_t substr = StripSubdetector::TID;
00978   for (uint32_t layer=1; layer<=3; layer++) {
00979     if (getTrackerLayerCase(substr, layer) == 1) count++;
00980   }
00981   return count;
00982 }
00983 
00984 int HitPattern::stripTOBLayersWithoutMeasurement() const {
00985   int count = 0;
00986   uint32_t substr = StripSubdetector::TOB;
00987   for (uint32_t layer=1; layer<=6; layer++) {
00988     if (getTrackerLayerCase(substr, layer) == 1) count++;
00989   }
00990   return count;
00991 }
00992 
00993 int HitPattern::stripTECLayersWithoutMeasurement() const {
00994   int count = 0;
00995   uint32_t substr = StripSubdetector::TEC;
00996   for (uint32_t layer=1; layer<=9; layer++) {
00997     if (getTrackerLayerCase(substr, layer) == 1) count++;
00998   }
00999   return count;
01000 }
01001 
01002 int HitPattern::trackerLayersTotallyOffOrBad() const {
01003   return pixelLayersTotallyOffOrBad() + 
01004          stripLayersTotallyOffOrBad();
01005 }
01006 
01007 int HitPattern::pixelLayersTotallyOffOrBad() const {
01008   return pixelBarrelLayersTotallyOffOrBad() +
01009          pixelEndcapLayersTotallyOffOrBad();
01010 }
01011 
01012 int HitPattern::stripLayersTotallyOffOrBad() const {
01013   return stripTIBLayersTotallyOffOrBad() + 
01014          stripTIDLayersTotallyOffOrBad() +
01015          stripTOBLayersTotallyOffOrBad() + 
01016          stripTECLayersTotallyOffOrBad();
01017 }
01018 
01019 int HitPattern::pixelBarrelLayersTotallyOffOrBad() const {
01020   int count = 0;
01021   uint32_t substr = PixelSubdetector::PixelBarrel;
01022   for (uint32_t layer=1; layer<=3; layer++) {
01023     if (getTrackerLayerCase(substr, layer) == 2) count++;
01024   }
01025   return count;
01026 }
01027 
01028 int HitPattern::pixelEndcapLayersTotallyOffOrBad() const {
01029   int count = 0;
01030   uint32_t substr = PixelSubdetector::PixelEndcap;
01031   for (uint32_t layer=1; layer<=2; layer++) {
01032     if (getTrackerLayerCase(substr, layer) == 2) count++;
01033   }
01034   return count;
01035 }
01036 
01037 int HitPattern::stripTIBLayersTotallyOffOrBad() const {
01038   int count = 0;
01039   uint32_t substr = StripSubdetector::TIB;
01040   for (uint32_t layer=1; layer<=4; layer++) {
01041     if (getTrackerLayerCase(substr, layer) == 2) count++;
01042   }
01043   return count;
01044 }
01045 
01046 int HitPattern::stripTIDLayersTotallyOffOrBad() const {
01047   int count = 0;
01048   uint32_t substr = StripSubdetector::TID;
01049   for (uint32_t layer=1; layer<=3; layer++) {
01050     if (getTrackerLayerCase(substr, layer) == 2) count++;
01051   }
01052   return count;
01053 }
01054 
01055 int HitPattern::stripTOBLayersTotallyOffOrBad() const {
01056   int count = 0;
01057   uint32_t substr = StripSubdetector::TOB;
01058   for (uint32_t layer=1; layer<=6; layer++) {
01059     if (getTrackerLayerCase(substr, layer) == 2) count++;
01060   }
01061   return count;
01062 }
01063 
01064 int HitPattern::stripTECLayersTotallyOffOrBad() const {
01065   int count = 0;
01066   uint32_t substr = StripSubdetector::TEC;
01067   for (uint32_t layer=1; layer<=9; layer++) {
01068     if (getTrackerLayerCase(substr, layer) == 2) count++;
01069   }
01070   return count;
01071 }
01072 
01073 int HitPattern::trackerLayersNull() const {
01074   return pixelLayersNull() + 
01075          stripLayersNull();
01076 }
01077 
01078 int HitPattern::pixelLayersNull() const {
01079   return pixelBarrelLayersNull() +
01080          pixelEndcapLayersNull();
01081 }
01082 
01083 int HitPattern::stripLayersNull() const {
01084   return stripTIBLayersNull() + 
01085          stripTIDLayersNull() +
01086          stripTOBLayersNull() + 
01087          stripTECLayersNull();
01088 }
01089 
01090 int HitPattern::pixelBarrelLayersNull() const {
01091   int count = 0;
01092   uint32_t substr = PixelSubdetector::PixelBarrel;
01093   for (uint32_t layer=1; layer<=3; layer++) {
01094     if (getTrackerLayerCase(substr, layer) == 999999) count++;
01095   }
01096   return count;
01097 }
01098 
01099 int HitPattern::pixelEndcapLayersNull() const {
01100   int count = 0;
01101   uint32_t substr = PixelSubdetector::PixelEndcap;
01102   for (uint32_t layer=1; layer<=2; layer++) {
01103     if (getTrackerLayerCase(substr, layer) == 999999) count++;
01104   }
01105   return count;
01106 }
01107 
01108 int HitPattern::stripTIBLayersNull() const {
01109   int count = 0;
01110   uint32_t substr = StripSubdetector::TIB;
01111   for (uint32_t layer=1; layer<=4; layer++) {
01112     if (getTrackerLayerCase(substr, layer) == 999999) count++;
01113   }
01114   return count;
01115 }
01116 
01117 int HitPattern::stripTIDLayersNull() const {
01118   int count = 0;
01119   uint32_t substr = StripSubdetector::TID;
01120   for (uint32_t layer=1; layer<=3; layer++) {
01121     if (getTrackerLayerCase(substr, layer) == 999999) count++;
01122   }
01123   return count;
01124 }
01125 
01126 int HitPattern::stripTOBLayersNull() const {
01127   int count = 0;
01128   uint32_t substr = StripSubdetector::TOB;
01129   for (uint32_t layer=1; layer<=6; layer++) {
01130     if (getTrackerLayerCase(substr, layer) == 999999) count++;
01131   }
01132   return count;
01133 }
01134 
01135 int HitPattern::stripTECLayersNull() const {
01136   int count = 0;
01137   uint32_t substr = StripSubdetector::TEC;
01138   for (uint32_t layer=1; layer<=9; layer++) {
01139     if (getTrackerLayerCase(substr, layer) == 999999) count++;
01140   }
01141   return count;
01142 }
01143 
01144 void HitPattern::printHitPattern (int position, std::ostream &stream) const
01145 {
01146      uint32_t pattern = getHitPattern(position);
01147      stream << "\t";
01148      if (muonHitFilter(pattern))
01149           stream << "muon";
01150      if (trackerHitFilter(pattern))
01151           stream << "tracker";
01152      stream << "\tsubstructure " << getSubStructure(pattern);
01153      if (muonHitFilter(pattern)) {
01154          stream << "\tstation " << getMuonStation(pattern);
01155          if (muonDTHitFilter(pattern)) { 
01156             stream << "\tdt superlayer " << getDTSuperLayer(pattern); 
01157          } else if (muonCSCHitFilter(pattern)) { 
01158             stream << "\tcsc ring " << getCSCRing(pattern); 
01159          } else if (muonRPCHitFilter(pattern)) {
01160             stream << "\trpc " << (getRPCregion(pattern) ? "endcaps" : "barrel") << ", layer " << getRPCLayer(pattern); 
01161          } else {
01162             stream << "(UNKNOWN Muon SubStructure!) \tsubsubstructure " << getSubStructure(pattern);
01163          }
01164      } else {
01165          stream << "\tlayer " << getLayer(pattern);
01166      }
01167      stream << "\thit type " << getHitType(pattern);
01168      stream << std::endl;
01169 }
01170 
01171 void HitPattern::print (std::ostream &stream) const
01172 {
01173      stream << "HitPattern" << std::endl;
01174      for (int i = 0; i < numberOfHits(); i++) 
01175           printHitPattern(i, stream);
01176      std::ios_base::fmtflags flags = stream.flags();
01177      stream.setf ( std::ios_base::hex, std::ios_base::basefield );  
01178      stream.setf ( std::ios_base::showbase );               
01179      for (int i = 0; i < numberOfHits(); i++) {
01180           uint32_t pattern = getHitPattern(i);
01181           stream << pattern << std::endl;
01182      }
01183      stream.flags(flags);
01184 }
01185 
01186 uint32_t HitPattern::isStereo (DetId i) 
01187 {
01188      switch (i.det()) {
01189      case DetId::Tracker:
01190           switch (i.subdetId()) {
01191           case PixelSubdetector::PixelBarrel:
01192           case PixelSubdetector::PixelEndcap:
01193                return 0;
01194           case StripSubdetector::TIB:
01195           {
01196                TIBDetId id = i;
01197                return id.isStereo();
01198           }
01199           case StripSubdetector::TID:
01200           {
01201                TIDDetId id = i;
01202                return id.isStereo();
01203           }
01204           case StripSubdetector::TOB:
01205           {
01206                TOBDetId id = i;
01207                return id.isStereo();
01208           }
01209           case StripSubdetector::TEC:
01210           {
01211                TECDetId id = i;
01212                return id.isStereo();
01213           }
01214           default:
01215                return 0;
01216           }
01217           break;
01218      default:
01219           return 0;
01220      }
01221 }
01222 
01223 int  HitPattern::muonStations(int subdet, int hitType) const {
01224   int stations[4] = { 0,0,0,0 };
01225   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
01226     uint32_t pattern = getHitPattern(i);
01227     if (pattern == 0) break;
01228     if (muonHitFilter(pattern) &&
01229         (subdet  == 0  || int(getSubStructure(pattern)) == subdet) &&
01230         (hitType == -1 || int(getHitType(pattern))      == hitType)) {
01231         stations[getMuonStation(pattern)-1] = 1;
01232     }
01233   }
01234   return stations[0]+stations[1]+stations[2]+stations[3];
01235 }
01236 
01237 int HitPattern::muonStationsWithValidHits() const { return muonStations(0, 0); }
01238 int HitPattern::muonStationsWithBadHits()   const { return muonStations(0, 3); }
01239 int HitPattern::muonStationsWithAnyHits()   const { return muonStations(0,-1); }
01240 int HitPattern::dtStationsWithValidHits()   const { return muonStations(1, 0); }
01241 int HitPattern::dtStationsWithBadHits()     const { return muonStations(1, 3); }
01242 int HitPattern::dtStationsWithAnyHits()     const { return muonStations(1,-1); }
01243 int HitPattern::cscStationsWithValidHits()  const { return muonStations(2, 0); }
01244 int HitPattern::cscStationsWithBadHits()    const { return muonStations(2, 3); }
01245 int HitPattern::cscStationsWithAnyHits()    const { return muonStations(2,-1); }
01246 int HitPattern::rpcStationsWithValidHits()  const { return muonStations(3, 0); }
01247 int HitPattern::rpcStationsWithBadHits()    const { return muonStations(3, 3); }
01248 int HitPattern::rpcStationsWithAnyHits()    const { return muonStations(3,-1); }
01249 
01250 int HitPattern::innermostMuonStationWithHits(int hitType) const {
01251   int ret = 0;
01252   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
01253     uint32_t pattern = getHitPattern(i);
01254     if (pattern == 0) break;
01255     if (muonHitFilter(pattern) &&
01256         (hitType == -1 || int(getHitType(pattern)) == hitType)) {
01257         int stat = getMuonStation(pattern);
01258         if (ret == 0 || stat < ret) ret = stat;
01259     }
01260   }
01261   return ret;
01262 }
01263 
01264 int HitPattern::outermostMuonStationWithHits(int hitType) const {
01265   int ret = 0;
01266   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
01267     uint32_t pattern = getHitPattern(i);
01268     if (pattern == 0) break;
01269     if (muonHitFilter(pattern) &&
01270         (hitType == -1 || int(getHitType(pattern)) == hitType)) {
01271         int stat = getMuonStation(pattern);
01272         if (ret == 0 || stat > ret) ret = stat;
01273     }
01274   }
01275   return ret;
01276 }
01277 
01278 int HitPattern::innermostMuonStationWithValidHits() const { return innermostMuonStationWithHits(0);  }
01279 int HitPattern::innermostMuonStationWithBadHits()   const { return innermostMuonStationWithHits(3);  }
01280 int HitPattern::innermostMuonStationWithAnyHits()   const { return innermostMuonStationWithHits(-1); }
01281 int HitPattern::outermostMuonStationWithValidHits() const { return outermostMuonStationWithHits(0);  }
01282 int HitPattern::outermostMuonStationWithBadHits()   const { return outermostMuonStationWithHits(3);  }
01283 int HitPattern::outermostMuonStationWithAnyHits()   const { return outermostMuonStationWithHits(-1); }
01284 
01285 int HitPattern::numberOfDTStationsWithRPhiView() const {
01286   int stations[4] = { 0,0,0,0 };
01287   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
01288     uint32_t pattern = getHitPattern(i);
01289     if (pattern == 0) break;
01290     if (muonDTHitFilter(pattern) && validHitFilter(pattern) && getDTSuperLayer(pattern) != 2) {
01291         stations[getMuonStation(pattern)-1] = 1;
01292     }
01293   }
01294   return stations[0]+stations[1]+stations[2]+stations[3];
01295 }
01296 
01297 int HitPattern::numberOfDTStationsWithRZView() const {
01298   int stations[4] = { 0,0,0,0 };
01299   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
01300     uint32_t pattern = getHitPattern(i);
01301     if (pattern == 0) break;
01302     if (muonDTHitFilter(pattern) && validHitFilter(pattern) && getDTSuperLayer(pattern) == 2) {
01303         stations[getMuonStation(pattern)-1] = 1;
01304     }
01305   }
01306   return stations[0]+stations[1]+stations[2]+stations[3];
01307 }
01308 
01309 int HitPattern::numberOfDTStationsWithBothViews() const {
01310   int stations[4][2] = { {0,0}, {0,0}, {0,0}, {0,0} };
01311   for (int i=0; i<(PatternSize * 32) / HitSize; i++) {
01312     uint32_t pattern = getHitPattern(i);
01313     if (pattern == 0) break;
01314     if (muonDTHitFilter(pattern) && validHitFilter(pattern)) {
01315         stations[getMuonStation(pattern)-1][getDTSuperLayer(pattern) == 2] = 1;
01316     }
01317   }
01318   return stations[0][0]*stations[0][1] + stations[1][0]*stations[1][1] + stations[2][0]*stations[2][1] + stations[3][0]*stations[3][1];
01319 }
01320 
01321 
01322