51 #include "CLHEP/Random/RandGauss.h"
52 #include "CLHEP/Units/GlobalPhysicalConstants.h"
54 #include <unordered_map>
62 #include "CLHEP/Random/RandFlat.h"
83 CLHEP::HepRandomEngine *rndEngine,
85 std::vector<CTPPSLocalTrackLite> &out_tracks,
160 hepMCToken_(consumes<edm::HepMCProduct>(iConfig.getParameter<
edm::InputTag>(
"hepMCTag"))),
162 produceScoringPlaneHits_(iConfig.getParameter<
bool>(
"produceScoringPlaneHits")),
163 produceRecHits_(iConfig.getParameter<
bool>(
"produceRecHits")),
165 useEmpiricalApertures_(iConfig.getParameter<
bool>(
"useEmpiricalApertures")),
167 useTrackingEfficiencyPerRP_(iConfig.getParameter<
bool>(
"useTrackingEfficiencyPerRP")),
168 useTimingEfficiencyPerRP_(iConfig.getParameter<
bool>(
"useTimingEfficiencyPerRP")),
169 useTrackingEfficiencyPerPlane_(iConfig.getParameter<
bool>(
"useTrackingEfficiencyPerPlane")),
170 useTimingEfficiencyPerPlane_(iConfig.getParameter<
bool>(
"useTimingEfficiencyPerPlane")),
172 produceHitsRelativeToBeam_(iConfig.getParameter<
bool>(
"produceHitsRelativeToBeam")),
173 roundToPitch_(iConfig.getParameter<
bool>(
"roundToPitch")),
174 checkIsHit_(iConfig.getParameter<
bool>(
"checkIsHit")),
176 pitchStrips_(iConfig.getParameter<
double>(
"pitchStrips")),
177 insensitiveMarginStrips_(iConfig.getParameter<
double>(
"insensitiveMarginStrips")),
179 pitchPixelsHor_(iConfig.getParameter<
double>(
"pitchPixelsHor")),
180 pitchPixelsVer_(iConfig.getParameter<
double>(
"pitchPixelsVer")),
182 verbosity_(iConfig.getUntrackedParameter<
unsigned int>(
"verbosity", 0)) {
183 if (produceScoringPlaneHits_)
184 produces<std::vector<CTPPSLocalTrackLite>>();
186 if (produceRecHits_) {
187 produces<edm::DetSetVector<TotemRPRecHit>>();
188 produces<edm::DetSetVector<CTPPSDiamondRecHit>>();
189 produces<edm::DetSetVector<CTPPSPixelRecHit>>();
191 produces<std::map<int, edm::DetSetVector<TotemRPRecHit>>>();
192 produces<std::map<int, edm::DetSetVector<CTPPSDiamondRecHit>>>();
193 produces<std::map<int, edm::DetSetVector<CTPPSPixelRecHit>>>();
197 if (useTrackingEfficiencyPerRP_ && useTrackingEfficiencyPerPlane_)
199 <<
"useTrackingEfficiencyPerRP and useTrackingEfficiencyPerPlane should not be simultaneously set true.";
201 if (useTimingEfficiencyPerRP_ && useTimingEfficiencyPerPlane_)
203 <<
"useTimingEfficiencyPerRP and useTimingEfficiencyPerPlane should not be simultaneously set true.";
214 desc.addUntracked<
unsigned int>(
"verbosity", 0);
216 desc.add<
std::string>(
"lhcInfoLabel",
"")->setComment(
"label of the LHCInfo record");
217 desc.add<
std::string>(
"opticsLabel",
"")->setComment(
"label of the optics records");
221 desc.add<
bool>(
"produceScoringPlaneHits",
true);
222 desc.add<
bool>(
"produceRecHits",
true);
224 desc.add<
bool>(
"useEmpiricalApertures",
true);
226 desc.add<
bool>(
"useTrackingEfficiencyPerRP",
false);
227 desc.add<
bool>(
"useTimingEfficiencyPerRP",
false);
228 desc.add<
bool>(
"useTrackingEfficiencyPerPlane",
false);
229 desc.add<
bool>(
"useTimingEfficiencyPerPlane",
false);
231 desc.add<
bool>(
"produceHitsRelativeToBeam",
true);
232 desc.add<
bool>(
"roundToPitch",
true);
233 desc.add<
bool>(
"checkIsHit",
true);
234 desc.add<
double>(
"pitchStrips", 66.e-3);
235 desc.add<
double>(
"insensitiveMarginStrips", 34.e-3);
237 desc.add<
double>(
"pitchPixelsHor", 100.e-3);
238 desc.add<
double>(
"pitchPixelsVer", 150.e-3);
240 descriptions.
add(
"ctppsDirectProtonSimulation",
desc);
260 std::make_unique<TF1>(TF1(
"timeResolutionDiamonds45", directSimuData.getTimeResolutionDiamonds45().c_str()));
262 std::make_unique<TF1>(TF1(
"timeResolutionDiamonds56", directSimuData.getTimeResolutionDiamonds56().c_str()));
265 std::make_unique<TF2>(TF2(
"empiricalAperture45", directSimuData.getEmpiricalAperture45().c_str()));
267 std::make_unique<TF2>(TF2(
"empiricalAperture56", directSimuData.getEmpiricalAperture56().c_str()));
281 auto pStripRecHitsPerParticle = std::make_unique<std::map<int, edm::DetSetVector<TotemRPRecHit>>>();
282 auto pDiamondRecHitsPerParticle = std::make_unique<std::map<int, edm::DetSetVector<CTPPSDiamondRecHit>>>();
283 auto pPixelRecHitsPerParticle = std::make_unique<std::map<int, edm::DetSetVector<CTPPSPixelRecHit>>>();
285 std::unique_ptr<std::vector<CTPPSLocalTrackLite>> pTracks(
new std::vector<CTPPSLocalTrackLite>());
293 for (
auto it_vtx = evt->vertices_begin(); it_vtx != evt->vertices_end(); ++it_vtx) {
294 auto vtx = *(it_vtx);
297 for (
auto it_part =
vtx->particles_out_const_begin(); it_part !=
vtx->particles_out_const_end(); ++it_part) {
298 auto part = *(it_part);
301 if (
part->pdg_id() != 2212)
304 if (
part->status() != 1 &&
part->status() < 83)
319 *pStripRecHitsPerParticle,
320 *pPixelRecHitsPerParticle,
321 *pDiamondRecHitsPerParticle);
342 const HepMC::GenVertex *in_vtx,
349 CLHEP::HepRandomEngine *rndEngine,
350 std::vector<CTPPSLocalTrackLite> &out_tracks,
360 std::stringstream ssLog;
363 const HepMC::FourVector &vtx_cms = in_vtx->position();
364 const HepMC::FourVector &mom_cms = in_trk->momentum();
367 HepMC::FourVector vtx_lhc(-vtx_cms.x(), vtx_cms.y(), -vtx_cms.z(), vtx_cms.t());
368 HepMC::FourVector mom_lhc(-mom_cms.x(), mom_cms.y(), -mom_cms.z(), mom_cms.t());
371 unsigned int arm = 3;
373 double beamMomentum = 0.;
375 const std::unique_ptr<TF2> *empiricalAperture;
397 const double time_eff = (vtx_lhc.t() - z_sign * vtx_lhc.z()) / CLHEP::c_light;
400 const double p = mom_lhc.rho();
401 const double xi = 1. -
p / beamMomentum;
402 const double th_x_phys = mom_lhc.x() /
p;
403 const double th_y_phys = mom_lhc.y() /
p;
404 const double vtx_lhc_eff_x = vtx_lhc.x() - vtx_lhc.z() * (mom_lhc.x() / mom_lhc.z() +
xangle);
405 const double vtx_lhc_eff_y = vtx_lhc.y() - vtx_lhc.z() * (mom_lhc.y() / mom_lhc.z());
408 ssLog <<
"simu: xi = " <<
xi <<
", th_x_phys = " << th_x_phys <<
", th_y_phys = " << th_y_phys
409 <<
", vtx_lhc_eff_x = " << vtx_lhc_eff_x <<
", vtx_lhc_eff_y = " << vtx_lhc_eff_y << std::endl;
415 (*empiricalAperture)->SetParameter(
"xi",
xi);
416 (*empiricalAperture)->SetParameter(
"xangle",
xangle);
417 const double th_x_th = (*empiricalAperture)->EvalPar(
nullptr);
419 if (th_x_th > th_x_phys) {
421 ssLog <<
"stop because of empirical appertures";
432 const unsigned int rpDecId =
rpId.arm() * 100 +
rpId.station() * 10 +
rpId.rp();
439 ssLog <<
" RP " << rpDecId << std::endl;
443 vtx_lhc_eff_x * 1E-1, th_x_phys, vtx_lhc_eff_y * 1E-1, th_y_phys,
xi};
445 ofp.second.transport(k_in, k_out,
true);
447 double b_x = k_out.
x * 1E1, b_y = k_out.
y * 1E1;
448 double a_x = k_out.
th_x, a_y = k_out.
th_y;
455 ofp.second.transport(k_be_in, k_be_out,
true);
457 a_x -= k_be_out.
th_x;
458 a_y -= k_be_out.
th_y;
459 b_x -= k_be_out.
x * 1E1;
460 b_y -= k_be_out.
y * 1E1;
463 const double z_scoringPlane = ofp.second.getScoringPlaneZ() * 1E1;
466 ssLog <<
" proton transported: a_x = " << a_x <<
" rad, a_y = " << a_y <<
" rad, b_x = " << b_x
467 <<
" mm, b_y = " << b_y <<
" mm, z = " << z_scoringPlane <<
" mm" << std::endl;
471 const bool isTrackingRP =
480 const double r = CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
481 auto *effMap = it->second.get();
482 const double eff = effMap->GetBinContent(effMap->FindBin(b_x, b_y));
485 ssLog <<
" stop due to per-RP efficiency" << std::endl;
493 out_tracks.emplace_back(
494 rpId.rawId(), b_x, 0., b_y, 0., 0., 0., 0., 0., 0.,
CTPPSpixelLocalTrackReconstructionInfo::invalid, 0, 0., 0.);
501 for (
const auto &detIdInt :
geometry.sensorsInRP(
rpId)) {
510 const double gl_o_z = gl_o.z();
515 A(0, 1) = -gl_a1.x();
516 A(0, 2) = -gl_a2.x();
517 B(0) = gl_o.x() - b_x;
519 A(1, 1) = -gl_a1.y();
520 A(1, 2) = -gl_a2.y();
521 B(1) = gl_o.y() - b_y;
523 A(2, 1) = -gl_a1.z();
524 A(2, 2) = -gl_a2.z();
525 B(2) = gl_o_z - z_scoringPlane;
535 auto h_loc =
geometry.globalToLocal(detId, h_glo);
539 <<
" de z = " <<
P(0) <<
" mm, p1 = " <<
P(1) <<
" mm, p2 = " <<
P(2) <<
" mm" << std::endl
540 <<
" h_glo: x = " << h_glo.x() <<
" mm, y = " << h_glo.y() <<
" mm, z = " << h_glo.z() <<
" mm"
542 <<
" h_loc: c1 = " << h_loc.x() <<
" mm, c2 = " << h_loc.y() <<
" mm, c3 = " << h_loc.z() <<
" mm"
551 const double r = CLHEP::RandFlat::shoot(rndEngine, 0., 1.);
552 auto *effMap = it->second.get();
553 const double eff = effMap->GetBinContent(effMap->FindBin(h_glo.x(), h_glo.y()));
556 ssLog <<
" stop due to per-plane efficiency" << std::endl;
564 double u = h_loc.x();
565 double v = h_loc.y();
568 ssLog <<
" u=" << u <<
", v=" <<
v;
573 ssLog <<
" | no hit" << std::endl;
585 ssLog <<
" | strip=" <<
strip;
591 ssLog <<
" | m=" <<
v <<
", sigma=" << sigma << std::endl;
594 hits.emplace_back(
v, sigma);
597 out_strip_hits_per_particle[in_trk->barcode()].find_or_insert(detId);
606 const auto *dg =
geometry.sensor(detIdInt);
607 const auto &diamondDimensions = dg->getDiamondDimensions();
608 const auto x_half_width = diamondDimensions.xHalfWidth;
609 const auto y_half_width = diamondDimensions.yHalfWidth;
610 const auto z_half_width = diamondDimensions.zHalfWidth;
612 if (h_loc.x() < -x_half_width || h_loc.x() > +x_half_width || h_loc.y() < -y_half_width ||
613 h_loc.y() > +y_half_width)
620 const double t0 = time_eff + CLHEP::RandGauss::shoot(rndEngine, 0., time_resolution);
621 const double tot = 1.23456;
622 const double ch_t_precis = time_resolution;
623 const int time_slice = 0;
626 const bool multiHit =
false;
645 out_diamond_hits_per_particle[in_trk->barcode()].find_or_insert(detId);
653 ssLog <<
" pixel plane " << pixelDetId.
plane() <<
": local hit x = " << h_loc.x()
654 <<
" mm, y = " << h_loc.y() <<
" mm, z = " << h_loc.z() <<
" mm" << std::endl;
667 ssLog <<
" hit accepted: m1 = " << h_loc.x() <<
" mm, m2 = " << h_loc.y() <<
" mm" << std::endl;
672 const LocalPoint lp(h_loc.x(), h_loc.y(), h_loc.z());
676 hits.emplace_back(lp, le);
679 out_pixel_hits_per_particle[in_trk->barcode()].find_or_insert(detId);