CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ParticleReplacerParticleGun.cc
Go to the documentation of this file.
3 
5 
6 #include "HepMC/PythiaWrapper.h"
7 #include "HepMC/IO_HEPEVT.h"
8 
10  ParticleReplacerBase(iConfig),
11  pythia_(iConfig),
12  particleOrigin_(iConfig.getParameter<std::string>("particleOrigin")),
13  forceTauPolarization_(iConfig.getParameter<std::string>("forceTauPolarization")),
14  forceTauDecay_(iConfig.getParameter<std::string>("forceTauDecay")),
15  generatorMode_(iConfig.getParameter<std::string>("generatorMode")),
16  gunParticle_(iConfig.getParameter<int>("gunParticle")),
17  forceTauPlusHelicity_(iConfig.getParameter<int>("forceTauPlusHelicity")),
18  forceTauMinusHelicity_(iConfig.getParameter<int>("forceTauMinusHelicity")),
19  printout_(verbose) {
20  // tauola_ = (gen::TauolaInterfaceBase*)(TauolaFactory::get()->create("Tauola271215",iConfig.getParameter<edm::ParameterSet>("ExternalDecays").getParameter<edm::ParameterSet>("Tauola")));
21 
22  srand(time(NULL)); // Should we use RandomNumberGenerator service?
23  /*
24  CLHEP::HepRandomEngine* decayRandomEngine=new CLHEP::HepRandomEngine();
25  decayRandomEngine->setSeeds(time(NULL),232*time(NULL));
26  tauola_->SetDecayRandomEngine(decayRandomEngine);
27  */
28  if(forceTauPlusHelicity_ != 0)
29  edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
30  << "Forcing tau+ to helicity " << forceTauPlusHelicity_ << std::endl;
31  if(forceTauMinusHelicity_ != 0)
32  edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
33  << "Forcing tau- to helicity " << forceTauMinusHelicity_ << std::endl;
35  edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
36  << " Forcing tau helicity as decayed from a " << forceTauPolarization_ << std::endl;
37  if(forceTauDecay_ != "" && forceTauDecay_ != "none")
38  edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
39  << "Forcing tau decaying into " << forceTauDecay_ << std::endl;
40 
41  std::memset(pol1_, 0, 4*sizeof(float));
42  std::memset(pol2_, 0, 4*sizeof(float));
43 
44  if(generatorMode_ != "Tauola")
45  throw cms::Exception("Configuration") << "Generator mode other than Tauola is not supported" << std::endl;
46 
47  throw cms::Exception("UnimplementedFeature") << "ParticleReplacerParticleGun is not usable yet." << std::endl;
48 }
49 
51  /*
52  delete tauola_;
53  delete decayRandomEngine;
54  */
55 }
56 
59 
61 
62  if(abs(gunParticle_) == 15) {
63  /* FIXME
64  call_tauola(-1,1);
65  */
66  }
67 }
68 
70  if(abs(gunParticle_) == 15) {
71  /* FIXME
72  call_tauola(1,1);
73  */
74  }
75 }
76 
77 std::auto_ptr<HepMC::GenEvent> ParticleReplacerParticleGun::produce(const reco::MuonCollection& muons, const reco::Vertex *pvtx, const HepMC::GenEvent *genEvt) {
78  if(genEvt != 0)
79  throw cms::Exception("UnimplementedFeature") << "ParticleReplacerParticleGun does NOT support merging at HepMC level" << std::endl;
80 
81  std::auto_ptr<HepMC::GenEvent> evt(0);
82  std::vector<HepMC::FourVector> muons_corrected;
83  muons_corrected.reserve(muons.size());
84  correctTauMass(muons, muons_corrected);
85 
87 
88  for(unsigned int i=0; i<muons_corrected.size(); ++i) {
89  HepMC::FourVector& muon = muons_corrected[i];
90  call_py1ent(i+1, gunParticle_*muons[i].charge(), muon.e(), muon.theta(), muon.phi());
91  }
92 
93  // Let's not do a call_pyexec here because it's unnecessary
94 
95  if(printout_) {
96  std::cout << " ///////////////////// After py1ent, before pyhepc /////////////////////" << std::endl;
97  call_pylist(3);
98  }
99 
100  // Vertex shift
101  call_pyhepc(1); // pythia -> hepevt
102 
103  if(printout_) {
104  std::cout << " ///////////////////// After pyhepc, before vertex shift /////////////////////" << std::endl;
105  HepMC::HEPEVT_Wrapper::print_hepevt();
106  }
107  // Search for HepMC/HEPEVT_Wrapper.h for the wrapper interface
108  int nparticles = HepMC::HEPEVT_Wrapper::number_entries();
109  HepMC::ThreeVector shift(0,0,0);
110  if(particleOrigin_ == "primaryVertex") {
111  if(!pvtx)
112  throw cms::Exception("LogicError") << "Particle origin set to primaryVertex, but pvtx is null!" << std::endl;
113 
114  shift.setX(pvtx->x()*10); // cm -> mm
115  shift.setY(pvtx->y()*10); // cm -> mm
116  shift.setZ(pvtx->z()*10); // cm -> mm
117  }
118  for(int i=1; i <= nparticles; ++i) {
120  throw cms::Exception("LogicError") << "Particle in HEPEVT is " << HepMC::HEPEVT_Wrapper::id(i)
121  << " is not the same as gunParticle " << gunParticle_
122  << " for index " << i << std::endl;
123  }
124 
125  if(particleOrigin_ == "muonReferencePoint") {
126  const reco::Muon& muon = muons[i-1];
127  shift.setX(muon.vx()*10); // cm -> mm
128  shift.setY(muon.vy()*10); // cm -> mm
129  shift.setZ(muon.vz()*10); // cm -> mm
130  }
131 
132  HepMC::HEPEVT_Wrapper::set_position(i,
133  HepMC::HEPEVT_Wrapper::x(i) + shift.x(),
134  HepMC::HEPEVT_Wrapper::y(i) + shift.y(),
135  HepMC::HEPEVT_Wrapper::z(i) + shift.z(),
137  }
138 
139  if(printout_) {
140  std::cout << " ///////////////////// After vertex shift, before pyhepc/tauola /////////////////////" << std::endl;
141  HepMC::HEPEVT_Wrapper::print_hepevt();
142  }
143 
144  if(abs(gunParticle_) == 15){
145  // Code example from TauolaInterface::processEvent()
146  /* FIXME
147  int dummy = -1;
148  int numGenParticles_beforeTAUOLA = call_ihepdim(dummy);
149  */
150 
152 
153  for(unsigned int i=0; i<muons_corrected.size(); ++i) {
154  tauola_forParticleGun(i+1, gunParticle_*muons[i].charge(), muons_corrected[i]);
155  }
156 
157  if(printout_) {
158  std::cout << " ///////////////////// After tauola, before pyhepc /////////////////////" << std::endl;
159  HepMC::HEPEVT_Wrapper::print_hepevt();
160  }
161  call_pyhepc(2); // hepevt->pythia
162  if(printout_) {
163  std::cout << " ///////////////////// After pyhepc, before vertex fix /////////////////////" << std::endl;
164  call_pylist(3);
165  }
166 
167  // Fix tau decay vertex position
168  /* FIXME
169  int numGenParticles_afterTAUOLA = call_ihepdim(dummy);
170  tauola_.setDecayVertex(numGenParticles_beforeTAUOLA, numGenParticles_afterTAUOLA);
171  */
172 
173  if(printout_) {
174  /* FIXME
175  std::cout << " numGenParticles_beforeTAUOLA " << numGenParticles_beforeTAUOLA << std::endl
176  << " numGenParticles_afterTAUOLA " << numGenParticles_afterTAUOLA << std::endl;
177  */
178  std::cout << " ///////////////////// After vertex fix, before pyexec /////////////////////" << std::endl;
179  call_pylist(3);
180  }
181  }
182  else {
183  call_pyhepc(2); // hepevt->pythia
184  if(printout_) {
185  std::cout << " ///////////////////// After pyhepc, before pyexec /////////////////////" << std::endl;
186  call_pylist(3);
187  }
188  }
189 
190  call_pyexec(); // taus: decay pi0's etc; others: decay whatever
191 
192  if(printout_) {
193  std::cout << " ///////////////////// After pyexec, before pyhepc /////////////////////" << std::endl;
194  call_pylist(3);
195  }
196 
197  call_pyhepc(1); // pythia -> hepevt
198 
199  HepMC::IO_HEPEVT conv;
200  evt = std::auto_ptr<HepMC::GenEvent>(new HepMC::GenEvent(*conv.read_next_event()));
201 
202  if(printout_) {
203  evt->print();
204 
205  std::cout << std::endl << "Vertices: " << std::endl;
206  for(HepMC::GenEvent::vertex_const_iterator iter = evt->vertices_begin(); iter != evt->vertices_end(); ++iter) {
207  std::cout << "Vertex " << (*iter)->id() << ", barcode " << (*iter)->barcode() << std::endl;
208 
209  HepMC::ThreeVector point = (*iter)->point3d();
210  std::cout << " Point (" << point.x() << ", " << point.y() << ", " << point.z() << ")" << std::endl;
211 
212  std::cout << " Incoming particles: ";
213  for(HepMC::GenVertex::particles_in_const_iterator pi = (*iter)->particles_in_const_begin(); pi != (*iter)->particles_in_const_end(); ++pi) {
214  std::cout << (*pi)->pdg_id() << " ";
215  }
216  std::cout << std::endl;
217  std::cout << " Outgoing particles: ";
218  for(HepMC::GenVertex::particles_out_const_iterator pi = (*iter)->particles_out_const_begin(); pi != (*iter)->particles_out_const_end(); ++pi) {
219  std::cout << (*pi)->pdg_id() << " ";
220  }
221  std::cout << std::endl << std::endl;
222  }
223  }
224 
225  return evt;
226 }
227 
228 void ParticleReplacerParticleGun::correctTauMass(const reco::MuonCollection& muons, std::vector<HepMC::FourVector>& corrected) {
229  if(abs(gunParticle_) == 15) {
230  // Correct energy for tau
231  for(reco::MuonCollection::const_iterator iMuon = muons.begin(); iMuon != muons.end(); ++iMuon) {
232  const reco::Muon::LorentzVector& vec = iMuon->p4();
233 
234  double E = sqrt(tauMass*tauMass + vec.x()*vec.x() + vec.y()*vec.y() + vec.z()*vec.z());
235 
236  corrected.push_back(HepMC::FourVector(vec.x(), vec.y(), vec.z(), E));
237  }
238  }
239  else {
240  // Just copy the LorentzVector
241  for(reco::MuonCollection::const_iterator iMuon = muons.begin(); iMuon != muons.end(); ++iMuon) {
242  corrected.push_back(iMuon->p4());
243  }
244  }
245 }
246 
248  if(forceTauDecay_ == "" || forceTauDecay_ == "none") return;
249 
250  // for documentation look at Tauola file tauola_photos_ini.f
251  // COMMON block COMMON / TAUBRA / GAMPRT(30),JLIST(30),NCHAN
252 
253  if(forceTauDecay_ == "hadrons"){
254  /* FIXME
255  taubra.gamprt[0] = 0; // disable branchings to electrons in Tauola
256  taubra.gamprt[1] = 0; // disable branchings to muons in Tauola
257  */
258  }
259  else if(forceTauDecay_ == "1prong"){
260  /* FIXME
261  taubra.gamprt[0] = 0; // disable branchings to electrons in Tauola
262  taubra.gamprt[1] = 0; // disable branchings to muons in Tauola
263  taubra.gamprt[7] = 0;
264  taubra.gamprt[9] = 0;
265  taubra.gamprt[10] = 0;
266  taubra.gamprt[11] = 0;
267  taubra.gamprt[12] = 0;
268  taubra.gamprt[13] = 0;
269  taubra.gamprt[17] = 0;
270  */
271  }
272  else if(forceTauDecay_ == "3prong"){
273  /* FIXME
274  taubra.gamprt[0] = 0; // disable branchings to electrons in Tauola
275  taubra.gamprt[1] = 0; // disable branchings to muons in Tauola
276  taubra.gamprt[2] = 0;
277  taubra.gamprt[3] = 0;
278  taubra.gamprt[4] = 0;
279  taubra.gamprt[5] = 0;
280  taubra.gamprt[6] = 0;
281  taubra.gamprt[8] = 0;
282  taubra.gamprt[14] = 0;
283  taubra.gamprt[15] = 0;
284  taubra.gamprt[16] = 0;
285  taubra.gamprt[18] = 0;
286  taubra.gamprt[19] = 0;
287  taubra.gamprt[20] = 0;
288  taubra.gamprt[21] = 0;
289  */
290  }
291  else
292  edm::LogError("MuonReplacement") << "[ParticleReplacerAlgoParticleGun::forceTauoladecays] "
293  << "Unknown value for forcing tau decays: " << forceTauDecay_ << std::endl;
294 }
295 
296 void ParticleReplacerParticleGun::tauola_forParticleGun(int tau_idx, int pdg_id, const HepMC::FourVector& particle_momentum) {
297  if(abs(pdg_id) != 15) {
298  edm::LogError("MuonReplacement") << "[ParticleReplacerAlgoParticleGun::tauola_forParticleGuns] "
299  << "Trying to decay something else than tau: pdg_id = " << pdg_id << std::endl;
300  return;
301  }
302 
303  // By default the index of tau+ is 3 and tau- is 4. The TAUOLA
304  // routine takes internally care of finding the correct
305  // position of the tau which is decayed. However, since we are
306  // calling DEXAY routine directly by ourselves, we must set
307  // the index manually by ourselves. Fortunately, this seems to
308  // be simple.
309  /* FIXME
310  if(printout_)
311  std::cout << " Tauola taupos common block: np1 " << taupos.np1 << " np2 " << taupos.np2 << std::endl;
312  taupos.np1 = tau_idx;
313  taupos.np2 = tau_idx;
314  if(printout_)
315  std::cout << " Resetting taupos common block to: np1 " << taupos.np1 << " np2 " << taupos.np2 << std::endl;
316  */
317 
318  if(pdg_id == -15){ // tau+
319 
320  pol1_[2] = tauHelicity(pdg_id);
321 
322  /* FIXME
323  momdec.p1[0] = particle_momentum.x();
324  momdec.p1[1] = particle_momentum.y();
325  momdec.p1[2] = particle_momentum.z();
326  momdec.p1[3] = particle_momentum.e();
327 
328  momdec.p2[0] = -momdec.p1[0];
329  momdec.p2[1] = -momdec.p1[1];
330  momdec.p2[2] = -momdec.p1[2];
331  momdec.p2[3] = momdec.p1[3];
332 
333  // "mother" p4
334  momdec.q1[0] = 0;
335  momdec.q1[1] = 0;
336  momdec.q1[2] = 0;
337  momdec.q1[3] = momdec.p1[3] + momdec.p2[3];
338 
339  call_dexay(1,pol1);
340  */
341  }
342  else if (pdg_id == 15){ // tau-
343 
344  pol2_[2] = tauHelicity(pdg_id);
345 
346  /* FIXME
347  momdec.p2[0] = particle_momentum.x();
348  momdec.p2[1] = particle_momentum.y();
349  momdec.p2[2] = particle_momentum.z();
350  momdec.p2[3] = particle_momentum.e();
351 
352  momdec.p1[0] = -momdec.p2[0];
353  momdec.p1[1] = -momdec.p2[1];
354  momdec.p1[2] = -momdec.p2[2];
355  momdec.p1[3] = momdec.p2[3];
356 
357  // "mother" p4
358  momdec.q1[0] = 0;
359  momdec.q1[1] = 0;
360  momdec.q1[2] = 0;
361  momdec.q1[3] = momdec.p1[3] + momdec.p2[3];
362 
363  call_dexay(2,pol2);
364  */
365  }
366 }
367 
369  /* tau polarization summary from Tauola source code:
370  in all cases W : pol1 = -1, pol2 = -1 (tau or neutrino)
371  H+: pol1 = +1, pol2 = +1 (tau or neutrino)
372 
373  if neutral higgs : pol1 = +1, pol2 = -1 OR pol1 = -1, pol2 = +1 (tau tau)
374  if Z or undetermined: pol1 = +1, pol2 = +1 OR pol1 = -1, pol2 = -1 (tau tau)
375  */
376 
377  if(pdg_id < 0) { // tau+
378  if(forceTauPlusHelicity_ != 0) {
379  return forceTauPlusHelicity_;
380  }
381  if(forceTauPolarization_ == "W") return -1;
382  if(forceTauPolarization_ == "H+") return 1;
383  if(pol2_[2] != 0) {
384  if(forceTauPolarization_ == "h" ||
385  forceTauPolarization_ == "H" ||
386  forceTauPolarization_ == "A") return -pol2_[2];
387  else return pol2_[2];
388  }
389  else {
390  return randomPolarization(); //all other cases random, when first tau
391  }
392  }
393  else { // tau-
394  if(forceTauMinusHelicity_ != 0) {
395  return forceTauMinusHelicity_;
396  }
397  if(forceTauPolarization_ == "W") return -1;
398  if(forceTauPolarization_ == "H+") return 1;
399  if(pol1_[2] != 0){
400  if(forceTauPolarization_ == "h" ||
401  forceTauPolarization_ == "H" ||
402  forceTauPolarization_ == "A") return -pol1_[2];
403  else return pol1_[2];
404  }
405  else {
406  return randomPolarization(); //all other cases random, when first tau
407  }
408  }
409 
410  edm::LogError("MuonReplacement") << "[ParticleReplacerAlgoParticleGun::tauHelicity] "
411  << "tauHelicity undetermined, returning 0" << std::endl;
412  return 0;
413 }
414 
416  uint32_t randomNumber = rand();
417  if(randomNumber%2 > 0.5) return 1;
418  return -1;
419 }
int i
Definition: DBlmapReader.cc:9
void call_pylist(int mode)
static HepMC::IO_HEPEVT conv
double y() const
y coordinate
Definition: Vertex.h:97
void call_pyexec()
Definition: extraPythia.cc:3
void correctTauMass(const reco::MuonCollection &muons, std::vector< HepMC::FourVector > &corrected)
#define abs(x)
Definition: mlp_lapack.h:159
#define NULL
Definition: scimark2.h:8
virtual double vy() const
y coordinate of vertex position
double charge(const std::vector< uint8_t > &Ampls)
double double double z
void tauola_forParticleGun(int tau_idx, int pdg_id, const HepMC::FourVector &particle_momentum)
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
T sqrt(T t)
Definition: SSEVec.h:46
ParticleReplacerParticleGun(const edm::ParameterSet &, bool)
double z() const
y coordinate
Definition: Vertex.h:99
virtual double vz() const
z coordinate of vertex position
double x() const
x coordinate
Definition: Vertex.h:95
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:38
tuple muons
Definition: patZpeak.py:38
void call_py1ent(int, int, double, double, double)
Definition: extraPythia.cc:4
Signal rand(Signal arg)
Definition: vlib.cc:442
std::auto_ptr< HepMC::GenEvent > produce(const reco::MuonCollection &muons, const reco::Vertex *pvtx=0, const HepMC::GenEvent *genEvt=0)
static unsigned int const shift
virtual double vx() const
x coordinate of vertex position
tuple cout
Definition: gather_cfg.py:121
double pi
Definition: DDAxes.h:10
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5