CMS 3D CMS Logo

HectorTransport.cc
Go to the documentation of this file.
3 #include "TLorentzVector.h"
4 //Hector headers
5 #include "H_BeamLine.h"
6 #include "H_BeamParticle.h"
7 #include <memory>
8 
9 #include <string>
10 
12  : BaseProtonTransport(iConfig),
13  m_beamline45(nullptr),
14  m_beamline56(nullptr),
15  beamParametersToken_(iC.esConsumes()),
16  beamspotToken_(iC.esConsumes()) {
18  std::string s1 = iConfig.getParameter<std::string>("Beam1Filename");
19  std::string s2 = iConfig.getParameter<std::string>("Beam2Filename");
20  setBeamFileNames(s1, s2);
21  double cax45 = iConfig.getParameter<double>("halfCrossingAngleXSector45");
22  double cax56 = iConfig.getParameter<double>("halfCrossingAngleXSector56");
23  double cay45 = iConfig.getParameter<double>("halfCrossingAngleYSector45");
24  double cay56 = iConfig.getParameter<double>("halfCrossingAngleYSector56");
25  setCrossingAngles(cax45, cax56, cay45, cay56);
26  double stx = iConfig.getParameter<double>("BeamDivergenceX");
27  double sty = iConfig.getParameter<double>("BeamDivergenceY");
28  double sx = iConfig.getParameter<double>("BeamSigmaX");
29  double sy = iConfig.getParameter<double>("BeamSigmaY");
30  double se = iConfig.getParameter<double>("BeamEnergyDispersion");
31  setBeamParameters(stx, sty, sx, sy, se);
32  //PPS
33  edm::LogVerbatim("ProtonTransport")
34  << "=============================================================================\n"
35  << " Bulding LHC Proton transporter based on HECTOR model\n"
36  << "=============================================================================\n";
37  setBeamLine();
38 }
40 //
41 // this method is the same for all propagator, but since transportProton is different for each derived class
42 // it needes to be overriden
43 //
45  const edm::EventSetup& iSetup,
46  CLHEP::HepRandomEngine* engine) {
47  clear();
48  engine_ = engine; // the engine needs to be updated for each event
49 
50  beamspot_ = &iSetup.getData(beamspotToken_);
52 
53  for (HepMC::GenEvent::particle_const_iterator eventParticle = evt->particles_begin();
54  eventParticle != evt->particles_end();
55  ++eventParticle) {
56  if (!((*eventParticle)->status() == 1 && (*eventParticle)->pdg_id() == 2212))
57  continue;
58 
59  if (!(fabs((*eventParticle)->momentum().eta()) > etaCut_ && fabs((*eventParticle)->momentum().pz()) > momentumCut_))
60  continue; // discard protons outside kinematic acceptance
61 
62  unsigned int line = (*eventParticle)->barcode();
63  HepMC::GenParticle* gpart = (*eventParticle);
64 
65  if (gpart->pdg_id() != 2212)
66  continue; // only transport stable protons
67  if (gpart->status() != 1)
68  continue;
69  if (m_beamPart.find(line) != m_beamPart.end())
70  continue; // assures this protons has not been already propagated
71 
72  transportProton(gpart);
73  }
74 }
76  edm::LogVerbatim("ProtonTransport") << "Starting proton transport using HECTOR method\n";
77 
78  double px, py, pz, e;
79  unsigned int line = (gpart)->barcode();
80 
81  double mass = gpart->generatedMass();
82  double charge = 1.;
83 
84  // remove the CMS vertex shift
85  double vtxXoffset;
86  double vtxYoffset;
88  vtxXoffset = beamParameters_->getVtxOffsetX45() * cm_to_mm;
89  vtxYoffset = beamParameters_->getVtxOffsetY45() * cm_to_mm;
90  } else {
91  vtxXoffset = beamspot_->x() * cm_to_mm;
92  vtxYoffset = beamspot_->y() * cm_to_mm;
93  }
94 
95  // Momentum in LHC ref. frame
96  px = -gpart->momentum().px();
97  py = gpart->momentum().py();
98  pz = -gpart->momentum().pz();
99  e = gpart->momentum().e();
100 
101  int direction = (pz > 0) ? 1 : -1; // in relation to LHC ref frame
102 
103  double XforPosition = -gpart->production_vertex()->position().x(); //mm in the ref. frame of LHC
104  double YforPosition = gpart->production_vertex()->position().y(); //mm
105  double ZforPosition = -gpart->production_vertex()->position().z(); //mm
106  double fCrossingAngleX = (pz < 0) ? fCrossingAngleX_45_ : fCrossingAngleX_56_;
107  double fCrossingAngleY = (pz < 0) ? fCrossingAngleY_45_ : fCrossingAngleY_56_;
108  //
109  H_BeamParticle h_p(mass, charge);
110  h_p.set4Momentum(px, py, pz, e);
111  //
112  // shift the starting position of the track to Z=0 if configured so (all the variables below are still in cm)
113  XforPosition = XforPosition - ZforPosition * (px / pz + fCrossingAngleX * urad); // theta ~=tan(theta)
114  YforPosition = YforPosition - ZforPosition * (py / pz + fCrossingAngleY * urad);
115  XforPosition -= (-vtxXoffset); // X was already in the LHC ref. frame
116  YforPosition -= vtxYoffset;
117 
118  // set position, but do not invert the coordinate for the angles (TX,TY) because it is done by set4Momentum
119  h_p.setPosition(XforPosition * mm_to_um, YforPosition * mm_to_um, h_p.getTX(), h_p.getTY(), 0.);
120 
121  bool is_stop;
122  float x1_ctpps;
123  float y1_ctpps;
124 
125  H_BeamLine* beamline = nullptr;
126  double targetZ = 0;
127  switch (direction) {
128  case 1:
129  beamline = &*m_beamline56; // negative side propagation
130  targetZ = fPPSRegionStart_56_;
131  break;
132  case -1:
133  beamline = &*m_beamline45;
134  targetZ = fPPSRegionStart_45_;
135  break;
136  }
137  // insert protection for NULL beamlines here
138  h_p.computePath(&*beamline);
139  is_stop = h_p.stopped(&*beamline);
140  if (verbosity_)
141  LogDebug("HectorTransportEventProcessing")
142  << "HectorTransport:filterPPS: barcode = " << line << " is_stop= " << is_stop;
143  if (is_stop) {
144  return false;
145  }
146  //
147  //propagating
148  //
149  h_p.propagate(targetZ);
150  x1_ctpps = h_p.getX();
151  y1_ctpps = h_p.getY();
152 
153  double thx = h_p.getTX();
154  double thy = h_p.getTY();
155 
157  H_BeamParticle p_beam(mass, charge);
158  p_beam.set4Momentum(0., 0., beamMomentum(), beamEnergy());
159  p_beam.setPosition(0., 0., fCrossingAngleX * urad, fCrossingAngleY * urad, 0.);
160  p_beam.computePath(&*beamline);
161  thx -= p_beam.getTX();
162  thy -= p_beam.getTY();
163  x1_ctpps -= p_beam.getX();
164  y1_ctpps -= p_beam.getY();
165  edm::LogVerbatim("HectorTransportEventProcessing")
166  << "Shifting the hit relative to beam : X = " << p_beam.getX() << "(mm) Y = " << p_beam.getY() << "(mm)";
167  }
168 
169  double partP = sqrt(pow(h_p.getE(), 2) - ProtonMassSQ);
170  double theta = sqrt(thx * thx + thy * thy) * urad;
171 
172  // copy the kinematic changing to CMS ref. frame, only the negative Pz needs to be changed
173  TLorentzVector p_out(-tan(thx * urad) * partP * cos(theta),
174  tan(thy * urad) * partP * cos(theta),
175  -direction * partP * cos(theta),
176  h_p.getE());
177 
178  m_beamPart[line] = p_out;
179  m_xAtTrPoint[line] = -x1_ctpps * um_to_mm; // move to CMS ref. frame
180  m_yAtTrPoint[line] = y1_ctpps * um_to_mm;
181  if (verbosity_)
182  LogDebug("HectorTransportEventProcessing")
183  << "HectorTransport:filterPPS: barcode = " << line << " x= " << x1_ctpps << " y= " << y1_ctpps;
184 
185  return true;
186 }
190 
191  // construct beam line for PPS (forward 1 backward 2):
192  if (fPPSBeamLineLength_ > 0.) {
193  m_beamline45 = std::make_unique<H_BeamLine>(-1, fPPSBeamLineLength_ + 0.1);
194  m_beamline45->fill(b2.fullPath(), 1, "IP5");
195  m_beamline56 = std::make_unique<H_BeamLine>(1, fPPSBeamLineLength_ + 0.1);
196  m_beamline56->fill(b1.fullPath(), 1, "IP5");
197  } else {
198  if (verbosity_)
199  LogDebug("HectorTransportSetup") << "HectorTransport: WARNING: lengthctpps= " << fPPSBeamLineLength_;
200  return false;
201  }
202  if (verbosity_) {
203  edm::LogInfo("HectorTransportSetup") << "===================================================================\n"
204  << " * * * * * * * * * * * * * * * * * * * * * * * * * * * * \n"
205  << " * * \n"
206  << " * --<--<-- A fast simulator --<--<-- * \n"
207  << " * | --<--<-- of particle --<--<-- * \n"
208  << " * ----HECTOR----< * \n"
209  << " * | -->-->-- transport through-->-->-- * \n"
210  << " * -->-->-- generic beamlines -->-->-- * \n"
211  << " * * \n"
212  << " * JINST 2:P09005 (2007) * \n"
213  << " * X Rouby, J de Favereau, K Piotrzkowski (CP3) * \n"
214  << " * http://www.fynu.ucl.ac.be/hector.html * \n"
215  << " * * \n"
216  << " * Center for Cosmology, Particle Physics and Phenomenology * \n"
217  << " * Universite catholique de Louvain * \n"
218  << " * Louvain-la-Neuve, Belgium * \n"
219  << " * * \n"
220  << " * * * * * * * * * * * * * * * * * * * * * * * * * * * * \n"
221  << " HectorTransport configuration: \n"
222  << " Beam line length = " << fPPSBeamLineLength_ << "\n"
223  << " PPS Region Start 44 = " << fPPSRegionStart_45_ << "\n"
224  << " PPS Region Start 56 = " << fPPSRegionStart_56_ << "\n"
225  << "===================================================================\n";
226  edm::LogVerbatim("HectorTransportSetup") << "===================================================================\n"
227  << " Forward beam line elements \n";
228  m_beamline45->showElements();
229  edm::LogVerbatim("HectorTransportSetup") << "===================================================================\n"
230  << " Backward beam line elements \n";
231  m_beamline56->showElements();
232  }
233  return true;
234 }
Log< level::Info, true > LogVerbatim
weight_default_t b1[25]
Definition: b1.h:9
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
~HectorTransport() override
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
static const double urad
double getVtxOffsetX45() const
bool transportProton(const HepMC::GenParticle *)
propagate the particles through a beamline to PPS
void setBeamParameters(double stx, double sty, double sx, double sy, double se)
edm::ESGetToken< CTPPSBeamParameters, CTPPSBeamParametersRcd > beamParametersToken_
const CTPPSBeamParameters * beamParameters_
T sqrt(T t)
Definition: SSEVec.h:19
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
double x() const
get X beam position
double getVtxOffsetY45() const
weight_default_t b2[10]
Definition: b2.h:9
const BeamSpotObjects * beamspot_
CLHEP::HepRandomEngine * engine_
void setCrossingAngles(double cx45, double cx56, double cy45, double cy56)
void setBeamFileNames(const std::string &nam1, const std::string &nam2)
static const double um_to_mm
HectorTransport(const edm::ParameterSet &ps, edm::ConsumesCollector iC)
Log< level::Info, false > LogInfo
double y() const
get Y beam position
void process(const HepMC::GenEvent *ev, const edm::EventSetup &es, CLHEP::HepRandomEngine *engine) override
std::map< unsigned int, double > m_xAtTrPoint
static const double mm_to_um
std::map< unsigned int, TLorentzVector > m_beamPart
static constexpr double fPPSBeamLineLength_
std::unique_ptr< H_BeamLine > m_beamline56
std::unique_ptr< H_BeamLine > m_beamline45
edm::ESGetToken< BeamSpotObjects, BeamSpotObjectsRcd > beamspotToken_
static const double ProtonMassSQ
std::map< unsigned int, double > m_yAtTrPoint
Geom::Theta< T > theta() const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
static const double cm_to_mm
#define LogDebug(id)