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 | } |