1 |
// C/C++ headers |
2 |
// |
3 |
#include <fstream> |
4 |
#include <string.h> |
5 |
#include <iostream> |
6 |
#include <stdio.h> |
7 |
#include <ctype.h> |
8 |
// |
9 |
// ROOT headers |
10 |
// |
11 |
|
12 |
#include <TTree.h> |
13 |
|
14 |
#include <TSystem.h> |
15 |
#include <TStopwatch.h> |
16 |
#include <TSystemDirectory.h> |
17 |
#include <TGraphAsymmErrors.h> |
18 |
#include <TString.h> |
19 |
#include <TFile.h> |
20 |
#include <TClass.h> |
21 |
#include <TGraph.h> |
22 |
#include <TLine.h> |
23 |
#include <TH1F.h> |
24 |
#include <TMath.h> |
25 |
#include <TRandom3.h> |
26 |
#include <TF1.h> |
27 |
// |
28 |
// RunInfo header |
29 |
// |
30 |
#include <RunInfo.h> |
31 |
|
32 |
#include <PamLevel2.h> |
33 |
|
34 |
#include <TClonesArray.h> |
35 |
#include "PrimaryInfo.h" |
36 |
|
37 |
using namespace std; |
38 |
using TMath::Pi; |
39 |
//This program generate trajectories, which are going in acceptance |
40 |
|
41 |
|
42 |
void Usage (); |
43 |
|
44 |
|
45 |
|
46 |
Bool_t IsInside(Trajectory *t, Double_t fiducial, |
47 |
float *xmin, float *xmax, float *ymin, float *ymax){ |
48 |
|
49 |
for(Int_t i = 0; i<t->npoint; i++){ |
50 |
if( !(((xmin[i]+fiducial)<t->x[i])*(t->x[i]<(xmax[i]-fiducial))) ) return kFALSE; |
51 |
if( !(((ymin[i]+fiducial)<t->y[i])*(t->y[i]<(ymax[i]-fiducial))) ) return kFALSE; |
52 |
//cout<<"XMIN:"<<xmin[i] |
53 |
//<<" XMAX:"<<xmax[i] |
54 |
//<<" YMIN:"<<ymin[i] |
55 |
//<<" YMAX:"<<ymax[i] |
56 |
//<<" Z:"<<TrkParams::zGF[i]<<endl; |
57 |
} |
58 |
//t->Dump(); |
59 |
|
60 |
return kTRUE; |
61 |
} |
62 |
|
63 |
|
64 |
|
65 |
void DoHistogramFromGraph(TGraph* g, TH1F* htemplate, Double_t factor){ |
66 |
//TH1F* hout = (TH1F*) htemplate->Clone(name); |
67 |
htemplate->Reset(); |
68 |
int n = htemplate->GetNbinsX(); |
69 |
for(int bin=1; bin<=n; bin++) { |
70 |
htemplate->SetBinContent(bin, g->Eval(htemplate->GetBinCenter(bin))*factor); |
71 |
Double_t *gx = g->GetX(); |
72 |
int p = 0; |
73 |
Double_t x = htemplate->GetBinCenter(bin); |
74 |
for(p=1; p<g->GetN(); p++) |
75 |
if((gx[p-1] <= x) && (gx[p] > x)) break; |
76 |
Double_t gey = g->GetErrorY(p-1)*factor; |
77 |
//cout<<"gx: "<< hout->GetBinCenter(bin)<<"gy: "<<hout->GetBinContent(bin)<<endl; |
78 |
htemplate->SetBinError(bin, gey); |
79 |
//cout<<"gx: "<< htemplate->GetBinCenter(bin)<<"gy: "<<htemplate->GetBinContent(bin)<<endl; |
80 |
} |
81 |
} |
82 |
|
83 |
void BinLogX(TH1*h){ |
84 |
// |
85 |
// Modify histogram h to create an histogram logarithmically binned |
86 |
// along the X axis. It works on normally defined, not |
87 |
// filled,histograms. |
88 |
// |
89 |
TAxis *axis = h->GetXaxis(); |
90 |
int bins = axis->GetNbins(); |
91 |
|
92 |
Axis_t xmin = axis->GetXmin(); |
93 |
Axis_t xmax = axis->GetXmax(); |
94 |
|
95 |
if (xmin==0) |
96 |
{ |
97 |
xmin = 1e-6; |
98 |
cout<<"Warning: low edge of histogram set from 0 to 1e-6"<<endl; |
99 |
} |
100 |
Axis_t from = TMath::Log10(xmin); |
101 |
Axis_t to = TMath::Log10(xmax); |
102 |
|
103 |
// Axis_t width = (xmax - xmin) / bins; |
104 |
Axis_t width = (to - from) / bins; |
105 |
Axis_t *new_bins = new Axis_t[bins + 1]; |
106 |
|
107 |
for (int i = 0; i <= bins; i++) { |
108 |
new_bins[i] = TMath::Power(10, from + i * width); |
109 |
} |
110 |
axis->Set(bins, new_bins); |
111 |
delete new_bins; |
112 |
} |
113 |
|
114 |
|
115 |
int main(int argc, char * argv[] ){ |
116 |
TStopwatch timer; |
117 |
timer.Start(); |
118 |
|
119 |
TString DataPATH = gSystem->Getenv("PWD"); |
120 |
|
121 |
|
122 |
TString inputfilename, outputfilename; |
123 |
TFile* rfin = 0; |
124 |
TFile* rfout = 0; |
125 |
TTree* primaries = 0; |
126 |
PrimaryInfo *p = 0; |
127 |
Double_t fiducial, Z, Rmin, Rmax, R; |
128 |
Int_t PDG; |
129 |
fiducial=Z=Rmin=Rmax=R=0.; |
130 |
Int_t nev; |
131 |
TF1 *frigflat = 0; |
132 |
TH1F * flux = new TH1F("flux", "flux", 2000, 0.4, 1000.); |
133 |
|
134 |
enum mode {SPECTRA, FLATBIN, SINGLEPOINT}; |
135 |
mode md; |
136 |
|
137 |
TString innf(argv[5]); |
138 |
switch(argc){ |
139 |
case 7: |
140 |
if(innf.Contains(".root")) md = SPECTRA; else md = SINGLEPOINT; |
141 |
break; |
142 |
case 8: |
143 |
md = FLATBIN; |
144 |
break; |
145 |
default: |
146 |
Usage(); |
147 |
return 0; |
148 |
break; |
149 |
} |
150 |
|
151 |
nev = atoi(argv[1]); |
152 |
Z = atof(argv[2]); |
153 |
PDG = atoi(argv[3]); |
154 |
fiducial = atof(argv[4]); |
155 |
|
156 |
|
157 |
TSystemDirectory *workdir = 0; |
158 |
|
159 |
switch(md){ |
160 |
case SPECTRA: |
161 |
inputfilename = TString(argv[5]); |
162 |
outputfilename = TString(argv[6]); |
163 |
workdir=new TSystemDirectory("workdir",DataPATH); |
164 |
rfin = new TFile(inputfilename); |
165 |
if (rfin){ |
166 |
cout<<"Generating spectra from file: "<<inputfilename<<endl; |
167 |
//Taking RIGIDITY p.d.f. |
168 |
|
169 |
// TList * outlist = (TList*)rfin->Get("outlist"); |
170 |
//flux = (TH1F*)outlist->At(5); //CHANGE THIS IF NEED |
171 |
TGraphAsymmErrors *gr1 = (TGraphAsymmErrors*)rfin->Get("gflux"); |
172 |
//TH1F * temp = new TH1F("template", "template", 40, 0.4, 250.); |
173 |
BinLogX(flux); |
174 |
DoHistogramFromGraph(gr1, flux, 100000.); |
175 |
rfin->Close(); |
176 |
//cout<<"test"<<flux->GetBinCenter(10)<<endl; |
177 |
} |
178 |
break; |
179 |
case FLATBIN: |
180 |
Rmin = atof(argv[5]); |
181 |
Rmax = atof(argv[6]); |
182 |
if (Rmin == Rmax) cout<<"ERROR: Rmin = Rmax"<<endl; |
183 |
frigflat = new TF1("fmom","1",Rmin,Rmax); |
184 |
outputfilename = TString(argv[7]); |
185 |
cout<<"Generating flat spectra, Rmin="<<Rmin<<" GV,"<<" Rmax="<<Rmax<<" GV"<<endl; |
186 |
break; |
187 |
case SINGLEPOINT: |
188 |
R = atof(argv[5]); |
189 |
outputfilename = TString(argv[6]); |
190 |
cout<<"Generating fixed rigidity, R="<<R<<" GV"<<endl; |
191 |
break; |
192 |
default: |
193 |
break; |
194 |
} |
195 |
|
196 |
//Creating output root-file |
197 |
rfout = new TFile(outputfilename.Data(),"recreate"); |
198 |
primaries = new TTree("primaries","primaries"); |
199 |
TTree::SetMaxTreeSize(1000*Long64_t(2000000000)); |
200 |
p = new PrimaryInfo(); |
201 |
if(!primaries->GetBranch("PRIM")) |
202 |
primaries ->Branch("PRIM","PrimaryInfo", &p,32000,99); |
203 |
else |
204 |
primaries->GetBranch("PRIM")->SetAddress(&p); |
205 |
|
206 |
|
207 |
|
208 |
|
209 |
//Loading field, Initialization |
210 |
|
211 |
TRandom3 *ran = new TRandom3(0); |
212 |
TF1 *ftheta = new TF1("ftheta","sin(x)*cos(x)",0.,acos(-1.)/4.); |
213 |
ftheta->SetNpx(99999); |
214 |
|
215 |
cout<<"Load Magnetic Field... "<<endl; |
216 |
TrkTrack *track = new TrkTrack(); |
217 |
track->LoadField(getenv("PAM_FIELD")); |
218 |
track->SetTrackingMode(0); |
219 |
cout<<"Magnetic Field Loaded. "<<endl; |
220 |
|
221 |
//Start |
222 |
|
223 |
cout<<"Nevents: "<<nev<<", FIDUCIAL: "<<fiducial<<" (cm), Z:"<<Z<<", PDG:"<<PDG<<endl; |
224 |
|
225 |
#define ZCAL 13.05 //cm |
226 |
#define CALS3 10.639 //cm |
227 |
#define ZSPEBP 2.97 //cm |
228 |
#define HORMG 22.57 //cm |
229 |
|
230 |
|
231 |
#define XMINGEN -30. |
232 |
#define XMAXGEN 30. |
233 |
#define YMINGEN -30. |
234 |
#define YMAXGEN 30. |
235 |
#define ZINP 110. |
236 |
|
237 |
setprecision(8); |
238 |
|
239 |
float *xmin = TrkParams::xGF_min; |
240 |
float *xmax = TrkParams::xGF_max; |
241 |
float *ymin = TrkParams::yGF_min; |
242 |
float *ymax = TrkParams::yGF_max; |
243 |
|
244 |
Float_t zin[TrkParams::nGF]; |
245 |
for (Int_t igf=0; igf<TrkParams::nGF; igf++) zin[igf]=TrkParams::zGF[igf]; |
246 |
Trajectory* t = new Trajectory(TrkParams::nGF,zin); |
247 |
Float_t al[5]; |
248 |
|
249 |
//Main LOOP |
250 |
|
251 |
Int_t goodev = 0; |
252 |
Int_t totev = 0; |
253 |
Double_t mom = 0.; |
254 |
Double_t x,y,z,theta,phi; |
255 |
while (goodev<nev){ |
256 |
x = ran->Uniform(XMINGEN, XMAXGEN); |
257 |
y = ran->Uniform(YMINGEN, YMAXGEN); |
258 |
z = ZINP-ZCAL-CALS3-ZSPEBP-HORMG; |
259 |
theta = ftheta->GetRandom(); |
260 |
phi = ran->Uniform(0.,2.*acos(-1.)); |
261 |
|
262 |
switch(md){ |
263 |
case SPECTRA: |
264 |
mom = Z*flux->GetRandom(); |
265 |
break; |
266 |
case FLATBIN: |
267 |
mom = Z*frigflat->GetRandom(); |
268 |
break; |
269 |
case SINGLEPOINT: |
270 |
mom = Z*R; |
271 |
break; |
272 |
default: |
273 |
break; |
274 |
} |
275 |
|
276 |
al[0] = x; |
277 |
al[1] = y; |
278 |
al[2] = sin(theta); |
279 |
al[3] = phi; |
280 |
al[4] = Z/mom; |
281 |
|
282 |
t->DoTrack(al, z); |
283 |
|
284 |
if(IsInside(t,fiducial, xmin, xmax, ymin, ymax)){ |
285 |
p->X0 = x; |
286 |
p->Y0 = y; |
287 |
p->Z0 = ZINP; |
288 |
p->Theta = theta; |
289 |
p->Phi = phi; |
290 |
p->P0 = mom; |
291 |
p->PDG=PDG; //He-4 |
292 |
primaries->Fill(); |
293 |
goodev++; |
294 |
} |
295 |
totev++; |
296 |
if( ((totev%10000)==0) || (goodev==nev) ) cout<<"-> "<<totev<<" "<<goodev<<endl; |
297 |
} |
298 |
primaries->Write(); |
299 |
if(md==SPECTRA) flux->Write(); |
300 |
rfout->Close(); |
301 |
|
302 |
Double_t gf = Double_t(goodev)/Double_t(totev)*(XMAXGEN-XMINGEN)*(YMAXGEN-YMINGEN)*TMath::Pi()/2.; |
303 |
Double_t err_gf = (Double_t)1./TMath::Sqrt(goodev)*gf; |
304 |
cout<<"GF="<<gf<<" +- "<<err_gf<<endl; |
305 |
|
306 |
//delete primaries; |
307 |
delete p; |
308 |
delete ran; |
309 |
delete ftheta; |
310 |
delete track; |
311 |
delete t; |
312 |
return 0; |
313 |
} |
314 |
|
315 |
void Usage(){ |
316 |
cout<<"NAME"<<endl; |
317 |
cout<<" sp_sen - spectra generator"<<endl; |
318 |
cout<<"SYNOPSIS"<<endl; |
319 |
cout<<" sp_gen NUMPAR Z PDG FIDUCIAL(cm) RIGIDITY(GV) OUTFILE"<<endl; |
320 |
cout<<" sp_gen NUMPAR Z PDG FIDUCIAL(cm) RIGMIN(GV) RIGMAX(GV) OUTFILE"<<endl; |
321 |
cout<<" sp_gen NUMPAR Z PDG FIDUCIAL(cm) INPUTFILE OUTFILE"<<endl; |
322 |
cout<<"DISCRIPTION"<<endl; |
323 |
cout<<" Generate tracks above the apparatus "<<endl; |
324 |
cout<<" isotropically and save initial kinematic parameters (X0,Y0,Z0=110., P, Theta, Phi)"<<endl; |
325 |
cout<<" good tracks in output root-file. After this, file could be used to do simulations."<<endl; |
326 |
cout<<" The condition to accept tracks is satisfaction to 14 acceptance planes, defined by"<<endl; |
327 |
cout<<" TrkParams in Level2. This tool is based on DoTrack method of Level2. "<<endl; |
328 |
cout<<" To save data in root-file PrimaryInfo class was developed and compiled in library. "<<endl; |
329 |
cout<<" If later you wish to develop your own script to work with data stored threre, "<<endl; |
330 |
cout<<" you need just load libPrimaryInfo.so shared library"<<endl; |
331 |
cout<<"NOTE"<<endl; |
332 |
cout<<" Use http://pdg.lbl.gov/2007/reviews/montecarlorpp.pdf document to define your"<<endl; |
333 |
cout<<" particle according PDG numeration scheme."<<endl; |
334 |
} |