/
FlatRandomPtAndDxyGunProducer.cc
160 lines (136 loc) · 5.22 KB
/
FlatRandomPtAndDxyGunProducer.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <ostream>
#include "IOMC/ParticleGuns/interface/FlatRandomPtAndDxyGunProducer.h"
#include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
#include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/Utilities/interface/RandomNumberGenerator.h"
#include "CLHEP/Random/RandFlat.h"
using namespace edm;
using namespace std;
FlatRandomPtAndDxyGunProducer::FlatRandomPtAndDxyGunProducer(const ParameterSet& pset) : BaseFlatGunProducer(pset) {
ParameterSet defpset;
ParameterSet pgun_params = pset.getParameter<ParameterSet>("PGunParameters");
fMinPt = pgun_params.getParameter<double>("MinPt");
fMaxPt = pgun_params.getParameter<double>("MaxPt");
dxyMin_ = pgun_params.getParameter<double>("dxyMin");
dxyMax_ = pgun_params.getParameter<double>("dxyMax");
lxyMax_ = pgun_params.getParameter<double>("LxyMax");
lzMax_ = pgun_params.getParameter<double>("LzMax");
ConeRadius_ = pgun_params.getParameter<double>("ConeRadius");
ConeH_ = pgun_params.getParameter<double>("ConeH");
DistanceToAPEX_ = pgun_params.getParameter<double>("DistanceToAPEX");
produces<HepMCProduct>("unsmeared");
produces<GenEventInfoProduct>();
}
FlatRandomPtAndDxyGunProducer::~FlatRandomPtAndDxyGunProducer() {
// no need to cleanup GenEvent memory - done in HepMCProduct
}
void FlatRandomPtAndDxyGunProducer::produce(Event& e, const EventSetup& es) {
edm::Service<edm::RandomNumberGenerator> rng;
CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
if (fVerbosity > 0) {
cout << " FlatRandomPtAndDxyGunProducer : Begin New Event Generation" << endl;
}
// event loop (well, another step in it...)
// no need to clean up GenEvent memory - done in HepMCProduct
//
// here re-create fEvt (memory)
//
fEvt = new HepMC::GenEvent();
// now actualy, cook up the event from PDGTable and gun parameters
int barcode = 1;
for (unsigned int ip = 0; ip < fPartIDs.size(); ++ip) {
double phi_vtx = 0;
double dxy = 0;
double pt = 0;
double eta = 0;
double px = 0;
double py = 0;
double pz = 0;
double vx = 0;
double vy = 0;
double vz = 0;
double lxy = 0;
bool passLoop = false;
while (not passLoop) {
bool passLxy = false;
bool passLz = false;
phi_vtx = CLHEP::RandFlat::shoot(engine, fMinPhi, fMaxPhi);
dxy = CLHEP::RandFlat::shoot(engine, dxyMin_, dxyMax_);
float dxysign = CLHEP::RandFlat::shoot(engine, -1, 1);
if (dxysign < 0)
dxy = -dxy;
pt = CLHEP::RandFlat::shoot(engine, fMinPt, fMaxPt);
px = pt * cos(phi_vtx);
py = pt * sin(phi_vtx);
for (int i = 0; i < 10000; i++) {
vx = CLHEP::RandFlat::shoot(engine, -lxyMax_, lxyMax_);
vy = (pt * dxy + vx * py) / px;
lxy = sqrt(vx * vx + vy * vy);
if (lxy < abs(lxyMax_) and (vx * px + vy * py) > 0) {
passLxy = true;
break;
}
}
eta = CLHEP::RandFlat::shoot(engine, fMinEta, fMaxEta);
pz = pt * sinh(eta);
//vz = fabs(fRandomGaussGenerator->fire(0.0, LzWidth_/2.0));
float ConeTheta = ConeRadius_ / ConeH_;
for (int j = 0; j < 100; j++) {
vz = CLHEP::RandFlat::shoot(engine, 0.0, lzMax_); // this is abs(vz)
float v0 = vz - DistanceToAPEX_;
if (v0 <= 0 or lxy * lxy / (ConeTheta * ConeTheta) > v0 * v0) {
passLz = true;
break;
}
}
if (pz < 0)
vz = -vz;
passLoop = (passLxy and passLz);
if (passLoop)
break;
}
float time = sqrt(vx * vx + vy * vy + vz * vz);
HepMC::GenVertex* Vtx1 = new HepMC::GenVertex(HepMC::FourVector(vx, vy, vz, time));
int PartID = fPartIDs[ip];
const HepPDT::ParticleData* PData = fPDGTable->particle(HepPDT::ParticleID(abs(PartID)));
double mass = PData->mass().value();
double energy2 = px * px + py * py + pz * pz + mass * mass;
double energy = sqrt(energy2);
HepMC::FourVector p(px, py, pz, energy);
HepMC::GenParticle* Part = new HepMC::GenParticle(p, PartID, 1);
Part->suggest_barcode(barcode);
barcode++;
Vtx1->add_particle_out(Part);
fEvt->add_vertex(Vtx1);
if (fAddAntiParticle) {
HepMC::GenVertex* Vtx2 = new HepMC::GenVertex(HepMC::FourVector(-vx, -vy, -vz, time));
HepMC::FourVector ap(-px, -py, -pz, energy);
int APartID = -PartID;
if (PartID == 22 || PartID == 23) {
APartID = PartID;
}
HepMC::GenParticle* APart = new HepMC::GenParticle(ap, APartID, 1);
APart->suggest_barcode(barcode);
barcode++;
Vtx2->add_particle_out(APart);
fEvt->add_vertex(Vtx2);
}
}
fEvt->set_event_number(e.id().event());
fEvt->set_signal_process_id(20);
if (fVerbosity > 0) {
fEvt->print();
}
unique_ptr<HepMCProduct> BProduct(new HepMCProduct());
BProduct->addHepMCData(fEvt);
e.put(std::move(BProduct), "unsmeared");
unique_ptr<GenEventInfoProduct> genEventInfo(new GenEventInfoProduct(fEvt));
e.put(std::move(genEventInfo));
if (fVerbosity > 0) {
cout << " FlatRandomPtAndDxyGunProducer : End New Event Generation" << endl;
fEvt->print();
}
}