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