122 std::vector<TrigSiSpacePointBase> convertedSpacePoints;
123 convertedSpacePoints.reserve(5000);
136 auto monitorIt =
Monitored::Group(
m_monTool, mon_n_dvtrks, mon_n_dvsps, mon_n_jetseeds, mon_n_jetseedsdel, mon_n_spseeds, mon_n_spseedsdel, mon_average_mu );
141 ATH_CHECK( previousDecisionsHandle.isValid() );
143 ATH_MSG_DEBUG(
"Running with " << previousDecisionsHandle->size() <<
" previous decisions" );
144 if( previousDecisionsHandle->size()!=1 ) {
145 ATH_MSG_ERROR(
"Previous decision handle size is not 1. It is" << previousDecisionsHandle->size() );
146 return StatusCode::FAILURE;
148 const Decision * previousDecision = previousDecisionsHandle->at(0);
153 for(
auto decisionID: previousDecisionIDs) {
ATH_MSG_DEBUG(
" " << decisionID ); }
158 auto outputDecisions = outputHandle.
ptr();
168 if( jetsContainer ==
nullptr ) {
170 return StatusCode::FAILURE;
172 bool isJetEtPassToolsCut =
false;
173 float jetEtaToolsCut = 2.0;
176 float jet_pt =
static_cast<float>(
jet->pt() / Gaudi::Units::GeV );
177 float jet_eta =
static_cast<float>(
jet->eta());
179 isJetEtPassToolsCut =
true;
187 std::vector<HitDVSeed> hitDVSeedsContainer;
188 std::vector<HitDVTrk> hitDVTrksContainer;
189 std::vector<HitDVSpacePoint> hitDVSPsContainer;
192 ATH_CHECK(
findHitDV(context, convertedSpacePoints, *tracks, hitDVSeedsContainer, hitDVTrksContainer, hitDVSPsContainer) );
194 mon_n_dvtrks = hitDVTrksContainer.size();
195 mon_n_dvsps = hitDVSPsContainer.size();
196 const unsigned int N_MAX_SP_STORED = 100000;
197 bool isSPOverflow =
false;
198 if( hitDVSPsContainer.size() >= N_MAX_SP_STORED ) isSPOverflow =
true;
205 averageMu =
static_cast<float>(
m_lumiBlockMuTool->averageInteractionsPerCrossing(context));
211 averageMu = lcd.
cptr()->lbAverageInteractionsPerCrossing();
214 mon_average_mu = averageMu;
217 std::vector<float> jetSeeds_pt;
218 std::vector<float> jetSeeds_eta;
219 std::vector<float> jetSeeds_phi;
221 int n_alljetseeds = jetSeeds_eta.size();
223 mon_n_jetseeds = jetSeeds_eta.size();
224 mon_n_jetseedsdel = n_alljetseeds - jetSeeds_eta.size();
227 std::vector<float> spSeeds_eta;
228 std::vector<float> spSeeds_phi;
229 std::vector<float> void_pt;
230 int n_allspseeds = 0;
233 n_allspseeds = spSeeds_eta.size();
235 mon_n_spseeds = spSeeds_eta.size();
236 mon_n_spseedsdel = n_allspseeds - spSeeds_eta.size();
240 mon_n_spseedsdel = 0;
244 auto hitDVContainer = std::make_unique<xAOD::TrigCompositeContainer>();
245 auto hitDVContainerAux = std::make_unique<xAOD::TrigCompositeAuxContainer>();
246 hitDVContainer->setStore(hitDVContainerAux.get());
249 std::vector<TrigHitDVHypoTool::HitDVHypoInfo> hitDVHypoInputs;
250 std::unordered_map<Decision*, size_t> mapDecIdx;
253 if( isJetEtPassToolsCut ) {
254 const float preselBDTthreshold = -0.6;
256 int n_passed_jet = 0;
257 int seed_type = SeedType::HLTJet;
258 ATH_CHECK(
calculateBDT(hitDVSPsContainer, hitDVTrksContainer, jetSeeds_pt, jetSeeds_eta, jetSeeds_phi, preselBDTthreshold, seed_type, dvContainer, n_passed_jet) );
262 seed_type = SeedType::SP;
263 ATH_CHECK(
calculateBDT(hitDVSPsContainer, hitDVTrksContainer, void_pt, spSeeds_eta, spSeeds_phi, preselBDTthreshold, seed_type, dvContainer, n_passed_sp) );
266 ATH_MSG_DEBUG(
"nr of dv container / jet-seeded / sp-seed candidates = " << dvContainer->
size() <<
" / " << n_passed_jet <<
" / " << n_passed_sp );
269 for (
auto dv : *dvContainer ) {
271 mapDecIdx.emplace( newDecision, dv->index() );
273 hitDVHypoInputs.push_back( hypoInfo );
282 ATH_MSG_DEBUG(
"+++++ Now computing decision for " << tool->name() );
283 ATH_CHECK( tool->decide( hitDVHypoInputs ) );
288 ATH_CHECK( hitDVHandle.
record( std::move( hitDVContainer ), std::move( hitDVContainerAux ) ) );
292 while(it != outputDecisions->end()) {
293 ATH_MSG_DEBUG(
"+++++ outputDecision: " << *it <<
" +++++" );
296 it = outputDecisions->erase(it);
302 size_t idx = mapDecIdx.at(*it);
318 return StatusCode::SUCCESS;
510 const std::vector<HitDVTrk>& trksContainer,
511 const std::vector<float>& seeds_pt,
512 const std::vector<float>& seeds_eta,
const std::vector<float>& seeds_phi,
513 const float& cutBDTthreshold,
const int seed_type,
516 if( seeds_eta.size() != seeds_phi.size() )
return StatusCode::SUCCESS;
519 for(
unsigned int iseed=0; iseed<seeds_eta.size(); iseed++) {
521 float seed_eta = seeds_eta[iseed];
522 float seed_phi = seeds_phi[iseed];
524 ATH_MSG_VERBOSE(
"+++++ seed eta: " << seed_eta <<
", phi:" << seed_phi <<
" +++++");
527 const int N_LAYER = 8;
528 const float DR_SQUARED_TO_REF_CUT = 0.16;
531 int n_sp_injet_usedByTrk = 0;
532 int v_n_sp_injet[N_LAYER];
533 int v_n_sp_injet_usedByTrk[N_LAYER];
534 for(
int i=0; i<N_LAYER; i++) { v_n_sp_injet[i]=0; v_n_sp_injet_usedByTrk[i]=0; }
536 for (
const auto & spData : spsContainer ) {
538 float sp_eta = spData.eta;
539 float sp_phi = spData.phi;
540 float dR2 =
deltaR2(sp_eta,sp_phi,seed_eta,seed_phi);
541 if( dR2 > DR_SQUARED_TO_REF_CUT )
continue;
544 int sp_layer = (int)spData.layer;
545 int sp_trkid = (int)spData.usedTrkId;
546 bool isUsedByTrk = (sp_trkid != -1);
552 v_n_sp_injet[ilayer]++;
554 n_sp_injet_usedByTrk++;
555 v_n_sp_injet_usedByTrk[ilayer]++;
559 ATH_MSG_VERBOSE(
"nr of SPs in jet: usedByTrk / all = " << n_sp_injet_usedByTrk <<
" / " << n_sp_injet);
560 float v_ly_sp_frac[N_LAYER];
561 for(
int i=0; i<N_LAYER; i++) {
563 if( v_n_sp_injet[i] > 0 ) frac = 1.0 -
static_cast<float>(v_n_sp_injet_usedByTrk[i]) /
static_cast<float>(v_n_sp_injet[i]);
564 v_ly_sp_frac[i] = frac;
565 ATH_MSG_VERBOSE(
"Layer " << i <<
": frac=" << v_ly_sp_frac[i] <<
", n used / all = " << v_n_sp_injet_usedByTrk[i] <<
" / " << v_n_sp_injet[i]);
569 const float TRK_PT_GEV_CUT = 2.0;
571 unsigned int n_qtrk_injet = 0;
572 for (
const auto& trk : trksContainer ) {
573 float trk_ptGeV = trk.pt;
574 trk_ptGeV /= Gaudi::Units::GeV;
575 if( trk_ptGeV < TRK_PT_GEV_CUT )
continue;
576 float dR2 =
deltaR2(trk.eta,trk.phi,seed_eta,seed_phi);
577 if( dR2 > DR_SQUARED_TO_REF_CUT )
continue;
580 ATH_MSG_DEBUG(
"nr of all / quality tracks matched = " << trksContainer.size() <<
" / " << n_qtrk_injet);
583 bool isSeedOutOfRange =
false;
584 if( n_qtrk_injet == 0 ) {
585 isSeedOutOfRange =
true;
586 for(
int i=0; i<N_LAYER; i++) {
587 if( std::fabs(v_ly_sp_frac[i]) > 1e-3 ) {
588 isSeedOutOfRange =
false;
break;
592 float bdt_score = -2.0;
593 if( ! isSeedOutOfRange ) {
594 const std::vector<float> input_values = {
595 static_cast<float>(n_qtrk_injet),
605 if ( std::abs(seed_eta) < 1 ) {
606 bdt_score =
m_bdt_eta[0]->GetClassification(input_values);
607 }
else if ( std::abs(seed_eta) < 2 ) {
608 bdt_score =
m_bdt_eta[1]->GetClassification(input_values);
613 if( bdt_score < cutBDTthreshold )
continue;
621 dv->makePrivateStore();
625 if ( seed_type == SeedType::HLTJet ) seed_pt = seeds_pt[iseed];
626 dv->setDetail<
float>(
"hitDV_seed_pt", seed_pt);
627 dv->setDetail<
float>(
"hitDV_seed_eta", seed_eta);
628 dv->setDetail<
float>(
"hitDV_seed_phi", seed_phi);
629 dv->setDetail<
int> (
"hitDV_seed_type", seed_type);
630 dv->setDetail<
int> (
"hitDV_n_track_qual", n_qtrk_injet);
631 dv->setDetail<
float>(
"hitDV_ly0_sp_frac", v_ly_sp_frac[0]);
632 dv->setDetail<
float>(
"hitDV_ly1_sp_frac", v_ly_sp_frac[1]);
633 dv->setDetail<
float>(
"hitDV_ly2_sp_frac", v_ly_sp_frac[2]);
634 dv->setDetail<
float>(
"hitDV_ly3_sp_frac", v_ly_sp_frac[3]);
635 dv->setDetail<
float>(
"hitDV_ly4_sp_frac", v_ly_sp_frac[4]);
636 dv->setDetail<
float>(
"hitDV_ly5_sp_frac", v_ly_sp_frac[5]);
637 dv->setDetail<
float>(
"hitDV_ly6_sp_frac", v_ly_sp_frac[6]);
638 dv->setDetail<
float>(
"hitDV_ly7_sp_frac", v_ly_sp_frac[7]);
639 dv->setDetail<
float>(
"hitDV_bdt_score", bdt_score);
646 return StatusCode::SUCCESS;
689 std::vector<float>& seeds_eta, std::vector<float>& seeds_phi )
const
694 const int NBINS_ETA = 50;
695 const float ETA_MIN = -2.5;
696 const float ETA_MAX = 2.5;
698 const int NBINS_PHI = 80;
699 const float PHI_MIN = -4.0;
700 const float PHI_MAX = 4.0;
704 unsigned int slotnr = ctx.slot();
705 unsigned int subSlotnr = ctx.subSlot();
707 sprintf(hname,
"hitdv_s%u_ss%u_ly6_h2_nsp",slotnr,subSlotnr);
708 std::unique_ptr<TH2F> ly6_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
709 sprintf(hname,
"hitdv_s%u_ss%u_ly7_h2_nsp",slotnr,subSlotnr);
710 std::unique_ptr<TH2F> ly7_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
712 sprintf(hname,
"hitdv_s%u_ss%u_ly6_h2_nsp_notrk",slotnr,subSlotnr);
713 std::unique_ptr<TH2F> ly6_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
714 sprintf(hname,
"hitdv_s%u_ss%u_ly7_h2_nsp_notrk",slotnr,subSlotnr);
715 std::unique_ptr<TH2F> ly7_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
717 for (
const auto& spData : spsContainer ) {
718 int16_t sp_layer = spData.layer;
719 float sp_eta = spData.eta;
721 if( ilayer<6 )
continue;
723 int sp_trkid = (int)spData.usedTrkId;
724 bool isUsedByTrk = (sp_trkid != -1);
725 float sp_phi = spData.phi;
727 bool fill_out_of_pi =
false;
730 sp_phi2 = 2*TMath::Pi() + sp_phi;
731 if( sp_phi2 < PHI_MAX ) fill_out_of_pi =
true;
734 sp_phi2 = -2*TMath::Pi() + sp_phi;
735 if( PHI_MIN < sp_phi2 ) fill_out_of_pi =
true;
738 ly6_h2_nsp->Fill(sp_eta,sp_phi);
739 if( fill_out_of_pi ) ly6_h2_nsp->Fill(sp_eta,sp_phi2);
740 if( ! isUsedByTrk ) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi);
741 if( ! isUsedByTrk && fill_out_of_pi) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
744 ly7_h2_nsp->Fill(sp_eta,sp_phi);
745 if( fill_out_of_pi ) ly7_h2_nsp->Fill(sp_eta,sp_phi2);
746 if( ! isUsedByTrk ) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi);
747 if( ! isUsedByTrk && fill_out_of_pi) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
754 std::vector<std::tuple<int,float,float,float>> QT;
756 for(
int ly6_ieta=1; ly6_ieta<=NBINS_ETA; ly6_ieta++) {
757 float ly6_eta = (ly6_h2_nsp->GetXaxis()->GetBinLowEdge(ly6_ieta) + ly6_h2_nsp->GetXaxis()->GetBinUpEdge(ly6_ieta))/2.0;
758 for(
int ly6_iphi=1; ly6_iphi<=NBINS_PHI; ly6_iphi++) {
759 float ly6_phi = (ly6_h2_nsp->GetYaxis()->GetBinLowEdge(ly6_iphi) + ly6_h2_nsp->GetYaxis()->GetBinUpEdge(ly6_iphi))/2.0;
761 float ly6_nsp = ly6_h2_nsp ->GetBinContent(ly6_ieta,ly6_iphi);
762 float ly6_nsp_notrk = ly6_h2_nsp_notrk->GetBinContent(ly6_ieta,ly6_iphi);
763 float ly6_frac = ( ly6_nsp > 0 ) ? ly6_nsp_notrk / ly6_nsp : 0;
764 if( ly6_nsp < 10 || ly6_frac < 0.85 )
continue;
766 float ly7_frac_max = 0;
767 float ly7_eta_max = 0;
768 float ly7_phi_max = 0;
769 for(
int ly7_ieta=std::max(1,ly6_ieta-1); ly7_ieta<std::min(NBINS_ETA,ly6_ieta+1); ly7_ieta++) {
770 for(
int ly7_iphi=std::max(1,ly6_iphi-1); ly7_iphi<=std::min(NBINS_PHI,ly6_iphi+1); ly7_iphi++) {
771 float ly7_nsp = ly7_h2_nsp ->GetBinContent(ly7_ieta,ly7_iphi);
772 float ly7_nsp_notrk = ly7_h2_nsp_notrk->GetBinContent(ly7_ieta,ly7_iphi);
773 float ly7_frac = ( ly7_nsp > 0 ) ? ly7_nsp_notrk / ly7_nsp : 0;
774 if( ly7_nsp < 10 )
continue;
775 if( ly7_frac > ly7_frac_max ) {
776 ly7_frac_max = ly7_frac;
777 ly7_eta_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_ieta) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_ieta))/2.0;
778 ly7_phi_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_iphi) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_iphi))/2.0;
782 if( ly7_frac_max < 0.85 )
continue;
784 float wsum = ly6_frac + ly7_frac_max;
785 float weta = (ly6_eta*ly6_frac + ly7_eta_max*ly7_frac_max) / wsum;
786 float wphi = (ly6_phi*ly6_frac + ly7_phi_max*ly7_frac_max) / wsum;
787 float w = wsum / 2.0;
788 QT.push_back(std::make_tuple(-1,w,weta,wphi));
791 ATH_MSG_VERBOSE(
"nr of ly6/ly7 doublet candidate seeds=" << QT.size() <<
", doing clustering...");
795 [](
const std::tuple<int,float,float,float>& lhs,
const std::tuple<int,float,float,float>& rhs) {
796 return std::get<1>(lhs) > std::get<1>(rhs); } );
799 const double CLUSTCUT_DIST_SQUARED = 0.04;
800 const double CLUSTCUT_SEED_FRAC = 0.9;
802 std::vector<float> seeds_wsum;
804 for(
unsigned int i=0; i<QT.size(); i++) {
805 float phi = std::get<3>(QT[i]);
806 float eta = std::get<2>(QT[i]);
807 float w = std::get<1>(QT[i]);
809 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
810 seeds_wsum.push_back(w);
813 const int IDX_INITIAL = 100;
814 float dist2_min = 100.0;
815 int idx_min = IDX_INITIAL;
816 for(
unsigned j=0; j<seeds_eta.size(); j++) {
817 float ceta = seeds_eta[j]/seeds_wsum[j];
818 float cphi = seeds_phi[j]/seeds_wsum[j];
820 float deta = std::fabs(ceta-
eta);
821 float dphi = std::fabs(cphi-
phi);
822 float dist2 = dphi*dphi+deta*deta;
823 if( dist2 < dist2_min ) {
828 int match_idx = IDX_INITIAL;
829 if( idx_min != IDX_INITIAL ) {
830 if( dist2_min < CLUSTCUT_DIST_SQUARED ) { match_idx = idx_min; }
832 if( match_idx == IDX_INITIAL ) {
833 if( w > CLUSTCUT_SEED_FRAC && dist2_min > CLUSTCUT_DIST_SQUARED ) {
834 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
835 seeds_wsum.push_back(w);
839 float new_eta = seeds_eta[match_idx] + w*
eta;
840 float new_phi = seeds_phi[match_idx] + w*
phi;
841 float new_wsum = seeds_wsum[match_idx] + w;
842 seeds_eta[match_idx] = new_eta;
843 seeds_phi[match_idx] = new_phi;
844 seeds_wsum[match_idx] = new_wsum;
847 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
848 float eta = seeds_eta[i] / seeds_wsum[i];
849 float phi = seeds_phi[i] / seeds_wsum[i];
852 if(
phi < -TMath::Pi() )
phi = 2*TMath::Pi() +
phi;
853 if(
phi > TMath::Pi() )
phi = -2*TMath::Pi() +
phi;
856 ATH_MSG_VERBOSE(
"after clustering, nr of seeds = " << seeds_eta.size());
859 std::vector<unsigned int> idx_to_delete;
860 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
861 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),i) != idx_to_delete.end() )
continue;
862 float eta_i = seeds_eta[i];
863 float phi_i = seeds_phi[i];
864 for(
unsigned int j=i+1; j<seeds_eta.size(); j++) {
865 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),j) != idx_to_delete.end() )
continue;
866 float eta_j = seeds_eta[j];
867 float phi_j = seeds_phi[j];
868 float dR2 =
deltaR2(eta_i,phi_i,eta_j,phi_j);
869 if( dR2 < CLUSTCUT_DIST_SQUARED ) idx_to_delete.push_back(j);
872 ATH_MSG_VERBOSE(
"nr of duplicated seeds to be removed = " << idx_to_delete.size());
873 if( idx_to_delete.size() > 0 ) {
874 std::sort(idx_to_delete.begin(),idx_to_delete.end());
875 for(
unsigned int j=idx_to_delete.size(); j>0; j--) {
876 unsigned int idx = idx_to_delete[j-1];
877 seeds_eta.erase(seeds_eta.begin()+idx);
878 seeds_phi.erase(seeds_phi.begin()+idx);
885 return StatusCode::SUCCESS;
922 const std::vector<float>& v_sp_eta,
const std::vector<float>& v_sp_phi,
923 const std::vector<int>& v_sp_layer,
const std::vector<int>& v_sp_usedTrkId,
924 std::vector<float>& seeds_eta, std::vector<float>& seeds_phi )
const
926 const int NBINS_ETA = 50;
927 const float ETA_MIN = -2.5;
928 const float ETA_MAX = 2.5;
930 const int NBINS_PHI = 80;
931 const float PHI_MIN = -4.0;
932 const float PHI_MAX = 4.0;
936 unsigned int slotnr = ctx.slot();
937 unsigned int subSlotnr = ctx.subSlot();
939 sprintf(hname,
"ftf_s%u_ss%u_ly6_h2_nsp",slotnr,subSlotnr);
940 std::unique_ptr<TH2F> ly6_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
941 sprintf(hname,
"ftf_s%u_ss%u_ly7_h2_nsp",slotnr,subSlotnr);
942 std::unique_ptr<TH2F> ly7_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
944 sprintf(hname,
"ftf_s%u_ss%u_ly6_h2_nsp_notrk",slotnr,subSlotnr);
945 std::unique_ptr<TH2F> ly6_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
946 sprintf(hname,
"ftf_s%u_ss%u_ly7_h2_nsp_notrk",slotnr,subSlotnr);
947 std::unique_ptr<TH2F> ly7_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
949 for(
unsigned int iSeed=0; iSeed<v_sp_eta.size(); ++iSeed) {
951 int sp_layer = v_sp_layer[iSeed];
952 float sp_eta = v_sp_eta[iSeed];
954 if( ilayer<6 )
continue;
956 int sp_trkid = v_sp_usedTrkId[iSeed];
957 bool isUsedByTrk = (sp_trkid != -1);
958 float sp_phi = v_sp_phi[iSeed];
960 bool fill_out_of_pi =
false;
963 sp_phi2 = 2*TMath::Pi() + sp_phi;
964 if( sp_phi2 < PHI_MAX ) fill_out_of_pi =
true;
967 sp_phi2 = -2*TMath::Pi() + sp_phi;
968 if( PHI_MIN < sp_phi2 ) fill_out_of_pi =
true;
971 ly6_h2_nsp->Fill(sp_eta,sp_phi);
972 if( fill_out_of_pi ) ly6_h2_nsp->Fill(sp_eta,sp_phi2);
973 if( ! isUsedByTrk ) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi);
974 if( ! isUsedByTrk && fill_out_of_pi) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
977 ly7_h2_nsp->Fill(sp_eta,sp_phi);
978 if( fill_out_of_pi ) ly7_h2_nsp->Fill(sp_eta,sp_phi2);
979 if( ! isUsedByTrk ) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi);
980 if( ! isUsedByTrk && fill_out_of_pi) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
987 std::vector<std::tuple<int,float,float,float>> QT;
989 for(
int ly6_ieta=1; ly6_ieta<=NBINS_ETA; ly6_ieta++) {
990 float ly6_eta = (ly6_h2_nsp->GetXaxis()->GetBinLowEdge(ly6_ieta) + ly6_h2_nsp->GetXaxis()->GetBinUpEdge(ly6_ieta))/2.0;
991 for(
int ly6_iphi=1; ly6_iphi<=NBINS_PHI; ly6_iphi++) {
992 float ly6_phi = (ly6_h2_nsp->GetYaxis()->GetBinLowEdge(ly6_iphi) + ly6_h2_nsp->GetYaxis()->GetBinUpEdge(ly6_iphi))/2.0;
994 float ly6_nsp = ly6_h2_nsp ->GetBinContent(ly6_ieta,ly6_iphi);
995 float ly6_nsp_notrk = ly6_h2_nsp_notrk->GetBinContent(ly6_ieta,ly6_iphi);
996 float ly6_frac = ( ly6_nsp > 0 ) ? ly6_nsp_notrk / ly6_nsp : 0;
997 if( ly6_nsp < 10 || ly6_frac < 0.85 )
continue;
999 float ly7_frac_max = 0;
1000 float ly7_eta_max = 0;
1001 float ly7_phi_max = 0;
1002 for(
int ly7_ieta=std::max(1,ly6_ieta-1); ly7_ieta<std::min(NBINS_ETA,ly6_ieta+1); ly7_ieta++) {
1003 for(
int ly7_iphi=std::max(1,ly6_iphi-1); ly7_iphi<=std::min(NBINS_PHI,ly6_iphi+1); ly7_iphi++) {
1004 float ly7_nsp = ly7_h2_nsp ->GetBinContent(ly7_ieta,ly7_iphi);
1005 float ly7_nsp_notrk = ly7_h2_nsp_notrk->GetBinContent(ly7_ieta,ly7_iphi);
1006 float ly7_frac = ( ly7_nsp > 0 ) ? ly7_nsp_notrk / ly7_nsp : 0;
1007 if( ly7_nsp < 10 )
continue;
1008 if( ly7_frac > ly7_frac_max ) {
1009 ly7_frac_max = ly7_frac;
1010 ly7_eta_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_ieta) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_ieta))/2.0;
1011 ly7_phi_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_iphi) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_iphi))/2.0;
1015 if( ly7_frac_max < 0.85 )
continue;
1017 float wsum = ly6_frac + ly7_frac_max;
1018 float weta = (ly6_eta*ly6_frac + ly7_eta_max*ly7_frac_max) / wsum;
1019 float wphi = (ly6_phi*ly6_frac + ly7_phi_max*ly7_frac_max) / wsum;
1020 float w = wsum / 2.0;
1021 QT.push_back(std::make_tuple(-1,w,weta,wphi));
1024 ATH_MSG_VERBOSE(
"nr of ly6/ly7 doublet candidate seeds=" << QT.size() <<
", doing clustering...");
1028 [](
const std::tuple<int,float,float,float>& lhs,
const std::tuple<int,float,float,float>& rhs) {
1029 return std::get<1>(lhs) > std::get<1>(rhs); } );
1032 const double CLUSTCUT_DIST_SQUARED = 0.04;
1033 const double CLUSTCUT_SEED_FRAC = 0.9;
1035 std::vector<float> seeds_wsum;
1037 for(
unsigned int i=0; i<QT.size(); i++) {
1038 float phi = std::get<3>(QT[i]);
1039 float eta = std::get<2>(QT[i]);
1040 float w = std::get<1>(QT[i]);
1042 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
1043 seeds_wsum.push_back(w);
1046 const int IDX_INITIAL = 100;
1047 float dist2_min = 100.0;
1048 int idx_min = IDX_INITIAL;
1049 for(
unsigned j=0; j<seeds_eta.size(); j++) {
1050 float ceta = seeds_eta[j]/seeds_wsum[j];
1051 float cphi = seeds_phi[j]/seeds_wsum[j];
1053 float deta = std::fabs(ceta-
eta);
1054 float dphi = std::fabs(cphi-
phi);
1055 float dist2 = dphi*dphi+deta*deta;
1056 if( dist2 < dist2_min ) {
1061 int match_idx = IDX_INITIAL;
1062 if( idx_min != IDX_INITIAL ) {
1063 if( dist2_min < CLUSTCUT_DIST_SQUARED ) { match_idx = idx_min; }
1065 if( match_idx == IDX_INITIAL ) {
1066 if( w > CLUSTCUT_SEED_FRAC && dist2_min > CLUSTCUT_DIST_SQUARED ) {
1067 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
1068 seeds_wsum.push_back(w);
1072 float new_eta = seeds_eta[match_idx] + w*
eta;
1073 float new_phi = seeds_phi[match_idx] + w*
phi;
1074 float new_wsum = seeds_wsum[match_idx] + w;
1075 seeds_eta[match_idx] = new_eta;
1076 seeds_phi[match_idx] = new_phi;
1077 seeds_wsum[match_idx] = new_wsum;
1080 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
1081 float eta = seeds_eta[i] / seeds_wsum[i];
1082 float phi = seeds_phi[i] / seeds_wsum[i];
1084 if(
phi < -TMath::Pi() )
phi = 2*TMath::Pi() +
phi;
1085 if(
phi > TMath::Pi() )
phi = -2*TMath::Pi() +
phi;
1088 ATH_MSG_VERBOSE(
"after clustering, nr of seeds = " << seeds_eta.size());
1091 std::vector<unsigned int> idx_to_delete;
1092 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
1093 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),i) != idx_to_delete.end() )
continue;
1094 float eta_i = seeds_eta[i];
1095 float phi_i = seeds_phi[i];
1096 for(
unsigned int j=i+1; j<seeds_eta.size(); j++) {
1097 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),j) != idx_to_delete.end() )
continue;
1098 float eta_j = seeds_eta[j];
1099 float phi_j = seeds_phi[j];
1100 float dR2 =
deltaR2(eta_i,phi_i,eta_j,phi_j);
1101 if( dR2 < CLUSTCUT_DIST_SQUARED ) idx_to_delete.push_back(j);
1104 ATH_MSG_VERBOSE(
"nr of duplicated seeds to be removed = " << idx_to_delete.size());
1105 if( idx_to_delete.size() > 0 ) {
1106 std::sort(idx_to_delete.begin(),idx_to_delete.end());
1107 for(
unsigned int j=idx_to_delete.size(); j>0; j--) {
1108 unsigned int idx = idx_to_delete[j-1];
1109 seeds_eta.erase(seeds_eta.begin()+idx);
1110 seeds_phi.erase(seeds_phi.begin()+idx);
1117 return StatusCode::SUCCESS;
1122 std::vector<HitDVTrk>& hitDVTrksContainer,
1123 std::vector<HitDVSpacePoint>& hitDVSPsContainer)
const
1125 std::vector<int> v_dvtrk_id;
1126 std::vector<float> v_dvtrk_pt;
1127 std::vector<float> v_dvtrk_eta;
1128 std::vector<float> v_dvtrk_phi;
1129 std::vector<int> v_dvtrk_n_hits_inner;
1130 std::vector<int> v_dvtrk_n_hits_pix;
1131 std::vector<int> v_dvtrk_n_hits_sct;
1132 std::vector<float> v_dvtrk_a0beam;
1133 std::unordered_map<Identifier, int> umap_fittedTrack_identifier;
1134 int fittedTrack_id = -1;
1136 static constexpr float TRKCUT_PTGEV_HITDV = 0.5;
1138 for (
const auto track: tracks) {
1139 float shift_x = 0;
float shift_y = 0;
1145 bool igt =
FTF::isGoodTrackUTT(track, theTrackInfo, shift_x, shift_y, TRKCUT_PTGEV_HITDV);
1146 if (not igt) {
continue;}
1153 m = track->measurementsOnTrack()->begin(),
1154 me = track->measurementsOnTrack()->end ();
1155 for(; m!=me; ++m ) {
1157 if( prd ==
nullptr )
continue;
1159 if( umap_fittedTrack_identifier.find(id_prd) == umap_fittedTrack_identifier.end() ) {
1160 umap_fittedTrack_identifier.insert(std::make_pair(id_prd,fittedTrack_id));
1163 float phi = track->perigeeParameters()->parameters()[
Trk::phi];
1164 v_dvtrk_id.push_back(fittedTrack_id);
1165 v_dvtrk_pt.push_back(theTrackInfo.
ptGeV*Gaudi::Units::GeV);
1166 v_dvtrk_eta.push_back(theTrackInfo.
eta);
1167 v_dvtrk_phi.push_back(
phi);
1168 v_dvtrk_n_hits_inner.push_back(theTrackInfo.
n_hits_inner);
1169 v_dvtrk_n_hits_pix.push_back(theTrackInfo.
n_hits_pix);
1170 v_dvtrk_n_hits_sct.push_back(theTrackInfo.
n_hits_sct);
1171 v_dvtrk_a0beam.push_back(theTrackInfo.
a0beam);
1173 ATH_MSG_DEBUG(
"Nr of selected tracks / all = " << fittedTrack_id <<
" / " << tracks.
size());
1174 ATH_MSG_DEBUG(
"Nr of Identifiers used by selected tracks = " << umap_fittedTrack_identifier.size());
1178 int n_sp_usedByTrk = 0;
1180 std::unordered_map<Identifier, int> umap_sp_identifier;
1181 umap_sp_identifier.reserve(1.3*convertedSpacePoints.size());
1186 if( umap_sp_identifier.find(id_prd) == umap_sp_identifier.end() ) {
1187 umap_sp_identifier.insert(std::make_pair(id_prd,-1));
1192 for(
unsigned int iSp=0; iSp<convertedSpacePoints.size(); ++iSp) {
1193 bool isPix = convertedSpacePoints[iSp].isPixel();
1194 bool isSct = convertedSpacePoints[iSp].isSCT();
1195 if( ! isPix && ! isSct )
continue;
1197 add_to_sp_map(
sp->clusterList().first);
1198 add_to_sp_map(
sp->clusterList().second);
1200 int n_id_usedByTrack = 0;
1201 for(
auto it=umap_sp_identifier.begin(); it!=umap_sp_identifier.end(); ++it) {
1203 if( umap_fittedTrack_identifier.find(id_sp) != umap_fittedTrack_identifier.end() ) {
1204 umap_sp_identifier[id_sp] = umap_fittedTrack_identifier[id_sp];
1208 ATH_MSG_DEBUG(
"Nr of SPs / Identifiers (all) / Identifiers (usedByTrack) = " << convertedSpacePoints.size() <<
" / " << umap_sp_identifier.size() <<
" / " << n_id_usedByTrack);
1211 int usedTrack_id = -1;
1214 if( umap_sp_identifier.find(id_prd) != umap_sp_identifier.end() ) {
1215 usedTrack_id = umap_sp_identifier[id_prd];
1218 return usedTrack_id;
1221 std::vector<float> v_sp_eta;
1222 v_sp_eta.reserve(convertedSpacePoints.size());
1223 std::vector<float> v_sp_r;
1224 v_sp_r.reserve(convertedSpacePoints.size());
1225 std::vector<float> v_sp_phi;
1226 v_sp_phi.reserve(convertedSpacePoints.size());
1227 std::vector<int> v_sp_layer;
1228 v_sp_layer.reserve(convertedSpacePoints.size());
1229 std::vector<bool> v_sp_isPix;
1230 v_sp_isPix.reserve(convertedSpacePoints.size());
1231 std::vector<bool> v_sp_isSct;
1232 v_sp_isSct.reserve(convertedSpacePoints.size());
1233 std::vector<int> v_sp_usedTrkId;
1234 v_sp_usedTrkId.reserve(convertedSpacePoints.size());
1236 for(
const auto&
sp : convertedSpacePoints) {
1237 bool isPix =
sp.isPixel();
1238 bool isSct =
sp.isSCT();
1239 if( ! isPix && ! isSct )
continue;
1242 int usedTrack_id = -1;
1243 int usedTrack_id_first = sp_map_used_id(osp->
clusterList().first);
1244 if (usedTrack_id_first != -1) {
1245 usedTrack_id = usedTrack_id_first;
1247 int usedTrack_id_second = sp_map_used_id(osp->
clusterList().second);
1248 if (usedTrack_id_second != -1) {
1249 usedTrack_id = usedTrack_id_second;
1254 if( usedTrack_id != -1 ) n_sp_usedByTrk++;
1255 int layer =
sp.layer();
1256 float sp_r =
sp.r();
1259 float sp_eta = pos_sp.eta();
1260 float sp_phi = pos_sp.phi();
1262 v_sp_eta.push_back(sp_eta);
1263 v_sp_r.push_back(sp_r);
1264 v_sp_phi.push_back(sp_phi);
1265 v_sp_layer.push_back(layer);
1266 v_sp_isPix.push_back(isPix);
1267 v_sp_isSct.push_back(isSct);
1268 v_sp_usedTrkId.push_back(usedTrack_id);
1270 ATH_MSG_VERBOSE(
"+++ SP eta / phi / layer / ixPix / usedTrack_id = " << sp_eta <<
" / " << sp_phi <<
" / " << layer <<
" / " << isPix <<
" / " << usedTrack_id);
1273 ATH_MSG_DEBUG(
"Nr of SPs / all = " << n_sp <<
" / " << convertedSpacePoints.size());
1274 ATH_MSG_DEBUG(
"Nr of SPs used by selected tracks = " << n_sp_usedByTrk);
1277 std::vector<float> v_seeds_eta;
1278 std::vector<float> v_seeds_phi;
1279 std::vector<int16_t> v_seeds_type;
1284 const unsigned int L1JET_ET_CUT = 27;
1288 if (!jetRoiCollectionHandle.isValid()){
1290 return StatusCode::FAILURE;
1292 for (
size_t size=0; size<jetRoiCollection->
size(); ++size){
1294 if( jetRoI ==
nullptr )
continue;
1296 if( jetRoI->
et() >= L1JET_ET_CUT ) {
1297 v_seeds_eta.push_back(jetRoI->
eta());
1298 v_seeds_phi.push_back(jetRoI->
phi());
1299 v_seeds_type.push_back(0);
1302 ATH_MSG_DEBUG(
"Nr of L1_J" << L1JET_ET_CUT <<
" seeds = " << v_seeds_eta.size());
1305 std::vector<float> v_spseeds_eta;
1306 std::vector<float> v_spseeds_phi;
1307 ATH_CHECK(
findSPSeeds(ctx, v_sp_eta, v_sp_phi, v_sp_layer, v_sp_usedTrkId, v_spseeds_eta, v_spseeds_phi) );
1309 for(
size_t idx=0; idx<v_spseeds_eta.size(); ++idx) {
1310 v_seeds_eta.push_back(v_spseeds_eta[idx]);
1311 v_seeds_phi.push_back(v_spseeds_phi[idx]);
1312 v_seeds_type.push_back(1);
1314 ATH_MSG_DEBUG(
"Nr of SP + L1_J" << L1JET_ET_CUT <<
" seeds = " << v_seeds_eta.size());
1320 const int N_MAX_SEEDS = 200;
1321 int n_seeds = std::min(N_MAX_SEEDS,(
int)v_seeds_eta.size());
1322 hitDVSeedsContainer.reserve(n_seeds);
1323 for(
auto iSeed=0; iSeed < n_seeds; ++iSeed) {
1325 seed.eta = v_seeds_eta[iSeed];
1326 seed.phi = v_seeds_phi[iSeed];
1327 seed.type = v_seeds_type[iSeed];
1328 hitDVSeedsContainer.push_back(seed);
1332 const float TRKCUT_DELTA_R_TO_SEED = 1.0;
1333 hitDVTrksContainer.reserve(v_dvtrk_pt.size());
1334 for(
unsigned int iTrk=0; iTrk<v_dvtrk_pt.size(); ++iTrk) {
1335 float trk_eta = v_dvtrk_eta[iTrk];
1336 float trk_phi = v_dvtrk_phi[iTrk];
1338 bool isNearSeed =
false;
1339 for (
unsigned int iSeed=0; iSeed<v_seeds_eta.size(); ++iSeed) {
1340 float seed_eta = v_seeds_eta[iSeed];
1341 float seed_phi = v_seeds_phi[iSeed];
1342 float dR2 =
deltaR2(trk_eta,trk_phi,seed_eta,seed_phi);
1343 if( dR2 <= TRKCUT_DELTA_R_TO_SEED*TRKCUT_DELTA_R_TO_SEED ) { isNearSeed =
true;
break; }
1345 if( ! isNearSeed )
continue;
1348 hitDVTrk.
id = v_dvtrk_id[iTrk];
1349 hitDVTrk.
pt = v_dvtrk_pt[iTrk];
1350 hitDVTrk.
eta = v_dvtrk_eta[iTrk];
1351 hitDVTrk.
phi = v_dvtrk_phi[iTrk];
1353 hitDVTrk.
n_hits_pix = v_dvtrk_n_hits_pix[iTrk];
1354 hitDVTrk.
n_hits_sct = v_dvtrk_n_hits_sct[iTrk];
1355 hitDVTrk.
a0beam = v_dvtrk_a0beam[iTrk];
1357 hitDVTrksContainer.push_back(hitDVTrk);
1361 const float SPCUT_DELTA_R_TO_SEED = 1.0;
1362 const size_t n_sp_max = std::min<size_t>(100000, v_sp_eta.size());
1363 size_t n_sp_stored = 0;
1365 hitDVSPsContainer.reserve(n_sp_max);
1367 for(
size_t iSp=0; iSp<v_sp_eta.size(); ++iSp) {
1369 const float sp_eta = v_sp_eta[iSp];
1370 const float sp_phi = v_sp_phi[iSp];
1371 bool isNearSeed =
false;
1372 for (
size_t iSeed=0; iSeed<v_seeds_eta.size(); ++iSeed) {
1373 const float seed_eta = v_seeds_eta[iSeed];
1374 const float seed_phi = v_seeds_phi[iSeed];
1375 const float dR2 =
deltaR2(sp_eta, sp_phi, seed_eta, seed_phi);
1376 if( dR2 <= SPCUT_DELTA_R_TO_SEED*SPCUT_DELTA_R_TO_SEED ) { isNearSeed =
true;
break; }
1378 if( ! isNearSeed )
continue;
1380 if( n_sp_stored >= n_sp_max )
break;
1382 hitDVSP.
eta = v_sp_eta[iSp];
1383 hitDVSP.
r = v_sp_r[iSp];
1384 hitDVSP.
phi = v_sp_phi[iSp];
1385 hitDVSP.
layer = v_sp_layer[iSp];
1386 hitDVSP.
isPix = v_sp_isPix[iSp];
1387 hitDVSP.
isSct = v_sp_isSct[iSp];
1388 hitDVSP.
usedTrkId = v_sp_usedTrkId[iSp];
1389 hitDVSPsContainer.push_back(hitDVSP);
1394 return StatusCode::SUCCESS;