CMS 3D CMS Logo

CTPPSDirectProtonSimulation.cc
Go to the documentation of this file.
1 /****************************************************************************
2  * Authors:
3  * Jan Kašpar
4  * Laurent Forthomme
5  ****************************************************************************/
6 
15 
17 
20 
26 
29 
32 
36 
37 #include <unordered_map>
38 
39 #include "TMath.h"
40 #include "TMatrixD.h"
41 #include "TVectorD.h"
42 
43 //----------------------------------------------------------------------------------------------------
44 
46 public:
49 
50  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
51 
52 private:
53  void produce(edm::Event&, const edm::EventSetup&) override;
54 
55  void processProton(const HepMC::GenVertex* in_vtx,
56  const HepMC::GenParticle* in_trk,
57  const CTPPSGeometry& geometry,
58  const CTPPSBeamParameters& beamParameters,
59  const LHCInterpolatedOpticalFunctionsSetCollection& opticalFunctions,
60  std::vector<CTPPSLocalTrackLite>& out_tracks,
61  edm::DetSetVector<TotemRPRecHit>& out_strip_hits,
63  edm::DetSetVector<CTPPSDiamondRecHit>& out_diamond_hits) const;
64 
65  static bool isPixelHit(float xLocalCoordinate, float yLocalCoordinate, bool is3x2 = true) {
66  float tmpXlocalCoordinate = xLocalCoordinate + (79 * 0.1 + 0.2);
67  float tmpYlocalCoordinate = yLocalCoordinate + (0.15 * 51 + 0.3 * 2 + 0.15 * 25);
68 
69  if (tmpXlocalCoordinate < 0)
70  return false;
71  if (tmpYlocalCoordinate < 0)
72  return false;
73  int xModuleSize = 0.1 * 79 + 0.2 * 2 + 0.1 * 79; // mm - 100 um pitch direction
74  int yModuleSize; // mm - 150 um pitch direction
75  if (is3x2)
76  yModuleSize = 0.15 * 51 + 0.3 * 2 + 0.15 * 50 + 0.3 * 2 + 0.15 * 51;
77  else
78  yModuleSize = 0.15 * 51 + 0.3 * 2 + 0.15 * 51;
79  if (tmpXlocalCoordinate > xModuleSize)
80  return false;
81  if (tmpYlocalCoordinate > yModuleSize)
82  return false;
83  return true;
84  }
85 
86  // ------------ config file parameters ------------
87 
90 
94 
97 
101 
105 
106  double pitchStrips_;
108 
111 
112  unsigned int verbosity_;
113 
114  // ------------ internal parameters ------------
115 
118 };
119 
120 //----------------------------------------------------------------------------------------------------
121 
123  : hepMCToken_(consumes<edm::HepMCProduct>(iConfig.getParameter<edm::InputTag>("hepMCTag"))),
124 
125  produceScoringPlaneHits_(iConfig.getParameter<bool>("produceScoringPlaneHits")),
126  produceRecHits_(iConfig.getParameter<bool>("produceRecHits")),
127 
128  useEmpiricalApertures_(iConfig.getParameter<bool>("useEmpiricalApertures")),
129  empiricalAperture45_xi0_(iConfig.getParameter<double>("empiricalAperture45_xi0")),
130  empiricalAperture45_a_(iConfig.getParameter<double>("empiricalAperture45_a")),
131  empiricalAperture56_xi0_(iConfig.getParameter<double>("empiricalAperture56_xi0")),
132  empiricalAperture56_a_(iConfig.getParameter<double>("empiricalAperture56_a")),
133 
134  produceHitsRelativeToBeam_(iConfig.getParameter<bool>("produceHitsRelativeToBeam")),
135  roundToPitch_(iConfig.getParameter<bool>("roundToPitch")),
136  checkIsHit_(iConfig.getParameter<bool>("checkIsHit")),
137 
138  pitchStrips_(iConfig.getParameter<double>("pitchStrips")),
139  insensitiveMarginStrips_(iConfig.getParameter<double>("insensitiveMarginStrips")),
140 
141  pitchPixelsHor_(iConfig.getParameter<double>("pitchPixelsHor")),
142  pitchPixelsVer_(iConfig.getParameter<double>("pitchPixelsVer")),
143 
144  verbosity_(iConfig.getUntrackedParameter<unsigned int>("verbosity", 0)) {
146  produces<std::vector<CTPPSLocalTrackLite>>();
147 
148  if (produceRecHits_) {
149  produces<edm::DetSetVector<TotemRPRecHit>>();
150  produces<edm::DetSetVector<CTPPSDiamondRecHit>>();
151  produces<edm::DetSetVector<CTPPSPixelRecHit>>();
152  }
153 
154  // v position of strip 0
157 }
158 
159 //----------------------------------------------------------------------------------------------------
160 
162  // get input
164  iEvent.getByToken(hepMCToken_, hepmc_prod);
165 
166  // get conditions
167  edm::ESHandle<CTPPSBeamParameters> hBeamParameters;
168  iSetup.get<CTPPSBeamParametersRcd>().get(hBeamParameters);
169 
171  iSetup.get<CTPPSInterpolatedOpticsRcd>().get(hOpticalFunctions);
172 
174  iSetup.get<VeryForwardMisalignedGeometryRecord>().get(geometry);
175 
176  // prepare outputs
177  std::unique_ptr<edm::DetSetVector<TotemRPRecHit>> pStripRecHits(new edm::DetSetVector<TotemRPRecHit>());
178  std::unique_ptr<edm::DetSetVector<CTPPSDiamondRecHit>> pDiamondRecHits(new edm::DetSetVector<CTPPSDiamondRecHit>());
179  std::unique_ptr<edm::DetSetVector<CTPPSPixelRecHit>> pPixelRecHits(new edm::DetSetVector<CTPPSPixelRecHit>());
180 
181  std::unique_ptr<std::vector<CTPPSLocalTrackLite>> pTracks(new std::vector<CTPPSLocalTrackLite>());
182 
183  // loop over event vertices
184  auto evt = new HepMC::GenEvent(*hepmc_prod->GetEvent());
185  for (auto it_vtx = evt->vertices_begin(); it_vtx != evt->vertices_end(); ++it_vtx) {
186  auto vtx = *(it_vtx);
187 
188  // loop over outgoing particles
189  for (auto it_part = vtx->particles_out_const_begin(); it_part != vtx->particles_out_const_end(); ++it_part) {
190  auto part = *(it_part);
191 
192  // accept only stable protons
193  if (part->pdg_id() != 2212)
194  continue;
195 
196  if (part->status() != 1 && part->status() < 83)
197  continue;
198 
200  part,
201  *geometry,
202  *hBeamParameters,
203  *hOpticalFunctions,
204  *pTracks,
205  *pStripRecHits,
206  *pPixelRecHits,
207  *pDiamondRecHits);
208  }
209  }
210 
212  iEvent.put(std::move(pTracks));
213 
214  if (produceRecHits_) {
215  iEvent.put(std::move(pStripRecHits));
216  iEvent.put(std::move(pPixelRecHits));
217  iEvent.put(std::move(pDiamondRecHits));
218  }
219 }
220 
221 //----------------------------------------------------------------------------------------------------
222 
223 void CTPPSDirectProtonSimulation::processProton(const HepMC::GenVertex* in_vtx,
224  const HepMC::GenParticle* in_trk,
225  const CTPPSGeometry& geometry,
226  const CTPPSBeamParameters& beamParameters,
227  const LHCInterpolatedOpticalFunctionsSetCollection& opticalFunctions,
228  std::vector<CTPPSLocalTrackLite>& out_tracks,
229  edm::DetSetVector<TotemRPRecHit>& out_strip_hits,
230  edm::DetSetVector<CTPPSPixelRecHit>& out_pixel_hits,
231  edm::DetSetVector<CTPPSDiamondRecHit>& out_diamond_hits) const {
234 
235  std::stringstream ssLog;
236 
237  // vectors in CMS convention
238  const HepMC::FourVector& vtx_cms = in_vtx->position(); // in mm
239  const HepMC::FourVector& mom_cms = in_trk->momentum();
240 
241  // transformation to LHC/TOTEM convention
242  HepMC::FourVector vtx_lhc(-vtx_cms.x(), vtx_cms.y(), -vtx_cms.z(), vtx_cms.t());
243  HepMC::FourVector mom_lhc(-mom_cms.x(), mom_cms.y(), -mom_cms.z(), mom_cms.t());
244 
245  // determine the LHC arm and related parameters
246  unsigned int arm = 3;
247  double z_sign;
248  double beamMomentum = 0.;
249  double xangle = 0.;
250  double empiricalAperture_xi0, empiricalAperture_a;
251 
252  if (mom_lhc.z() < 0) // sector 45
253  {
254  arm = 0;
255  z_sign = -1;
256  beamMomentum = beamParameters.getBeamMom45();
257  xangle = beamParameters.getHalfXangleX45();
258  empiricalAperture_xi0 = empiricalAperture45_xi0_;
259  empiricalAperture_a = empiricalAperture45_a_;
260  } else { // sector 56
261  arm = 1;
262  z_sign = +1;
263  beamMomentum = beamParameters.getBeamMom56();
264  xangle = beamParameters.getHalfXangleX56();
265  empiricalAperture_xi0 = empiricalAperture56_xi0_;
266  empiricalAperture_a = empiricalAperture56_a_;
267  }
268 
269  // calculate kinematics for optics parametrisation
270  const double p = mom_lhc.rho();
271  const double xi = 1. - p / beamMomentum;
272  const double th_x_phys = mom_lhc.x() / p;
273  const double th_y_phys = mom_lhc.y() / p;
274  const double vtx_lhc_eff_x = vtx_lhc.x() - vtx_lhc.z() * (mom_lhc.x() / mom_lhc.z() + xangle);
275  const double vtx_lhc_eff_y = vtx_lhc.y() - vtx_lhc.z() * (mom_lhc.y() / mom_lhc.z());
276 
277  if (verbosity_) {
278  ssLog << "simu: xi = " << xi << ", th_x_phys = " << th_x_phys << ", th_y_phys = " << th_y_phys
279  << ", vtx_lhc_eff_x = " << vtx_lhc_eff_x << ", vtx_lhc_eff_y = " << vtx_lhc_eff_y << std::endl;
280  }
281 
282  // check empirical aperture
284  const double xi_th = empiricalAperture_xi0 + th_x_phys * empiricalAperture_a;
285  if (xi > xi_th) {
286  if (verbosity_) {
287  ssLog << "stop because of empirical appertures";
288  edm::LogInfo("CTPPSDirectProtonSimulation") << ssLog.str();
289  }
290 
291  return;
292  }
293  }
294 
295  // transport the proton into each pot/scoring plane
296  for (const auto& ofp : opticalFunctions) {
297  CTPPSDetId rpId(ofp.first);
298  const unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
299 
300  // first check the arm
301  if (rpId.arm() != arm)
302  continue;
303 
304  if (verbosity_)
305  ssLog << " RP " << rpDecId << std::endl;
306 
307  // transport proton
309  vtx_lhc_eff_x * 1E-1, th_x_phys, vtx_lhc_eff_y * 1E-1, th_y_phys, xi}; // conversions: mm -> cm
311  ofp.second.transport(k_in, k_out, true);
312 
313  double b_x = k_out.x * 1E1, b_y = k_out.y * 1E1; // conversions: cm -> mm
314  double a_x = k_out.th_x, a_y = k_out.th_y;
315 
316  // if needed, subtract beam position and angle
318  // determine beam position
319  LHCInterpolatedOpticalFunctionsSet::Kinematics k_be_in = {0., 0., 0., 0., 0.};
321  ofp.second.transport(k_be_in, k_be_out, true);
322 
323  a_x -= k_be_out.th_x;
324  a_y -= k_be_out.th_y;
325  b_x -= k_be_out.x * 1E1;
326  b_y -= k_be_out.y * 1E1; // conversions: cm -> mm
327  }
328 
329  const double z_scoringPlane = ofp.second.getScoringPlaneZ() * 1E1; // conversion: cm --> mm
330 
331  if (verbosity_) {
332  ssLog << " proton transported: a_x = " << a_x << " rad, a_y = " << a_y << " rad, b_x = " << b_x
333  << " mm, b_y = " << b_y << " mm, z = " << z_scoringPlane << " mm" << std::endl;
334  }
335 
336  // save scoring plane hit
338  out_tracks.emplace_back(
339  rpId.rawId(), b_x, 0., b_y, 0., 0., 0., 0., 0., 0., CTPPSpixelLocalTrackReconstructionInfo::invalid, 0, 0., 0.);
340 
341  // stop if rec hits are not to be produced
342  if (!produceRecHits_)
343  continue;
344 
345  // loop over all sensors in the RP
346  for (const auto& detIdInt : geometry.sensorsInRP(rpId)) {
347  CTPPSDetId detId(detIdInt);
348 
349  // determine the track impact point (in global coordinates)
350  // !! this assumes that local axes (1, 0, 0) and (0, 1, 0) describe the sensor surface
351  CLHEP::Hep3Vector gl_o = geometry.localToGlobal(detId, CLHEP::Hep3Vector(0, 0, 0));
352  CLHEP::Hep3Vector gl_a1 = geometry.localToGlobal(detId, CLHEP::Hep3Vector(1, 0, 0)) - gl_o;
353  CLHEP::Hep3Vector gl_a2 = geometry.localToGlobal(detId, CLHEP::Hep3Vector(0, 1, 0)) - gl_o;
354 
355  TMatrixD A(3, 3);
356  TVectorD B(3);
357  A(0, 0) = a_x;
358  A(0, 1) = -gl_a1.x();
359  A(0, 2) = -gl_a2.x();
360  B(0) = gl_o.x() - b_x;
361  A(1, 0) = a_y;
362  A(1, 1) = -gl_a1.y();
363  A(1, 2) = -gl_a2.y();
364  B(1) = gl_o.y() - b_y;
365  A(2, 0) = z_sign;
366  A(2, 1) = -gl_a1.z();
367  A(2, 2) = -gl_a2.z();
368  B(2) = gl_o.z() - z_scoringPlane;
369  TMatrixD Ai(3, 3);
370  Ai = A.Invert();
371  TVectorD P(3);
372  P = Ai * B;
373 
374  double ze = P(0);
375  CLHEP::Hep3Vector h_glo(a_x * ze + b_x, a_y * ze + b_y, z_sign * ze + z_scoringPlane);
376 
377  // hit in local coordinates
378  CLHEP::Hep3Vector h_loc = geometry.globalToLocal(detId, h_glo);
379 
380  if (verbosity_) {
381  ssLog << std::endl
382  << " de z = " << P(0) << " mm, p1 = " << P(1) << " mm, p2 = " << P(2) << " mm" << std::endl
383  << " h_glo: x = " << h_glo.x() << " mm, y = " << h_glo.y() << " mm, z = " << h_glo.z() << " mm"
384  << std::endl
385  << " h_loc: c1 = " << h_loc.x() << " mm, c2 = " << h_loc.y() << " mm, c3 = " << h_loc.z() << " mm"
386  << std::endl;
387  }
388 
389  // strips
390  if (detId.subdetId() == CTPPSDetId::sdTrackingStrip) {
391  double u = h_loc.x();
392  double v = h_loc.y();
393 
394  if (verbosity_ > 5)
395  ssLog << " u=" << u << ", v=" << v;
396 
397  // is it within detector?
399  if (verbosity_ > 5)
400  ssLog << " | no hit" << std::endl;
401  continue;
402  }
403 
404  // round the measurement
405  if (roundToPitch_) {
406  double m = stripZeroPosition_ - v;
407  signed int strip = (int)floor(m / pitchStrips_ + 0.5);
408 
410 
411  if (verbosity_ > 5)
412  ssLog << " | strip=" << strip;
413  }
414 
415  double sigma = pitchStrips_ / sqrt(12.);
416 
417  if (verbosity_ > 5)
418  ssLog << " | m=" << v << ", sigma=" << sigma << std::endl;
419 
420  edm::DetSet<TotemRPRecHit>& hits = out_strip_hits.find_or_insert(detId);
421  hits.push_back(TotemRPRecHit(v, sigma));
422  }
423 
424  // diamonds
425  if (detId.subdetId() == CTPPSDetId::sdTimingDiamond) {
426  throw cms::Exception("CTPPSDirectProtonSimulation") << "Diamonds are not yet supported.";
427  }
428 
429  // pixels
430  if (detId.subdetId() == CTPPSDetId::sdTrackingPixel) {
431  if (verbosity_) {
432  CTPPSPixelDetId pixelDetId(detIdInt);
433  ssLog << " pixel plane " << pixelDetId.plane() << ": local hit x = " << h_loc.x()
434  << " mm, y = " << h_loc.y() << " mm, z = " << h_loc.z() << " mm" << std::endl;
435  }
436 
437  if (checkIsHit_ && !isPixelHit(h_loc.x(), h_loc.y()))
438  continue;
439 
440  if (roundToPitch_) {
441  h_loc.setX(pitchPixelsHor_ * floor(h_loc.x() / pitchPixelsHor_ + 0.5));
442  h_loc.setY(pitchPixelsVer_ * floor(h_loc.y() / pitchPixelsVer_ + 0.5));
443  }
444 
445  if (verbosity_ > 5)
446  ssLog << " hit accepted: m1 = " << h_loc.x() << " mm, m2 = " << h_loc.y() << " mm" << std::endl;
447 
448  const double sigmaHor = pitchPixelsHor_ / sqrt(12.);
449  const double sigmaVer = pitchPixelsVer_ / sqrt(12.);
450 
451  const LocalPoint lp(h_loc.x(), h_loc.y(), h_loc.z());
452  const LocalError le(sigmaHor, 0., sigmaVer);
453 
454  edm::DetSet<CTPPSPixelRecHit>& hits = out_pixel_hits.find_or_insert(detId);
455  hits.push_back(CTPPSPixelRecHit(lp, le));
456  }
457  }
458  }
459 
460  if (verbosity_)
461  edm::LogInfo("CTPPSDirectProtonSimulation") << ssLog.str();
462 }
463 
464 //----------------------------------------------------------------------------------------------------
465 
468  desc.addUntracked<unsigned int>("verbosity", 0);
469  desc.add<edm::InputTag>("hepMCTag", edm::InputTag("generator", "unsmeared"));
470  desc.add<bool>("produceScoringPlaneHits", true);
471  desc.add<bool>("produceRecHits", true);
472  desc.add<bool>("useEmpiricalApertures", false);
473  desc.add<double>("empiricalAperture45_xi0", 0.);
474  desc.add<double>("empiricalAperture45_a", 0.);
475  desc.add<double>("empiricalAperture56_xi0", 0.);
476  desc.add<double>("empiricalAperture56_a", 0.);
477  desc.add<bool>("produceHitsRelativeToBeam", false);
478  desc.add<bool>("roundToPitch", true);
479  desc.add<bool>("checkIsHit", true);
480  desc.add<double>("pitchStrips", 66.e-3); // in mm
481  desc.add<double>("insensitiveMarginStrips", 34.e-3); // in mm
482  desc.add<double>("pitchPixelsHor", 100.e-3)->setComment("x in local coordinates, in mm");
483  desc.add<double>("pitchPixelsVer", 150.e-3)->setComment("y in local coordinates, in mm");
484 
485  descriptions.add("ctppsDirectProtonSimulation", desc);
486 }
487 
488 //----------------------------------------------------------------------------------------------------
489 
uint32_t station() const
Definition: CTPPSDetId.h:58
uint32_t plane() const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
void push_back(const T &t)
Definition: DetSet.h:67
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
bool produceScoringPlaneHits_
flags what output to be produced
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
static bool IsHit(double u, double v, double insensitiveMargin=0)
Definition: RPTopology.cc:29
static const unsigned short no_of_strips_
Definition: RPTopology.h:61
void produce(edm::Event &, const edm::EventSetup &) override
static bool isPixelHit(float xLocalCoordinate, float yLocalCoordinate, bool is3x2=true)
reference find_or_insert(det_id_type id)
Definition: DetSetVector.h:234
edm::EDGetTokenT< edm::HepMCProduct > hepMCToken_
input tag
static const double y_width_
Definition: RPTopology.h:63
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
T sqrt(T t)
Definition: SSEVec.h:19
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
Reconstructed hit in TOTEM RP.
Definition: TotemRPRecHit.h:18
double getBeamMom56() const
double insensitiveMarginStrips_
size of insensitive margin at sensor&#39;s edge facing the beam, in mm
double getHalfXangleX56() const
static const std::string B
uint32_t arm() const
Definition: CTPPSDetId.h:51
CLHEP::Hep3Vector localToGlobal(const DetGeomDesc *, const CLHEP::Hep3Vector &) const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool checkApertures_
simulation parameters
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
The manager class for TOTEM RP geometry.
Definition: CTPPSGeometry.h:33
static const double last_strip_to_border_dist_
Definition: RPTopology.h:65
const std::set< unsigned int > & sensorsInRP(unsigned int) const
after checks returns set of sensor ids corresponding to the given RP id
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:34
part
Definition: HCALResponse.h:20
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::pair< OmniClusterRef, TrackingParticleRef > P
Base class for CTPPS detector IDs.
Definition: CTPPSDetId.h:32
double stripZeroPosition_
internal variable: v position of strip 0, in mm
ESHandle< TrackerGeometry > geometry
HLT enums.
Event setup record containing the misaligned geometry information. It is used for alignment studies o...
static const double pitch_
Definition: RPTopology.h:59
T get() const
Definition: EventSetup.h:73
double getBeamMom45() const
void processProton(const HepMC::GenVertex *in_vtx, const HepMC::GenParticle *in_trk, const CTPPSGeometry &geometry, const CTPPSBeamParameters &beamParameters, const LHCInterpolatedOpticalFunctionsSetCollection &opticalFunctions, std::vector< CTPPSLocalTrackLite > &out_tracks, edm::DetSetVector< TotemRPRecHit > &out_strip_hits, edm::DetSetVector< CTPPSPixelRecHit > &out_pixel_hits, edm::DetSetVector< CTPPSDiamondRecHit > &out_diamond_hits) const
double getHalfXangleX45() const
CLHEP::Hep3Vector globalToLocal(const DetGeomDesc *, const CLHEP::Hep3Vector &) const
def move(src, dest)
Definition: eostools.py:511
CTPPSDirectProtonSimulation(const edm::ParameterSet &)
uint32_t rp() const
Definition: CTPPSDetId.h:65