]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSDDLRawData.cxx
Bug fix related to reconstruction of simulated data in raw format (E. Fragiacomo)
[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 "AliRawDataHeaderSim.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=0x30000000+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       if(anode == 256){
195         last = 0;
196         first = 0;
197         flag = kFALSE;
198         diff = 0;
199         word2=0;
200       }
201       
202       for(Int_t tb=0;tb<256;tb++){
203         if(digarr[anode][tb]!=0){
204           if(flag){      
205             last = first+diff-1;
206             AliBitPacking::PackWord(word2,baseWord,first,last);
207             flag = kFALSE;
208             first = last+1;
209             diff=0;
210           }
211           wordinfo1[1] = tb;
212           //non lossy compression as it is done in Carlos 
213           //(data are already 10to8bit compressed by AMBRA
214
215           /* if value < 8  value = value - (1 << 2) (word is 2 bit long) 
216              if value < 16 value = value - (1 << 3) (word is 3 bit long)
217              if value < 32 value = value - (1 << 4) (word is 4 bit long)
218              if value < 64 value = value - (1 << 5) (word is 5 bit long)
219              if value <128 value = value - (1 << 6) (word is 6 bit long)
220              if value >=128value = value - (1 << 7) (word is 7 bit long)
221
222           */
223           if(digarr[anode][tb]<8){
224             bitinfo1[3] = 2;
225             wordinfo1[2] = 2;
226             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
227           }               
228           if(digarr[anode][tb]>=8 && digarr[anode][tb]<16){
229             bitinfo1[3] = 3;
230             wordinfo1[2] = 3;
231             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
232           }
233           if(digarr[anode][tb]>=16 && digarr[anode][tb]<32){
234             bitinfo1[3] = 4;
235             wordinfo1[2] = 4;
236             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
237           }
238           if(digarr[anode][tb]>=32 && digarr[anode][tb]<64){
239             bitinfo1[3] = 5;
240             wordinfo1[2] = 5;
241             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
242           }
243           if(digarr[anode][tb]>=64 && digarr[anode][tb]<128){
244             bitinfo1[3] = 6;
245             wordinfo1[2] = 6;
246             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
247           }
248           if(digarr[anode][tb]>=128){
249             bitinfo1[3] = 7;
250             wordinfo1[2] = 7;
251             wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
252           }
253           
254           for(Int_t ie=0;ie<4;ie++){
255             
256             if(flag){      
257               last = first+diff-1;
258               AliBitPacking::PackWord(word2,baseWord,first,last);
259               flag = kFALSE;
260               first = last+1;
261               diff=0;
262             }
263             last = first+bitinfo1[ie]-1;
264             if(first < 30 && last < 30){                  
265               AliBitPacking::PackWord(wordinfo1[ie],baseWord,first,last); 
266               first = last+1;
267             }
268             else{
269               if(first<=29){
270                 UInt_t w = AliBitPacking::UnpackWord(wordinfo1[ie],0,29-first);
271                 AliBitPacking::PackWord(w,baseWord,first,29);
272                 Int_t lb = 29-first+1;
273                 diff = bitinfo1[ie]-lb;
274                 word2 = AliBitPacking::UnpackWord(wordinfo1[ie],lb,lb+diff-1);
275                 flag = kTRUE;
276                 if(anode<256) word = 2;//channel 0 of carlos
277                 else word = 3; //channel 1 of carlos
278                 AliBitPacking::PackWord(word,baseWord,30,31);
279                 fIndex++;
280                 buf[fIndex]=baseWord;
281                 first=0;
282                 last = 0;
283                 baseWord=0;
284                 word = 0;
285               }
286               else{
287                 word2 = wordinfo1[ie];
288                 diff = bitinfo1[ie];
289                 flag = kTRUE;
290                 if(anode<256) word = 2; //channel 0 of carlos
291                 else word = 3; //channel 1 of carlos
292                 AliBitPacking::PackWord(word,baseWord,30,31);
293                 fIndex++;
294                 buf[fIndex]=baseWord;
295                 first=0;
296                 last=0;
297                 baseWord=0;
298                 word = 0;
299               }
300             }
301           }
302           
303         }//END IF
304         
305       }//end loop on tb
306     
307       for(Int_t i=0;i<2;i++){
308         if(flag){      
309           last = first+diff-1;
310           AliBitPacking::PackWord(word2,baseWord,first,last);
311           flag = kFALSE;
312           first = last+1;
313           diff=0;
314         }
315         
316         word = wordinfo2[i];
317         nbit = bitinfo2[i];
318         last = first+nbit-1;
319         if(first < 30 && last < 30){              
320           AliBitPacking::PackWord(word,baseWord,first,last); //3 bit code =1 -> next 18 bits for EOR
321           first = last+1;
322         }
323         
324         else{
325           if(first<=29){
326             UInt_t w = AliBitPacking::UnpackWord(word,0,29-first);
327             AliBitPacking::PackWord(w,baseWord,first,29);
328             Int_t lb = 29-first+1;
329             diff = nbit-lb;        
330             word2 = AliBitPacking::UnpackWord(word,lb,lb+diff-1);
331             flag = kTRUE;
332             if(anode<256) word = 2;
333             else word = 3;
334             AliBitPacking::PackWord(word,baseWord,30,31);
335             fIndex++;
336             buf[fIndex]=baseWord;
337             first=0;
338             last = 0;
339             baseWord=0;
340             if(anode==255){
341               flag=kFALSE;
342               word2=0;
343             }
344           }
345           else{
346             word2 = word;
347             diff = nbit;
348             flag = kTRUE;
349             if(anode<256) word = 2;
350             else word = 3;
351             AliBitPacking::PackWord(word,baseWord,30,31);
352             fIndex++;
353             buf[fIndex]=baseWord;
354             first=0;
355             last=0;
356             baseWord=0;
357             if(anode==255){
358               flag=kFALSE;
359               word2=0;
360             }
361           }
362         }
363       }
364     } //end for
365     
366   }
367   if(fVerbose==2)
368     ftxt.close();
369   return;
370 }//end GetDigitsSDD
371
372 ////////////////////////////////////////////////////////////////////////////////////////
373 //PIXEL 
374 //
375
376 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
377   //This method packs the SPD digits in a proper 32 structure
378   //Since data is zero suppressed,the coordinates for the chip having zero digits 
379   //doesn't get listed in the galice.root file. However the SPD format requires 
380   //the empty chip to be written with chip header and chip trailer.
381   //The index of the half stave is calculated as (mod/2).
382   Int_t ix;
383   Int_t iz;
384   Int_t chipNo=0;
385   UInt_t baseWord=0;
386   UInt_t hitRow=0;
387   Int_t chipHitCount=0;  //Number of Hit in the current chip
388   Int_t previousChip=-1; //Previuos chip respect to the actual aone
389   Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
390   //cout<<"      Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
391   AliITSdigit *digs;
392   fHalfStaveModule++;    //It's a private variable used to distinguish between the firs  
393                          //and the second module of an Half Stave Module
394   ofstream ftxt;
395   if(ndigits){
396     //loop over digits
397     if (fVerbose==2)
398       ftxt.open("SPDdigits.txt",ios::app);
399     for (Int_t digit=0;digit<ndigits;digit++){
400       digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
401       /*---------------------------------------------------------------------------
402        *     Each module contains 5 read out chips of 256 rows and 32 columns.
403        *     So, the cell number in Z direction varies from 0 to 159.  Therefore,
404        *     to get the chip address (0 to 4), we need to divide column number by 32.
405        *     ---------------------------------------------------------------------*/
406       iz=digs->GetCoord1();  // Cell number in Z direction 
407       ix=digs->GetCoord2();  // Cell number in X direction
408       chipNo=iz/32;
409       if(fVerbose==2)
410         ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
411       hitRow=iz-chipNo*32;
412       if(fHalfStaveModule){
413         chipNo+=5;
414         fHalfStaveModule=-1;
415       }//end if
416       if(previousChip==-1){
417         //loop over chip without digits 
418         //Even if there aren't digits for a given chip 
419         //the chip header and the chip trailer are stored
420         for(Int_t i=0;i<(iz/32);i++){
421           if(chipNo>4)
422             WriteChipHeader(i+5,(mod/2),baseWord);
423           else
424             WriteChipHeader(i,(mod/2),baseWord);
425           WriteChipTrailer(buf,chipHitCount,baseWord);
426           chipHitCount=0;
427         }//end for
428         WriteChipHeader(chipNo,(mod/2),baseWord);
429         chipHitCount++;
430         WriteHit(buf,ix,hitRow,baseWord);
431         previousChip=chipNo;
432       }//end if
433       else{
434         if(previousChip!=chipNo){
435           WriteChipTrailer(buf,chipHitCount,baseWord);
436           chipHitCount=0;
437           for(Int_t i=previousChip+1;i<chipNo;i++){
438             WriteChipHeader(i,(mod/2),baseWord);
439             WriteChipTrailer(buf,0,baseWord);
440             chipHitCount=0;
441           }//end for
442           WriteChipHeader(chipNo,(mod/2),baseWord);
443           previousChip=chipNo;
444         }//end if
445         chipHitCount++;
446         WriteHit(buf,ix,hitRow,baseWord);
447       }//end else
448     }//end for
449     //Even if there aren't digits for a given chip 
450     //the chip header and the chip trailer are stored
451     Int_t end=4;
452     if(chipNo>4)end+=5;
453     WriteChipTrailer(buf,chipHitCount,baseWord);
454     chipHitCount=0;
455     for(Int_t i=chipNo+1;i<=end;i++){
456       WriteChipHeader(i,(mod/2),baseWord);
457       WriteChipTrailer(buf,0,baseWord);
458       chipHitCount=0;
459     }//end for
460   }//end if
461   else{
462     //In this module there aren't digits but
463     //the chip header and chip trailer are store anyway
464     if(fHalfStaveModule){
465       chipNo=5;
466       fHalfStaveModule=-1;
467     }//end if
468     for(Int_t i=0;i<5;i++){
469       WriteChipHeader(chipNo+i,(mod/2),baseWord);
470       WriteChipTrailer(buf,chipHitCount,baseWord);
471       chipHitCount=0;
472     }//end for
473   }//end else 
474   if(fVerbose==2)
475     ftxt.close();
476   return;
477 }//end GetDigitsSPD
478
479 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
480
481 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
482   //This method creates the Raw data files for SPD detectors
483   const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
484   UInt_t buf[kSize];      //One buffer cell can contain 2 digits 
485   fIndex=-1;
486
487   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
488   char fileName[15];
489   AliFstream* outfile;         // logical name of the output file 
490   AliRawDataHeaderSim header;
491
492   //loop over DDLs
493   for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSPD");i++){
494     strcpy(fileName,AliDAQ::DdlFileName("ITSSPD",i)); //The name of the output file.
495     outfile = new AliFstream(fileName);
496     //write Dummy DATA HEADER
497     UInt_t dataHeaderPosition=outfile->Tellp();
498     outfile->WriteBuffer((char*)(&header),sizeof(header));
499     //Loops over Modules of a particular DDL
500     for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
501       Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
502       digits->Clear();
503       branch->GetEvent(moduleNumber);
504       //For each Module, buf contains the array of data words in Binary format    
505       //fIndex gives the number of 32 bits words in the buffer for each module
506       GetDigitsSPD(digits,mod,i,buf);
507       outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
508       for(Int_t i=0;i<(fIndex+1);i++){
509         buf[i]=0;
510       }//end for
511       fIndex=-1;
512     }//end for
513     
514     //Write REAL DATA HEADER
515     UInt_t currentFilePosition=outfile->Tellp();
516     outfile->Seekp(dataHeaderPosition);
517     header.fSize=currentFilePosition-dataHeaderPosition;
518     outfile->WriteBuffer((char*)(&header),sizeof(header));
519     delete outfile;
520   }//end for
521
522   return 0;  
523 }
524
525 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
526
527 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
528
529     //This method creates the Raw data files for SSD detectors
530   const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
531   UInt_t buf[kSize];      
532   fIndex=-1;
533
534   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
535   char fileName[15];
536   AliFstream* outfile;         // logical name of the output file 
537   AliRawDataHeaderSim header;
538
539   //loop over DDLs  
540   for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSSD");i++){
541     strcpy(fileName,AliDAQ::DdlFileName("ITSSSD",i)); //The name of the output file.
542     outfile = new AliFstream(fileName);
543     //write Dummy DATA HEADER
544     UInt_t dataHeaderPosition=outfile->Tellp();
545     outfile->WriteBuffer((char*)(&header),sizeof(header));
546     
547     //Loops over Modules of a particular DDL
548     for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
549       Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
550       if(moduleNumber!=-1){
551         digits->Clear();
552         branch->GetEvent(moduleNumber);
553         //For each Module, buf contains the array of data words in Binary format          
554         //fIndex gives the number of 32 bits words in the buffer for each module
555         GetDigitsSSD(digits,mod,moduleNumber,i,buf);
556         outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
557         fIndex=-1;
558       }//end if
559     }//end for
560
561     //Write REAL DATA HEADER
562     UInt_t currentFilePosition=outfile->Tellp();
563     outfile->Seekp(dataHeaderPosition);
564     header.fSize=currentFilePosition-dataHeaderPosition;
565     header.SetAttribute(0);  // valid data
566     outfile->WriteBuffer((char*)(&header),sizeof(header));
567     delete outfile;
568   }//end for
569
570   return 0;  
571 }
572
573 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
574
575 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
576     //This method creates the Raw data files for SDD detectors
577   const Int_t kSize=131072; //256*512
578   UInt_t buf[kSize];      
579   fIndex=-1;
580
581   TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
582   char fileName[15];
583   AliFstream* outfile;             // logical name of the output file 
584   AliRawDataHeaderSim header;
585   UInt_t skippedword, carlosFooterWord,fifoFooterWord,jitterWord;
586   Bool_t retcode;
587   retcode = AliBitPacking::PackWord(0x3FFFFFFF,carlosFooterWord,0,31);
588   retcode = AliBitPacking::PackWord(0x3F1F1F1F,fifoFooterWord,0,31);
589   retcode = AliBitPacking::PackWord(0x7F00000E,jitterWord,0,31);
590
591   //loop over DDLs  
592   for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSDD");i++){
593     strcpy(fileName,AliDAQ::DdlFileName("ITSSDD",i)); //The name of the output file.
594     outfile = new AliFstream(fileName);
595     //write Dummy DATA HEADER
596     UInt_t dataHeaderPosition=outfile->Tellp();
597     outfile->WriteBuffer((char*)(&header),sizeof(header));
598
599
600     //first 9 "dummy" words to be skipped
601     for(Int_t iw=0;iw<9;iw++){
602       if(iw==0 || iw==8) retcode = AliBitPacking::PackWord(0xFFFFFFFF,skippedword,0,31);
603       else retcode = AliBitPacking::PackWord(2,skippedword,0,31);
604         outfile->WriteBuffer((char*)(&skippedword),sizeof(skippedword));
605     }
606     //Loops over Modules of a particular DDL
607     for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
608       Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
609       if(moduleNumber!=-1){
610         digits->Clear();
611         branch->GetEvent(moduleNumber);
612
613         //For each Module, buf contains the array of data words in Binary format          
614         //fIndex gives the number of 32 bits words in the buffer for each module
615         //      cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
616         GetDigitsSDD(digits,mod,moduleNumber,i,buf);
617         outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
618         for(Int_t iw=0;iw<3;iw++) outfile->WriteBuffer((char*)(&carlosFooterWord),sizeof(carlosFooterWord));
619         fIndex=-1;
620       }//end if
621     }//end for
622     // 12 words with FIFO footers (=4 FIFO x 3 3F1F1F1F words per DDL)
623     for(Int_t iw=0;iw<12;iw++) outfile->WriteBuffer((char*)(&fifoFooterWord),sizeof(fifoFooterWord));
624    
625     outfile->WriteBuffer((char*)(&jitterWord),sizeof(jitterWord));      
626     
627     //Write REAL DATA HEADER
628     UInt_t currentFilePosition=outfile->Tellp();
629     outfile->Seekp(dataHeaderPosition);
630     header.fSize=currentFilePosition-dataHeaderPosition;
631     header.SetAttribute(0);  // valid data
632     outfile->WriteBuffer((char*)(&header),sizeof(header));
633     delete outfile;
634   }//end for
635
636   return 0;  
637 }
638
639 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
640
641 void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t halfStave,UInt_t &BaseWord){
642   //This method writes a chip header 
643   //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<halfStave<<endl;
644   BaseWord=0;
645   AliBitPacking::PackWord(ChipAddr,BaseWord,16,19);
646   //  At the moment the event count is always 0 (bits 20-26)
647   AliBitPacking::PackWord(0,BaseWord,20,26);
648   AliBitPacking::PackWord(halfStave,BaseWord,27,29);
649   AliBitPacking::PackWord(0x1,BaseWord,30,31);
650   return;
651 }//end WriteChipHeader
652
653 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
654
655 void  AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
656   //This method writes a chip trailer
657   //pixel fill word
658   if((ChipHitCount%2)!=0){
659     AliBitPacking::PackWord(0xC000,BaseWord,16,31);
660   }
661   AliBitPacking::PackWord(ChipHitCount,BaseWord,0,13);
662   AliBitPacking::PackWord(0x0,BaseWord,14,15);
663   fIndex++;
664   buf[fIndex]=BaseWord;
665   BaseWord=0;
666   return;
667 }//end WriteChipTrailer
668
669 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
670
671 void  AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
672   //This method writs an hit
673   if(!BaseWord){
674     AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
675     AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
676     AliBitPacking::PackWord(2,BaseWord,30,31);
677   }//end if
678   else{
679     AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
680     AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
681     AliBitPacking::PackWord(2,BaseWord,14,15);
682     fIndex++;
683     buf[fIndex]=BaseWord;
684     BaseWord=0;
685   }//end else
686   return;
687 }//end WriteHit
688