Bug fix for SDD Test Beam simulation
[u/mrichter/AliRoot.git] / ITS / AliITSspdTestBeam.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17   $Id$
18 */
19 #include <stddef.h>
20 #include <iomanip>
21 #include <Riostream.h>
22 #include <fstream>
23
24 #include "AliITSspdTestBeam.h"
25
26 ClassImp(AliITSspdTestBeam)
27
28 //----------------------------------------------------------------------
29 AliITSspdTestBeam::AliITSspdTestBeam(){
30     // Default Constructor for the Task AliITSspdTestBeam.
31     // Inputs:
32     //    none.
33     // Outputs:
34     //    none.
35     // Return:
36     //     A default constructed AliITSspdTestBeam class
37
38     fRH           = 0;
39     fRT           = 0;
40     fNBrst        = 0;
41     fBrstSize     = 0;
42     fBrst         = 0;
43     fNData        = 0;
44     fData         = 0;
45     fHData        = 0;
46     fTData        = 0;
47     SetTerminationWord();
48     fNEvents      = 0;
49     fBuffSize     = 0;
50     fBuff         = 0;
51     fITS          = 0;
52     fNfiles       = 0;
53     fMaxFiles     = 0;
54     fFiles        = 0;
55     fNeventsStart = 0;
56     fNeventsEnd   = 0;
57 }
58 //----------------------------------------------------------------------
59 AliITSspdTestBeam::AliITSspdTestBeam(const Char_t *filename,const Char_t *opt,
60                                      AliITS *its){
61     // Standard Constructor for the Task AliITSspdTestBeam.
62     // Inputs:
63     //    const Char_t *filename   File where to read in the SPD test beam data
64     //    const Char_t *opt        Option, 2002 => 2002 test beam data.
65     // Outputs:
66     //    none.
67     // Return:
68     //     A default constructed AliITSspdTestBeam class
69
70     fRH           = 0;
71     fRT           = 0;
72     fNBrst        = 0;
73     fBrstSize     = 0;
74     fBrst         = 0;
75     fNData        = 0;
76     fData         = 0;
77     fHData        = 0;
78     fTData        = 0;
79     SetTerminationWord();
80     fNEvents      = 0;
81     fBuffSize     = 0;
82     fBuff         = 0;
83     fITS          = 0;
84     fNfiles       = 0;
85     fMaxFiles     = 0;
86     fFiles        = 0;
87     fNeventsStart = 0;
88     fNeventsEnd   = 0;
89     //
90     fITS          = its;
91     fNfiles       = 0;
92     OpenInputFile(filename,0,-1);
93     if(strcmp(opt,"2002")) cout << "2002 assumed" << endl;
94 }
95
96 //----------------------------------------------------------------------
97 AliITSspdTestBeam::~AliITSspdTestBeam(){
98     // Destructor. Frees up any memory allocated or closes any files opened.
99     // Inputs:
100     //    none.
101     // Outputs:
102     //    none.
103     // Return:
104     //     nothing.
105     Int_t i,np;
106
107     np = GetNumberOfPilots();
108     fRH = 0;  // Just a Pointer into fBuff.
109     fRT = 0;  // Just a Pointer into fBuff.
110     if(fBrst){delete[] fBrst; fBrst = 0;}
111     if(fNData)for(i=0;i<np;i++){
112         if(fNData[i]) delete[] fNData[i];
113     } // end if
114     if(fNData) {delete[] fNData; fNData = 0;}
115     if(fData)for(i=0;i<np;i++){
116         if(fData[i]) delete[] fData[i];
117     } // end if
118     if(fData) delete[] fData;
119     fData = 0;
120     if(fHData)for(i=0;i<np;i++){
121         if(fHData[i]) delete[] fHData[i];
122     } // end if
123     if(fHData) delete[] fHData;
124     fHData = 0;
125     if(fTData)for(i=0;i<np;i++){
126         if(fTData[i]) delete[] fTData[i];
127     } // end if
128     if(fTData) delete[] fTData;
129     fTData = 0;
130     for(i=0;i<fMaxFiles;i++){
131         if(fFiles[i]!=0) delete fFiles[i];
132     } // end for i
133     if(fBrstSize)for(i=0;i<np;i++){
134         if(fBrstSize[i]) delete[] fBrstSize[i];
135     } // end if
136     if(fBrstSize) {delete[] fBrstSize; fBrstSize = 0;}
137     delete[] fBuff;
138     fITS = 0; //delete fITS;
139     delete[] fFiles;
140     delete[] fNeventsStart;
141     delete[] fNeventsEnd;
142 }
143 //----------------------------------------------------------------------
144 Int_t AliITSspdTestBeam::OpenInputFile(const Char_t *filename,Int_t start,Int_t end){
145     // Opens input file for reading spd test beam data.
146     // Inputs:
147     //    const Char_t *filename    file name to read data from
148     // Outputs:
149     //    none.
150     // Return:
151     //    An error number. 0=success, -1=failure.
152     Int_t stat = 0,i;
153
154     if(fMaxFiles==0) {
155         fMaxFiles     = 5;
156         fFiles        = new ifstream*[fMaxFiles];
157         fNeventsStart = new Int_t[fMaxFiles];
158         fNeventsEnd   = new Int_t[fMaxFiles];
159     } // end if
160     if(fNfiles==fMaxFiles){// Need to expand array of open files.
161         ifstream *tmp[fMaxFiles];
162         Int_t st[fMaxFiles],en[fMaxFiles];
163         for(i=0;i<fMaxFiles;i++) { // copy pointers into tmp
164             tmp[i]    = fFiles[i];
165             fFiles[i] = 0;
166             st[i]     = fNeventsStart[i];
167             en[i]     = fNeventsEnd[i];
168         } // end for i
169         delete fFiles;
170         fMaxFiles    += 5;  // expand by 5.
171         fFiles        = new ifstream*[fMaxFiles];
172         fNeventsStart = new Int_t[fMaxFiles];
173         fNeventsEnd   = new Int_t[fMaxFiles];
174         for(i=0;i<fMaxFiles;i++) { // copy pointers back into fFiles
175             fFiles[i]        = 0;  // and zero rest.
176             fNeventsStart[i] = 0;
177             fNeventsEnd[i]   = 0;
178             if(i<fNfiles) {
179                 fFiles[i]        = tmp[i];
180                 tmp[i]           = 0;
181                 fNeventsStart[i] = st[i];
182                 fNeventsEnd[i]   = en[i];
183             } // end if i<fNfiles
184         } // end for i
185         // the array of pointers tmp is deleted automatically.
186     } // end if
187     // Open file
188     fFiles[fNfiles] = new ifstream(filename,ios::in|ios::binary);
189     if(fFiles[fNfiles]==0){// file open error
190         cout << "Error opening input file " << filename << endl;
191         stat = -1;
192         return stat;
193     } // end if
194     fNeventsStart[fNfiles] = start;
195     fNeventsEnd[fNfiles]   = end;
196     fNfiles++;
197     return stat;
198 }
199 //----------------------------------------------------------------------
200 Int_t AliITSspdTestBeam::Read(Int_t i){
201     // Read in one buffer's worth of the file.
202     // Inputs:
203     //    Int_t i  Which file from the array of files to be read in.
204     // Outputs:
205     //    none.
206     // Return:
207     //    size of file.
208     Int_t filesize=0;
209
210     fFiles[i]->seekg(0,ios::end);
211     filesize  = fFiles[i]->tellg();
212     fFiles[i]->seekg(0,ios::beg);
213     if(fBuff) delete[] fBuff;
214     fBuffSize = filesize;
215     fBuff     = new UChar_t[fBuffSize];
216     fFiles[i]->read((Char_t*)fBuff,fBuffSize);
217     fFiles[i] ->close();
218     return filesize;
219 }
220 //----------------------------------------------------------------------
221 Int_t AliITSspdTestBeam::Decode(){
222     // Decode the fBuff read in.
223     // Inputs:
224     //    none.
225     // Outputs:
226     //    none.
227     // Return:
228     //    sets up the array fData fRH, and fRT
229     Int_t stat=0;
230     UInt_t *tr;
231     union {
232         UInt_t  *wd;
233         UChar_t *bt;
234     }u; // end union
235     Int_t size;
236     Int_t *ivnt,iburst,ip,np,i,j;
237     AliITSspdTestBeamData  *d;
238     AliITSspdTestBeamBurst *b;
239
240     np = GetNumberOfPilots();
241     ivnt = new Int_t[np];
242     for(i=0;i<np;i++) ivnt[i] = 0;
243     fRH  = (AliITSspdTestBeamHeader*) &(fBuff[0]); // Sets up the Run Header.
244     fRT  = (AliITSspdTestBeamTail*)&(fBuff[fBuffSize-fRT->SizeOf()]);
245     // Check termination
246     tr   = (UInt_t*) &(fBuff[fBuffSize-(fRT->SizeOf())-sizeof(UInt_t)]);
247     if(!(*tr==fTermination)){
248         cout << "Error Termination word not found at "<<tr<<endl;
249         exit(-1);
250     } // end if
251     if(fNData)for(i=0;i<np;i++){
252         if(fNData[i]) delete[] fNData[i];
253     } // end if
254     if(fNData) {delete[] fNData; fNData = 0;}
255     if(fData)for(i=0;i<np;i++){
256         if(fData[i]) delete[] fData[i];
257     } // end if
258     if(fData) {delete[] fData; fData = 0;}
259     if(fHData)for(i=0;i<np;i++){
260         if(fHData[i]) delete[] fHData[i];
261     } // end if
262     if(fHData) {delete[] fHData; fHData = 0;}
263     if(fTData)for(i=0;i<np;i++){
264         if(fTData[i]) delete[] fTData[i];
265     } // end if
266     if(fTData) {delete[] fTData; fTData = 0;}
267     if(fBrstSize)for(i=0;i<np;i++){
268         if(fBrstSize[i]) delete[] fBrstSize[i];
269     } // end if
270     if(fBrstSize) {delete[] fBrstSize; fBrstSize = 0;}
271     fNEvents  = fRH->GetNumberOfEvents();
272     fNBrst    = fNEvents/fRH->GetBurstSize();
273     fBrst     = new AliITSspdTestBeamBurst*[fNBrst];
274     fBrstSize = new Int_t*[np];
275     fNData    = new Int_t*[np];
276     fData     = new AliITSspdTestBeamData**[np];
277     fHData    = new AliITSspdTestBeamData**[np];
278     fTData    = new AliITSspdTestBeamData**[np];
279     for(i=0;i<np;i++){
280         fBrstSize[i] = new Int_t[fNBrst];
281         fNData[i]    = new Int_t[fNEvents];
282         fData[i]     = new AliITSspdTestBeamData*[fNEvents];
283         fHData[i]    = new AliITSspdTestBeamData*[fNEvents];
284         fTData[i]    = new AliITSspdTestBeamData*[fNEvents];
285         for(j=0;j<fNEvents;j++){
286             fNData[i][j] = 0;
287             fData[i][j]  = 0;
288             fHData[i][j] = 0;
289             fTData[i][j] = 0;
290         } // end for j
291     } // end for i
292     if(fBrst){delete[] fBrst; fBrst = 0;}
293     size      = fRH->SizeOf();
294     u.bt      = &fBuff[size];
295     //
296     for(iburst=0;(*(u.wd) != fTermination)&&(u.wd<tr);iburst++){ // loop over Bursts
297         b   = (AliITSspdTestBeamBurst *) u.wd;
298         fBrst[iburst] = b;
299         u.bt += b->SizeOf(); // increment wd byte wise
300         for(ip=0;ip<np;ip++){  // loop over pilots
301             // Get size of data stored for this pilot.
302             fBrstSize[ip][iburst] = (UInt_t) u.wd;
303             u.bt += sizeof(UInt_t); // increment wd byte wise
304             for(i=0;i<fBrstSize[ip][iburst];i++){ // loop over data
305                 d = (AliITSspdTestBeamData *) u.wd;
306                 switch (d->Mode()){
307                 case AliITSTestBeamData::kData :
308                     fNData[ip][ivnt[ip]]++;
309                     // set pointer to first data member
310                     if(fData[ip][ivnt[ip]] == 0 ) fData[ip][ivnt[ip]] = d;
311                     break;
312                 case AliITSTestBeamData::kHead :
313                     fNData[ip][ivnt[ip]]   = 0;
314                     fData[ip][ivnt[ip]]    = 0;
315                     fHData[ip][ivnt[ip]++] = d;
316                     break;
317                 case AliITSTestBeamData::kTail  : 
318                 case AliITSTestBeamData::kAbort :
319                     fTData[ip][ivnt[ip]] = d;
320                     break;
321                 default:
322                     cout << "Unknown Data Type: wd="<<hex<<*(u.wd)<<dec<<endl; 
323                     break;
324                 } // end switch
325                 u.bt += d->SizeOf(); // increment wd byte wise
326             } // end for i (next data word).
327         } // end for loop over pilots (ip).
328     } // end for loop over bursts
329     delete[] ivnt;
330     return stat;
331 }
332 //============================================================================
333 void AliITSspdTestBeamHeader::Print(ostream *os){
334     // print out the header information
335     // Inputs:
336     //    ostream *os  Pointer to the output stream.
337     // Outputs:
338     //    none.
339     // Return:
340     //    none.
341 /*
342 #if defined __GNUC__
343 #if __GNUC__ > 2
344     ios::fmtflags fmt;
345 #else
346     Int_t fmt;
347 #endif
348 #else
349 #if defined __ICC || defined __ECC
350     ios::fmtflags fmt;
351 #else
352     Int_t fmt;
353 #endif
354 #endif
355 */
356     *os<<"Version: "<<fUnion.fHead.fVersion<<" Written: "<<fUnion.fHead.fDate;
357     *os<<" " << fUnion.fHead.fTime << endl;
358     *os<<"Buffer Size [0], [1], [2]: " << fUnion.fHead.fBuffSize[0] << ",";
359     *os<<fUnion.fHead.fBuffSize[1]<<"," <<fUnion.fHead.fBuffSize[2] << endl;
360     *os<<"Test Pulse: " << fUnion.fHead.fTestPulse << endl;
361     *os<<"Trigger Mode General, [0], [1], [2]: " << fUnion.fHead.fTriggerMode;
362     *os<<","<<fUnion.fHead.fTrigger[0]<<","<<fUnion.fHead.fTrigger[1]<< ",";
363     *os<<fUnion.fHead.fTrigger[2] << endl;
364     *os<<"Number of Events: " << fUnion.fHead.fNEvents << " Burst Size: ";
365     *os<<fUnion.fHead.fBurstSize << endl;
366     return;
367 }
368 //----------------------------------------------------------------------
369 ostream &operator<<(ostream &os,AliITSspdTestBeamHeader &p){
370     // Standard output operator. See Print
371     // Inputs:
372     //    ostream                 &os  the output stream.
373     //    AliITSspdTestBeamHeader &p   the data to be printed out.
374     // Outputs:
375     //    none.
376     // Return:
377     //    ostream &os pointing now to the end of the present stream.
378
379     p.Print(&os);
380     return os;
381 }
382 //============================================================================
383 void AliITSspdTestBeamTail::Print(ostream *os){
384     // print out the Tail information
385     // Inputs:
386     //    ostream *os  Pointer to the output stream.
387     // Outputs:
388     //    none.
389     // Return:
390     //    none.
391 /*
392 #if defined __GNUC__
393 #if __GNUC__ > 2
394     ios::fmtflags fmt;
395 #else
396     Int_t fmt;
397 #endif
398 #else
399 #if defined __ICC || defined __ECC
400     ios::fmtflags fmt;
401 #else
402     Int_t fmt;
403 #endif
404 #endif
405 */
406     *os << "Number of Events: "<< fUnion.fTail.fEvents << " Written: "
407         << fUnion.fTail.fDate;
408     *os << " " << fUnion.fTail.fTime << endl;
409     *os <<"Termination Flag: " << fUnion.fTail.fTermMode << endl; 
410     return;
411 }
412 //----------------------------------------------------------------------
413 ostream &operator<<(ostream &os,AliITSspdTestBeamTail &p){
414     // Standard output operator. See Print
415     // Inputs:
416     //    ostream                 &os  the output stream.
417     //    AliITSspdTestBeamHeader &p   the data to be printed out.
418     // Outputs:
419     //    none.
420     // Return:
421     //    ostream &os pointing now to the end of the present stream.
422
423     p.Print(&os);
424     return os;
425 }
426 //============================================================================
427 void AliITSspdTestBeamBurst::Print(ostream *os){
428     // print out the Burst information
429     // Inputs:
430     //    ostream *os  Pointer to the output stream.
431     // Outputs:
432     //    none.
433     // Return:
434     //    none.
435 /*
436 #if defined __GNUC__
437 #if __GNUC__ > 2
438     ios::fmtflags fmt;
439 #else
440     Int_t fmt;
441 #endif
442 #else
443 #if defined __ICC || defined __ECC
444     ios::fmtflags fmt;
445 #else
446     Int_t fmt;
447 #endif
448 #endif
449 */
450     *os << "Burst Number: "<< fUnion.fBrst.fNumber << " Transfers: " 
451         << fUnion.fBrst.fTransfers << endl; 
452     return;
453 }
454 //----------------------------------------------------------------------
455 ostream &operator<<(ostream &os,AliITSspdTestBeamBurst &p){
456     // Standard output operator. See Print
457     // Inputs:
458     //    ostream                 &os  the output stream.
459     //    AliITSspdTestBeamHeader &p   the data to be printed out.
460     // Outputs:
461     //    none.
462     // Return:
463     //    ostream &os pointing now to the end of the present stream.
464
465     p.Print(&os);
466     return os;
467 }
468 //======================================================================
469 void AliITSspdTestBeamData::Print(ostream *os){
470     // print out the the Test Beam Data information
471     // Inputs:
472     //    ostream *os  Pointer to the output stream.
473     // Outputs:
474     //    none.
475     // Return:
476     //    none.
477 /*
478 #if defined __GNUC__
479 #if __GNUC__ > 2
480     ios::fmtflags fmt;
481 #else
482     Int_t fmt;
483 #endif
484 #else
485 #if defined __ICC || defined __ECC
486     ios::fmtflags fmt;
487 #else
488     Int_t fmt;
489 #endif
490 #endif
491 */
492     *os << "Word=" << hex << fUnion.fBuf[0] << hex << fUnion.fBuf[1] 
493                    << hex << fUnion.fBuf[2] << hex << fUnion.fBuf[3] << dec;
494     switch (this->Mode()){
495     case AliITSTestBeamData::kData :
496         *os << " kData chip=" << setw(3) << fUnion.fDataD.fChip; 
497         *os << " Row="        << setw(3) << fUnion.fDataD.fRow;
498         *os << " Column="     << setw(3) << fUnion.fDataD.fColm;
499         break;
500     case AliITSTestBeamData::kHead :
501         *os << " kHead Event Sync =" << fUnion.fDataH.fEventSync;
502         break;
503     case AliITSTestBeamData::kTail  :
504         *os << " kTail Transmitted word count =" << fUnion.fDataT.fTrans;
505         break;
506     case AliITSTestBeamData::kAbort :
507         *os << " kAbort Transmitted word count =" << fUnion.fDataA.fTrans;
508         break;
509     default:
510         *os << " Unknown Data Type"; 
511         break;
512     } // end switch
513     *os << endl;
514     return;
515 }
516 //----------------------------------------------------------------------
517 ostream &operator<<(ostream &os,AliITSspdTestBeamData &p){
518     // Standard output operator. See Print
519     // Inputs:
520     //    ostream                 &os  the output stream.
521     //    AliITSspdTestBeamHeader &p   the data to be printed out.
522     // Outputs:
523     //    none.
524     // Return:
525     //    ostream &os pointing now to the end of the present stream.
526
527     p.Print(&os);
528     return os;
529 }