Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
264 | f9daq | 1 | |
2 | #include <stdlib.h> |
||
3 | #include <stdio.h> |
||
4 | #include <stdint.h> |
||
5 | #include "daq.h" |
||
6 | #include "H1D.h" |
||
7 | #include "H2D.h" |
||
8 | #include "PETProjDataMgr.h" |
||
9 | |||
10 | double gAdc[MAXCH]; // raw ADC ji |
||
11 | float gNtdata[MAXCH*3]; |
||
12 | int m_write=0; |
||
13 | |||
14 | double gData[MAXCH]; // korigirani ADC ji |
||
15 | |||
16 | float gSum[MAXPMT]; |
||
17 | float gRawSum[MAXPMT]; |
||
18 | float gMax[MAXPMT]; |
||
19 | float gSumCluster[MAXPMT]; |
||
20 | int gNabove[MAXPMT]; |
||
21 | |||
22 | |||
23 | |||
24 | |||
25 | |||
26 | double GetEnergy(int ch, int adc) { |
||
27 | return (adc-conf.apedestals[ch])/(conf.apeak[ch]-conf.apedestals[ch])*conf.peakscaling; |
||
28 | } |
||
29 | |||
30 | |||
31 | |||
32 | int GetGlobalPosition(int ipmt, double angle, float cx, float cy, float *gposition) { |
||
33 | |||
34 | double phi = angle + conf.module[ipmt].phi; |
||
35 | double r = conf.module[ipmt].r; |
||
36 | double sinphi = sin(phi); |
||
37 | double cosphi = cos(phi); |
||
38 | |||
39 | gposition[0]= cosphi* r + sinphi * cx ; |
||
40 | gposition[1]= sinphi* r - cosphi * cx ; |
||
41 | gposition[2]= cy; |
||
42 | |||
43 | //if (m_debug) printf( "[%d] phi=%f %f global ( %f , %f , %f )\n" ,ipmt, module[ipmt].phi,angle, rv.x(), rv.y(), rv.z()); |
||
44 | return 0; |
||
45 | } |
||
46 | |||
47 | |||
48 | int GetRealPosition(int ipmt, float px,float py,float *cx,float *cy) { |
||
49 | // iz CoG izracuna pozicijo na kristalu |
||
50 | |||
51 | int binx = 0; //####m_crystalid[ipmt]->GetXaxis()->FindBin(px); |
||
52 | int biny = 0; //####m_crystalid[ipmt]->GetYaxis()->FindBin(py); |
||
53 | int crystalid = 0;//####m_crystalid[ipmt]->GetBinContent(binx,biny); |
||
54 | *cx= ( crystalid % conf.nofcrystalsx - conf.nofcrystalsy/2. + 0.5 ) * conf.crystalpitchx; |
||
55 | *cy= ( crystalid / conf.nofcrystalsx - conf.nofcrystalsx/2. + 0.5 ) * conf.crystalpitchy; |
||
56 | |||
57 | |||
58 | // razmazi pozicijo po povrsini kristala |
||
59 | double rndx = Random(-0.5,0.5)* conf.crystalpitchx; |
||
60 | double rndy = Random(-0.5,0.5)* conf.crystalpitchy; |
||
61 | *cx+= rndx; |
||
62 | *cy+= rndy; |
||
63 | return crystalid; |
||
64 | } |
||
65 | |||
66 | |||
67 | int HistogramsInit() { |
||
68 | |||
69 | if (conf.write) { |
||
70 | char varlist[1024], tmplist[1024]; |
||
71 | 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"); |
||
72 | for (int i=0; i<MAXCH; i++) { |
||
73 | sprintf(tmplist,"%s",varlist); |
||
74 | sprintf(varlist,"%s:a%d",tmplist,i); |
||
75 | } |
||
76 | /* |
||
77 | energija .. (adc -pedestal) * scaling |
||
78 | |||
79 | sum0 .. sum3 vsota energij po vseh kanalih fotopomnozevalke |
||
80 | nh0 .. nh4 stevilo zadetkov na fotopomnozevalki (adc nad thresholdom) |
||
81 | c0 .. c4 vsota energij za kanale nad thresholdom |
||
82 | px0 .. px4 x koordinata COG na fotopomnozevalki |
||
83 | py0 .. py4 y koordinata COG na fotopomnozevalki |
||
84 | max0 .. max3 maximalna energija na kanalu na fotopomnozevalki |
||
85 | a0 .. a63 energija na i-tem kanalu |
||
86 | */ |
||
87 | //gNtuple = new TNtuple("nt","Pet RAW data",varlist); |
||
88 | printf ("#%s#\n",varlist); |
||
89 | } |
||
90 | m_Nhits = H2D_Init(301,"hnabove","Stevilo zadetkov nad nivojem diskriminacije",4,-0.5,3.5, 16,+0.5,16.5 ); // stevilo hitov nad thresholdom |
||
91 | m_GlobalPosition =H2D_Init(302,"globalxy","Rekonstruirana koordinata zadetka",200,-80,80,200,-80,80); // reconstruirana koordinata v globalnem sistemu |
||
92 | |||
93 | |||
94 | char hname[0xFF]; |
||
95 | char hn[0xFF]; |
||
96 | int i; |
||
97 | for (i=0; i<MAXCH; i++) { |
||
98 | sprintf(hname,"Raw ADC Ch. %d ;ADC;N",i); |
||
99 | sprintf(hn,"ach%d",i); |
||
100 | //m_Adc[i] = H1D_Init(i,hn,hname,4000,-0.5,3999.5); // osnovni adcji |
||
101 | m_Adc[i] = H1D_Init(i,hn,hname,400,500-0.5,899.5); // osnovni adcji |
||
102 | sprintf(hname,"cADC za dogodke z manj kot x hitov na pmtju Ch. %d ;ADC;N",i); |
||
103 | sprintf(hn,"cutch%d",i); |
||
104 | m_AdcCut[i] = H1D_Init(i+MAXCH, hn,hname,4000,-0.5,3999.5); // adcji za zadetke z manj kot 7 hiti na PMTju |
||
105 | sprintf(hname,"cADC proti stevilu zadetkov na pmtju Ch. %d ;ADC;N",i); |
||
106 | sprintf(hn,"singlech%d",i); |
||
107 | m_Adc_vs_Nhits[i] = H2D_Init(i,hn,hname,200,0,4000, 17,-0.5,16.5); // adc proti stevilu zadetkov na PMTju |
||
108 | sprintf(hname,"cADC proti vsoti kanalov na pmtju, Ch. %d ;ADC;ADCsum",i); |
||
109 | sprintf(hn,"corrch%d",i); |
||
110 | m_Adc_vs_Sum[i] = H2D_Init(i+MAXCH,hn,hname,200,0,4000, 200,0,12000 ); // raw adc proti vsoti kanalov na PMTju |
||
111 | sprintf(hname,"Raw ADC proti vsoti kanalov na pmtju, Ch. %d ;ADC;ADCsum",i); |
||
112 | sprintf(hn,"adcvssumch%d",i); |
||
113 | m_Adc_vs_Sum_Uncorected[i] =H2D_Init(i+MAXCH*2,hn,hname,100,0,3500, 100,5000,12000 ); // adc proti vsoti kanalov na PMTju |
||
114 | } |
||
115 | |||
116 | for (i=0; i<MAXPMT; i++) { |
||
117 | sprintf(hname,"Vsota cADC na PMTju %d ;ADC;N",i); |
||
118 | sprintf(hn,"pmt%d",i); |
||
119 | m_AdcSum[i] =H1D_Init(200+i,hn,hname,200,0,20000); // vsota adcjev na PMTju |
||
120 | sprintf(hname,"Vsota cADC na PMTju za dogodke z manj kot x zadetki %d ;ADC;N",i); |
||
121 | sprintf(hn,"clusterpmt%d",i); |
||
122 | m_AdcSumCluster[i] = H1D_Init(216+i,hn,hname,200,0,20000); // vsota adcjev na pmtju, ki so nad threshholdom, za dogodke z manj kot 5 zadetki na PMTju |
||
123 | |||
124 | sprintf(hname,"Center naboja CoG PMT %d ;x;y",i); |
||
125 | sprintf(hn,"pmt1%d",i); |
||
126 | m_CenterOfGravity[i] =H2D_Init(200+i,hn,hname,200,-1.25,4.25,200,-1.25,4.25); // center naboja na PMTju |
||
127 | |||
128 | sprintf(hname,"Center naboja CoG za zadetke nad thresholdom PMT %d ;x;y",i); |
||
129 | sprintf(hn,"pmt2%d",i); |
||
130 | m_CenterOfGravityforChAboveThreshold[i] = H2D_Init(216+i,hn,hname,200,0,3,200,0,3); // center naboja za zadetke nad thresholdom |
||
131 | |||
132 | sprintf(hname,"Rekonstruirana koordinata PMT %d ;x(mm);y(mm)",i); |
||
133 | sprintf(hn,"pmt3%d",i); |
||
134 | m_ReconstructedPosition[i] = H2D_Init(232+i,hn,hname,200,-12,12,200,-12,12); // korigirana koordinata na pmtju |
||
135 | |||
136 | sprintf(hname,"SumAdc PMT %d ;SumAdc(a.u.);crystal ID",i); |
||
137 | sprintf(hn,"sumadc%d",i); |
||
138 | m_SumAdc[i] =H2D_Init(248+i,hn,hname,200,0,12000,81,-0.5,80.5); // SumADC spekter za razlicne kristale |
||
139 | } |
||
140 | |||
141 | // store mapping |
||
142 | //TH1I *hx= new TH1I("mapping", "ch mapping", 16, -0.5,15.5); |
||
143 | //for (int j=0;j<16;j++) hx->Fill(j,m_geo->ch[j].idx); |
||
144 | |||
145 | return 0; |
||
146 | }; |
||
147 | |||
148 | int HistogramsWrite(const char *fname){ |
||
149 | FILE *fp = fopen(fname, "wb"); |
||
150 | |||
151 | if (fp){ |
||
152 | int i; |
||
153 | for (i=0;i<H1DMAX;i++){ if (H1D_Exist(i)) H1D_Write2File(i, fp); } |
||
154 | for (i=0;i<H2DMAX;i++){ if (H2D_Exist(i)) H2D_Write2File(i, fp); } |
||
155 | for (i=0;i<H3DMAX;i++){ if (H3D_Exist(i)) H3D_Write2File(i, fp); } |
||
156 | fclose(fp); |
||
157 | |||
158 | } |
||
159 | |||
160 | return 0; |
||
161 | } |
||
162 | |||
163 | |||
164 | int HistogramsFill() { |
||
165 | int i=0, ipmt; |
||
166 | for (i=0; i<MAXCH; i++) { // zanka cez vse elektronske kanale; |
||
167 | float x=gData[i]; |
||
168 | int ipmt= i/16; |
||
169 | float s=gSum[ipmt]; |
||
170 | // int idx= 2*(ipmt)+64; |
||
171 | // const float fSlope1=2; |
||
172 | // const float fSlope2=3; |
||
173 | // if ( ((s-gSumPedestals[ipmt] ) > fSlope1*(x-gPedestals[i])) && ((s-gSumPedestals[ipmt] ) < fSlope2*(x-gPedestals[ipmt])) ) { |
||
174 | if (gNabove[ipmt]<7) { |
||
175 | H2D_Fill(m_Adc_vs_Sum[i],x,s,1); |
||
176 | H2D_Fill(m_Adc_vs_Sum_Uncorected[i], gAdc[i],gRawSum[ipmt],1); |
||
177 | H1D_Fill(m_AdcCut[i],x,1); |
||
178 | } |
||
179 | } |
||
180 | |||
181 | HVector3 r_coincidence[2]; |
||
182 | for (int k=0; k<2; k++) for (int i1=0; i1<3; i1++) r_coincidence[k].x[i1]=0; |
||
183 | int f_coincidence[2]= {0,0}; |
||
184 | |||
185 | for (ipmt=0; ipmt<4; ipmt++) { // zanka preko pmtjev |
||
186 | int j2= (ipmt/2)*2+1-ipmt%2; // sosednja fotopomnozevalka |
||
187 | |||
188 | float posx[2]= {0,0}; |
||
189 | float posy[2]= {0,0}; |
||
190 | float sum[2]= {0,0}; |
||
191 | for (int ich=0; ich<16; ich++) { // zanka preko elektronskih kanalov na fotopomnozevalki |
||
192 | int ch= ich+ipmt*16; |
||
193 | if (gMax[ipmt]>conf.adcthreshold) { |
||
194 | posx[0]+= gData[ch]*conf.channel[ich].ix; |
||
195 | posy[0]+= gData[ch]*conf.channel[ich].iy; |
||
196 | sum[0] += gData[ch]; |
||
197 | |||
198 | if (gData[ch]> 0.1*gMax[ipmt]) { // pri racunanju pozicije upostevaj le kanale, ki imajo vrednost vecjo od ratio*maksimalna na tisti fotopomnozevalki ******** |
||
199 | posx[1]+= gData[ch]*conf.channel[ich].ix; |
||
200 | posy[1]+= gData[ch]*conf.channel[ich].iy; |
||
201 | sum[1] += gData[ch]; |
||
202 | } |
||
203 | } |
||
204 | } |
||
205 | |||
206 | if (m_write) { |
||
207 | gNtdata[12+ipmt]=posx[0]/sum[0]; |
||
208 | gNtdata[16+ipmt]=posy[0]/sum[0]; |
||
209 | gNtdata[20+ipmt]=(sum[1]>0)?posx[1]/sum[1]:-10; |
||
210 | gNtdata[24+ipmt]=(sum[1]>0)?posy[1]/sum[1]:-10; |
||
211 | gNtdata[28+ipmt]=sum[0]; |
||
212 | } |
||
213 | if (gMax[ipmt]>gMax[j2]) { // izberi fotopomnozevalko, ki ima vec zadetkov kot soseda TRG= (P1|P2) & (P3|P4) |
||
214 | |||
215 | if ( sum[0] > 0 ) { |
||
216 | float px=posx[0]/sum[0]; |
||
217 | float py=posy[0]/sum[0]; |
||
218 | |||
219 | H2D_Fill(m_CenterOfGravity[ipmt],px,py,1); |
||
220 | |||
221 | float cx=0; //koordinata na pmtju |
||
222 | float cy=0; |
||
223 | int crystalID = GetRealPosition(ipmt,px,py,&cx,&cy); |
||
224 | H2D_Fill(m_ReconstructedPosition[ipmt],cx,cy,1); |
||
225 | H2D_Fill(m_SumAdc[ipmt],gSum[ipmt], crystalID,1 ); |
||
226 | if (debug > 2) printf("ipmt=%d cx=%f cy=%f\n",ipmt,cx,cy); |
||
227 | GetGlobalPosition(ipmt, conf.rotation, cx, cy,r_coincidence[ipmt/2].x) ; |
||
228 | f_coincidence[ipmt/2] =1; |
||
229 | H2D_Fill(m_GlobalPosition,r_coincidence[ipmt/2].x[0],r_coincidence[ipmt/2].x[1],1); |
||
230 | |||
231 | } |
||
232 | if ( sum[1] > 0 ) { |
||
233 | |||
234 | float px=posx[1]/sum[1]; |
||
235 | float py=posy[1]/sum[1]; |
||
236 | // float px0=posx[0]/sum[0]; |
||
237 | // float py0=posy[0]/sum[0]; |
||
238 | // if (px0<0.25 || px0>2.75 || py0< 0.25 || py0> 2.75) |
||
239 | // if (((py0>0.75 && py0<1.25) || (py0>1.75 && py0<2.25)) && (px0< 0.25 || px0>2.75 ) ) |
||
240 | H2D_Fill(m_CenterOfGravityforChAboveThreshold[ipmt],px,py,1); |
||
241 | } |
||
242 | |||
243 | } |
||
244 | } |
||
245 | |||
246 | for (i=0; i<MAXCH; i++) if (gData[i]>conf.adcthreshold) { |
||
247 | H2D_Fill(m_Adc_vs_Nhits[i],gData[i],gNabove[i/16],1); |
||
248 | } |
||
249 | for (i=0; i<MAXCH; i++) if (gData[i]>conf.adcthreshold && gNabove[i/16]<5 ) { |
||
250 | gSumCluster[i/16]+=gData[i]; |
||
251 | } |
||
252 | for (ipmt=0; ipmt<4; ipmt++) { |
||
253 | H1D_Fill(m_AdcSum[ipmt],gSum[ipmt],1); |
||
254 | H1D_Fill(m_AdcSumCluster[ipmt],gSumCluster[ipmt],1); |
||
255 | } |
||
256 | |||
257 | for (i=0; i<4; i++) H1D_Fill(m_Nhits,i,gNabove[i]); |
||
258 | |||
259 | if (m_write) { |
||
260 | for (i=0; i<4; i++) { |
||
261 | gNtdata[i]=gSum[i]; |
||
262 | gNtdata[4+i]=gNabove[i]; |
||
263 | gNtdata[8+i]=gSumCluster[i]; |
||
264 | } |
||
265 | for (i=0; i<MAXCH; i++) gNtdata[32+i]=gData[i]; |
||
266 | //gNtuple->Fill(gNtdata); |
||
267 | } |
||
268 | // |
||
269 | // coincidences |
||
270 | // |
||
271 | if (f_coincidence[0]&&f_coincidence[1]) { |
||
272 | conf.coincidences++; |
||
273 | if (debug > 1) { |
||
274 | printf( "Coincidence ( %f , %f , %f ) ( %f , %f , %f )\n" , |
||
275 | r_coincidence[0].x[0], r_coincidence[0].x[1], r_coincidence[0].x[2], |
||
276 | r_coincidence[1].x[0], r_coincidence[1].x[1], r_coincidence[1].x[2] ); |
||
277 | } |
||
278 | AddEvent( r_coincidence[0] , r_coincidence[1]); |
||
279 | } |
||
280 | return 0; |
||
281 | }; |
||
282 | |||
283 | |||
284 | |||
285 | int analyse(int nb, uint32_t *buf) { |
||
286 | |||
287 | int idx=1; |
||
288 | int neve=buf[0]/2; |
||
289 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
290 | for (int nev=0; nev<neve; nev++) { |
||
291 | int len=buf[idx]; |
||
292 | int sb =buf[idx+1]; |
||
293 | unsigned int *pbuf=&buf[idx+2]; |
||
294 | if (sb!=0xffab) { |
||
295 | printf("0x%04x!0xffab len=%d\n",sb,len); |
||
296 | break; |
||
297 | } |
||
298 | // postavi na nic |
||
299 | #define InitArrayWithAValue(arr,n,x) {for (int i=0;i<n;i++) arr[i]=x;} |
||
300 | |||
301 | //------------------------------------------------------------ |
||
302 | // postavi na nic |
||
303 | |||
304 | InitArrayWithAValue( gSum , MAXPMT , 0); |
||
305 | InitArrayWithAValue( gRawSum , MAXPMT , 0); |
||
306 | InitArrayWithAValue( gMax , MAXPMT , 0); |
||
307 | InitArrayWithAValue( gSumCluster, MAXPMT , 0); |
||
308 | InitArrayWithAValue( gNabove , MAXPMT , 0); |
||
309 | InitArrayWithAValue( gData , MAXCH, 0); |
||
310 | InitArrayWithAValue( gAdc , MAXCH, 0); |
||
311 | for (int i0=0; i0<len-2; i0+=2) { |
||
312 | |||
313 | int data0 = pbuf[i0]; |
||
314 | int data1 = pbuf[i0+1]; |
||
315 | int geo = (data1 >> 11) & 0x1f; |
||
316 | int ch = (data1&0x1f) | (geo<<5); |
||
317 | int dtype = (data1>>9)&0x3; |
||
318 | int adc = data0&0xfff; |
||
319 | if (dtype == 0 & ch<MAXCH) { |
||
320 | if (debug) printf("%d ADC %d %d\n", geo, ch, adc); |
||
321 | if (ch<MAXCH) H1D_Fill(ch, adc,1); |
||
322 | int ipmt = ch/16; |
||
323 | |||
324 | gAdc[ch]=adc; |
||
325 | gRawSum[ipmt]+=adc; |
||
326 | |||
327 | gData[ch]=GetEnergy(ch,adc); |
||
328 | |||
329 | gSum[ipmt]+=gData[ch]; |
||
330 | if (gData[ch] >gMax[ipmt] ) gMax[ipmt]= gData[ch]; |
||
331 | if (gData[ch] >conf.adcthreshold ) gNabove[ipmt]++; |
||
332 | //#### m_Adc[ch]->Fill(adc); |
||
333 | } |
||
334 | };// for (int i0=0;i0<len-2;i0+=2) |
||
335 | //------------------------------------------------------------ |
||
336 | |||
337 | idx+=len+1; |
||
338 | HistogramsFill(); |
||
339 | if (m_write) { |
||
340 | gNtdata[0]=0; |
||
341 | for (int i=0; i<MAXCH; i++) gNtdata[i+1]=gAdc[i]; |
||
342 | //####gNtuple->Fill(gNtdata); |
||
343 | } |
||
344 | |||
345 | } // for (int nev=0;nev<neve;nev++) |
||
346 | |||
347 | |||
348 | |||
349 | |||
350 | return 0; |
||
351 | } |