1 /**************************************************************************
2 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 //This class contains all the necessary methods to create the Raw Data
20 //files (slides) for the ITS data challenges for:
26 //#include <Riostream.h>
27 #include <TClonesArray.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"
37 #include "AliFstream.h"
39 ClassImp(AliITSDDLRawData)
41 ////////////////////////////////////////////////////////////////////////////////////////
42 AliITSDDLRawData::AliITSDDLRawData():
50 ////////////////////////////////////////////////////////////////////////////////////////
52 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) :
54 fVerbose(source.fVerbose),
55 fIndex(source.fIndex),
56 fHalfStaveModule(source.fHalfStaveModule){
60 ////////////////////////////////////////////////////////////////////////////////////////
62 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
64 this->fIndex=source.fIndex;
65 this->fHalfStaveModule=source.fHalfStaveModule;
66 this->fVerbose=source.fVerbose;
70 ////////////////////////////////////////////////////////////////////////////////////////
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
82 Int_t ndigits = ITSdigits->GetEntries();
87 ftxt.open("SSDdigits.txt",ios::app);
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;
97 ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
102 AliBitPacking::PackWord(word,baseWord,0,11);//ADC data
104 word = (iz==0) ? ix : 1535-ix ; // on N-side 1535-768 -> 0-767
105 AliBitPacking::PackWord(word,baseWord,12,22);//Strip Number
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
111 word = mod/12+1; // AD-number (AD module index ranges 1-9)
112 AliBitPacking::PackWord(word,baseWord,28,31);//AD slot
114 buf[fIndex]=baseWord;
122 ////////////////////////////////////////////////////////////////////////////////////////
123 //Silicon Drift Detector
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
133 Int_t ndigits = ITSdigits->GetEntries();
136 Int_t digarr[512][256];
137 for(Int_t i=0;i<512;i++){
138 for(Int_t j=0;j<256;j++){
142 //word to select the 12 carlos for the 12 modules
143 UInt_t carlosid=805306368+mod;
146 buf[fIndex]=carlosid;
152 Bool_t flag = kFALSE;
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
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
166 for anode info: 1 3 next 18 bits are for EOR
167 increments the anode value
169 EOR 18 error codes + other info
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
182 ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
183 if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
186 for(Int_t anode=0;anode<512;anode++){
189 AliBitPacking::PackWord(word2,baseWord,first,last);
205 for(Int_t tb=0;tb<256;tb++){
206 if(digarr[anode][tb]!=0){
209 AliBitPacking::PackWord(word2,baseWord,first,last);
215 //non lossy compression as it is done in Carlos
216 //(data are already 10to8bit compressed by AMBRA
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)
226 if(digarr[anode][tb]<8){
229 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
231 if(digarr[anode][tb]>=8 && digarr[anode][tb]<16){
234 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
236 if(digarr[anode][tb]>=16 && digarr[anode][tb]<32){
239 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
241 if(digarr[anode][tb]>=32 && digarr[anode][tb]<64){
244 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
246 if(digarr[anode][tb]>=64 && digarr[anode][tb]<128){
249 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
251 if(digarr[anode][tb]>=128){
254 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
257 for(Int_t ie=0;ie<4;ie++){
261 AliBitPacking::PackWord(word2,baseWord,first,last);
266 last = first+bitinfo1[ie]-1;
267 if(first < 30 && last < 30){
268 AliBitPacking::PackWord(wordinfo1[ie],baseWord,first,last);
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);
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);
283 buf[fIndex]=baseWord;
290 word2 = wordinfo1[ie];
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);
297 buf[fIndex]=baseWord;
310 for(Int_t i=0;i<2;i++){
313 AliBitPacking::PackWord(word2,baseWord,first,last);
322 if(first < 30 && last < 30){
323 AliBitPacking::PackWord(word,baseWord,first,last); //3 bit code =1 -> next 18 bits for EOR
329 UInt_t w = AliBitPacking::UnpackWord(word,0,29-first);
330 AliBitPacking::PackWord(w,baseWord,first,29);
331 Int_t lb = 29-first+1;
333 word2 = AliBitPacking::UnpackWord(word,lb,lb+diff-1);
335 if(anode<256) word = 2;
337 AliBitPacking::PackWord(word,baseWord,30,31);
339 buf[fIndex]=baseWord;
352 if(anode<256) word = 2;
354 AliBitPacking::PackWord(word,baseWord,30,31);
356 buf[fIndex]=baseWord;
375 ////////////////////////////////////////////////////////////////////////////////////////
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).
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;
395 fHalfStaveModule++; //It's a private variable used to distinguish between the firs
396 //and the second module of an Half Stave Module
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
413 ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
415 if(fHalfStaveModule){
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++){
425 WriteChipHeader(i+5,(mod/2),baseWord);
427 WriteChipHeader(i,(mod/2),baseWord);
428 WriteChipTrailer(buf,chipHitCount,baseWord);
431 WriteChipHeader(chipNo,(mod/2),baseWord);
433 WriteHit(buf,ix,hitRow,baseWord);
437 if(previousChip!=chipNo){
438 WriteChipTrailer(buf,chipHitCount,baseWord);
440 for(Int_t i=previousChip+1;i<chipNo;i++){
441 WriteChipHeader(i,(mod/2),baseWord);
442 WriteChipTrailer(buf,0,baseWord);
445 WriteChipHeader(chipNo,(mod/2),baseWord);
449 WriteHit(buf,ix,hitRow,baseWord);
452 //Even if there aren't digits for a given chip
453 //the chip header and the chip trailer are stored
456 WriteChipTrailer(buf,chipHitCount,baseWord);
458 for(Int_t i=chipNo+1;i<=end;i++){
459 WriteChipHeader(i,(mod/2),baseWord);
460 WriteChipTrailer(buf,0,baseWord);
465 //In this module there aren't digits but
466 //the chip header and chip trailer are store anyway
467 if(fHalfStaveModule){
471 for(Int_t i=0;i<5;i++){
472 WriteChipHeader(chipNo+i,(mod/2),baseWord);
473 WriteChipTrailer(buf,chipHitCount,baseWord);
482 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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
490 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
492 AliFstream* outfile; // logical name of the output file
493 AliRawDataHeader header;
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);
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++){
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));
528 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
530 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
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)
537 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
539 AliFstream* outfile; // logical name of the output file
540 AliRawDataHeader header;
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));
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){
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)));
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));
576 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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
584 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
586 AliFstream* outfile; // logical name of the output file
587 AliRawDataHeader header;
588 UInt_t skippedword, carlosFooterWord,fifoFooterWord,jitterWord;
590 retcode = AliBitPacking::PackWord(0x3FFFFFFF,carlosFooterWord,0,31);
591 retcode = AliBitPacking::PackWord(0x3F1F1F1F,fifoFooterWord,0,31);
592 retcode = AliBitPacking::PackWord(0xFF00000E,jitterWord,0,31);
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));
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));
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){
614 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 // 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));
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));
628 outfile->WriteBuffer((char*)(&jitterWord),sizeof(jitterWord));
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));
642 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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;
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);
654 }//end WriteChipHeader
656 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
658 void AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
659 //This method writes a chip trailer
661 if((ChipHitCount%2)!=0){
662 AliBitPacking::PackWord(0xC000,BaseWord,16,31);
664 AliBitPacking::PackWord(ChipHitCount,BaseWord,0,13);
665 AliBitPacking::PackWord(0x0,BaseWord,14,15);
667 buf[fIndex]=BaseWord;
670 }//end WriteChipTrailer
672 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
674 void AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
675 //This method writs an hit
677 AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
678 AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
679 AliBitPacking::PackWord(2,BaseWord,30,31);
682 AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
683 AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
684 AliBitPacking::PackWord(2,BaseWord,14,15);
686 buf[fIndex]=BaseWord;