Compatibility with raw data from the beam test
[u/mrichter/AliRoot.git] / ITS / AliITSDDLRawData.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2003, 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 /* $Id$ */
17
18
19 //This class contains all the necessary methods to create the Raw Data
20 //files (slides) for the ITS data challenges for:
21 //SPD 
22 //SDD
23 //SSD
24
25 #include <stdlib.h>
26 #include <Riostream.h>
27 #include <TClonesArray.h>
28 #include <TTree.h>
29 #include <TMath.h>
30 #include "AliITS.h"
31 #include "AliITSgeom.h"
32 #include "AliITSdigitSPD.h"
33 #include "AliITSdigitSDD.h"
34 #include "AliITSdigitSSD.h"
35 #include "AliITSDDLRawData.h"
36 #include "AliRawDataHeader.h"
37 #include "AliITSRawStreamSPD.h"
38 #include "AliITSRawStreamSDD.h"
39 #include "AliITSRawStreamSSD.h"
40 #include "AliBitPacking.h"
41
42 ClassImp(AliITSDDLRawData)
43
44 ////////////////////////////////////////////////////////////////////////////////////////
45 AliITSDDLRawData::AliITSDDLRawData(){
46   //Default constructor
47   fIndex=-1;
48   fHalfStaveModule=-1;
49   fVerbose=0;
50 }
51
52 ////////////////////////////////////////////////////////////////////////////////////////
53
54 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) : 
55     TObject(source){
56   //Copy Constructor
57   this->fIndex=source.fIndex;
58   this->fHalfStaveModule=source.fHalfStaveModule;
59   this->fVerbose=source.fVerbose;
60   return;
61 }
62
63 ////////////////////////////////////////////////////////////////////////////////////////
64
65 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
66   //Assigment operator
67   this->fIndex=source.fIndex;
68   this->fHalfStaveModule=source.fHalfStaveModule;
69   this->fVerbose=source.fVerbose;
70   return *this;
71 }
72
73 ////////////////////////////////////////////////////////////////////////////////////////
74 //STRIP 
75 //
76
77 void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
78   //This method packs the SSD digits in a proper 32 bits structure
79   Int_t ix;
80   Int_t iz;
81   Int_t is;
82   UInt_t word;
83   UInt_t baseWord;
84   Int_t ndigits = ITSdigits->GetEntries();
85   AliITSdigit *digs;
86   ofstream ftxt;
87   if(ndigits){
88     if (fVerbose==2){
89       ftxt.open("SSDdigits.txt",ios::app);
90     }
91     for (Int_t digit=0;digit<ndigits;digit++) {
92       digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
93       iz=digs->GetCoord1();  // If iz==0, N side and if iz=1 P side
94       ix=digs->GetCoord2();  // Strip Numbar
95       is=digs->GetCompressedSignal();  // ADC Signal
96       // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
97       if (fVerbose==2)
98         ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
99       baseWord=0;
100       word=is-1;
101       AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
102       word=ix;
103       AliBitPacking::PackWord(word,baseWord,10,19);//Strip Number
104       word=iz;      
105       AliBitPacking::PackWord(word,baseWord,20,20);//ADC Channel ID (N or P side)
106       word=mod;
107       AliBitPacking::PackWord(word,baseWord,21,31);//ADC module ID
108       fIndex++;
109       buf[fIndex]=baseWord;
110     }//end for
111   }//end if
112   if (fVerbose==2)
113     ftxt.close();
114   return;
115 }//end GetDigitsSSD
116
117 ////////////////////////////////////////////////////////////////////////////////////////
118 //Silicon Drift Detector
119 //
120
121 void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){  
122   //This method packs the SSD digits in a proper 32 bits structure
123   Int_t ix;
124   Int_t iz;
125   Int_t is;
126   UInt_t word;
127   UInt_t baseWord;
128   Int_t ndigits = ITSdigits->GetEntries();
129   AliITSdigit *digs;
130   ofstream ftxt;
131   if(ndigits){
132     //cout<<"Mudule "<<mod<<" number of digits "<<ndigits<<endl;
133     if (fVerbose==2)
134       ftxt.open("SDDdigits.txt",ios::app);
135     for (Int_t digit=0;digit<ndigits;digit++) {
136       digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
137       iz=digs->GetCoord1();  // Anode
138       ix=digs->GetCoord2();  // Time
139       is=digs->GetCompressedSignal();  // ADC Signal
140       if (fVerbose==2)
141         ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
142       //      cout<<"Amplitude value:"<<is<<" Time Bucket:"<<ix<<" Anode:"<<iz<<endl;
143       if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
144       baseWord=0;
145       /*
146       //10 bits words for amplitude value
147       word=is;
148       AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
149       word=ix;
150       AliBitPacking::PackWord(word,baseWord,10,17);//Time bucket
151       word=iz;
152       AliBitPacking::PackWord(word,baseWord,18,26);//Anode Number
153       word=mod;
154       AliBitPacking::PackWord(word,baseWord,27,31);//Module number
155       */
156       
157       //8bits words for amplitude value
158       word=is;
159       AliBitPacking::PackWord(word,baseWord,0,7);//ADC data
160       word=ix;
161       AliBitPacking::PackWord(word,baseWord,8,15);//Time bucket
162       word=iz;
163       AliBitPacking::PackWord(word,baseWord,16,24);//Anode Number
164       word=mod;
165       AliBitPacking::PackWord(word,baseWord,25,31);//Module number
166      
167       fIndex++;
168       buf[fIndex]=baseWord;
169     }//end for
170   }//end if
171   if(fVerbose==2)
172     ftxt.close();
173   return;
174 }//end GetDigitsSDD
175
176 ////////////////////////////////////////////////////////////////////////////////////////
177 //PIXEL 
178 //
179
180 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
181   //This method packs the SPD digits in a proper 32 structure
182   //Since data is zero suppressed,the coordinates for the chip having zero digits 
183   //doesn't get listed in the galice.root file. However the SPD format requires 
184   //the empty chip to be written with chip header and chip trailer.
185   Int_t ix;
186   Int_t iz;
187   Int_t chipNo=0;
188   UInt_t baseWord=0;
189   UInt_t hitRow=0;
190   Int_t chipHitCount=0;  //Number of Hit in the current chip
191   Int_t previousChip=-1; //Previuos chip respect to the actual aone
192   Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
193   //cout<<"      Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
194   AliITSdigit *digs;
195   fHalfStaveModule++;    //It's a private variable used to distinguish between the firs  
196                          //and the second module of an Half Stave Module
197   ofstream ftxt;
198   if(ndigits){
199     //loop over digits
200     if (fVerbose==2)
201       ftxt.open("SPDdigits.txt",ios::app);
202     for (Int_t digit=0;digit<ndigits;digit++){
203       digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
204       /*---------------------------------------------------------------------------
205        *     Each module contains 5 read out chips of 256 rows and 32 columns.
206        *     So, the cell number in Z direction varies from 0 to 159.  Therefore,
207        *     to get the chip address (0 to 4), we need to divide column number by 32.
208        *     ---------------------------------------------------------------------*/
209       iz=digs->GetCoord1();  // Cell number in Z direction 
210       ix=digs->GetCoord2();  // Cell number in X direction
211       chipNo=iz/32;
212       if(fVerbose==2)
213         ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
214       hitRow=iz-chipNo*32;
215       if(fHalfStaveModule){
216         chipNo+=5;
217         fHalfStaveModule=-1;
218       }//end if
219       if(previousChip==-1){
220         //loop over chip without digits 
221         //Even if there aren't digits for a given chip 
222         //the chip header and the chip trailer are stored
223         for(Int_t i=0;i<(iz/32);i++){
224           if(chipNo>4)
225             WriteChipHeader(i+5,(mod/2),baseWord);
226           else
227             WriteChipHeader(i,(mod/2),baseWord);
228           WriteChipTrailer(buf,chipHitCount,baseWord);
229           chipHitCount=0;
230         }//end for
231         WriteChipHeader(chipNo,(mod/2),baseWord);
232         chipHitCount++;
233         WriteHit(buf,ix,hitRow,baseWord);
234         previousChip=chipNo;
235       }//end if
236       else{
237         if(previousChip!=chipNo){
238           WriteChipTrailer(buf,chipHitCount,baseWord);
239           chipHitCount=0;
240           for(Int_t i=previousChip+1;i<chipNo;i++){
241             WriteChipHeader(i,(mod/2),baseWord);
242             WriteChipTrailer(buf,0,baseWord);
243             chipHitCount=0;
244           }//end for
245           WriteChipHeader(chipNo,(mod/2),baseWord);
246           previousChip=chipNo;
247         }//end if
248         chipHitCount++;
249         WriteHit(buf,ix,hitRow,baseWord);
250       }//end else
251     }//end for
252     //Even if there aren't digits for a given chip 
253     //the chip header and the chip trailer are stored
254     Int_t end=4;
255     if(chipNo>4)end+=5;
256     WriteChipTrailer(buf,chipHitCount,baseWord);
257     chipHitCount=0;
258     for(Int_t i=chipNo+1;i<=end;i++){
259       WriteChipHeader(i,(mod/2),baseWord);
260       WriteChipTrailer(buf,0,baseWord);
261       chipHitCount=0;
262     }//end for
263   }//end if
264   else{
265     //In this module there aren't digits but
266     //the chip header and chip trailer are store anyway
267     if(fHalfStaveModule){
268       chipNo=5;
269       fHalfStaveModule=-1;
270     }//end if
271     for(Int_t i=0;i<5;i++){
272       WriteChipHeader(chipNo+i,(mod/2),baseWord);
273       WriteChipTrailer(buf,chipHitCount,baseWord);
274       chipHitCount=0;
275     }//end for
276   }//end else 
277   if(fVerbose==2)
278     ftxt.close();
279   return;
280 }//end GetDigitsSPD
281
282 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
283
284 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
285   //This method creates the Raw data files for SPD detectors
286   const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
287   UInt_t buf[kSize];      //One buffer cell can contain 2 digits 
288   fIndex=-1;
289
290   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
291   char fileName[15];
292   ofstream outfile;         // logical name of the output file 
293   AliRawDataHeader header;
294
295   //loop over DDLs
296   for(Int_t i=0;i<AliITSRawStreamSPD::kDDLsNumber;i++){
297     sprintf(fileName,"ITSSPD_%d.ddl",i+AliITSRawStreamSPD::kDDLOffset); //The name of the output file.
298 #ifndef __DECCXX
299     outfile.open(fileName,ios::binary);
300 #else
301     outfile.open(fileName);
302 #endif
303     //write Dummy DATA HEADER
304     UInt_t dataHeaderPosition=outfile.tellp();
305     outfile.write((char*)(&header),sizeof(header));
306     //Loops over Modules of a particular DDL
307     for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
308       Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
309       digits->Clear();
310       branch->GetEvent(moduleNumber);
311       //For each Module, buf contains the array of data words in Binary format    
312       //fIndex gives the number of 32 bits words in the buffer for each module
313       GetDigitsSPD(digits,moduleNumber,i,buf);
314       outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
315       for(Int_t i=0;i<(fIndex+1);i++){
316         buf[i]=0;
317       }//end for
318       fIndex=-1;
319     }//end for
320     
321     //Write REAL DATA HEADER
322     UInt_t currentFilePosition=outfile.tellp();
323     outfile.seekp(dataHeaderPosition);
324     header.fSize=currentFilePosition-dataHeaderPosition;
325     outfile.write((char*)(&header),sizeof(header));
326     outfile.close();
327   }//end for
328
329   return 0;  
330 }
331
332 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
333
334 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
335   //This method creates the Raw data files for SSD detectors
336   const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
337   UInt_t buf[kSize];      
338   fIndex=-1;
339
340   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
341   char fileName[15];
342   ofstream outfile;         // logical name of the output file 
343   AliRawDataHeader header;
344
345   //loop over DDLs  
346   for(Int_t i=0;i<AliITSRawStreamSSD::kDDLsNumber;i++){
347     sprintf(fileName,"ITSSSD_%d.ddl",i+AliITSRawStreamSSD::kDDLOffset); //The name of the output file
348 #ifndef __DECCXX
349     outfile.open(fileName,ios::binary);
350 #else
351     outfile.open(fileName);
352 #endif
353     //write Dummy DATA HEADER
354     UInt_t dataHeaderPosition=outfile.tellp();
355     outfile.write((char*)(&header),sizeof(header));
356     
357     //Loops over Modules of a particular DDL
358     for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
359       Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
360       if(moduleNumber!=-1){
361         digits->Clear();
362         branch->GetEvent(moduleNumber);
363         //For each Module, buf contains the array of data words in Binary format          
364         //fIndex gives the number of 32 bits words in the buffer for each module
365         GetDigitsSSD(digits,mod,moduleNumber,i,buf);
366         outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
367         fIndex=-1;
368       }//end if
369     }//end for
370
371     //Write REAL DATA HEADER
372     UInt_t currentFilePosition=outfile.tellp();
373     outfile.seekp(dataHeaderPosition);
374     header.fSize=currentFilePosition-dataHeaderPosition;
375     header.SetAttribute(0);  // valid data
376     outfile.write((char*)(&header),sizeof(header));
377     outfile.close();
378   }//end for
379
380   return 0;  
381 }
382
383 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
384
385 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
386     //This method creates the Raw data files for SDD detectors
387   const Int_t kSize=131072; //256*512
388   UInt_t buf[kSize];      
389   fIndex=-1;
390
391   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
392   char fileName[15];
393   ofstream outfile;             // logical name of the output file 
394   AliRawDataHeader header;
395
396   //loop over DDLs  
397   for(Int_t i=0;i<AliITSRawStreamSDD::kDDLsNumber;i++){
398     sprintf(fileName,"ITSSDD_%d.ddl",i+AliITSRawStreamSDD::kDDLOffset); //The name of the output file
399 #ifndef __DECCXX
400     outfile.open(fileName,ios::binary);
401 #else
402     outfile.open(fileName);
403 #endif
404     //write Dummy DATA HEADER
405     UInt_t dataHeaderPosition=outfile.tellp();
406     outfile.write((char*)(&header),sizeof(header));
407
408     //Loops over Modules of a particular DDL
409     for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
410       Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
411       if(moduleNumber!=-1){
412         digits->Clear();
413         branch->GetEvent(moduleNumber);
414         //For each Module, buf contains the array of data words in Binary format          
415         //fIndex gives the number of 32 bits words in the buffer for each module
416         //      cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
417         GetDigitsSDD(digits,mod,moduleNumber,i,buf);
418         outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
419         fIndex=-1;
420       }//end if
421     }//end for
422     
423     //Write REAL DATA HEADER
424     UInt_t currentFilePosition=outfile.tellp();
425     outfile.seekp(dataHeaderPosition);
426     header.fSize=currentFilePosition-dataHeaderPosition;
427     header.SetAttribute(0);  // valid data
428     outfile.write((char*)(&header),sizeof(header));
429     outfile.close();
430   }//end for
431
432   return 0;  
433 }
434
435 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
436
437 void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t /*EventCnt*/,UInt_t &BaseWord){
438   //This method writes a chip header 
439   //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
440   BaseWord=0;
441   AliBitPacking::PackWord(ChipAddr,BaseWord,0,3);
442 //  AliBitPacking::PackWord(EventCnt,BaseWord,4,10);
443   AliBitPacking::PackWord(0,BaseWord,4,10);
444   AliBitPacking::PackWord(0x7,BaseWord,11,13);
445   AliBitPacking::PackWord(0x1,BaseWord,14,15);
446   return;
447 }//end WriteChipHeader
448
449 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
450
451 void AliITSDDLRawData::ReadChipHeader(Int_t &ChipAddr,Int_t &EventCnt,UInt_t BaseWord){
452   //This method reads a chip header
453   UInt_t temp=AliBitPacking::UnpackWord(BaseWord,0,3);
454   ChipAddr=(Int_t)temp;
455   temp=AliBitPacking::UnpackWord(BaseWord,4,10);
456   EventCnt=(Int_t)temp;
457   if(fVerbose)
458     Info("ReadChipHeader", "Chip:&d Half Stave module:%d",ChipAddr,EventCnt);
459   return;
460 }//end ReadChipHeader
461
462 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
463
464 void  AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
465   //This method writes a chip trailer
466   //pixel fill word
467   if((ChipHitCount%2)!=0){
468     AliBitPacking::PackWord(0xC000,BaseWord,0,15);
469   }
470   AliBitPacking::PackWord(ChipHitCount,BaseWord,16,29);
471   AliBitPacking::PackWord(0x0,BaseWord,30,31);
472   fIndex++;
473   buf[fIndex]=BaseWord;
474   BaseWord=0;
475   return;
476 }//end WriteChipTrailer
477
478 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
479
480 void  AliITSDDLRawData::ReadChipTrailer(Int_t &ChipHitCount,UInt_t BaseWord){
481   //This method reads a chip trailer
482   UInt_t temp=AliBitPacking::UnpackWord(BaseWord,16,29);
483   ChipHitCount=(Int_t)temp;
484   return;
485 }//end ReadChipTrailer
486
487 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
488
489 void  AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
490   //This method writs an hit
491   if(!BaseWord){
492     AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
493     AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
494     AliBitPacking::PackWord(2,BaseWord,14,15);
495   }//end if
496   else{
497     AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
498     AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
499     AliBitPacking::PackWord(2,BaseWord,30,31);
500     fIndex++;
501     buf[fIndex]=BaseWord;
502     BaseWord=0;
503   }//end else
504   return;
505 }//end WriteHit
506