CMS 3D CMS Logo

BeamDivergenceVtxGenerator.cc
Go to the documentation of this file.
1 /****************************************************************************
2  * Authors:
3  * Jan Kašpar
4  ****************************************************************************/
5 
16 
18 
20 
23 
24 #include <CLHEP/Random/RandGauss.h>
25 
26 //----------------------------------------------------------------------------------------------------
27 
29 {
30  public:
32  ~BeamDivergenceVtxGenerator() override = default;
33 
35 
36  void produce(edm::Event&, const edm::EventSetup&) override;
37 
38  private:
40  std::vector<edm::EDGetTokenT<reco::GenParticleCollection>> genParticleTokens_;
41 
44 
46  {
47  double vtx_x, vtx_y, vtx_z; // cm
48  double bd_x_45, bd_y_45, bd_x_56, bd_y_56; // rad
49  };
50 
51  template <typename T>
52  static HepMC::FourVector smearMomentum(const T &mom, const SmearingParameters &sp);
53 
55 
57 };
58 
59 //----------------------------------------------------------------------------------------------------
60 
62  simulateVertex_ (iConfig.getParameter<bool>("simulateVertex")),
63  simulateBeamDivergence_(iConfig.getParameter<bool>("simulateBeamDivergence"))
64 {
65  const edm::InputTag tagSrcHepMC = iConfig.getParameter<edm::InputTag>("src");
66  if (tagSrcHepMC.label() != "")
67  sourceToken_ = consumes<edm::HepMCProduct>(tagSrcHepMC);
68 
69  for (const auto &it : iConfig.getParameter<std::vector<edm::InputTag>>("srcGenParticle"))
70  genParticleTokens_.push_back(consumes<reco::GenParticleCollection>(it));
71 
73  if (!rng.isAvailable())
74  throw cms::Exception("Configuration")
75  << "The BeamDivergenceVtxGenerator requires the RandomNumberGeneratorService\n"
76  "which is not present in the configuration file. \n"
77  "You must add the service\n"
78  "in the configuration file or remove the modules that require it.";
79 
80  produces<edm::HepMCProduct>();
81 }
82 
83 //----------------------------------------------------------------------------------------------------
84 
86 {
88 
89  desc.add<edm::InputTag>("src", edm::InputTag("generator", "unsmeared"))
90  ->setComment("input collection in HepMC format");
91 
92  desc.add<std::vector<edm::InputTag>>("srcGenParticle", std::vector<edm::InputTag>())
93  ->setComment("input collections in GenParticle format");
94 
95  desc.add<bool>("simulateBeamDivergence", true)->setComment("account for the beam angular divergence?");
96  desc.add<bool>("simulateVertex", true)->setComment("account for the vertex transverse smearing?");
97 
98  descriptions.add("beamDivergenceVtxGenerator", desc);
99 }
100 
101 //----------------------------------------------------------------------------------------------------
102 
104 {
105  // get random engine
107  CLHEP::HepRandomEngine* rnd = &(rng->getEngine(iEvent.streamID()));
108 
109  // get conditions
110  edm::ESHandle<CTPPSBeamParameters> hBeamParameters;
111  iSetup.get<CTPPSBeamParametersRcd>().get(hBeamParameters);
112 
113  // get HepMC input (if given)
116  {
117  genEvt = new HepMC::GenEvent();
118  } else {
119  edm::Handle<edm::HepMCProduct> hepUnsmearedMCEvt;
120  iEvent.getByToken(sourceToken_, hepUnsmearedMCEvt);
121 
122  genEvt = new HepMC::GenEvent(*hepUnsmearedMCEvt->GetEvent());
123  }
124 
125  // prepare output
126  std::unique_ptr<edm::HepMCProduct> output(new edm::HepMCProduct(genEvt));
127 
128  // generate smearing parameters
130 
131  if (simulateVertex_)
132  {
133  // NB: the separtion between effective offsets in LHC sectors 45 and 56 cannot be applied, thus the values for 45 are used
134  sp.vtx_x = hBeamParameters->getVtxOffsetX45() + CLHEP::RandGauss::shoot(rnd) * hBeamParameters->getVtxStddevX();
135  sp.vtx_y = hBeamParameters->getVtxOffsetY45() + CLHEP::RandGauss::shoot(rnd) * hBeamParameters->getVtxStddevY();
136  sp.vtx_z = hBeamParameters->getVtxOffsetZ45() + CLHEP::RandGauss::shoot(rnd) * hBeamParameters->getVtxStddevZ();
137  }
138 
140  {
141  sp.bd_x_45 = CLHEP::RandGauss::shoot(rnd) * hBeamParameters->getBeamDivergenceX45();
142  sp.bd_x_56 = CLHEP::RandGauss::shoot(rnd) * hBeamParameters->getBeamDivergenceX56();
143  sp.bd_y_45 = CLHEP::RandGauss::shoot(rnd) * hBeamParameters->getBeamDivergenceY45();
144  sp.bd_y_56 = CLHEP::RandGauss::shoot(rnd) * hBeamParameters->getBeamDivergenceY56();
145  }
146 
147  // apply smearing
148  applySmearingHepMC(sp, genEvt);
149 
150  for (const auto &token : genParticleTokens_)
151  {
153  iEvent.getByToken(token, hGPCollection);
154 
155  for (const auto &gp : *hGPCollection)
156  addSmearedGenParticle(gp, sp, genEvt);
157  }
158 
159  // save output
160  iEvent.put(std::move(output));
161 }
162 
163 //----------------------------------------------------------------------------------------------------
164 
165 template <typename T>
166 HepMC::FourVector BeamDivergenceVtxGenerator::smearMomentum(const T &mom, const SmearingParameters &sp)
167 {
168  // TODO: this is an oversimplified implemetation
169  // the TOTEM smearing module should be taken as reference
170 
171  double th_x = mom.x() / mom.z();
172  double th_y = mom.y() / mom.z();
173 
174  if (mom.z() > 0.)
175  {
176  th_x += sp.bd_x_45;
177  th_y += sp.bd_y_45;
178  } else {
179  th_x += sp.bd_x_56;
180  th_y += sp.bd_y_56;
181  }
182 
183  // calculate consistent p_z component
184  const double sign = (mom.z() > 0.) ? 1. : -1.;
185  const double p = sqrt(mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z());
186  const double p_z = sign * p / sqrt(1. + th_x*th_x + th_y*th_y);
187 
188  return HepMC::FourVector(p_z * th_x, p_z * th_y, p_z, mom.e());
189 }
190 
191 //----------------------------------------------------------------------------------------------------
192 
194 {
195  if (simulateVertex_)
196  {
197  for (HepMC::GenEvent::vertex_iterator vit = genEvt->vertices_begin(); vit != genEvt->vertices_end(); ++vit)
198  {
199  const auto &pos = (*vit)->position();
200  (*vit)->set_position(HepMC::FourVector(
201  pos.x() + sp.vtx_x*1E1, // conversion: cm to mm
202  pos.y() + sp.vtx_y*1E1,
203  pos.z() + sp.vtx_z*1E1,
204  pos.t()
205  ));
206  }
207  }
208 
210  {
211  for (HepMC::GenEvent::particle_iterator part = genEvt->particles_begin(); part != genEvt->particles_end(); ++part)
212  (*part)->set_momentum(smearMomentum((*part)->momentum(), sp));
213  }
214 }
215 
216 //----------------------------------------------------------------------------------------------------
217 
219 {
220  // add vertex of the particle
221  HepMC::GenVertex *vtx = new HepMC::GenVertex(HepMC::FourVector(
222  (gp.vx() + sp.vtx_x)*1E1, // conversion: cm to mm
223  (gp.vy() + sp.vtx_y)*1E1,
224  (gp.vz() + sp.vtx_z)*1E1,
225  0.
226  ));
227  genEvt->add_vertex(vtx);
228 
229  // add the particle itself
230  HepMC::GenParticle* particle = new HepMC::GenParticle(smearMomentum(gp.p4(), sp), gp.pdgId(), gp.status());
231  vtx->add_particle_out(particle);
232 }
233 
234 //----------------------------------------------------------------------------------------------------
235 
T getParameter(std::string const &) const
int pdgId() const final
PDG identifier.
void setComment(std::string const &value)
std::vector< edm::EDGetTokenT< reco::GenParticleCollection > > genParticleTokens_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
static void fillDescriptions(edm::ConfigurationDescriptions &)
double vy() const override
y coordinate of vertex position
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
double getBeamDivergenceX56() const
static HepMC::FourVector smearMomentum(const T &mom, const SmearingParameters &sp)
double getVtxStddevZ() const
double getVtxOffsetX45() const
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
double getBeamDivergenceX45() const
double getBeamDivergenceY56() const
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
T sqrt(T t)
Definition: SSEVec.h:18
bool isAvailable() const
Definition: Service.h:40
const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::EDGetTokenT< edm::HepMCProduct > sourceToken_
double vz() const override
z coordinate of vertex position
double getVtxStddevX() const
void applySmearingHepMC(const SmearingParameters &sp, HepMC::GenEvent *genEvt)
double getBeamDivergenceY45() const
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:38
part
Definition: HCALResponse.h:20
void addSmearedGenParticle(const reco::GenParticle &gp, const SmearingParameters &sp, HepMC::GenEvent *genEvt)
BeamDivergenceVtxGenerator(const edm::ParameterSet &)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
~BeamDivergenceVtxGenerator() override=default
double getVtxOffsetZ45() const
std::string const & label() const
Definition: InputTag.h:36
double getVtxOffsetY45() const
T get() const
Definition: EventSetup.h:71
StreamID streamID() const
Definition: Event.h:95
int status() const final
status word
bool isUninitialized() const
Definition: EDGetToken.h:70
double getVtxStddevY() const
VertexRefVector::iterator vertex_iterator
iterator over a vector of references to Vertex objects in the same collection
Definition: VertexFwd.h:19
long double T
def move(src, dest)
Definition: eostools.py:511
double vx() const override
x coordinate of vertex position
void produce(edm::Event &, const edm::EventSetup &) override