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 "AliRawDataHeaderSim.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=0x30000000+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);
202 for(Int_t tb=0;tb<256;tb++){
203 if(digarr[anode][tb]!=0){
206 AliBitPacking::PackWord(word2,baseWord,first,last);
212 //non lossy compression as it is done in Carlos
213 //(data are already 10to8bit compressed by AMBRA
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)
223 if(digarr[anode][tb]<8){
226 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
228 if(digarr[anode][tb]>=8 && digarr[anode][tb]<16){
231 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
233 if(digarr[anode][tb]>=16 && digarr[anode][tb]<32){
236 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
238 if(digarr[anode][tb]>=32 && digarr[anode][tb]<64){
241 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
243 if(digarr[anode][tb]>=64 && digarr[anode][tb]<128){
246 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
248 if(digarr[anode][tb]>=128){
251 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
254 for(Int_t ie=0;ie<4;ie++){
258 AliBitPacking::PackWord(word2,baseWord,first,last);
263 last = first+bitinfo1[ie]-1;
264 if(first < 30 && last < 30){
265 AliBitPacking::PackWord(wordinfo1[ie],baseWord,first,last);
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);
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);
280 buf[fIndex]=baseWord;
287 word2 = wordinfo1[ie];
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);
294 buf[fIndex]=baseWord;
307 for(Int_t i=0;i<2;i++){
310 AliBitPacking::PackWord(word2,baseWord,first,last);
319 if(first < 30 && last < 30){
320 AliBitPacking::PackWord(word,baseWord,first,last); //3 bit code =1 -> next 18 bits for EOR
326 UInt_t w = AliBitPacking::UnpackWord(word,0,29-first);
327 AliBitPacking::PackWord(w,baseWord,first,29);
328 Int_t lb = 29-first+1;
330 word2 = AliBitPacking::UnpackWord(word,lb,lb+diff-1);
332 if(anode<256) word = 2;
334 AliBitPacking::PackWord(word,baseWord,30,31);
336 buf[fIndex]=baseWord;
349 if(anode<256) word = 2;
351 AliBitPacking::PackWord(word,baseWord,30,31);
353 buf[fIndex]=baseWord;
372 ////////////////////////////////////////////////////////////////////////////////////////
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).
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;
392 fHalfStaveModule++; //It's a private variable used to distinguish between the firs
393 //and the second module of an Half Stave Module
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
410 ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
412 if(fHalfStaveModule){
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++){
422 WriteChipHeader(i+5,(mod/2),baseWord);
424 WriteChipHeader(i,(mod/2),baseWord);
425 WriteChipTrailer(buf,chipHitCount,baseWord);
428 WriteChipHeader(chipNo,(mod/2),baseWord);
430 WriteHit(buf,ix,hitRow,baseWord);
434 if(previousChip!=chipNo){
435 WriteChipTrailer(buf,chipHitCount,baseWord);
437 for(Int_t i=previousChip+1;i<chipNo;i++){
438 WriteChipHeader(i,(mod/2),baseWord);
439 WriteChipTrailer(buf,0,baseWord);
442 WriteChipHeader(chipNo,(mod/2),baseWord);
446 WriteHit(buf,ix,hitRow,baseWord);
449 //Even if there aren't digits for a given chip
450 //the chip header and the chip trailer are stored
453 WriteChipTrailer(buf,chipHitCount,baseWord);
455 for(Int_t i=chipNo+1;i<=end;i++){
456 WriteChipHeader(i,(mod/2),baseWord);
457 WriteChipTrailer(buf,0,baseWord);
462 //In this module there aren't digits but
463 //the chip header and chip trailer are store anyway
464 if(fHalfStaveModule){
468 for(Int_t i=0;i<5;i++){
469 WriteChipHeader(chipNo+i,(mod/2),baseWord);
470 WriteChipTrailer(buf,chipHitCount,baseWord);
479 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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
487 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
489 AliFstream* outfile; // logical name of the output file
490 AliRawDataHeaderSim header;
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);
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++){
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));
525 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
527 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
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)
534 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
536 AliFstream* outfile; // logical name of the output file
537 AliRawDataHeaderSim header;
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));
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){
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)));
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));
573 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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
581 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
583 AliFstream* outfile; // logical name of the output file
584 AliRawDataHeaderSim header;
585 UInt_t skippedword, carlosFooterWord,fifoFooterWord,jitterWord;
587 retcode = AliBitPacking::PackWord(0x3FFFFFFF,carlosFooterWord,0,31);
588 retcode = AliBitPacking::PackWord(0x3F1F1F1F,fifoFooterWord,0,31);
589 retcode = AliBitPacking::PackWord(0x7F00000E,jitterWord,0,31);
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));
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));
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){
611 branch->GetEvent(moduleNumber);
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));
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));
625 outfile->WriteBuffer((char*)(&jitterWord),sizeof(jitterWord));
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));
639 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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;
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);
651 }//end WriteChipHeader
653 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
655 void AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
656 //This method writes a chip trailer
658 if((ChipHitCount%2)!=0){
659 AliBitPacking::PackWord(0xC000,BaseWord,16,31);
661 AliBitPacking::PackWord(ChipHitCount,BaseWord,0,13);
662 AliBitPacking::PackWord(0x0,BaseWord,14,15);
664 buf[fIndex]=BaseWord;
667 }//end WriteChipTrailer
669 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
671 void AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
672 //This method writs an hit
674 AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
675 AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
676 AliBitPacking::PackWord(2,BaseWord,30,31);
679 AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
680 AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
681 AliBitPacking::PackWord(2,BaseWord,14,15);
683 buf[fIndex]=BaseWord;