CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoMuon/DetLayers/src/MuRingForwardLayer.cc

Go to the documentation of this file.
00001 
00008 #include <RecoMuon/DetLayers/interface/MuRingForwardLayer.h>
00009 #include <RecoMuon/DetLayers/interface/MuDetRing.h>
00010 #include <Geometry/CommonDetUnit/interface/GeomDet.h>
00011 #include <DataFormats/GeometrySurface/interface/SimpleDiskBounds.h>
00012 #include <TrackingTools/GeomPropagators/interface/Propagator.h>
00013 #include <TrackingTools/PatternTools/interface/MeasurementEstimator.h>
00014 
00015 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00016 
00017 #include "RBorderFinder.h"
00018 #include "GeneralBinFinderInR.h"
00019 
00020 #include <algorithm>
00021 #include <iostream>
00022 #include <vector>
00023 
00024 using namespace std;
00025 
00026 MuRingForwardLayer::MuRingForwardLayer(const vector<const ForwardDetRing*>& rings) :
00027   theRings(rings),
00028   theComponents(theRings.begin(),theRings.end()),
00029   theBinFinder(0),
00030   isOverlapping(false) 
00031 {
00032 
00033   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardLayer";
00034 
00035   // Initial values for R and Z bounds
00036   float theRmin = rings.front()->basicComponents().front()->position().perp(); 
00037   float theRmax = theRmin;
00038   float theZmin = rings.front()->position().z();
00039   float theZmax = theZmin;
00040 
00041   // Cache chamber pointers (the basic components_)
00042   // and find extension in R and Z
00043   for (vector<const ForwardDetRing*>::const_iterator it=rings.begin();
00044        it!=rings.end(); it++) {
00045     vector<const GeomDet*> tmp2 = (*it)->basicComponents();
00046     theBasicComps.insert(theBasicComps.end(),tmp2.begin(),tmp2.end());
00047     
00048     theRmin = min( theRmin, (*it)->specificSurface().innerRadius());
00049     theRmax = max( theRmax, (*it)->specificSurface().outerRadius());
00050     float halfThick = (*it)->surface().bounds().thickness()/2.;
00051     float zCenter = (*it)->surface().position().z();
00052     theZmin = min( theZmin, zCenter-halfThick);
00053     theZmax = max( theZmax, zCenter+halfThick); 
00054   }  
00055   
00056   RBorderFinder bf(theRings);
00057   isOverlapping = bf.isROverlapping();
00058   theBinFinder = new GeneralBinFinderInR<double>(bf);
00059 
00060   // Build surface
00061   
00062   float zPos = (theZmax+theZmin)/2.;
00063   PositionType pos(0.,0.,zPos);
00064   RotationType rot;
00065 
00066   setSurface(new BoundDisk( pos, rot, 
00067                             SimpleDiskBounds( theRmin, theRmax, 
00068                                               theZmin-zPos, theZmax-zPos)));
00069 
00070 
00071    
00072   LogTrace(metname) << "Constructing MuRingForwardLayer: "
00073                     << basicComponents().size() << " Dets " 
00074                     << theRings.size() << " Rings "
00075                     << " Z: " << specificSurface().position().z()
00076                     << " R1: " << specificSurface().innerRadius()
00077                     << " R2: " << specificSurface().outerRadius()
00078                     << " Per.: " << bf.isRPeriodic()
00079                     << " Overl.: " << bf.isROverlapping();
00080 }
00081 
00082 
00083 MuRingForwardLayer::~MuRingForwardLayer(){
00084   delete theBinFinder;
00085   for (vector <const ForwardDetRing*>::iterator i = theRings.begin();
00086        i<theRings.end(); i++) {delete *i;}
00087 }
00088 
00089 
00090 vector<GeometricSearchDet::DetWithState> 
00091 MuRingForwardLayer::compatibleDets(const TrajectoryStateOnSurface& startingState,
00092                                    const Propagator& prop, 
00093                                    const MeasurementEstimator& est) const {
00094   
00095   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardLayer";
00096   vector<DetWithState> result; 
00097   
00098   
00099   LogTrace(metname) << "MuRingForwardLayer::compatibleDets," 
00100                     << " R1 " << specificSurface().innerRadius()
00101                     << " R2: " << specificSurface().outerRadius()
00102                     << " FTS at R: " << startingState.globalPosition().perp();
00103   
00104   pair<bool, TrajectoryStateOnSurface> compat =
00105     compatible(startingState, prop, est);
00106   
00107   if (!compat.first) {
00108     
00109     LogTrace(metname) << "     MuRingForwardLayer::compatibleDets: not compatible"
00110                       << " (should not have been selected!)";
00111     return result;
00112   }
00113   
00114   
00115   TrajectoryStateOnSurface& tsos = compat.second;
00116   
00117   int closest = theBinFinder->binIndex(tsos.globalPosition().perp());
00118   const ForwardDetRing* closestRing = theRings[closest];
00119   
00120   // Check the closest ring
00121   
00122   LogTrace(metname) << "     MuRingForwardLayer::fastCompatibleDets, closestRing: "
00123                     << closest
00124                     << " R1 " << closestRing->specificSurface().innerRadius()
00125                     << " R2: " << closestRing->specificSurface().outerRadius()
00126                     << " FTS R: " << tsos.globalPosition().perp();
00127   if (tsos.hasError()) {
00128     LogTrace(metname)  << " sR: " << sqrt(tsos.localError().positionError().yy())
00129                        << " sX: " << sqrt(tsos.localError().positionError().xx());
00130   }
00131   LogTrace(metname) << endl;
00132    
00133    
00134   result = closestRing->compatibleDets(tsos, prop, est);
00135    
00136   int nclosest = result.size(); int nnextdet=0; // MDEBUG counters
00137    
00138   //FIXME: if closest is not compatible next cannot be either?
00139    
00140   // Use state on layer surface. Note that local coordinates and errors
00141   // are the same on the layer and on all rings surfaces, since 
00142   // all BoundDisks are centered in 0,0 and have the same rotation.
00143   // CAVEAT: if the rings are not at the same Z, the local position and error
00144   // will be "Z-projected" to the rings. This is a fairly good approximation.
00145   // However in this case additional propagation will be done when calling
00146   // compatibleDets.
00147   GlobalPoint startPos = tsos.globalPosition();
00148   LocalPoint nextPos(surface().toLocal(startPos));
00149    
00150   for (unsigned int idet=closest+1; idet < theRings.size(); idet++) {
00151     bool inside = false;
00152     if (tsos.hasError()) {
00153       inside=theRings[idet]->specificSurface().bounds().inside(nextPos,tsos.localError().positionError());
00154     } else {
00155       inside=theRings[idet]->specificSurface().bounds().inside(nextPos);
00156     }
00157     if (inside){
00158       LogTrace(metname) << "     MuRingForwardLayer::fastCompatibleDets:NextRing" << idet
00159                         << " R1 " << theRings[idet]->specificSurface().innerRadius()
00160                         << " R2: " << theRings[idet]->specificSurface().outerRadius()
00161                         << " FTS R " << nextPos.perp();
00162       nnextdet++;      
00163       vector<DetWithState> nextRodDets =
00164         theRings[idet]->compatibleDets(tsos, prop, est);
00165       if (nextRodDets.size()!=0) {
00166         result.insert( result.end(), 
00167                        nextRodDets.begin(), nextRodDets.end());
00168       } else {
00169         break;
00170       }
00171     }
00172   }
00173    
00174   for (int idet=closest-1; idet >= 0; idet--) {
00175     bool inside = false;
00176     if (tsos.hasError()) {
00177       inside=theRings[idet]->specificSurface().bounds().inside(nextPos,tsos.localError().positionError());
00178     } else {
00179       inside=theRings[idet]->specificSurface().bounds().inside(nextPos);
00180     }
00181     if (inside){
00182       LogTrace(metname) << "     MuRingForwardLayer::fastCompatibleDets:PreviousRing:" << idet
00183                         << " R1 " << theRings[idet]->specificSurface().innerRadius()
00184                         << " R2: " << theRings[idet]->specificSurface().outerRadius()
00185                         << " FTS R " << nextPos.perp();
00186       nnextdet++;
00187       vector<DetWithState> nextRodDets =
00188         theRings[idet]->compatibleDets(tsos, prop, est);
00189       if (nextRodDets.size()!=0) {
00190         result.insert( result.end(), 
00191                        nextRodDets.begin(), nextRodDets.end());
00192       } else {
00193         break;
00194       }
00195     }
00196   }
00197    
00198   LogTrace(metname) << "     MuRingForwardLayer::fastCompatibleDets: found: "
00199                     << result.size()
00200                     << " on closest: " << nclosest
00201                     << " # checked rings: " << 1 + nnextdet;
00202    
00203   return result;
00204 }
00205 
00206 
00207 vector<DetGroup> 
00208 MuRingForwardLayer::groupedCompatibleDets( const TrajectoryStateOnSurface& startingState,
00209                                            const Propagator& prop,
00210                                            const MeasurementEstimator& est) const {
00211   // FIXME should return only 1 group 
00212   cout << "dummy implementation of MuRingForwardLayer::groupedCompatibleDets()" << endl;
00213   return vector<DetGroup>();
00214 }
00215 
00216 
00217 bool MuRingForwardLayer::hasGroups() const {
00218   // FIXME : depending on isOverlapping?
00219   return false;
00220 }
00221 
00222 
00223 GeomDetEnumerators::SubDetector MuRingForwardLayer::subDetector() const {
00224   return theBasicComps.front()->subDetector();
00225 }
00226 
00227 const vector<const GeometricSearchDet*> &
00228 MuRingForwardLayer::components() const {
00229   return theComponents;
00230 }