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