22 #include "TGraphErrors.h"
24 #include "TVirtualFitter.h"
37 (
const std::string&
t,
const std::string&
n,
const IInterface*
p)
40 m_riomakerD (
"InDet::TRT_DriftCircleOnTrackTool/TRT_DriftCircleOnTrackTool" ),
41 m_riomakerN (
"InDet::TRT_DriftCircleOnTrackNoDriftTimeTool/TRT_DriftCircleOnTrackNoDriftTimeTool"),
42 m_useDriftTime(false),
44 m_scaleFactorDrift(1.0),
45 m_scaleTubeNoise(1.0),
51 declareInterface<ITRT_TrackSegmentsMaker>(
this);
112 return StatusCode::FAILURE;
119 return StatusCode::FAILURE;
128 return StatusCode::FAILURE;
142 std::string fit_name1=
"ztanphi";
143 std::string fit_name2=
"zphi";
144 std::string fit_name3=
"zphi_ap";
181 std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
185 std::unique_ptr<TRT_TrackSegmentsMaker_ECcosmics::EventData>
186 event_data = std::make_unique<TRT_TrackSegmentsMaker_ECcosmics::EventData>();
193 it=event_data->m_goodHits.begin();
194 itE=event_data->m_goodHits.end();
206 else if(
phi>15 )
phi = 0 ;
211 int zslice=
int((std::abs(
sc.z())-800.)/100.);
213 event_data->m_sectors[
z][zslice][
phi].push_back(*
it);
217 ATH_MSG_DEBUG(
"Number of good driftcircles: "<<event_data->m_goodHits.size());
218 ATH_MSG_DEBUG(
"Number of noise driftcircles: "<<event_data->m_noiseHits.size());
220 return std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>(event_data.release());
227 std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
229 (
const EventContext& ,
const std::vector<IdentifierHash>& vTRT)
const
232 std::unique_ptr<TRT_TrackSegmentsMaker_ECcosmics::EventData>
233 event_data = std::make_unique<TRT_TrackSegmentsMaker_ECcosmics::EventData>();
241 it=event_data->m_goodHits.begin();
242 itE=event_data->m_goodHits.end();
254 else if(
phi>15 )
phi = 0 ;
258 int zslice=
int((std::abs(
sc.z())-800.)/100.);
260 event_data->m_sectors[
z][zslice][
phi].push_back(*
it);
264 ATH_MSG_DEBUG(
"Number of good driftcircles: "<<event_data->m_goodHits.size());
265 ATH_MSG_DEBUG(
"Number of noise driftcircles: "<<event_data->m_noiseHits.size());
267 return std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>(event_data.release());
338 for(
int endcap=0;endcap<2;endcap++){
350 for(
int j=0;j<20;j++){
351 for(
int i=0;
i<16;
i++){
365 if(sector<0)
continue;
367 max=event_data.
m_sectors[endcap][zslice][sector].size();
379 event_data.
m_sectors[endcap][zslice][sector].clear();
391 std::vector<std::vector<const InDet::TRT_DriftCircle*> *>
::iterator sit,sitE;
393 sit=event_data.
m_seeds.begin();
396 for(;sit!=sitE;++sit){
421 std::vector<const InDet::TRT_DriftCircle*> dc;
424 dc.reserve(event_data.
m_sectors[endcap][zslice][sector].size());
439 for(;vit!=vitE;++vit){
450 if(dc.size()>=40)
return false;
458 for(;vit!=vitE;++vit){
469 shift=(phimax+phimin)/2.-M_PI_4;
470 ATH_MSG_VERBOSE(
"Phimin="<<phimin<<
" Phimax="<<phimax<<
" -> shift = "<<shift);
473 if(phimin<-M_PI_2 && phimax>M_PI_2){
475 ATH_MSG_VERBOSE(
"Boundary between pi and -pi!!! use the following shift: "<<shift);
480 for(vit=dc.begin();vit!=vitE;++vit){
484 double orig=
sc.phi();
486 double corr=orig-shift;
501 double p_best[3]={0,0,0};
505 for(
int j=
i+1;j<
count;j++){
542 for(
auto &
i : muster)
546 std::vector<const InDet::TRT_DriftCircle*> *seed=
new std::vector<const InDet::TRT_DriftCircle*>;
548 for(
int zsl=zslice-1;zsl<=zslice+1;zsl++){
549 for(
int ps=sector-1;ps<=sector+1;ps++){
552 if(zsl<0 || zsl>=20)
continue;
562 double pred_phi=
sc.z()*p_best[0]+p_best[1];
563 double corr=
sc.phi()-p_best[2];
566 if(
sc.z()==p_best[1]) {
576 if(std::abs(
phidiff(pred_phi,corr))<=4./650.){
577 seed->push_back(*
it);
580 muster[zsl-zslice+1][ps-sector+1]=1;
592 ATH_MSG_VERBOSE(
"\t"<<muster[0][0]<<
" "<<muster[1][0]<<
" "<<muster[2][0]);
593 ATH_MSG_VERBOSE(
"\t"<<muster[0][1]<<
" "<<muster[1][1]<<
" "<<muster[2][1]);
594 ATH_MSG_VERBOSE(
"\t"<<muster[0][2]<<
" "<<muster[1][2]<<
" "<<muster[2][2]);
597 if(muster[2][0] || muster[2][1] || muster[2][2]){
601 for(
int ps=sector-2;ps<=sector+2;ps++){
604 if(zsl<0 || zsl>=20)
continue;
614 double pred_phi=
sc.z()*p_best[0]+p_best[1];
615 double corr=
sc.phi()-p_best[2];
618 if(
sc.z()==p_best[1]) {
628 if(std::abs(
phidiff(pred_phi,corr))<=4./650.){
632 seed->push_back(*
it);
638 if(muster[0][0] || muster[0][1] || muster[0][2]){
642 for(
int ps=sector-2;ps<=sector+2;ps++){
645 if(zsl<0 || zsl>=20)
continue;
655 double pred_phi=
sc.z()*p_best[0]+p_best[1];
656 double corr=
sc.phi()-p_best[2];
659 if(
sc.z()==p_best[1]) {
669 if(std::abs(
phidiff(pred_phi,corr))<=4./650.){
673 seed->push_back(*
it);
691 for(;vit!=vitE;++vit){
697 if ( phi<0 ) phi = 15;
698 else if( phi>15 ) phi = 0 ;
702 int zslic=
int((std::abs(
sc.z())-800.)/100.);
704 event_data.
m_sectors[
z][zslic][phi].remove(*vit);
714 for(;lit!=litE;++lit){
724 if ( phi<0 ) phi = 15;
725 else if( phi>15 ) phi = 0 ;
728 int zsl=
int((std::abs(
sc.z())-800.)/100.);
730 if(std::abs(zsl-zslice)<2){
731 double pred_phi=
sc.z()*p_best[0]+p_best[1];
732 double corr=
sc.phi()-p_best[2];
735 if(
sc.z()==p_best[1]) {
745 if(std::abs(
phidiff(pred_phi,corr))<=4./650.){
747 seed->push_back(*lit);
760 event_data.
m_seeds.push_back(seed);
783 for(
int zsl=zslice-1;zsl<=zslice+1;zsl++){
784 for(
int ps=sector-1;ps<=sector+1;ps++){
787 if(zsl<0 || zsl>=20)
continue;
799 double pred_phi=
sc.z()*
p[0]+
p[1];
800 double corr=
sc.phi()-
p[2];
813 if(std::abs(
phidiff(pred_phi,corr))<=4./650.){
844 for(;vit!=vitE;++vit){
872 shift=(phimax+phimin)/2.-M_PI_4;
873 ATH_MSG_VERBOSE(
"Phimin="<<phimin<<
" Phimax="<<phimax<<
" shift="<<shift);
876 if(phimin<-M_PI_2 && phimax>M_PI_2){
878 ATH_MSG_VERBOSE(
"Boundary between pi and -pi!!! use the following shift: "<<shift);
887 double corr=orig-shift;
894 event_data.
m_a_tan_err[
i]=(1.15/700.)/(cosCorr*cosCorr);
906 std::vector<const InDet::TRT_DriftCircle*> tobeadded;
909 for(;lit!=litE;++lit){
913 double fitted_phi=
fit->Eval(
sc.z(),0.,0.);
916 if (fitted_phi >
M_PI) fitted_phi = std::fmod(fitted_phi+
M_PI,2.*
M_PI)-
M_PI;
917 else if(fitted_phi <-
M_PI) fitted_phi = std::fmod(fitted_phi-
M_PI,2.*
M_PI)+
M_PI;
925 for(;vit!=vitE && new_hit;++vit){
931 ATH_MSG_VERBOSE(
"\t\t good hit matched! fitted_phi="<<fitted_phi<<
" z=" <<
sc.z());
937 seed->push_back(*lit);
940 tobeadded.push_back(*lit);
946 std::sort(tobeadded.begin(),tobeadded.end(),
CompareDCz);
954 for(vit=tobeadded.begin();vit!=tobeadded.end();++vit){
977 seed->push_back(tobeadded[
i]);
991 seed->push_back(tobeadded[
i]);
1004 std::sort(seed->begin(),seed->end(),
CompareDCz);
1010 for(;vit!=vitE;++vit){
1035 shift=(phimax+phimin)/2.-M_PI_4;
1036 ATH_MSG_VERBOSE(
"Phimin="<<phimin<<
" Phimax="<<phimax<<
" shift="<<shift);
1039 if(phimin<-M_PI_2 && phimax>M_PI_2){
1041 ATH_MSG_VERBOSE(
"Boundary between pi and -pi!!! use the following shift: "<<shift);
1048 double corr=orig-shift;
1055 const auto cosCorr{
std::cos(corr)};
1056 event_data.
m_a_tan_err[
i]=(1.15/700.)/(cosCorr*cosCorr);
1067 for(;lit!=litE;++lit){
1075 double phi=
sc.phi();
1076 double fitted_phi=
fit->Eval(
sc.z(),0.,0.);
1079 if (fitted_phi >
M_PI) fitted_phi = std::fmod(fitted_phi+
M_PI,2.*
M_PI)-
M_PI;
1080 else if(fitted_phi <-
M_PI) fitted_phi = std::fmod(fitted_phi-
M_PI,2.*
M_PI)+
M_PI;
1083 if(
z*event_data.
m_a_z[0]<0)
continue;
1089 for(;vit!=vitE && new_hit;++vit){
1096 ATH_MSG_VERBOSE(
"\t\t noise hit matched! fitted_phi="<<fitted_phi<<
" z=" <<
sc.z());
1097 seed->push_back(*lit);
1099 ATH_MSG_VERBOSE(
"\t\t noise hit matched but too far away! fitted_phi="<<fitted_phi<<
" z=" <<
sc.z());
1106 std::sort(seed->begin(),seed->end(),
CompareDCy);
1110 Amg::Vector3D laststraw=((*seed)[seed->size()-1]->detectorElement()->strawCenter(
m_trtid->
straw((*seed)[seed->size()-1]->identify()) ));
1112 double z2=laststraw.z();
1113 double yfirst=firststraw.y();
1114 double ylast=laststraw.y();
1122 if (std::abs(yfirst-ylast)>50){
1126 std::sort(seed->begin(),seed->end(),
CompareDCz);
1130 if ((yfirst>0 && z1<0) || (yfirst<0 && z1>0)) std::sort(seed->begin(),seed->end(),
CompareDCz);
1133 firststraw=(*seed)[0]->detectorElement()->strawCenter(
m_trtid->
straw((*seed)[0]->identify()) );
1134 laststraw=(*seed)[seed->size()-1]->detectorElement()->strawCenter(
m_trtid->
straw((*seed)[seed->size()-1]->identify()) );
1140 Theta=
M_PI-std::atan2(400.,std::abs(z1-z2));
1143 Theta=std::atan2(400.,std::abs(z1-z2));
1147 double globaly=((*seed)[0]->detectorElement()->strawCenter(
m_trtid->
straw((*seed)[0]->identify()) )).
y();
1148 double firstphi=((*seed)[0]->detectorElement()->strawCenter(
m_trtid->
straw((*seed)[0]->identify()) )).phi();
1151 ATH_MSG_VERBOSE(
"Number of tube hits matching straight line: "<<seed->size());
1157 const Amg::Vector3D& sc_last = ((*seed)[seed->size()-1]->detectorElement()->strawCenter(
m_trtid->
straw((*seed)[seed->size()-1]->identify()) ));
1160 double tx1,tx2,ty1,ty2;
1168 double tphi=std::atan2(ty2-ty1,tx2-tx1);
1193 ATH_MSG_VERBOSE(
"globaly = "<<globaly<<
" phi="<<firstphi<<
" theta="<<Theta<<
" --> state = "<<state);
1200 for(;vit!=vitE;++vit){
1220 for(;vit!=vitE;++vit){
1224 double fitted_phi=
fit->Eval(
sc.z(),0.,0.);
1227 if (fitted_phi >
M_PI) fitted_phi = std::fmod(fitted_phi+
M_PI,2.*
M_PI)-
M_PI;
1228 else if(fitted_phi <-
M_PI) fitted_phi = std::fmod(fitted_phi-
M_PI,2.*
M_PI)+
M_PI;
1231 if(fitted_phi<
sc.phi())
sign=-1;
1235 double drifte = 2*std::sqrt((*vit)->localCovariance()(0,0));
1237 double straw_r=640+400./std::abs(z2-z1)*std::abs(
sc.z()-z1);
1239 double dphi=
sign*driftr/straw_r;
1268 for(;vit!=vitE;++vit){
1271 double fitted_phi=
fit->Eval(
sc.z(),0.,0.);
1275 double drifte = 2*std::sqrt((*vit)->localCovariance()(0,0));
1278 if(fitted_phi<
sc.phi())
sign=-1;
1280 double straw_r=640+400./std::abs(z2-z1)*std::abs(
sc.z()-z1);
1281 double dphi=
sign*driftr/straw_r;
1319 for(;vit!=vitE;++vit){
1323 double fitted_phi=
fit->Eval(
sc.z(),0.,0.);
1326 if (fitted_phi >
M_PI) fitted_phi = std::fmod(fitted_phi+
M_PI,2.*
M_PI)-
M_PI;
1327 else if(fitted_phi <-
M_PI) fitted_phi = std::fmod(fitted_phi-
M_PI,2.*
M_PI)+
M_PI;
1330 double drifte = 2*std::sqrt((*vit)->localCovariance()(0,0));
1333 if(fitted_phi<
sc.phi())
sign=-1;
1335 double straw_r=640+400./std::abs(z2-z1)*std::abs(
sc.z()-z1);
1336 double dphi=
sign*driftr/straw_r;
1357 if(
count>=400)
return;
1370 double initial_r=-10.;
1371 double initial_locz=0.;
1374 for(;vit!=vitE;++vit){
1376 (&((*vit)->detectorElement())->surface( (*vit)->identify()));
1387 if(std::abs(z2-z1)>0.000001){
1389 locz=400./std::abs(z2-z1)*std::abs(
z-z1)-200.;
1391 locz=200.-400./std::abs(z2-z1)*std::abs(
z-z1);
1394 double fitted_phi=
fit->Eval(
z,0.,0.);
1397 if (fitted_phi >
M_PI) fitted_phi = std::fmod(fitted_phi+
M_PI,2.*
M_PI)-
M_PI;
1398 else if(fitted_phi <-
M_PI) fitted_phi = std::fmod(fitted_phi-
M_PI,2.*
M_PI)+
M_PI;
1400 double fitted_r=(
phidiff(fitted_phi,
sc.phi()))*(840+locz);
1401 double temp_phi=fitted_phi;
1403 if(initial_r==-10. && std::abs(fitted_r)<4.0){
1426 bool useDrift=
false;
1430 double drifte = 2*std::sqrt((*vit)->localCovariance()(0,0));
1433 if(fitted_phi<
sc.phi())
sign=-1;
1435 double straw_r=640+400./std::abs(z2-z1)*std::abs(
sc.z()-z1);
1436 double dphi=
sign*driftr/straw_r;
1438 if(std::abs(
phidiff(fitted_phi,
sc.phi()-dphi)) < 3* drifte/straw_r){
1440 chi2+=(std::abs(fitted_r)-std::abs(driftr))*(std::abs(fitted_r)-std::abs(driftr))/(drifte*drifte);
1448 rio.push_back(
m_riomakerD->correct(*(*vit),Tp, Gaudi::Hive::currentContext()));
1451 chi2+=(fitted_r/1.15)*(fitted_r/1.15);
1453 rio.push_back(
m_riomakerN->correct(*(*vit),Tp, Gaudi::Hive::currentContext()));
1468 if(state==2 || state==3){
1484 rio.push_back(pseudo);
1493 const Trk::Surface * sur = &((*seed)[0]->detectorElement())->surface((*seed)[0]->identify());
1498 if(firstphi>0) firstphi=-firstphi;
1507 std::array<Trk::DefinedParameter,5> defPar = {dp0,dp1,dp2,dp3,dp4};
1514 double universal=1.15;
1519 universal*universal, 0., 0., 0., 0.,
1520 0. , 160000./12., 0., 0., 0.,
1521 0. , 0., 0.1, 0., 0.,
1522 0. , 0., 0., 1., 0.,
1523 0. , 0., 0., 0., 1.;
1582 if (not trtcontainer.
isValid()) {
1591 if (!prd_to_track_map.
isValid()) {
1594 prd_to_track_map_cptr = prd_to_track_map.
cptr();
1598 if (!mjo_trtcontainer)
return;
1600 InDet::TRT_DriftCircleContainer::const_iterator
1601 w = trtcontainer->begin(),we = trtcontainer->end();
1607 InDet::TRT_DriftCircleCollection::const_iterator
1608 c = (*w)->begin(), ce = (*w)->end();
1612 if(prd_to_track_map_cptr && prd_to_track_map_cptr->
isUsed(*(*
c)))
continue;
1614 if( (*c)->isNoise() || (*c)->timeOverThreshold()<
m_cutToTLoose) {
1642 const double dPhiLimit{0.03};
1643 const double dzLimit{31.};
1721 std::list<const InDet::TRT_DriftCircle*> & container,
1722 double dPhiLimit,
double dzLimit)
const{
1724 const auto id = (*it)->identify();
1731 for(
auto it2=container.begin();it2!=container.end();++it2){
1732 if(
it==it2)
continue;
1737 if(endcap!=endcap2 || wheel2!=wheel)
continue;
1739 const Amg::Vector3D& sc2 = (*it2)->detectorElement()->strawCenter(ns2);
1740 double dz=
sc.z()-sc2.z();
1741 double dphi=
phidiff(
sc.phi(),sc2.phi());
1744 dphi=std::abs(dphi/300.0);
1745 if(dphi<dPhiLimit and dz<dzLimit){
1764 std::lock_guard<std::mutex> lock(
s_fitMutex);
1765 TVirtualFitter::SetMaxIterations(100000);
1779 <<event_data.
m_fitf_ztanphi->GetParameter(2)<<
" fitresult="<<fitresult1);
1804 if(fitresult1!=0 && fitresult2!=0)
return nullptr;
1806 if(fitresult1==0 && fitresult2!=0)
return event_data.
m_fitf_zphi;
1824 ATH_MSG_VERBOSE(
"Number of hits matching this fit: tan="<<match_tan<<
" pol2="<<match_phi);
1826 if(match_tan>match_phi){
1828 }
else if(match_tan<match_phi){
1847 std::vector<const InDet::TRT_DriftCircle*> *seed)
const
1851 double meanz=0,varz=0;
1861 for(;vit!=vitE;++vit){
1869 varz+=
sc.z()*
sc.z();
1872 if(
count < 2)
return true;
1874 varz=(
count*varz-meanz*meanz);
1879 varz=std::sqrt(varz);
1881 double zmin_sel=100000;
1887 if(std::abs(dcz[
i]-dcz[
i-1])<
zmin)
zmin=std::abs(dcz[
i]-dcz[
i-1]);
1889 if(std::abs(dcz[
i]-dcz[
i+1])<
zmin)
zmin=std::abs(dcz[
i]-dcz[
i+1]);
1907 if(std::abs(zmin_sel-
mean)>2*
var){
1909 ATH_MSG_VERBOSE(
"Hit is suspicious, remove it! "<<std::abs(zmin_sel-
mean)<<
" , "<<2*
var<<
" -> "<<zmin_sel<<
" : "<<dcz[
index]<<
" <-> "<<meanz<<
" ("<<varz<<
")");
1914 ATH_MSG_VERBOSE(
"Hit seems to be ok: "<<std::abs(zmin_sel-
mean)<<
" < "<<2*
var<<
" && "<<std::abs(dcz[
index]-meanz)<<
" < "<<1.5*varz);