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( std::move(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;
511 const std::vector<HitDVTrk>& trksContainer,
512 const std::vector<float>& seeds_pt,
513 const std::vector<float>& seeds_eta,
const std::vector<float>& seeds_phi,
514 const float& cutBDTthreshold,
const int seed_type,
517 if( seeds_eta.size() != seeds_phi.size() )
return StatusCode::SUCCESS;
520 for(
unsigned int iseed=0; iseed<seeds_eta.size(); iseed++) {
522 float seed_eta = seeds_eta[iseed];
523 float seed_phi = seeds_phi[iseed];
525 ATH_MSG_VERBOSE(
"+++++ seed eta: " << seed_eta <<
", phi:" << seed_phi <<
" +++++");
528 const int N_LAYER = 8;
529 const float DR_SQUARED_TO_REF_CUT = 0.16;
532 int n_sp_injet_usedByTrk = 0;
533 int v_n_sp_injet[N_LAYER];
534 int v_n_sp_injet_usedByTrk[N_LAYER];
535 for(
int i=0; i<N_LAYER; i++) { v_n_sp_injet[i]=0; v_n_sp_injet_usedByTrk[i]=0; }
537 for (
const auto & spData : spsContainer ) {
539 float sp_eta = spData.eta;
540 float sp_phi = spData.phi;
541 float dR2 =
deltaR2(sp_eta,sp_phi,seed_eta,seed_phi);
542 if( dR2 > DR_SQUARED_TO_REF_CUT )
continue;
545 int sp_layer = (int)spData.layer;
546 int sp_trkid = (int)spData.usedTrkId;
547 bool isUsedByTrk = (sp_trkid != -1);
553 v_n_sp_injet[ilayer]++;
555 n_sp_injet_usedByTrk++;
556 v_n_sp_injet_usedByTrk[ilayer]++;
560 ATH_MSG_VERBOSE(
"nr of SPs in jet: usedByTrk / all = " << n_sp_injet_usedByTrk <<
" / " << n_sp_injet);
561 float v_ly_sp_frac[N_LAYER];
562 for(
int i=0; i<N_LAYER; i++) {
564 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]);
565 v_ly_sp_frac[i] = frac;
566 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]);
570 const float TRK_PT_GEV_CUT = 2.0;
572 unsigned int n_qtrk_injet = 0;
573 for (
const auto& trk : trksContainer ) {
574 float trk_ptGeV = trk.pt;
575 trk_ptGeV /= Gaudi::Units::GeV;
576 if( trk_ptGeV < TRK_PT_GEV_CUT )
continue;
577 float dR2 =
deltaR2(trk.eta,trk.phi,seed_eta,seed_phi);
578 if( dR2 > DR_SQUARED_TO_REF_CUT )
continue;
581 ATH_MSG_DEBUG(
"nr of all / quality tracks matched = " << trksContainer.size() <<
" / " << n_qtrk_injet);
584 bool isSeedOutOfRange =
false;
585 if( n_qtrk_injet == 0 ) {
586 isSeedOutOfRange =
true;
587 for(
int i=0; i<N_LAYER; i++) {
588 if( std::fabs(v_ly_sp_frac[i]) > 1e-3 ) {
589 isSeedOutOfRange =
false;
break;
593 float bdt_score = -2.0;
594 if( ! isSeedOutOfRange ) {
595 const std::vector<float> input_values = {
596 static_cast<float>(n_qtrk_injet),
606 if ( std::abs(seed_eta) < 1 ) {
607 bdt_score =
m_bdt_eta[0]->GetClassification(input_values);
608 }
else if ( std::abs(seed_eta) < 2 ) {
609 bdt_score =
m_bdt_eta[1]->GetClassification(input_values);
614 if( bdt_score < cutBDTthreshold )
continue;
622 dv->makePrivateStore();
626 if ( seed_type == SeedType::HLTJet ) seed_pt = seeds_pt[iseed];
627 dv->setDetail<
float>(
"hitDV_seed_pt", seed_pt);
628 dv->setDetail<
float>(
"hitDV_seed_eta", seed_eta);
629 dv->setDetail<
float>(
"hitDV_seed_phi", seed_phi);
630 dv->setDetail<
int> (
"hitDV_seed_type", seed_type);
631 dv->setDetail<
int> (
"hitDV_n_track_qual", n_qtrk_injet);
632 dv->setDetail<
float>(
"hitDV_ly0_sp_frac", v_ly_sp_frac[0]);
633 dv->setDetail<
float>(
"hitDV_ly1_sp_frac", v_ly_sp_frac[1]);
634 dv->setDetail<
float>(
"hitDV_ly2_sp_frac", v_ly_sp_frac[2]);
635 dv->setDetail<
float>(
"hitDV_ly3_sp_frac", v_ly_sp_frac[3]);
636 dv->setDetail<
float>(
"hitDV_ly4_sp_frac", v_ly_sp_frac[4]);
637 dv->setDetail<
float>(
"hitDV_ly5_sp_frac", v_ly_sp_frac[5]);
638 dv->setDetail<
float>(
"hitDV_ly6_sp_frac", v_ly_sp_frac[6]);
639 dv->setDetail<
float>(
"hitDV_ly7_sp_frac", v_ly_sp_frac[7]);
640 dv->setDetail<
float>(
"hitDV_bdt_score", bdt_score);
647 return StatusCode::SUCCESS;
690 std::vector<float>& seeds_eta, std::vector<float>& seeds_phi )
const
695 const int NBINS_ETA = 50;
696 const float ETA_MIN = -2.5;
697 const float ETA_MAX = 2.5;
699 const int NBINS_PHI = 80;
700 const float PHI_MIN = -4.0;
701 const float PHI_MAX = 4.0;
705 unsigned int slotnr = ctx.slot();
706 unsigned int subSlotnr = ctx.subSlot();
708 sprintf(hname,
"hitdv_s%u_ss%u_ly6_h2_nsp",slotnr,subSlotnr);
709 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);
710 sprintf(hname,
"hitdv_s%u_ss%u_ly7_h2_nsp",slotnr,subSlotnr);
711 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);
713 sprintf(hname,
"hitdv_s%u_ss%u_ly6_h2_nsp_notrk",slotnr,subSlotnr);
714 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);
715 sprintf(hname,
"hitdv_s%u_ss%u_ly7_h2_nsp_notrk",slotnr,subSlotnr);
716 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);
718 for (
const auto& spData : spsContainer ) {
719 int16_t sp_layer = spData.layer;
720 float sp_eta = spData.eta;
722 if( ilayer<6 )
continue;
724 int sp_trkid = (int)spData.usedTrkId;
725 bool isUsedByTrk = (sp_trkid != -1);
726 float sp_phi = spData.phi;
728 bool fill_out_of_pi =
false;
731 sp_phi2 = 2*TMath::Pi() + sp_phi;
732 if( sp_phi2 < PHI_MAX ) fill_out_of_pi =
true;
735 sp_phi2 = -2*TMath::Pi() + sp_phi;
736 if( PHI_MIN < sp_phi2 ) fill_out_of_pi =
true;
739 ly6_h2_nsp->Fill(sp_eta,sp_phi);
740 if( fill_out_of_pi ) ly6_h2_nsp->Fill(sp_eta,sp_phi2);
741 if( ! isUsedByTrk ) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi);
742 if( ! isUsedByTrk && fill_out_of_pi) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
745 ly7_h2_nsp->Fill(sp_eta,sp_phi);
746 if( fill_out_of_pi ) ly7_h2_nsp->Fill(sp_eta,sp_phi2);
747 if( ! isUsedByTrk ) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi);
748 if( ! isUsedByTrk && fill_out_of_pi) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
755 std::vector<std::tuple<int,float,float,float>> QT;
757 for(
int ly6_ieta=1; ly6_ieta<=NBINS_ETA; ly6_ieta++) {
758 float ly6_eta = (ly6_h2_nsp->GetXaxis()->GetBinLowEdge(ly6_ieta) + ly6_h2_nsp->GetXaxis()->GetBinUpEdge(ly6_ieta))/2.0;
759 for(
int ly6_iphi=1; ly6_iphi<=NBINS_PHI; ly6_iphi++) {
760 float ly6_phi = (ly6_h2_nsp->GetYaxis()->GetBinLowEdge(ly6_iphi) + ly6_h2_nsp->GetYaxis()->GetBinUpEdge(ly6_iphi))/2.0;
762 float ly6_nsp = ly6_h2_nsp ->GetBinContent(ly6_ieta,ly6_iphi);
763 float ly6_nsp_notrk = ly6_h2_nsp_notrk->GetBinContent(ly6_ieta,ly6_iphi);
764 float ly6_frac = ( ly6_nsp > 0 ) ? ly6_nsp_notrk / ly6_nsp : 0;
765 if( ly6_nsp < 10 || ly6_frac < 0.85 )
continue;
767 float ly7_frac_max = 0;
768 float ly7_eta_max = 0;
769 float ly7_phi_max = 0;
770 for(
int ly7_ieta=std::max(1,ly6_ieta-1); ly7_ieta<std::min(NBINS_ETA,ly6_ieta+1); ly7_ieta++) {
771 for(
int ly7_iphi=std::max(1,ly6_iphi-1); ly7_iphi<=std::min(NBINS_PHI,ly6_iphi+1); ly7_iphi++) {
772 float ly7_nsp = ly7_h2_nsp ->GetBinContent(ly7_ieta,ly7_iphi);
773 float ly7_nsp_notrk = ly7_h2_nsp_notrk->GetBinContent(ly7_ieta,ly7_iphi);
774 float ly7_frac = ( ly7_nsp > 0 ) ? ly7_nsp_notrk / ly7_nsp : 0;
775 if( ly7_nsp < 10 )
continue;
776 if( ly7_frac > ly7_frac_max ) {
777 ly7_frac_max = ly7_frac;
778 ly7_eta_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_ieta) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_ieta))/2.0;
779 ly7_phi_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_iphi) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_iphi))/2.0;
783 if( ly7_frac_max < 0.85 )
continue;
785 float wsum = ly6_frac + ly7_frac_max;
786 float weta = (ly6_eta*ly6_frac + ly7_eta_max*ly7_frac_max) / wsum;
787 float wphi = (ly6_phi*ly6_frac + ly7_phi_max*ly7_frac_max) / wsum;
788 float w = wsum / 2.0;
789 QT.push_back(std::make_tuple(-1,w,weta,wphi));
792 ATH_MSG_VERBOSE(
"nr of ly6/ly7 doublet candidate seeds=" << QT.size() <<
", doing clustering...");
796 [](
const std::tuple<int,float,float,float>& lhs,
const std::tuple<int,float,float,float>& rhs) {
797 return std::get<1>(lhs) > std::get<1>(rhs); } );
800 const double CLUSTCUT_DIST_SQUARED = 0.04;
801 const double CLUSTCUT_SEED_FRAC = 0.9;
803 std::vector<float> seeds_wsum;
805 for(
unsigned int i=0; i<QT.size(); i++) {
806 float phi = std::get<3>(QT[i]);
807 float eta = std::get<2>(QT[i]);
808 float w = std::get<1>(QT[i]);
810 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
811 seeds_wsum.push_back(w);
814 const int IDX_INITIAL = 100;
815 float dist2_min = 100.0;
816 int idx_min = IDX_INITIAL;
817 for(
unsigned j=0; j<seeds_eta.size(); j++) {
818 float ceta = seeds_eta[j]/seeds_wsum[j];
819 float cphi = seeds_phi[j]/seeds_wsum[j];
821 float deta = std::fabs(ceta-
eta);
822 float dphi = std::fabs(cphi-
phi);
823 float dist2 = dphi*dphi+deta*deta;
824 if( dist2 < dist2_min ) {
829 int match_idx = IDX_INITIAL;
830 if( idx_min != IDX_INITIAL ) {
831 if( dist2_min < CLUSTCUT_DIST_SQUARED ) { match_idx = idx_min; }
833 if( match_idx == IDX_INITIAL ) {
834 if( w > CLUSTCUT_SEED_FRAC && dist2_min > CLUSTCUT_DIST_SQUARED ) {
835 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
836 seeds_wsum.push_back(w);
840 float new_eta = seeds_eta[match_idx] + w*
eta;
841 float new_phi = seeds_phi[match_idx] + w*
phi;
842 float new_wsum = seeds_wsum[match_idx] + w;
843 seeds_eta[match_idx] = new_eta;
844 seeds_phi[match_idx] = new_phi;
845 seeds_wsum[match_idx] = new_wsum;
848 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
849 float eta = seeds_eta[i] / seeds_wsum[i];
850 float phi = seeds_phi[i] / seeds_wsum[i];
853 if(
phi < -TMath::Pi() )
phi = 2*TMath::Pi() +
phi;
854 if(
phi > TMath::Pi() )
phi = -2*TMath::Pi() +
phi;
857 ATH_MSG_VERBOSE(
"after clustering, nr of seeds = " << seeds_eta.size());
860 std::vector<unsigned int> idx_to_delete;
861 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
862 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),i) != idx_to_delete.end() )
continue;
863 float eta_i = seeds_eta[i];
864 float phi_i = seeds_phi[i];
865 for(
unsigned int j=i+1; j<seeds_eta.size(); j++) {
866 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),j) != idx_to_delete.end() )
continue;
867 float eta_j = seeds_eta[j];
868 float phi_j = seeds_phi[j];
869 float dR2 =
deltaR2(eta_i,phi_i,eta_j,phi_j);
870 if( dR2 < CLUSTCUT_DIST_SQUARED ) idx_to_delete.push_back(j);
873 ATH_MSG_VERBOSE(
"nr of duplicated seeds to be removed = " << idx_to_delete.size());
874 if( idx_to_delete.size() > 0 ) {
875 std::sort(idx_to_delete.begin(),idx_to_delete.end());
876 for(
unsigned int j=idx_to_delete.size(); j>0; j--) {
877 unsigned int idx = idx_to_delete[j-1];
878 seeds_eta.erase(seeds_eta.begin()+idx);
879 seeds_phi.erase(seeds_phi.begin()+idx);
886 return StatusCode::SUCCESS;
923 const std::vector<float>& v_sp_eta,
const std::vector<float>& v_sp_phi,
924 const std::vector<int>& v_sp_layer,
const std::vector<int>& v_sp_usedTrkId,
925 std::vector<float>& seeds_eta, std::vector<float>& seeds_phi )
const
927 const int NBINS_ETA = 50;
928 const float ETA_MIN = -2.5;
929 const float ETA_MAX = 2.5;
931 const int NBINS_PHI = 80;
932 const float PHI_MIN = -4.0;
933 const float PHI_MAX = 4.0;
937 unsigned int slotnr = ctx.slot();
938 unsigned int subSlotnr = ctx.subSlot();
940 sprintf(hname,
"ftf_s%u_ss%u_ly6_h2_nsp",slotnr,subSlotnr);
941 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);
942 sprintf(hname,
"ftf_s%u_ss%u_ly7_h2_nsp",slotnr,subSlotnr);
943 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);
945 sprintf(hname,
"ftf_s%u_ss%u_ly6_h2_nsp_notrk",slotnr,subSlotnr);
946 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);
947 sprintf(hname,
"ftf_s%u_ss%u_ly7_h2_nsp_notrk",slotnr,subSlotnr);
948 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);
950 for(
unsigned int iSeed=0; iSeed<v_sp_eta.size(); ++iSeed) {
952 int sp_layer = v_sp_layer[iSeed];
953 float sp_eta = v_sp_eta[iSeed];
955 if( ilayer<6 )
continue;
957 int sp_trkid = v_sp_usedTrkId[iSeed];
958 bool isUsedByTrk = (sp_trkid != -1);
959 float sp_phi = v_sp_phi[iSeed];
961 bool fill_out_of_pi =
false;
964 sp_phi2 = 2*TMath::Pi() + sp_phi;
965 if( sp_phi2 < PHI_MAX ) fill_out_of_pi =
true;
968 sp_phi2 = -2*TMath::Pi() + sp_phi;
969 if( PHI_MIN < sp_phi2 ) fill_out_of_pi =
true;
972 ly6_h2_nsp->Fill(sp_eta,sp_phi);
973 if( fill_out_of_pi ) ly6_h2_nsp->Fill(sp_eta,sp_phi2);
974 if( ! isUsedByTrk ) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi);
975 if( ! isUsedByTrk && fill_out_of_pi) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
978 ly7_h2_nsp->Fill(sp_eta,sp_phi);
979 if( fill_out_of_pi ) ly7_h2_nsp->Fill(sp_eta,sp_phi2);
980 if( ! isUsedByTrk ) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi);
981 if( ! isUsedByTrk && fill_out_of_pi) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
988 std::vector<std::tuple<int,float,float,float>> QT;
990 for(
int ly6_ieta=1; ly6_ieta<=NBINS_ETA; ly6_ieta++) {
991 float ly6_eta = (ly6_h2_nsp->GetXaxis()->GetBinLowEdge(ly6_ieta) + ly6_h2_nsp->GetXaxis()->GetBinUpEdge(ly6_ieta))/2.0;
992 for(
int ly6_iphi=1; ly6_iphi<=NBINS_PHI; ly6_iphi++) {
993 float ly6_phi = (ly6_h2_nsp->GetYaxis()->GetBinLowEdge(ly6_iphi) + ly6_h2_nsp->GetYaxis()->GetBinUpEdge(ly6_iphi))/2.0;
995 float ly6_nsp = ly6_h2_nsp ->GetBinContent(ly6_ieta,ly6_iphi);
996 float ly6_nsp_notrk = ly6_h2_nsp_notrk->GetBinContent(ly6_ieta,ly6_iphi);
997 float ly6_frac = ( ly6_nsp > 0 ) ? ly6_nsp_notrk / ly6_nsp : 0;
998 if( ly6_nsp < 10 || ly6_frac < 0.85 )
continue;
1000 float ly7_frac_max = 0;
1001 float ly7_eta_max = 0;
1002 float ly7_phi_max = 0;
1003 for(
int ly7_ieta=std::max(1,ly6_ieta-1); ly7_ieta<std::min(NBINS_ETA,ly6_ieta+1); ly7_ieta++) {
1004 for(
int ly7_iphi=std::max(1,ly6_iphi-1); ly7_iphi<=std::min(NBINS_PHI,ly6_iphi+1); ly7_iphi++) {
1005 float ly7_nsp = ly7_h2_nsp ->GetBinContent(ly7_ieta,ly7_iphi);
1006 float ly7_nsp_notrk = ly7_h2_nsp_notrk->GetBinContent(ly7_ieta,ly7_iphi);
1007 float ly7_frac = ( ly7_nsp > 0 ) ? ly7_nsp_notrk / ly7_nsp : 0;
1008 if( ly7_nsp < 10 )
continue;
1009 if( ly7_frac > ly7_frac_max ) {
1010 ly7_frac_max = ly7_frac;
1011 ly7_eta_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_ieta) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_ieta))/2.0;
1012 ly7_phi_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_iphi) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_iphi))/2.0;
1016 if( ly7_frac_max < 0.85 )
continue;
1018 float wsum = ly6_frac + ly7_frac_max;
1019 float weta = (ly6_eta*ly6_frac + ly7_eta_max*ly7_frac_max) / wsum;
1020 float wphi = (ly6_phi*ly6_frac + ly7_phi_max*ly7_frac_max) / wsum;
1021 float w = wsum / 2.0;
1022 QT.push_back(std::make_tuple(-1,w,weta,wphi));
1025 ATH_MSG_VERBOSE(
"nr of ly6/ly7 doublet candidate seeds=" << QT.size() <<
", doing clustering...");
1029 [](
const std::tuple<int,float,float,float>& lhs,
const std::tuple<int,float,float,float>& rhs) {
1030 return std::get<1>(lhs) > std::get<1>(rhs); } );
1033 const double CLUSTCUT_DIST_SQUARED = 0.04;
1034 const double CLUSTCUT_SEED_FRAC = 0.9;
1036 std::vector<float> seeds_wsum;
1038 for(
unsigned int i=0; i<QT.size(); i++) {
1039 float phi = std::get<3>(QT[i]);
1040 float eta = std::get<2>(QT[i]);
1041 float w = std::get<1>(QT[i]);
1043 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
1044 seeds_wsum.push_back(w);
1047 const int IDX_INITIAL = 100;
1048 float dist2_min = 100.0;
1049 int idx_min = IDX_INITIAL;
1050 for(
unsigned j=0; j<seeds_eta.size(); j++) {
1051 float ceta = seeds_eta[j]/seeds_wsum[j];
1052 float cphi = seeds_phi[j]/seeds_wsum[j];
1054 float deta = std::fabs(ceta-
eta);
1055 float dphi = std::fabs(cphi-
phi);
1056 float dist2 = dphi*dphi+deta*deta;
1057 if( dist2 < dist2_min ) {
1062 int match_idx = IDX_INITIAL;
1063 if( idx_min != IDX_INITIAL ) {
1064 if( dist2_min < CLUSTCUT_DIST_SQUARED ) { match_idx = idx_min; }
1066 if( match_idx == IDX_INITIAL ) {
1067 if( w > CLUSTCUT_SEED_FRAC && dist2_min > CLUSTCUT_DIST_SQUARED ) {
1068 seeds_eta.push_back(w*
eta); seeds_phi.push_back(w*
phi);
1069 seeds_wsum.push_back(w);
1073 float new_eta = seeds_eta[match_idx] + w*
eta;
1074 float new_phi = seeds_phi[match_idx] + w*
phi;
1075 float new_wsum = seeds_wsum[match_idx] + w;
1076 seeds_eta[match_idx] = new_eta;
1077 seeds_phi[match_idx] = new_phi;
1078 seeds_wsum[match_idx] = new_wsum;
1081 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
1082 float eta = seeds_eta[i] / seeds_wsum[i];
1083 float phi = seeds_phi[i] / seeds_wsum[i];
1085 if(
phi < -TMath::Pi() )
phi = 2*TMath::Pi() +
phi;
1086 if(
phi > TMath::Pi() )
phi = -2*TMath::Pi() +
phi;
1089 ATH_MSG_VERBOSE(
"after clustering, nr of seeds = " << seeds_eta.size());
1092 std::vector<unsigned int> idx_to_delete;
1093 for(
unsigned int i=0; i<seeds_eta.size(); i++) {
1094 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),i) != idx_to_delete.end() )
continue;
1095 float eta_i = seeds_eta[i];
1096 float phi_i = seeds_phi[i];
1097 for(
unsigned int j=i+1; j<seeds_eta.size(); j++) {
1098 if( std::find(idx_to_delete.begin(),idx_to_delete.end(),j) != idx_to_delete.end() )
continue;
1099 float eta_j = seeds_eta[j];
1100 float phi_j = seeds_phi[j];
1101 float dR2 =
deltaR2(eta_i,phi_i,eta_j,phi_j);
1102 if( dR2 < CLUSTCUT_DIST_SQUARED ) idx_to_delete.push_back(j);
1105 ATH_MSG_VERBOSE(
"nr of duplicated seeds to be removed = " << idx_to_delete.size());
1106 if( idx_to_delete.size() > 0 ) {
1107 std::sort(idx_to_delete.begin(),idx_to_delete.end());
1108 for(
unsigned int j=idx_to_delete.size(); j>0; j--) {
1109 unsigned int idx = idx_to_delete[j-1];
1110 seeds_eta.erase(seeds_eta.begin()+idx);
1111 seeds_phi.erase(seeds_phi.begin()+idx);
1118 return StatusCode::SUCCESS;
1123 std::vector<HitDVTrk>& hitDVTrksContainer,
1124 std::vector<HitDVSpacePoint>& hitDVSPsContainer)
const
1126 std::vector<int> v_dvtrk_id;
1127 std::vector<float> v_dvtrk_pt;
1128 std::vector<float> v_dvtrk_eta;
1129 std::vector<float> v_dvtrk_phi;
1130 std::vector<int> v_dvtrk_n_hits_inner;
1131 std::vector<int> v_dvtrk_n_hits_pix;
1132 std::vector<int> v_dvtrk_n_hits_sct;
1133 std::vector<float> v_dvtrk_a0beam;
1134 std::unordered_map<Identifier, int> umap_fittedTrack_identifier;
1135 int fittedTrack_id = -1;
1137 static constexpr float TRKCUT_PTGEV_HITDV = 0.5;
1139 for (
const auto track: tracks) {
1140 float shift_x = 0;
float shift_y = 0;
1146 bool igt =
FTF::isGoodTrackUTT(track, theTrackInfo, shift_x, shift_y, TRKCUT_PTGEV_HITDV);
1147 if (not igt) {
continue;}
1154 m = track->measurementsOnTrack()->begin(),
1155 me = track->measurementsOnTrack()->end ();
1156 for(; m!=me; ++m ) {
1158 if( prd ==
nullptr )
continue;
1160 if( umap_fittedTrack_identifier.find(id_prd) == umap_fittedTrack_identifier.end() ) {
1161 umap_fittedTrack_identifier.insert(std::make_pair(id_prd,fittedTrack_id));
1164 float phi = track->perigeeParameters()->parameters()[
Trk::phi];
1165 v_dvtrk_id.push_back(fittedTrack_id);
1166 v_dvtrk_pt.push_back(theTrackInfo.
ptGeV*Gaudi::Units::GeV);
1167 v_dvtrk_eta.push_back(theTrackInfo.
eta);
1168 v_dvtrk_phi.push_back(
phi);
1169 v_dvtrk_n_hits_inner.push_back(theTrackInfo.
n_hits_inner);
1170 v_dvtrk_n_hits_pix.push_back(theTrackInfo.
n_hits_pix);
1171 v_dvtrk_n_hits_sct.push_back(theTrackInfo.
n_hits_sct);
1172 v_dvtrk_a0beam.push_back(theTrackInfo.
a0beam);
1174 ATH_MSG_DEBUG(
"Nr of selected tracks / all = " << fittedTrack_id <<
" / " << tracks.
size());
1175 ATH_MSG_DEBUG(
"Nr of Identifiers used by selected tracks = " << umap_fittedTrack_identifier.size());
1179 int n_sp_usedByTrk = 0;
1181 std::unordered_map<Identifier, int> umap_sp_identifier;
1182 umap_sp_identifier.reserve(1.3*convertedSpacePoints.size());
1187 if( umap_sp_identifier.find(id_prd) == umap_sp_identifier.end() ) {
1188 umap_sp_identifier.insert(std::make_pair(id_prd,-1));
1193 for(
unsigned int iSp=0; iSp<convertedSpacePoints.size(); ++iSp) {
1194 bool isPix = convertedSpacePoints[iSp].isPixel();
1195 bool isSct = convertedSpacePoints[iSp].isSCT();
1196 if( ! isPix && ! isSct )
continue;
1198 add_to_sp_map(
sp->clusterList().first);
1199 add_to_sp_map(
sp->clusterList().second);
1201 int n_id_usedByTrack = 0;
1202 for(
auto it=umap_sp_identifier.begin(); it!=umap_sp_identifier.end(); ++it) {
1204 if( umap_fittedTrack_identifier.find(id_sp) != umap_fittedTrack_identifier.end() ) {
1205 umap_sp_identifier[id_sp] = umap_fittedTrack_identifier[id_sp];
1209 ATH_MSG_DEBUG(
"Nr of SPs / Identifiers (all) / Identifiers (usedByTrack) = " << convertedSpacePoints.size() <<
" / " << umap_sp_identifier.size() <<
" / " << n_id_usedByTrack);
1212 int usedTrack_id = -1;
1215 if( umap_sp_identifier.find(id_prd) != umap_sp_identifier.end() ) {
1216 usedTrack_id = umap_sp_identifier[id_prd];
1219 return usedTrack_id;
1222 std::vector<float> v_sp_eta;
1223 v_sp_eta.reserve(convertedSpacePoints.size());
1224 std::vector<float> v_sp_r;
1225 v_sp_r.reserve(convertedSpacePoints.size());
1226 std::vector<float> v_sp_phi;
1227 v_sp_phi.reserve(convertedSpacePoints.size());
1228 std::vector<int> v_sp_layer;
1229 v_sp_layer.reserve(convertedSpacePoints.size());
1230 std::vector<bool> v_sp_isPix;
1231 v_sp_isPix.reserve(convertedSpacePoints.size());
1232 std::vector<bool> v_sp_isSct;
1233 v_sp_isSct.reserve(convertedSpacePoints.size());
1234 std::vector<int> v_sp_usedTrkId;
1235 v_sp_usedTrkId.reserve(convertedSpacePoints.size());
1237 for(
const auto&
sp : convertedSpacePoints) {
1238 bool isPix =
sp.isPixel();
1239 bool isSct =
sp.isSCT();
1240 if( ! isPix && ! isSct )
continue;
1243 int usedTrack_id = -1;
1244 int usedTrack_id_first = sp_map_used_id(osp->
clusterList().first);
1245 if (usedTrack_id_first != -1) {
1246 usedTrack_id = usedTrack_id_first;
1248 int usedTrack_id_second = sp_map_used_id(osp->
clusterList().second);
1249 if (usedTrack_id_second != -1) {
1250 usedTrack_id = usedTrack_id_second;
1255 if( usedTrack_id != -1 ) n_sp_usedByTrk++;
1256 int layer =
sp.layer();
1257 float sp_r =
sp.r();
1260 float sp_eta = pos_sp.eta();
1261 float sp_phi = pos_sp.phi();
1263 v_sp_eta.push_back(sp_eta);
1264 v_sp_r.push_back(sp_r);
1265 v_sp_phi.push_back(sp_phi);
1266 v_sp_layer.push_back(layer);
1267 v_sp_isPix.push_back(isPix);
1268 v_sp_isSct.push_back(isSct);
1269 v_sp_usedTrkId.push_back(usedTrack_id);
1271 ATH_MSG_VERBOSE(
"+++ SP eta / phi / layer / ixPix / usedTrack_id = " << sp_eta <<
" / " << sp_phi <<
" / " << layer <<
" / " << isPix <<
" / " << usedTrack_id);
1274 ATH_MSG_DEBUG(
"Nr of SPs / all = " << n_sp <<
" / " << convertedSpacePoints.size());
1275 ATH_MSG_DEBUG(
"Nr of SPs used by selected tracks = " << n_sp_usedByTrk);
1278 std::vector<float> v_seeds_eta;
1279 std::vector<float> v_seeds_phi;
1280 std::vector<int16_t> v_seeds_type;
1285 const unsigned int L1JET_ET_CUT = 27;
1289 if (!jetRoiCollectionHandle.isValid()){
1291 return StatusCode::FAILURE;
1295 if( jetRoI ==
nullptr )
continue;
1297 if( jetRoI->
et() >= L1JET_ET_CUT ) {
1298 v_seeds_eta.push_back(jetRoI->
eta());
1299 v_seeds_phi.push_back(jetRoI->
phi());
1300 v_seeds_type.push_back(0);
1303 ATH_MSG_DEBUG(
"Nr of L1_J" << L1JET_ET_CUT <<
" seeds = " << v_seeds_eta.size());
1306 std::vector<float> v_spseeds_eta;
1307 std::vector<float> v_spseeds_phi;
1308 ATH_CHECK(
findSPSeeds(ctx, v_sp_eta, v_sp_phi, v_sp_layer, v_sp_usedTrkId, v_spseeds_eta, v_spseeds_phi) );
1310 for(
size_t idx=0; idx<v_spseeds_eta.size(); ++idx) {
1311 v_seeds_eta.push_back(v_spseeds_eta[idx]);
1312 v_seeds_phi.push_back(v_spseeds_phi[idx]);
1313 v_seeds_type.push_back(1);
1315 ATH_MSG_DEBUG(
"Nr of SP + L1_J" << L1JET_ET_CUT <<
" seeds = " << v_seeds_eta.size());
1321 const int N_MAX_SEEDS = 200;
1322 int n_seeds = std::min(N_MAX_SEEDS,(
int)v_seeds_eta.size());
1323 hitDVSeedsContainer.reserve(n_seeds);
1324 for(
auto iSeed=0; iSeed < n_seeds; ++iSeed) {
1326 seed.eta = v_seeds_eta[iSeed];
1327 seed.phi = v_seeds_phi[iSeed];
1328 seed.type = v_seeds_type[iSeed];
1329 hitDVSeedsContainer.push_back(seed);
1333 const float TRKCUT_DELTA_R_TO_SEED = 1.0;
1334 hitDVTrksContainer.reserve(v_dvtrk_pt.size());
1335 for(
unsigned int iTrk=0; iTrk<v_dvtrk_pt.size(); ++iTrk) {
1336 float trk_eta = v_dvtrk_eta[iTrk];
1337 float trk_phi = v_dvtrk_phi[iTrk];
1339 bool isNearSeed =
false;
1340 for (
unsigned int iSeed=0; iSeed<v_seeds_eta.size(); ++iSeed) {
1341 float seed_eta = v_seeds_eta[iSeed];
1342 float seed_phi = v_seeds_phi[iSeed];
1343 float dR2 =
deltaR2(trk_eta,trk_phi,seed_eta,seed_phi);
1344 if( dR2 <= TRKCUT_DELTA_R_TO_SEED*TRKCUT_DELTA_R_TO_SEED ) { isNearSeed =
true;
break; }
1346 if( ! isNearSeed )
continue;
1349 hitDVTrk.
id = v_dvtrk_id[iTrk];
1350 hitDVTrk.
pt = v_dvtrk_pt[iTrk];
1351 hitDVTrk.
eta = v_dvtrk_eta[iTrk];
1352 hitDVTrk.
phi = v_dvtrk_phi[iTrk];
1354 hitDVTrk.
n_hits_pix = v_dvtrk_n_hits_pix[iTrk];
1355 hitDVTrk.
n_hits_sct = v_dvtrk_n_hits_sct[iTrk];
1356 hitDVTrk.
a0beam = v_dvtrk_a0beam[iTrk];
1358 hitDVTrksContainer.push_back(hitDVTrk);
1362 const float SPCUT_DELTA_R_TO_SEED = 1.0;
1363 const size_t n_sp_max = std::min<size_t>(100000, v_sp_eta.size());
1364 size_t n_sp_stored = 0;
1366 hitDVSPsContainer.reserve(n_sp_max);
1368 for(
size_t iSp=0; iSp<v_sp_eta.size(); ++iSp) {
1370 const float sp_eta = v_sp_eta[iSp];
1371 const float sp_phi = v_sp_phi[iSp];
1372 bool isNearSeed =
false;
1373 for (
size_t iSeed=0; iSeed<v_seeds_eta.size(); ++iSeed) {
1374 const float seed_eta = v_seeds_eta[iSeed];
1375 const float seed_phi = v_seeds_phi[iSeed];
1376 const float dR2 =
deltaR2(sp_eta, sp_phi, seed_eta, seed_phi);
1377 if( dR2 <= SPCUT_DELTA_R_TO_SEED*SPCUT_DELTA_R_TO_SEED ) { isNearSeed =
true;
break; }
1379 if( ! isNearSeed )
continue;
1381 if( n_sp_stored >= n_sp_max )
break;
1383 hitDVSP.
eta = v_sp_eta[iSp];
1384 hitDVSP.
r = v_sp_r[iSp];
1385 hitDVSP.
phi = v_sp_phi[iSp];
1386 hitDVSP.
layer = v_sp_layer[iSp];
1387 hitDVSP.
isPix = v_sp_isPix[iSp];
1388 hitDVSP.
isSct = v_sp_isSct[iSp];
1389 hitDVSP.
usedTrkId = v_sp_usedTrkId[iSp];
1390 hitDVSPsContainer.push_back(hitDVSP);
1395 return StatusCode::SUCCESS;