File indexing completed on 2024-04-06 12:31:09
0001 #include "SimTransport/PPSProtonTransport/interface/OpticalFunctionsTransport.h"
0002 #include "DataFormats/CTPPSDetId/interface/CTPPSDetId.h"
0003
0004 OpticalFunctionsTransport::OpticalFunctionsTransport(const edm::ParameterSet& iConfig, edm::ConsumesCollector iC)
0005 : BaseProtonTransport(iConfig),
0006 lhcInfoToken_(iC.esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("lhcInfoLabel")))),
0007 beamParametersToken_(iC.esConsumes()),
0008 opticsToken_(iC.esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("opticsLabel")))),
0009 beamspotToken_(iC.esConsumes()),
0010 useEmpiricalApertures_(iConfig.getParameter<bool>("useEmpiricalApertures")),
0011 empiricalAperture45_xi0_int_(iConfig.getParameter<double>("empiricalAperture45_xi0_int")),
0012 empiricalAperture45_xi0_slp_(iConfig.getParameter<double>("empiricalAperture45_xi0_slp")),
0013 empiricalAperture45_a_int_(iConfig.getParameter<double>("empiricalAperture45_a_int")),
0014 empiricalAperture45_a_slp_(iConfig.getParameter<double>("empiricalAperture45_a_slp")),
0015 empiricalAperture56_xi0_int_(iConfig.getParameter<double>("empiricalAperture56_xi0_int")),
0016 empiricalAperture56_xi0_slp_(iConfig.getParameter<double>("empiricalAperture56_xi0_slp")),
0017 empiricalAperture56_a_int_(iConfig.getParameter<double>("empiricalAperture56_a_int")),
0018 empiricalAperture56_a_slp_(iConfig.getParameter<double>("empiricalAperture56_a_slp")) {
0019 MODE = TransportMode::OPTICALFUNCTIONS;
0020 }
0021 OpticalFunctionsTransport::~OpticalFunctionsTransport() {}
0022
0023 void OpticalFunctionsTransport::process(const HepMC::GenEvent* evt,
0024 const edm::EventSetup& iSetup,
0025 CLHEP::HepRandomEngine* engine) {
0026 clear();
0027
0028 lhcInfo_ = &iSetup.getData(lhcInfoToken_);
0029 beamParameters_ = &iSetup.getData(beamParametersToken_);
0030 opticalFunctions_ = &iSetup.getData(opticsToken_);
0031 beamspot_ = &iSetup.getData(beamspotToken_);
0032
0033
0034 optFunctionId45_ = 0;
0035 optFunctionId56_ = 0;
0036 for (const auto& ofp : (*opticalFunctions_)) {
0037 if (ofp.second.getScoringPlaneZ() < 0) {
0038 if (optFunctionId45_ == 0)
0039 optFunctionId45_ = ofp.first;
0040 if (opticalFunctions_->at(optFunctionId45_).getScoringPlaneZ() < ofp.second.getScoringPlaneZ())
0041 optFunctionId45_ = ofp.first;
0042 }
0043 if (ofp.second.getScoringPlaneZ() > 0) {
0044 if (optFunctionId56_ == 0)
0045 optFunctionId56_ = ofp.first;
0046 if (opticalFunctions_->at(optFunctionId56_).getScoringPlaneZ() > ofp.second.getScoringPlaneZ())
0047 optFunctionId56_ = ofp.first;
0048 }
0049 }
0050
0051 engine_ = engine;
0052
0053 for (HepMC::GenEvent::particle_const_iterator eventParticle = evt->particles_begin();
0054 eventParticle != evt->particles_end();
0055 ++eventParticle) {
0056 if (!((*eventParticle)->status() == 1 && (*eventParticle)->pdg_id() == 2212))
0057 continue;
0058
0059 if (!(fabs((*eventParticle)->momentum().eta()) > etaCut_ && fabs((*eventParticle)->momentum().pz()) > momentumCut_))
0060 continue;
0061
0062 unsigned int line = (*eventParticle)->barcode();
0063 HepMC::GenParticle* gpart = (*eventParticle);
0064 if (gpart->pdg_id() != 2212)
0065 continue;
0066 if (gpart->status() != 1)
0067 continue;
0068 if (m_beamPart.find(line) != m_beamPart.end())
0069 continue;
0070
0071 transportProton(gpart);
0072 }
0073 }
0074
0075 bool OpticalFunctionsTransport::transportProton(const HepMC::GenParticle* in_trk) {
0076 const HepMC::FourVector& vtx_cms = in_trk->production_vertex()->position();
0077 const HepMC::FourVector& mom_cms = in_trk->momentum();
0078
0079
0080 HepMC::FourVector vtx_lhc(-vtx_cms.x(), vtx_cms.y(), -vtx_cms.z(), vtx_cms.t());
0081 HepMC::FourVector mom_lhc(-mom_cms.x(), mom_cms.y(), -mom_cms.z(), mom_cms.t());
0082
0083
0084 double urad = 1.e-6;
0085 double beamMomentum = 0.;
0086 double xangle = 0.;
0087 double empiricalAperture_xi0_int, empiricalAperture_xi0_slp;
0088 double empiricalAperture_a_int, empiricalAperture_a_slp;
0089 unsigned int optFunctionId;
0090
0091 double vtxXoffset;
0092 double vtxYoffset;
0093 if (useBeamPositionFromLHCInfo_) {
0094 vtxXoffset = -beamParameters_->getVtxOffsetX45() * cm_to_mm;
0095 vtxYoffset = beamParameters_->getVtxOffsetY45() * cm_to_mm;
0096 } else {
0097 vtxXoffset = -beamspot_->x() * cm_to_mm;
0098 vtxYoffset = beamspot_->y() * cm_to_mm;
0099 }
0100
0101 if (mom_lhc.z() < 0)
0102 {
0103 optFunctionId = optFunctionId45_;
0104 beamMomentum = beamParameters_->getBeamMom45();
0105 xangle = beamParameters_->getHalfXangleX45();
0106 empiricalAperture_xi0_int = empiricalAperture45_xi0_int_;
0107 empiricalAperture_xi0_slp = empiricalAperture45_xi0_slp_;
0108 empiricalAperture_a_int = empiricalAperture45_a_int_;
0109 empiricalAperture_a_slp = empiricalAperture45_a_slp_;
0110 } else {
0111 optFunctionId = optFunctionId56_;
0112 beamMomentum = beamParameters_->getBeamMom56();
0113 xangle = beamParameters_->getHalfXangleX56();
0114 empiricalAperture_xi0_int = empiricalAperture56_xi0_int_;
0115 empiricalAperture_xi0_slp = empiricalAperture56_xi0_slp_;
0116 empiricalAperture_a_int = empiricalAperture56_a_int_;
0117 empiricalAperture_a_slp = empiricalAperture56_a_slp_;
0118 }
0119 if (xangle > 1.0)
0120 xangle *= urad;
0121
0122 const double p = mom_lhc.rho();
0123 const double xi = 1. - p / beamMomentum;
0124 const double th_x_phys = mom_lhc.x() / abs(mom_lhc.z()) - tan(xangle);
0125 const double th_y_phys = mom_lhc.y() / abs(mom_lhc.z());
0126 const double vtx_lhc_eff_x = vtx_lhc.x() - vtx_lhc.z() * (mom_lhc.x() / mom_lhc.z() + tan(xangle)) - (vtxXoffset);
0127 const double vtx_lhc_eff_y = vtx_lhc.y() - vtx_lhc.z() * (mom_lhc.y() / mom_lhc.z()) - (vtxYoffset);
0128
0129 if (verbosity_) {
0130 LogDebug("OpticalFunctionsTransport")
0131 << "simu: xi = " << xi << ", th_x_phys = " << th_x_phys << ", th_y_phys = " << th_y_phys
0132 << ", vtx_lhc_eff_x = " << vtx_lhc_eff_x << ", vtx_lhc_eff_y = " << vtx_lhc_eff_y;
0133 }
0134
0135
0136 if (useEmpiricalApertures_) {
0137 const auto& xangle =
0138 (lhcInfo_->crossingAngle() > 1.0) ? lhcInfo_->crossingAngle() * urad : lhcInfo_->crossingAngle();
0139 const double xi_th = (empiricalAperture_xi0_int + xangle * empiricalAperture_xi0_slp) +
0140 (empiricalAperture_a_int + xangle * empiricalAperture_a_slp) * th_x_phys;
0141
0142 if (xi > xi_th) {
0143 if (verbosity_) {
0144 LogDebug("OpticalFunctionsTransport") << "stop because of empirical appertures";
0145 }
0146 return false;
0147 }
0148 }
0149
0150
0151 auto ofp = opticalFunctions_->at(optFunctionId);
0152 CTPPSDetId rpId(optFunctionId);
0153 const unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
0154
0155 if (verbosity_)
0156 LogDebug("OpticalFunctionsTransport") << " RP " << rpDecId << std::endl;
0157
0158
0159 LHCInterpolatedOpticalFunctionsSet::Kinematics k_in = {
0160 vtx_lhc_eff_x * cm_to_mm, th_x_phys, vtx_lhc_eff_y * cm_to_mm, th_y_phys, xi};
0161
0162 LHCInterpolatedOpticalFunctionsSet::Kinematics k_out;
0163 ofp.transport(k_in, k_out, true);
0164
0165
0166 double b_x = k_out.x * cm_to_mm, b_y = k_out.y * cm_to_mm;
0167 double a_x = k_out.th_x, a_y = k_out.th_y;
0168
0169
0170 if (produceHitsRelativeToBeam_) {
0171
0172 LHCInterpolatedOpticalFunctionsSet::Kinematics k_be_in = {0., -tan(xangle), 0., 0., 0.};
0173 LHCInterpolatedOpticalFunctionsSet::Kinematics k_be_out;
0174 ofp.transport(k_be_in, k_be_out, true);
0175
0176 a_x -= k_be_out.th_x;
0177 a_y -= k_be_out.th_y;
0178 b_x -= k_be_out.x * cm_to_mm;
0179 b_y -= k_be_out.y * cm_to_mm;
0180 }
0181
0182 const double z_scoringPlane = ofp.getScoringPlaneZ() * cm_to_mm;
0183
0184 if (verbosity_) {
0185 LogDebug("OpticalFunctionsTransport")
0186 << " proton transported: a_x = " << a_x << " rad, a_y = " << a_y << " rad, b_x = " << b_x
0187 << " mm, b_y = " << b_y << " mm, z = " << z_scoringPlane << " mm";
0188 }
0189
0190
0191 b_x -= (abs(z_scoringPlane) - ((z_scoringPlane < 0) ? fPPSRegionStart_45_ : fPPSRegionStart_56_) * 1e3) * a_x;
0192 b_y -= (abs(z_scoringPlane) - ((z_scoringPlane < 0) ? fPPSRegionStart_45_ : fPPSRegionStart_56_) * 1e3) * a_y;
0193
0194 unsigned int line = in_trk->barcode();
0195 double px = -p * a_x;
0196 double py = p * a_y;
0197 double pz = std::copysign(sqrt(p * p - px * px - py * py), mom_cms.z());
0198 double e = sqrt(px * px + py * py + pz * pz + ProtonMassSQ);
0199 TLorentzVector p_out(px, py, pz, e);
0200 m_beamPart[line] = p_out;
0201 m_xAtTrPoint[line] = -b_x;
0202 m_yAtTrPoint[line] = b_y;
0203 return true;
0204 }