31 const std::string &
name,
32 const IInterface *
parent) :
34 m_fieldUnitConversion(1000.),
35 m_extrapolator(
"Trk::Extrapolator/InDetExtrapolator"),
36 m_scoringTool(
"Trk::TrackScoringTool/TrackScoringTool"),
39 declareInterface<InDet::ITRT_SegmentToTrackTool>(
this );
76 return StatusCode::SUCCESS;
101 std::string s1;
for(
int i=0;
i<
n; ++
i) s1.append(
" "); s1.append(
"|");
103 std::string
s2;
for(
int i=0;
i<
n; ++
i)
s2.append(
" ");
s2.append(
"|");
105 std::string s5;
for(
int i=0;
i<
n; ++
i) s5.append(
" "); s5.append(
"|");
109 <<
"|----------------------------------------------------------------------"
110 <<
"-------------------|"<<std::endl;
111 out<<
"| Tool for final track refitting | "<<
m_fitterTool.type() <<s1<<std::endl;
114 out<<
"|----------------------------------------------------------------------"
115 <<
"-------------------|";
139 ATH_MSG_DEBUG(
"Transforming the TRT segment into a track...");
168 ATH_MSG_DEBUG(
"Could not get initial TRT segment parameters! ");
174 auto ntsos = std::make_unique<Trk::TrackStates>();
187 std::unique_ptr<Trk::TrackParameters>
tmp =
189 std::unique_ptr<Trk::Perigee> perParm =
nullptr;
197 ATH_MSG_DEBUG(
"Failed to build perigee parameters.Discard...");
205 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
209 nullptr, std::move(perParm),
nullptr, typePattern);
211 ntsos->push_back(par_tsos);
220 double pseudotheta = 0;
223 const Trk::Surface *firstsurf =
nullptr, *firstecsurf =
nullptr,
227 int nbarrel = 0, nendcap = 0;
229 std::vector<std::pair<double, double>> points;
293 if (!points.empty() &&
294 std::abs(tmpphi - oldphi) >
M_PI) {
325 ntsos->push_back(seg_tsos);
346 double myqoverp = 0, myphi = 0, myd0 = 0, myz0 = 0, mytheta = pseudotheta;
360 std::unique_ptr<const Trk::TrackParameters>
tmp =
362 std::unique_ptr<const Trk::Perigee> tempper =
nullptr;
374 myd0 = tempper->parameters()[
Trk::d0];
375 myphi = tempper->parameters()[
Trk::phi0];
383 double sx = 0,
sy = 0, sxx = 0, sxy = 0,
d = 0;
384 float zmin = points.empty() ? 0 : points.begin()->first,
zmax = 0;
387 for (
auto & point : points) {
390 sxy += point.first * point.second;
391 sxx += point.first * point.first;
392 if (std::abs(point.first) > std::abs(
zmax)) {
395 if (std::abs(point.first) < std::abs(
zmin)) {
400 if (std::abs(pseudotheta) < 1.
e-6) {
407 double diff_z (meas_zmax.z() - meas_zmin.z());
408 if (std::abs(diff_z)>1
e-6) {
409 double diff_r( meas_zmax.perp() - meas_zmin.perp());
410 pseudotheta = std::atan2(diff_r, diff_z);
411 ATH_MSG_DEBUG(
"Initial pseudo theta is zero. Compute pseudo from inner- and outermost endcap measurements. delta R: " <<
412 meas_zmax.perp() <<
" - " << meas_zmin.perp() <<
" = " << diff_r
413 <<
" , diff Z: " << meas_zmax.z() <<
" - " << meas_zmin.z()
415 <<
" " << pseudotheta);
419 if (std::abs(pseudotheta) < 1.
e-6) {
420 constexpr std::array<float,2> boundary_r {644., 1004.};
422 bool is_across_sides=std::signbit(
zmin)!=std::signbit(
zmax);
423 double r_path=is_across_sides ? 2 * boundary_r[1] : boundary_r[1]-boundary_r[0];
426 if (surf_zmin && surf_zmax) {
427 bool is_reverse=std::abs(surf_zmin->
center().z())>std::abs(surf_zmax->
center().z());
434 std::array<const Trk::Surface *,2> boundary_surface{
435 is_reverse ? surf_zmax : surf_zmin,
436 is_reverse ? surf_zmin : surf_zmax};
438 std::array<Amg::Vector2D,2> translation;
439 std::array<Amg::Vector2D,2> height;
440 for (
unsigned int boundary_i=boundary_surface.size(); boundary_i-->0;) {
444 cylinder_bounds =
dynamic_cast<const Trk::CylinderBounds &
>(boundary_surface[boundary_i]->bounds());
445 height[boundary_i]= project2D( boundary_surface[boundary_i]->
transform().
rotation()
447 translation[boundary_i]=project2D( boundary_surface[boundary_i]->
transform().translation() );
450 r1 = (translation[1] + height[1] - ( translation[0] + height[0])).perp();
451 r2 = (translation[1] + height[1] - ( translation[0] - height[0])).perp();
455 pseudotheta = std::atan2(r_path,
zmax -
zmin);
456 ATH_MSG_DEBUG(
"Initial pseudo theta is zero. Pseudo theta from inner- and outermost surfaces. Deleta r " << r2 <<
" - " << r1 <<
" -> " << r_path
458 <<
" " << pseudotheta);
463 d = (points.size() * sxx -
sx *
sx);
464 double dphidz = ((points.size() * sxy -
sy *
sx) /
d);
465 myqoverp = (std::abs(pseudotheta) > 1
e-6)
466 ? -dphidz / (0.6 *
std::tan(pseudotheta))
479 double halfz2 = 200.;
485 Amg::Vector3D strawdir2 = -lastsurf->transform().rotation().col(2);
490 if (std::abs(lastsurf->center().z()) < 2650 *
mm) {
491 pos2 = lastsurf->center() + halfz2 * strawdir2;
493 double dr = std::abs(
std::tan(pseudotheta) * (lastsurf->center().z() -
494 firstsurf->
center().z()));
495 pos1 = firstsurf->
center() + (halfz -
dr) * strawdir1;
497 double dz = std::abs((pos2.perp() - firstsurf->
center().perp()) /
501 double z1 = pos2.z() + dz;
507 (lastsurf->center().z() - firstsurf->
center().z()));
508 pos2 = lastsurf->center() + (
dr - halfz2) * strawdir2;
509 pos1 = firstsurf->
center() - halfz * strawdir1;
516 lastsurf->center().z())) < 250 *
mm &&
517 std::abs(firstsurf->
center().z()) > 1000 *
mm) {
521 (**ntsos->begin()).measurementOnTrack();
525 newcov(1, 1) = (myqoverp != 0) ? .0001 * myqoverp * myqoverp : 1.
e-8;
529 std::make_unique<Trk::PseudoMeasurementOnTrack>(
534 ntsos->erase(ntsos->begin());
535 ntsos->insert(ntsos->begin(),
548 if (fieldCondObj ==
nullptr) {
550 "segToTrack: Failed to retrieve AtlasFieldCacheCondObj with key "
554 fieldCondObj->getInitializedCache(fieldCache);
562 double phideflection =
563 -.3 * (pos2 - pos1).
perp() * field1.z() * myqoverp /
std::sin(pseudotheta);
564 double precisephi = (nbarrel == 0)
565 ? (pos2 - pos1).phi() - .5 * phideflection
566 : (pos2 - pos1).
phi() + .5 * phideflection;
567 double radius = (myqoverp != 0. && field1.z() != 0.)
568 ? -
std::sin(pseudotheta) / (.3 * field1.z() * myqoverp)
570 double precisetheta =
572 ? std::atan2(std::abs(
radius * phideflection), pos2.z() - pos1.z())
574 if (precisetheta < 0)
575 precisetheta +=
M_PI;
576 if (precisephi < -
M_PI)
577 precisephi += 2 *
M_PI;
578 if (precisephi >
M_PI)
579 precisephi -= 2 *
M_PI;
589 ATH_MSG_ERROR(
"Cast of surface failed, should never happen");
598 m_extrapolator->extrapolateDirectly(ctx, ataline, persurf).release();
603 myphi = extrappar->parameters()[
Trk::phi0];
604 myd0 = extrappar->parameters()[
Trk::d0];
608 double z0 = extrappar->parameters()[
Trk::z0];
611 std::abs((
z0 - pos1.z()) / pos1.z()));
614 std::abs((
z0 - pos2.z()) / pos2.z()));
625 while (myphi < -
M_PI)
628 double P[5] = { myd0, myz0, myphi, mytheta, myqoverp };
634 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
638 nullptr, std::move(per),
nullptr, typePattern);
639 ntsos->insert(ntsos->begin(), seg_tsos);
670 if ((*parit)->covariance() &&
672 firstmeaspar = *parit;
674 }
while (firstmeaspar ==
nullptr &&
683 if (!perTrack || !perTrack->covariance()) {
684 ATH_MSG_ERROR(
"Cast of perigee fails, should never happen !");
687 ATH_MSG_VERBOSE (
"Perigee after refit with fudges to make it converge : " << (*perTrack) );
689 if(firstmeaspar && firstmeaspar->
position().perp()<2000*
mm && std::abs(firstmeaspar->
position().z())<3000*
mm){
694 double scaleZ = std::sqrt(tS.
localCovariance()(1,1))/std::sqrt( (fcovmat)(1,1));
695 double scaleTheta = std::sqrt(tS.
localCovariance()(3,3))/std::sqrt( (fcovmat)(3,3));
697 fcovmat(1,0)=scaleZ*((fcovmat)(1,0));
698 fcovmat(0,1) = (fcovmat)(1,0);
700 fcovmat(2,1)=scaleZ*((fcovmat)(2,1));
701 fcovmat(1,2) = (fcovmat)(2,1);
702 fcovmat(3,1)=scaleZ*scaleTheta*((fcovmat)(3,1));
703 fcovmat(1,3) = (fcovmat)(3,1);
704 fcovmat(4,1)=scaleZ*((fcovmat)(4,1));
705 fcovmat(1,4) = (fcovmat)(4,1);
706 fcovmat(3,0)=scaleTheta*((fcovmat)(3,0));
707 fcovmat(0,3) = (fcovmat)(3,0);
708 fcovmat(3,2)=scaleTheta*((fcovmat)(3,2));
709 fcovmat(2,3) = (fcovmat)(3,2);
711 fcovmat(4,3)=scaleTheta*((fcovmat)(4,3));
712 fcovmat(3,4) = (fcovmat)(4,3);
723 std::move(fcovmat)).release();
733 delete updatedPars; updatedPars =
nullptr;
735 if (!newperpar || !newperpar->covariance()) {
736 ATH_MSG_WARNING (
"Can not hack perigee parameters, extrapolation failed");
737 delete newperpar; newperpar =
nullptr;
744 errmat = *newperpar->covariance();
745 delete newperpar; newperpar =
nullptr;
748 if( CM(1,1)==0.||CM(3,3)==0. ) {
749 ATH_MSG_DEBUG (
"Hacked perigee covariance is CRAP, reject track");
750 delete fitTrack;
return nullptr;
752 ATH_MSG_VERBOSE (
"Perigee after fit with scaled covariance matrix : " << *perTrack);
766 ATH_MSG_DEBUG (
"Checking whether the TRT segment has already been used...");
772 if (
m_assoTool.isEnabled()&& !prd_to_track_map)
ATH_MSG_ERROR(
"PRDtoTrackMap to be used but not provided by the client");
782 if (!trtcircle)
continue;
786 if(!RawDataClus)
continue;
791 if(
m_assoTool.isEnabled() && prd_to_track_map && prd_to_track_map->
isUsed(*RawDataClus)) nShared++;
795 ATH_MSG_DEBUG (
"Too many shared hits.Will drop the TRT segment");
806 ATH_MSG_DEBUG (
"Try to recover low TRT DC segments in crack...");
809 int nEC = 0;
int nBRL = 0;
int firstWheel = -999;
int lastLayer = -999;
820 if(!trtcircle)
continue;
826 if (isB==2 || isB==-2) {
831 else if (isB==1 || isB==-1) {
839 return (nEC>0 && nBRL>0) ||
841 (nEC==0 && nBRL>0 && lastLayer<2) ||
843 (nEC>0 && nBRL==0 && (firstWheel>10 || firstWheel<2));
880 std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map;
882 prd_to_track_map=
m_assoTool->createPRDtoTrackMap();
883 if (prd_to_track_map_in) {
884 *prd_to_track_map = *prd_to_track_map_in;
889 std::unique_ptr<TrackCollection> final_tracks = std::make_unique<TrackCollection>();
893 [](
const std::pair< Trk::TrackScore, Trk::Track* > &
a,
894 const std::pair< Trk::TrackScore, Trk::Track* > &
b)
895 { return a.first < b.first; });
897 for (std::pair< Trk::TrackScore, Trk::Track* > &track_score : event_data.
m_trackScores) {
899 ATH_MSG_DEBUG (
"--- Trying next track "<<track_score.second<<
"\t with score "<<-track_score.first);
906 const Trk::TrackStates* tsos = (track_score.second)->trackStateOnSurfaces();
936 ATH_MSG_DEBUG (
"TRT-only has " << nHits <<
" hits and " << nShared <<
" of them are shared");
943 delete track_score.second;
948 final_tracks->
push_back(track_score.second);
955 if(
m_assoTool->addPRDs(*prd_to_track_map,*(track_score.second)).isFailure()) {
962 return final_tracks.release();