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 <TClonesArray.h>
28 #include "AliITSdigit.h"
29 #include "AliITSDDLRawData.h"
30 #include "AliRawDataHeader.h"
31 #include "AliITSRawStreamSPD.h"
32 #include "AliITSRawStreamSDD.h"
33 #include "AliITSRawStreamSSD.h"
34 #include "AliBitPacking.h"
36 #include "AliFstream.h"
38 ClassImp(AliITSDDLRawData)
40 ////////////////////////////////////////////////////////////////////////////////////////
41 AliITSDDLRawData::AliITSDDLRawData():
49 ////////////////////////////////////////////////////////////////////////////////////////
51 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) :
53 fVerbose(source.fVerbose),
54 fIndex(source.fIndex),
55 fHalfStaveModule(source.fHalfStaveModule){
59 ////////////////////////////////////////////////////////////////////////////////////////
61 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
63 this->fIndex=source.fIndex;
64 this->fHalfStaveModule=source.fHalfStaveModule;
65 this->fVerbose=source.fVerbose;
69 ////////////////////////////////////////////////////////////////////////////////////////
73 void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
74 //This method packs the SSD digits in a proper 32 bits structure
75 // Revised by Enrico Fragiacomo
81 Int_t ndigits = ITSdigits->GetEntries();
86 ftxt.open("SSDdigits.txt",ios::app);
88 for (Int_t digit=0;digit<ndigits;digit++) {
89 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
90 iz=digs->GetCoord1(); // If iz==0, O side and if iz=1 N side
91 ix=digs->GetCoord2(); // Strip Number
92 is=digs->GetCompressedSignal(); // ADC Signal
93 // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
94 if(is<0) is = 4096 + is;
96 ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
101 AliBitPacking::PackWord(word,baseWord,0,11);//ADC data
103 word = (iz==0) ? ix : 1535-ix ; // on N-side 1535-768 -> 0-767
104 AliBitPacking::PackWord(word,baseWord,12,22);//Strip Number
106 word = mod%12; // ADC-number (12 ADCs per AD module)
107 word += ( word<6 ) ? 0 : 2; // ADC range 0-5 and 8-13
108 AliBitPacking::PackWord(word,baseWord,24,27);//ADC Channel
110 word = mod/12+1; // AD-number (AD module index ranges 1-9)
111 AliBitPacking::PackWord(word,baseWord,28,31);//AD slot
113 buf[fIndex]=baseWord;
121 ////////////////////////////////////////////////////////////////////////////////////////
122 //Silicon Drift Detector
125 void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
126 //This method packs the SDD digits in a proper 32 bits structure
132 Int_t ndigits = ITSdigits->GetEntries();
135 Int_t digarr[512][256];
136 for(Int_t i=0;i<512;i++){
137 for(Int_t j=0;j<256;j++){
141 //word to select the 12 carlos for the 12 modules
143 if(mod==0) carlosid=805306368;
144 if(mod==1) carlosid=805306369;
145 if(mod==2) carlosid=805306370;
146 if(mod==3) carlosid=805306371;
147 if(mod==4) carlosid=805306372;
148 if(mod==5) carlosid=805306373;
149 if(mod==6) carlosid=805306374;
150 if(mod==7) carlosid=805306375;
151 if(mod==8) carlosid=805306376;
152 if(mod==9) carlosid=805306377;
153 if(mod==10) carlosid=805306378;
154 if(mod==11) carlosid=805306379;
157 buf[fIndex]=carlosid;
163 Bool_t flag = kFALSE;
165 Int_t bitinfo1[4] = {3,8,3,7}; //vector with info on bit for timebin info
166 Int_t wordinfo1[4]= {0,0,0,0}; //vector with word info for timebin info
167 Int_t bitinfo2[2] = {3,18}; //vector with info on bit for EOR (end of row) info
168 Int_t wordinfo2[3]= {1,65593}; //vector with word info for anode info
170 /* for time bin info: word n bits meaning
171 0 3 next info is timebin
172 8 3 next word is 8 bit long
173 tb value 8 timebin value
174 n (2->7) 3 next info is n bit long
175 signal n signal value
177 for anode info: 1 3 next 18 bits are for EOR
178 increments the anode value
180 EOR 18 error codes + other info
185 ftxt.open("SDDdigits.txt",ios::app);
186 for (Int_t digit=0;digit<ndigits;digit++) {
187 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
188 iz=digs->GetCoord1(); // Anode
189 ix=digs->GetCoord2(); // Time
190 is=digs->GetCompressedSignal(); // ADC Signal
193 ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
194 if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
197 for(Int_t anode=0;anode<512;anode++){
200 AliBitPacking::PackWord(word2,baseWord,first,last);
216 for(Int_t tb=0;tb<256;tb++){
217 if(digarr[anode][tb]!=0){
220 AliBitPacking::PackWord(word2,baseWord,first,last);
226 //non lossy compression as it is done in Carlos
227 //(data are already 10to8bit compressed by AMBRA
229 /* if value < 8 value = value - (1 << 2) (word is 2 bit long)
230 if value < 16 value = value - (1 << 3) (word is 3 bit long)
231 if value < 32 value = value - (1 << 4) (word is 4 bit long)
232 if value < 64 value = value - (1 << 5) (word is 5 bit long)
233 if value <128 value = value - (1 << 6) (word is 6 bit long)
234 if value >=128value = value - (1 << 7) (word is 7 bit long)
237 if(digarr[anode][tb]<8){
240 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
242 if(digarr[anode][tb]>=8 && digarr[anode][tb]<16){
245 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
247 if(digarr[anode][tb]>=16 && digarr[anode][tb]<32){
250 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
252 if(digarr[anode][tb]>=32 && digarr[anode][tb]<64){
255 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
257 if(digarr[anode][tb]>=64 && digarr[anode][tb]<128){
260 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
262 if(digarr[anode][tb]>=128){
265 wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]);
268 for(Int_t ie=0;ie<4;ie++){
272 AliBitPacking::PackWord(word2,baseWord,first,last);
277 last = first+bitinfo1[ie]-1;
278 if(first < 30 && last < 30){
279 AliBitPacking::PackWord(wordinfo1[ie],baseWord,first,last);
284 UInt_t w = AliBitPacking::UnpackWord(wordinfo1[ie],0,29-first);
285 AliBitPacking::PackWord(w,baseWord,first,29);
286 Int_t lb = 29-first+1;
287 diff = bitinfo1[ie]-lb;
288 word2 = AliBitPacking::UnpackWord(wordinfo1[ie],lb,lb+diff-1);
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;
301 word2 = wordinfo1[ie];
304 if(anode<256) word = 2; //channel 0 of carlos
305 else word = 3; //channel 1 of carlos
306 AliBitPacking::PackWord(word,baseWord,30,31);
308 buf[fIndex]=baseWord;
321 for(Int_t i=0;i<2;i++){
324 AliBitPacking::PackWord(word2,baseWord,first,last);
333 if(first < 30 && last < 30){
334 AliBitPacking::PackWord(word,baseWord,first,last); //3 bit code =1 -> next 18 bits for EOR
340 UInt_t w = AliBitPacking::UnpackWord(word,0,29-first);
341 AliBitPacking::PackWord(w,baseWord,first,29);
342 Int_t lb = 29-first+1;
344 word2 = AliBitPacking::UnpackWord(word,lb,lb+diff-1);
346 if(anode<256) word = 2;
348 AliBitPacking::PackWord(word,baseWord,30,31);
350 buf[fIndex]=baseWord;
363 if(anode<256) word = 2;
365 AliBitPacking::PackWord(word,baseWord,30,31);
367 buf[fIndex]=baseWord;
386 ////////////////////////////////////////////////////////////////////////////////////////
390 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
391 //This method packs the SPD digits in a proper 32 structure
392 //Since data is zero suppressed,the coordinates for the chip having zero digits
393 //doesn't get listed in the galice.root file. However the SPD format requires
394 //the empty chip to be written with chip header and chip trailer.
395 //The index of the half stave is calculated as (mod/2).
401 Int_t chipHitCount=0; //Number of Hit in the current chip
402 Int_t previousChip=-1; //Previuos chip respect to the actual aone
403 Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
404 //cout<<" Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
406 fHalfStaveModule++; //It's a private variable used to distinguish between the firs
407 //and the second module of an Half Stave Module
412 ftxt.open("SPDdigits.txt",ios::app);
413 for (Int_t digit=0;digit<ndigits;digit++){
414 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
415 /*---------------------------------------------------------------------------
416 * Each module contains 5 read out chips of 256 rows and 32 columns.
417 * So, the cell number in Z direction varies from 0 to 159. Therefore,
418 * to get the chip address (0 to 4), we need to divide column number by 32.
419 * ---------------------------------------------------------------------*/
420 iz=digs->GetCoord1(); // Cell number in Z direction
421 ix=digs->GetCoord2(); // Cell number in X direction
424 ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
426 if(fHalfStaveModule){
430 if(previousChip==-1){
431 //loop over chip without digits
432 //Even if there aren't digits for a given chip
433 //the chip header and the chip trailer are stored
434 for(Int_t i=0;i<(iz/32);i++){
436 WriteChipHeader(i+5,(mod/2),baseWord);
438 WriteChipHeader(i,(mod/2),baseWord);
439 WriteChipTrailer(buf,chipHitCount,baseWord);
442 WriteChipHeader(chipNo,(mod/2),baseWord);
444 WriteHit(buf,ix,hitRow,baseWord);
448 if(previousChip!=chipNo){
449 WriteChipTrailer(buf,chipHitCount,baseWord);
451 for(Int_t i=previousChip+1;i<chipNo;i++){
452 WriteChipHeader(i,(mod/2),baseWord);
453 WriteChipTrailer(buf,0,baseWord);
456 WriteChipHeader(chipNo,(mod/2),baseWord);
460 WriteHit(buf,ix,hitRow,baseWord);
463 //Even if there aren't digits for a given chip
464 //the chip header and the chip trailer are stored
467 WriteChipTrailer(buf,chipHitCount,baseWord);
469 for(Int_t i=chipNo+1;i<=end;i++){
470 WriteChipHeader(i,(mod/2),baseWord);
471 WriteChipTrailer(buf,0,baseWord);
476 //In this module there aren't digits but
477 //the chip header and chip trailer are store anyway
478 if(fHalfStaveModule){
482 for(Int_t i=0;i<5;i++){
483 WriteChipHeader(chipNo+i,(mod/2),baseWord);
484 WriteChipTrailer(buf,chipHitCount,baseWord);
493 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
495 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
496 //This method creates the Raw data files for SPD detectors
497 const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
498 UInt_t buf[kSize]; //One buffer cell can contain 2 digits
501 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
503 AliFstream* outfile; // logical name of the output file
504 AliRawDataHeader header;
507 for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSPD");i++){
508 strcpy(fileName,AliDAQ::DdlFileName("ITSSPD",i)); //The name of the output file.
509 outfile = new AliFstream(fileName);
510 //write Dummy DATA HEADER
511 UInt_t dataHeaderPosition=outfile->Tellp();
512 outfile->WriteBuffer((char*)(&header),sizeof(header));
513 //Loops over Modules of a particular DDL
514 for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
515 Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
517 branch->GetEvent(moduleNumber);
518 //For each Module, buf contains the array of data words in Binary format
519 //fIndex gives the number of 32 bits words in the buffer for each module
520 GetDigitsSPD(digits,mod,i,buf);
521 outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
522 for(Int_t i=0;i<(fIndex+1);i++){
528 //Write REAL DATA HEADER
529 UInt_t currentFilePosition=outfile->Tellp();
530 outfile->Seekp(dataHeaderPosition);
531 header.fSize=currentFilePosition-dataHeaderPosition;
532 outfile->WriteBuffer((char*)(&header),sizeof(header));
539 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
541 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
543 //This method creates the Raw data files for SSD detectors
544 const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
548 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
550 AliFstream* outfile; // logical name of the output file
551 AliRawDataHeader header;
554 for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSSD");i++){
555 strcpy(fileName,AliDAQ::DdlFileName("ITSSSD",i)); //The name of the output file.
556 outfile = new AliFstream(fileName);
557 //write Dummy DATA HEADER
558 UInt_t dataHeaderPosition=outfile->Tellp();
559 outfile->WriteBuffer((char*)(&header),sizeof(header));
561 //Loops over Modules of a particular DDL
562 for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
563 Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
564 if(moduleNumber!=-1){
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 GetDigitsSSD(digits,mod,moduleNumber,i,buf);
570 outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
575 //Write REAL DATA HEADER
576 UInt_t currentFilePosition=outfile->Tellp();
577 outfile->Seekp(dataHeaderPosition);
578 header.fSize=currentFilePosition-dataHeaderPosition;
579 header.SetAttribute(0); // valid data
580 outfile->WriteBuffer((char*)(&header),sizeof(header));
587 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
589 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
590 //This method creates the Raw data files for SDD detectors
591 const Int_t kSize=131072; //256*512
595 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
597 AliFstream* outfile; // logical name of the output file
598 AliRawDataHeader header;
599 UInt_t skippedword = AliBitPacking::PackWord(2,skippedword,0,31);
602 for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSDD");i++){
603 strcpy(fileName,AliDAQ::DdlFileName("ITSSDD",i)); //The name of the output file.
604 outfile = new AliFstream(fileName);
605 //write Dummy DATA HEADER
606 UInt_t dataHeaderPosition=outfile->Tellp();
607 outfile->WriteBuffer((char*)(&header),sizeof(header));
609 //first 9 "dummy" words to be skipped
610 for(Int_t iw=0;iw<9;iw++){
611 outfile->WriteBuffer((char*)(&skippedword),sizeof(skippedword));
614 //Loops over Modules of a particular DDL
615 for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
616 Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
617 if(moduleNumber!=-1){
619 branch->GetEvent(moduleNumber);
621 //For each Module, buf contains the array of data words in Binary format
622 //fIndex gives the number of 32 bits words in the buffer for each module
623 // cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
624 GetDigitsSDD(digits,mod,moduleNumber,i,buf);
625 outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t)));
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;