21 #include <TDatabasePDG.h>
53 int main(
int argc,
char* argv[]){
68 cerr <<
"Detector sepcified as " << qapars.
detstring
69 <<
" not recognized or empty." << endl;
75 TFile * outfile =
new TFile ( qapars.
outfilebase +
".pgun." + qapars.
detstring +
".root",
"RECREATE");
79 map<int,pidqacollection> qabook;
81 if ( qapars.
pids.size() == 0 ) qapars.
pids = { 11, 211, 321, 2212, 2112 };
86 TH2D*
h = qabook[ qapars.pids[0] ].dPhi_p;
88 double pmin =
std::max (
h->GetXaxis()->GetXmin(), 0.1);
89 double pmax =
h->GetXaxis()->GetXmax();
93 h = qabook[ qapars.pids[0] ].DelP_th;
94 double thmin =
std::max (
h->GetXaxis()->GetXmin(),
eps );
95 double thmax =
std::min (
h->GetXaxis()->GetXmax(), TMath::Pi() -
eps);
100 double phimin = -TMath::Pi();
101 double phimax = TMath::Pi();
104 TDatabasePDG*
db = TDatabasePDG::Instance();
111 for(
int np=0; np<qapars.nparticles; np++){
112 if ( !(np%20000) ) cout <<
"Generated " << np*qapars.pids.size() <<
" particles" << endl;
114 for (
auto pid : qapars.pids ){
116 TParticlePDG* pdg_particle = db->GetParticle(
pid);
119 if (
std::abs(pdg_particle->Charge()) <1
e-1){
120 if ( gRandom->Integer(2) == 1)
pid = -
pid;
126 double theta = gRandom->Uniform (thmin,thmax);
129 double phi = gRandom->Uniform (phimin,phimax);
135 pt = gRandom->Uniform (0,pmax);
138 }
while ( mom < pmin || mom > pmax);
140 TLorentzVector input_vect;
141 input_vect.SetPtEtaPhiM ( pt, eta , phi, pdg_particle->Mass());
143 if ( inParticle )
delete inParticle;
151 if ( inParticleS )
delete inParticleS;
152 inParticleS = detector.Smear( *inParticle);
155 if( !inParticleS )
continue;
165 if ( inParticle )
delete inParticle;
166 if ( inParticleS )
delete inParticleS;
184 for (
auto& pidcoll : qabook ){
185 auto&
pid = pidcoll.first;
186 auto& coll = pidcoll.second;
190 auto delP = (inParticle->
GetP() - inParticleS->
GetP()) / inParticle->
GetP();
191 coll.DelP_th->Fill(inParticle->
GetTheta(), delP);
192 coll.DelP_eta->Fill(inParticle->
GetEta(), delP);
196 auto delE = (inParticle->
GetE() - inParticleS->
GetE()) / inParticle->
GetE();
197 coll.DelE_E->Fill(inParticle->
GetE(), delE);
198 coll.DelE_th->Fill(inParticle->
GetTheta(), delE);
199 coll.DelE_eta->Fill(inParticle->
GetEta(), delE);
204 coll.dEta_p->Fill(inParticle->
GetP(), inParticle->
GetEta() - inParticleS->
GetEta());
208 coll.dPhi_p->Fill(inParticle->
GetP(), inParticle->
GetPhi() - inParticleS->
GetPhi());
217 vector<string> arguments(argv + 1, argv + argc);
221 for (
auto parg = arguments.begin() ; parg!=arguments.end() ; ++parg){
226 }
else if ( arg ==
"-o" ){
227 if (++parg == arguments.end() ){ argsokay=
false;
break; }
229 }
else if ( arg ==
"-N" ){
230 if (++parg==arguments.end() ){ argsokay=
false;
break; }
232 }
else if ( arg ==
"-addpid" ){
233 if ( ++parg == arguments.end() ){ argsokay=
false;
break; }
234 qapars.
pids.push_back(std::stoi(parg->data()));
235 }
else if ( arg ==
"-det" ){
236 if (++parg == arguments.end() ){ argsokay=
false;
break; }
239 if ( TString(qapars.
detstring).Contains(
"MATRIX") && TString(qapars.
detstring).Contains(
"FF")){
240 if (++parg == arguments.end() ){ argsokay=
false;
break; }
243 if ( TString(qapars.
detstring).Contains(
"CORE") && !TString(qapars.
detstring).Contains(
"B")){
244 if (++parg == arguments.end() ){ argsokay=
false;
break; }
252 }
catch (
const std::exception&
e){
253 cerr <<
"Caught exception during argument parsing: "
259 cerr <<
"usage: " << argv[0] << endl
260 <<
" [-o OutFileBase] (extension will be added)" << endl
261 <<
" [-N #particles per pid]" << endl
262 <<
" [-addpid pid] (can be called multiple times)" << endl
263 <<
" [-det detstring] matrix, matrixff [beam_mom_nn], handbook, perfect, beast, ephenix, zeus, jleic (capitalization does not matter.)" << endl
265 throw std::runtime_error(
"Not a valid list of options");
274 gStyle->SetHistLineColor(kRed);
294 float thmax = TMath::Pi();
305 float detamin = -0.1;
309 double phimin = -TMath::Pi();
310 double phimax = TMath::Pi();
313 float dphimin = -0.1;
317 for (
auto pid : qapars.
pids ){
321 qabook[
pid].DelE_E =
new TH2D( s,s+
";E;#Delta E/E", ebins, emin, emax, debins, demin, demax);
324 qabook[
pid].dPhi_p =
new TH2D( s,s+
";p;#Delta#phi", pbins, pmin, pmax, dphibins, dphimin, dphimax );
327 qabook[
pid].DelP_th =
new TH2D( s,s+
";#theta;#Delta p/p", thbins, thmin, thmax, dpbins, dpmin, dpmax);
330 qabook[
pid].DelE_th =
new TH2D( s,s+
";#theta;#Delta E/E", thbins, thmin, thmax, debins, demin, demax);
333 qabook[
pid].dTh_p =
new TH2D( s,s+
";p;#Delta#theta", pbins, pmin, pmax, dthbins, dthmin, dthmax );
336 qabook[
pid].DelP_eta =
new TH2D( s,s+
";#eta;#Delta p/p", etabins, etamin, etamax, dpbins, dpmin, dpmax);
339 qabook[
pid].DelE_eta =
new TH2D( s,s+
";#eta;#Delta E/E", etabins, etamin, etamax, debins, demin, demax);
342 qabook[
pid].dEta_p =
new TH2D( s,s+
";p;#Delta#eta", pbins, pmin, pmax, detabins, detamin, detamax );
353 gStyle->SetStatX(0.55);
354 gStyle->SetStatW(0.15);
355 gStyle->SetStatY(0.9);
356 gStyle->SetStatH(0.15);
361 gErrorIgnoreLevel = kWarning;
366 gPad->SaveAs( pdfname +
"[" );
370 for (
auto& pidcoll : qabook ){
371 auto&
pid = pidcoll.first;
372 auto& coll = pidcoll.second;
376 coll.DelP_th->Draw(
"colz");
377 gPad->SaveAs( pdfname );
379 coll.DelP_eta->Draw(
"colz");
380 coll.DelP_eta->ProfileX(
"_px",1,-1,
"s")->Draw(
"same");
381 gPad->SaveAs( pdfname );
383 gStyle->SetStatX(0.25);
384 coll.DelE_th->Draw(
"colz");
385 gPad->SaveAs( pdfname );
387 coll.DelE_eta->Draw(
"colz");
388 coll.DelE_eta->ProfileX(
"_px",1,-1,
"s")->Draw(
"same");
389 gPad->SaveAs( pdfname );
390 gStyle->SetStatX(0.55);
392 coll.DelE_E->Draw(
"colz");
393 coll.DelE_E->ProfileX(
"_px",1,-1,
"s")->Draw(
"same");
394 gPad->SaveAs( pdfname );
396 coll.dTh_p->Draw(
"colz");
397 gPad->SaveAs( pdfname );
399 coll.dEta_p->Draw(
"colz");
400 coll.dEta_p->ProfileX(
"_px",1,-1,
"s")->Draw(
"same");
401 gPad->SaveAs( pdfname );
403 coll.dPhi_p->Draw(
"colz");
404 coll.dPhi_p->ProfileX(
"_px",1,-1,
"s")->Draw(
"same");
405 gPad->SaveAs( pdfname );
409 gErrorIgnoreLevel = kInfo;
412 gPad->SaveAs( pdfname +
"]" );
416 return log ( tan ( 0.5*theta ));
420 if ( !std::isnan(eta) && !std::isinf(eta) ) {
421 return 2.0 * atan( exp( -eta ));
423 throw std::runtime_error(
"ThetaFromEta called with NaN or Inf");