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