ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_SegmentsToTrack.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5//======================================================
6//
7// Algorithm for creating Tracks out of TrackSegments
8// by feeding them through a TrackFitter
9//
10// Author: Christian Schmitt <Christian.Schmitt@cern.ch>
11//
12//=======================================================
13
14#include <fstream>
15#include <iostream>
16#include <sstream>
17
18
21
22#include "TrkTrack/Track.h"
31
33
36
39
40// Geometry Stuff
41#include "Identifier/Identifier.h"
43
45
48
51
52
53
54
55InDet::TRT_SegmentsToTrack::TRT_SegmentsToTrack(const std::string& name, ISvcLocator* pSvcLocator):
56 AthAlgorithm(name, pSvcLocator),
57 m_idHelper(nullptr),
58 m_trtid(nullptr),
61 m_noiseratio(0.),
62 m_events(0),
64{
65 declareProperty("NoiseCut", m_noiseCut = -1.);
66 declareProperty("MinNHit", m_minTRTHits = 1);
67 declareProperty("MaterialEffects", m_materialEffects = false);
68 declareProperty("OutlierRemoval", m_outlierRemoval = false);
69 declareProperty("CombineSegments", m_combineSegments = false);
70}
71
75
77{
78
79 ATH_MSG_DEBUG("TrkSegmenttoTrack initialize()");
80
82
85 m_events=0;
86 m_noiseratio=0.;
87
88 // Initialize handle keys
94 ATH_CHECK(m_BECCollectionName.initialize());
95
96 //--------- Set up fitter -------------
97 CHECK( m_trackFitter.retrieve());
98
99 CHECK(detStore()->retrieve(m_trtid));
100
101 CHECK(detStore()->retrieve(m_idHelper, "AtlasID"));
102
103 CHECK(m_extrapolator.retrieve());
104 ATH_CHECK(m_trkSummaryTool.retrieve( DisableTool{ m_trkSummaryTool.empty() } ));
105 ATH_CHECK(m_assoTool.retrieve( DisableTool{ m_assoTool.empty() || (m_trkSummaryTool.empty() && m_assoMapName.empty()) } ));
106 ATH_CHECK(m_inputAssoMapName.initialize( !m_inputAssoMapName.empty() && m_assoTool.isEnabled()));
107 ATH_CHECK(m_assoMapName.initialize( !m_assoMapName.empty() && m_assoTool.isEnabled()));
108 return StatusCode::SUCCESS;
109}
110
112{
113 ATH_MSG_INFO("Summary of" << m_events << " Events");
114 ATH_MSG_INFO("Found Real Tracks : " << m_nTracksReal);
115 ATH_MSG_INFO("Found Fake Tracks : " << m_nTracksFake);
116
117 if(m_nTracksReal>0) {
118 ATH_MSG_INFO("Average noise percentage " << m_noiseratio/double(m_nTracksReal));
119 }
120
121 for (const auto& mitr : m_MapReal) {
122 ATH_MSG_INFO("Real tracks with " << mitr.first << " hits: " << mitr.second);
123 }
124 for (const auto& mitr : m_MapFake) {
125 ATH_MSG_INFO("Fake tracks with " << mitr.first << " hits: " << mitr.second);
126 }
127
129 ATH_MSG_INFO("Number of combined Barrel+Endcap tracks: "<<m_n_combined_fit);
130 }
131
132 ATH_MSG_DEBUG(name() << " finalize() successful ");
133
134 return StatusCode::SUCCESS;
135}
136
138{
139 int segmentCounter=0;
140 const EventContext& ctx = Gaudi::Hive::currentContext();
141 m_events++;
142
143 ATH_MSG_DEBUG(name() << " execute() start");
144
145 StatusCode sc = StatusCode::SUCCESS;
146
147 //combine segments
149 combineSegments(ctx);
150
151 // input TrackSegment Collection
152
154 if (!inputSegments.isValid()) {
155 ATH_MSG_ERROR("Could not open: " <<m_inputSegmentCollectionName.key());
156 sc = StatusCode::FAILURE;
157 return sc;
158 }
159
160
161 //output collections for fitted tracks
162
163 SG::WriteHandle<TrackCollection> final_outputTrackCollection(m_outputTrackCollectionName,ctx);
164 ATH_CHECK(final_outputTrackCollection.record(std::make_unique<TrackCollection>()));
165
166 std::vector<std::unique_ptr<Trk::Track> > output_track_collection;
167 //try to get truth information
168
169 if(not m_multiTruthCollectionTRTName.empty()){
171
172 if (!truthCollectionTRT.isValid()){
173 ATH_MSG_FATAL("Could not open PRD_MultiTruthCollection : " << m_multiTruthCollectionTRTName.key());
174 return StatusCode::FAILURE;
175 }
176 }
177
178 Trk::SegmentCollection::const_iterator iseg = inputSegments->begin();
179 Trk::SegmentCollection::const_iterator isegEnd = inputSegments->end();
180
181
182
183 for(iseg=inputSegments->begin(); iseg != isegEnd; ++ iseg) {
184
185 segmentCounter++;
186
187
188 if((*iseg)->numberOfMeasurementBases()<10) continue; //only convert segments that are large enough
189
191 for(unsigned int i=0;i<(*iseg)->numberOfMeasurementBases();++i){
192 const Amg::VectorX& LocalParameters = (*iseg)->measurement(i)->localParameters();
193 const Amg::MatrixX& LocalErrorMatrix = (*iseg)->measurement(i)->localCovariance();
194 double z=(*iseg)->measurement(i)->globalPosition().z();
195 ATH_MSG_DEBUG("Segment "<<segmentCounter<<" rioOnTrack "<<i<<" (z="<<z<<") : "<<LocalParameters[0]
196 <<" ; "<<std::sqrt(LocalErrorMatrix(Trk::locR,Trk::locR)));
197 myset.push_back((*iseg)->measurement(i));
198 } //end of loop over measurements
199
200 if((*iseg)->numberOfMeasurementBases()>0){
201 ATH_MSG_DEBUG("numberOfContainedRots: " << (*iseg)->numberOfMeasurementBases());
202
203 const Trk::StraightLineSurface* testSf
204 = dynamic_cast<const Trk::StraightLineSurface*>(&((*iseg)->associatedSurface()));
205
206
207 const Trk::AtaStraightLine* inputMatchLine =nullptr;
208 const Trk::Perigee* inputMatchPerigee =nullptr;
209 const Amg::VectorX &p = dynamic_cast<const Amg::VectorX&>((**iseg).localParameters());
210
211 if(!testSf){
212 ATH_MSG_DEBUG("No straightLineSurface !! Trying Perigee ...");
213 const Trk::PerigeeSurface *testPSf=dynamic_cast<const Trk::PerigeeSurface*>(&((*iseg)->associatedSurface()));
214
215 if(!testPSf){
216 ATH_MSG_DEBUG("Associated surface dynamic_cast into PerigeeSurface failed: "<<(*iseg)->associatedSurface());
217 ATH_MSG_DEBUG("Leaving input matching perigee as nullptr, will not get a fittedTrack");
218 }else{
219 ATH_MSG_DEBUG("Ok, it seems to be a PerigeeSurface");
220 inputMatchPerigee = new Trk::Perigee(p(0),p(1),p(2),p(3),p(4), *testPSf);
221 }
222 }else{
223 inputMatchLine = new Trk::AtaStraightLine(p(0),p(1),p(2),p(3),p(4),*testSf);
224
225 ATH_MSG_DEBUG("Created testSf : " << (*inputMatchLine));
226 int nmeas=(*iseg)->numberOfMeasurementBases();
227 Amg::Vector3D surfpos(.5*((*iseg)->measurement(nmeas/2)->globalPosition()+(*iseg)->measurement(nmeas/2+1)->globalPosition()));
228 Trk::PerigeeSurface persurf(surfpos);
229 std::unique_ptr<const Trk::TrackParameters> tmp =
230 m_extrapolator->extrapolateDirectly(ctx, *inputMatchLine, persurf);
231 if (tmp && tmp->associatedSurface().type() == Trk::SurfaceType::Perigee) {
232 inputMatchPerigee = static_cast<const Trk::Perigee*>(tmp.release());
233 }
234 }
235 ATH_MSG_DEBUG("Created inputMatchLine");
236
237 std::unique_ptr<Trk::Track> fittedTrack;
238 const Trk::TrackParameters *inputpar=nullptr;
239 if (inputMatchPerigee) inputpar=inputMatchPerigee;
240 else if (inputMatchLine) inputpar=inputMatchLine;
241
242 if (inputpar) {
243 fittedTrack = m_trackFitter->fit(ctx,
244 myset,
245 *inputpar,
248 }
249 if(fittedTrack){
250 Trk::TrackStates::const_iterator itSet = fittedTrack->trackStateOnSurfaces()->begin();
251 Trk::TrackStates::const_iterator itSetEnd = fittedTrack->trackStateOnSurfaces()->end();
252 const Trk::TrackParameters *measpar=nullptr;
253 double mindist=9999;
254 for ( ; itSet!=itSetEnd; ++itSet) {
255 if ((**itSet).type(Trk::TrackStateOnSurface::Measurement) && (**itSet).trackParameters()->position().perp()<mindist) {
256 mindist=(**itSet).trackParameters()->position().perp();
257 measpar=(**itSet).trackParameters();
258 }
259 }
260 std::unique_ptr<Trk::TrackParameters> myper;
261 if (measpar){
263 }
264 if (!myper){
265 fittedTrack.reset();
266 }
267 else {
268 auto trajectory = std::make_unique<Trk::TrackStates>();
269 itSet = fittedTrack->trackStateOnSurfaces()->begin();
270 for ( ; itSet!=itSetEnd; ++itSet) {
271 if (!(**itSet).type(Trk::TrackStateOnSurface::Perigee)) {
272 auto trackpar=(**itSet).trackParameters() ? (**itSet).trackParameters()->uniqueClone() : nullptr;
273 auto measurement=(**itSet).measurementOnTrack() ? (**itSet).measurementOnTrack()->uniqueClone() : nullptr;
274 auto fitQual=(**itSet).fitQualityOnSurface() ;
275 auto mateff=(**itSet).materialEffectsOnTrack() ? (**itSet).materialEffectsOnTrack()->uniqueClone() : nullptr;
276 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
278 else if ((**itSet).type(Trk::TrackStateOnSurface::Outlier)) typePattern.set(Trk::TrackStateOnSurface::Outlier);
279 else if ((**itSet).type(Trk::TrackStateOnSurface::Scatterer)) typePattern.set(Trk::TrackStateOnSurface::Scatterer);
280 else if ((**itSet).type(Trk::TrackStateOnSurface::BremPoint)) typePattern.set(Trk::TrackStateOnSurface::BremPoint);
281 trajectory->push_back(
282 new Trk::TrackStateOnSurface(fitQual,
283 std::move(measurement),
284 std::move(trackpar),
285 std::move(mateff),
286 typePattern));
287 }
288 }
289 bool peradded=false;
290 itSet = trajectory->begin()+1;
291 itSetEnd = trajectory->end();
292 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
293 typePattern.set(Trk::TrackStateOnSurface::Perigee);
294 const auto myPosition {myper->position()};
295 const auto myMomentum {myper->momentum()};
296 const Trk::TrackStateOnSurface* pertsos =
297 new Trk::TrackStateOnSurface(nullptr,
298 std::move(myper),
299 nullptr,
300 typePattern);
301
302 int index=1;
303 for ( ; itSet!=itSetEnd; ++itSet) {
304 double inprod1=((**itSet).trackParameters()->position()-myPosition).dot(myMomentum);
305 --itSet;
306 double inprod2=((**itSet).trackParameters()->position()-myPosition).dot(myMomentum);
307 ++itSet;
308 if (inprod1>0 && inprod2<0) {
309 trajectory->insert(trajectory->begin()+index,pertsos);
310 peradded=true;
311 break;
312 }
313 index++;
314 }
315 if (!peradded){
316 itSet = trajectory->begin();
317 double inprod=((**itSet).trackParameters()->position()-myPosition).dot(myMomentum);
318 if (inprod>0) trajectory->insert(trajectory->begin(),pertsos);
319 else trajectory->push_back(pertsos);
320 }
321 std::unique_ptr<Trk::Track> track =
322 std::make_unique<Trk::Track>(fittedTrack->info(),
323 std::move(trajectory),
324 fittedTrack->fitQuality()->uniqueClone());
325 fittedTrack = std::move(track);
326 }
327 }
328 if(fittedTrack){
329
330 int nHT=nHTHits(fittedTrack.get());
331 ATH_MSG_DEBUG("Number of HT hits: "<<nHT);
332 ATH_MSG_DEBUG(" Successful fit of track.");
333 if ((*iseg)->fitQuality()) ATH_MSG_DEBUG("Quality of Segment: chi^2 /ndof "<<(*iseg)->fitQuality()->chiSquared()<<" / "<<(*iseg)->fitQuality()->numberDoF());
334 ATH_MSG_DEBUG("Quality of Track: chi^2 /ndof "<<fittedTrack->fitQuality()->chiSquared()<<" / "<<fittedTrack->fitQuality()->numberDoF());
335 ATH_MSG_DEBUG("Noise probability: "<<getNoiseProbability(fittedTrack.get()));
336 ATH_MSG_DEBUG((*fittedTrack));
337
338 if( nTRTHits(fittedTrack.get())>=m_minTRTHits){
339 if(getNoiseProbability(fittedTrack.get())>m_noiseCut){
340 double truefraction=getRealFractionTRT(fittedTrack.get(),ctx);
341
342 int nhits=(*iseg)->numberOfMeasurementBases();
343 ATH_MSG_DEBUG("Real/Noise : "<< truefraction << " chi2="<<fittedTrack->fitQuality()->chiSquared()/double(fittedTrack->fitQuality()->numberDoF()));
344 if(truefraction>0.5){
345 ATH_MSG_DEBUG("==> Real Track");
346
347 if(m_MapReal.find(nhits)==m_MapReal.end()){
348 m_MapReal[nhits]=1;
349 }else{
350 m_MapReal[nhits]++;
351 }
352
354 m_noiseratio+=(1-truefraction);
355 }else{
356 ATH_MSG_DEBUG(" ==> Fake Track");
357
358 if(m_MapFake.find(nhits)==m_MapFake.end()){
359 m_MapFake[nhits]=1;
360 }else{
361 m_MapFake[nhits]++;
362 }
363
365 }
366 }
367 output_track_collection.push_back(std::move(fittedTrack));
368 }else{
369 ATH_MSG_DEBUG("This tracks has only "<<nTRTHits(fittedTrack.get())<<" Hits! Will reject it!");
370 }
371
372 }else{
373 ATH_MSG_DEBUG("Fit did not converge!");
374 } //end of if(fittedTrack)
375
376 delete inputMatchLine;
377 delete inputMatchPerigee;
378
379 } //end of if: (*iseg)->numberOfMeasurementBases()>0
380 } //end of loop over segments
381
382 std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map;
383 if (m_assoTool.isEnabled()) {
384 // create internal PRD-to-track map
385 prd_to_track_map = m_assoTool->createPRDtoTrackMap();
386 if (!m_inputAssoMapName.key().empty()) {
388 if (!input_asso_map.isValid()) {
389 ATH_MSG_FATAL("No valid input PRT-to-track map with key " << m_inputAssoMapName.key());
390 }
391 *prd_to_track_map = *input_asso_map;
392 ATH_MSG_INFO("PRD to track map input " << m_inputAssoMapName.key() );
393 }
394 for (const std::unique_ptr<Trk::Track> &track : output_track_collection) {
395 ATH_CHECK( m_assoTool->addPRDs(*prd_to_track_map, *track) );
396 }
397 }
398 // @TODO sort output track collection ?
399 final_outputTrackCollection->reserve(output_track_collection.size());
400 if (m_trkSummaryTool.isEnabled()) {
401 for (std::unique_ptr<Trk::Track> &track : output_track_collection) {
402 m_trkSummaryTool->computeAndReplaceTrackSummary(*track,prd_to_track_map.get());
403 final_outputTrackCollection->push_back(std::move(track));
404 }
405 }
406 else {
407 for (std::unique_ptr<Trk::Track> &track : output_track_collection) {
408 final_outputTrackCollection->push_back(std::move(track));
409 }
410 }
411 if (!m_assoMapName.key().empty()) {
412 ATH_CHECK(SG::WriteHandle<Trk::PRDtoTrackMap>(m_assoMapName,ctx).record(std::move(prd_to_track_map)));
413 }
414
415 if (!final_outputTrackCollection.isValid()) {
416 // @TODO never reached (?)
417 ATH_MSG_ERROR("Could not write track collection " << m_outputTrackCollectionName.key());
418 return StatusCode::FAILURE;
419 //return sc;
420 }
421
422 return sc;
423}
424
425int InDet::TRT_SegmentsToTrack::getNumberReal(const InDet::TRT_DriftCircle* driftcircle,const EventContext& ctx) const
426{
427 int numBarcodes = 0;
428 using iter = PRD_MultiTruthCollection::const_iterator;
429
430 if(m_multiTruthCollectionTRTName.empty()) return 0;
431
432 else{
434 if(truthCollectionTRT.isValid()){
435 std::pair<iter,iter> range = truthCollectionTRT->equal_range(driftcircle->identify());
436 numBarcodes+=std::distance(range.first,range.second);
437 }
438 }
439 return numBarcodes;
440}
441
442
443
444double InDet::TRT_SegmentsToTrack::getRealFractionTRT(const Trk::Track *track,const EventContext& ctx) const
445{
446 double fraction=0.;
447 int nDriftReal=0;
448 int nDriftNoise=0;
449
450 //loop over the hits
451 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
452
453 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
454 if (hitOnTrack) {
455 const Identifier& surfaceID = hitOnTrack->identify();
456
457 //take only TRT hits
458 if(m_idHelper->is_trt(surfaceID)){
459
460 const InDet::TRT_DriftCircleOnTrack *dcot= dynamic_cast <const InDet::TRT_DriftCircleOnTrack*>(hitOnTrack);
461 if(dcot) {
462 const InDet::TRT_DriftCircle *dc=dcot->prepRawData();
463
464 if(dc){
465 int nreal=getNumberReal(dc,ctx);
466
467 if(nreal>0) nDriftReal++;
468 else nDriftNoise++;
469
470 }
471 }
472 }
473 }
474 }
475
476 if(nDriftReal>0)
477 fraction=double(nDriftReal)/double(nDriftNoise+nDriftReal);
478
479 return fraction;
480}
481
482
484{
485
486 int nHT=0;
487
488 //loop over the hits
489 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
490
491 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
492 if (hitOnTrack != nullptr) {
493 const Identifier& surfaceID = hitOnTrack->identify();
494
495 //take only TRT hits
496 if(m_idHelper->is_trt(surfaceID) && !tsos->type(Trk::TrackStateOnSurface::Outlier)){
497 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(hitOnTrack);
498 if(trtcirc) {
499 if(trtcirc->highLevel()){
500 nHT++;
501 }
502 }
503 }
504 }
505 }
506
507 return nHT;
508}
509
510
511
513{
514 int nhits=0;
515
516 //loop over the hits
517 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
518
519 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
520 if (hitOnTrack != nullptr) {
521 const Identifier& surfaceID = hitOnTrack->identify();
522
523 //take only TRT hits
524 if(m_idHelper->is_trt(surfaceID) && !tsos->type(Trk::TrackStateOnSurface::Outlier)){
525 nhits++;
526 }
527 }
528 }
529
530 return nhits;
531}
532
533
535{
536 double fraction=0.;
537 int nDriftReal=0;
538 int nDriftNoise=0;
539
540 //loop over the hits
541 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
542 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
543 if (hitOnTrack) {
544 const Identifier& surfaceID = hitOnTrack->identify();
545
546 //take only TRT hits
547 if(m_idHelper->is_trt(surfaceID)){
548
549 const InDet::TRT_DriftCircleOnTrack *dcot= dynamic_cast <const InDet::TRT_DriftCircleOnTrack*>(hitOnTrack);
550 if (dcot) {
551 const InDet::TRT_DriftCircle *dc=dcot->prepRawData();
552
553 if(dc){
554
555 if(dc->isNoise())
556 nDriftNoise++;
557 else
558 nDriftReal++;
559 }
560 }
561 }
562 }
563 }
564
565 if(nDriftReal>0)
566 fraction=double(nDriftReal)/double(nDriftNoise+nDriftReal);
567
568 return fraction;
569}
570
571
572
573void InDet::TRT_SegmentsToTrack::combineSegments(const EventContext& ctx) const
574{
575 //Idea:
576 // - get from endcap segment z-phi dependence
577 // - get from barrel segment r-phi dependence and z dependence from endcap segment fit
578
579 int n_combined_fit=0;
582
583 StatusCode sc;
584
585 SG::WriteHandle<TrackCollection> outputCombiCollection(m_BECCollectionName,ctx);
586 sc = outputCombiCollection.record(std::make_unique<TrackCollection>());
587 if (sc.isFailure()) return;
588
589 if (!BarrelSegments.isValid()){
590 ATH_MSG_FATAL("Could not open barrel segments collection : " << m_barrelSegments.key());
591 return;
592 }
593
594 if (!EndcapSegments.isValid()) {
595 ATH_MSG_FATAL("Could not open endcap segments collection : " << m_endcapSegments.key());
596 return;
597 }
598
599 ATH_MSG_VERBOSE("Got both barrel and endcap segment collections of size "<<BarrelSegments->size()<<" "<<EndcapSegments->size());
600
601 Trk::SegmentCollection::const_iterator iseg = BarrelSegments->begin();
602 Trk::SegmentCollection::const_iterator isegE = BarrelSegments->end();
603
604 int scount=0;
605 for(;iseg!=isegE;++iseg,scount++){
606 ATH_MSG_VERBOSE("Barrel Segment "<<scount<<" : phi="<<(*iseg)->localParameters()[Trk::phi]);
607 }
608
609 iseg = EndcapSegments->begin();
610 isegE = EndcapSegments->end();
611
612 scount=0;
613 for(;iseg!=isegE;++iseg,scount++){
614 ATH_MSG_VERBOSE("Endcap Segment "<<scount<<" : phi="<<(*iseg)->localParameters()[Trk::phi]);
615 }
616
617 if(BarrelSegments->size()==1 && EndcapSegments->size()==1){
618 ATH_MSG_VERBOSE("Here we go: one barrel segment and one endcap segment!");
619
620 Trk::SegmentCollection::const_iterator isegBarrel = BarrelSegments->begin();
621 Trk::SegmentCollection::const_iterator isegBarrelE = BarrelSegments->end();
622
623 Trk::SegmentCollection::const_iterator isegEndcap = EndcapSegments->begin();
624 Trk::SegmentCollection::const_iterator isegEndcapE = EndcapSegments->end();
625
626 //loop over all Barrel Segments
627 for(;isegBarrel!=isegBarrelE;++isegBarrel){
628 for(;isegEndcap!=isegEndcapE;++isegEndcap){
629
630 std::vector< Trk::PseudoMeasurementOnTrack*> tobedeleted;
631
632 ATH_MSG_VERBOSE("Barrel Segment : phi="<<(*isegBarrel)->localParameters()[Trk::phi]<<" with "<<(*isegBarrel)->numberOfMeasurementBases()<<" hits");
633 ATH_MSG_VERBOSE("Endcap Segment : phi="<<(*isegEndcap)->localParameters()[Trk::phi]<<" with "<<(*isegEndcap)->numberOfMeasurementBases()<<" hits");
634
635 int count=0;
636 Trk::MeasurementSet myset,myset2,echits=(*isegEndcap)->containedMeasurements();
637
638 bool barreldown=((*isegBarrel)->measurement((*isegBarrel)->numberOfMeasurementBases()/2)->globalPosition().y()<0);
639 double theta=0;
640 if((*isegEndcap)->localParameters().contains(Trk::theta)){
641 theta = (*isegEndcap)->localParameters()[Trk::theta];
642 }
643
644 //correct theta to point towards the barrel
645 if(( (*isegEndcap)->globalPosition().y()>0 && (*isegEndcap)->globalPosition().z()>0) ||
646 ((*isegEndcap)->globalPosition().y()<0 && (*isegEndcap)->globalPosition().z()<0)
647 ){
648 //endcap A top pointing to barrel A bottom or Barrel C top pointing to Endcap C bottom
649 //--> Theta between 90 and 180 degrees
650 if(theta<M_PI/2.) {
652 std::reverse(echits.begin(),echits.end());
653 }
654 }else{
655 //Theta between 0 and 90 degrees
656 if(theta>M_PI/2.) {
658 std::reverse(echits.begin(),echits.end());
659 }
660 }
661
662 //decide if barrel or endcap hits come first depending on global position of segments
663
664 if(!barreldown && (*isegEndcap)->globalPosition().y()>0){
665 ATH_MSG_VERBOSE("Both barrel and endcap segments in top sectors, won't fit");
666 continue;
667 }
668
669 if(barreldown && (*isegEndcap)->globalPosition().y()<0){
670 ATH_MSG_VERBOSE("Both barrel and endcap segments in lower sectors, won't fit");
671 continue;
672 }
673 int firstechit=0,lastechit=0;
674 if((*isegEndcap)->globalPosition().y()>0){
675 //first endcap then barrel
676 for(int i=0;i<(int)echits.size();++i){
677 const Trk::MeasurementBase *meas=echits[i];
678 const Amg::VectorX LocalParameters = meas->localParameters();
679 const Amg::MatrixX LocalErrorMatrix = meas->localCovariance();
680 double z=meas->globalPosition().z();
681 double phi=meas->globalPosition().phi();
682 double r=meas->globalPosition().perp();
683
684 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(meas);
685 if(trtcirc){
686 myset.push_back(meas);
687 ATH_MSG_VERBOSE("Endcap : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
688 count++;
689 }
690 }
691 firstechit=0;
692 lastechit=count-1;
693
694 for(unsigned int i=0;i<(*isegBarrel)->numberOfMeasurementBases();++i){
695 const Amg::VectorX LocalParameters = (*isegBarrel)->measurement(i)->localParameters();
696 const Amg::MatrixX LocalErrorMatrix = (*isegBarrel)->measurement(i)->localCovariance();
697 double z=(*isegBarrel)->measurement(i)->globalPosition().z();
698 double phi=(*isegBarrel)->measurement(i)->globalPosition().phi();
699 double r=(*isegBarrel)->measurement(i)->globalPosition().perp();
700
701 const Trk::MeasurementBase *mesb=(*isegBarrel)->measurement(i);
702 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(mesb);
703 if(trtcirc){
704 myset.push_back((*isegBarrel)->measurement(i));
705 ATH_MSG_VERBOSE("Barrel : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
706 count++;
707 }
708
709 }
710 }else{
711 //first barrel then endcap
712 for(unsigned int i=0;i<(*isegBarrel)->numberOfMeasurementBases();++i){
713 const Amg::VectorX LocalParameters = (*isegBarrel)->measurement(i)->localParameters();
714 const Amg::MatrixX LocalErrorMatrix = (*isegBarrel)->measurement(i)->localCovariance();
715 double z=(*isegBarrel)->measurement(i)->globalPosition().z();
716 double phi=(*isegBarrel)->measurement(i)->globalPosition().phi();
717 double r=(*isegBarrel)->measurement(i)->globalPosition().perp();
718
719 const Trk::MeasurementBase *mesb=(*isegBarrel)->measurement(i);
720 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(mesb);
721 if(trtcirc){
722 myset.push_back((*isegBarrel)->measurement(i));
723 ATH_MSG_VERBOSE("Barrel : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
724 count++;
725 }
726
727 }
728 firstechit=count;
729
730 for(int i=0;i<(int)echits.size();++i){
731 const Trk::MeasurementBase *meas=echits[i];
732 const Amg::VectorX LocalParameters = meas->localParameters();
733 const Amg::MatrixX LocalErrorMatrix = meas->localCovariance();
734 double z=meas->globalPosition().z();
735 double phi=meas->globalPosition().phi();
736 double r=meas->globalPosition().perp();
737
738 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(meas);
739 if(trtcirc){
740 myset.push_back(meas);
741 ATH_MSG_VERBOSE("Endcap : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
742 count++;
743 }
744
745 }
746 lastechit=count-1;
747 }
748
749
750
751 Amg::Vector3D inputMatchingPos((*isegBarrel)->globalPosition());
752
753 if((*isegEndcap)->globalPosition().y()>0)
754 inputMatchingPos=(*isegEndcap)->globalPosition();
755
756 Amg::Vector3D inputMatchingMom;
757 double p = 10e7;
758
759 if((*isegBarrel)->localParameters().contains(Trk::qOverP)){
760 p = ((*isegBarrel)->localParameters()[Trk::qOverP]!=0.) ? fabs(1./((*isegBarrel)->localParameters()[Trk::qOverP])) : 10e7;
761 }
762
763 double phi=0.;
764 if((*isegBarrel)->localParameters().contains(Trk::phi)){
765 phi = (*isegBarrel)->localParameters()[Trk::phi];
766 }
767
768
769 inputMatchingMom[Trk::px] = p * cos(phi) * sin(theta);
770 inputMatchingMom[Trk::py] = p * sin(phi) * sin(theta);
771 inputMatchingMom[Trk::pz] = p * cos(theta);
772
773
774 ATH_MSG_VERBOSE("Global position: "<<inputMatchingPos<<" Globalmomentum: "<<inputMatchingMom);
775
776
777
778 //add two pseudomeasurements at the beginning and at the end of the track
779 Trk::MeasurementSet::const_iterator mit;
780 Trk::MeasurementSet::const_iterator mitE=myset.end();
781
782 int count2=0;
783 for(mit=myset.begin();mit!=mitE;++mit){
784 myset2.push_back(*mit);
785 if(count2==firstechit || count2==lastechit){
786 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(*mit);
787 if(trtcirc){
788 const Trk::StraightLineSurface *line=dynamic_cast<const
790 if (line) {
791 //add pseudomeasurement
792 double locz=-200.;
793 if ((count2==firstechit && firstechit!=0) || (count2==lastechit && firstechit==0)) locz=200;
795 Trk::LocalParameters par(dp);
796
797 Amg::MatrixX cov(1,1);
798 cov(0,0) = 16./12. ; // take actual length of straw instead !!!!!
799
800 //create new surface
801 Amg::Vector3D C = line->transform().translation();
802
803 //decide on movement
804
805 const Amg::Vector3D& gpos=(*mit)->globalPosition();
806
807 if(fabs(gpos.z())>800){
808 if(theta>M_PI/2.){
809 C[2]-=1.;
810 }else{
811 C[2]+=1.;
812 }
813 }else{
814 C[1]-=1.;
815 }
816
817
819 T = line->transform().rotation();
820 T *= Amg::Translation3D(C.x(),C.y(),C.z());
822
824 std::move(cov),
825 *surface);
826
827 tobedeleted.push_back(pseudo);
828
829 delete surface;
830
831 myset2.push_back(pseudo);
832 }
833 }
834 }
835 count2++;
836 }
837
838
839
840 const Trk::StraightLineSurface* testSf;
841 if((*isegEndcap)->globalPosition().y()>0){
842 testSf= dynamic_cast<const Trk::StraightLineSurface*>(&((*isegEndcap)->associatedSurface()));
843 }else{
844 testSf= dynamic_cast<const Trk::StraightLineSurface*>(&((*isegBarrel)->associatedSurface()));
845 }
846
847 const Trk::AtaStraightLine* inputMatchLine = nullptr;
848 const Trk::Perigee* inputMatchPerigee = nullptr;
849
850 if(!testSf){
851 ATH_MSG_VERBOSE("No straightLineSurface !! Trying Perigee ...");
852
853 const Trk::PerigeeSurface *testPSf=dynamic_cast<const Trk::PerigeeSurface*>(&((*isegBarrel)->associatedSurface()));
854
855 if(!testPSf){
856 ATH_MSG_VERBOSE("Associated surface dynamic_cast into PerigeeSurface failed. "<<(*isegBarrel)->associatedSurface());
857 ATH_MSG_VERBOSE("Leaving input matching perigee as nullptr, will not get a fittedTrack");
858 }else{
859 ATH_MSG_VERBOSE("Ok, it seems to be a PerigeeSurface");
860 inputMatchPerigee = new Trk::Perigee(inputMatchingPos,inputMatchingMom, 1., *testPSf);
861 }
862
863 }else{
864 inputMatchLine = new Trk::AtaStraightLine(inputMatchingPos,inputMatchingMom, 1., *testSf);
865 ATH_MSG_VERBOSE("Created testSf : " << (*inputMatchLine));
866 }
867
868 Amg::Vector3D startMomentum( 0., 0., 1.);
869 std::unique_ptr<Trk::Track> fittedTrack;
871 if(inputMatchLine){
872 fittedTrack=m_trackFitter->fit(ctx,
873 myset2,
874 *inputMatchLine,
875 false,
877 );
878 }else if (inputMatchPerigee){
879 fittedTrack=m_trackFitter->fit(ctx,
880 myset2,
881 *inputMatchPerigee,
882 false,
884 );
885 }
886 }else{
887 if(inputMatchLine){
888 fittedTrack=m_trackFitter->fit(ctx,
889 myset2,
890 *inputMatchLine,
891 false,
893 );
894 }else if (inputMatchPerigee){
895 fittedTrack=m_trackFitter->fit(ctx,
896 myset2,
897 *inputMatchPerigee,
898 false,
900 );
901 }
902 }
903
904 if(fittedTrack){
905 n_combined_fit++;
906 ATH_MSG_DEBUG("Successful Barrel+Endcap fit of segment. ");
907 ATH_MSG_DEBUG("Quality of Track: "<<fittedTrack->fitQuality()->chiSquared()<<" / "<<fittedTrack->fitQuality()->numberDoF());
908 ATH_MSG_VERBOSE(*fittedTrack);
909 outputCombiCollection->push_back(std::move(fittedTrack));
910}
911
912 delete inputMatchPerigee;
913 delete inputMatchLine;
914
915 for(size_t i=0;i<tobedeleted.size();i++)
916 delete tobedeleted[i];
917 tobedeleted.clear();
918 }
919 }
920 }
921 m_n_combined_fit += n_combined_fit;
922
923 if (!outputCombiCollection.isValid()) {
924 ATH_MSG_ERROR("Could not write track Barrel+EC collection TRT_Barrel_EC");
925 }
926}
#define M_PI
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
#define CHECK(...)
Evaluate an expression and check for errors.
An STL vector of pointers that by default owns its pointed-to elements.
static Double_t sc
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
This is an Identifier helper class for the TRT subdetector.
#define z
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
Represents 'corrected' measurements from the TRT (for example, corrected for wire sag).
bool highLevel() const
returns true if the high level threshold was passed
virtual const TRT_DriftCircle * prepRawData() const override final
returns the PrepRawData - is a TRT_DriftCircle in this scope
virtual const Trk::Surface & associatedSurface() const override final
returns the surface for the local to global transformation
bool isNoise() const
returns true if the hit is caused by noise with a high probability.
int m_nTracksReal
Counter for real reconstructed Tracks.
double getNoiseProbability(const Trk::Track *track) const
Get the fraction of noise TRT hits on this Track.
std::atomic< int > m_events
Event counter.
ToolHandle< Trk::ITrackFitter > m_trackFitter
The TrackFitter.
int nHTHits(const Trk::Track *track) const
Count number of TRT HT Hits on track.
SG::ReadHandleKey< Trk::SegmentCollection > m_endcapSegments
Name of Endcap segment collection.
ToolHandle< Trk::IExtrapolator > m_extrapolator
The Extrapolator.
SG::ReadHandleKey< Trk::SegmentCollection > m_inputSegmentCollectionName
Name of the TrackSegment Collection to read in.
const AtlasDetectorID * m_idHelper
double getRealFractionTRT(const Trk::Track *track, const EventContext &ctx) const
Get the fraction of truth TRT hits on this Track.
ToolHandle< Trk::IPRDtoTrackMapTool > m_assoTool
void combineSegments(const EventContext &ctx) const
int m_minTRTHits
All tracks with less Hits (after the track fit) will be thrown away.
SG::ReadHandleKey< PRD_MultiTruthCollection > m_multiTruthCollectionTRTName
Name of the TRT MultiTruthCollection.
std::map< int, int > m_MapReal
Map of hits and real tracks.
int m_nTracksFake
Counter for fake reconstructed Track.
std::atomic< int > m_n_combined_fit
std::map< int, int > m_MapFake
Map of hits and fake tracks.
int getNumberReal(const InDet::TRT_DriftCircle *, const EventContext &ctx) const
Get the number of truth particles associated with this hit.
SG::WriteHandleKey< TrackCollection > m_BECCollectionName
Name of the combined (TRT Barrel+EC) TrackCollection to write out.
SG::ReadHandleKey< Trk::SegmentCollection > m_barrelSegments
Name of Barrel segment collection.
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trkSummaryTool
bool m_outlierRemoval
Flag to switch on the outlier removal in the track fitter.
SG::ReadHandleKey< Trk::PRDtoTrackMap > m_inputAssoMapName
key to be set to optionally store PRD to track association map
SG::WriteHandleKey< TrackCollection > m_outputTrackCollectionName
Name of the TrackCollection to write out.
TRT_SegmentsToTrack(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteHandleKey< Trk::PRDtoTrackMap > m_assoMapName
key for the PRDtoTrackMap to filled by the ambiguity score processor.
int nTRTHits(const Trk::Track *track) const
Count number of TRT Hits on track.
bool m_combineSegments
Try to combine segments from Barrel and Endcap.
double m_noiseCut
All tracks with a TRT Noise fraction larger than this variable will be thrown away.
bool m_materialEffects
Flag to switch on Material Effects in the Fitter.
double m_noiseratio
average percentage of noise in real tracks
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual const Amg::Vector3D & globalPosition() const =0
Interface method to get the global Position.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Class describing the Line to which the Perigee refers to.
Identifier identify() const
return the identifier
Class to handle pseudo-measurements in fitters and on track objects.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
Class for a StraightLineSurface in the ATLAS detector to describe dirft tube and straw like detectors...
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ BremPoint
This represents a brem point on the track, and so will contain TrackParameters and MaterialEffectsBas...
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
int r
Definition globals.cxx:22
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
struct color C
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
@ anyDirection
std::vector< const MeasurementBase * > MeasurementSet
vector of fittable measurements
Definition FitterTypes.h:30
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersT< TrackParametersDim, Charged, StraightLineSurface > AtaStraightLine
@ pz
global momentum (cartesian)
Definition ParamDefs.h:61
@ locR
Definition ParamDefs.h:44
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
@ locZ
local cylindrical
Definition ParamDefs.h:42
@ px
Definition ParamDefs.h:59
@ py
Definition ParamDefs.h:60
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.