ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_SegmentsToTrack.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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
137StatusCode InDet::TRT_SegmentsToTrack::execute(const EventContext& ctx)
138{
139 int segmentCounter=0;
140 m_events++;
141
142 ATH_MSG_DEBUG(name() << " execute() start");
143
144 StatusCode sc = StatusCode::SUCCESS;
145
146 //combine segments
148 combineSegments(ctx);
149
150 // input TrackSegment Collection
151
153 if (!inputSegments.isValid()) {
154 ATH_MSG_ERROR("Could not open: " <<m_inputSegmentCollectionName.key());
155 sc = StatusCode::FAILURE;
156 return sc;
157 }
158
159
160 //output collections for fitted tracks
161
162 SG::WriteHandle<TrackCollection> final_outputTrackCollection(m_outputTrackCollectionName,ctx);
163 ATH_CHECK(final_outputTrackCollection.record(std::make_unique<TrackCollection>()));
164
165 std::vector<std::unique_ptr<Trk::Track> > output_track_collection;
166 //try to get truth information
167
168 if(not m_multiTruthCollectionTRTName.empty()){
170
171 if (!truthCollectionTRT.isValid()){
172 ATH_MSG_FATAL("Could not open PRD_MultiTruthCollection : " << m_multiTruthCollectionTRTName.key());
173 return StatusCode::FAILURE;
174 }
175 }
176
177 Trk::SegmentCollection::const_iterator iseg = inputSegments->begin();
178 Trk::SegmentCollection::const_iterator isegEnd = inputSegments->end();
179
180
181
182 for(iseg=inputSegments->begin(); iseg != isegEnd; ++ iseg) {
183
184 segmentCounter++;
185
186
187 if((*iseg)->numberOfMeasurementBases()<10) continue; //only convert segments that are large enough
188
190 for(unsigned int i=0;i<(*iseg)->numberOfMeasurementBases();++i){
191 const Amg::VectorX& LocalParameters = (*iseg)->measurement(i)->localParameters();
192 const Amg::MatrixX& LocalErrorMatrix = (*iseg)->measurement(i)->localCovariance();
193 double z=(*iseg)->measurement(i)->globalPosition().z();
194 ATH_MSG_DEBUG("Segment "<<segmentCounter<<" rioOnTrack "<<i<<" (z="<<z<<") : "<<LocalParameters[0]
195 <<" ; "<<std::sqrt(LocalErrorMatrix(Trk::locR,Trk::locR)));
196 myset.push_back((*iseg)->measurement(i));
197 } //end of loop over measurements
198
199 if((*iseg)->numberOfMeasurementBases()>0){
200 ATH_MSG_DEBUG("numberOfContainedRots: " << (*iseg)->numberOfMeasurementBases());
201
202 const Trk::StraightLineSurface* testSf
203 = dynamic_cast<const Trk::StraightLineSurface*>(&((*iseg)->associatedSurface()));
204
205
206 const Trk::AtaStraightLine* inputMatchLine =nullptr;
207 const Trk::Perigee* inputMatchPerigee =nullptr;
208 const Amg::VectorX &p = dynamic_cast<const Amg::VectorX&>((**iseg).localParameters());
209
210 if(!testSf){
211 ATH_MSG_DEBUG("No straightLineSurface !! Trying Perigee ...");
212 const Trk::PerigeeSurface *testPSf=dynamic_cast<const Trk::PerigeeSurface*>(&((*iseg)->associatedSurface()));
213
214 if(!testPSf){
215 ATH_MSG_DEBUG("Associated surface dynamic_cast into PerigeeSurface failed: "<<(*iseg)->associatedSurface());
216 ATH_MSG_DEBUG("Leaving input matching perigee as nullptr, will not get a fittedTrack");
217 }else{
218 ATH_MSG_DEBUG("Ok, it seems to be a PerigeeSurface");
219 inputMatchPerigee = new Trk::Perigee(p(0),p(1),p(2),p(3),p(4), *testPSf);
220 }
221 }else{
222 inputMatchLine = new Trk::AtaStraightLine(p(0),p(1),p(2),p(3),p(4),*testSf);
223
224 ATH_MSG_DEBUG("Created testSf : " << (*inputMatchLine));
225 int nmeas=(*iseg)->numberOfMeasurementBases();
226 Amg::Vector3D surfpos(.5*((*iseg)->measurement(nmeas/2)->globalPosition()+(*iseg)->measurement(nmeas/2+1)->globalPosition()));
227 Trk::PerigeeSurface persurf(surfpos);
228 std::unique_ptr<const Trk::TrackParameters> tmp =
229 m_extrapolator->extrapolateDirectly(ctx, *inputMatchLine, persurf);
230 if (tmp && tmp->associatedSurface().type() == Trk::SurfaceType::Perigee) {
231 inputMatchPerigee = static_cast<const Trk::Perigee*>(tmp.release());
232 }
233 }
234 ATH_MSG_DEBUG("Created inputMatchLine");
235
236 std::unique_ptr<Trk::Track> fittedTrack;
237 const Trk::TrackParameters *inputpar=nullptr;
238 if (inputMatchPerigee) inputpar=inputMatchPerigee;
239 else if (inputMatchLine) inputpar=inputMatchLine;
240
241 if (inputpar) {
242 fittedTrack = m_trackFitter->fit(ctx,
243 myset,
244 *inputpar,
247 }
248 if(fittedTrack){
249 Trk::TrackStates::const_iterator itSet = fittedTrack->trackStateOnSurfaces()->begin();
250 Trk::TrackStates::const_iterator itSetEnd = fittedTrack->trackStateOnSurfaces()->end();
251 const Trk::TrackParameters *measpar=nullptr;
252 double mindist=9999;
253 for ( ; itSet!=itSetEnd; ++itSet) {
254 if ((**itSet).type(Trk::TrackStateOnSurface::Measurement) && (**itSet).trackParameters()->position().perp()<mindist) {
255 mindist=(**itSet).trackParameters()->position().perp();
256 measpar=(**itSet).trackParameters();
257 }
258 }
259 std::unique_ptr<Trk::TrackParameters> myper;
260 if (measpar){
262 }
263 if (!myper){
264 fittedTrack.reset();
265 }
266 else {
267 auto trajectory = std::make_unique<Trk::TrackStates>();
268 itSet = fittedTrack->trackStateOnSurfaces()->begin();
269 for ( ; itSet!=itSetEnd; ++itSet) {
270 if (!(**itSet).type(Trk::TrackStateOnSurface::Perigee)) {
271 auto trackpar=(**itSet).trackParameters() ? (**itSet).trackParameters()->uniqueClone() : nullptr;
272 auto measurement=(**itSet).measurementOnTrack() ? (**itSet).measurementOnTrack()->uniqueClone() : nullptr;
273 auto fitQual=(**itSet).fitQualityOnSurface() ;
274 auto mateff=(**itSet).materialEffectsOnTrack() ? (**itSet).materialEffectsOnTrack()->uniqueClone() : nullptr;
275 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
277 else if ((**itSet).type(Trk::TrackStateOnSurface::Outlier)) typePattern.set(Trk::TrackStateOnSurface::Outlier);
278 else if ((**itSet).type(Trk::TrackStateOnSurface::Scatterer)) typePattern.set(Trk::TrackStateOnSurface::Scatterer);
279 else if ((**itSet).type(Trk::TrackStateOnSurface::BremPoint)) typePattern.set(Trk::TrackStateOnSurface::BremPoint);
280 trajectory->push_back(
281 new Trk::TrackStateOnSurface(fitQual,
282 std::move(measurement),
283 std::move(trackpar),
284 std::move(mateff),
285 typePattern));
286 }
287 }
288 bool peradded=false;
289 itSet = trajectory->begin()+1;
290 itSetEnd = trajectory->end();
291 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
292 typePattern.set(Trk::TrackStateOnSurface::Perigee);
293 const auto myPosition {myper->position()};
294 const auto myMomentum {myper->momentum()};
295 const Trk::TrackStateOnSurface* pertsos =
296 new Trk::TrackStateOnSurface(nullptr,
297 std::move(myper),
298 nullptr,
299 typePattern);
300
301 int index=1;
302 for ( ; itSet!=itSetEnd; ++itSet) {
303 double inprod1=((**itSet).trackParameters()->position()-myPosition).dot(myMomentum);
304 --itSet;
305 double inprod2=((**itSet).trackParameters()->position()-myPosition).dot(myMomentum);
306 ++itSet;
307 if (inprod1>0 && inprod2<0) {
308 trajectory->insert(trajectory->begin()+index,pertsos);
309 peradded=true;
310 break;
311 }
312 index++;
313 }
314 if (!peradded){
315 itSet = trajectory->begin();
316 double inprod=((**itSet).trackParameters()->position()-myPosition).dot(myMomentum);
317 if (inprod>0) trajectory->insert(trajectory->begin(),pertsos);
318 else trajectory->push_back(pertsos);
319 }
320 std::unique_ptr<Trk::Track> track =
321 std::make_unique<Trk::Track>(fittedTrack->info(),
322 std::move(trajectory),
323 fittedTrack->fitQuality()->uniqueClone());
324 fittedTrack = std::move(track);
325 }
326 }
327 if(fittedTrack){
328
329 int nHT=nHTHits(fittedTrack.get());
330 ATH_MSG_DEBUG("Number of HT hits: "<<nHT);
331 ATH_MSG_DEBUG(" Successful fit of track.");
332 if ((*iseg)->fitQuality()) ATH_MSG_DEBUG("Quality of Segment: chi^2 /ndof "<<(*iseg)->fitQuality()->chiSquared()<<" / "<<(*iseg)->fitQuality()->numberDoF());
333 ATH_MSG_DEBUG("Quality of Track: chi^2 /ndof "<<fittedTrack->fitQuality()->chiSquared()<<" / "<<fittedTrack->fitQuality()->numberDoF());
334 ATH_MSG_DEBUG("Noise probability: "<<getNoiseProbability(fittedTrack.get()));
335 ATH_MSG_DEBUG((*fittedTrack));
336
337 if( nTRTHits(fittedTrack.get())>=m_minTRTHits){
338 if(getNoiseProbability(fittedTrack.get())>m_noiseCut){
339 double truefraction=getRealFractionTRT(fittedTrack.get(),ctx);
340
341 int nhits=(*iseg)->numberOfMeasurementBases();
342 ATH_MSG_DEBUG("Real/Noise : "<< truefraction << " chi2="<<fittedTrack->fitQuality()->chiSquared()/double(fittedTrack->fitQuality()->numberDoF()));
343 if(truefraction>0.5){
344 ATH_MSG_DEBUG("==> Real Track");
345
346 if(m_MapReal.find(nhits)==m_MapReal.end()){
347 m_MapReal[nhits]=1;
348 }else{
349 m_MapReal[nhits]++;
350 }
351
353 m_noiseratio+=(1-truefraction);
354 }else{
355 ATH_MSG_DEBUG(" ==> Fake Track");
356
357 if(m_MapFake.find(nhits)==m_MapFake.end()){
358 m_MapFake[nhits]=1;
359 }else{
360 m_MapFake[nhits]++;
361 }
362
364 }
365 }
366 output_track_collection.push_back(std::move(fittedTrack));
367 }else{
368 ATH_MSG_DEBUG("This tracks has only "<<nTRTHits(fittedTrack.get())<<" Hits! Will reject it!");
369 }
370
371 }else{
372 ATH_MSG_DEBUG("Fit did not converge!");
373 } //end of if(fittedTrack)
374
375 delete inputMatchLine;
376 delete inputMatchPerigee;
377
378 } //end of if: (*iseg)->numberOfMeasurementBases()>0
379 } //end of loop over segments
380
381 std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map;
382 if (m_assoTool.isEnabled()) {
383 // create internal PRD-to-track map
384 prd_to_track_map = m_assoTool->createPRDtoTrackMap();
385 if (!m_inputAssoMapName.key().empty()) {
387 if (!input_asso_map.isValid()) {
388 ATH_MSG_FATAL("No valid input PRT-to-track map with key " << m_inputAssoMapName.key());
389 }
390 *prd_to_track_map = *input_asso_map;
391 ATH_MSG_INFO("PRD to track map input " << m_inputAssoMapName.key() );
392 }
393 for (const std::unique_ptr<Trk::Track> &track : output_track_collection) {
394 ATH_CHECK( m_assoTool->addPRDs(*prd_to_track_map, *track) );
395 }
396 }
397 // @TODO sort output track collection ?
398 final_outputTrackCollection->reserve(output_track_collection.size());
399 if (m_trkSummaryTool.isEnabled()) {
400 for (std::unique_ptr<Trk::Track> &track : output_track_collection) {
401 m_trkSummaryTool->computeAndReplaceTrackSummary(ctx, *track,prd_to_track_map.get());
402 final_outputTrackCollection->push_back(std::move(track));
403 }
404 }
405 else {
406 for (std::unique_ptr<Trk::Track> &track : output_track_collection) {
407 final_outputTrackCollection->push_back(std::move(track));
408 }
409 }
410 if (!m_assoMapName.key().empty()) {
411 ATH_CHECK(SG::WriteHandle<Trk::PRDtoTrackMap>(m_assoMapName,ctx).record(std::move(prd_to_track_map)));
412 }
413
414 if (!final_outputTrackCollection.isValid()) {
415 // @TODO never reached (?)
416 ATH_MSG_ERROR("Could not write track collection " << m_outputTrackCollectionName.key());
417 return StatusCode::FAILURE;
418 //return sc;
419 }
420
421 return sc;
422}
423
424int InDet::TRT_SegmentsToTrack::getNumberReal(const InDet::TRT_DriftCircle* driftcircle,const EventContext& ctx) const
425{
426 int numBarcodes = 0;
427 using iter = PRD_MultiTruthCollection::const_iterator;
428
429 if(m_multiTruthCollectionTRTName.empty()) return 0;
430
431 else{
433 if(truthCollectionTRT.isValid()){
434 std::pair<iter,iter> range = truthCollectionTRT->equal_range(driftcircle->identify());
435 numBarcodes+=std::distance(range.first,range.second);
436 }
437 }
438 return numBarcodes;
439}
440
441
442
443double InDet::TRT_SegmentsToTrack::getRealFractionTRT(const Trk::Track *track,const EventContext& ctx) const
444{
445 double fraction=0.;
446 int nDriftReal=0;
447 int nDriftNoise=0;
448
449 //loop over the hits
450 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
451
452 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
453 if (hitOnTrack) {
454 const Identifier& surfaceID = hitOnTrack->identify();
455
456 //take only TRT hits
457 if(m_idHelper->is_trt(surfaceID)){
458
459 const InDet::TRT_DriftCircleOnTrack *dcot= dynamic_cast <const InDet::TRT_DriftCircleOnTrack*>(hitOnTrack);
460 if(dcot) {
461 const InDet::TRT_DriftCircle *dc=dcot->prepRawData();
462
463 if(dc){
464 int nreal=getNumberReal(dc,ctx);
465
466 if(nreal>0) nDriftReal++;
467 else nDriftNoise++;
468
469 }
470 }
471 }
472 }
473 }
474
475 if(nDriftReal>0)
476 fraction=double(nDriftReal)/double(nDriftNoise+nDriftReal);
477
478 return fraction;
479}
480
481
483{
484
485 int nHT=0;
486
487 //loop over the hits
488 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
489
490 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
491 if (hitOnTrack != nullptr) {
492 const Identifier& surfaceID = hitOnTrack->identify();
493
494 //take only TRT hits
495 if(m_idHelper->is_trt(surfaceID) && !tsos->type(Trk::TrackStateOnSurface::Outlier)){
496 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(hitOnTrack);
497 if(trtcirc) {
498 if(trtcirc->highLevel()){
499 nHT++;
500 }
501 }
502 }
503 }
504 }
505
506 return nHT;
507}
508
509
510
512{
513 int nhits=0;
514
515 //loop over the hits
516 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
517
518 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
519 if (hitOnTrack != nullptr) {
520 const Identifier& surfaceID = hitOnTrack->identify();
521
522 //take only TRT hits
523 if(m_idHelper->is_trt(surfaceID) && !tsos->type(Trk::TrackStateOnSurface::Outlier)){
524 nhits++;
525 }
526 }
527 }
528
529 return nhits;
530}
531
532
534{
535 double fraction=0.;
536 int nDriftReal=0;
537 int nDriftNoise=0;
538
539 //loop over the hits
540 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
541 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
542 if (hitOnTrack) {
543 const Identifier& surfaceID = hitOnTrack->identify();
544
545 //take only TRT hits
546 if(m_idHelper->is_trt(surfaceID)){
547
548 const InDet::TRT_DriftCircleOnTrack *dcot= dynamic_cast <const InDet::TRT_DriftCircleOnTrack*>(hitOnTrack);
549 if (dcot) {
550 const InDet::TRT_DriftCircle *dc=dcot->prepRawData();
551
552 if(dc){
553
554 if(dc->isNoise())
555 nDriftNoise++;
556 else
557 nDriftReal++;
558 }
559 }
560 }
561 }
562 }
563
564 if(nDriftReal>0)
565 fraction=double(nDriftReal)/double(nDriftNoise+nDriftReal);
566
567 return fraction;
568}
569
570
571
572void InDet::TRT_SegmentsToTrack::combineSegments(const EventContext& ctx) const
573{
574 //Idea:
575 // - get from endcap segment z-phi dependence
576 // - get from barrel segment r-phi dependence and z dependence from endcap segment fit
577
578 int n_combined_fit=0;
581
582 StatusCode sc;
583
584 SG::WriteHandle<TrackCollection> outputCombiCollection(m_BECCollectionName,ctx);
585 sc = outputCombiCollection.record(std::make_unique<TrackCollection>());
586 if (sc.isFailure()) return;
587
588 if (!BarrelSegments.isValid()){
589 ATH_MSG_FATAL("Could not open barrel segments collection : " << m_barrelSegments.key());
590 return;
591 }
592
593 if (!EndcapSegments.isValid()) {
594 ATH_MSG_FATAL("Could not open endcap segments collection : " << m_endcapSegments.key());
595 return;
596 }
597
598 ATH_MSG_VERBOSE("Got both barrel and endcap segment collections of size "<<BarrelSegments->size()<<" "<<EndcapSegments->size());
599
600 Trk::SegmentCollection::const_iterator iseg = BarrelSegments->begin();
601 Trk::SegmentCollection::const_iterator isegE = BarrelSegments->end();
602
603 int scount=0;
604 for(;iseg!=isegE;++iseg,scount++){
605 ATH_MSG_VERBOSE("Barrel Segment "<<scount<<" : phi="<<(*iseg)->localParameters()[Trk::phi]);
606 }
607
608 iseg = EndcapSegments->begin();
609 isegE = EndcapSegments->end();
610
611 scount=0;
612 for(;iseg!=isegE;++iseg,scount++){
613 ATH_MSG_VERBOSE("Endcap Segment "<<scount<<" : phi="<<(*iseg)->localParameters()[Trk::phi]);
614 }
615
616 if(BarrelSegments->size()==1 && EndcapSegments->size()==1){
617 ATH_MSG_VERBOSE("Here we go: one barrel segment and one endcap segment!");
618
619 Trk::SegmentCollection::const_iterator isegBarrel = BarrelSegments->begin();
620 Trk::SegmentCollection::const_iterator isegBarrelE = BarrelSegments->end();
621
622 Trk::SegmentCollection::const_iterator isegEndcap = EndcapSegments->begin();
623 Trk::SegmentCollection::const_iterator isegEndcapE = EndcapSegments->end();
624
625 //loop over all Barrel Segments
626 for(;isegBarrel!=isegBarrelE;++isegBarrel){
627 for(;isegEndcap!=isegEndcapE;++isegEndcap){
628
629 std::vector< Trk::PseudoMeasurementOnTrack*> tobedeleted;
630
631 ATH_MSG_VERBOSE("Barrel Segment : phi="<<(*isegBarrel)->localParameters()[Trk::phi]<<" with "<<(*isegBarrel)->numberOfMeasurementBases()<<" hits");
632 ATH_MSG_VERBOSE("Endcap Segment : phi="<<(*isegEndcap)->localParameters()[Trk::phi]<<" with "<<(*isegEndcap)->numberOfMeasurementBases()<<" hits");
633
634 int count=0;
635 Trk::MeasurementSet myset,myset2,echits=(*isegEndcap)->containedMeasurements();
636
637 bool barreldown=((*isegBarrel)->measurement((*isegBarrel)->numberOfMeasurementBases()/2)->globalPosition().y()<0);
638 double theta=0;
639 if((*isegEndcap)->localParameters().contains(Trk::theta)){
640 theta = (*isegEndcap)->localParameters()[Trk::theta];
641 }
642
643 //correct theta to point towards the barrel
644 if(( (*isegEndcap)->globalPosition().y()>0 && (*isegEndcap)->globalPosition().z()>0) ||
645 ((*isegEndcap)->globalPosition().y()<0 && (*isegEndcap)->globalPosition().z()<0)
646 ){
647 //endcap A top pointing to barrel A bottom or Barrel C top pointing to Endcap C bottom
648 //--> Theta between 90 and 180 degrees
649 if(theta<M_PI/2.) {
651 std::reverse(echits.begin(),echits.end());
652 }
653 }else{
654 //Theta between 0 and 90 degrees
655 if(theta>M_PI/2.) {
657 std::reverse(echits.begin(),echits.end());
658 }
659 }
660
661 //decide if barrel or endcap hits come first depending on global position of segments
662
663 if(!barreldown && (*isegEndcap)->globalPosition().y()>0){
664 ATH_MSG_VERBOSE("Both barrel and endcap segments in top sectors, won't fit");
665 continue;
666 }
667
668 if(barreldown && (*isegEndcap)->globalPosition().y()<0){
669 ATH_MSG_VERBOSE("Both barrel and endcap segments in lower sectors, won't fit");
670 continue;
671 }
672 int firstechit=0,lastechit=0;
673 if((*isegEndcap)->globalPosition().y()>0){
674 //first endcap then barrel
675 for(int i=0;i<(int)echits.size();++i){
676 const Trk::MeasurementBase *meas=echits[i];
677 const Amg::VectorX LocalParameters = meas->localParameters();
678 const Amg::MatrixX LocalErrorMatrix = meas->localCovariance();
679 double z=meas->globalPosition().z();
680 double phi=meas->globalPosition().phi();
681 double r=meas->globalPosition().perp();
682
683 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(meas);
684 if(trtcirc){
685 myset.push_back(meas);
686 ATH_MSG_VERBOSE("Endcap : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
687 count++;
688 }
689 }
690 firstechit=0;
691 lastechit=count-1;
692
693 for(unsigned int i=0;i<(*isegBarrel)->numberOfMeasurementBases();++i){
694 const Amg::VectorX LocalParameters = (*isegBarrel)->measurement(i)->localParameters();
695 const Amg::MatrixX LocalErrorMatrix = (*isegBarrel)->measurement(i)->localCovariance();
696 double z=(*isegBarrel)->measurement(i)->globalPosition().z();
697 double phi=(*isegBarrel)->measurement(i)->globalPosition().phi();
698 double r=(*isegBarrel)->measurement(i)->globalPosition().perp();
699
700 const Trk::MeasurementBase *mesb=(*isegBarrel)->measurement(i);
701 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(mesb);
702 if(trtcirc){
703 myset.push_back((*isegBarrel)->measurement(i));
704 ATH_MSG_VERBOSE("Barrel : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
705 count++;
706 }
707
708 }
709 }else{
710 //first barrel then endcap
711 for(unsigned int i=0;i<(*isegBarrel)->numberOfMeasurementBases();++i){
712 const Amg::VectorX LocalParameters = (*isegBarrel)->measurement(i)->localParameters();
713 const Amg::MatrixX LocalErrorMatrix = (*isegBarrel)->measurement(i)->localCovariance();
714 double z=(*isegBarrel)->measurement(i)->globalPosition().z();
715 double phi=(*isegBarrel)->measurement(i)->globalPosition().phi();
716 double r=(*isegBarrel)->measurement(i)->globalPosition().perp();
717
718 const Trk::MeasurementBase *mesb=(*isegBarrel)->measurement(i);
719 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(mesb);
720 if(trtcirc){
721 myset.push_back((*isegBarrel)->measurement(i));
722 ATH_MSG_VERBOSE("Barrel : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
723 count++;
724 }
725
726 }
727 firstechit=count;
728
729 for(int i=0;i<(int)echits.size();++i){
730 const Trk::MeasurementBase *meas=echits[i];
731 const Amg::VectorX LocalParameters = meas->localParameters();
732 const Amg::MatrixX LocalErrorMatrix = meas->localCovariance();
733 double z=meas->globalPosition().z();
734 double phi=meas->globalPosition().phi();
735 double r=meas->globalPosition().perp();
736
737 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(meas);
738 if(trtcirc){
739 myset.push_back(meas);
740 ATH_MSG_VERBOSE("Endcap : (phi,r,z) = ( "<<phi<<" , "<<r<<" , "<<z<<" ) ");
741 count++;
742 }
743
744 }
745 lastechit=count-1;
746 }
747
748
749
750 Amg::Vector3D inputMatchingPos((*isegBarrel)->globalPosition());
751
752 if((*isegEndcap)->globalPosition().y()>0)
753 inputMatchingPos=(*isegEndcap)->globalPosition();
754
755 Amg::Vector3D inputMatchingMom;
756 double p = 10e7;
757
758 if((*isegBarrel)->localParameters().contains(Trk::qOverP)){
759 p = ((*isegBarrel)->localParameters()[Trk::qOverP]!=0.) ? fabs(1./((*isegBarrel)->localParameters()[Trk::qOverP])) : 10e7;
760 }
761
762 double phi=0.;
763 if((*isegBarrel)->localParameters().contains(Trk::phi)){
764 phi = (*isegBarrel)->localParameters()[Trk::phi];
765 }
766
767
768 inputMatchingMom[Trk::px] = p * cos(phi) * sin(theta);
769 inputMatchingMom[Trk::py] = p * sin(phi) * sin(theta);
770 inputMatchingMom[Trk::pz] = p * cos(theta);
771
772
773 ATH_MSG_VERBOSE("Global position: "<<inputMatchingPos<<" Globalmomentum: "<<inputMatchingMom);
774
775
776
777 //add two pseudomeasurements at the beginning and at the end of the track
778 Trk::MeasurementSet::const_iterator mit;
779 Trk::MeasurementSet::const_iterator mitE=myset.end();
780
781 int count2=0;
782 for(mit=myset.begin();mit!=mitE;++mit){
783 myset2.push_back(*mit);
784 if(count2==firstechit || count2==lastechit){
785 const InDet::TRT_DriftCircleOnTrack* trtcirc = dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(*mit);
786 if(trtcirc){
787 const Trk::StraightLineSurface *line=dynamic_cast<const
789 if (line) {
790 //add pseudomeasurement
791 double locz=-200.;
792 if ((count2==firstechit && firstechit!=0) || (count2==lastechit && firstechit==0)) locz=200;
794 Trk::LocalParameters par(dp);
795
796 Amg::MatrixX cov(1,1);
797 cov(0,0) = 16./12. ; // take actual length of straw instead !!!!!
798
799 //create new surface
800 Amg::Vector3D C = line->transform().translation();
801
802 //decide on movement
803
804 const Amg::Vector3D& gpos=(*mit)->globalPosition();
805
806 if(fabs(gpos.z())>800){
807 if(theta>M_PI/2.){
808 C[2]-=1.;
809 }else{
810 C[2]+=1.;
811 }
812 }else{
813 C[1]-=1.;
814 }
815
816
818 T = line->transform().rotation();
819 T *= Amg::Translation3D(C.x(),C.y(),C.z());
821
823 std::move(cov),
824 *surface);
825
826 tobedeleted.push_back(pseudo);
827
828 delete surface;
829
830 myset2.push_back(pseudo);
831 }
832 }
833 }
834 count2++;
835 }
836
837
838
839 const Trk::StraightLineSurface* testSf;
840 if((*isegEndcap)->globalPosition().y()>0){
841 testSf= dynamic_cast<const Trk::StraightLineSurface*>(&((*isegEndcap)->associatedSurface()));
842 }else{
843 testSf= dynamic_cast<const Trk::StraightLineSurface*>(&((*isegBarrel)->associatedSurface()));
844 }
845
846 const Trk::AtaStraightLine* inputMatchLine = nullptr;
847 const Trk::Perigee* inputMatchPerigee = nullptr;
848
849 if(!testSf){
850 ATH_MSG_VERBOSE("No straightLineSurface !! Trying Perigee ...");
851
852 const Trk::PerigeeSurface *testPSf=dynamic_cast<const Trk::PerigeeSurface*>(&((*isegBarrel)->associatedSurface()));
853
854 if(!testPSf){
855 ATH_MSG_VERBOSE("Associated surface dynamic_cast into PerigeeSurface failed. "<<(*isegBarrel)->associatedSurface());
856 ATH_MSG_VERBOSE("Leaving input matching perigee as nullptr, will not get a fittedTrack");
857 }else{
858 ATH_MSG_VERBOSE("Ok, it seems to be a PerigeeSurface");
859 inputMatchPerigee = new Trk::Perigee(inputMatchingPos,inputMatchingMom, 1., *testPSf);
860 }
861
862 }else{
863 inputMatchLine = new Trk::AtaStraightLine(inputMatchingPos,inputMatchingMom, 1., *testSf);
864 ATH_MSG_VERBOSE("Created testSf : " << (*inputMatchLine));
865 }
866
867 Amg::Vector3D startMomentum( 0., 0., 1.);
868 std::unique_ptr<Trk::Track> fittedTrack;
870 if(inputMatchLine){
871 fittedTrack=m_trackFitter->fit(ctx,
872 myset2,
873 *inputMatchLine,
874 false,
876 );
877 }else if (inputMatchPerigee){
878 fittedTrack=m_trackFitter->fit(ctx,
879 myset2,
880 *inputMatchPerigee,
881 false,
883 );
884 }
885 }else{
886 if(inputMatchLine){
887 fittedTrack=m_trackFitter->fit(ctx,
888 myset2,
889 *inputMatchLine,
890 false,
892 );
893 }else if (inputMatchPerigee){
894 fittedTrack=m_trackFitter->fit(ctx,
895 myset2,
896 *inputMatchPerigee,
897 false,
899 );
900 }
901 }
902
903 if(fittedTrack){
904 n_combined_fit++;
905 ATH_MSG_DEBUG("Successful Barrel+Endcap fit of segment. ");
906 ATH_MSG_DEBUG("Quality of Track: "<<fittedTrack->fitQuality()->chiSquared()<<" / "<<fittedTrack->fitQuality()->numberDoF());
907 ATH_MSG_VERBOSE(*fittedTrack);
908 outputCombiCollection->push_back(std::move(fittedTrack));
909}
910
911 delete inputMatchPerigee;
912 delete inputMatchLine;
913
914 for(size_t i=0;i<tobedeleted.size();i++)
915 delete tobedeleted[i];
916 tobedeleted.clear();
917 }
918 }
919 }
920 m_n_combined_fit += n_combined_fit;
921
922 if (!outputCombiCollection.isValid()) {
923 ATH_MSG_ERROR("Could not write track Barrel+EC collection TRT_Barrel_EC");
924 }
925}
#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.
StatusCode execute(const EventContext &ctx)
Execute method.
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:148
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.