321 std::ostringstream os;
342 std::vector<unsigned int> sel_track_idc;
344 std::map<unsigned int, std::vector<unsigned int>> trackingSelection;
346 for (
unsigned int idx = 0;
idx < hTracks->size(); ++
idx) {
347 const auto &tr = hTracks->at(
idx);
359 sel_track_idc.push_back(
idx);
363 const bool trackerRP =
367 trackingSelection[rpId.arm()].push_back(
idx);
372 os <<
"* tracks (pre-selected):" << std::endl;
374 for (
const auto idx : sel_track_idc) {
375 const auto &tr = hTracks->at(
idx);
377 unsigned int decRPId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
379 os <<
" [" <<
idx <<
"] RP=" <<
decRPId <<
", x=" << tr.x() <<
", y=" << tr.y() << std::endl;
382 os <<
"* protons:" << std::endl;
383 for (
unsigned int i = 0;
i < hRecoProtonsMultiRP->size(); ++
i) {
384 const auto &
pr = (*hRecoProtonsMultiRP)[
i];
385 os <<
" [" <<
i <<
"] track indices: ";
386 for (
const auto &trr :
pr.contributingLocalTracks())
387 os << trr.key() <<
", ";
393 map<unsigned int, bool> hasTracksInArm;
395 for (
const auto idx_i : sel_track_idc) {
396 const auto &tr_i = hTracks->at(idx_i);
398 unsigned int decRPId_i = rpId_i.
arm() * 100 + rpId_i.station() * 10 + rpId_i.rp();
400 for (
const auto idx_j : sel_track_idc) {
401 const auto &tr_j = hTracks->at(idx_j);
403 unsigned int decRPId_j = rpId_j.
arm() * 100 + rpId_j.station() * 10 + rpId_j.rp();
406 unsigned int arm = 123;
407 for (
const auto &ap :
data_) {
408 if (ap.second.rpId_N == decRPId_i && ap.second.rpId_F == decRPId_j)
416 hasTracksInArm[
arm] =
true;
420 const double de_x = tr_j.x() - tr_i.x();
421 const double de_y = tr_j.y() - tr_i.y();
424 ad.h_de_x->Fill(
de_x);
425 ad.h_de_y->Fill(
de_y);
428 ad.h2_de_y_vs_de_x->Fill(
de_x,
de_y);
433 for (
auto &ap :
data_) {
434 if (hasTracksInArm[ap.first])
435 ap.second.n_events_with_tracks++;
439 for (
auto &ap :
data_) {
440 auto &ad = ap.second;
443 if (ad.de_x_sigma > 0. && ad.de_y_sigma > 0.)
446 std::vector<std::pair<unsigned int, TH1D *>>
m;
447 m.emplace_back(0, ad.h_de_x.get());
448 m.emplace_back(1, ad.h_de_y.get());
450 for (
const auto &
p :
m) {
451 double max_pos = -1E100, max_val = -1.;
452 for (
int bi = 1; bi <
p.second->GetNbinsX(); ++bi) {
453 const double pos =
p.second->GetBinCenter(bi);
454 const double val =
p.second->GetBinContent(bi);
462 const double sig = 0.2;
464 ff_->SetParameters(max_val, max_pos, sig, 0.);
465 p.second->Fit(
ff_.get(),
"Q",
"", max_pos - 3. * sig, max_pos + 3. * sig);
466 p.second->Fit(
ff_.get(),
"Q",
"", max_pos - 3. * sig, max_pos + 3. * sig);
469 ad.de_x_mean =
ff_->GetParameter(1);
470 ad.de_x_sigma = fabs(
ff_->GetParameter(2));
473 ad.de_y_mean =
ff_->GetParameter(1);
474 ad.de_y_sigma = fabs(
ff_->GetParameter(2));
479 os <<
"* fitting arm " << ap.first << std::endl
480 <<
" de_x: mean = " << ad.de_x_mean <<
", sigma = " << ad.de_x_sigma << std::endl
481 <<
" de_y: mean = " << ad.de_y_mean <<
", sigma = " << ad.de_y_sigma;
494 struct ArmEventData {
496 std::map<unsigned int, std::set<unsigned int>> matched_track_idc;
499 std::set<unsigned int> reco_proton_idc;
502 std::map<unsigned int, std::set<unsigned int>> matched_track_with_prot_idc, matched_track_without_prot_idc;
505 struct EvaluatedPair {
506 unsigned idx_N, idx_F;
512 vector<EvaluatedPair> evaluatedPairs;
515 std::map<unsigned int, ArmEventData> armEventData;
518 for (
const auto idx_i : sel_track_idc) {
519 const auto &tr_i = hTracks->at(idx_i);
521 unsigned int decRPId_i = rpId_i.
arm() * 100 + rpId_i.station() * 10 + rpId_i.rp();
523 for (
const auto idx_j : sel_track_idc) {
524 const auto &tr_j = hTracks->at(idx_j);
526 unsigned int decRPId_j = rpId_j.
arm() * 100 + rpId_j.station() * 10 + rpId_j.rp();
529 unsigned int arm = 123;
530 for (
const auto &ap :
data_) {
531 if (ap.second.rpId_N == decRPId_i && ap.second.rpId_F == decRPId_j)
540 const double de_x = tr_j.x() - tr_i.x();
541 const double de_y = tr_j.y() - tr_i.y();
543 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
544 const double n_si = ad.n_sigmas[nsi];
545 const bool match_x = fabs(
de_x - ad.de_x_mean) < n_si * ad.de_x_sigma;
546 const bool match_y = fabs(
de_y - ad.de_y_mean) < n_si * ad.de_y_sigma;
547 if (match_x && match_y)
548 armEventData[
arm].matched_track_idc[nsi].insert(idx_i);
554 for (
unsigned int i = 0;
i < hRecoProtonsMultiRP->size(); ++
i) {
555 const auto &proton = (*hRecoProtonsMultiRP)[
i];
557 CTPPSDetId rpId((*proton.contributingLocalTracks().begin())->rpId());
558 unsigned int arm = rpId.arm();
560 if (proton.validFit())
561 armEventData[
arm].reco_proton_idc.insert(
i);
566 os <<
"* cmp matched tracks vs. reco protons" << std::endl;
568 for (
auto &ap : armEventData) {
569 auto &ad =
data_[ap.first];
572 os <<
" arm " << ap.first << std::endl;
574 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
576 os <<
" nsi = " << nsi << std::endl;
578 for (
const auto &tri : ap.second.matched_track_idc[nsi]) {
579 const auto &
track = hTracks->at(tri);
581 bool some_proton_matching =
false;
584 os <<
" tri = " << tri << std::endl;
586 for (
const auto &pri : ap.second.reco_proton_idc) {
587 const auto &proton = (*hRecoProtonsMultiRP)[pri];
589 bool proton_matching =
false;
591 for (
const auto &pr_tr : proton.contributingLocalTracks()) {
593 unsigned int decRPId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
598 const double x = pr_tr->x();
599 const double y = pr_tr->y();
600 const double th = 1E-3;
605 os <<
" pri = " << pri <<
": x_tr = " <<
track.x() <<
", x_pr = " <<
x 606 <<
", match = " <<
match << std::endl;
609 proton_matching =
true;
614 if (proton_matching) {
615 some_proton_matching =
true;
621 os <<
" --> some_proton_matching " << some_proton_matching << std::endl;
623 if (some_proton_matching)
624 ap.second.matched_track_with_prot_idc[nsi].insert(tri);
626 ap.second.matched_track_without_prot_idc[nsi].insert(tri);
632 for (
auto &ap : armEventData) {
633 const auto &
arm = ap.first;
637 auto &aed = ap.second;
639 auto &ass_cut = ppsAssociationCuts.getAssociationCuts(
arm);
643 map<unsigned int, unsigned> matching_multiplicity;
647 const auto &tr_i = hTracks->at(
i);
648 const auto &tr_j = hTracks->at(
j);
653 const unsigned rpDecId_i = id_i.
arm() * 100 + id_i.station() * 10 + id_i.rp();
654 const unsigned rpDecId_j = id_j.arm() * 100 + id_j.station() * 10 + id_j.rp();
656 if (rpDecId_i != ad.rpId_N || rpDecId_j != ad.rpId_F)
659 ArmEventData::EvaluatedPair evp;
663 evp.x_cut = ass_cut.isSatisfied(ass_cut.qX, tr_i.x(), tr_i.y(), lhcInfo.crossingAngle(), tr_i.x() - tr_j.x());
664 evp.y_cut = ass_cut.isSatisfied(ass_cut.qY, tr_i.x(), tr_i.y(), lhcInfo.crossingAngle(), tr_i.y() - tr_j.y());
666 evp.match = evp.x_cut && evp.y_cut;
668 aed.evaluatedPairs.push_back(evp);
671 matching_multiplicity[
i]++;
672 matching_multiplicity[
j]++;
677 for (
auto &evp : aed.evaluatedPairs)
678 evp.unique = (matching_multiplicity[evp.idx_N] == 1) && (matching_multiplicity[evp.idx_F] == 1);
683 for (
auto &ap : armEventData) {
684 auto &ad =
data_[ap.first];
686 if (ad.de_x_sigma <= 0. && ad.de_y_sigma <= 0.)
689 os <<
"* results for arm " << ap.first << std::endl;
691 os <<
" reco_proton_idc: ";
692 for (
const auto &
idx : ap.second.reco_proton_idc)
696 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
697 os <<
" n_si = " << ad.n_sigmas[nsi] << std::endl;
699 os <<
" matched_track_idc: ";
700 for (
const auto &
idx : ap.second.matched_track_idc[nsi])
704 os <<
" matched_track_with_prot_idc: ";
705 for (
const auto &
idx : ap.second.matched_track_with_prot_idc[nsi])
709 os <<
" matched_track_without_prot_idc: ";
710 for (
const auto &
idx : ap.second.matched_track_without_prot_idc[nsi])
715 os <<
" evaluated pairs: ";
716 for (
const auto &
p : ap.second.evaluatedPairs)
717 os <<
"(" <<
p.idx_N <<
"-" <<
p.idx_F <<
",M" <<
p.match <<
",U" <<
p.unique <<
")" 724 for (
auto &ap : armEventData) {
725 const auto &
arm = ap.first;
729 if (ad.de_x_sigma <= 0. && ad.de_y_sigma <= 0.)
733 for (
unsigned int nsi = 0; nsi < ad.n_sigmas.size(); ++nsi) {
734 const unsigned int n_exp_prot = ap.second.matched_track_idc[nsi].size();
735 const unsigned int n_rec_prot = ap.second.reco_proton_idc.size();
738 if (n_exp_prot < 1 || n_exp_prot > ad.n_exp_prot_max)
742 const double eff = double(n_rec_prot) / n_exp_prot;
744 for (
unsigned int tri : ap.second.matched_track_idc[nsi]) {
745 const double x_N = hTracks->at(tri).x();
746 const double xi_N = ad.s_x_to_xi_N->Eval(x_N * 1E-1);
748 ad.effPlots[0][nsi].p_eff1_vs_x_N->Fill(x_N, eff);
749 ad.effPlots[0][nsi].p_eff1_vs_xi_N->Fill(xi_N, eff);
751 ad.effPlots[n_exp_prot][nsi].p_eff1_vs_x_N->Fill(x_N, eff);
752 ad.effPlots[n_exp_prot][nsi].p_eff1_vs_xi_N->Fill(xi_N, eff);
756 for (
const auto &tri : ap.second.matched_track_with_prot_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_eff2_vs_x_N->Fill(x_N, 1.);
761 ad.effPlots[0][nsi].p_eff2_vs_xi_N->Fill(xi_N, 1.);
763 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_x_N->Fill(x_N, 1.);
764 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_xi_N->Fill(xi_N, 1.);
767 for (
const auto &tri : ap.second.matched_track_without_prot_idc[nsi]) {
768 const double x_N = hTracks->at(tri).x();
769 const double xi_N = ad.s_x_to_xi_N->Eval(x_N * 1E-1);
771 ad.effPlots[0][nsi].p_eff2_vs_x_N->Fill(x_N, 0.);
772 ad.effPlots[0][nsi].p_eff2_vs_xi_N->Fill(xi_N, 0.);
774 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_x_N->Fill(x_N, 0.);
775 ad.effPlots[n_exp_prot][nsi].p_eff2_vs_xi_N->Fill(xi_N, 0.);
779 for (
const auto &
cand : ap.second.matched_track_idc[nsi])
781 const double x_N = hTracks->at(
cand).x();
783 auto &
plots = ad.effPlots[n_exp_prot][nsi];
785 bool hasMatchingAndUniquePair =
false;
786 bool hasMatchingAndNonUniquePair =
false;
787 for (
const auto &pair : ap.second.evaluatedPairs)
790 if (
cand != pair.idx_N)
793 if (pair.match && pair.unique)
794 hasMatchingAndUniquePair =
true;
796 if (pair.match && !pair.unique)
797 hasMatchingAndNonUniquePair =
true;
800 if (!pair.x_cut && !pair.y_cut)
802 if (pair.x_cut && !pair.y_cut)
804 if (!pair.x_cut && pair.y_cut)
806 if (pair.x_cut && pair.y_cut)
815 plots.p_fr_match_unique->Fill(x_N, (hasMatchingAndUniquePair) ? 1 : 0);
816 plots.p_fr_match_non_unique->Fill(x_N, (hasMatchingAndNonUniquePair) ? 1 : 0);
822 edm::LogInfo(
"CTPPSProtonReconstructionEfficiencyEstimatorData") << os.str();
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
std::map< unsigned int, ArmData > data_
edm::ESGetToken< LHCInfo, LHCInfoRcd > lhcInfoESToken_
def unique(seq, keepstr=True)
edm::EDGetTokenT< reco::ForwardProtonCollection > tokenRecoProtonsMultiRP_
std::unique_ptr< TF1 > ff_
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_