00001
00002
00003
00004 #include "Relations/RelationWeighted1D.h"
00005
00006
00007 #include "Event/EventHeader.h"
00008
00009
00010 #include "Event/TrackKeys.h"
00011
00012
00013 #include "Event/OTMeasurement.h"
00014 #include "Event/ITMeasurement.h"
00015 #include "Event/VeloRMeasurement.h"
00016 #include "Event/VeloPhiMeasurement.h"
00017
00018
00019 #include "TrueTracksCreator.h"
00020
00021 static const AlgFactory<TrueTracksCreator> s_factory;
00022 const IAlgFactory& TrueTracksCreatorFactory = s_factory;
00023
00035
00036
00037
00038 TrueTracksCreator::TrueTracksCreator( const std::string& name,
00039 ISvcLocator* pSvcLocator )
00040 : GaudiAlgorithm( name, pSvcLocator )
00041 , m_otTim2MCHit(0)
00042 , m_itClus2MCP(0)
00043 , m_veloClus2MCP(0)
00044 , m_otTracker(0)
00045 , m_itTracker(0)
00046 , m_velo(0)
00047 , m_trackSelector(0)
00048 , m_stateCreator(0)
00049
00050
00051
00052 {
00054 declareProperty( "AddOTTimes", m_addOTTimes = true );
00055 declareProperty( "AddITClusters", m_addITClusters = true );
00056 declareProperty( "AddVeloClusters", m_addVeloClusters = true );
00057 declareProperty( "InitState", m_initState = true );
00058 declareProperty( "FitTracks", m_fitTracks = true );
00059 declareProperty( "FitUpstream", m_upstream = true );
00060 declareProperty( "TrueStatesAtMeasZPos", m_trueStatesAtMeas = false );
00061 declareProperty( "TracksTESPath",
00062 m_tracksTESPath = "Rec/Track/Ideal" );
00063 declareProperty( "RelationTable",
00064 m_relationTable = "Rec/Relations/IdealTr2MCP" );
00065 declareProperty( "OTGeometryPath",
00066 m_otTrackerPath = DeOTDetectorLocation::Default );
00067 declareProperty( "ITGeometryPath",
00068 m_itTrackerPath = DeSTDetectorLocation::Default );
00069 declareProperty( "VeloGeometryPath",
00070 m_veloPath = "/dd/Structure/LHCb/Velo" );
00071 declareProperty( "MinNHits", m_minNHits = 6 );
00072 declareProperty( "ErrorX2", m_errorX2 = 4.0 );
00073 declareProperty( "ErrorY2", m_errorY2 = 400.0 );
00074 declareProperty( "ErrorTx2", m_errorTx2 = 6.e-5 );
00075 declareProperty( "ErrorTy2", m_errorTy2 = 1.e-4 );
00076 declareProperty( "ErrorP", m_errorP = 0.15 );
00077 }
00078
00079
00080
00081
00082 TrueTracksCreator::~TrueTracksCreator() {}
00083
00084
00085
00086
00087 StatusCode TrueTracksCreator::initialize()
00088 {
00089 StatusCode sc = GaudiAlgorithm::initialize();
00090
00091
00092
00093 sc = toolSvc() -> retrieveTool( "OTTime2MCHitAsct", m_otTim2MCHit );
00094 if ( !sc ) { return sc; }
00095 sc = toolSvc() -> retrieveTool( "ITCluster2MCParticleAsct", m_itClus2MCP );
00096 if ( !sc ) { return sc; }
00097 sc = toolSvc() -> retrieveTool( "VeloCluster2MCParticleAsct", m_veloClus2MCP );
00098 if ( !sc ) { return sc; }
00099 debug() << "Associators retrieved." << endreq;
00100
00101
00102
00103 m_otTracker = getDet<DeOTDetector>( m_otTrackerPath );
00104
00105 m_itTracker = getDet<DeSTDetector>( m_itTrackerPath );
00106
00107 m_velo = getDet<DeVelo>( m_veloPath );
00108 debug() << "Geometry read in." << endreq;
00109
00110
00111 m_trackSelector = tool<ITrackSelector>( "TrackSelector" );
00112
00113
00114 m_stateCreator = tool<IStateCreator>( "TrueStateCreator" );
00115
00116 if ( m_fitTracks ) {
00117 always() << "Fitting part of algorithm not yet done!" << endreq;
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 }
00131
00132 info() << "initialized succesfully" << endreq;
00133
00134 return StatusCode::SUCCESS;
00135 }
00136
00137
00138
00139
00140 StatusCode TrueTracksCreator::execute()
00141 {
00142 debug() << "==> Execute" << endreq;
00143
00144
00145 EventHeader* evtHdr = get<EventHeader>( EventHeaderLocation::Default );
00146 debug() << "Run " << evtHdr -> runNum()
00147 << "\tEvent " << evtHdr -> evtNum() << endreq;
00148
00149
00150 MCParticles* particles = get<MCParticles>( MCParticleLocation::Default );
00151
00153 OTTimes* otTimes = get<OTTimes>( OTTimeLocation::Default );
00154 debug() << "- retrieved " << otTimes -> size() << " OTTimes." << endreq;
00155
00156
00157 Tracks* tracksCont = new Tracks();
00158
00159
00160 typedef RelationWeighted1D<Track,MCParticle,double> Table;
00161 Table* table = new Table();
00162 StatusCode sc = eventSvc() -> registerObject( m_relationTable, table );
00163 if( sc.isFailure() ) {
00164 error() << "Unable to register the relation container = "
00165 << m_relationTable << " status = " << sc << endreq;
00166 return sc ;
00167 }
00168 else {
00169 verbose() << "Relations container " << m_relationTable
00170 << " registered" << endreq;
00171 }
00172
00173 debug() << "Starting loop over the "
00174 << particles -> size() << " MCParticles ... " << endreq;
00175
00176
00177
00178 MCParticles::const_iterator iPart;
00179 for ( iPart = particles->begin(); particles->end() != iPart; ++iPart ) {
00180 MCParticle* mcParticle = *iPart;
00181 debug() << endreq
00182 << "- MCParticle of type "
00183 << m_trackSelector -> trackType( mcParticle )
00184 << " , (key # " << mcParticle -> key() << ")" << endreq
00185 << " - momentum = " << mcParticle -> momentum() << " MeV" << endreq
00186 << " - P = " << mcParticle -> momentum().vect().mag()
00187 << " MeV" <<endreq
00188 << " - charge = "
00189 << ( mcParticle -> particleID().threeCharge() / 3 ) << endreq;
00190 if ( m_trackSelector -> select( mcParticle ) ) {
00191 debug() << endreq
00192 << "Selected MCParticle of type "
00193 << m_trackSelector -> trackType( mcParticle )
00194 << " , (key # " << mcParticle -> key() << ")" << endreq
00195 << " - momentum = " << mcParticle -> momentum() << " MeV" <<endreq
00196 << " - P = " << mcParticle -> momentum().vect().mag()
00197 << " MeV" <<endreq
00198 << " - charge = "
00199 << ( mcParticle -> particleID().threeCharge() / 3 ) << endreq;
00200
00201
00202
00203 Track* track = new Track();
00204
00205 m_trackSelector -> setTrackType( mcParticle, track );
00206
00207
00208 if ( TrackKeys::Velo == track -> type() ) {
00209 const double pz = mcParticle -> momentum().pz();
00210 if ( pz < 0.0 ) track -> setFlag( TrackKeys::Backward, true );
00211 }
00212
00213
00214
00215 if ( m_addVeloClusters == true ) {
00216 debug() << "... adding VeloXxxClusters" << endreq;
00217 sc = addVeloClusters( mcParticle, track );
00218 if ( sc.isFailure() ) {
00219 error() << "Unable to add velo R clusters" << endreq;
00220 return StatusCode::FAILURE;
00221 }
00222 }
00223
00224
00225
00226 if ( m_addITClusters == true ) {
00227 debug() << "... adding ITClusters" << endreq;
00228 sc = addITClusters( mcParticle, track );
00229 if ( sc.isFailure() ) {
00230 error() << "Unable to add inner tracker clusters" << endreq;
00231 return StatusCode::FAILURE;
00232 }
00233 }
00234
00235
00236
00237 if ( m_addOTTimes == true && otTimes != 0 ) {
00238 debug() << "... adding OTTimes" << endreq;
00239 sc = addOTTimes( otTimes, mcParticle, track );
00240 if ( sc.isFailure() ) {
00241 error() << "Unable to add outer tracker OTTimes" << endreq;
00242 return StatusCode::FAILURE;
00243 }
00244 }
00245
00246
00247
00248 if ( (int) track -> nMeasurements() < m_minNHits) {
00249 debug() << " -> track deleted. Had only " << track -> nMeasurements()
00250 << " hits" << endreq;
00251 delete track;
00252 continue;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 if ( m_initState ) {
00262 if ( m_upstream ) {
00263 std::vector<Measurement*>::const_reverse_iterator rbeginM =
00264 track -> measurements().rbegin();
00265 sc = this -> initializeState( (*rbeginM)->z(),
00266 track, mcParticle );
00267 }
00268 else {
00269 std::vector<Measurement*>::const_iterator beginM =
00270 track -> measurements().begin();
00271 sc = this -> initializeState( (*beginM)->z(),
00272 track, mcParticle );
00273 }
00274 if ( !sc.isSuccess() ) {
00275 delete track;
00276 continue;
00277 }
00278 }
00279
00280
00281
00282 track -> setStatus( TrackKeys::PatRecMeas );
00283 track -> setFlag( TrackKeys::Unique, true );
00284 track -> setHistory( TrackKeys::TrackIdealPR );
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 if ( m_trueStatesAtMeas ) {
00311 deleteStates( track );
00312 sc = StatusCode::SUCCESS;
00313 std::vector<Measurement*>::const_iterator iMeas =
00314 track -> measurements().begin();
00315 std::vector<Measurement*>::const_iterator endM =
00316 track -> measurements().end();
00317
00318 while ( sc.isSuccess() && iMeas != endM ) {
00319 State* tempState;
00320 sc = m_stateCreator -> createState( mcParticle,
00321 (*iMeas)->z(),
00322 tempState );
00323 if ( sc.isSuccess() ) track -> addToStates( *tempState );
00324 else delete tempState;
00325 ++iMeas;
00326 }
00327 if ( sc.isFailure() ) {
00328 delete track;
00329 continue;
00330 }
00331 }
00332
00333
00334
00335 tracksCont -> add( track );
00336 table -> relate( track, mcParticle, 1.0 );
00337
00338
00339
00340 debug()
00341 << "-> Track with key # " << track -> key() << endreq
00342 << " * charge = " << track -> charge() << endreq
00343 << " * is Invalid = " << track -> checkFlag( TrackKeys::Invalid ) << endreq
00344 << " * is Unique = " << track -> checkFlag( TrackKeys::Unique ) << endreq
00345 << " * is of type = " << track -> type() << endreq
00346 << " * is Backward = " << track -> checkFlag( TrackKeys::Backward ) << endreq
00347 << " * # measurements = " << track -> nMeasurements() << endreq;
00348
00349
00350 const std::vector<Measurement*>& meas = track -> measurements();
00351 for ( std::vector<Measurement*>::const_iterator itMeas = meas.begin();
00352 itMeas != meas.end(); itMeas++ ) {
00353 debug() << " - measurement of type " << (*itMeas) -> type() << endreq
00354 << " - z = " << (*itMeas) -> z() << " mm" << endreq
00355 << " - LHCbID = " << (*itMeas) -> lhcbID() << endreq;
00356
00357 if ( (*itMeas) -> lhcbID().isOT() ) {
00358 debug() << " - XxxChannelID = " << (*itMeas) -> lhcbID().otID() << endreq;
00359 }
00360 else if ( (*itMeas) -> lhcbID().isST() ) {
00361 debug() << " - XxxChannelID = " << (*itMeas) -> lhcbID().stID() << endreq;
00362 }
00363 else if ( (*itMeas) -> lhcbID().isVelo() ) {
00364 debug() << " - XxxChannelID = " << (*itMeas) -> lhcbID().veloID() << endreq;
00365 }
00366 }
00367
00368 }
00369 }
00370
00371
00372
00373 sc = registerTracks( tracksCont );
00374 if( sc.isFailure() ) return sc;
00375
00376 debug() << "Created " << tracksCont -> size() << " tracks." << endreq;
00377
00378 return StatusCode::SUCCESS;
00379 }
00380
00381
00382
00383
00384 StatusCode TrueTracksCreator::finalize()
00385 {
00386 debug() << "==> Finalize" << endreq;
00387
00388
00389
00390 if ( m_veloClus2MCP ) toolSvc()->releaseTool( m_veloClus2MCP );
00391 if ( m_itClus2MCP ) toolSvc()->releaseTool( m_itClus2MCP );
00392 if ( m_otTim2MCHit ) toolSvc()->releaseTool( m_otTim2MCHit );
00393 if ( m_trackSelector ) toolSvc()->releaseTool( m_trackSelector );
00394
00395
00396
00397
00398
00399 return GaudiAlgorithm::finalize();
00400 }
00401
00402
00403
00404
00405 StatusCode TrueTracksCreator::addOTTimes( OTTimes* times,
00406 MCParticle* mcPart,
00407 Track* track )
00408 {
00409 unsigned int nOTMeas = 0;
00410
00411
00412 OTTimes::const_iterator itOTTime = times -> begin();
00413 while ( itOTTime != times->end() ) {
00414 OTTime* aTime = *itOTTime;
00415
00416
00417 OTTime2MCHitAsct::ToRange range = m_otTim2MCHit -> rangeFrom(aTime);
00418 OTTime2MCHitAsct::ToIterator iTim;
00419 for ( iTim = range.begin(); iTim != range.end(); ++iTim ) {
00420 MCHit* aMCHit = iTim -> to();
00421 MCParticle* aParticle = aMCHit -> mcParticle();
00422 if ( aParticle == mcPart ) {
00423
00424 const OTChannelID channel = aTime -> channel();
00425 DeOTModule* module = m_otTracker -> module( channel );
00426 const HepPoint3D entryP = aMCHit -> entry();
00427 const HepPoint3D exitP = aMCHit -> exit();
00428 double deltaZ = exitP.z() - entryP.z();
00429 if (0.0 == deltaZ) continue;
00430 const double tx = (exitP.x() - entryP.x()) / deltaZ;
00431 const double ty = (exitP.y() - entryP.y()) / deltaZ;
00432 double mcDist = module -> distanceToWire( channel.straw(),
00433 entryP, tx, ty );
00434 int ambiguity = 1;
00435 if ( mcDist < 0.0 ) ambiguity = -1;
00436
00437 double angle = module -> stereoAngle();
00438 double tu = tx * cos(angle) + ty * sin(angle);
00439
00440 OTMeasurement otTim = OTMeasurement( *aTime, *m_otTracker,
00441 ambiguity, tu );
00442 track -> addToMeasurements( otTim );
00443 nOTMeas++;
00444 debug() << " - added OTMeasurement, ambiguity = "
00445 << ambiguity << endreq;
00446 }
00447 }
00448
00449 ++itOTTime;
00450 }
00451
00452 debug() << "- " << nOTMeas << " OTMeasurements added" << endreq;
00453
00454 return StatusCode::SUCCESS;
00455 }
00456
00457
00458
00459
00460 StatusCode TrueTracksCreator::addITClusters( MCParticle* mcPart,
00461 Track* track )
00462 {
00463 unsigned int nITMeas = 0;
00464
00466 ITCluster2MCParticleAsct::FromRange range = m_itClus2MCP -> rangeTo( mcPart );
00467 ITCluster2MCParticleAsct::FromIterator iClus;
00468 for ( iClus = range.begin(); iClus != range.end(); ++iClus) {
00469 ITCluster* aCluster = iClus->to();
00470 ITMeasurement meas = ITMeasurement( *aCluster, *m_itTracker );
00471 track -> addToMeasurements( meas );
00472 nITMeas++;
00473 }
00474
00475 debug() << "- " << nITMeas << " ITMeasurements added" << endreq;
00476
00477 return StatusCode::SUCCESS;
00478 }
00479
00480
00481
00482
00483 StatusCode TrueTracksCreator::addVeloClusters( MCParticle* mcPart,
00484 Track* track )
00485 {
00486 unsigned int nVeloRMeas = 0;
00487 unsigned int nVeloPhiMeas = 0;
00488
00490 VeloCluster2MCParticleAsct::FromRange range = m_veloClus2MCP->rangeTo(mcPart);
00491 VeloCluster2MCParticleAsct::FromIterator iClus;
00492 for ( iClus = range.begin(); iClus != range.end(); ++iClus) {
00493 VeloCluster* aCluster = iClus->to();
00494
00495 if ( m_velo -> isRSensor( aCluster->sensor() ) ) {
00496
00497 double z = m_velo -> zSensor( aCluster -> sensor() );
00498 double phi = 999.0;
00499 State* tempState;
00500 StatusCode sc = m_stateCreator -> createState( mcPart, z, tempState );
00501 if ( sc.isSuccess() ) {
00502 HepVector vec = tempState -> stateVector();
00503 phi = atan2( vec[1], vec[0] );
00504 }
00505 delete tempState;
00506
00507 VeloRMeasurement meas = VeloRMeasurement( *aCluster, *m_velo, phi );
00508 track -> addToMeasurements( meas );
00509 nVeloRMeas++;
00510 }
00511 else {
00512 VeloPhiMeasurement meas = VeloPhiMeasurement( *aCluster, *m_velo );
00513 track -> addToMeasurements( meas );
00514 nVeloPhiMeas++;
00515 }
00516 }
00517
00518 debug() << "- " << nVeloRMeas << " / " << nVeloPhiMeas
00519 << " Velo R/Phi Measurements added" << endreq;
00520
00521 return StatusCode::SUCCESS;
00522 }
00523
00524
00525
00526
00527 StatusCode TrueTracksCreator::registerTracks( Tracks* tracksCont )
00528 {
00529 StatusCode sc = put( tracksCont, m_tracksTESPath );
00530 if ( sc.isFailure() )
00531 error() << "Unable to register the output container at "
00532 << m_tracksTESPath << ". Status is " << sc << endreq;
00533 verbose() << "Tracks container stored in the TES" << endreq;
00534
00535 return StatusCode::SUCCESS;
00536 }
00537
00538
00539
00540
00541 StatusCode TrueTracksCreator::initializeState( double z,
00542 Track* track,
00543 MCParticle* mcPart )
00544 {
00545 State* state;
00546 StatusCode sc = m_stateCreator -> createState( mcPart, z, state );
00547 if ( sc.isSuccess() ) {
00548
00549 HepSymMatrix& cov = state -> covariance();
00550 cov.fast(1,1) = m_errorX2;
00551 cov.fast(2,2) = m_errorY2;
00552 cov.fast(3,3) = m_errorTx2;
00553 cov.fast(4,4) = m_errorTy2;
00554 cov.fast(5,5) = pow( m_errorP * state->qOverP(), 2. );
00555
00556 track -> addToStates( *state );
00557
00558 double qP = state -> qOverP();
00559
00560 debug() << "- State added:" << endreq
00561 << " - position = " << state -> position() << " mm" <<endreq
00562 << " - momentum = " << state -> momentum() << " MeV" <<endreq
00563 << " - P = " << state -> p() << " MeV" <<endreq
00564 << " - charge = " << ( qP != 0. ? int(fabs(qP)/qP) : 0 ) << endreq;
00565 }
00566 else {
00567 delete state;
00568 debug() << "-> unable to add a State!" << endreq;
00569 }
00570
00571 return sc;
00572 }
00573
00574
00575
00576
00577 StatusCode TrueTracksCreator::deleteStates( Track* track )
00578 {
00579 std::vector<State*> tmpStates = track -> states();
00580 for ( std::vector<State*>::const_iterator it = tmpStates.begin();
00581 it != tmpStates.end(); it++) {
00582 track -> removeFromStates( (*it) );
00583 }
00584
00585 return StatusCode::SUCCESS;
00586 }
00587
00588