Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | f9daq | 1 | /* |
2 | |||
3 | vhodne datoteke: |
||
4 | |||
5 | Mappingi: |
||
6 | m16.map channel mapping |
||
7 | modules.map mapping modulov |
||
8 | |||
9 | Kalibracija: |
||
10 | pedestals.dat ... adc suma |
||
11 | ph511.dat ... adc fotovrhov vrhov |
||
12 | |||
13 | |||
14 | // sumpedestals.dat vsota adc po modulih |
||
15 | |||
16 | ./readdata -c config.xml -i input.dat -o output -n nevents -w writentuple -d debuglevel |
||
17 | |||
18 | */ |
||
19 | #include <stdlib.h> |
||
20 | #include <stdio.h> |
||
21 | #include "TNtuple.h" |
||
22 | #include "TH1F.h" |
||
23 | #include "TH2F.h" |
||
24 | #include "TF1.h" |
||
25 | #include "TCanvas.h" |
||
26 | #include "TStyle.h" |
||
27 | #include "TFile.h" |
||
28 | #include "TMath.h" |
||
29 | #include "TRandom3.h" |
||
30 | #include <zlib.h> |
||
31 | #include <iostream> |
||
32 | #include <fstream> |
||
33 | |||
34 | |||
35 | #include <stdlib.h> |
||
36 | #include <stdio.h> |
||
37 | #include <string.h> |
||
38 | #include <assert.h> |
||
39 | #include <vector> |
||
40 | |||
41 | #include <libxml/tree.h> |
||
42 | #include <libxml/parser.h> |
||
43 | #include <libxml/xpath.h> |
||
44 | #include <libxml/xpathInternals.h> |
||
45 | |||
46 | #include "PETProjDataMgr.h" |
||
47 | |||
48 | |||
49 | // en krog je 4790 korakov |
||
50 | #define NSTEPS 4790 |
||
51 | // nt->Draw("px1/max1:py1/max1>>hmy(200,-1,4,200,-1,4)","max1>500","colz") |
||
52 | //#define MAXCH 64 |
||
53 | #define MAXCH 72 |
||
54 | |||
55 | |||
56 | #define RUNREC_ID 1 |
||
57 | #define EVTREC_ID 2 |
||
58 | #define POSREC_ID 3 |
||
59 | |||
60 | typedef struct { |
||
61 | unsigned int num_events,num_channels,pedestal,xy; |
||
62 | int nx,x0,dx,ny,y0,dy; |
||
63 | } RUNREC; |
||
64 | RUNREC *runrec; // start header: appears once at the start of the file |
||
65 | |||
66 | typedef struct { |
||
67 | int mikro_pos_x,set_pos_x; |
||
68 | int num_iter_y,mikro_pos_y,set_pos_y; |
||
69 | } POSREC; |
||
70 | POSREC *posrec; // position header: appears at every change of position |
||
71 | |||
72 | class Channel { |
||
73 | public: |
||
74 | Channel(){}; |
||
75 | ~Channel(){}; |
||
76 | int ix; |
||
77 | int iy; |
||
78 | int idx; |
||
79 | void SetIxIy(int a,int b){ix=a;iy=b;idx=ix+4*iy;}; |
||
80 | }; |
||
81 | |||
82 | class Module { |
||
83 | public: |
||
84 | Module(){}; |
||
85 | ~Module(){}; |
||
86 | double r; |
||
87 | double phi; |
||
88 | void SetRPhi(double rr, double pphi){r=rr;phi=pphi*TMath::Pi()/180.;}; |
||
89 | }; |
||
90 | |||
91 | class Geometry { |
||
92 | |||
93 | public: |
||
94 | |||
95 | |||
96 | ~Geometry(){ m_calibration->Close(); }; |
||
97 | Channel ch[16]; |
||
98 | Module module[4]; |
||
99 | |||
100 | |||
101 | TRandom3 *m_rnd; // random generator |
||
102 | TH1I *m_crystalid[4];// kalibracijski histogrami |
||
103 | char * m_modulesmapName; // ime datoteke s podatki o pozicijah modulov |
||
104 | char * m_channelsmapName; // ime datoteke s podatki o pozicijah elektronskih kanalov |
||
105 | //char * m_sumpedestalsName; |
||
106 | char * m_pedestalsName; // ime datoteke s podatki o pedestalih |
||
107 | char * m_photopeakName; // ime datoteke s podatki o vrhovih |
||
108 | char * m_calibrationrootName; // ime datoteke s kalibracijskimi histogrami |
||
109 | TFile *m_calibration; // datoteke s kalibracijskimi histogrami |
||
110 | |||
111 | double m_dx; // pitch x kristalov |
||
112 | double m_dy; // pitch y kristalov |
||
113 | int m_nx; // stevilo kristalov v x smeri |
||
114 | int m_ny; // stevilo kristalov v y smeri |
||
115 | |||
116 | float gPedestals[MAXCH]; |
||
117 | float gPeak[MAXCH]; |
||
118 | |||
119 | //float gSumPedestals[MAXCH]; |
||
120 | double m_peakscaling; // scaling za adcje |
||
121 | double m_threshold; // threshold za upostevanje zadetkov na kanalih |
||
122 | int m_debug; |
||
123 | |||
124 | |||
125 | //--------------------------------------------------- |
||
126 | int SetThreshold(int threshold){ |
||
127 | m_threshold=threshold; |
||
128 | return 0; |
||
129 | }; |
||
130 | double GetThreshold(){ |
||
131 | return m_threshold; |
||
132 | } |
||
133 | |||
134 | |||
135 | int readfile(const char *fname, float *x, int nmax, int defaultvalue=0){ |
||
136 | int id; |
||
137 | float ix; |
||
138 | std::ifstream f(fname); |
||
139 | if (f.is_open()){ |
||
140 | std::cout << "Reading ... " << fname << std::endl; |
||
141 | while (f.good()){ |
||
142 | f >> id >> ix; |
||
143 | if (id<nmax) x[id]=ix; |
||
144 | if (m_debug) std::cout << fname << " " << id << " " << ix <<" "<< std::endl; |
||
145 | } |
||
146 | f.close(); |
||
147 | } else { |
||
148 | std::cout << "Cannot read " << fname << std::endl; |
||
149 | std::cout << "Default value will be used :" << defaultvalue << std::endl; |
||
150 | for (int i=0;i<nmax;i++){ |
||
151 | x[i]=defaultvalue; |
||
152 | } |
||
153 | } |
||
154 | return 0; |
||
155 | }; |
||
156 | |||
157 | void ReadChannelMap(const char *fname){ |
||
158 | int id,ix,iy; |
||
159 | char line[400]; |
||
160 | std::ifstream f(fname); |
||
161 | if (f.is_open()){ |
||
162 | std::cout << "Reading ... " << fname << std::endl; |
||
163 | f.getline(line,400); |
||
164 | while (f.good()){ |
||
165 | f >> id >> ix >> iy; |
||
166 | if (id<16) ch[id].SetIxIy(ix,iy); |
||
167 | if (m_debug) std::cout << fname << " " << id << " " << ix <<" "<< iy << std::endl; |
||
168 | } |
||
169 | f.close(); |
||
170 | } else { |
||
171 | std::cout << "Cannot read " << fname << std::endl; |
||
172 | } |
||
173 | |||
174 | }; |
||
175 | |||
176 | void ReadModuleMap(const char *fname){ |
||
177 | int id; |
||
178 | double r,phi; |
||
179 | char line[400]; |
||
180 | std::ifstream f(fname); |
||
181 | if (f.is_open()){ |
||
182 | std::cout << "Reading ... " << fname << std::endl; |
||
183 | f.getline(line,400); |
||
184 | while (f.good()){ |
||
185 | f >> id >> r >> phi; |
||
186 | if (id<4) module[id].SetRPhi(r,phi); |
||
187 | if (m_debug) std::cout << fname << " " << id << " " << r <<" "<< phi << std::endl; |
||
188 | } |
||
189 | f.close(); |
||
190 | } else { |
||
191 | std::cout << "Cannot read " << fname << std::endl; |
||
192 | } |
||
193 | |||
194 | }; |
||
195 | |||
196 | int getvalue(xmlXPathContextPtr xpathCtx, const char* xpathExpr, std::vector<xmlChar *> &retval) { |
||
197 | |||
198 | xmlXPathObjectPtr xpathObj; |
||
199 | xmlNodeSetPtr nodes; |
||
200 | xmlChar * ret=NULL; |
||
201 | int size; |
||
202 | int i; |
||
203 | assert(xpathExpr); |
||
204 | /* Evaluate xpath expression */ |
||
205 | xpathObj = xmlXPathEvalExpression(BAD_CAST xpathExpr, xpathCtx); |
||
206 | if(xpathObj == NULL) { |
||
207 | fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr); |
||
208 | return retval.size(); |
||
209 | } |
||
210 | |||
211 | nodes = xpathObj->nodesetval; |
||
212 | size = (nodes) ? nodes->nodeNr : 0; |
||
213 | for(i = 0; i< size; i++) { |
||
214 | ret = xmlNodeGetContent(nodes->nodeTab[i]); |
||
215 | if(ret) { |
||
216 | retval.push_back(ret); |
||
217 | printf("[%d] %s Return value: %s\n", i, xpathExpr, ret); |
||
218 | } |
||
219 | } |
||
220 | |||
221 | /* Cleanup of XPath data */ |
||
222 | xmlXPathFreeObject(xpathObj); |
||
223 | |||
224 | return retval.size(); |
||
225 | } |
||
226 | |||
227 | char * getvalue(xmlXPathContextPtr xpathCtx, const char* xpathExpr, int which) { |
||
228 | |||
229 | xmlXPathObjectPtr xpathObj; |
||
230 | xmlNodeSetPtr nodes; |
||
231 | xmlChar * ret=NULL; |
||
232 | int size; |
||
233 | int i; |
||
234 | assert(xpathExpr); |
||
235 | |||
236 | xpathObj = xmlXPathEvalExpression(BAD_CAST xpathExpr, xpathCtx); |
||
237 | if(xpathObj == NULL) { |
||
238 | fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr); |
||
239 | return NULL; |
||
240 | } |
||
241 | |||
242 | nodes = xpathObj->nodesetval; |
||
243 | size = (nodes) ? nodes->nodeNr : 0; |
||
244 | for(i = 0; i< size; i++) { |
||
245 | ret = xmlNodeGetContent(nodes->nodeTab[i]); |
||
246 | if(ret) { |
||
247 | printf("%s=%s\n", xpathExpr, ret); |
||
248 | if (which == i) break; |
||
249 | } |
||
250 | } |
||
251 | |||
252 | xmlXPathFreeObject(xpathObj); |
||
253 | return (char *) ret; |
||
254 | |||
255 | } |
||
256 | |||
257 | int readxmlconfig(const char *fname){ |
||
258 | xmlInitParser(); |
||
259 | LIBXML_TEST_VERSION |
||
260 | |||
261 | /* Load XML document */ |
||
262 | xmlDocPtr doc = xmlParseFile(fname); |
||
263 | if (doc == NULL) { |
||
264 | fprintf(stderr, "Error: unable to parse file \"%s\"\n", fname); |
||
265 | return(-1); |
||
266 | } else { |
||
267 | std::cout << "Reading ... " << fname << std::endl; |
||
268 | } |
||
269 | |||
270 | /* Create xpath evaluation context */ |
||
271 | xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc); |
||
272 | if(xpathCtx == NULL) { |
||
273 | fprintf(stderr,"Error: unable to create new XPath context\n"); |
||
274 | xmlFreeDoc(doc); |
||
275 | return(-1); |
||
276 | } |
||
277 | |||
278 | m_pedestalsName = getvalue(xpathCtx, "//pedestals" , 0); |
||
279 | //m_sumpedestalsName = getvalue(xpathCtx, "//sumpedestals", 0); |
||
280 | m_photopeakName = getvalue(xpathCtx, "//photopeak" , 0); |
||
281 | m_modulesmapName = getvalue(xpathCtx, "//modules" , 0); |
||
282 | m_channelsmapName = getvalue(xpathCtx, "//channels" , 0); |
||
283 | m_calibrationrootName = getvalue(xpathCtx, "//channelcalibration", 0); |
||
284 | m_threshold = atoi(getvalue(xpathCtx, "//adcthreshold", 0)); |
||
285 | m_nx = atoi(getvalue(xpathCtx, "//nofcrystalsx", 0)); |
||
286 | m_ny = atoi(getvalue(xpathCtx, "//nofcrystalsx", 0)); |
||
287 | m_dx = atof(getvalue(xpathCtx, "//crystalpitchx", 0)); |
||
288 | m_dy = atof(getvalue(xpathCtx, "//crystalpitchy", 0)); |
||
289 | |||
290 | xmlXPathFreeContext(xpathCtx); |
||
291 | xmlFreeDoc(doc); |
||
292 | xmlCleanupParser(); |
||
293 | xmlMemoryDump(); |
||
294 | return 0; |
||
295 | }; |
||
296 | |||
297 | |||
298 | double GetEnergy(int ch, int adc){ |
||
299 | return (adc-gPedestals[ch])/(gPeak[ch]-gPedestals[ch])*m_peakscaling; |
||
300 | } |
||
301 | int GetRealPosition(int ipmt, float px,float py,float &cx,float &cy){ |
||
302 | // iz CoG izracuna pozicijo na kristalu |
||
303 | |||
304 | int binx = m_crystalid[ipmt]->GetXaxis()->FindBin(px); |
||
305 | int biny = m_crystalid[ipmt]->GetYaxis()->FindBin(py); |
||
306 | int crystalid = m_crystalid[ipmt]->GetBinContent(binx,biny); |
||
307 | cx= ( crystalid % m_nx - m_nx/2. + 0.5 ) * m_dx; |
||
308 | cy= ( crystalid / m_nx - m_ny/2. + 0.5 ) * m_dy; |
||
309 | |||
310 | |||
311 | // razmazi pozicijo po povrsini kristala |
||
312 | double rndx = (m_rnd->Rndm()-0.5) * m_dx; |
||
313 | double rndy = (m_rnd->Rndm()-0.5) * m_dy; |
||
314 | cx+= rndx; |
||
315 | cy+= rndy; |
||
316 | return crystalid; |
||
317 | } |
||
318 | |||
319 | TVector3 GetGlobalPosition(int ipmt, double angle, float cx, float cy){ |
||
320 | |||
321 | double phi = angle + module[ipmt].phi; |
||
322 | double &r = module[ipmt].r; |
||
323 | double sinphi = sin(phi); |
||
324 | double cosphi = cos(phi); |
||
325 | |||
326 | TVector3 rv( cosphi* r + sinphi * cx , sinphi* r - cosphi * cx, cy); |
||
327 | //if (m_debug) printf( "[%d] phi=%f %f global ( %f , %f , %f )\n" ,ipmt, module[ipmt].phi,angle, rv.x(), rv.y(), rv.z()); |
||
328 | return rv; |
||
329 | } |
||
330 | |||
331 | Geometry(const char *fnameconfig, int debug){ |
||
332 | m_debug = debug; |
||
333 | readxmlconfig(fnameconfig); |
||
334 | |||
335 | ReadModuleMap(m_modulesmapName); |
||
336 | ReadChannelMap(m_channelsmapName); |
||
337 | |||
338 | std::cout << "Reading ... " << m_calibrationrootName << std::endl; |
||
339 | m_calibration = new TFile(m_calibrationrootName); |
||
340 | for (int i=0; i<4;i++) { |
||
341 | char hn[256]; |
||
342 | sprintf(hn,"pmt1%d_calib",i); |
||
343 | m_crystalid[i]= (TH1I *) m_calibration->Get(hn); |
||
344 | m_crystalid[i]->ls(); |
||
345 | } |
||
346 | |||
347 | //readfile(m_sumpedestalsName ,gSumPedestals,4); |
||
348 | m_peakscaling=3000; |
||
349 | |||
350 | readfile(m_pedestalsName,gPedestals,4*16, 0); |
||
351 | readfile(m_photopeakName,gPeak,4*16, m_peakscaling); |
||
352 | |||
353 | m_rnd= new TRandom3(); |
||
354 | }; |
||
355 | |||
356 | }; |
||
357 | |||
358 | |||
359 | class readdata { |
||
360 | private: |
||
361 | |||
362 | TNtuple* gNtuple; |
||
363 | |||
364 | |||
365 | TH1F* m_Adc[MAXCH]; |
||
366 | TH1F* m_AdcCut[MAXCH]; |
||
367 | TH2F* m_Adc_vs_Nhits[MAXCH]; |
||
368 | TH2F* m_Adc_vs_Sum[MAXCH]; |
||
369 | TH2F* m_Adc_vs_Sum_Uncorected[MAXCH]; |
||
370 | TH2F* m_Nhits; |
||
371 | TH1F* m_AdcSum[6]; |
||
372 | TH2F* m_CenterOfGravity[6]; |
||
373 | TH2F* m_ReconstructedPosition[6]; |
||
374 | TH2F* m_CenterOfGravityforChAboveThreshold[6]; |
||
375 | TH2F* m_GlobalPosition; |
||
376 | TH1F* m_AdcSumCluster[6]; |
||
377 | TH2F* m_MaxAdc[4]; |
||
378 | TH2F* m_SumAdc[4]; |
||
379 | |||
380 | Geometry *m_geo; // pozicije modulov in kanalov |
||
381 | float gSum[6]; |
||
382 | float gRawSum[6]; |
||
383 | float gMax[6]; |
||
384 | float gSumCluster[6]; |
||
385 | float gNtdata[MAXCH*3]; |
||
386 | int gNabove[5]; |
||
387 | int m_neve; // number of events to process |
||
388 | |||
389 | public: |
||
390 | PETProjDataMgr *m_projector; // projektor za sinograme |
||
391 | |||
392 | double m_rotation; // trenutna rotacija setupa |
||
393 | double m_threshold; // |
||
394 | |||
395 | double gData[MAXCH]; // korigirani ADC ji |
||
396 | double gAdc[MAXCH]; // raw ADC ji |
||
397 | int m_debug; // debug izpisi |
||
398 | int m_write; // ce je ta flag nastavljen, se v root file izpisuje ntuple |
||
399 | int m_coincidences; // stevilo koincidenc |
||
400 | |||
401 | //--------------------------------------------------- |
||
402 | int Initialize(){ |
||
403 | |||
404 | if (m_write) { |
||
405 | char varlist[1024], tmplist[1024]; |
||
406 | sprintf( varlist,"sum0:sum1:sum2:sum3:nh0:nh1:nh2:nh3:c0:c1:c2:c3:px0:px1:px2:px3:py0:py1:py2:py3:rx0:rx1:rx2:rx3:ry0:ry1:ry2:ry3:max0:max1:max2:max3"); |
||
407 | for (int i=0;i<MAXCH;i++) { |
||
408 | sprintf(tmplist,"%s",varlist); |
||
409 | sprintf(varlist,"%s:a%d",tmplist,i); |
||
410 | } |
||
411 | /* |
||
412 | energija .. (adc -pedestal) * scaling |
||
413 | |||
414 | sum0 .. sum3 vsota energij po vseh kanalih fotopomnozevalke |
||
415 | nh0 .. nh4 stevilo zadetkov na fotopomnozevalki (adc nad thresholdom) |
||
416 | c0 .. c4 vsota energij za kanale nad thresholdom |
||
417 | px0 .. px4 x koordinata COG na fotopomnozevalki |
||
418 | py0 .. py4 y koordinata COG na fotopomnozevalki |
||
419 | max0 .. max3 maximalna energija na kanalu na fotopomnozevalki |
||
420 | a0 .. a63 energija na i-tem kanalu |
||
421 | */ |
||
422 | gNtuple = new TNtuple("nt","Pet RAW data",varlist); |
||
423 | printf ("#%s#\n",varlist); |
||
424 | } |
||
425 | m_Nhits = new TH2F("hnabove","Stevilo zadetkov nad nivojem diskriminacije",4,-0.5,3.5, 16,+0.5,16.5 ); // stevilo hitov nad thresholdom |
||
426 | m_GlobalPosition = new TH2F("globalxy","Rekonstruirana koordinata zadetka",200,-80,80,200,-80,80); // reconstruirana koordinata v globalnem sistemu |
||
427 | |||
428 | |||
429 | char hname[0xFF]; |
||
430 | char hn[0xFF]; |
||
431 | for (int i=0;i<MAXCH;i++){ |
||
432 | sprintf(hname,"Raw ADC Ch. %d ;ADC;N",i); |
||
433 | sprintf(hn,"ach%d",i); |
||
434 | m_Adc[i] = new TH1F(hn,hname,4000,-0.5,3999.5); // osnovni adcji |
||
435 | sprintf(hname,"cADC za dogodke z manj kot x hitov na pmtju Ch. %d ;ADC;N",i); |
||
436 | sprintf(hn,"cutch%d",i); |
||
437 | m_AdcCut[i] = new TH1F(hn,hname,4000,-0.5,3999.5); // adcji za zadetke z manj kot 7 hiti na PMTju |
||
438 | sprintf(hname,"cADC proti stevilu zadetkov na pmtju Ch. %d ;ADC;N",i); |
||
439 | sprintf(hn,"singlech%d",i); |
||
440 | m_Adc_vs_Nhits[i] = new TH2F(hn,hname,200,0,4000, 17,-0.5,16.5); // adc proti stevilu zadetkov na PMTju |
||
441 | sprintf(hname,"cADC proti vsoti kanalov na pmtju, Ch. %d ;ADC;ADCsum",i); |
||
442 | sprintf(hn,"corrch%d",i); |
||
443 | m_Adc_vs_Sum[i] = new TH2F(hn,hname,200,0,4000, 200,0,12000 ); // raw adc proti vsoti kanalov na PMTju |
||
444 | sprintf(hname,"Raw ADC proti vsoti kanalov na pmtju, Ch. %d ;ADC;ADCsum",i); |
||
445 | sprintf(hn,"adcvssumch%d",i); |
||
446 | m_Adc_vs_Sum_Uncorected[i] = new TH2F(hn,hname,100,0,3500, 100,5000,12000 ); // adc proti vsoti kanalov na PMTju |
||
447 | } |
||
448 | |||
449 | for (int i=0;i<4;i++) { |
||
450 | sprintf(hname,"Vsota cADC na PMTju %d ;ADC;N",i); |
||
451 | sprintf(hn,"pmt%d",i); |
||
452 | m_AdcSum[i] = new TH1F(hn,hname,200,0,20000); // vsota adcjev na PMTju |
||
453 | sprintf(hname,"Vsota cADC na PMTju za dogodke z manj kot x zadetki %d ;ADC;N",i); |
||
454 | sprintf(hn,"clusterpmt%d",i); |
||
455 | m_AdcSumCluster[i] = new TH1F(hn,hname,200,0,20000); // vsota adcjev na pmtju, ki so nad threshholdom, za dogodke z manj kot 5 zadetki na PMTju |
||
456 | |||
457 | sprintf(hname,"Center naboja CoG PMT %d ;x;y",i); |
||
458 | sprintf(hn,"pmt1%d",i); |
||
459 | m_CenterOfGravity[i] = new TH2F(hn,hname,200,-0.25,3.25,200,-0.25,3.25); // center naboja na PMTju |
||
460 | |||
461 | sprintf(hname,"Center naboja CoG za zadetke nbad thresholdom PMT %d ;x;y",i); |
||
462 | sprintf(hn,"pmt2%d",i); |
||
463 | m_CenterOfGravityforChAboveThreshold[i] = new TH2F(hn,hname,200,0,3,200,0,3); // center naboja za zadetke nad thresholdom |
||
464 | |||
465 | sprintf(hname,"Rekonstruirana koordinata PMT %d ;x(mm);y(mm)",i); |
||
466 | sprintf(hn,"pmt3%d",i); |
||
467 | m_ReconstructedPosition[i] = new TH2F(hn,hname,200,-12,12,200,-12,12); // korigirana koordinata na pmtju |
||
468 | |||
469 | sprintf(hname,"SumAdc PMT %d ;SumAdc(a.u.);crystal ID",i); |
||
470 | sprintf(hn,"sumadc%d",i); |
||
471 | m_SumAdc[i] = new TH2F(hn,hname,200,0,12000,81,-0.5,80.5); // SumADC spekter za razlicne kristale |
||
472 | } |
||
473 | |||
474 | // store mapping |
||
475 | TH1I *hx= new TH1I("mapping", "ch mapping", 16, -0.5,15.5); |
||
476 | for (int j=0;j<16;j++) hx->Fill(j,m_geo->ch[j].idx); |
||
477 | |||
478 | return 0; |
||
479 | }; |
||
480 | |||
481 | int FillHistograms(){ |
||
482 | for (int i=0;i<MAXCH;i++) { // zanka cez vse elektronske kanale; |
||
483 | float x=gData[i]; |
||
484 | int ipmt= i/16; |
||
485 | float s=gSum[ipmt]; |
||
486 | // int idx= 2*(ipmt)+64; |
||
487 | // const float fSlope1=2; |
||
488 | // const float fSlope2=3; |
||
489 | // if ( ((s-gSumPedestals[ipmt] ) > fSlope1*(x-gPedestals[i])) && ((s-gSumPedestals[ipmt] ) < fSlope2*(x-gPedestals[ipmt])) ) { |
||
490 | if (gNabove[ipmt]<7){ |
||
491 | m_Adc_vs_Sum[i]->Fill(x,s); |
||
492 | m_Adc_vs_Sum_Uncorected[i]->Fill(gAdc[i],gRawSum[ipmt]); |
||
493 | m_AdcCut[i]->Fill(x); |
||
494 | } |
||
495 | } |
||
496 | |||
497 | TVector3 r_coincidence[2]; |
||
498 | int f_coincidence[2]={0,0}; |
||
499 | |||
500 | for (int ipmt=0;ipmt<4;ipmt++){ // zanka preko pmtjev |
||
501 | int j2= (ipmt/2)*2+1-ipmt%2; // sosednja fotopomnozevalka |
||
502 | |||
503 | float posx[2]={0,0}; |
||
504 | float posy[2]={0,0}; |
||
505 | float sum[2]={0,0}; |
||
506 | for (int ich=0;ich<16;ich++){ // zanka preko elektronskih kanalov na fotopomnozevalki |
||
507 | int ch= ich+ipmt*16; |
||
508 | if (gMax[ipmt]>m_threshold) { |
||
509 | posx[0]+= gData[ch]*m_geo->ch[ich].ix; |
||
510 | posy[0]+= gData[ch]*m_geo->ch[ich].iy; |
||
511 | sum[0] += gData[ch]; |
||
512 | |||
513 | if (gData[ch]> 0.2*gMax[ipmt]){ // pri racunanju pozicije upostevaj le kanale, ki imajo vrednost vecjo od ratio*maksimalna na tisti fotopomnozevalki |
||
514 | posx[1]+= gData[ch]*m_geo->ch[ich].ix; |
||
515 | posy[1]+= gData[ch]*m_geo->ch[ich].iy; |
||
516 | sum[1] += gData[ch]; |
||
517 | } |
||
518 | } |
||
519 | } |
||
520 | |||
521 | if (m_write) { |
||
522 | gNtdata[12+ipmt]=posx[0]/sum[0]; |
||
523 | gNtdata[16+ipmt]=posy[0]/sum[0]; |
||
524 | gNtdata[20+ipmt]=(sum[1]>0)?posx[1]/sum[1]:-10; |
||
525 | gNtdata[24+ipmt]=(sum[1]>0)?posy[1]/sum[1]:-10; |
||
526 | gNtdata[28+ipmt]=sum[0]; |
||
527 | } |
||
528 | if (gMax[ipmt]>gMax[j2]){ // izberi fotopomnozevalko, ki ima vec zadetkov kot soseda TRG= (P1|P2) & (P3|P4) |
||
529 | |||
530 | if ( sum[0] > 0 ) { |
||
531 | float px=posx[0]/sum[0]; |
||
532 | float py=posy[0]/sum[0]; |
||
533 | |||
534 | m_CenterOfGravity[ipmt]->Fill(px,py); |
||
535 | |||
536 | float cx=0; //koordinata na pmtju |
||
537 | float cy=0; |
||
538 | int crystalID = m_geo->GetRealPosition(ipmt,px,py,cx,cy); |
||
539 | m_ReconstructedPosition[ipmt]->Fill(cx,cy); |
||
540 | m_SumAdc[ipmt]->Fill(gSum[ipmt], crystalID ); |
||
541 | if (m_debug > 2) printf("ipmt=%d cx=%f cy=%f\n",ipmt,cx,cy); |
||
542 | r_coincidence[ipmt/2] = m_geo->GetGlobalPosition(ipmt, m_rotation, cx, cy) ; |
||
543 | f_coincidence[ipmt/2] =1; |
||
544 | m_GlobalPosition->Fill( r_coincidence[ipmt/2].x(),r_coincidence[ipmt/2].y()); |
||
545 | |||
546 | } |
||
547 | if ( sum[1] > 0 ) { |
||
548 | |||
549 | float px=posx[1]/sum[1]; |
||
550 | float py=posy[1]/sum[1]; |
||
551 | m_CenterOfGravityforChAboveThreshold[ipmt]->Fill(px,py); |
||
552 | } |
||
553 | |||
554 | } |
||
555 | } |
||
556 | |||
557 | for (int i=0;i<MAXCH;i++) if (gData[i]>m_threshold) { m_Adc_vs_Nhits[i]->Fill(gData[i],gNabove[i/16]); } |
||
558 | for (int i=0;i<MAXCH;i++) if (gData[i]>m_threshold && gNabove[i/16]<5 ) { gSumCluster[i/16]+=gData[i]; } |
||
559 | for (int ipmt=0;ipmt<4;ipmt++) { |
||
560 | m_AdcSum[ipmt]->Fill(gSum[ipmt]); |
||
561 | m_AdcSumCluster[ipmt]->Fill(gSumCluster[ipmt]); |
||
562 | } |
||
563 | |||
564 | for (int i=0;i<4;i++) m_Nhits->Fill(i,gNabove[i]); |
||
565 | |||
566 | if (m_write) { |
||
567 | for (int i=0;i<4;i++) gNtdata[i]=gSum[i]; |
||
568 | for (int i=0;i<4;i++) gNtdata[4+i]=gNabove[i]; |
||
569 | for (int i=0;i<4;i++) gNtdata[8+i]=gSumCluster[i]; |
||
570 | for (int i=0;i<MAXCH;i++) gNtdata[32+i]=gData[i]; |
||
571 | gNtuple->Fill(gNtdata); |
||
572 | } |
||
573 | // |
||
574 | // coincidences |
||
575 | // |
||
576 | if (f_coincidence[0]&&f_coincidence[1]){ |
||
577 | m_coincidences++; |
||
578 | if (m_debug > 1) { |
||
579 | printf( "Coincidence ( %f , %f , %f ) ( %f , %f , %f )\n" , |
||
580 | r_coincidence[0].x(), r_coincidence[0].y(), r_coincidence[0].z(), |
||
581 | r_coincidence[1].x(), r_coincidence[1].y(), r_coincidence[1].z() ); |
||
582 | } |
||
583 | m_projector->AddEvent( r_coincidence[0] , r_coincidence[1]); |
||
584 | } |
||
585 | return 0; |
||
586 | }; |
||
587 | |||
588 | |||
589 | int Process( const char *fnamein, int nevetoprocess){ |
||
590 | gzFile fp=gzopen(fnamein,"r"); |
||
591 | printf("Process....\n"); |
||
592 | if (!fp) { |
||
593 | printf("File %s cannot be opened!\n", fnamein); |
||
594 | return 0; |
||
595 | } else { |
||
596 | printf("Processing file %s\n", fnamein); |
||
597 | } |
||
598 | const int bsize=20000; |
||
599 | |||
600 | unsigned int *buf = new unsigned int[bsize]; |
||
601 | int nr=0; |
||
602 | int hdr[4]; |
||
603 | |||
604 | int nread=0; |
||
605 | while (!gzeof(fp) ){ |
||
606 | int nitems = gzread(fp,hdr, sizeof(int)*4 ); |
||
607 | if (nitems !=4*sizeof(int)) break; |
||
608 | int recid = hdr[0]; |
||
609 | int nb = hdr[1] - 4*sizeof(int); |
||
610 | if ( nb > bsize) { |
||
611 | nb=bsize; |
||
612 | printf ("Error bsize %d nb=%d\n",bsize,nb); |
||
613 | } |
||
614 | // int nint = nb/sizeof(int); |
||
615 | int n=hdr[3]; |
||
616 | nitems=gzread(fp, buf, nb); |
||
617 | nr++; |
||
618 | if (nitems!=nb){ printf("Read Error nb=%d nitems=%d\n",nb,nitems); continue; } |
||
619 | |||
620 | switch (recid){ |
||
621 | case RUNREC_ID: |
||
622 | runrec=(RUNREC *) (&buf[0]); |
||
623 | printf("RUNREC RECID = %u\n",hdr[0]); |
||
624 | printf("RUNREC Length = %u\n",hdr[1]); |
||
625 | printf("RUNREC File version = %u\n",hdr[2]); |
||
626 | |||
627 | printf("RUNREC Time = %u\n",hdr[3]); |
||
628 | printf("Number of events per step = %u\n",runrec->num_events); |
||
629 | printf("Number of channels measured = %u\n",runrec->num_channels); |
||
630 | printf("Pedestal = %u\n",runrec->pedestal); |
||
631 | printf("Scan type = %u :: 0 -> single data scan :: 1 -> XY position scan\n",runrec->xy); |
||
632 | printf("Number of steps in X = %d\n",runrec->nx); |
||
633 | printf("Start position X = %d\n",runrec->x0); |
||
634 | printf("Step size direction X = %d\n",runrec->dx); |
||
635 | printf("Number of steps in Y = %d\n",runrec->ny); |
||
636 | printf("Start position Y = %d\n",runrec->y0); |
||
637 | printf("Step size direction Y = %d\n",runrec->dy); |
||
638 | |||
639 | break; |
||
640 | case POSREC_ID: |
||
641 | posrec=(POSREC *) (&buf[0]); |
||
642 | printf("POSREC nx=%d , posx=%d setx=%d posy=%d sety=%d angle(deg)= %3.2f \n",n,posrec->mikro_pos_x,posrec->set_pos_x,posrec->mikro_pos_y,posrec->set_pos_y, posrec->set_pos_x*360./NSTEPS); |
||
643 | m_rotation = posrec->set_pos_x*2*TMath::Pi()/NSTEPS; |
||
644 | break; |
||
645 | case EVTREC_ID: |
||
646 | break; |
||
647 | |||
648 | } |
||
649 | |||
650 | if (recid!=EVTREC_ID) continue; |
||
651 | if (nread++==nevetoprocess) break; |
||
652 | int idx=1; |
||
653 | int neve=buf[0]/2; |
||
654 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
655 | for (int nev=0;nev<neve;nev++){ |
||
656 | int len=buf[idx]; |
||
657 | int sb =buf[idx+1]; |
||
658 | unsigned int *pbuf=&buf[idx+2]; |
||
659 | if (sb!=0xffab) { |
||
660 | printf("0x%04x!0xffab len=%d\n",sb,len); |
||
661 | break; |
||
662 | } |
||
663 | // postavi na nic |
||
664 | #define InitArrayWithAValue(arr,n,x) {for (int i=0;i<n;i++) arr[i]=x;} |
||
665 | InitArrayWithAValue( gSum , 4 , 0); |
||
666 | InitArrayWithAValue( gRawSum , 4 , 0); |
||
667 | InitArrayWithAValue( gMax , 4 , 0); |
||
668 | InitArrayWithAValue( gSumCluster, 4 , 0); |
||
669 | InitArrayWithAValue( gNabove , 4 , 0); |
||
670 | InitArrayWithAValue( gData , MAXCH, 0); |
||
671 | InitArrayWithAValue( gAdc , MAXCH, 0); |
||
672 | //------------------------------------------------------------ |
||
673 | for (int i0=0;i0<len-2;i0+=2) { |
||
674 | |||
675 | int data0 = pbuf[i0]; |
||
676 | int data1 = pbuf[i0+1]; |
||
677 | int geo = (data1 >> 11) & 0x1f; |
||
678 | int ch = (data1&0x1f) | (geo<<5); |
||
679 | int dtype = (data1>>9)&0x3; |
||
680 | int adc = data0&0xfff; |
||
681 | |||
682 | switch (dtype) { |
||
683 | case 0x0: |
||
684 | if (ch<MAXCH) { |
||
685 | m_Adc[ch]->Fill(adc); |
||
686 | |||
687 | int ipmt = ch/16; |
||
688 | |||
689 | gAdc[ch]=adc; |
||
690 | gRawSum[ipmt]+=adc; |
||
691 | |||
692 | if (ch<64) gData[ch]=m_geo->GetEnergy(ch,adc); else gData[ch]=adc; |
||
693 | |||
694 | gSum[ipmt]+=gData[ch]; |
||
695 | if (gData[ch] >gMax[ipmt] ) gMax[ipmt]= gData[ch]; |
||
696 | if (gData[ch] >m_threshold ) gNabove[ipmt]++; |
||
697 | } |
||
698 | break; |
||
699 | case 0x10: |
||
700 | case 0x11: |
||
701 | case 0x01: |
||
702 | break; |
||
703 | } |
||
704 | |||
705 | };// for (int i0=0;i0<len-2;i0+=2) |
||
706 | //------------------------------------------------------------ |
||
707 | |||
708 | idx+=len+1; |
||
709 | FillHistograms(); |
||
710 | } // for (int nev=0;nev<neve;nev++) |
||
711 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
712 | } // while (!gzeof(fp) ) |
||
713 | gzclose(fp); |
||
714 | delete buf; |
||
715 | return nr; |
||
716 | } |
||
717 | |||
718 | readdata(const char *fnameconfig, std::vector<TString> &fnamein, const char *fnameout, int write2root=0, int nevetoread=-1, int debug=0 ){ |
||
719 | m_debug = debug; |
||
720 | m_write = write2root; |
||
721 | m_neve = nevetoread; |
||
722 | |||
723 | m_geo = new Geometry(fnameconfig,m_debug); |
||
724 | m_threshold=m_geo->GetThreshold(); |
||
725 | |||
726 | char rootname[0xFF]; sprintf(rootname,"%s.root",fnameout); |
||
727 | TFile *rootFile = new TFile(rootname,"RECREATE"); |
||
728 | Initialize(); |
||
729 | printf("Konec inicializacije ...\n"); |
||
730 | |||
731 | m_projector=PETProjDataMgr::GetInstance(); |
||
732 | m_projector->SetDebug(m_debug); |
||
733 | m_projector->SetRingDiameter(2*m_geo->module[0].r); |
||
734 | m_projector->SetFilename(fnameout); |
||
735 | |||
736 | m_coincidences=0; |
||
737 | |||
738 | int nr = 0; |
||
739 | for (unsigned int i=0;i< fnamein.size() ;i++) { |
||
740 | int neve = m_neve -nr; |
||
741 | if (m_neve == -1) nr += Process(fnamein[i].Data(), m_neve); |
||
742 | else if (neve>0) nr += Process(fnamein[i].Data(), neve); |
||
743 | } |
||
744 | printf("End...\nreaddata::Number of events read=%d\nreaddata::Number of coincidences=%d\n",nr,m_coincidences); |
||
745 | |||
746 | m_projector->WriteInterfile(); |
||
747 | rootFile->Write(); |
||
748 | rootFile->Close(); |
||
749 | } |
||
750 | |||
751 | ~readdata(){ |
||
752 | if (m_geo) delete m_geo; |
||
753 | }; |
||
754 | |||
755 | }; |
||
756 | |||
757 | #ifdef MAIN |
||
758 | |||
759 | |||
760 | int main(int argc, char **argv){ |
||
761 | |||
762 | std::cout << "Usage:" << argv[0] << " -c config.xml -i input.dat -o output -n nevents -w writentuple -d debuglevel "<< std::endl; |
||
763 | //----------------------------------------------------------------- |
||
764 | char configfile[256]="ini/config.xml"; |
||
765 | char outputfile[256]="/tmp/petfmf"; |
||
766 | int nevetoread =-1; |
||
767 | int writentuple =0; |
||
768 | int verbose =0; |
||
769 | char c; |
||
770 | |||
771 | std::vector<TString> inputfilelist; |
||
772 | while ((c=getopt (argc, argv, "c:i:o:n:w:d:")) != -1){ |
||
773 | switch(c){ |
||
774 | case 'c': sprintf(configfile,"%s",optarg); break; |
||
775 | case 'i': inputfilelist.push_back(TString(optarg)); break; |
||
776 | case 'o': sprintf(outputfile,"%s",optarg); break; |
||
777 | case 'n': nevetoread = atoi(optarg) ; break; |
||
778 | case 'w': writentuple = atoi(optarg); break; |
||
779 | case 'd': verbose = atoi(optarg); break; |
||
780 | default: abort(); |
||
781 | } |
||
782 | } |
||
783 | std::cout << "Used: " << argv[0] << " -c " << configfile << " -o " << outputfile << " -n " << nevetoread << " -w " << writentuple << " -d " << verbose ; |
||
784 | for (unsigned int i=0;i< inputfilelist.size() ;i++) std::cout << " -i " << inputfilelist[i]; |
||
785 | std::cout << std::endl; |
||
786 | //----------------------------------------------------------------- |
||
787 | new readdata(configfile, inputfilelist,outputfile, writentuple, nevetoread, verbose); |
||
788 | |||
789 | std::cout << "Output data files " << outputfile << std::endl; |
||
790 | return 0; |
||
791 | } |
||
792 | |||
793 | #endif |