/[PAMELA software]/PamelaDigitizer/Digitizer.cxx
ViewVC logotype

Contents of /PamelaDigitizer/Digitizer.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations) (download)
Thu Oct 11 11:29:21 2007 UTC (17 years, 1 month ago) by orsi
Branch: MAIN
Changes since 1.2: +201 -133 lines
TOF/AC/S4 changes;packet length bug fixed

1 // ------ PAMELA Digitizer ------
2 //
3 // Date, release and how-to: see file Pamelagp2Digits.cxx
4 //
5 // NB: Check length physics packet [packet type (0x10 = physics data)]
6 //
7 #include <sstream>
8 #include <fstream>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <time.h>
14 #include "Riostream.h"
15 #include "TFile.h"
16 #include "TDirectory.h"
17 #include "TTree.h"
18 #include "TLeafI.h"
19 #include "TH1.h"
20 #include "TH2.h"
21 #include "TMath.h"
22 #include "TRandom.h"
23 #include "TSQLServer.h"
24 #include "TSystem.h"
25 //
26 #include "Digitizer.h"
27 #include "CRC.h"
28 //
29 #include <PamelaRun.h>
30 #include <physics/calorimeter/CalorimeterEvent.h>
31 #include <CalibCalPedEvent.h>
32 #include "GLTables.h"
33 //
34 extern "C"{
35 short crc(short, short);
36 };
37 //
38
39 Digitizer::Digitizer(TTree* tree, char* &file_raw){
40 fhBookTree = tree;
41 fFilename = file_raw;
42 fCounter = 0;
43 fOBT = 0;
44
45 //
46 // DB connections
47 //
48 TString host = "mysql://localhost/pamelaprod";
49 TString user = "anonymous";
50 TString psw = "";
51 //
52 const char *pamdbhost=gSystem->Getenv("PAM_DBHOST");
53 const char *pamdbuser=gSystem->Getenv("PAM_DBUSER");
54 const char *pamdbpsw=gSystem->Getenv("PAM_DBPSW");
55 if ( !pamdbhost ) pamdbhost = "";
56 if ( !pamdbuser ) pamdbuser = "";
57 if ( !pamdbpsw ) pamdbpsw = "";
58 if ( strcmp(pamdbhost,"") ) host = pamdbhost;
59 if ( strcmp(pamdbuser,"") ) user = pamdbuser;
60 if ( strcmp(pamdbpsw,"") ) psw = pamdbpsw;
61 fDbc = TSQLServer::Connect(host.Data(),user.Data(),psw.Data());
62 //
63 GL_TABLES *glt = new GL_TABLES(host,user,psw);
64 if ( glt->IsConnected(fDbc) ) printf("\n DB INFORMATION:\n SQL: %s Version: %s Host %s Port %i \n\n",fDbc->GetDBMS(),fDbc->ServerInfo(),fDbc->GetHost(),fDbc->GetPort());
65 //
66 // Use UTC in the DB and make timeout bigger
67 //
68 stringstream myquery;
69 myquery.str("");
70 myquery << "SET time_zone='+0:00'";
71 fDbc->Query(myquery.str().c_str());
72 myquery.str("");
73 myquery << "SET wait_timeout=173000;";
74 fDbc->Query(myquery.str().c_str());
75 //
76
77 std:: cout << "preparing tree" << endl;
78
79 // prepare tree
80 fhBookTree->SetBranchAddress("Irun",&Irun);
81 fhBookTree->SetBranchAddress("Ievnt",&Ievnt);
82 fhBookTree->SetBranchAddress("Ipa",&Ipa);
83 fhBookTree->SetBranchAddress("X0",&X0);
84 fhBookTree->SetBranchAddress("Y0",&Y0);
85 fhBookTree->SetBranchAddress("Z0",&Z0);
86 fhBookTree->SetBranchAddress("Theta",&Theta);
87 fhBookTree->SetBranchAddress("Phi",&Phi);
88 fhBookTree->SetBranchAddress("P0",&P0);
89 fhBookTree->SetBranchAddress("Nthtof",&Nthtof);
90 fhBookTree->SetBranchAddress("Ipltof",Ipltof);
91 fhBookTree->SetBranchAddress("Ipaddle",Ipaddle);
92 fhBookTree->SetBranchAddress("Ipartof",Ipartof);
93 fhBookTree->SetBranchAddress("Xintof",Xintof);
94 fhBookTree->SetBranchAddress("Yintof",Yintof);
95 fhBookTree->SetBranchAddress("Zintof",Zintof);
96 fhBookTree->SetBranchAddress("Xouttof",Xouttof);
97 fhBookTree->SetBranchAddress("Youttof",Youttof);
98 fhBookTree->SetBranchAddress("Zouttof",Zouttof);
99 fhBookTree->SetBranchAddress("Ereltof",Ereltof);
100 fhBookTree->SetBranchAddress("Timetof",Timetof);
101 fhBookTree->SetBranchAddress("Pathtof",Pathtof);
102 fhBookTree->SetBranchAddress("P0tof",P0tof);
103 fhBookTree->SetBranchAddress("Nthcat",&Nthcat);
104 fhBookTree->SetBranchAddress("Iparcat",Iparcat);
105 fhBookTree->SetBranchAddress("Icat",Icat);
106 fhBookTree->SetBranchAddress("Xincat",Xincat);
107 fhBookTree->SetBranchAddress("Yincat",Yincat);
108 fhBookTree->SetBranchAddress("Zincat",Zincat);
109 fhBookTree->SetBranchAddress("Xoutcat",Xoutcat);
110 fhBookTree->SetBranchAddress("Youtcat",Youtcat);
111 fhBookTree->SetBranchAddress("Zoutcat",Zoutcat);
112 fhBookTree->SetBranchAddress("Erelcat",Erelcat);
113 fhBookTree->SetBranchAddress("Timecat",Timecat);
114 fhBookTree->SetBranchAddress("Pathcat",Pathcat);
115 fhBookTree->SetBranchAddress("P0cat",P0cat);
116 fhBookTree->SetBranchAddress("Nthcas",&Nthcas);
117 fhBookTree->SetBranchAddress("Iparcas",Iparcas);
118 fhBookTree->SetBranchAddress("Icas",Icas);
119 fhBookTree->SetBranchAddress("Xincas",Xincas);
120 fhBookTree->SetBranchAddress("Yincas",Yincas);
121 fhBookTree->SetBranchAddress("Zincas",Zincas);
122 fhBookTree->SetBranchAddress("Xoutcas",Xoutcas);
123 fhBookTree->SetBranchAddress("Youtcas",Youtcas);
124 fhBookTree->SetBranchAddress("Zoutcas",Zoutcas);
125 fhBookTree->SetBranchAddress("Erelcas",Erelcas);
126 fhBookTree->SetBranchAddress("Timecas",Timecas);
127 fhBookTree->SetBranchAddress("Pathcas",Pathcas);
128 fhBookTree->SetBranchAddress("P0cas",P0cas);
129 fhBookTree->SetBranchAddress("Nthspe",&Nthspe);
130 fhBookTree->SetBranchAddress("Iparspe",Iparspe);
131 fhBookTree->SetBranchAddress("Itrpb",Itrpb);
132 fhBookTree->SetBranchAddress("Itrsl",Itrsl);
133 fhBookTree->SetBranchAddress("Itspa",Itspa);
134 fhBookTree->SetBranchAddress("Xinspe",Xinspe);
135 fhBookTree->SetBranchAddress("Yinspe",Yinspe);
136 fhBookTree->SetBranchAddress("Zinspe",Zinspe);
137 fhBookTree->SetBranchAddress("Xoutspe",Xoutspe);
138 fhBookTree->SetBranchAddress("Youtspe",Youtspe);
139 fhBookTree->SetBranchAddress("Zoutspe",Zoutspe);
140 fhBookTree->SetBranchAddress("Xavspe",Xavspe);
141 fhBookTree->SetBranchAddress("Yavspe",Yavspe);
142 fhBookTree->SetBranchAddress("Zavspe",Zavspe);
143 fhBookTree->SetBranchAddress("Erelspe",Erelspe);
144 fhBookTree->SetBranchAddress("Pathspe",Pathspe);
145 fhBookTree->SetBranchAddress("P0spe",P0spe);
146 fhBookTree->SetBranchAddress("Nxmult",Nxmult);
147 fhBookTree->SetBranchAddress("Nymult",Nymult);
148 fhBookTree->SetBranchAddress("Nstrpx",&Nstrpx);
149 fhBookTree->SetBranchAddress("Npstripx",Npstripx);
150 fhBookTree->SetBranchAddress("Ntstripx",Ntstripx);
151 fhBookTree->SetBranchAddress("Istripx",Istripx);
152 fhBookTree->SetBranchAddress("Qstripx",Qstripx);
153 fhBookTree->SetBranchAddress("Xstripx",Xstripx);
154 fhBookTree->SetBranchAddress("Nstrpy",&Nstrpy);
155 fhBookTree->SetBranchAddress("Npstripy",Npstripy);
156 fhBookTree->SetBranchAddress("Ntstripy",Ntstripy);
157 fhBookTree->SetBranchAddress("Istripy",Istripy);
158 fhBookTree->SetBranchAddress("Qstripy",Qstripy);
159 fhBookTree->SetBranchAddress("Ystripy",Ystripy);
160 fhBookTree->SetBranchAddress("Nthcali",&Nthcali);
161 fhBookTree->SetBranchAddress("Icaplane",Icaplane);
162 fhBookTree->SetBranchAddress("Icastrip",Icastrip);
163 fhBookTree->SetBranchAddress("Icamod",Icamod);
164 fhBookTree->SetBranchAddress("Enestrip",Enestrip);
165 fhBookTree->SetBranchAddress("Nthcal",&Nthcal);
166 fhBookTree->SetBranchAddress("Icapl",Icapl);
167 fhBookTree->SetBranchAddress("Icasi",Icasi);
168 fhBookTree->SetBranchAddress("Icast",Icast);
169 fhBookTree->SetBranchAddress("Xincal",Xincal);
170 fhBookTree->SetBranchAddress("Yincal",Yincal);
171 fhBookTree->SetBranchAddress("Zincal",Zincal);
172 fhBookTree->SetBranchAddress("Erelcal",Erelcal);
173 fhBookTree->SetBranchAddress("Nthnd",&Nthnd);
174 fhBookTree->SetBranchAddress("Itubend",Itubend);
175 fhBookTree->SetBranchAddress("Iparnd",Iparnd);
176 fhBookTree->SetBranchAddress("Xinnd",Xinnd);
177 fhBookTree->SetBranchAddress("Yinnd",Yinnd);
178 fhBookTree->SetBranchAddress("Zinnd",Zinnd);
179 fhBookTree->SetBranchAddress("Xoutnd",Xoutnd);
180 fhBookTree->SetBranchAddress("Youtnd",Youtnd);
181 fhBookTree->SetBranchAddress("Zoutnd",Zoutnd);
182 fhBookTree->SetBranchAddress("Erelnd",Erelnd);
183 fhBookTree->SetBranchAddress("Timend",Timend);
184 fhBookTree->SetBranchAddress("Pathnd",Pathnd);
185 fhBookTree->SetBranchAddress("P0nd",P0nd);
186 fhBookTree->SetBranchAddress("Nthcard",&Nthcard);
187 fhBookTree->SetBranchAddress("Iparcard",Iparcard);
188 fhBookTree->SetBranchAddress("Icard",Icard);
189 fhBookTree->SetBranchAddress("Xincard",Xincard);
190 fhBookTree->SetBranchAddress("Yincard",Yincard);
191 fhBookTree->SetBranchAddress("Zincard",Zincard);
192 fhBookTree->SetBranchAddress("Xoutcard",Xoutcard);
193 fhBookTree->SetBranchAddress("Youtcard",Youtcard);
194 fhBookTree->SetBranchAddress("Zoutcard",Zoutcard);
195 fhBookTree->SetBranchAddress("Erelcard",Erelcard);
196 fhBookTree->SetBranchAddress("Timecard",Timecard);
197 fhBookTree->SetBranchAddress("Pathcard",Pathcard);
198 fhBookTree->SetBranchAddress("P0card",P0card);
199
200 fhBookTree->SetBranchStatus("*",0);
201
202 };
203
204
205
206 void Digitizer::Close(){
207
208 delete fhBookTree;
209
210 };
211
212
213
214
215 void Digitizer::Loop() {
216 //
217 // opens the raw output file and loops over the events
218 //
219 fOutputfile.open(fFilename, ios::out | ios::binary);
220 //fOutputfile.open(Form("Output%s",fFilename), ios::out | ios::binary);
221 //
222 // Load in memory and save at the beginning of file the calorimeter calibration
223 //
224 CaloLoadCalib();
225 DigitizeCALOCALIB();
226
227 // load, digitize and write tracker calibration
228 LoadTrackCalib();
229
230 DigitizeTrackCalib(1);
231 UInt_t length=fTracklength*2;
232 DigitizePSCU(length,0x12);
233 AddPadding();
234 WriteTrackCalib();
235
236 DigitizeTrackCalib(2);
237 length=fTracklength*2;
238 DigitizePSCU(length,0x13);
239 AddPadding();
240 WriteTrackCalib();
241
242 LoadMipCor(); // some initialization of parameters -not used now-
243 // end loading, digitizing and writing tracker calibration
244
245 //
246 // loops over the events
247 //
248
249 Int_t nentries = fhBookTree->GetEntriesFast();
250 Long64_t nbytes = 0;
251 for (Int_t i=0; i<nentries;i++) {
252 //
253 nbytes += fhBookTree->GetEntry(i);
254 // read detectors sequentially:
255 // http://www.ts.infn.it/fileadmin/documents/physics/experiments/wizard/cpu/gen_arch/RM_Acquisition.pdf
256 // on pamelatov:
257 // /cvs/yoda/techmodel/physics/NeutronDetectorReader.cpp
258 DigitizeTRIGGER();
259 DigitizeTOF();
260 DigitizeAC();
261 DigitizeCALO();
262 DigitizeTrack();
263 DigitizeS4();
264 DigitizeND();
265 //
266 // Add padding to 64 bits
267 //
268 AddPadding();
269 //
270 // Create CPU header, we need packet type (0x10 = physics data) and packet length.
271 //
272 UInt_t length=2*(fCALOlength+fACbuffer+fTracklength+fNDbuffer+fS4buffer)+fPadding+fTOFbuffer+fTRIGGERbuffer;
273 //UInt_t length=2*(fCALOlength+fACbuffer+fTracklength+fNDbuffer)+fPadding+fTOFbuffer+fTRIGGERbuffer;
274 DigitizePSCU(length,0x10);
275 if ( !i%100 ) std::cout << "writing event " << i << endl;
276 WriteData();
277 };
278
279 fOutputfile.close();
280 std::cout << "files closed" << endl << flush;
281
282 };
283
284 void Digitizer::AddPadding(){
285 //
286 Float_t pd0 = (fLen+16)/64.;
287 Float_t pd1 = pd0 - (Float_t)int(pd0);
288 Float_t padfrac = 64. - pd1 * 64.;
289 //
290 UInt_t padbytes = (UInt_t)padfrac;
291 if ( padbytes > 0 && padbytes < 64 ){
292 //
293 // here the padding length
294 //
295 fPadding = padbytes+64;
296 //
297 // random padding bytes
298 //
299 for (Int_t ur=0; ur<32; ur++){
300 fDataPadding[ur] = (UShort_t)rand();
301 };
302 };
303 };
304
305
306 void Digitizer::DigitizePSCU(UInt_t length, UChar_t type) {
307 //
308 UChar_t buff[16];
309 //
310 // CPU signature
311 //
312 buff[0] = 0xFA;
313 buff[1] = 0xFE;
314 buff[2] = 0xDE;
315 //
316 // packet type (twice)
317 //
318 buff[3] = type;
319 buff[4] = type;
320 //
321 // counter
322 //
323 fCounter++;
324 while ( fCounter > 16777215 ){
325 fCounter -= 16777215;
326 };
327 //
328 buff[5] = (UChar_t)(fCounter >> 16);
329 buff[6] = (UChar_t)(fCounter >> 8);
330 buff[7] = (UChar_t)fCounter;
331 //
332 // on board time
333 //
334 ULong64_t obt = fOBT + 30LL;
335 //
336 while ( obt > 4294967295LL ){
337 obt -= 4294967295LL;
338 };
339 fOBT = (UInt_t)obt;
340 //
341 buff[8] = (UChar_t)(fOBT >> 24);
342 buff[9] = (UChar_t)(fOBT >> 16);
343 buff[10] = (UChar_t)(fOBT >> 8);
344 buff[11] = (UChar_t)fOBT;
345 //
346 // Packet length
347 //
348 fLen = length;
349 //
350 buff[12] = (UChar_t)(fLen >> 16);
351 buff[13] = (UChar_t)(fLen >> 8);
352 buff[14] = (UChar_t)fLen;
353 //
354 // CPU header CRC
355 //
356 buff[15] = (BYTE)CM_Compute_CRC16((UINT16)0, (BYTE*)&buff, (UINT32)15);
357 //
358 memcpy(fDataPSCU,buff,16*sizeof(UChar_t));
359 //
360 };
361
362 void Digitizer::ClearCaloCalib(Int_t s){
363 //
364 fcstwerr[s] = 0;
365 fcperror[s] = 0.;
366 for ( Int_t d=0 ; d<11 ;d++ ){
367 Int_t pre = -1;
368 for ( Int_t j=0; j<96 ;j++){
369 if ( j%16 == 0 ) pre++;
370 fcalped[s][d][j] = 0.;
371 fcstwerr[s] = 0.;
372 fcperror[s] = 0.;
373 fcalgood[s][d][j] = 0.;
374 fcalthr[s][d][pre] = 0.;
375 fcalrms[s][d][j] = 0.;
376 fcalbase[s][d][pre] = 0.;
377 fcalvar[s][d][pre] = 0.;
378 };
379 };
380 return;
381 }
382
383 Int_t Digitizer::CaloLoadCalib(Int_t s,TString fcalname, UInt_t calibno){
384 //
385 //
386 UInt_t e = 0;
387 if ( s == 0 ) e = 0;
388 if ( s == 1 ) e = 2;
389 if ( s == 2 ) e = 3;
390 if ( s == 3 ) e = 1;
391 //
392 ifstream myfile;
393 myfile.open(fcalname.Data());
394 if ( !myfile ){
395 return(-107);
396 };
397 myfile.close();
398 //
399 TFile *File = new TFile(fcalname.Data());
400 if ( !File ) return(-108);
401 TTree *tr = (TTree*)File->Get("CalibCalPed");
402 if ( !tr ) return(-109);
403 //
404 TBranch *calo = tr->GetBranch("CalibCalPed");
405 //
406 pamela::CalibCalPedEvent *ce = 0;
407 tr->SetBranchAddress("CalibCalPed", &ce);
408 //
409 Long64_t ncalibs = calo->GetEntries();
410 //
411 if ( !ncalibs ) return(-110);
412 //
413 calo->GetEntry(calibno);
414 //
415 if (ce->cstwerr[s] != 0 && ce->cperror[s] == 0 ) {
416 fcstwerr[s] = ce->cstwerr[s];
417 fcperror[s] = ce->cperror[s];
418 for ( Int_t d=0 ; d<11 ;d++ ){
419 Int_t pre = -1;
420 for ( Int_t j=0; j<96 ;j++){
421 if ( j%16 == 0 ) pre++;
422 fcalped[s][d][j] = ce->calped[e][d][j];
423 fcalgood[s][d][j] = ce->calgood[e][d][j];
424 fcalthr[s][d][pre] = ce->calthr[e][d][pre];
425 fcalrms[s][d][j] = ce->calrms[e][d][j];
426 fcalbase[s][d][pre] = ce->calbase[e][d][pre];
427 fcalvar[s][d][pre] = ce->calvar[e][d][pre];
428 };
429 };
430 } else {
431 printf(" CALORIMETER - ERROR: problems finding a good calibration in this file! \n\n ");
432 File->Close();
433 return(-111);
434 };
435 File->Close();
436 return(0);
437 }
438
439
440 void Digitizer::DigitizeCALOCALIB() {
441 //
442 // Header of the four sections
443 //
444 fSecCalo[0] = 0xAA00; // XE
445 fSecCalo[1] = 0xB100; // XO
446 fSecCalo[2] = 0xB600; // YE
447 fSecCalo[3] = 0xAD00; // YO
448 //
449 // length of the data is 0x1215
450 //
451 fSecCALOLength[0] = 0x1215; // XE
452 fSecCALOLength[1] = 0x1215; // XO
453 fSecCALOLength[2] = 0x1215; // YE
454 fSecCALOLength[3] = 0x1215; // YO
455 //
456 Int_t chksum = 0;
457 UInt_t tstrip = 0;
458 UInt_t fSecPointer = 0;
459 //
460 for (Int_t sec=0; sec < 4; sec++){
461 //
462 // sec = 0 -> XE 1 -> XO 2-> YE 3 -> YO
463 //
464 fCALOlength = 0;
465 memset(fDataCALO,0,sizeof(UShort_t)*fCALObuffer);
466 fSecPointer = fCALOlength;
467 //
468 // First of all we have section header and packet length
469 //
470 fDataCALO[fCALOlength] = fSecCalo[sec];
471 fCALOlength++;
472 fDataCALO[fCALOlength] = fSecCALOLength[sec];
473 fCALOlength++;
474 //
475 // Section XO is read in the opposite direction respect to the others
476 //
477 chksum = 0;
478 //
479 for (Int_t plane=0; plane < 11; plane++){
480 //
481 if ( sec == 1 ) tstrip = fCALOlength + 96*2;
482 //
483 for (Int_t strip=0; strip < 96; strip++){
484 //
485 chksum += (Int_t)fcalped[sec][plane][strip];
486 //
487 // save value
488 //
489 if ( sec == 1 ){
490 tstrip -= 2;
491 fDataCALO[tstrip] = (Int_t)fcalped[sec][plane][strip];
492 fDataCALO[tstrip+1] = (Int_t)fcalgood[sec][plane][strip];
493 } else {
494 fDataCALO[fCALOlength] = (Int_t)fcalped[sec][plane][strip];
495 fDataCALO[fCALOlength+1] = (Int_t)fcalgood[sec][plane][strip];
496 };
497 fCALOlength +=2;
498 };
499 //
500 };
501 //
502 fDataCALO[fCALOlength] = (UShort_t)chksum;
503 fCALOlength++;
504 fDataCALO[fCALOlength] = 0;
505 fCALOlength++;
506 fDataCALO[fCALOlength] = (UShort_t)((Int_t)(chksum >> 16));
507 fCALOlength++;
508 //
509 // Section XO is read in the opposite direction respect to the others
510 //
511 chksum = 0;
512 //
513 for (Int_t plane=0; plane < 11; plane++){
514 //
515 if ( sec == 1 ) tstrip = fCALOlength+6*2;
516 //
517 for (Int_t strip=0; strip < 6; strip++){
518 //
519 chksum += (Int_t)fcalthr[sec][plane][strip];
520 //
521 // save value
522 //
523 if ( sec == 1 ){
524 tstrip -= 2;
525 fDataCALO[tstrip] = 0;
526 fDataCALO[tstrip+1] = (Int_t)fcalthr[sec][plane][strip];
527 } else {
528 fDataCALO[fCALOlength] = 0;
529 fDataCALO[fCALOlength+1] = (Int_t)fcalthr[sec][plane][strip];
530 };
531 fCALOlength +=2;
532 };
533 //
534 };
535 //
536 fDataCALO[fCALOlength] = 0;
537 fCALOlength++;
538 fDataCALO[fCALOlength] = (UShort_t)chksum;
539 fCALOlength++;
540 fDataCALO[fCALOlength] = 0;
541 fCALOlength++;
542 fDataCALO[fCALOlength] = (UShort_t)((Int_t)(chksum >> 16));
543 fCALOlength++;
544 //
545 // Section XO is read in the opposite direction respect to the others
546 //
547 for (Int_t plane=0; plane < 11; plane++){
548 //
549 if ( sec == 1 ) tstrip = fCALOlength+96*2;
550 //
551 for (Int_t strip=0; strip < 96; strip++){
552 //
553 // save value
554 //
555 if ( sec == 1 ){
556 tstrip -= 2;
557 fDataCALO[tstrip] = 0;
558 fDataCALO[tstrip+1] = (Int_t)fcalrms[sec][plane][strip];
559 } else {
560 fDataCALO[fCALOlength] = 0;
561 fDataCALO[fCALOlength+1] = (Int_t)fcalrms[sec][plane][strip];
562 };
563 fCALOlength += 2;
564 };
565 //
566 };
567 //
568 // Section XO is read in the opposite direction respect to the others
569 //
570 for (Int_t plane=0; plane < 11; plane++){
571 //
572 if ( sec == 1 ) tstrip = fCALOlength+6*4;
573 //
574 for (Int_t strip=0; strip < 6; strip++){
575 //
576 // save value
577 //
578 if ( sec == 1 ){
579 tstrip -= 4;
580 fDataCALO[tstrip] = 0;
581 fDataCALO[tstrip+1] = (Int_t)fcalbase[sec][plane][strip];
582 fDataCALO[tstrip+2] = 0;
583 fDataCALO[tstrip+3] = (Int_t)fcalvar[sec][plane][strip];
584 } else {
585 fDataCALO[fCALOlength] = 0;
586 fDataCALO[fCALOlength+1] = (Int_t)fcalbase[sec][plane][strip];
587 fDataCALO[fCALOlength+2] = 0;
588 fDataCALO[fCALOlength+3] = (Int_t)fcalvar[sec][plane][strip];
589 };
590 fCALOlength +=4;
591 };
592 //
593 };
594 //
595 //
596 // here we calculate and save the CRC
597 //
598 fDataCALO[fCALOlength] = 0;
599 fCALOlength++;
600 Short_t CRC = 0;
601 for (UInt_t i=0; i<(fCALOlength-fSecPointer); i++){
602 CRC=crc(CRC,fDataCALO[i+fSecPointer]);
603 };
604 fDataCALO[fCALOlength] = (UShort_t)CRC;
605 fCALOlength++;
606 //
607 UInt_t length=fCALOlength*2;
608 DigitizePSCU(length,0x18);
609 //
610 // Add padding to 64 bits
611 //
612 AddPadding();
613 //
614 fOutputfile.write(reinterpret_cast<char*>(fDataPSCU),sizeof(UShort_t)*fPSCUbuffer);
615 UShort_t temp[1000000];
616 memset(temp,0,sizeof(UShort_t)*1000000);
617 swab(fDataCALO,temp,sizeof(UShort_t)*fCALOlength); // WE MUST SWAP THE BYTES!!!
618 fOutputfile.write(reinterpret_cast<char*>(temp),sizeof(UShort_t)*fCALOlength);
619 //
620 // padding to 64 bytes
621 //
622 if ( fPadding ){
623 fOutputfile.write(reinterpret_cast<char*>(fDataPadding),sizeof(UChar_t)*fPadding);
624 };
625 //
626 //
627 };
628 //
629 };
630
631 void Digitizer::CaloLoadCalib() {
632 //
633 fGivenCaloCalib = 0; // ####@@@@ should be given as input par @@@@####
634 //
635 // first of all load the MIP to ADC conversion values
636 //
637 stringstream calfile;
638 Int_t error = 0;
639 GL_PARAM *glparam = new GL_PARAM();
640 //
641 // determine where I can find calorimeter ADC to MIP conversion file
642 //
643 error = 0;
644 error = glparam->Query_GL_PARAM(3,101,fDbc);
645 //
646 calfile.str("");
647 calfile << glparam->PATH.Data() << "/";
648 calfile << glparam->NAME.Data();
649 //
650 printf("\n Using Calorimeter ADC to MIP conversion file: \n %s \n",calfile.str().c_str());
651 FILE *f;
652 f = fopen(calfile.str().c_str(),"rb");
653 //
654 memset(fCalomip,0,4224*sizeof(fCalomip[0][0][0]));
655 //
656 for (Int_t m = 0; m < 2 ; m++ ){
657 for (Int_t k = 0; k < 22; k++ ){
658 for (Int_t l = 0; l < 96; l++ ){
659 fread(&fCalomip[m][k][l],sizeof(fCalomip[m][k][l]),1,f);
660 };
661 };
662 };
663 fclose(f);
664 //
665 // determine which calibration has to be used and load it for each section
666 //
667 GL_CALO_CALIB *glcalo = new GL_CALO_CALIB();
668 GL_ROOT *glroot = new GL_ROOT();
669 TString fcalname;
670 UInt_t idcalib;
671 UInt_t calibno;
672 UInt_t utime = 0;
673 //
674 for (UInt_t s=0; s<4; s++){
675 //
676 // clear calo calib variables for section s
677 //
678 ClearCaloCalib(s);
679 //
680 if ( fGivenCaloCalib ){
681 //
682 // a time has been given as input on the command line so retrieve the calibration that preceed that time
683 //
684 glcalo->Query_GL_CALO_CALIB(fGivenCaloCalib,utime,s,fDbc);
685 //
686 calibno = glcalo->EV_ROOT;
687 idcalib = glcalo->ID_ROOT_L0;
688 //
689 // determine path and name and entry of the calibration file
690 //
691 printf("\n");
692 printf(" ** SECTION %i **\n",s);
693 //
694 glroot->Query_GL_ROOT(idcalib,fDbc);
695 //
696 stringstream name;
697 name.str("");
698 name << glroot->PATH.Data() << "/";
699 name << glroot->NAME.Data();
700 //
701 fcalname = (TString)name.str().c_str();
702 //
703 printf("\n Section %i : using file %s calibration at entry %i: \n",s,fcalname.Data(),calibno);
704 //
705 } else {
706 error = 0;
707 error = glparam->Query_GL_PARAM(1,104,fDbc);
708 //
709 calfile.str("");
710 calfile << glparam->PATH.Data() << "/";
711 calfile << glparam->NAME.Data();
712 //
713 printf("\n Section %i : using default calorimeter calibration: \n %s \n",s,calfile.str().c_str());
714 //
715 fcalname = (TString)calfile.str().c_str();
716 calibno = s;
717 //
718 };
719 //
720 // load calibration variables in memory
721 //
722 CaloLoadCalib(s,fcalname,calibno);
723 //
724 };
725 //
726 // at this point we have in memory the calorimeter calibration and we can save it to disk in the correct format and use it to digitize the data
727 //
728 delete glparam;
729 delete glcalo;
730 delete glroot;
731 };
732
733 void Digitizer::DigitizeCALO() {
734 //
735 fModCalo = 0; // 0 is RAW, 1 is COMPRESS, 2 is FULL ####@@@@ should be given as input par @@@@####
736 //
737 //
738 //
739 fCALOlength = 0; // reset total dimension of calo data
740 //
741 // gpamela variables to be used
742 //
743 fhBookTree->SetBranchStatus("Nthcali",1);
744 fhBookTree->SetBranchStatus("Icaplane",1);
745 fhBookTree->SetBranchStatus("Icastrip",1);
746 fhBookTree->SetBranchStatus("Icamod",1);
747 fhBookTree->SetBranchStatus("Enestrip",1);
748 //
749 // call different routines depending on the acq mode you want to simulate
750 //
751 switch ( fModCalo ){
752 case 0:
753 this->DigitizeCALORAW();
754 break;
755 case 1:
756 this->DigitizeCALOCOMPRESS();
757 break;
758 case 2:
759 this->DigitizeCALOFULL();
760 break;
761 };
762 //
763 };
764
765 Float_t Digitizer::GetCALOen(Int_t sec, Int_t plane, Int_t strip){
766 //
767 // determine plane and strip
768 //
769 Int_t mplane = 0;
770 //
771 // wrong!
772 //
773 // if ( sec == 0 || sec == 3 ) mplane = (plane * 4) + sec + 1;
774 // if ( sec == 1 ) mplane = (plane * 4) + 2 + 1;
775 // if ( sec == 2 ) mplane = (plane * 4) + 1 + 1;
776 //
777 if ( sec == 0 ) mplane = plane * 4 + 1; // it must be 0, 4, 8, ... (+1) from plane = 0, 11
778 if ( sec == 1 ) mplane = plane * 4 + 2 + 1; // it must be 2, 6, 10, ... (+1) from plane = 0, 11
779 if ( sec == 2 ) mplane = plane * 4 + 3 + 1; // it must be 3, 7, 11, ... (+1) from plane = 0, 11
780 if ( sec == 3 ) mplane = plane * 4 + 1 + 1; // it must be 1, 5, 9, ... (+1) from plane = 0, 11
781 //
782 Int_t mstrip = strip + 1;
783 //
784 // search energy release in gpamela output
785 //
786 for (Int_t i=0; i<Nthcali;i++){
787 if ( Icaplane[i] == mplane && Icastrip[i] == mstrip ){
788 return (Enestrip[i]);
789 };
790 };
791 //
792 // if not found it means no energy release so return 0.
793 //
794 return(0.);
795 };
796
797 void Digitizer::DigitizeCALORAW() {
798 //
799 // some variables
800 //
801 Float_t ens = 0.;
802 UInt_t adcsig = 0;
803 UInt_t adcbase = 0;
804 UInt_t adc = 0;
805 Int_t pre = 0;
806 UInt_t l = 0;
807 UInt_t lpl = 0;
808 UInt_t tstrip = 0;
809 UInt_t fSecPointer = 0;
810 Double_t pedenoise;
811 Float_t rms = 0.;
812 Float_t pedestal = 0.;
813 //
814 // clean the data structure
815 //
816 memset(fDataCALO,0,sizeof(UShort_t)*fCALObuffer);
817 //
818 // Header of the four sections
819 //
820 fSecCalo[0] = 0xEA08; // XE
821 fSecCalo[1] = 0xF108; // XO
822 fSecCalo[2] = 0xF608; // YE
823 fSecCalo[3] = 0xED08; // YO
824 //
825 // length of the data is 0x0428 in RAW mode
826 //
827 fSecCALOLength[0] = 0x0428; // XE
828 fSecCALOLength[1] = 0x0428; // XO
829 fSecCALOLength[2] = 0x0428; // YE
830 fSecCALOLength[3] = 0x0428; // YO
831 //
832 // let's start
833 //
834 fCALOlength = 0;
835 //
836 for (Int_t sec=0; sec < 4; sec++){
837 //
838 // sec = 0 -> XE 1 -> XO 2-> YE 3 -> YO
839 //
840 l = 0; // XE and XO are Y planes
841 if ( sec < 2 ) l = 1; // while YE and YO are X planes
842 //
843 fSecPointer = fCALOlength;
844 //
845 // First of all we have section header and packet length
846 //
847 fDataCALO[fCALOlength] = fSecCalo[sec];
848 fCALOlength++;
849 fDataCALO[fCALOlength] = fSecCALOLength[sec];
850 fCALOlength++;
851 //
852 // selftrigger coincidences - in the future we should add here some code to simulate timing response of pre-amplifiers
853 //
854 for (Int_t autoplane=0; autoplane < 7; autoplane++){
855 fDataCALO[fCALOlength] = 0x0000;
856 fCALOlength++;
857 };
858 //
859 //
860 // here comes data
861 //
862 //
863 // Section XO is read in the opposite direction respect to the others
864 //
865 if ( sec == 1 ){
866 tstrip = 96*11 + fCALOlength;
867 } else {
868 tstrip = 0;
869 };
870 //
871 pre = -1;
872 //
873 for (Int_t strip=0; strip < 96; strip++){
874 //
875 // which is the pre for this strip?
876 //
877 if (strip%16 == 0) {
878 pre++;
879 };
880 //
881 if ( sec == 1 ) tstrip -= 11;
882 //
883 for (Int_t plane=0; plane < 11; plane++){
884 //
885 // here is wrong!!!!
886 //
887 //
888 // if ( plane%2 == 0 && sec%2 != 0){
889 // lpl = plane*2;
890 // } else {
891 // lpl = (plane*2) + 1;
892 // };
893 //
894 if ( sec == 0 || sec == 3 ) lpl = plane * 2;
895 if ( sec == 1 || sec == 2 ) lpl = (plane * 2) + 1;
896 //
897 // get the energy in GeV from the simulation for that strip
898 //
899 ens = this->GetCALOen(sec,plane,strip);
900 //
901 // convert it into ADC channels
902 //
903 adcsig = int(ens*fCalomip[l][lpl][strip]/fCALOGeV2MIPratio);
904 //
905 // sum baselines
906 //
907 adcbase = (UInt_t)fcalbase[sec][plane][pre];
908 //
909 // add noise and pedestals
910 //
911 pedestal = fcalped[sec][plane][strip];
912 rms = fcalrms[sec][plane][strip]/4.;
913 //
914 // Add random gaussian noise of RMS rms and Centered in the pedestal
915 //
916 pedenoise = gRandom->Gaus((Double_t)pedestal,(Double_t)rms);
917 //
918 // Sum all contribution
919 //
920 adc = adcsig + adcbase + (Int_t)round(pedenoise);
921 //
922 // Signal saturation
923 //
924 if ( adc > 0x7FFF ) adc = 0x7FFF;
925 //
926 // save value
927 //
928 if ( sec == 1 ){
929 fDataCALO[tstrip] = adc;
930 tstrip++;
931 } else {
932 fDataCALO[fCALOlength] = adc;
933 };
934 fCALOlength++;
935 //
936 };
937 //
938 if ( sec == 1 ) tstrip -= 11;
939 //
940 };
941 //
942 // here we calculate and save the CRC
943 //
944 Short_t CRC = 0;
945 for (UInt_t i=0; i<(fCALOlength-fSecPointer); i++){
946 CRC=crc(CRC,fDataCALO[i+fSecPointer]);
947 };
948 fDataCALO[fCALOlength] = (UShort_t)CRC;
949 fCALOlength++;
950 //
951 };
952 //
953 // for (Int_t i=0; i<fCALOlength; i++){
954 // printf(" WORD %i DIGIT %0x \n",i,fDataCALO[i]);
955 // };
956 //
957 };
958
959 void Digitizer::DigitizeCALOCOMPRESS() {
960 //
961 printf(" COMPRESS MODE STILL NOT IMPLEMENTED! \n");
962 //
963 this->DigitizeCALORAW();
964 return;
965 //
966 //
967 //
968 fSecCalo[0] = 0xEA00;
969 fSecCalo[1] = 0xF100;
970 fSecCalo[2] = 0xF600;
971 fSecCalo[3] = 0xED00;
972 //
973 // length of the data in DSP mode must be calculated on fly during digitization
974 //
975 memset(fSecCALOLength,0x0,4*sizeof(UShort_t));
976 //
977 // here comes raw data
978 //
979 Int_t en = 0;
980 //
981 for (Int_t sec=0; sec < 4; sec++){
982 fDataCALO[en] = fSecCalo[sec];
983 en++;
984 fDataCALO[en] = fSecCALOLength[sec];
985 en++;
986 for (Int_t plane=0; plane < 11; plane++){
987 for (Int_t strip=0; strip < 11; strip++){
988 fDataCALO[en] = 0x0;
989 en++;
990 };
991 };
992 };
993 //
994 };
995
996 void Digitizer::DigitizeCALOFULL() {
997 //
998 printf(" FULL MODE STILL NOT IMPLEMENTED! \n");
999 //
1000 this->DigitizeCALORAW();
1001 return;
1002 //
1003 fSecCalo[0] = 0xEA00;
1004 fSecCalo[1] = 0xF100;
1005 fSecCalo[2] = 0xF600;
1006 fSecCalo[3] = 0xED00;
1007 //
1008 // length of the data in DSP mode must be calculated on fly during digitization
1009 //
1010 memset(fSecCALOLength,0x0,4*sizeof(UShort_t));
1011 //
1012 // here comes raw data
1013 //
1014 Int_t en = 0;
1015 //
1016 for (Int_t sec=0; sec < 4; sec++){
1017 fDataCALO[en] = fSecCalo[sec];
1018 en++;
1019 fDataCALO[en] = fSecCALOLength[sec];
1020 en++;
1021 for (Int_t plane=0; plane < 11; plane++){
1022 for (Int_t strip=0; strip < 11; strip++){
1023 fDataCALO[en] = 0x0;
1024 en++;
1025 };
1026 };
1027 };
1028 //
1029 };
1030
1031 void Digitizer::DigitizeTRIGGER() {
1032 //fDataTrigger: 153 bytes
1033 for (Int_t j=0; j < 153; j++)
1034 fDataTrigger[0]=0x00;
1035 };
1036
1037 Int_t Digitizer::DigitizeTOF() {
1038 //fDataTof: 12 x 23 bytes (=276 bytes)
1039 UChar_t *pTof=fDataTof;
1040 Bool_t DEBUG=false;
1041
1042 // --- activate branches:
1043 fhBookTree->SetBranchStatus("Nthtof",1);
1044 fhBookTree->SetBranchStatus("Ipltof",1);
1045 fhBookTree->SetBranchStatus("Ipaddle",1);
1046 fhBookTree->SetBranchStatus("Xintof",1);
1047 fhBookTree->SetBranchStatus("Yintof",1);
1048 fhBookTree->SetBranchStatus("Xouttof",1);
1049 fhBookTree->SetBranchStatus("Youttof",1);
1050 fhBookTree->SetBranchStatus("Ereltof",1);
1051 fhBookTree->SetBranchStatus("Timetof",1);
1052 // not yet used: Zintof, Xouttof, Youttof, Zouttof
1053
1054 // ------ evaluate energy in each pmt: ------
1055 // strip geometry (lenght/width)
1056 Float_t dimel[6] = {33.0, 40.8 ,18.0, 15.0, 15.0, 18.0};
1057 //Float_t dimes[6] = {5.1, 5.5, 7.5, 9.0, 6.0, 5.0};
1058
1059 // S11 8 paddles 33.0 x 5.1 cm
1060 // S12 6 paddles 40.8 x 5.5 cm
1061 // S21 2 paddles 18.0 x 7.5 cm
1062 // S22 2 paddles 15.0 x 9.0 cm
1063 // S31 3 paddles 15.0 x 6.0 cm
1064 // S32 3 paddles 18.0 x 5.0 cm
1065
1066 // distance from the interaction point to the pmts (right,left)
1067 Float_t xpath[2]={0., 0.}; /*path(cm) in X per S12,S21,S32 verso il pmt DX o SX*/
1068 Float_t ypath[2]={0., 0.}; /*path(cm) in Y per S11,S22,S31 verso il pmt DX o SX*/
1069 Float_t FGeo[2]={0., 0.}; /* fattore geometrico */
1070
1071 const Float_t Pho_keV = 10.; // photons per keV in scintillator
1072 const Float_t echarge = 1.6e-19; // carica dell'elettrone
1073 Float_t Npho=0.;
1074 Float_t QevePmt_pC[48];
1075 Float_t QhitPad_pC[2]={0., 0.};
1076 Float_t QhitPmt_pC[2]={0., 0.};
1077 Float_t pmGain = 3.5e6; /* Gain: per il momento uguale per tutti */
1078 Float_t effi=0.21; /* Efficienza di fotocatodo */
1079 Float_t ADC_pC=1.666667; // ADC_ch/pC conversion = 0.6 pC/channel (+30 di offset)
1080 Float_t ADCoffset=30.;
1081 Int_t ADClast=4095; // no signal --> ADC ch=4095
1082 Int_t ADCtof[48];
1083 //Float_t ADCsat=3100; ci pensiamo in futuro !
1084 //Float_t pCsat=2500;
1085 for(Int_t i=0; i<48; i++){
1086 QevePmt_pC[i] = 0;
1087 ADCtof[i]=0;
1088 }
1089
1090 // ------ read calibration file (get A1, A2, lambda1, lambda2)
1091 ifstream fileTriggerCalib;
1092 TString ftrigname="TrigCalibParam.txt";
1093 fileTriggerCalib.open(ftrigname.Data());
1094 if ( !fileTriggerCalib ) {
1095 printf("debug: no trigger calib file!\n");
1096 return(-117); //check output!
1097 };
1098 Float_t atte1[48],atte2[48],lambda1[48],lambda2[48];
1099 Int_t temp=0;
1100 // correct readout WM Oct '07
1101 for(Int_t i=0; i<48; i++){
1102 fileTriggerCalib >> temp;
1103 fileTriggerCalib >> atte1[i];
1104 fileTriggerCalib >> lambda1[i];
1105 fileTriggerCalib >> atte2[i];
1106 fileTriggerCalib >> lambda2[i];
1107 fileTriggerCalib >> temp;
1108 }
1109 fileTriggerCalib.close();
1110
1111 // Read from file the 48*4 values of the attenuation fit function
1112 // NB: lambda<0; x,y defined in gpamela (=0 in the centre of the cavity)
1113 // Qhitpmt_pC = atte1 * exp(x/lambda1) + atte2 * exp(x/lambda2)
1114
1115 // fine lettura dal file */
1116
1117 //const Int_t nmax=??; = Nthtof
1118 Int_t ip, ipad;
1119 //Int_t ipmt;
1120 Int_t pmtleft=0, pmtright=0;
1121 Int_t *pl, *pr;
1122 pl = &pmtleft;
1123 pr = &pmtright;
1124
1125 // TDC variables:
1126 Int_t TDClast=4095; // no signal --> ADC ch=4095
1127 Int_t TDCint[48];
1128 Float_t tdc[48],tdc1[48],tdcpmt[48];
1129 for(Int_t i=0; i<48; i++)
1130 tdcpmt[i] = 1000.;
1131 Float_t thresh=10.; // to be defined better... (Wolfgang)
1132
1133 // === TDC: simulate timing for each paddle
1134 Float_t dt1 = 285.e-12 ; // single PMT resolution
1135 Float_t tdcres[50],c1_S[50],c2_S[50],c3_S[50];
1136 for(Int_t j=0;j<48;j++) tdcres[j] = 50.E-12; // TDC resolution 50 picosec
1137 for(Int_t j=0;j<48;j++) c1_S[j] = 500.; // cable length in channels
1138 for(Int_t j=0;j<48;j++) c2_S[j] = 0.;
1139 for(Int_t j=0;j<48;j++) c3_S[j] = 1000.;
1140 for(Int_t j=0;j<48;j++) c1_S[j] = c1_S[j]*tdcres[j]; // cable length in sec
1141 for(Int_t j=0;j<48;j++) c2_S[j] = c2_S[j]*tdcres[j];
1142 // ih = 0 + i1; // not used?? (Silvio)
1143
1144 /* ********************************** start loop over hits */
1145
1146 for(Int_t nh=0; nh<Nthtof; nh++){
1147
1148 for(Int_t j=0; j<2; j++) { // already done!! remove???
1149 xpath[j]=0.;
1150 ypath[j]=0.;
1151 FGeo[j]=0.;
1152 }
1153
1154 Float_t s_l_g[6] = {8.0, 8.0, 20.9, 22.0, 9.8, 8.3 }; // length of the lightguide
1155 Float_t t1,t2,veff,veff1,veff0 ;
1156 veff0 = 100.*1.0e8 ; // light velocity in the scintillator in m/sec
1157 veff1 = 100.*1.5e8; // light velocity in the lightguide in m/sec
1158 veff=veff0; // signal velocity in the paddle
1159
1160 t1 = Timetof[nh] ; // Start
1161 t2 = Timetof[nh] ;
1162
1163 // Donatella: redefinition plane and pad for vectors in C
1164 ip = Ipltof[nh]-1;
1165 ipad = Ipaddle[nh]-1;
1166 pmtleft=0;
1167 pmtright=0;
1168
1169 if (ip<6) {
1170 Paddle2Pmt(ip, ipad, &pmtleft, &pmtright);
1171
1172 // per avere anche la corrispondenza pmt --> half board e canale
1173 // metodo GetPMTIndex(Int_t ipmt, Int_t &hb, Int_t &ch) // non lo usiamo x ora
1174
1175 // evaluates mean position and path inside the paddle
1176
1177 Float_t tpos=0.;
1178 Float_t path[2] = {0., 0.};
1179 //--- Strip in Y = S11,S22,S31 ------
1180 if(ip==0 || ip==3 || ip==4)
1181 tpos = (Yintof[nh]+Youttof[nh])/2.;
1182 else
1183 if(ip==1 || ip==2 || ip==5) //--- Strip in X per S12,S21,S32
1184 tpos = (Xintof[nh]+Xouttof[nh])/2.;
1185 else //if (ip!=6)
1186 printf("*** WARNING TOF: this option should never occur! (ip=%2i, nh=%2i)\n",ip,nh);
1187 path[0]= tpos + dimel[ip]/2.;
1188 path[1]= dimel[ip]/2.- tpos;
1189
1190 // cout <<"Strip N. ="<< ipaddle <<" piano n.= "<< iplane <<" POSIZ = "<< tpos <<"\n";
1191
1192 if (DEBUG) {
1193 cout <<" plane "<<ip<<" strip # ="<< ipad <<" tpos "<< tpos <<"\n";
1194 cout <<"pmtleft, pmtright "<<pmtleft<<" "<<pmtright<<endl;
1195 }
1196
1197 // constant geometric factor, for the moment
1198 FGeo[0] =0.5;
1199 FGeo[1] =0.5;
1200 // FGeo[1] = atan(path[1]/dimes[ip])/6.28318; // frazione fotoni verso SX
1201 // FGeo[2] = atan(path[2]/dimes[ip])/6.28318; // e verso DX
1202
1203 /* rimando la fluttuazione poissoniana sui fotoni prodotti
1204 sto studiando come funziona la funzione:
1205 long int i = sto.Poisson(double x); */
1206 // Npho = Poisson(ERELTOF[nh])*Pho_keV*1e6 Eloss in GeV ?
1207 Npho = Ereltof[nh]*Pho_keV*1.0e6; // Eloss in GeV ?
1208
1209 Float_t knorm[2]={0., 0.}; // Donatella
1210 Float_t Atten[2]={0., 0.}; // Donatella
1211 for(Int_t j=0; j<2; j++){
1212 QhitPad_pC[j]= Npho*FGeo[j]*effi*pmGain*echarge*1.E12; // corrected WM
1213 /* knorm[j]=QhitPad_pC[j]/(atte1[pmtleft+j]*exp((dimel[ip]/2.*pow(-1,j+1))/lambda1[pmtleft+j]) +
1214 atte2[pmtleft+j]*exp((dimel[ip]/2.*pow(-1,j+1))/lambda2[pmtleft+j]));
1215 Atten[j]=knorm[j]*(atte1[pmtleft+j]*exp(tpos/lambda1[pmtleft+j]) +
1216 atte2[pmtleft+j]*exp(tpos/lambda2[pmtleft+j]));
1217 QhitPmt_pC[j]= QhitPad_pC[j]*Atten[j];
1218 */
1219 // WM
1220 knorm[j]=atte1[pmtleft+j]*exp(lambda1[pmtleft+j]*dimel[ip]/2.*pow(-1,j+1)) +
1221 atte2[pmtleft+j]*exp(lambda2[pmtleft+j]*dimel[ip]/2.*pow(-1,j+1));
1222 Atten[j]=atte1[pmtleft+j]*exp(tpos*lambda1[pmtleft+j]) +
1223 atte2[pmtleft+j]*exp(tpos*lambda2[pmtleft+j]) ;
1224 QhitPmt_pC[j]= QhitPad_pC[j]*Atten[j]/knorm[j];
1225 if (DEBUG) {
1226 cout<<"pmtleft "<<pmtleft<<" j "<<j<<endl;
1227 cout<<" atte1 "<<atte1[pmtleft+j]<<"lambda1 "<<lambda1[pmtleft+j]<<" atte2 "<<atte2[pmtleft+j]<<"lambda2 "<<lambda2[pmtleft+j] <<endl;
1228 cout<<j<<" tpos "<<tpos<<" knorm "<<knorm[j]<<" "<<Atten[j]<<" "<<"QhitPmt_pC "<<QhitPmt_pC[j]<<endl;
1229 }
1230 }
1231
1232 if (DEBUG)
1233 cout<<"Npho "<<Npho<<" QhitPmt_pC "<<QhitPmt_pC[0]<<" "<<QhitPmt_pC[1]<<endl;
1234
1235 QevePmt_pC[pmtleft] += QhitPmt_pC[0];
1236 QevePmt_pC[pmtright] += QhitPmt_pC[1];
1237
1238 // TDC
1239 t2 = t2 + fabs(path[0]/veff) + s_l_g[ip]/veff1 ; // Signal reaches PMT
1240 t1 = t1 + fabs(path[1]/veff) + s_l_g[ip]/veff1;
1241
1242 TRandom r;
1243 t1 = r.Gaus(t1,dt1); //apply gaussian error dt
1244 t2 = r.Gaus(t2,dt1); //apply gaussian error dt
1245
1246 t1 = t1 + c1_S[pmtleft] ; // Signal reaches Discriminator ,TDC starts to run
1247 t2 = t2 + c1_S[pmtright] ;
1248
1249 // check if signal is above threshold
1250 // then check if tdcpmt is already filled by another hit...
1251 // only re-fill if time is smaller
1252
1253 if (QhitPmt_pC[0] > thresh) {
1254 if (tdcpmt[pmtleft] == 1000.) { // fill for the first time
1255 tdcpmt[pmtleft] = t1;
1256 tdc[pmtleft] = t1 + c2_S[pmtleft] ; // Signal reaches Coincidence
1257 }
1258 if (tdcpmt[pmtleft] < 1000.) // is already filled!
1259 if (t1 < tdcpmt[pmtleft]) {
1260 tdcpmt[pmtleft] = t1;
1261 t1 = t1 + c2_S[pmtleft] ; // Signal reaches Coincidence
1262 tdc[pmtleft] = t1;
1263 }
1264 }
1265 if (QhitPmt_pC[1] > thresh) {
1266 if (tdcpmt[pmtright] == 1000.) { // fill for the first time
1267 tdcpmt[pmtright] = t2;
1268 tdc[pmtright] = t2 + c2_S[pmtright] ; // Signal reaches Coincidence
1269 }
1270 if (tdcpmt[pmtright] < 1000.) // is already filled!
1271 if (t2 < tdcpmt[pmtright]) {
1272 tdcpmt[pmtright] = t2;
1273 t2 = t2 + c2_S[pmtright] ;
1274 tdc[pmtright] = t2;
1275 }
1276 }
1277
1278 if (DEBUG)
1279 cout<<nh<<" "<<Timetof[nh]<<" "<<t1<<" "<<t2<<endl;
1280
1281 } // ip < 6
1282
1283 }; // **************************************** end loop over hits
1284
1285 // ====== ADC ======
1286 for(Int_t i=0; i<48; i++){
1287 if(QevePmt_pC[i] != 0.){
1288 ADCtof[i]= (Int_t)(ADC_pC*QevePmt_pC[i] + ADCoffset);
1289 if(ADCtof[i]> ADClast) ADCtof[i]=ADClast;
1290 } else
1291 ADCtof[i]= ADClast;
1292 }
1293
1294
1295 // ====== build TDC coincidence ======
1296
1297 Float_t t_coinc = 0;
1298 Int_t ilast = 100;
1299 for (Int_t ii=0; ii<48;ii++)
1300 if (tdc[ii] > t_coinc) {
1301 t_coinc = tdc[ii];
1302 ilast = ii;
1303 }
1304
1305 // cout<<ilast<<" "<<t_coinc<<endl;
1306 // At t_coinc trigger condition is fulfilled
1307
1308 for (Int_t ii=0; ii<48;ii++){
1309 // if (tdc[ii] != 0) tdc1[ii] = t_coinc - tdc[ii]; // test 1
1310 if (tdc[ii] != 0) tdc1[ii] = t_coinc - tdcpmt[ii]; // test 2
1311 tdc1[ii] = tdc1[ii]/tdcres[ii]; // divide by TDC resolution
1312 if (tdc[ii] != 0) tdc1[ii] = tdc1[ii] + c3_S[ii]; // add cable length c3
1313
1314 } // missing parenthesis inserted! (Silvio)
1315
1316 for(Int_t i=0; i<48; i++){
1317 if(tdc1[i] != 0.){
1318 TDCint[i]=(Int_t)tdc1[i];
1319 if (DEBUG)
1320 cout<<i<<" "<<TDCint[i]<<endl;
1321 //ADC[i]= ADC_pC * QevePmt_pC[i] + ADCoffset;
1322 //if(ADC[i]> ADClast) ADC[i]=ADClast;
1323 } else
1324 TDCint[i]= TDClast;
1325 }
1326
1327 if (DEBUG)
1328 cout<<"-----------"<<endl;
1329
1330 // ====== write fDataTof =======
1331 UChar_t tofBin;
1332 for (Int_t j=0; j < 12; j++){
1333 Int_t j12=j*12;
1334 fDataTof[j12+0]=0x00; // TDC_ID
1335 fDataTof[j12+1]=0x00; // EV_COUNT
1336 fDataTof[j12+2]=0x00; // TDC_MASK (1)
1337 fDataTof[j12+3]=0x00; // TDC_MASK (2)
1338 for (Int_t k=0; k < 4; k++){
1339 Int_t jk12=j12+k;
1340 tofBin=(UChar_t)(ADCtof[k+4*j]/256); // ADC# (msb) (#=1+k+4*j)
1341 fDataTof[jk12+4] = Bin2GrayTof(tofBin,fDataTof[jk12+4]);
1342 tofBin=(UChar_t)(ADCtof[k+4*j]%256); // ADC# (lsb)
1343 fDataTof[jk12+5] = Bin2GrayTof(tofBin,fDataTof[jk12+5]);
1344 tofBin=(UChar_t)(TDCint[k+4*j]/256); // TDC# (msb)
1345 fDataTof[jk12+6]=Bin2GrayTof(tofBin,fDataTof[jk12+6]);
1346 tofBin=(UChar_t)(TDCint[k+4*j]%256); // TDC# (lsb)
1347 fDataTof[jk12+7]=Bin2GrayTof(tofBin,fDataTof[jk12+7]);
1348 };
1349 fDataTof[j12+20]=0x00; // TEMP1
1350 fDataTof[j12+21]=0x00; // TEMP2
1351 fDataTof[j12+22]= EvaluateCrcTof(pTof); // CRC
1352 pTof+=23;
1353 };
1354 return(0);
1355 };
1356
1357 UChar_t Digitizer::Bin2GrayTof(UChar_t binaTOF,UChar_t grayTOF){
1358 union graytof_data {
1359 UChar_t word;
1360 struct bit_field {
1361 unsigned b0:1;
1362 unsigned b1:1;
1363 unsigned b2:1;
1364 unsigned b3:1;
1365 unsigned b4:1;
1366 unsigned b5:1;
1367 unsigned b6:1;
1368 unsigned b7:1;
1369 } bit;
1370 } bi,gr;
1371 //
1372 bi.word = binaTOF;
1373 gr.word = grayTOF;
1374 //
1375 gr.bit.b0 = bi.bit.b1 ^ bi.bit.b0;
1376 gr.bit.b1 = bi.bit.b2 ^ bi.bit.b1;
1377 gr.bit.b2 = bi.bit.b3 ^ bi.bit.b2;
1378 gr.bit.b3 = bi.bit.b3;
1379 //
1380 /* bin to gray conversion 4 bit per time*/
1381 //
1382 gr.bit.b4 = bi.bit.b5 ^ bi.bit.b4;
1383 gr.bit.b5 = bi.bit.b6 ^ bi.bit.b5;
1384 gr.bit.b6 = bi.bit.b7 ^ bi.bit.b6;
1385 gr.bit.b7 = bi.bit.b7;
1386 //
1387 return(gr.word);
1388 }
1389
1390 UChar_t Digitizer::EvaluateCrcTof(UChar_t *pTof) {
1391 // UChar_t crcTof=0x00;
1392 // for (Int_t jp=0; jp < 23; jp++){
1393 // crcTof = crc8(...)
1394 // }
1395 return(0x00);
1396 };
1397
1398 //void Digitizer::Paddle2Pmt(Int_t plane, Int_t paddle, Int_t* &pmtleft, Int_t* &pmtright){
1399 void Digitizer::Paddle2Pmt(Int_t plane, Int_t paddle, Int_t *pl, Int_t *pr){
1400 //* @param plane (0 - 5)
1401 //* @param paddle (plane=0, paddle = 0,...5)
1402 //* @param padid (0 - 23)
1403 //
1404 Int_t padid=-1;
1405 Int_t pads[6]={8,6,2,2,3,3};
1406 //
1407 Int_t somma=0;
1408 Int_t np=plane;
1409 for(Int_t j=0; j<np; j++)
1410 somma+=pads[j];
1411 padid=paddle+somma;
1412 *pl = padid*2;
1413 // *pr = *pr + 1;
1414 *pr = *pl + 1; // WM
1415 };
1416
1417 void Digitizer::DigitizeAC() {
1418 // created: J. Conrad, KTH
1419 // modified: S. Orsi, INFN Roma2
1420 // fDataAC[0-63]: main AC board
1421 // fDataAC[64-127]: extra AC board
1422
1423 fDataAC[0] = 0xACAC;
1424 fDataAC[64]= 0xACAC;
1425 fDataAC[1] = 0xAC11;
1426 fDataAC[65] = 0xAC22;
1427
1428 // the third word is a status word (dummy: "no errors are present in the AC boards")
1429 fDataAC[2] = 0xFFFF; //FFEF?
1430 fDataAC[66] = 0xFFFF;
1431
1432 const UInt_t nReg = 6;
1433
1434 // FPGA Registers (dummy)
1435 for (UInt_t i=0; i<=nReg; i++){
1436 fDataAC[i+4] = 0xFFFF;
1437 fDataAC[i+68] = 0xFFFF;
1438 }
1439
1440 // the last word is a CRC
1441 // Dummy for the time being, but it might need to be calculated in the end
1442 fDataAC[63] = 0xABCD;
1443 fDataAC[127] = 0xABCD;
1444
1445 // shift registers (moved to the end of the routine)
1446
1447 Int_t evntLSB=Ievnt%65536;
1448 Int_t evntMSB=(Int_t)(Ievnt/65536);
1449
1450 // singles counters are dummy
1451 for (UInt_t i=0; i<=15; i++){ //SO Oct '07: // for (UInt_t i=0; i<=16; i++){
1452 // fDataAC[i+26] = 0x0000;
1453 // fDataAC[i+90] = 0x0000;
1454 fDataAC[i+26] = evntLSB;
1455 fDataAC[i+90] = evntLSB;
1456 };
1457
1458 // coincidences are dummy (increment by 1 at each event)
1459 // for (UInt_t i=0; i<=7; i++){
1460 // fDataAC[i+42] = 0x0000;
1461 // fDataAC[i+106] = 0x0000;
1462 // }
1463 for (UInt_t i=0; i<=7; i++){
1464 fDataAC[i+42] = evntLSB;
1465 fDataAC[i+106] = evntLSB;
1466 };
1467
1468 // increments for every trigger might be needed at some point.
1469 // dummy for now
1470 fDataAC[50] = 0x0000;
1471 fDataAC[114] = 0x0000;
1472
1473 // dummy FPGA clock (increment by 1 at each event)
1474 /*
1475 fDataAC[51] = 0x006C;
1476 fDataAC[52] = 0x6C6C;
1477 fDataAC[115] = 0x006C;
1478 fDataAC[116] = 0x6C6C;
1479 */
1480 if (Ievnt<=0xFFFF) {
1481 fDataAC[51] = 0x0000;
1482 fDataAC[52] = Ievnt;
1483 fDataAC[115] = 0x0000;
1484 fDataAC[116] = Ievnt;
1485 } else {
1486 fDataAC[51] = evntMSB;
1487 fDataAC[52] = evntLSB;
1488 fDataAC[115] = fDataAC[51];
1489 fDataAC[116] = fDataAC[52];
1490 }
1491
1492 // dummy temperatures
1493 fDataAC[53] = 0x0000;
1494 fDataAC[54] = 0x0000;
1495 fDataAC[117] = 0x0000;
1496 fDataAC[118] = 0x0000;
1497
1498
1499 // dummy DAC thresholds
1500 for (UInt_t i=0; i<=7; i++){
1501 fDataAC[i+55] = 0x1A13;
1502 fDataAC[i+119] = 0x1A13;
1503 }
1504
1505 // We activate all branches. Once the digitization algorithm is determined
1506 // only the branches that involve needed information will be activated
1507
1508 fhBookTree->SetBranchAddress("Ievnt",&Ievnt);
1509 fhBookTree->SetBranchStatus("Nthcat",1);
1510 fhBookTree->SetBranchStatus("Iparcat",1);
1511 fhBookTree->SetBranchStatus("Icat",1);
1512 fhBookTree->SetBranchStatus("Xincat",1);
1513 fhBookTree->SetBranchStatus("Yincat",1);
1514 fhBookTree->SetBranchStatus("Zincat",1);
1515 fhBookTree->SetBranchStatus("Xoutcat",1);
1516 fhBookTree->SetBranchStatus("Youtcat",1);
1517 fhBookTree->SetBranchStatus("Zoutcat",1);
1518 fhBookTree->SetBranchStatus("Erelcat",1);
1519 fhBookTree->SetBranchStatus("Timecat",1);
1520 fhBookTree->SetBranchStatus("Pathcat",1);
1521 fhBookTree->SetBranchStatus("P0cat",1);
1522 fhBookTree->SetBranchStatus("Nthcas",1);
1523 fhBookTree->SetBranchStatus("Iparcas",1);
1524 fhBookTree->SetBranchStatus("Icas",1);
1525 fhBookTree->SetBranchStatus("Xincas",1);
1526 fhBookTree->SetBranchStatus("Yincas",1);
1527 fhBookTree->SetBranchStatus("Zincas",1);
1528 fhBookTree->SetBranchStatus("Xoutcas",1);
1529 fhBookTree->SetBranchStatus("Youtcas",1);
1530 fhBookTree->SetBranchStatus("Zoutcas",1);
1531 fhBookTree->SetBranchStatus("Erelcas",1);
1532 fhBookTree->SetBranchStatus("Timecas",1);
1533 fhBookTree->SetBranchStatus("Pathcas",1);
1534 fhBookTree->SetBranchStatus("P0cas",1);
1535 fhBookTree->SetBranchStatus("Nthcard",1);
1536 fhBookTree->SetBranchStatus("Iparcard",1);
1537 fhBookTree->SetBranchStatus("Icard",1);
1538 fhBookTree->SetBranchStatus("Xincard",1);
1539 fhBookTree->SetBranchStatus("Yincard",1);
1540 fhBookTree->SetBranchStatus("Zincard",1);
1541 fhBookTree->SetBranchStatus("Xoutcard",1);
1542 fhBookTree->SetBranchStatus("Youtcard",1);
1543 fhBookTree->SetBranchStatus("Zoutcard",1);
1544 fhBookTree->SetBranchStatus("Erelcard",1);
1545 fhBookTree->SetBranchStatus("Timecard",1);
1546 fhBookTree->SetBranchStatus("Pathcard",1);
1547 fhBookTree->SetBranchStatus("P0card",1);
1548
1549 // In this simpliefied approach we will assume that once
1550 // a particle releases > 0.5 mip in one of the 12 AC detectors it
1551 // will fire. We will furthermore assume that both cards read out
1552 // identical data.
1553
1554 // If you develop your digitization algorithm, you should start by
1555 // identifying the information present in level2 (post-darth-vader)
1556 // data.
1557
1558 Float_t SumEcat[5];
1559 Float_t SumEcas[5];
1560 Float_t SumEcard[5];
1561 for (Int_t k= 0;k<5;k++){
1562 SumEcat[k]=0.;
1563 SumEcas[k]=0.;
1564 SumEcard[k]=0.;
1565 };
1566
1567 if (Nthcat>50 || Nthcas>50 || Nthcard>50)
1568 printf("*** ERROR AC! NthAC out of range!\n\n");
1569
1570 // energy dependence on position (see file AcFitOutputDistancePmt.C by S.Orsi)
1571 // based on J.Lundquist's calculations (PhD thesis, page 94)
1572 // function: [0]+[1]*atan([2]/(x+1)), where the 3 parameters are:
1573 // 8.25470e-01 +- 1.79489e-02
1574 // 6.41609e-01 +- 2.65846e-02
1575 // 9.81177e+00 +- 1.21284e+00
1576 // hp: 1 minimum ionising particle at 35cm from the PMT releases 1mip
1577 //
1578 // NB: the PMT positions are needed!
1579
1580 // look in CAT
1581 // for (UInt_t k= 0;k<50;k++){
1582 for (Int_t k= 0;k<Nthcat;k++){
1583 if (Erelcat[k] > 0)
1584 SumEcat[Icat[k]] += Erelcat[k];
1585 };
1586
1587 // look in CAS
1588 for (Int_t k= 0;k<Nthcas;k++){
1589 if (Erelcas[k] >0)
1590 SumEcas[Icas[k]] += Erelcas[k];
1591 };
1592
1593 // look in CARD
1594 for (Int_t k= 0;k<Nthcard;k++){
1595 if (Erelcard[k] >0)
1596 SumEcard[Icard[k]] += Erelcard[k];
1597 };
1598
1599 // channel mapping Hit Map
1600 // 1 CARD4 0 LSB
1601 // 2 CAT2 0
1602 // 3 CAS1 0
1603 // 4 NC 0
1604 // 5 CARD2 0
1605 // 6 CAT4 1
1606 // 7 CAS4 0
1607 // 8 NC 0
1608 // 9 CARD3 0
1609 // 10 CAT3 0
1610 // 11 CAS3 0
1611 // 12 NC 0
1612 // 13 CARD1 0
1613 // 14 CAT1 0
1614 // 15 CAS2 0
1615 // 16 NC 0 MSB
1616
1617 // In the first version only the hit-map is filled, not the SR.
1618
1619 // Threshold: 0.8 MeV.
1620
1621 Float_t thr = 8e-4;
1622
1623 fDataAC[3] = 0x0000;
1624
1625 if (SumEcas[0] > thr) fDataAC[3] = 0x0004;
1626 if (SumEcas[1] > thr) fDataAC[3] += 0x4000;
1627 if (SumEcas[2] > thr) fDataAC[3] += 0x0400;
1628 if (SumEcas[3] > thr) fDataAC[3] += 0x0040;
1629
1630 if (SumEcat[0] > thr) fDataAC[3] += 0x2000;
1631 if (SumEcat[1] > thr) fDataAC[3] += 0x0002;
1632 if (SumEcat[2] > thr) fDataAC[3] += 0x0200;
1633 if (SumEcat[3] > thr) fDataAC[3] += 0x0020;
1634
1635 if (SumEcard[0] > thr) fDataAC[3] += 0x1000;
1636 if (SumEcard[1] > thr) fDataAC[3] += 0x0010;
1637 if (SumEcard[2] > thr) fDataAC[3] += 0x0100;
1638 if (SumEcard[3] > thr) fDataAC[3] += 0x0001;
1639
1640 fDataAC[67] = fDataAC[3];
1641
1642 // shift registers
1643 // the central bin is equal to the hitmap, all other bins in the shift register are 0
1644 for (UInt_t i=0; i<=15; i++){
1645 fDataAC[i+11] = 0x0000;
1646 fDataAC[i+75] = 0x0000;
1647 }
1648 fDataAC[18] = fDataAC[3];
1649 fDataAC[82] = fDataAC[3];
1650
1651 // for (Int_t i=0; i<fACbuffer; i++){
1652 // printf("%0x ",fDataAC[i]);
1653 // if ((i+1)%8 ==0) cout << endl;
1654 // }
1655 };
1656
1657
1658 void Digitizer::DigitizeS4(){
1659 Int_t DEBUG=0;
1660 // creato: S. Borisov, INFN Roma2 e MEPHI, Sett 2007
1661 TString ciao,modo="ns";
1662 Int_t i,j,t,NdF,pmt,NdFT,S4,S4v=0,S4p=32;
1663 Float_t E0,E1=1e-6,Ert,X,Y,Z,x,y,z,V[3],Xs[2],Ys[2],Zs[2],Yp[6],q,w,p=0.1,l,l0=500;
1664 Xs[0]=-24.1;
1665 Xs[1]=24.1;
1666 Ys[0]=-24.1;
1667 Ys[1]=24.1;
1668 Zs[0]=-0.5;
1669 Zs[1]=0.5;
1670 Yp[0]=-20.;
1671 Yp[2]=-1.;
1672 Yp[4]=17.;
1673 for(i=0;i<3;i++)
1674 Yp[2*i+1]=Yp[2*i]+3;
1675 srand(time(NULL));
1676 // --- activate branches:
1677 fhBookTree->SetBranchStatus("Nthtof",1);
1678 fhBookTree->SetBranchStatus("Ipltof",1);
1679 fhBookTree->SetBranchStatus("Ipaddle",1);
1680
1681 fhBookTree->SetBranchStatus("Xintof",1);
1682 fhBookTree->SetBranchStatus("Yintof",1);
1683 fhBookTree->SetBranchStatus("Xouttof",1);
1684 fhBookTree->SetBranchStatus("Youttof",1);
1685
1686 fhBookTree->SetBranchStatus("Ereltof",1);
1687 fhBookTree->SetBranchStatus("Timetof",1);
1688 NdFT=0;
1689 Ert=0;
1690 for(i=0;i<Nthtof;i++){
1691 if(Ipltof[i]!=6) continue;
1692 Ert+=Ereltof[i];
1693
1694 if(modo=="ns") continue;
1695 NdF=Int_t(Ereltof[i]/E1);
1696 NdFT=0;
1697 X=Xintof[i];
1698 Y=Yintof[i];
1699 Z=(Float_t)(random())/(Float_t)(0x7fffffff)-0.5;
1700 //cout<<"XYZ "<<X<<" "<<Y<<" "<<Z<<endl;
1701 for(j=0;j<NdF;j++){
1702 q=(Float_t)random()/(Float_t)0x7fffffff;
1703 w=(Float_t)random()/(Float_t)0x7fffffff;
1704 // cout<<"qw "<<q<<" "<<w<<endl;
1705 V[0]=p*cos(6.28318*q);
1706 V[1]=p*sin(6.28318*q);
1707 V[2]=p*(2.*w-1.);
1708 pmt=0;
1709 x=X;
1710 y=Y;
1711 z=Z;
1712 while(pmt==0 && (x>Xs[0] && x<Xs[1])&&(y>Ys[0] && y<Ys[1])&&(z>Zs[0] && z<Zs[1])){
1713 l=0;
1714 while(pmt==0 && (x>Xs[0] && x<Xs[1])&&(y>Ys[0] && y<Ys[1])&&(z>Zs[0] && z<Zs[1])){
1715 x+=V[0];
1716 y+=V[1];
1717 z+=V[2];
1718 l+=p;
1719 //cout<<x<<" "<<y<<" "<<z<<" "<<l<<endl;
1720 //cin>>ciao;
1721 }
1722 if((x<Xs[0]+p || x>Xs[1]-p)&&(y>Ys[0]+p && y<Ys[1]-p)&&(z>Zs[0]+p && z<Zs[1]-p)){
1723 for(t=0;t<3;t++){
1724 if(y>=Yp[2*t] && y<Yp[2*t+1]){
1725 if(pmt==0)NdFT++;
1726 pmt=1;
1727 //cout<<NdFT<<endl;
1728 break;
1729 }
1730 }
1731 if(pmt==1)break;
1732 V[0]=-V[0];
1733 }
1734 q=(Float_t)random()/(Float_t)0x7fffffff;
1735 w=1-exp(-l/l0);
1736 if(q<w)break;
1737 q=(Float_t)random()/(Float_t)0x7fffffff;
1738 w=0.5;
1739 if(q<w)break;
1740 if((x>Xs[0]+p && x<Xs[1]-p)&&(y<Ys[0]+p || y>Ys[1]-p)&&(z>Zs[0]+p && z<Zs[1]-p))V[1]=-V[1];
1741 if((x>Xs[0]+p && x<Xs[1]-p)&&(y>Ys[0]+p && y<Ys[1]-p)&&(z<Zs[0]+p || z>Zs[1]-p))V[2]=-V[2];
1742 x+=V[0];
1743 y+=V[1];
1744 z+=V[2];
1745 l=0;
1746 //cout<<x<<" "<<y<<" "<<z<<" "<<l<<endl;
1747 //cin>>ciao;
1748 }
1749 }
1750 }
1751 Ert=Ert/0.002;
1752 q=(Float_t)(random())/(Float_t)0x7fffffff;
1753 w=0.7;
1754 //E0=(Float_t)(4064./7.);
1755 E0=4064./7.;
1756 if(Ert<1) S4=0;
1757 else S4=(Int_t)(4064.*(1.-exp(-(Ert-1.)/E0)));
1758 i=S4/4;
1759 if(S4%4==0)
1760 S4v=S4+S4p;
1761 else if(S4%4==1){
1762 if(q<w) S4v=S4-1+S4p;
1763 else S4v=S4+1+S4p;
1764 } else if(S4%4==2) S4v=S4+S4p;
1765 else if(S4%4==3){
1766 if(q<w) S4v=S4+1+S4p;
1767 else S4v=S4-1+S4p;
1768 }
1769 if (DEBUG)
1770 cout<<"Ert_S4 = " << Ert << " --- S4v = " << S4v << endl;
1771 fDataS4[0]=S4v;//0xf028;
1772 fDataS4[1]=0xd800;
1773 fDataS4[2]=0x0300;
1774 //cout<<" PMT "<<NdFT<<" "<<NdF<<endl;
1775 //cin>>ciao;
1776 }
1777
1778
1779
1780 void Digitizer::DigitizeND(){
1781 // creato: S. Borisov, INFN Roma2 e MEPHI, Sett 2007
1782 Int_t i=0;
1783 UShort_t NdN=0;
1784 fhBookTree->SetBranchStatus("Nthnd",1);
1785 fhBookTree->SetBranchStatus("Itubend",1);
1786 fhBookTree->SetBranchStatus("Iparnd",1);
1787 fhBookTree->SetBranchStatus("Xinnd",1);
1788 fhBookTree->SetBranchStatus("Yinnd",1);
1789 fhBookTree->SetBranchStatus("Zinnd",1);
1790 fhBookTree->SetBranchStatus("Xoutnd",1);
1791 fhBookTree->SetBranchStatus("Youtnd",1);
1792 fhBookTree->SetBranchStatus("Zoutnd",1);
1793 fhBookTree->SetBranchStatus("Erelnd",1);
1794 fhBookTree->SetBranchStatus("Timend",1);
1795 fhBookTree->SetBranchStatus("Pathnd",1);
1796 fhBookTree->SetBranchStatus("P0nd",1);
1797 //cout<<"n="<<Nthnd<<" "<<NdN<<"\n";
1798 for(i=0;i<Nthnd;i++){
1799 if(Iparnd[i]==13){
1800 NdN++;
1801 }
1802 }
1803 //NdN=100; //only for debug
1804
1805 for(i=0;i<3;i++){
1806 fDataND[2*i]=0x0000;
1807 fDataND[2*i+1]=0x010F;
1808 }
1809 fDataND[0]=0xFF00 & (256*NdN);
1810 }
1811
1812
1813 void Digitizer::DigitizeDummy() {
1814
1815 fhBookTree->SetBranchStatus("Enestrip",1);
1816
1817 // dumy header
1818 fDataDummy[0] = 0xCAAA;
1819
1820 for (Int_t i=1; i<fDummybuffer; i++){
1821 fDataDummy[i] = 0xFFFF;
1822 // printf("%0x ",fDataDummy[i]);
1823 //if ((i+1)%8 ==0) cout << endl;
1824 }
1825 };
1826
1827
1828 void Digitizer::WriteData(){
1829
1830 // Routine that writes the data to a binary file
1831 // PSCU data are already swapped
1832 fOutputfile.write(reinterpret_cast<char*>(fDataPSCU),sizeof(UShort_t)*fPSCUbuffer);
1833 // TRG
1834 fOutputfile.write(reinterpret_cast<char*>(fDataTrigger),sizeof(UChar_t)*153);
1835 // TOF
1836 fOutputfile.write(reinterpret_cast<char*>(fDataTof),sizeof(UChar_t)*276);
1837 // AC
1838 UShort_t temp[1000000];
1839 memset(temp,0,sizeof(UShort_t)*1000000);
1840 swab(fDataAC,temp,sizeof(UShort_t)*fACbuffer); // WE MUST SWAP THE BYTES!!!
1841 fOutputfile.write(reinterpret_cast<char*>(temp),sizeof(UShort_t)*fACbuffer);
1842 // CALO
1843 memset(temp,0,sizeof(UShort_t)*1000000);
1844 swab(fDataCALO,temp,sizeof(UShort_t)*fCALOlength); // WE MUST SWAP THE BYTES!!!
1845 fOutputfile.write(reinterpret_cast<char*>(temp),sizeof(UShort_t)*fCALOlength);
1846 // TRK
1847 memset(temp,0,sizeof(UShort_t)*1000000);
1848 swab(fDataTrack,temp,sizeof(UShort_t)*fTracklength); // WE MUST SWAP THE BYTES!!!
1849 fOutputfile.write(reinterpret_cast<char*>(temp),sizeof(UShort_t)*fTracklength);
1850 fTracklength=0;
1851 // padding to 64 bytes
1852 //
1853 if ( fPadding ){
1854 fOutputfile.write(reinterpret_cast<char*>(fDataPadding),sizeof(UChar_t)*fPadding);
1855 };
1856 // S4
1857 memset(temp,0,sizeof(UShort_t)*1000000);
1858 swab(fDataS4,temp,sizeof(UShort_t)*fS4buffer); // WE MUST SWAP THE BYTES!!!
1859 fOutputfile.write(reinterpret_cast<char*>(temp),sizeof(UShort_t)*fS4buffer);
1860 // ND
1861 memset(temp,0,sizeof(UShort_t)*1000000);
1862 swab(fDataND,temp,sizeof(UShort_t)*fNDbuffer); // WE MUST SWAP THE BYTES!!!
1863 fOutputfile.write(reinterpret_cast<char*>(temp),sizeof(UShort_t)*fNDbuffer);
1864 };
1865
1866
1867 void Digitizer::ReadData(){
1868
1869 UShort_t InData[64];
1870
1871 // for debuggigng purposes only, write your own routine if you like (many
1872 // hardwired things.
1873
1874 ifstream InputFile;
1875
1876 // if (!InputFile) {
1877
1878 // std::cout << "ERROR" << endl;
1879 // // An error occurred!
1880 // // myFile.gcount() returns the number of bytes read.
1881 // // calling myFile.clear() will reset the stream state
1882 // // so it is usable again.
1883 // };
1884
1885
1886
1887 //InputFile.seekg(0);
1888
1889 InputFile.open(fFilename, ios::in | ios::binary);
1890 // fOutputfile.seekg(0);
1891 if (!InputFile.is_open()) std::cout << "ERROR" << endl;
1892
1893 InputFile.seekg(0);
1894
1895 for (Int_t k=0; k<=1000; k++){
1896 InputFile.read(reinterpret_cast<char*>(InData),384*sizeof(UShort_t));
1897
1898 std::cout << "Read back: " << endl << endl;
1899
1900 for (Int_t i=0; i<=384; i++){
1901 printf("%4x ", InData[i]);
1902 if ((i+1)%8 ==0) cout << endl;
1903 }
1904
1905 }
1906 cout << endl;
1907 InputFile.close();
1908
1909 };
1910
1911
1912
1913 void Digitizer::DigitizeTrack() {
1914 //std:: cout << "Entering DigitizeTrack " << endl;
1915 Float_t AdcTrack[fNviews][fNstrips_view]; // Vector of strips to be compressed
1916
1917 Int_t Iview;
1918 Int_t Nstrip;
1919
1920 for (Int_t j=0; j<fNviews;j++) {
1921
1922 for (Int_t i=0; i<fNladder;i++) {
1923
1924 Float_t commonN1=gRandom->Gaus(0.,fSigmaCommon);
1925 Float_t commonN2=gRandom->Gaus(0.,fSigmaCommon);
1926 for (Int_t k=0; k<fNstrips_ladder;k++) {
1927 Nstrip=i*fNstrips_ladder+k;
1928 AdcTrack[j][Nstrip]=gRandom->Gaus(fPedeTrack[j][Nstrip],fSigmaTrack[j][Nstrip]);
1929 if(k<4*128) {AdcTrack[j][Nstrip] += commonN1;} // full correlation of 4 VA1 Com. Noise
1930 else {AdcTrack[j][Nstrip] += commonN2;} // full correlation of 4 VA1 Com. Noise
1931
1932 };
1933
1934
1935 };
1936
1937
1938 };
1939
1940
1941 fhBookTree->SetBranchStatus("Nstrpx",1);
1942 fhBookTree->SetBranchStatus("Npstripx",1);
1943 fhBookTree->SetBranchStatus("Ntstripx",1);
1944 fhBookTree->SetBranchStatus("Istripx",1);
1945 fhBookTree->SetBranchStatus("Qstripx",1);
1946 fhBookTree->SetBranchStatus("Xstripx",1);
1947 fhBookTree->SetBranchStatus("Nstrpy",1);
1948 fhBookTree->SetBranchStatus("Npstripy",1);
1949 fhBookTree->SetBranchStatus("Ntstripy",1);
1950 fhBookTree->SetBranchStatus("Istripy",1);
1951 fhBookTree->SetBranchStatus("Qstripy",1);
1952 fhBookTree->SetBranchStatus("Ystripy",1);
1953
1954
1955
1956 Float_t ADCfull;
1957 Int_t iladd=0;
1958 for (Int_t ix=0; ix<Nstrpx;ix++) {
1959 Iview=Npstripx[ix]*2-1;
1960 Nstrip=(Int_t)Istripx[ix]-1;
1961 if(Nstrip<fNstrips_ladder) iladd=0;
1962 if((Nstrip>=fNstrips_ladder)&&(Nstrip<2*fNstrips_ladder)) iladd=1;
1963 if((Nstrip>=2*fNstrips_ladder)&&(Nstrip<3*fNstrips_ladder)) iladd=2;
1964 ADCfull=AdcTrack[Iview][Nstrip] += Qstripx[ix]*fMipCor[iladd][Iview];
1965 AdcTrack[Iview][Nstrip] *= SaturationTrack(ADCfull);
1966
1967 };
1968
1969
1970 for (Int_t iy=0; iy<Nstrpy;iy++) {
1971 Iview=Npstripy[iy]*2-2;
1972 Nstrip=(Int_t)Istripy[iy]-1;
1973 if(Nstrip<fNstrips_ladder) iladd=0;
1974 if((Nstrip>=fNstrips_ladder)&&(Nstrip<2*fNstrips_ladder)) iladd=1;
1975 if((Nstrip>=2*fNstrips_ladder)&&(Nstrip<3*fNstrips_ladder)) iladd=2;
1976 ADCfull=AdcTrack[Iview][Nstrip] -= Qstripy[iy]*fMipCor[iladd][Iview];
1977 AdcTrack[Iview][Nstrip] *= SaturationTrack(ADCfull);
1978
1979 };
1980
1981 CompressTrackData(AdcTrack); // Compress and Digitize data of one Ladder in turn for all ladders
1982
1983 };
1984
1985
1986
1987 void Digitizer::DigitizeTrackCalib(Int_t ii) {
1988
1989 std:: cout << "Entering DigitizeTrackCalib " << ii << endl;
1990 if( (ii!=1)&&(ii!=2) ) {
1991 std:: cout << "error wrong DigitizeTrackCalib argument" << endl;
1992 return;
1993 };
1994
1995 memset(fDataTrack,0,sizeof(UShort_t)*fTRACKbuffer);
1996 fTracklength=0;
1997
1998 UShort_t Dato;
1999
2000 Float_t dato1;
2001 Float_t dato2;
2002 Float_t dato3;
2003 Float_t dato4;
2004
2005 UShort_t DatoDec;
2006 UShort_t DatoDec1;
2007 UShort_t DatoDec2;
2008 UShort_t DatoDec3;
2009 UShort_t DatoDec4;
2010
2011 UShort_t EVENT_CAL;
2012 UShort_t PED_L1;
2013 UShort_t ReLength;
2014 UShort_t OveCheckCode;
2015 //UShort_t PED_L2;
2016 //UShort_t PED_L3HI;
2017 //UShort_t PED_L3LO;
2018 //UShort_t SIG_L1HI;
2019 //UShort_t SIG_L1LO;
2020 //UShort_t SIG_L2HI;
2021 //UShort_t SIG_L2LO;
2022 //UShort_t SIG_L3;
2023 //UShort_t BAD_L1;
2024 //UShort_t BAD_L2LO;
2025 //UShort_t BAD_L3HI;
2026 //UShort_t BAD_L3LO;
2027 //UShort_t FLAG;
2028
2029
2030 Int_t DSPpos;
2031 for (Int_t j=ii-1; j<fNviews;j+=2) {
2032 UShort_t CkSum=0;
2033 // here skip the dsp header and his trailer , to be written later
2034 DSPpos=fTracklength;
2035 fTracklength=fTracklength+13+3;
2036
2037
2038 for (Int_t i=0; i<fNladder;i++) {
2039 for (Int_t k=0; k<fNstrips_ladder;k++) {
2040 // write in buffer the current LADDER
2041 Dato=(UShort_t)fPedeTrack[j][i*fNstrips_ladder+k];
2042 dato1=fPedeTrack[j][i*fNstrips_ladder+k]-Dato;
2043
2044 DatoDec1=(UShort_t)(dato1*2);
2045 dato2=dato1*2-DatoDec1;
2046
2047 DatoDec2=(UShort_t)(dato2*2);
2048 dato3=dato2*2-DatoDec2;
2049
2050 DatoDec3=(UShort_t)(dato3*2);
2051 dato4=dato3*2-DatoDec3;
2052
2053 DatoDec4=(UShort_t)(dato4*2);
2054
2055 DatoDec=DatoDec1*0x0008+DatoDec2*0x0004+DatoDec3*0x0002+DatoDec4*0x0001;
2056 fDataTrack[fTracklength]=( (Dato << 4) | (DatoDec & 0x000F) );
2057 CkSum=CkSum^fDataTrack[fTracklength];
2058 fTracklength++;
2059 };
2060
2061 for (Int_t k=0; k<fNstrips_ladder;k++) {
2062 // write in buffer the current LADDER
2063 Dato=(UShort_t)fSigmaTrack[j][i*fNstrips_ladder+k];
2064 dato1=fSigmaTrack[j][i*fNstrips_ladder+k]-Dato;
2065
2066 DatoDec1=(UShort_t)(dato1*2);
2067 dato2=dato1*2-DatoDec1;
2068
2069 DatoDec2=(UShort_t)(dato2*2);
2070 dato3=dato2*2-DatoDec2;
2071
2072 DatoDec3=(UShort_t)(dato3*2);
2073 dato4=dato3*2-DatoDec3;
2074
2075 DatoDec4=(UShort_t)(dato4*2);
2076
2077 DatoDec=DatoDec1*0x0008+DatoDec2*0x0004+DatoDec3*0x0002+DatoDec4*0x0001;
2078
2079 fDataTrack[fTracklength]=( (Dato << 4) | (DatoDec & 0x000F) );
2080 CkSum=CkSum^fDataTrack[fTracklength];
2081 fTracklength++;
2082 };
2083
2084 for (Int_t k=0; k<64;k++) {
2085 fDataTrack[fTracklength]=0x0000;
2086 CkSum=CkSum^fDataTrack[fTracklength];
2087 fTracklength++;
2088
2089 };
2090 // end ladder
2091
2092 // write in buffer the end ladder word
2093 if(i==0) fDataTrack[fTracklength]=0x1807;
2094 if(i==1) fDataTrack[fTracklength]=0x1808;
2095 if(i==2) fDataTrack[fTracklength]=0x1809;
2096 CkSum=CkSum^fDataTrack[fTracklength];
2097 fTracklength++;
2098
2099 // write in buffer the TRAILER
2100 ReLength=(UShort_t)((fNstrips_ladder*2+64+1)*2+3);
2101 OveCheckCode=0x0000;
2102
2103 fDataTrack[fTracklength]=0x0000;
2104 fTracklength++;
2105
2106 fDataTrack[fTracklength]=(ReLength >> 8);
2107 fTracklength++;
2108
2109 fDataTrack[fTracklength]=( (ReLength << 8) | (OveCheckCode & 0x00FF) );
2110 fTracklength++;
2111
2112 // end TRAILER
2113 };
2114
2115 // write in buffer the DSP header
2116
2117 fDataTrack[DSPpos]=(0xE800 | ( ((j+1) << 3) | 0x0005) );
2118
2119 fDataTrack[DSPpos+1]=0x01A9;
2120
2121 fDataTrack[DSPpos+2]=0x8740;
2122
2123 EVENT_CAL=0;
2124 fDataTrack[DSPpos+3]=(0x1A00 | ( (0x03FF & EVENT_CAL)>> 1) );
2125
2126 PED_L1=0;
2127 fDataTrack[DSPpos+4]=( ((EVENT_CAL << 15) | 0x5002 ) | ((0x03FF & PED_L1) << 2) );
2128
2129 // FROM HERE WE WRITE AS ALL VARIABLE apart CkSum are =0
2130
2131 fDataTrack[DSPpos+5]=0x8014;
2132
2133 fDataTrack[DSPpos+6]=0x00A0;
2134
2135 fDataTrack[DSPpos+7]=0x0500;
2136
2137 fDataTrack[DSPpos+8]=0x2801;
2138
2139 fDataTrack[DSPpos+9]=0x400A;
2140
2141 fDataTrack[DSPpos+10]=0x0050;
2142
2143 CkSum=(CkSum >> 8)^(CkSum&0x00FF);
2144 fDataTrack[DSPpos+11]=(0x0280 | (CkSum >> 3));
2145
2146 fDataTrack[DSPpos+12]=(0x1FFF | (CkSum << 13) );
2147
2148 // end dsp header
2149
2150 // write in buffer the TRAILER
2151
2152 ReLength=(UShort_t)((13*2)+3);
2153 OveCheckCode=0x0000;
2154 fDataTrack[DSPpos+13]=0x0000;
2155
2156 fDataTrack[DSPpos+14]=(ReLength >> 8);
2157
2158 fDataTrack[DSPpos+15]=( (ReLength << 8) | (OveCheckCode & 0x00FF) );
2159
2160 // end TRAILER
2161
2162
2163
2164
2165 // end DSP
2166 };
2167
2168
2169
2170 };
2171
2172 void Digitizer::WriteTrackCalib() {
2173
2174
2175 std:: cout << " Entering WriteTrackCalib " << endl;
2176
2177 fOutputfile.write(reinterpret_cast<char*>(fDataPSCU),sizeof(UShort_t)*fPSCUbuffer);
2178
2179 UShort_t temp[1000000];
2180 memset(temp,0,sizeof(UShort_t)*1000000);
2181 swab(fDataTrack,temp,sizeof(UShort_t)*fTracklength); // WE MUST SWAP THE BYTES!!!
2182 fOutputfile.write(reinterpret_cast<char*>(temp),sizeof(UShort_t)*fTracklength);
2183 fTracklength=0;
2184 if ( fPadding ){
2185 fOutputfile.write(reinterpret_cast<char*>(fDataPadding),sizeof(UChar_t)*fPadding);
2186 };
2187
2188 };
2189
2190
2191 void Digitizer::ClearTrackCalib() {
2192
2193 std:: cout << "Entering ClearTrackCalib " << endl;
2194
2195
2196 };
2197
2198
2199 void Digitizer::LoadTrackCalib() {
2200 std:: cout << "Entering LoadTrackCalib " << endl;
2201
2202 // Generate the pedestals and sigmas according to parametrization
2203 for (Int_t j=0; j<fNviews;j++) {
2204 for (Int_t i=0; i<fNstrips_view;i++) {
2205
2206 if((j+1)%2==0) {
2207 fPedeTrack[j][i]=gRandom->Gaus(fAvePedex,fSigmaPedex);
2208 fSigmaTrack[j][i]=gRandom->Gaus(fAveSigmax,fSigmaSigmax);
2209 };
2210 if((j+1)%2==1) {
2211 fPedeTrack[j][i]=gRandom->Gaus(fAvePedey,fSigmaPedey);
2212 fSigmaTrack[j][i]=gRandom->Gaus(fAveSigmay,fSigmaSigmay);
2213 };
2214
2215 };
2216 };
2217
2218
2219
2220 };
2221
2222 void Digitizer::LoadMipCor() {
2223 std:: cout << "Entering LoadMipCor" << endl;
2224 Float_t xfactor=1./151.6*1.04;
2225 Float_t yfactor=1./152.1;
2226
2227 fMipCor[0][0]=140.02*yfactor;
2228 fMipCor[0][1]=140.99*xfactor;
2229 fMipCor[0][2]=134.48*yfactor;
2230 fMipCor[0][3]=144.41*xfactor;
2231 fMipCor[0][4]=140.74*yfactor;
2232 fMipCor[0][5]=142.28*xfactor;
2233 fMipCor[0][6]=134.53*yfactor;
2234 fMipCor[0][7]=140.63*xfactor;
2235 fMipCor[0][8]=135.55*yfactor;
2236 fMipCor[0][9]=138.00*xfactor;
2237 fMipCor[0][10]=154.95*yfactor;
2238 fMipCor[0][11]=158.44*xfactor;
2239
2240
2241 fMipCor[1][0]=136.07*yfactor;
2242 fMipCor[1][1]=135.59*xfactor;
2243 fMipCor[1][2]=142.69*yfactor;
2244 fMipCor[1][3]=138.19*xfactor;
2245 fMipCor[1][4]=137.35*yfactor;
2246 fMipCor[1][5]=140.23*xfactor;
2247 fMipCor[1][6]=153.15*yfactor;
2248 fMipCor[1][7]=151.42*xfactor;
2249 fMipCor[1][8]=129.76*yfactor;
2250 fMipCor[1][9]=140.63*xfactor;
2251 fMipCor[1][10]=157.87*yfactor;
2252 fMipCor[1][11]=153.64*xfactor;
2253
2254 fMipCor[2][0]=134.98*yfactor;
2255 fMipCor[2][1]=143.95*xfactor;
2256 fMipCor[2][2]=140.23*yfactor;
2257 fMipCor[2][3]=138.88*xfactor;
2258 fMipCor[2][4]=137.95*yfactor;
2259 fMipCor[2][5]=134.87*xfactor;
2260 fMipCor[2][6]=157.56*yfactor;
2261 fMipCor[2][7]=157.31*xfactor;
2262 fMipCor[2][8]=141.37*yfactor;
2263 fMipCor[2][9]=143.39*xfactor;
2264 fMipCor[2][10]=156.15*yfactor;
2265 fMipCor[2][11]=158.79*xfactor;
2266
2267 /*
2268 for (Int_t j=0; j<fNviews;j++) {
2269 for (Int_t i=0; i<fNstrips_view;i++) {
2270 fMipCor[j][i]=1.;
2271 };
2272 };
2273
2274
2275 */
2276 };
2277
2278 void Digitizer::CompressTrackData(Float_t AdcTrack[fNviews][fNstrips_view]) {
2279 // copy of the corresponding compression fortran routine + new digitization
2280 // std:: cout << "Entering CompressTrackData " << endl;
2281 Int_t oldval=0;
2282 Int_t newval=0;
2283 Int_t trasmesso=0;
2284 Int_t ntrastot=0;
2285 Float_t real;
2286 Float_t inte;
2287 Int_t cercacluster=0;
2288 Int_t kt=0;
2289 static const int DSPbufferSize = 4000; // 13 bit buffer to be rearranged in 16 bit Track buffer
2290 UShort_t DataDSP[DSPbufferSize]; // 13 bit buffer to be rearranged in 16 bit Track buffer
2291 UShort_t DSPlength; // 13 bit buffer to be rearranged in 16 bit Track buffer
2292
2293 memset(fDataTrack,0,sizeof(UShort_t)*fTRACKbuffer); // probably not necessary becouse already done ?
2294 fTracklength=0;
2295
2296 for (Int_t iv=0; iv<fNviews;iv++) {
2297 memset(DataDSP,0,sizeof(UShort_t)*DSPbufferSize);
2298 DSPlength=16; // skip the header, to be written later
2299 UShort_t CheckSum=0;
2300 // write dsp header on buffer
2301
2302 // fDataTrack[fTracklength]=0xE805;
2303 // fTracklength++;
2304
2305 // fDataTrack[fTracklength]=0x01A9;
2306 // fTracklength++;
2307
2308 // end dsp header
2309
2310 //
2311 // INIZIO VISTA IV - TAKE PROPER ACTION
2312 //
2313
2314
2315
2316 for (Int_t ladder=0; ladder<fNladder;ladder++) {
2317 Int_t k=0;
2318 while (k<fNstrips_ladder) {
2319 // compress write in buffer the current LADDER
2320 if ( k == 0) {
2321 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+k],&inte);
2322 if (real > 0.5) inte=inte+1;
2323 newval=(Int_t)inte -(Int_t)fPedeTrack[iv][ladder*fNstrips_ladder+k];
2324 // first strip of ladder is transmitted
2325 // DC_TOT first " << AdcTrack[iv][ladder*fNstrips_ladder+k] << endl;
2326 DataDSP[DSPlength]=( ((UShort_t)inte) & 0x0FFF);
2327 DSPlength++;
2328 ntrastot++;
2329 trasmesso=1;
2330 oldval=newval;
2331 kt=k;
2332 k++;
2333 continue;
2334 };
2335 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+k],&inte);
2336 if (real > 0.5) inte=inte+1;
2337 newval=(Int_t)inte -(Int_t)(fPedeTrack[iv][ladder*fNstrips_ladder+k]);
2338 cercacluster=1; // ?????????
2339 if (cercacluster==1) {
2340
2341 // controlla l'ordine di tutti queste strip ladder e DSP !!!!!!!
2342 Int_t diff=0;
2343
2344
2345 switch ((iv+1)%2) {
2346 case 0: diff=newval-oldval;
2347 break;
2348 case 1: diff=oldval-newval;
2349 break;
2350 };
2351
2352 if (diff>fCutclu*(Int_t)fSigmaTrack[iv][ladder*fNstrips_ladder+k]) {
2353 Int_t clval=newval;
2354 Int_t klp=k; // go on to search for maximum
2355 klp++;
2356
2357 while(klp<fNstrips_ladder) {
2358 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+klp],&inte);
2359 if (real > 0.5) inte=inte+1;
2360 Int_t clvalp=(Int_t)inte -(Int_t)fPedeTrack[iv][ladder*fNstrips_ladder+klp];
2361 if((iv+1)%2==0) {
2362
2363 if(clvalp>clval) {
2364 clval=clvalp;
2365 k=klp;}
2366 else break; // max of cluster found
2367
2368 } else {
2369
2370 if(clvalp<clval) {
2371 clval=clvalp;
2372 k=klp;}
2373 else break; // max of cluster found
2374
2375 };
2376
2377 klp++;
2378 };
2379
2380 Int_t kl1=k-fNclst; // max of cluster (or end of ladder ?)
2381 trasmesso=0;
2382 if(kl1<0) kl1=0;
2383
2384 if(kt>=kl1) kl1=kt+1;
2385 if( (kt+1)==kl1 ) trasmesso=1;
2386
2387
2388
2389 Int_t kl2=k+fNclst;
2390 if(kl2>=fNstrips_ladder) kl2=fNstrips_ladder-1;
2391
2392 for(Int_t klt=kl1 ; klt<=kl2 ; klt++) {
2393 if(trasmesso==0) {
2394 // std:: cout << "STRIP " << klt << endl;
2395 // std:: cout << "ADC_TOT " <<AdcTrack[iv][ladder*fNstrips_ladder+klt] << endl;
2396
2397 DataDSP[DSPlength]=( ((UShort_t)klt) | 0x1000);
2398 DSPlength++;
2399 ntrastot++;
2400
2401
2402 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+klt],&inte);
2403 if (real > 0.5) inte=inte+1;
2404 DataDSP[DSPlength]=( ((UShort_t)inte) & 0x0FFF);
2405 DSPlength++;
2406 ntrastot++;
2407
2408 }
2409 else {
2410 // std:: cout << "ADC_TOT " <<AdcTrack[iv][ladder*fNstrips_ladder+klt] << endl;
2411 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+klt],&inte);
2412 if (real > 0.5) inte=inte+1;
2413 DataDSP[DSPlength]=( ((UShort_t)inte) & 0x0FFF);
2414 DSPlength++;
2415 ntrastot++;
2416 };
2417 trasmesso=1;
2418 }; // end trasmission
2419 kt=kl2;
2420 k=kl2;
2421 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+kt],&inte);
2422 if (real > 0.5) inte=inte+1;
2423 oldval=(Int_t)inte -(Int_t)fPedeTrack[iv][ladder*fNstrips_ladder+kt];
2424 k++;
2425 continue;
2426
2427
2428 }; // end cercacluster
2429 }; // end cercacluster
2430
2431 // start ZOP check for strips no
2432
2433 if(abs(newval-oldval)>=fCutzop*(Int_t)fSigmaTrack[iv][ladder*fNstrips_ladder+k]) {
2434
2435 if(trasmesso==0) {
2436 // std:: cout << "STRIP " << k << endl;
2437 // std:: cout << "ADC_TOT " << AdcTrack[iv][ladder*fNstrips_ladder+k] << endl;
2438
2439 DataDSP[DSPlength]=( ((UShort_t)k) | 0x1000);
2440 DSPlength++;
2441 ntrastot++;
2442
2443
2444 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+k],&inte);
2445 if (real > 0.5) inte=inte+1;
2446 DataDSP[DSPlength]=( ((UShort_t)inte) & 0x0FFF);
2447 DSPlength++;
2448 ntrastot++;
2449
2450 }
2451 else {
2452 // std:: cout << "ADC_TOT " << AdcTrack[iv][ladder*fNstrips_ladder+k] << endl;
2453 real=modff(AdcTrack[iv][ladder*fNstrips_ladder+k],&inte);
2454 if (real > 0.5) inte=inte+1;
2455 DataDSP[DSPlength]=( ((UShort_t)inte) & 0x0FFF);
2456 DSPlength++;
2457 ntrastot++;
2458 };
2459 trasmesso=1;
2460 oldval=newval;
2461 kt=k;
2462
2463 }
2464 else trasmesso=0;
2465 // end zop
2466
2467 k++;
2468 }; // end cycle inside ladder
2469 // write here the end ladder bytes
2470 // std:: cout << "FINE LADDER " << ladder+1 << endl;
2471
2472 DataDSP[DSPlength]=( ((UShort_t)(ladder+1)) | 0x1800);
2473 DSPlength++;
2474 ntrastot++;
2475 trasmesso=0;
2476
2477 }; //end cycle inside dsp
2478 // std:: cout << "FINE DSP " << iv+1 << endl;
2479 // here put DSP header
2480 DataDSP[0]=(0x1CA0 | ((UShort_t)(iv+1)) );
2481 UShort_t Nword=(DSPlength*13)/16;
2482 if( ((DSPlength*13)%16)!=0) Nword++;
2483 DataDSP[1]=(0x1400 | ( Nword >> 10));
2484 DataDSP[2]=(0x1400 | ( Nword & 0x03FF) );
2485 DataDSP[3]=(0x1400 | (( (UShort_t)(fCounter >> 10) ) & 0x03FF) );
2486 DataDSP[4]=(0x1400 | (( (UShort_t)(fCounter) ) & 0x03FF) );
2487 DataDSP[5]=(0x1400 | ( (UShort_t)(fNclst << 7) ) | ( (UShort_t)(fCutzop << 4) )
2488 | ( (UShort_t)fCutzop ) );
2489 DataDSP[6]=0x1400;
2490 DataDSP[7]=0x1400;
2491 DataDSP[8]=0x1400;
2492 DataDSP[9]=0x1400;
2493 DataDSP[10]=0x1400;
2494 DataDSP[11]=0x1400;
2495 DataDSP[12]=0x1400;
2496 DataDSP[13]=0x1400;
2497 DataDSP[14]=(0x1400 | (CheckSum & 0x00FF) );
2498 DataDSP[15]=0x1C00;
2499 // end DSP header
2500
2501
2502 // write 13 bit DataDSP bufer inside 16 bit fDataTrack buffer
2503 Int_t Bit16free=16;
2504 UShort_t Dato;
2505 for (Int_t NDSP=0; NDSP<DSPlength;NDSP++) {
2506 Int_t Bit13ToWrite=13;
2507 while(Bit13ToWrite>0) {
2508 if(Bit13ToWrite<=Bit16free) {
2509 Dato=((DataDSP[NDSP]&(0xFFFF >> (16-Bit13ToWrite)))<<(Bit16free-Bit13ToWrite));
2510 fDataTrack[fTracklength]=fDataTrack[fTracklength] | Dato ;
2511 Bit16free=Bit16free-Bit13ToWrite;
2512 Bit13ToWrite=0;
2513 if(Bit16free==0) {
2514 if(NDSP>15) CheckSum=CheckSum^fDataTrack[fTracklength];
2515 fTracklength++;
2516 Bit16free=16;
2517 };
2518 }
2519 else if(Bit13ToWrite>Bit16free) {
2520 Dato=( (DataDSP[NDSP]&(0xFFFF >> (16-Bit13ToWrite) ) ) >> (Bit13ToWrite-Bit16free) );
2521 fDataTrack[fTracklength]=fDataTrack[fTracklength] | Dato ;
2522 if(NDSP>15) CheckSum=CheckSum^fDataTrack[fTracklength];
2523 fTracklength++;
2524 Bit13ToWrite=Bit13ToWrite-Bit16free;
2525 Bit16free=16;
2526 };
2527
2528 }; // end cycle while(Bit13ToWrite>0)
2529
2530 }; // end cycle DataDSP
2531 if(Bit16free!=16) { fTracklength++; CheckSum=CheckSum^fDataTrack[fTracklength]; };
2532 CheckSum=(CheckSum >> 8)^(CheckSum&0x00FF);
2533 fDataTrack[fTracklength-Nword+11]=(0x0280 | (CheckSum >> 3));
2534 fDataTrack[fTracklength-Nword+12]=(0x1C00 | (CheckSum << 13) );
2535
2536 // end write 13 bit DataDSP bufer inside 16 bit fDataTrack buffer
2537
2538 //write trailer on buffer
2539 UShort_t ReLength=(UShort_t)((Nword+13)*2+3);
2540 UShort_t OveCheckCode=0x0000;
2541
2542 fDataTrack[fTracklength]=0x0000;
2543 fTracklength++;
2544
2545 fDataTrack[fTracklength]=(ReLength >> 8);
2546 fTracklength++;
2547
2548 fDataTrack[fTracklength]=( (ReLength << 8) | (OveCheckCode & 0x00FF) );
2549 fTracklength++;
2550 // end trailer
2551 // std:: cout << "DSPlength " <<DSPlength << endl;
2552 // std:: cout << "Nword " << Nword << endl;
2553 // std:: cout << "ReLength " << ReLength << endl;
2554 };
2555 // std:: cout << "ntrastot " << ntrastot << endl;
2556
2557 };
2558
2559
2560 Float_t Digitizer::SaturationTrack(Float_t ADC) {
2561 Float_t SatFact=1.;
2562 if(ADC<70.) { SatFact=80./ADC; };
2563 if(ADC>3000.) { SatFact=3000./ADC; };
2564 return SatFact;
2565 };
2566
2567
2568
2569
2570
2571

  ViewVC Help
Powered by ViewVC 1.1.23