]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSDDLRawData.cxx
Fix problem in simulated raw data + code cleanup (F.Prino)
[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 "AliITSdigit.h"
30 #include "AliITSDDLRawData.h"
31 #include "AliRawDataHeader.h"
32 #include "AliITSRawStreamSPD.h"
33 #include "AliITSRawStreamSDD.h"
34 #include "AliITSRawStreamSSD.h"
35 #include "AliBitPacking.h"
36 #include "AliDAQ.h"
37 #include "AliFstream.h"
38
39 ClassImp(AliITSDDLRawData)
40
41 ////////////////////////////////////////////////////////////////////////////////////////
42 AliITSDDLRawData::AliITSDDLRawData():
43 fVerbose(0),
44 fIndex(-1),
45 fHalfStaveModule(-1){
46   //Default constructor
47
48 }
49
50 ////////////////////////////////////////////////////////////////////////////////////////
51
52 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) : 
53     TObject(source),
54 fVerbose(source.fVerbose),
55 fIndex(source.fIndex),
56 fHalfStaveModule(source.fHalfStaveModule){
57   //Copy Constructor
58 }
59
60 ////////////////////////////////////////////////////////////////////////////////////////
61
62 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
63   //Assigment operator
64   this->fIndex=source.fIndex;
65   this->fHalfStaveModule=source.fHalfStaveModule;
66   this->fVerbose=source.fVerbose;
67   return *this;
68 }
69
70 ////////////////////////////////////////////////////////////////////////////////////////
71 //STRIP 
72 //
73
74 void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
75   //This method packs the SSD digits in a proper 32 bits structure
76   // Revised by Enrico Fragiacomo
77   Int_t ix;
78   Int_t iz;
79   Int_t is;
80   UInt_t word;
81   UInt_t baseWord;
82   Int_t ndigits = ITSdigits->GetEntries();
83   AliITSdigit *digs;
84   ofstream ftxt;
85   if(ndigits){
86     if (fVerbose==2){
87       ftxt.open("SSDdigits.txt",ios::app);
88     }
89     for (Int_t digit=0;digit<ndigits;digit++) {
90       digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
91       iz=digs->GetCoord1();  // If iz==0, O side and if iz=1 N side
92       ix=digs->GetCoord2();  // Strip Number
93       is=digs->GetCompressedSignal();  // ADC Signal
94       // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
95       if(is<0) is = 4096 + is;
96       if (fVerbose==2)
97         ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
98
99       baseWord=0;
100
101       word=is;
102       AliBitPacking::PackWord(word,baseWord,0,11);//ADC data
103
104       word = (iz==0) ? ix : 1535-ix ; // on N-side 1535-768 -> 0-767
105       AliBitPacking::PackWord(word,baseWord,12,22);//Strip Number
106
107       word = mod%12; // ADC-number (12 ADCs per AD module)
108       word += ( word<6 ) ? 0 : 2; // ADC range 0-5 and 8-13
109       AliBitPacking::PackWord(word,baseWord,24,27);//ADC Channel
110
111       word = mod/12+1; // AD-number (AD module index ranges 1-9)
112       AliBitPacking::PackWord(word,baseWord,28,31);//AD slot
113       fIndex++;
114       buf[fIndex]=baseWord;
115     }//end for
116   }//end if
117   if (fVerbose==2)
118     ftxt.close();
119   return;
120 }//end GetDigitsSSD
121
122 ////////////////////////////////////////////////////////////////////////////////////////
123 //Silicon Drift Detector
124 //
125
126 void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){  
127   //This method packs the SDD digits in a proper 32 bits structure
128   Int_t ix;
129   Int_t iz;
130   Int_t is;
131   UInt_t word=0;
132   UInt_t baseWord=0;
133   Int_t ndigits = ITSdigits->GetEntries();
134   AliITSdigit *digs;
135   ofstream ftxt;
136   Int_t digarr[512][256];
137   for(Int_t i=0;i<512;i++){
138     for(Int_t j=0;j<256;j++){
139       digarr[i][j]=0;
140     }
141   }
142   //word to select the 12 carlos for the 12 modules
143   UInt_t carlosid=805306368+mod;
144   
145   fIndex++;
146   buf[fIndex]=carlosid;
147   Int_t first=0;
148   Int_t last=0;
149   Int_t diff=0;
150   Int_t nbit=0;
151   UInt_t word2=0;
152   Bool_t flag = kFALSE;
153   baseWord=0;
154   Int_t bitinfo1[4] = {3,8,3,7}; //vector with info on bit for timebin info 
155   Int_t wordinfo1[4]= {0,0,0,0}; //vector with word info for timebin info 
156   Int_t bitinfo2[2] = {3,18};    //vector with info on bit for EOR (end of row) info
157   Int_t wordinfo2[3]= {1,65593}; //vector with word info for anode info
158
159   /* for time bin info: word          n bits   meaning
160                          0               3      next info is timebin 
161                          8               3      next word is 8 bit long
162                        tb value          8      timebin value
163                        n (2->7)          3      next info is n bit long
164                         signal           n      signal value
165
166      for anode info:     1               3      next 18 bits are for EOR 
167                                                 increments the anode value
168
169                          EOR             18     error codes + other info
170   */
171              
172   if(ndigits){
173     if (fVerbose==2)
174       ftxt.open("SDDdigits.txt",ios::app);
175     for (Int_t digit=0;digit<ndigits;digit++) {
176       digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
177       iz=digs->GetCoord1();  // Anode
178       ix=digs->GetCoord2();  // Time
179       is=digs->GetCompressedSignal();  // ADC Signal
180       digarr[iz][ix]=is;
181         if (fVerbose==2)
182         ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
183       if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
184     }
185       
186     for(Int_t anode=0;anode<512;anode++){
187       if(flag){            
188         last = first+diff-1;
189         AliBitPacking::PackWord(word2,baseWord,first,last);
190         flag = kFALSE;
191         first = last+1;
192         diff=0;
193       }
194       
195       
196       if(anode == 256){
197         last = 0;
198         first = 0;
199         flag = kFALSE;
200         diff = 0;
201         word2=0;
202         
203       }
204       
205       for(Int_t tb=0;tb<256;tb++){
206         if(digarr[anode][tb]!=0){
207           if(flag){      
208             last = first+diff-1;
209             AliBitPacking::PackWord(word2,baseWord,first,last);
210             flag = kFALSE;
211             first = last+1;
212             diff=0;
213           }
214           wordinfo1[1] = tb;
215           //non lossy compression as it is done in Carlos 
216           //(data are already 10to8bit compressed by AMBRA
217
218           /* if value < 8  value = value - (1 << 2) (word is 2 bit long) 
219              if value < 16 value = value - (1 << 3) (word is 3 bit long)
220              if value < 32 value = value - (1 << 4) (word is 4 bit long)
221              if value < 64 value = value - (1 << 5) (word is 5 bit long)
222              if value <128 value = value - (1 << 6) (word is 6 bit long)
223              if value >=128value = value - (1 << 7) (word is 7 bit long)
224
225           */
226           if(digarr[anode][tb]<8){
227             bitinfo1[3] = 2;
228             wordinfo1[2] = 2;
229             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
230           }               
231           if(digarr[anode][tb]>=8 && digarr[anode][tb]<16){
232             bitinfo1[3] = 3;
233             wordinfo1[2] = 3;
234             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
235           }
236           if(digarr[anode][tb]>=16 && digarr[anode][tb]<32){
237             bitinfo1[3] = 4;
238             wordinfo1[2] = 4;
239             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
240           }
241           if(digarr[anode][tb]>=32 && digarr[anode][tb]<64){
242             bitinfo1[3] = 5;
243             wordinfo1[2] = 5;
244             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
245           }
246           if(digarr[anode][tb]>=64 && digarr[anode][tb]<128){
247             bitinfo1[3] = 6;
248             wordinfo1[2] = 6;
249             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
250           }
251           if(digarr[anode][tb]>=128){
252             bitinfo1[3] = 7;
253             wordinfo1[2] = 7;
254             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
255           }
256           
257           for(Int_t ie=0;ie<4;ie++){
258             
259             if(flag){      
260               last = first+diff-1;
261               AliBitPacking::PackWord(word2,baseWord,first,last);
262               flag = kFALSE;
263               first = last+1;
264               diff=0;
265             }
266             last = first+bitinfo1[ie]-1;
267             if(first < 30 && last < 30){                  
268               AliBitPacking::PackWord(wordinfo1[ie],baseWord,first,last); 
269               first = last+1;
270             }
271             else{
272               if(first<=29){
273                 UInt_t w = AliBitPacking::UnpackWord(wordinfo1[ie],0,29-first);
274                 AliBitPacking::PackWord(w,baseWord,first,29);
275                 Int_t lb = 29-first+1;
276                 diff = bitinfo1[ie]-lb;
277                 word2 = AliBitPacking::UnpackWord(wordinfo1[ie],lb,lb+diff-1);
278                 flag = kTRUE;
279                 if(anode<256) word = 2;//channel 0 of carlos
280                 else word = 3; //channel 1 of carlos
281                 AliBitPacking::PackWord(word,baseWord,30,31);
282                 fIndex++;
283                 buf[fIndex]=baseWord;
284                 first=0;
285                 last = 0;
286                 baseWord=0;
287                 word = 0;
288               }
289               else{
290                 word2 = wordinfo1[ie];
291                 diff = bitinfo1[ie];
292                 flag = kTRUE;
293                 if(anode<256) word = 2; //channel 0 of carlos
294                 else word = 3; //channel 1 of carlos
295                 AliBitPacking::PackWord(word,baseWord,30,31);
296                 fIndex++;
297                 buf[fIndex]=baseWord;
298                 first=0;
299                 last=0;
300                 baseWord=0;
301                 word = 0;
302               }
303             }
304           }
305           
306         }//END IF
307         
308       }//end loop on tb
309     
310       for(Int_t i=0;i<2;i++){
311         if(flag){      
312           last = first+diff-1;
313           AliBitPacking::PackWord(word2,baseWord,first,last);
314           flag = kFALSE;
315           first = last+1;
316           diff=0;
317         }
318         
319         word = wordinfo2[i];
320         nbit = bitinfo2[i];
321         last = first+nbit-1;
322         if(first < 30 && last < 30){              
323           AliBitPacking::PackWord(word,baseWord,first,last); //3 bit code =1 -> next 18 bits for EOR
324           first = last+1;
325         }
326         
327         else{
328           if(first<=29){
329             UInt_t w = AliBitPacking::UnpackWord(word,0,29-first);
330             AliBitPacking::PackWord(w,baseWord,first,29);
331             Int_t lb = 29-first+1;
332             diff = nbit-lb;        
333             word2 = AliBitPacking::UnpackWord(word,lb,lb+diff-1);
334             flag = kTRUE;
335             if(anode<256) word = 2;
336             else word = 3;
337             AliBitPacking::PackWord(word,baseWord,30,31);
338             fIndex++;
339             buf[fIndex]=baseWord;
340             first=0;
341             last = 0;
342             baseWord=0;
343             if(anode==255){
344               flag=kFALSE;
345               word2=0;
346             }
347           }
348           else{
349             word2 = word;
350             diff = nbit;
351             flag = kTRUE;
352             if(anode<256) word = 2;
353             else word = 3;
354             AliBitPacking::PackWord(word,baseWord,30,31);
355             fIndex++;
356             buf[fIndex]=baseWord;
357             first=0;
358             last=0;
359             baseWord=0;
360             if(anode==255){
361               flag=kFALSE;
362               word2=0;
363             }
364           }
365         }
366       }
367     } //end for
368     
369   }
370   if(fVerbose==2)
371     ftxt.close();
372   return;
373 }//end GetDigitsSDD
374
375 ////////////////////////////////////////////////////////////////////////////////////////
376 //PIXEL 
377 //
378
379 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
380   //This method packs the SPD digits in a proper 32 structure
381   //Since data is zero suppressed,the coordinates for the chip having zero digits 
382   //doesn't get listed in the galice.root file. However the SPD format requires 
383   //the empty chip to be written with chip header and chip trailer.
384   //The index of the half stave is calculated as (mod/2).
385   Int_t ix;
386   Int_t iz;
387   Int_t chipNo=0;
388   UInt_t baseWord=0;
389   UInt_t hitRow=0;
390   Int_t chipHitCount=0;  //Number of Hit in the current chip
391   Int_t previousChip=-1; //Previuos chip respect to the actual aone
392   Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
393   //cout<<"      Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
394   AliITSdigit *digs;
395   fHalfStaveModule++;    //It's a private variable used to distinguish between the firs  
396                          //and the second module of an Half Stave Module
397   ofstream ftxt;
398   if(ndigits){
399     //loop over digits
400     if (fVerbose==2)
401       ftxt.open("SPDdigits.txt",ios::app);
402     for (Int_t digit=0;digit<ndigits;digit++){
403       digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
404       /*---------------------------------------------------------------------------
405        *     Each module contains 5 read out chips of 256 rows and 32 columns.
406        *     So, the cell number in Z direction varies from 0 to 159.  Therefore,
407        *     to get the chip address (0 to 4), we need to divide column number by 32.
408        *     ---------------------------------------------------------------------*/
409       iz=digs->GetCoord1();  // Cell number in Z direction 
410       ix=digs->GetCoord2();  // Cell number in X direction
411       chipNo=iz/32;
412       if(fVerbose==2)
413         ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
414       hitRow=iz-chipNo*32;
415       if(fHalfStaveModule){
416         chipNo+=5;
417         fHalfStaveModule=-1;
418       }//end if
419       if(previousChip==-1){
420         //loop over chip without digits 
421         //Even if there aren't digits for a given chip 
422         //the chip header and the chip trailer are stored
423         for(Int_t i=0;i<(iz/32);i++){
424           if(chipNo>4)
425             WriteChipHeader(i+5,(mod/2),baseWord);
426           else
427             WriteChipHeader(i,(mod/2),baseWord);
428           WriteChipTrailer(buf,chipHitCount,baseWord);
429           chipHitCount=0;
430         }//end for
431         WriteChipHeader(chipNo,(mod/2),baseWord);
432         chipHitCount++;
433         WriteHit(buf,ix,hitRow,baseWord);
434         previousChip=chipNo;
435       }//end if
436       else{
437         if(previousChip!=chipNo){
438           WriteChipTrailer(buf,chipHitCount,baseWord);
439           chipHitCount=0;
440           for(Int_t i=previousChip+1;i<chipNo;i++){
441             WriteChipHeader(i,(mod/2),baseWord);
442             WriteChipTrailer(buf,0,baseWord);
443             chipHitCount=0;
444           }//end for
445           WriteChipHeader(chipNo,(mod/2),baseWord);
446           previousChip=chipNo;
447         }//end if
448         chipHitCount++;
449         WriteHit(buf,ix,hitRow,baseWord);
450       }//end else
451     }//end for
452     //Even if there aren't digits for a given chip 
453     //the chip header and the chip trailer are stored
454     Int_t end=4;
455     if(chipNo>4)end+=5;
456     WriteChipTrailer(buf,chipHitCount,baseWord);
457     chipHitCount=0;
458     for(Int_t i=chipNo+1;i<=end;i++){
459       WriteChipHeader(i,(mod/2),baseWord);
460       WriteChipTrailer(buf,0,baseWord);
461       chipHitCount=0;
462     }//end for
463   }//end if
464   else{
465     //In this module there aren't digits but
466     //the chip header and chip trailer are store anyway
467     if(fHalfStaveModule){
468       chipNo=5;
469       fHalfStaveModule=-1;
470     }//end if
471     for(Int_t i=0;i<5;i++){
472       WriteChipHeader(chipNo+i,(mod/2),baseWord);
473       WriteChipTrailer(buf,chipHitCount,baseWord);
474       chipHitCount=0;
475     }//end for
476   }//end else 
477   if(fVerbose==2)
478     ftxt.close();
479   return;
480 }//end GetDigitsSPD
481
482 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
483
484 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
485   //This method creates the Raw data files for SPD detectors
486   const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
487   UInt_t buf[kSize];      //One buffer cell can contain 2 digits 
488   fIndex=-1;
489
490   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
491   char fileName[15];
492   AliFstream* outfile;         // logical name of the output file 
493   AliRawDataHeader header;
494
495   //loop over DDLs
496   for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSPD");i++){
497     strcpy(fileName,AliDAQ::DdlFileName("ITSSPD",i)); //The name of the output file.
498     outfile = new AliFstream(fileName);
499     //write Dummy DATA HEADER
500     UInt_t dataHeaderPosition=outfile->Tellp();
501     outfile->WriteBuffer((char*)(&header),sizeof(header));
502     //Loops over Modules of a particular DDL
503     for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
504       Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
505       digits->Clear();
506       branch->GetEvent(moduleNumber);
507       //For each Module, buf contains the array of data words in Binary format    
508       //fIndex gives the number of 32 bits words in the buffer for each module
509       GetDigitsSPD(digits,mod,i,buf);
510       outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
511       for(Int_t i=0;i<(fIndex+1);i++){
512         buf[i]=0;
513       }//end for
514       fIndex=-1;
515     }//end for
516     
517     //Write REAL DATA HEADER
518     UInt_t currentFilePosition=outfile->Tellp();
519     outfile->Seekp(dataHeaderPosition);
520     header.fSize=currentFilePosition-dataHeaderPosition;
521     outfile->WriteBuffer((char*)(&header),sizeof(header));
522     delete outfile;
523   }//end for
524
525   return 0;  
526 }
527
528 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
529
530 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
531
532     //This method creates the Raw data files for SSD detectors
533   const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
534   UInt_t buf[kSize];      
535   fIndex=-1;
536
537   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
538   char fileName[15];
539   AliFstream* outfile;         // logical name of the output file 
540   AliRawDataHeader header;
541
542   //loop over DDLs  
543   for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSSD");i++){
544     strcpy(fileName,AliDAQ::DdlFileName("ITSSSD",i)); //The name of the output file.
545     outfile = new AliFstream(fileName);
546     //write Dummy DATA HEADER
547     UInt_t dataHeaderPosition=outfile->Tellp();
548     outfile->WriteBuffer((char*)(&header),sizeof(header));
549     
550     //Loops over Modules of a particular DDL
551     for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
552       Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
553       if(moduleNumber!=-1){
554         digits->Clear();
555         branch->GetEvent(moduleNumber);
556         //For each Module, buf contains the array of data words in Binary format          
557         //fIndex gives the number of 32 bits words in the buffer for each module
558         GetDigitsSSD(digits,mod,moduleNumber,i,buf);
559         outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
560         fIndex=-1;
561       }//end if
562     }//end for
563
564     //Write REAL DATA HEADER
565     UInt_t currentFilePosition=outfile->Tellp();
566     outfile->Seekp(dataHeaderPosition);
567     header.fSize=currentFilePosition-dataHeaderPosition;
568     header.SetAttribute(0);  // valid data
569     outfile->WriteBuffer((char*)(&header),sizeof(header));
570     delete outfile;
571   }//end for
572
573   return 0;  
574 }
575
576 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
577
578 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
579     //This method creates the Raw data files for SDD detectors
580   const Int_t kSize=131072; //256*512
581   UInt_t buf[kSize];      
582   fIndex=-1;
583
584   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
585   char fileName[15];
586   AliFstream* outfile;             // logical name of the output file 
587   AliRawDataHeader header;
588   UInt_t skippedword, carlosFooterWord,fifoFooterWord,jitterWord;
589   Bool_t retcode;
590   retcode = AliBitPacking::PackWord(0x3FFFFFFF,carlosFooterWord,0,31);
591   retcode = AliBitPacking::PackWord(0x3F1F1F1F,fifoFooterWord,0,31);
592   retcode = AliBitPacking::PackWord(0xFF00000E,jitterWord,0,31);
593
594   //loop over DDLs  
595   for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSDD");i++){
596     strcpy(fileName,AliDAQ::DdlFileName("ITSSDD",i)); //The name of the output file.
597     outfile = new AliFstream(fileName);
598     //write Dummy DATA HEADER
599     UInt_t dataHeaderPosition=outfile->Tellp();
600     outfile->WriteBuffer((char*)(&header),sizeof(header));
601
602
603     //first 9 "dummy" words to be skipped
604     for(Int_t iw=0;iw<9;iw++){
605       if(iw==0 || iw==8) retcode = AliBitPacking::PackWord(0xFFFFFFFF,skippedword,0,31);
606       else retcode = AliBitPacking::PackWord(2,skippedword,0,31);
607         outfile->WriteBuffer((char*)(&skippedword),sizeof(skippedword));
608     }
609     //Loops over Modules of a particular DDL
610     for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
611       Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
612       if(moduleNumber!=-1){
613         digits->Clear();
614         branch->GetEvent(moduleNumber);
615
616         //For each Module, buf contains the array of data words in Binary format          
617         //fIndex gives the number of 32 bits words in the buffer for each module
618         //      cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
619         GetDigitsSDD(digits,mod,moduleNumber,i,buf);
620         outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
621         for(Int_t iw=0;iw<3;iw++) outfile->WriteBuffer((char*)(&carlosFooterWord),sizeof(carlosFooterWord));
622         fIndex=-1;
623       }//end if
624     }//end for
625     // 12 words with FIFO footers (=4 FIFO x 3 3F1F1F1F words per DDL)
626     for(Int_t iw=0;iw<12;iw++) outfile->WriteBuffer((char*)(&fifoFooterWord),sizeof(fifoFooterWord));
627    
628     outfile->WriteBuffer((char*)(&jitterWord),sizeof(jitterWord));      
629     
630     //Write REAL DATA HEADER
631     UInt_t currentFilePosition=outfile->Tellp();
632     outfile->Seekp(dataHeaderPosition);
633     header.fSize=currentFilePosition-dataHeaderPosition;
634     header.SetAttribute(0);  // valid data
635     outfile->WriteBuffer((char*)(&header),sizeof(header));
636     delete outfile;
637   }//end for
638
639   return 0;  
640 }
641
642 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
643
644 void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t halfStave,UInt_t &BaseWord){
645   //This method writes a chip header 
646   //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<halfStave<<endl;
647   BaseWord=0;
648   AliBitPacking::PackWord(ChipAddr,BaseWord,16,19);
649   //  At the moment the event count is always 0 (bits 20-26)
650   AliBitPacking::PackWord(0,BaseWord,20,26);
651   AliBitPacking::PackWord(halfStave,BaseWord,27,29);
652   AliBitPacking::PackWord(0x1,BaseWord,30,31);
653   return;
654 }//end WriteChipHeader
655
656 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
657
658 void  AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
659   //This method writes a chip trailer
660   //pixel fill word
661   if((ChipHitCount%2)!=0){
662     AliBitPacking::PackWord(0xC000,BaseWord,16,31);
663   }
664   AliBitPacking::PackWord(ChipHitCount,BaseWord,0,13);
665   AliBitPacking::PackWord(0x0,BaseWord,14,15);
666   fIndex++;
667   buf[fIndex]=BaseWord;
668   BaseWord=0;
669   return;
670 }//end WriteChipTrailer
671
672 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
673
674 void  AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
675   //This method writs an hit
676   if(!BaseWord){
677     AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
678     AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
679     AliBitPacking::PackWord(2,BaseWord,30,31);
680   }//end if
681   else{
682     AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
683     AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
684     AliBitPacking::PackWord(2,BaseWord,14,15);
685     fIndex++;
686     buf[fIndex]=BaseWord;
687     BaseWord=0;
688   }//end else
689   return;
690 }//end WriteHit
691