CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoMuon/DetLayers/src/MuRingForwardDoubleLayer.cc

Go to the documentation of this file.
00001 
00008 #include <RecoMuon/DetLayers/interface/MuRingForwardDoubleLayer.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 <algorithm>
00018 #include <iostream>
00019 #include <vector>
00020 
00021 using namespace std;
00022 
00023 MuRingForwardDoubleLayer::MuRingForwardDoubleLayer(const vector<const ForwardDetRing*>& frontRings,
00024                                        const vector<const ForwardDetRing*>& backRings) :
00025 
00026   theFrontLayer(frontRings),
00027   theBackLayer(backRings),
00028   theRings(frontRings), // add back later
00029   theComponents(),
00030   theBasicComponents()
00031 {
00032 
00033   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardDoubleLayer";
00034 
00035   theRings.insert(theRings.end(), backRings.begin(), backRings.end());
00036   theComponents = std::vector <const GeometricSearchDet*>(theRings.begin(), theRings.end());
00037 
00038   // Cache chamber pointers (the basic components_)
00039   // and find extension in R and Z
00040   for (vector<const ForwardDetRing*>::const_iterator it=theRings.begin();
00041        it!=theRings.end(); it++) {
00042     vector<const GeomDet*> tmp2 = (*it)->basicComponents();
00043     theBasicComponents.insert(theBasicComponents.end(),tmp2.begin(),tmp2.end());
00044   }  
00045   
00046   setSurface(computeSurface());
00047    
00048   LogTrace(metname) << "Constructing MuRingForwardDoubleLayer: "
00049                     << basicComponents().size() << " Dets " 
00050                     << theRings.size() << " Rings "
00051                     << " Z: " << specificSurface().position().z()
00052                     << " R1: " << specificSurface().innerRadius()
00053                     << " R2: " << specificSurface().outerRadius();
00054 
00055   selfTest();
00056 }
00057 
00058 
00059 BoundDisk * MuRingForwardDoubleLayer::computeSurface() 
00060 {
00061   const BoundDisk & frontDisk = theFrontLayer.specificSurface();
00062   const BoundDisk & backDisk  = theBackLayer.specificSurface();
00063 
00064   float rmin = min( frontDisk.innerRadius(), backDisk.innerRadius() );
00065   float rmax = max( frontDisk.outerRadius(), backDisk.outerRadius() );
00066   float zmin = frontDisk.position().z();
00067   float halfThickness = frontDisk.bounds().thickness()/2.;
00068   zmin = (zmin > 0) ? zmin-halfThickness : zmin+halfThickness;
00069   float zmax = backDisk.position().z();
00070   halfThickness = backDisk.bounds().thickness()/2.;
00071   zmax = (zmax > 0) ? zmax+halfThickness : zmax-halfThickness;
00072   float zPos = (zmax+zmin)/2.;
00073   PositionType pos(0.,0.,zPos);
00074   RotationType rot;
00075 
00076   return new BoundDisk( pos, rot,
00077                         SimpleDiskBounds( rmin, rmax,
00078                                           zmin-zPos, zmax-zPos));
00079 }
00080 
00081 
00082 bool MuRingForwardDoubleLayer::isInsideOut(const TrajectoryStateOnSurface& tsos) const 
00083 {
00084   return tsos.globalPosition().basicVector().dot(tsos.globalMomentum().basicVector()) > 0;
00085 }
00086 
00087   
00088 
00089 std::pair<bool, TrajectoryStateOnSurface>
00090 MuRingForwardDoubleLayer::compatible(const TrajectoryStateOnSurface& startingState, const Propagator& prop,
00091                                      const MeasurementEstimator& est) const
00092 {
00093   // mostly copied from ForwardDetLayer, except propagates to closest surface,
00094   // not to center
00095   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardDoubleLayer";
00096 
00097   bool insideOut = isInsideOut(startingState);
00098   const MuRingForwardLayer & closerLayer = (insideOut) ? theFrontLayer : theBackLayer;
00099   LogTrace("Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardDoubleLayer") 
00100     << "MuRingForwardDoubleLayer::compatible is assuming inside-out direction: "<< insideOut;
00101 
00102 
00103   //std::pair<bool, TrajectoryStateOnSurface> result 
00104   //  = closerLayer.compatible(startingState, prop, est);
00105   //if(!result.first)
00106   // {
00107   //  result = furtherLayer.compatible(startingState, prop, est);
00108   //}
00109 
00110 
00111   TrajectoryStateOnSurface myState = prop.propagate( startingState, closerLayer.specificSurface());
00112   if ( !myState.isValid()) return make_pair( false, myState);
00113 
00114   // take into account the thickness of the layer
00115   float deltaR = surface().bounds().thickness()/2. *
00116     fabs( tan( myState.localDirection().theta()));
00117 
00118   // take into account the error on the predicted state
00119   const float nSigma = 3.;
00120   if (myState.hasError()) {
00121     LocalError err = myState.localError().positionError();
00122     // ignore correlation for the moment...
00123     deltaR += nSigma * sqrt(err.xx() + err.yy());
00124   }
00125 
00126   float zPos = (zmax()+zmin())/2.;
00127   SimpleDiskBounds tmp( rmin()-deltaR, rmax()+deltaR,
00128                         zmin()-zPos, zmax()-zPos);
00129 
00130   return make_pair( tmp.inside(myState.localPosition()), myState);
00131 }
00132 
00133 
00134 vector<GeometricSearchDet::DetWithState> 
00135 MuRingForwardDoubleLayer::compatibleDets(const TrajectoryStateOnSurface& startingState,
00136                                    const Propagator& prop, 
00137                                    const MeasurementEstimator& est) const {
00138   vector<DetWithState> result;
00139   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardDoubleLayer";
00140   pair<bool, TrajectoryStateOnSurface> compat =
00141     compatible(startingState, prop, est);
00142 
00143   if (!compat.first) {
00144 
00145     LogTrace(metname) << "     MuRingForwardDoubleLayer::compatibleDets: not compatible"
00146                       << " (should not have been selected!)";
00147     return result;
00148   }
00149 
00150 
00151   TrajectoryStateOnSurface& tsos = compat.second;
00152 
00153    // standard implementation of compatibleDets() for class which have 
00154   // groupedCompatibleDets implemented.
00155   // This code should be moved in a common place intead of being 
00156   // copied many times.
00157   vector<DetGroup> vectorGroups = groupedCompatibleDets(tsos,prop,est);
00158   for(vector<DetGroup>::const_iterator itDG=vectorGroups.begin();
00159       itDG!=vectorGroups.end();itDG++){
00160     for(vector<DetGroupElement>::const_iterator itDGE=itDG->begin();
00161         itDGE!=itDG->end();itDGE++){
00162       result.push_back(DetWithState(itDGE->det(),itDGE->trajectoryState()));
00163     }
00164   }
00165   return result;  
00166 } 
00167 
00168 
00169 vector<DetGroup>
00170 MuRingForwardDoubleLayer::groupedCompatibleDets( const TrajectoryStateOnSurface& startingState,
00171                                            const Propagator& prop,
00172                                            const MeasurementEstimator& est) const {
00173 
00174   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardDoubleLayer";
00175   vector<GeometricSearchDet::DetWithState> detWithStates1, detWithStates2;
00176   
00177   LogTrace(metname) << "groupedCompatibleDets are currently given always in inside-out order";
00178   // this should be fixed either in RecoMuon/MeasurementDet/MuonDetLayerMeasurements or
00179   // RecoMuon/DetLayers/MuRingForwardDoubleLayer
00180   // and removed the reverse operation in StandAloneMuonFilter::findBestMeasurements
00181 
00182   detWithStates1 = theFrontLayer.compatibleDets(startingState, prop, est);
00183   detWithStates2 = theBackLayer.compatibleDets(startingState, prop, est);    
00184   
00185   vector<DetGroup> result;
00186   if(!detWithStates1.empty()) result.push_back( DetGroup(detWithStates1) );
00187   if(!detWithStates2.empty()) result.push_back( DetGroup(detWithStates2) );
00188   LogTrace(metname) << "DoubleLayer Compatible dets: " << result.size();
00189   return result;
00190 }
00191 
00192 
00193 bool MuRingForwardDoubleLayer::isCrack(const GlobalPoint & gp) const
00194 {
00195   const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|MuRingForwardDoubleLayer";
00196   // approximate
00197   bool result = false;
00198   double r = gp.perp();
00199   const std::vector<const ForwardDetRing*>& backRings = theBackLayer.rings(); 
00200   if(backRings.size() > 1)
00201   {
00202     const MuDetRing * innerRing = dynamic_cast<const MuDetRing *>(backRings[0]);
00203     const MuDetRing * outerRing = dynamic_cast<const MuDetRing *>(backRings[1]);
00204     assert(innerRing && outerRing);
00205     float crackInner = innerRing->specificSurface().outerRadius();
00206     float crackOuter = outerRing->specificSurface().innerRadius();
00207     LogTrace(metname)  << "In a crack:" << crackInner << " " << r << " " << crackOuter;
00208     if(r > crackInner && r < crackOuter) return true;
00209   }
00210   // non-overlapping rings
00211   //double phi = gp.phi().degrees();
00212   return result;
00213 }
00214 
00215 
00216 void MuRingForwardDoubleLayer::selfTest() const
00217 {
00218   const std::vector<const GeomDet*>& frontDets = theFrontLayer.basicComponents();
00219   const std::vector<const GeomDet*>& backDets = theBackLayer.basicComponents();
00220 
00221   std::vector<const GeomDet*>::const_iterator frontItr = frontDets.begin(),
00222                                               lastFront = frontDets.end(),
00223                                               backItr = backDets.begin(),
00224                                               lastBack = backDets.end();
00225 
00226   // test that each front z is less than each back z
00227   for( ; frontItr != lastFront; ++frontItr)
00228   {
00229     float frontz = fabs( (**frontItr).surface().position().z() );
00230     for( ; backItr != lastBack; ++backItr)
00231     {
00232       float backz = fabs( (**backItr).surface().position().z() );
00233       assert(frontz < backz);
00234     }
00235   }
00236 }
00237 
00238