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