330 std::ostringstream
os;
352 std::vector<unsigned int> sel_track_idc;
354 std::map<unsigned int, std::vector<unsigned int>> trackingSelection;
356 for (
unsigned int idx = 0;
idx < hTracks->size(); ++
idx) {
357 const auto &tr = hTracks->at(
idx);
369 sel_track_idc.push_back(
idx);
373 const bool trackerRP =
377 trackingSelection[
rpId.arm()].push_back(
idx);
382 os <<
"* tracks (pre-selected):" << std::endl;
384 for (
const auto idx : sel_track_idc) {
385 const auto &tr = hTracks->at(
idx);
389 os <<
" [" <<
idx <<
"] RP=" <<
decRPId <<
", x=" << tr.x() <<
", y=" << tr.y() << std::endl;
392 os <<
"* protons:" << std::endl;
393 for (
unsigned int i = 0;
i < hRecoProtonsMultiRP->size(); ++
i) {
394 const auto &
pr = (*hRecoProtonsMultiRP)[
i];
395 os <<
" [" <<
i <<
"] track indices: ";
396 for (
const auto &trr :
pr.contributingLocalTracks())
397 os << trr.key() <<
", ";
403 map<unsigned int, bool> hasTracksInArm;
405 for (
const auto idx_i : sel_track_idc) {
406 const auto &tr_i = hTracks->at(idx_i);
408 unsigned int decRPId_i = rpId_i.
arm() * 100 + rpId_i.station() * 10 + rpId_i.rp();
410 for (
const auto idx_j : sel_track_idc) {
411 const auto &tr_j = hTracks->at(idx_j);
413 unsigned int decRPId_j = rpId_j.
arm() * 100 + rpId_j.station() * 10 + rpId_j.rp();
416 unsigned int arm = 123;
417 for (
const auto &ap :
data_) {
418 if (ap.second.rpId_N == decRPId_i && ap.second.rpId_F == decRPId_j)
426 hasTracksInArm[
arm] =
true;
430 const double de_x = tr_j.x() - tr_i.x();
431 const double de_y = tr_j.y() - tr_i.y();
434 ad.h_de_x->Fill(
de_x);
435 ad.h_de_y->Fill(
de_y);
438 ad.h2_de_y_vs_de_x->Fill(
de_x,
de_y);
443 for (
auto &ap :
data_) {
444 if (hasTracksInArm[ap.first])
445 ap.second.n_events_with_tracks++;
449 for (
auto &ap :
data_) {
450 auto &ad = ap.second;
453 if (ad.de_x_sigma > 0. && ad.de_y_sigma > 0.)
456 std::vector<std::pair<unsigned int, TH1D *>>
m;
457 m.emplace_back(0, ad.h_de_x.get());
458 m.emplace_back(1, ad.h_de_y.get());
460 for (
const auto &
p :
m) {
461 double max_pos = -1E100, max_val = -1.;
462 for (
int bi = 1; bi <
p.second->GetNbinsX(); ++bi) {
463 const double pos =
p.second->GetBinCenter(bi);
464 const double val =
p.second->GetBinContent(bi);
472 const double sig = 0.2;
474 ff_->SetParameters(max_val, max_pos, sig, 0.);
475 p.second->Fit(
ff_.get(),
"Q",
"", max_pos - 3. * sig, max_pos + 3. * sig);
476 p.second->Fit(
ff_.get(),
"Q",
"", max_pos - 3. * sig, max_pos + 3. * sig);
479 ad.de_x_mean =
ff_->GetParameter(1);
480 ad.de_x_sigma = fabs(
ff_->GetParameter(2));
483 ad.de_y_mean =
ff_->GetParameter(1);
484 ad.de_y_sigma = fabs(
ff_->GetParameter(2));
489 os <<
"* fitting arm " << ap.first << std::endl
490 <<
" de_x: mean = " << ad.de_x_mean <<
", sigma = " << ad.de_x_sigma << std::endl
491 <<
" de_y: mean = " << ad.de_y_mean <<
", sigma = " << ad.de_y_sigma;
504 struct ArmEventData {
506 std::map<unsigned int, std::set<unsigned int>> matched_track_idc;
509 std::set<unsigned int> reco_proton_idc;
512 std::map<unsigned int, std::set<unsigned int>> matched_track_with_prot_idc, matched_track_without_prot_idc;
515 struct EvaluatedPair {
516 unsigned idx_N, idx_F;
522 vector<EvaluatedPair> evaluatedPairs;
525 std::map<unsigned int, ArmEventData> armEventData;
528 for (
const auto idx_i : sel_track_idc) {
529 const auto &tr_i = hTracks->at(idx_i);
531 unsigned int decRPId_i = rpId_i.
arm() * 100 + rpId_i.station() * 10 + rpId_i.rp();
533 for (
const auto idx_j : sel_track_idc) {
534 const auto &tr_j = hTracks->at(idx_j);
536 unsigned int decRPId_j = rpId_j.
arm() * 100 + rpId_j.station() * 10 + rpId_j.rp();
539 unsigned int arm = 123;
540 for (
const auto &ap :
data_) {
541 if (ap.second.rpId_N == decRPId_i && ap.second.rpId_F == decRPId_j)
550 const double de_x = tr_j.x() - tr_i.x();
551 const double de_y = tr_j.y() - tr_i.y();
553 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
554 const double n_si = ad.n_sigmas[nsi];
555 const bool match_x = fabs(
de_x - ad.de_x_mean) < n_si * ad.de_x_sigma;
556 const bool match_y = fabs(
de_y - ad.de_y_mean) < n_si * ad.de_y_sigma;
557 if (match_x && match_y)
558 armEventData[
arm].matched_track_idc[nsi].insert(idx_i);
564 for (
unsigned int i = 0;
i < hRecoProtonsMultiRP->size(); ++
i) {
565 const auto &proton = (*hRecoProtonsMultiRP)[
i];
570 if (proton.validFit())
571 armEventData[
arm].reco_proton_idc.insert(
i);
576 os <<
"* cmp matched tracks vs. reco protons" << std::endl;
578 for (
auto &ap : armEventData) {
579 auto &ad =
data_[ap.first];
582 os <<
" arm " << ap.first << std::endl;
584 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
586 os <<
" nsi = " << nsi << std::endl;
588 for (
const auto &tri : ap.second.matched_track_idc[nsi]) {
589 const auto &
track = hTracks->at(tri);
591 bool some_proton_matching =
false;
594 os <<
" tri = " << tri << std::endl;
596 for (
const auto &pri : ap.second.reco_proton_idc) {
597 const auto &proton = (*hRecoProtonsMultiRP)[pri];
599 bool proton_matching =
false;
601 for (
const auto &pr_tr : proton.contributingLocalTracks()) {
608 const double x = pr_tr->x();
609 const double y = pr_tr->y();
610 const double th = 1E-3;
615 os <<
" pri = " << pri <<
": x_tr = " <<
track.x() <<
", x_pr = " <<
x 616 <<
", match = " <<
match << std::endl;
619 proton_matching =
true;
624 if (proton_matching) {
625 some_proton_matching =
true;
631 os <<
" --> some_proton_matching " << some_proton_matching << std::endl;
633 if (some_proton_matching)
634 ap.second.matched_track_with_prot_idc[nsi].insert(tri);
636 ap.second.matched_track_without_prot_idc[nsi].insert(tri);
642 for (
auto &ap : armEventData) {
643 const auto &
arm = ap.first;
647 auto &aed = ap.second;
649 auto &ass_cut = ppsAssociationCuts.getAssociationCuts(
arm);
653 map<unsigned int, unsigned> matching_multiplicity;
657 const auto &tr_i = hTracks->at(
i);
658 const auto &tr_j = hTracks->at(
j);
663 const unsigned rpDecId_i = id_i.
arm() * 100 + id_i.station() * 10 + id_i.rp();
664 const unsigned rpDecId_j = id_j.arm() * 100 + id_j.station() * 10 + id_j.rp();
666 if (rpDecId_i != ad.rpId_N || rpDecId_j != ad.rpId_F)
669 ArmEventData::EvaluatedPair evp;
674 ass_cut.isSatisfied(ass_cut.qX, tr_i.x(), tr_i.y(), lhcInfoCombined.crossingAngle(), tr_i.x() - tr_j.x());
676 ass_cut.isSatisfied(ass_cut.qY, tr_i.x(), tr_i.y(), lhcInfoCombined.crossingAngle(), tr_i.y() - tr_j.y());
678 evp.match = evp.x_cut && evp.y_cut;
680 aed.evaluatedPairs.push_back(evp);
683 matching_multiplicity[
i]++;
684 matching_multiplicity[
j]++;
689 for (
auto &evp : aed.evaluatedPairs)
690 evp.unique = (matching_multiplicity[evp.idx_N] == 1) && (matching_multiplicity[evp.idx_F] == 1);
695 for (
auto &ap : armEventData) {
696 auto &ad =
data_[ap.first];
698 if (ad.de_x_sigma <= 0. && ad.de_y_sigma <= 0.)
701 os <<
"* results for arm " << ap.first << std::endl;
703 os <<
" reco_proton_idc: ";
704 for (
const auto &
idx : ap.second.reco_proton_idc)
708 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
709 os <<
" n_si = " << ad.n_sigmas[nsi] << std::endl;
711 os <<
" matched_track_idc: ";
712 for (
const auto &
idx : ap.second.matched_track_idc[nsi])
716 os <<
" matched_track_with_prot_idc: ";
717 for (
const auto &
idx : ap.second.matched_track_with_prot_idc[nsi])
721 os <<
" matched_track_without_prot_idc: ";
722 for (
const auto &
idx : ap.second.matched_track_without_prot_idc[nsi])
727 os <<
" evaluated pairs: ";
728 for (
const auto &
p : ap.second.evaluatedPairs)
729 os <<
"(" <<
p.idx_N <<
"-" <<
p.idx_F <<
",M" <<
p.match <<
",U" <<
p.unique <<
")" 736 for (
auto &ap : armEventData) {
737 const auto &
arm = ap.first;
741 if (ad.de_x_sigma <= 0. && ad.de_y_sigma <= 0.)
745 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
746 const unsigned int n_exp_prot = ap.second.matched_track_idc[nsi].size();
747 const unsigned int n_rec_prot = ap.second.reco_proton_idc.size();
750 if (n_exp_prot < 1 || n_exp_prot > ad.n_exp_prot_max)
754 const double eff = double(n_rec_prot) / n_exp_prot;
756 for (
unsigned int tri : ap.second.matched_track_idc[nsi]) {
757 const double x_N = hTracks->at(tri).x();
758 const double xi_N = ad.s_x_to_xi_N->Eval(x_N * 1E-1);
760 ad.effPlots[0][nsi].p_eff1_vs_x_N->Fill(x_N, eff);
761 ad.effPlots[0][nsi].p_eff1_vs_xi_N->Fill(xi_N, eff);
763 ad.effPlots[n_exp_prot][nsi].p_eff1_vs_x_N->Fill(x_N, eff);
764 ad.effPlots[n_exp_prot][nsi].p_eff1_vs_xi_N->Fill(xi_N, eff);
768 for (
const auto &tri : ap.second.matched_track_with_prot_idc[nsi]) {
769 const double x_N = hTracks->at(tri).x();
770 const double xi_N = ad.s_x_to_xi_N->Eval(x_N * 1E-1);
772 ad.effPlots[0][nsi].p_eff2_vs_x_N->Fill(x_N, 1.);
773 ad.effPlots[0][nsi].p_eff2_vs_xi_N->Fill(xi_N, 1.);
775 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_x_N->Fill(x_N, 1.);
776 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_xi_N->Fill(xi_N, 1.);
779 for (
const auto &tri : ap.second.matched_track_without_prot_idc[nsi]) {
780 const double x_N = hTracks->at(tri).x();
781 const double xi_N = ad.s_x_to_xi_N->Eval(x_N * 1E-1);
783 ad.effPlots[0][nsi].p_eff2_vs_x_N->Fill(x_N, 0.);
784 ad.effPlots[0][nsi].p_eff2_vs_xi_N->Fill(xi_N, 0.);
786 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_x_N->Fill(x_N, 0.);
787 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_xi_N->Fill(xi_N, 0.);
791 for (
const auto &
cand : ap.second.matched_track_idc[nsi])
793 const double x_N = hTracks->at(
cand).x();
795 auto &
plots = ad.effPlots[n_exp_prot][nsi];
797 bool hasMatchingAndUniquePair =
false;
798 bool hasMatchingAndNonUniquePair =
false;
799 for (
const auto &pair : ap.second.evaluatedPairs)
802 if (
cand != pair.idx_N)
805 if (pair.match && pair.unique)
806 hasMatchingAndUniquePair =
true;
808 if (pair.match && !pair.unique)
809 hasMatchingAndNonUniquePair =
true;
812 if (!pair.x_cut && !pair.y_cut)
814 if (pair.x_cut && !pair.y_cut)
816 if (!pair.x_cut && pair.y_cut)
818 if (pair.x_cut && pair.y_cut)
827 plots.p_fr_match_unique->Fill(x_N, (hasMatchingAndUniquePair) ? 1 : 0);
828 plots.p_fr_match_non_unique->Fill(x_N, (hasMatchingAndNonUniquePair) ? 1 : 0);
834 edm::LogInfo(
"CTPPSProtonReconstructionEfficiencyEstimatorData") <<
os.str();
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
const edm::ESGetToken< LHCInfoPerFill, LHCInfoPerFillRcd > lhcInfoPerFillToken_
std::map< unsigned int, ArmData > data_
def unique(seq, keepstr=True)
edm::EDGetTokenT< reco::ForwardProtonCollection > tokenRecoProtonsMultiRP_
const edm::ESGetToken< LHCInfoPerLS, LHCInfoPerLSRcd > lhcInfoPerLSToken_
const bool useNewLHCInfo_
std::unique_ptr< TF1 > ff_
const edm::ESGetToken< LHCInfo, LHCInfoRcd > lhcInfoToken_
bool pixelDiscardBXShiftedTracks_
Log< level::Info, false > LogInfo
edm::ESGetToken< LHCInterpolatedOpticalFunctionsSetCollection, CTPPSInterpolatedOpticsRcd > opticsESToken_
bool check(const edm::EventSetup &iSetup)
Base class for CTPPS detector IDs.
edm::EDGetTokenT< CTPPSLocalTrackLiteCollection > tokenTracks_
unsigned int n_prep_events_
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined signature
edm::ESWatcher< CTPPSInterpolatedOpticsRcd > opticsWatcher_
edm::ESGetToken< PPSAssociationCuts, PPSAssociationCutsRcd > ppsAssociationCutsToken_