208 if (!hTracks->empty())
223 if (hOpticalFunctions->empty()) {
224 edm::LogInfo(
"CTPPSProtonProducer") <<
"No optical functions available, reconstruction disabled.";
238 std::ostringstream ssLog;
240 ssLog <<
"* input tracks:" << std::endl;
243 std::map<unsigned int, std::vector<unsigned int>> trackingSelection, timingSelection;
245 for (
unsigned int idx = 0;
idx < hTracks->size(); ++
idx)
247 const auto& tr = hTracks->at(
idx);
257 <<
"[" <<
idx <<
"] " 258 << tr.getRPId() <<
" (" << (rpId.arm()*100 + rpId.station()*10 + rpId.rp()) <<
"): " 259 <<
"x=" << tr.getX() <<
" +- " << tr.getXUnc() <<
" mm, " 260 <<
"y=" << tr.getY() <<
" +- " << tr.getYUnc() <<
" mm" << std::endl;
265 trackingSelection[rpId.arm()].push_back(
idx);
267 timingSelection[rpId.arm()].push_back(
idx);
271 for (
const auto &arm_it : trackingSelection)
273 const auto &indices = arm_it.second;
278 std::map<unsigned int, reco::ForwardProton> singleRPResultsIndexed;
281 for (
const auto &
idx : indices)
284 ssLog << std::endl <<
"* reconstruction from track " <<
idx << std::endl;
293 std::set<unsigned int> rpIds;
294 for (
const auto &
idx : indices)
295 rpIds.insert(hTracks->at(
idx).getRPId());
301 std::vector<std::pair<unsigned int, unsigned int>> idx_pairs;
302 std::map<unsigned int, unsigned int> idx_pair_multiplicity;
303 for (
const auto &
i : indices)
305 for (
const auto &j : indices)
310 const auto &tr_i = hTracks->at(
i);
311 const auto &tr_j = hTracks->at(j);
313 const auto &pr_i = singleRPResultsIndexed[
i];
314 const auto &pr_j = singleRPResultsIndexed[j];
316 if (tr_i.getRPId() == tr_j.getRPId())
321 if (ac.x_cut_apply &&
std::abs(tr_i.getX() - tr_j.getX()) > ac.x_cut_value)
323 if (ac.y_cut_apply &&
std::abs(tr_i.getY() - tr_j.getY()) > ac.y_cut_value)
325 if (ac.xi_cut_apply &&
std::abs(pr_i.xi() - pr_j.xi()) > ac.xi_cut_value)
327 if (ac.th_y_cut_apply &&
std::abs(pr_i.thetaY() - pr_j.thetaY()) > ac.th_y_cut_value)
333 idx_pairs.emplace_back(
i, j);
334 idx_pair_multiplicity[
i]++;
335 idx_pair_multiplicity[j]++;
340 std::map<unsigned int, unsigned int> timing_RP_track_multiplicity;
341 for (
const auto &ti : timingSelection[arm_it.first])
343 const auto &tr = hTracks->at(ti);
344 timing_RP_track_multiplicity[tr.getRPId()]++;
348 std::map<unsigned int, std::vector<unsigned int>> matched_timing_track_indices;
349 std::map<unsigned int, unsigned int> matched_timing_track_multiplicity;
350 for (
unsigned int pr_idx = 0; pr_idx < idx_pairs.size(); ++pr_idx)
352 const auto &
i = idx_pairs[pr_idx].first;
353 const auto &j = idx_pairs[pr_idx].second;
356 if (idx_pair_multiplicity[
i] > 1 || idx_pair_multiplicity[j] > 1)
359 const auto &tr_i = hTracks->at(
i);
360 const auto &tr_j = hTracks->at(j);
365 for (
const auto &ti : timingSelection[arm_it.first])
367 const auto &tr_ti = hTracks->at(ti);
375 const double f_i = (z_ti - z_j) / (z_i - z_j), f_j = (z_i - z_ti) / (z_i - z_j);
376 const double x_inter = f_i * tr_i.getX() + f_j * tr_j.getX();
377 const double x_inter_unc_sq = f_i*f_i * tr_i.getXUnc()*tr_i.getXUnc() + f_j*f_j * tr_j.getXUnc()*tr_j.getXUnc();
379 const double de_x = tr_ti.getX() - x_inter;
380 const double de_x_unc =
sqrt(tr_ti.getXUnc()*tr_ti.getXUnc() + x_inter_unc_sq);
382 const bool matching = (
std::abs(de_x) <= de_x_unc);
385 ssLog <<
"ti=" << ti <<
", i=" <<
i <<
", j=" << j
386 <<
" | z_ti=" << z_ti <<
", z_i=" << z_i <<
", z_j=" << z_j
387 <<
" | x_ti=" << tr_ti.getX() <<
", x_inter=" << x_inter <<
", de_x=" << de_x <<
", de_x_unc=" << de_x_unc
388 <<
", matching=" << matching << std::endl;
393 matched_timing_track_indices[pr_idx].push_back(ti);
394 matched_timing_track_multiplicity[ti]++;
399 for (
unsigned int pr_idx = 0; pr_idx < idx_pairs.size(); ++pr_idx)
401 const auto &
i = idx_pairs[pr_idx].first;
402 const auto &j = idx_pairs[pr_idx].second;
405 if (idx_pair_multiplicity[
i] > 1 || idx_pair_multiplicity[j] > 1)
409 ssLog << std::endl <<
"* reconstruction from tracking-RP tracks: " <<
i <<
", " << j <<
" and timing-RP tracks: ";
418 double sw=0., swt=0.;
419 for (
const auto &ti : matched_timing_track_indices[pr_idx])
422 if (matched_timing_track_multiplicity[ti] > 1)
430 const auto &tr = hTracks->at(ti);
431 const double t_unc = tr.getTimeUnc();
432 const double w = (t_unc > 0.) ? 1./t_unc/t_unc : 1.;
434 swt += w * tr.getTime();
437 float time = 0., time_unc = 0.;
441 time_unc = 1. /
sqrt(sw);
445 ssLog << std::endl <<
" time = " << time <<
" +- " << time_unc << std::endl;
452 pOutMultiRP->emplace_back(proton);
457 for (
const auto &
p : singleRPResultsIndexed)
458 pOutSingleRP->emplace_back(
std::move(
p.second));
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
std::string lhcInfoLabel_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
reco::ForwardProton reconstructFromSingleRP(const CTPPSLocalTrackLiteRef &track, const LHCInfo &lhcInfo, std::ostream &os) const
run proton reconstruction using single-RP strategy
bool doMultiRPReconstruction_
unsigned int max_n_timing_tracks_
Event setup record containing the real (actual) geometry information.
void init(const LHCInterpolatedOpticalFunctionsSetCollection &opticalFunctions)
void setTimeError(float time_err)
reco::ForwardProton reconstructFromMultiRP(const CTPPSLocalTrackLiteRefVector &tracks, const LHCInfo &lhcInfo, std::ostream &os) const
run proton reconstruction using multiple-RP strategy
edm::ESWatcher< CTPPSInterpolatedOpticsRcd > opticsWatcher_
Abs< T >::type abs(const T &t)
edm::Ref< CTPPSLocalTrackLiteCollection > CTPPSLocalTrackLiteRef
Persistent reference to a CTPPSLocalTrackLite.
std::map< unsigned int, AssociationCuts > association_cuts_
CLHEP::Hep3Vector getRPTranslation(unsigned int id) const
bool check(const edm::EventSetup &iSetup)
Base class for CTPPS detector IDs.
ProtonReconstructionAlgorithm algorithm_
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
std::vector< ForwardProton > ForwardProtonCollection
Collection of ForwardProton objects.
void setContributingLocalTracks(const CTPPSLocalTrackLiteRefVector &v)
store the list of RP tracks that contributed to this global track
std::string singleRPReconstructionLabel_
std::string multiRPReconstructionLabel_
bool doSingleRPReconstruction_
edm::EDGetTokenT< CTPPSLocalTrackLiteCollection > tracksToken_