Subversion Repositories f9daq

Rev

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