CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoMuon/DetLayers/src/MuRodBarrelLayer.cc

Go to the documentation of this file.
00001 
00009 #include "RecoMuon/DetLayers/interface/MuRodBarrelLayer.h"
00010 #include "RecoMuon/DetLayers/interface/MuDetRod.h"
00011 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00012 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
00013 #include "TrackingTools/PatternTools/interface/MeasurementEstimator.h"
00014 #include "Utilities/BinningTools/interface/PeriodicBinFinderInPhi.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 
00017 #include <Utilities/General/interface/precomputed_value_sort.h>
00018 #include "DataFormats/GeometrySurface/interface/GeometricSorting.h"
00019 
00020 #include "GeneralBinFinderInPhi.h"
00021 #include "PhiBorderFinder.h"
00022 
00023 #include <algorithm>
00024 #include <iostream>
00025 
00026 using namespace std;
00027 
00028 MuRodBarrelLayer::MuRodBarrelLayer(vector<const DetRod*>& rods) :
00029   theRods(rods),
00030   theBinFinder(0),
00031   isOverlapping(false)
00032 {
00033   // Sort rods in phi
00034   precomputed_value_sort(theRods.begin(),theRods.end(), geomsort::ExtractPhi<DetRod,float>());
00035 
00036   theComponents.reserve(theRods.size());
00037   std::copy(theRods.begin(),theRods.end(),back_inserter(theComponents));
00038 
00039   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRodBarrelLayer";
00040 
00041   // Cache chamber pointers (the basic components_)
00042   for (vector<const DetRod*>::const_iterator it=rods.begin();
00043        it!=rods.end(); it++) {
00044     vector<const GeomDet*> tmp2 = (*it)->basicComponents();
00045     theBasicComps.insert(theBasicComps.end(),tmp2.begin(),tmp2.end());
00046   }
00047 
00048   // Initialize the binfinder
00049   PhiBorderFinder bf(theRods);
00050   isOverlapping = bf.isPhiOverlapping();
00051 
00052   if ( bf.isPhiPeriodic() ) { 
00053     theBinFinder = new PeriodicBinFinderInPhi<double>
00054     (theRods.front()->position().phi(),theRods.size());
00055   } else {
00056     theBinFinder = new GeneralBinFinderInPhi<double>(bf);
00057   }
00058 
00059   // Compute the layer's surface and bounds (from the components())
00060   BarrelDetLayer::initialize(); 
00061   
00062   LogTrace(metname) << "Constructing MuRodBarrelLayer: "
00063                     << basicComponents().size() << " Dets " 
00064                     << theRods.size() << " Rods "
00065                     << " R: " << specificSurface().radius()
00066                     << " Per.: " << bf.isPhiPeriodic()
00067                     << " Overl.: " << isOverlapping;
00068 }
00069 
00070 
00071 MuRodBarrelLayer::~MuRodBarrelLayer() {
00072   delete theBinFinder;
00073   for (vector <const DetRod*>::iterator i = theRods.begin();
00074        i<theRods.end(); i++) {delete *i;}
00075 }
00076 
00077 
00078 vector<GeometricSearchDet::DetWithState> 
00079 MuRodBarrelLayer::compatibleDets(const TrajectoryStateOnSurface& startingState,
00080                                  const Propagator& prop, 
00081                                  const MeasurementEstimator& est) const {
00082 
00083   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRodBarrelLayer";
00084   vector<DetWithState> result; 
00085 
00086  
00087   LogTrace(metname) << "MuRodBarrelLayer::compatibleDets, Cyl R: " 
00088                     << specificSurface().radius()
00089                     << " TSOS at R= " << startingState.globalPosition().perp()
00090                     << " phi= " << startingState.globalPosition().phi();
00091 
00092   pair<bool, TrajectoryStateOnSurface> compat =
00093     compatible(startingState, prop, est);
00094   if (!compat.first) {
00095     LogTrace(metname) << "     MuRodBarrelLayer::compatibleDets: not compatible"
00096                       << " (should not have been selected!)";
00097     return vector<DetWithState>();
00098   } 
00099 
00100   TrajectoryStateOnSurface& tsos = compat.second;
00101 
00102   LogTrace(metname) << "     MuRodBarrelLayer::compatibleDets, reached layer at: "
00103                     << tsos.globalPosition()
00104                     << " R = " << tsos.globalPosition().perp()
00105                     << " phi = " << tsos.globalPosition().phi();
00106 
00107   int closest = theBinFinder->binIndex(tsos.globalPosition().phi());
00108   const DetRod* closestRod = theRods[closest];
00109 
00110   // Check the closest rod
00111   LogTrace(metname) << "     MuRodBarrelLayer::compatibleDets, closestRod: " << closest
00112                     << " phi : " << closestRod->surface().position().phi()
00113                     << " FTS phi: " << tsos.globalPosition().phi();
00114   
00115   result = closestRod->compatibleDets(tsos, prop, est);
00116 
00117   int nclosest = result.size(); // Debug counter
00118 
00119   bool checknext = false ;
00120   double dist;
00121 
00122   if (!result.empty()) { 
00123     // Check if the track go outside closest rod, then look for closest. 
00124     TrajectoryStateOnSurface& predictedState = result.front().second;
00125     float xErr = xError(predictedState, est);
00126     float halfWid = closestRod->surface().bounds().width()/2.;
00127     dist = predictedState.localPosition().x();
00128 
00129     // If the layer is overlapping, additionally reduce halfWid by 10%
00130     // to account for overlap.
00131     // FIXME: should we account for the real amount of overlap?
00132     if (isOverlapping) halfWid *= 0.9;
00133 
00134     if (fabs(dist) + xErr > halfWid) {
00135       checknext = true;
00136     }
00137   } else { // Rod is not compatible
00138     //FIXME: Usually next cannot be either. Implement proper logic.
00139     // (in general at least one rod should be when this method is called by
00140     // compatibleDets() which calls compatible())
00141     checknext = true;
00142     
00143     // Look for the next-to closest in phi.
00144     // Note Geom::Phi, subtraction is pi-border-safe
00145     if ( tsos.globalPosition().phi()-closestRod->surface().position().phi()>0.)
00146     {
00147       dist = -1.;
00148     } else {
00149       dist = +1.;
00150     }
00151 
00152     
00153     LogTrace(metname) << "     MuRodBarrelLayer::fastCompatibleDets, none on closest rod!";
00154   }
00155 
00156   if (checknext) {
00157     int next;
00158     if (dist<0.) next = closest+1;
00159     else next = closest-1;
00160 
00161     next = theBinFinder->binIndex(next); // Bin Periodicity
00162     const DetRod* nextRod = theRods[next];
00163 
00164   
00165     LogTrace(metname) << "     MuRodBarrelLayer::fastCompatibleDets, next-to closest"
00166                       << " rod: " << next << " dist " << dist
00167                       << " phi : " << nextRod->surface().position().phi()
00168                       << " FTS phi: " << tsos.globalPosition().phi();   
00169     
00170     vector<DetWithState> nextRodDets =
00171       nextRod->compatibleDets(tsos, prop, est);
00172     result.insert(result.end(), 
00173                   nextRodDets.begin(), nextRodDets.end());
00174   }
00175   
00176   
00177    LogTrace(metname) << "     MuRodBarrelLayer::fastCompatibleDets: found: "
00178                      << result.size()
00179                      << " on closest: " << nclosest
00180                      << " # checked rods: " << 1 + int(checknext);
00181   
00182   return result;
00183 }
00184 
00185 
00186 vector<DetGroup> 
00187 MuRodBarrelLayer::groupedCompatibleDets( const TrajectoryStateOnSurface& startingState,
00188                                          const Propagator& prop,
00189                                          const MeasurementEstimator& est) const {
00190   // FIXME should return only 1 group 
00191   cout << "dummy implementation of MuRodBarrelLayer::groupedCompatibleDets()" << endl;
00192   return vector<DetGroup>();
00193 }
00194 
00195 
00196 bool MuRodBarrelLayer::hasGroups() const {
00197   // FIXME : depending on isOverlapping?
00198   return false;
00199 }
00200 
00201 
00202 GeomDetEnumerators::SubDetector MuRodBarrelLayer::subDetector() const {
00203   return theBasicComps.front()->subDetector();
00204 }
00205 
00206 const vector<const GeometricSearchDet*>&
00207 MuRodBarrelLayer::components() const {
00208   return theComponents;
00209 }
00210 
00211 float MuRodBarrelLayer::xError(const TrajectoryStateOnSurface& tsos,
00212                                const MeasurementEstimator& est) const {
00213   const float nSigmas = 3.f;
00214   if (tsos.hasError()) {
00215     return nSigmas * sqrt(tsos.localError().positionError().xx());
00216   }
00217   else return nSigmas * 0.5;
00218 }