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),
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
00039
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
00094
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
00104
00105
00106
00107
00108
00109
00110
00111 TrajectoryStateOnSurface myState = prop.propagate( startingState, closerLayer.specificSurface());
00112 if ( !myState.isValid()) return make_pair( false, myState);
00113
00114
00115 float deltaR = surface().bounds().thickness()/2. *
00116 fabs( tan( myState.localDirection().theta()));
00117
00118
00119 const float nSigma = 3.;
00120 if (myState.hasError()) {
00121 LocalError err = myState.localError().positionError();
00122
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
00154
00155
00156
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
00179
00180
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
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
00211
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
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