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