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 != matches.end(); ++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] == 0 )
00102 {
00103 segmentLength = det->shape[3];
00104 }
00105
00106 if( ids.insert( rawid ).second &&
00107 ( chamber->detector() != MuonSubdetId::CSC || showEndcap ))
00108 {
00109 pb->setupAddElement( shape, parentList );
00110 }
00111
00112 for( std::vector<reco::MuonSegmentMatch>::const_iterator segment = chamber->segmentMatches.begin(),
00113 segmentEnd = chamber->segmentMatches.end();
00114 segment != segmentEnd; ++segment )
00115 {
00116 float segmentPosition[3] = { segment->x, segment->y, 0.0 };
00117 float segmentDirection[3] = { segment->dXdZ, segment->dYdZ, 0.0 };
00118
00119 float localSegmentInnerPoint[3];
00120 float localSegmentOuterPoint[3];
00121
00122 fireworks::createSegment( chamber->detector(), true,
00123 segmentLength, segmentLimit,
00124 segmentPosition, segmentDirection,
00125 localSegmentInnerPoint, localSegmentOuterPoint );
00126
00127 float globalSegmentInnerPoint[3];
00128 float globalSegmentOuterPoint[3];
00129
00130 geom->localToGlobal( *det, localSegmentInnerPoint, globalSegmentInnerPoint );
00131 geom->localToGlobal( *det, localSegmentOuterPoint, globalSegmentOuterPoint );
00132
00133 segmentSet->AddLine( globalSegmentInnerPoint[0], globalSegmentInnerPoint[1], globalSegmentInnerPoint[2],
00134 globalSegmentOuterPoint[0], globalSegmentOuterPoint[1], globalSegmentOuterPoint[2] );
00135 }
00136 }
00137 }
00138
00139 if( !matches.empty() )
00140 pb->setupAddElement( segmentSet.release(), parentList );
00141 }
00142
00143
00144
00145 bool
00146 buggyMuon( const reco::Muon* muon,
00147 const FWGeometry* geom )
00148 {
00149 if( !muon->standAloneMuon().isAvailable() ||
00150 !muon->standAloneMuon()->extra().isAvailable())
00151 return false;
00152
00153 float localTrajectoryPoint[3];
00154 float globalTrajectoryPoint[3];
00155
00156 const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
00157 for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
00158 chamberEnd = matches.end();
00159 chamber != chamberEnd; ++chamber )
00160 {
00161
00162 localTrajectoryPoint[0] = chamber->x;
00163 localTrajectoryPoint[1] = chamber->y;
00164 localTrajectoryPoint[2] = 0;
00165
00166 unsigned int rawid = chamber->id.rawId();
00167 if( geom->contains( rawid ))
00168 {
00169 geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
00170 double phi = atan2( globalTrajectoryPoint[1], globalTrajectoryPoint[0] );
00171 if( cos( phi - muon->standAloneMuon()->innerPosition().phi()) < 0 )
00172 return true;
00173 }
00174 }
00175 return false;
00176 }
00177
00178 }
00179
00180
00181
00182
00183 FWMuonBuilder::FWMuonBuilder()
00184 {
00185 }
00186
00187 FWMuonBuilder::~FWMuonBuilder()
00188 {
00189 }
00190
00191
00192
00193
00194
00195
00196 void
00197 FWMuonBuilder::calculateField( const reco::Muon& iData, FWMagField* field )
00198 {
00199
00200
00201 if( field->getSource() == FWMagField::kNone )
00202 {
00203 if( fabs( iData.eta() ) > 2.0 || iData.pt() < 3 ) return;
00204 if( iData.innerTrack().isAvailable())
00205 {
00206 double estimate = fw::estimate_field( *( iData.innerTrack()), true );
00207 if( estimate >= 0 ) field->guessField( estimate );
00208 }
00209 if( iData.outerTrack().isAvailable() )
00210 {
00211 double estimate = fw::estimate_field( *( iData.outerTrack()));
00212 if( estimate >= 0 ) field->guessFieldIsOn( estimate > 0.5 );
00213 }
00214 }
00215 }
00216
00217
00218
00219 void
00220 FWMuonBuilder::buildMuon( FWProxyBuilderBase* pb,
00221 const reco::Muon* muon,
00222 TEveElement* tList,
00223 bool showEndcap,
00224 bool tracksOnly )
00225 {
00226 calculateField( *muon, pb->context().getField());
00227
00228 TEveRecTrack recTrack;
00229 recTrack.fBeta = 1.;
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 if( muon->isTrackerMuon() &&
00241 muon->innerTrack().isAvailable() &&
00242 muon->isMatchesValid() &&
00243 !buggyMuon( &*muon, pb->context().getGeom()))
00244 {
00245 TEveTrack* trk = fireworks::prepareTrack( *(muon->innerTrack()),
00246 pb->context().getMuonTrackPropagator(),
00247 getRecoTrajectoryPoints( muon, pb->item()));
00248 trk->MakeTrack();
00249 pb->setupAddElement( trk, tList );
00250 if( ! tracksOnly )
00251 addMatchInformation( &(*muon), pb, tList, showEndcap );
00252 return;
00253 }
00254
00255 if( muon->isGlobalMuon() &&
00256 muon->globalTrack().isAvailable())
00257 {
00258 std::vector<TEveVector> extraPoints;
00259 if( muon->innerTrack().isAvailable() && muon->innerTrack()->extra().isAvailable())
00260 {
00261 extraPoints.push_back( TEveVector( muon->innerTrack()->innerPosition().x(),
00262 muon->innerTrack()->innerPosition().y(),
00263 muon->innerTrack()->innerPosition().z()));
00264 extraPoints.push_back( TEveVector( muon->innerTrack()->outerPosition().x(),
00265 muon->innerTrack()->outerPosition().y(),
00266 muon->innerTrack()->outerPosition().z()));
00267 }
00268 if( muon->outerTrack().isAvailable() && muon->outerTrack()->extra().isAvailable())
00269 {
00270 extraPoints.push_back( TEveVector( muon->outerTrack()->innerPosition().x(),
00271 muon->outerTrack()->innerPosition().y(),
00272 muon->outerTrack()->innerPosition().z()));
00273 extraPoints.push_back( TEveVector( muon->outerTrack()->outerPosition().x(),
00274 muon->outerTrack()->outerPosition().y(),
00275 muon->outerTrack()->outerPosition().z()));
00276 }
00277 TEveTrack* trk = fireworks::prepareTrack( *( muon->globalTrack()),
00278 pb->context().getMuonTrackPropagator(),
00279 extraPoints );
00280 trk->MakeTrack();
00281 pb->setupAddElement( trk, tList );
00282 return;
00283 }
00284
00285 if( muon->innerTrack().isAvailable())
00286 {
00287 TEveTrack* trk = fireworks::prepareTrack( *( muon->innerTrack()), pb->context().getMuonTrackPropagator());
00288 trk->MakeTrack();
00289 pb->setupAddElement( trk, tList );
00290 return;
00291 }
00292
00293 if( muon->outerTrack().isAvailable())
00294 {
00295 TEveTrack* trk = fireworks::prepareTrack( *( muon->outerTrack()), pb->context().getMuonTrackPropagator());
00296 trk->MakeTrack();
00297 pb->setupAddElement( trk, tList );
00298 return;
00299 }
00300
00301
00302
00303 TEveTrack* trk = fireworks::prepareCandidate( *muon, pb->context().getMuonTrackPropagator());
00304 trk->MakeTrack();
00305 pb->setupAddElement( trk, tList );
00306 }