00001
00002
00003
00004
00005
00006
00007
00008 #include "TEveVSDStructs.h"
00009 #include "TEveTrack.h"
00010 #include "TEveStraightLineSet.h"
00011 #include "TEveGeoNode.h"
00012 #include "TGeoArb8.h"
00013
00014 #include "Fireworks/Core/interface/FWEventItem.h"
00015 #include "Fireworks/Core/interface/FWMagField.h"
00016 #include "Fireworks/Core/interface/FWProxyBuilderBase.h"
00017 #include "Fireworks/Core/interface/FWGeometry.h"
00018 #include "Fireworks/Core/interface/fwLog.h"
00019
00020 #include "Fireworks/Candidates/interface/CandidateUtils.h"
00021
00022 #include "Fireworks/Tracks/interface/TrackUtils.h"
00023 #include "Fireworks/Tracks/interface/estimate_field.h"
00024
00025 #include "Fireworks/Muons/interface/FWMuonBuilder.h"
00026 #include "Fireworks/Muons/interface/SegmentUtils.h"
00027
00028 #include "DataFormats/MuonReco/interface/Muon.h"
00029 #include "DataFormats/TrackReco/interface/Track.h"
00030 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00031
00032 namespace {
00033 std::vector<TEveVector> getRecoTrajectoryPoints( const reco::Muon* muon,
00034 const FWEventItem* iItem )
00035 {
00036 std::vector<TEveVector> points;
00037 const FWGeometry* geom = iItem->getGeom();
00038
00039 float localTrajectoryPoint[3];
00040 float globalTrajectoryPoint[3];
00041
00042 const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00043 for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
00044 chamberEnd = matches.end();
00045 chamber != chamberEnd; ++chamber )
00046 {
00047
00048 localTrajectoryPoint[0] = chamber->x;
00049 localTrajectoryPoint[1] = chamber->y;
00050 localTrajectoryPoint[2] = 0;
00051
00052 unsigned int rawid = chamber->id.rawId();
00053 if( geom->contains( rawid ))
00054 {
00055 geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
00056 points.push_back( TEveVector(globalTrajectoryPoint[0],
00057 globalTrajectoryPoint[1],
00058 globalTrajectoryPoint[2] ));
00059 }
00060 }
00061 return points;
00062 }
00063
00064
00065
00066 void addMatchInformation( const reco::Muon* muon,
00067 FWProxyBuilderBase* pb,
00068 TEveElement* parentList,
00069 bool showEndcap )
00070 {
00071 std::set<unsigned int> ids;
00072 const FWGeometry* geom = pb->context().getGeom();
00073
00074 const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00075
00076
00077 std::auto_ptr<TEveStraightLineSet> segmentSet( new TEveStraightLineSet );
00078
00079 segmentSet->SetLineWidth( 4 );
00080
00081 for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
00082 chambersEnd = matches.end();
00083 chamber != chambersEnd; ++chamber )
00084 {
00085 unsigned int rawid = chamber->id.rawId();
00086 float segmentLength = 0.0;
00087 float segmentLimit = 0.0;
00088
00089 if( geom->contains( rawid ))
00090 {
00091 TEveGeoShape* shape = geom->getEveShape( rawid );
00092 shape->SetElementName( "Chamber" );
00093 shape->RefMainTrans().Scale( 0.999, 0.999, 0.999 );
00094
00095 FWGeometry::IdToInfoItr det = geom->find( rawid );
00096 if( det->shape[0] == 1 )
00097 {
00098 segmentLength = det->shape[3];
00099 segmentLimit = det->shape[4];
00100 }
00101 else if( det->shape[0] == 2 )
00102 {
00103 segmentLength = det->shape[3];
00104 }
00105 else
00106 {
00107 const double segmentLength = 15;
00108 fwLog( fwlog::kWarning ) << Form("FWMuonBuilder: unknown shape type in muon chamber with detId=%d. Setting segment length to %.0f cm.\n", rawid, segmentLength);
00109 }
00110
00111 if( ids.insert( rawid ).second &&
00112 ( chamber->detector() != MuonSubdetId::CSC || showEndcap ))
00113 {
00114 pb->setupAddElement( shape, parentList );
00115 }
00116
00117 for( std::vector<reco::MuonSegmentMatch>::const_iterator segment = chamber->segmentMatches.begin(),
00118 segmentEnd = chamber->segmentMatches.end();
00119 segment != segmentEnd; ++segment )
00120 {
00121 float segmentPosition[3] = { segment->x, segment->y, 0.0 };
00122 float segmentDirection[3] = { segment->dXdZ, segment->dYdZ, 0.0 };
00123
00124 float localSegmentInnerPoint[3];
00125 float localSegmentOuterPoint[3];
00126
00127 fireworks::createSegment( chamber->detector(), true,
00128 segmentLength, segmentLimit,
00129 segmentPosition, segmentDirection,
00130 localSegmentInnerPoint, localSegmentOuterPoint );
00131
00132 float globalSegmentInnerPoint[3];
00133 float globalSegmentOuterPoint[3];
00134
00135 geom->localToGlobal( *det, localSegmentInnerPoint, globalSegmentInnerPoint );
00136 geom->localToGlobal( *det, localSegmentOuterPoint, globalSegmentOuterPoint );
00137
00138 segmentSet->AddLine( globalSegmentInnerPoint[0], globalSegmentInnerPoint[1], globalSegmentInnerPoint[2],
00139 globalSegmentOuterPoint[0], globalSegmentOuterPoint[1], globalSegmentOuterPoint[2] );
00140 }
00141 }
00142 }
00143
00144 if( !matches.empty() )
00145 pb->setupAddElement( segmentSet.release(), parentList );
00146 }
00147
00148
00149
00150 bool
00151 buggyMuon( const reco::Muon* muon,
00152 const FWGeometry* geom )
00153 {
00154 if( !muon->standAloneMuon().isAvailable() ||
00155 !muon->standAloneMuon()->extra().isAvailable())
00156 return false;
00157
00158 float localTrajectoryPoint[3];
00159 float globalTrajectoryPoint[3];
00160
00161 const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00162 for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
00163 chamberEnd = matches.end();
00164 chamber != chamberEnd; ++chamber )
00165 {
00166
00167 localTrajectoryPoint[0] = chamber->x;
00168 localTrajectoryPoint[1] = chamber->y;
00169 localTrajectoryPoint[2] = 0;
00170
00171 unsigned int rawid = chamber->id.rawId();
00172 if( geom->contains( rawid ))
00173 {
00174 geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
00175 double phi = atan2( globalTrajectoryPoint[1], globalTrajectoryPoint[0] );
00176 if( cos( phi - muon->standAloneMuon()->innerPosition().phi()) < 0 )
00177 return true;
00178 }
00179 }
00180 return false;
00181 }
00182
00183 }
00184
00185
00186
00187
00188 FWMuonBuilder::FWMuonBuilder()
00189 {
00190 }
00191
00192 FWMuonBuilder::~FWMuonBuilder()
00193 {
00194 }
00195
00196
00197
00198
00199
00200
00201 void
00202 FWMuonBuilder::calculateField( const reco::Muon& iData, FWMagField* field )
00203 {
00204
00205
00206 if( field->getSource() == FWMagField::kNone )
00207 {
00208 if( fabs( iData.eta() ) > 2.0 || iData.pt() < 3 ) return;
00209 if( iData.innerTrack().isAvailable())
00210 {
00211 double estimate = fw::estimate_field( *( iData.innerTrack()), true );
00212 if( estimate >= 0 ) field->guessField( estimate );
00213 }
00214 if( iData.outerTrack().isAvailable() )
00215 {
00216 double estimate = fw::estimate_field( *( iData.outerTrack()));
00217 if( estimate >= 0 ) field->guessFieldIsOn( estimate > 0.5 );
00218 }
00219 }
00220 }
00221
00222
00223
00224 void
00225 FWMuonBuilder::buildMuon( FWProxyBuilderBase* pb,
00226 const reco::Muon* muon,
00227 TEveElement* tList,
00228 bool showEndcap,
00229 bool tracksOnly )
00230 {
00231 calculateField( *muon, pb->context().getField());
00232
00233 TEveRecTrack recTrack;
00234 recTrack.fBeta = 1.;
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 if( muon->isTrackerMuon() &&
00246 muon->innerTrack().isAvailable() &&
00247 muon->isMatchesValid() &&
00248 !buggyMuon( &*muon, pb->context().getGeom()))
00249 {
00250 TEveTrack* trk = fireworks::prepareTrack( *(muon->innerTrack()),
00251 pb->context().getMuonTrackPropagator(),
00252 getRecoTrajectoryPoints( muon, pb->item()));
00253 trk->MakeTrack();
00254 pb->setupAddElement( trk, tList );
00255 if( ! tracksOnly )
00256 addMatchInformation( &(*muon), pb, tList, showEndcap );
00257 return;
00258 }
00259
00260 if( muon->isGlobalMuon() &&
00261 muon->globalTrack().isAvailable())
00262 {
00263 std::vector<TEveVector> extraPoints;
00264 if( muon->innerTrack().isAvailable() && muon->innerTrack()->extra().isAvailable())
00265 {
00266 extraPoints.push_back( TEveVector( muon->innerTrack()->innerPosition().x(),
00267 muon->innerTrack()->innerPosition().y(),
00268 muon->innerTrack()->innerPosition().z()));
00269 extraPoints.push_back( TEveVector( muon->innerTrack()->outerPosition().x(),
00270 muon->innerTrack()->outerPosition().y(),
00271 muon->innerTrack()->outerPosition().z()));
00272 }
00273 if( muon->outerTrack().isAvailable() && muon->outerTrack()->extra().isAvailable())
00274 {
00275 extraPoints.push_back( TEveVector( muon->outerTrack()->innerPosition().x(),
00276 muon->outerTrack()->innerPosition().y(),
00277 muon->outerTrack()->innerPosition().z()));
00278 extraPoints.push_back( TEveVector( muon->outerTrack()->outerPosition().x(),
00279 muon->outerTrack()->outerPosition().y(),
00280 muon->outerTrack()->outerPosition().z()));
00281 }
00282 TEveTrack* trk = fireworks::prepareTrack( *( muon->globalTrack()),
00283 pb->context().getMuonTrackPropagator(),
00284 extraPoints );
00285 trk->MakeTrack();
00286 pb->setupAddElement( trk, tList );
00287 return;
00288 }
00289
00290 if( muon->innerTrack().isAvailable())
00291 {
00292 TEveTrack* trk = fireworks::prepareTrack( *( muon->innerTrack()), pb->context().getMuonTrackPropagator());
00293 trk->MakeTrack();
00294 pb->setupAddElement( trk, tList );
00295 return;
00296 }
00297
00298 if( muon->outerTrack().isAvailable())
00299 {
00300 TEveTrack* trk = fireworks::prepareTrack( *( muon->outerTrack()), pb->context().getMuonTrackPropagator());
00301 trk->MakeTrack();
00302 pb->setupAddElement( trk, tList );
00303 return;
00304 }
00305
00306
00307
00308 TEveTrack* trk = fireworks::prepareCandidate( *muon, pb->context().getMuonTrackPropagator());
00309 trk->MakeTrack();
00310 pb->setupAddElement( trk, tList );
00311 }