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>
31 #include "AliITSgeom.h"
32 #include "AliITSdigitSPD.h"
33 #include "AliITSdigitSDD.h"
34 #include "AliITSdigitSSD.h"
35 #include "AliITSDDLRawData.h"
36 #include "AliRawDataHeader.h"
37 #include "AliITSRawStreamSPD.h"
38 #include "AliITSRawStreamSDD.h"
39 #include "AliITSRawStreamSSD.h"
41 ClassImp(AliITSDDLRawData)
43 ////////////////////////////////////////////////////////////////////////////////////////
44 AliITSDDLRawData::AliITSDDLRawData(){
51 ////////////////////////////////////////////////////////////////////////////////////////
53 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) :
56 this->fIndex=source.fIndex;
57 this->fHalfStaveModule=source.fHalfStaveModule;
58 this->fVerbose=source.fVerbose;
62 ////////////////////////////////////////////////////////////////////////////////////////
64 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
66 this->fIndex=source.fIndex;
67 this->fHalfStaveModule=source.fHalfStaveModule;
68 this->fVerbose=source.fVerbose;
72 ////////////////////////////////////////////////////////////////////////////////////////
76 void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
77 //This method packs the SSD digits in a proper 32 bits structure
83 Int_t ndigits = ITSdigits->GetEntries();
88 ftxt.open("SSDdigits.txt",ios::app);
90 for (Int_t digit=0;digit<ndigits;digit++) {
91 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
92 iz=digs->GetCoord1(); // If iz==0, N side and if iz=1 P side
93 ix=digs->GetCoord2(); // Strip Numbar
94 is=digs->GetCompressedSignal(); // ADC Signal
95 // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
97 ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
100 PackWord(baseWord,word,0,9);//ADC data
102 PackWord(baseWord,word,10,19);//Strip Number
104 PackWord(baseWord,word,20,20);//ADC Channel ID (N or P side)
106 PackWord(baseWord,word,21,31);//ADC module ID
108 buf[fIndex]=baseWord;
116 ////////////////////////////////////////////////////////////////////////////////////////
117 //Silicon Drift Detector
120 void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
121 //This method packs the SSD digits in a proper 32 bits structure
127 Int_t ndigits = ITSdigits->GetEntries();
131 //cout<<"Mudule "<<mod<<" number of digits "<<ndigits<<endl;
133 ftxt.open("SDDdigits.txt",ios::app);
134 for (Int_t digit=0;digit<ndigits;digit++) {
135 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
136 iz=digs->GetCoord1(); // Anode
137 ix=digs->GetCoord2(); // Time
138 is=digs->GetCompressedSignal(); // ADC Signal
140 ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
141 // cout<<"Amplitude value:"<<is<<" Time Bucket:"<<ix<<" Anode:"<<iz<<endl;
142 if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
145 //10 bits words for amplitude value
147 PackWord(baseWord,word,0,9);//ADC data
149 PackWord(baseWord,word,10,17);//Time bucket
151 PackWord(baseWord,word,18,26);//Anode Number
153 PackWord(baseWord,word,27,31);//Module number
156 //8bits words for amplitude value
158 PackWord(baseWord,word,0,7);//ADC data
160 PackWord(baseWord,word,8,15);//Time bucket
162 PackWord(baseWord,word,16,24);//Anode Number
164 PackWord(baseWord,word,25,31);//Module number
167 buf[fIndex]=baseWord;
175 ////////////////////////////////////////////////////////////////////////////////////////
179 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
180 //This method packs the SPD digits in a proper 32 structure
181 //Since data is zero suppressed,the coordinates for the chip having zero digits
182 //doesn't get listed in the galice.root file. However the SPD format requires
183 //the empty chip to be written with chip header and chip trailer.
189 Int_t chipHitCount=0; //Number of Hit in the current chip
190 Int_t previousChip=-1; //Previuos chip respect to the actual aone
191 Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
192 //cout<<" Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
194 fHalfStaveModule++; //It's a private variable used to distinguish between the firs
195 //and the second module of an Half Stave Module
200 ftxt.open("SPDdigits.txt",ios::app);
201 for (Int_t digit=0;digit<ndigits;digit++){
202 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
203 /*---------------------------------------------------------------------------
204 * Each module contains 5 read out chips of 256 rows and 32 columns.
205 * So, the cell number in Z direction varies from 0 to 159. Therefore,
206 * to get the chip address (0 to 4), we need to divide column number by 32.
207 * ---------------------------------------------------------------------*/
208 iz=digs->GetCoord1(); // Cell number in Z direction
209 ix=digs->GetCoord2(); // Cell number in X direction
212 ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
214 if(fHalfStaveModule){
218 if(previousChip==-1){
219 //loop over chip without digits
220 //Even if there aren't digits for a given chip
221 //the chip header and the chip trailer are stored
222 for(Int_t i=0;i<(iz/32);i++){
224 WriteChipHeader(i+5,(mod/2),baseWord);
226 WriteChipHeader(i,(mod/2),baseWord);
227 WriteChipTrailer(buf,chipHitCount,baseWord);
230 WriteChipHeader(chipNo,(mod/2),baseWord);
232 WriteHit(buf,ix,hitRow,baseWord);
236 if(previousChip!=chipNo){
237 WriteChipTrailer(buf,chipHitCount,baseWord);
239 for(Int_t i=previousChip+1;i<chipNo;i++){
240 WriteChipHeader(i,(mod/2),baseWord);
241 WriteChipTrailer(buf,0,baseWord);
244 WriteChipHeader(chipNo,(mod/2),baseWord);
248 WriteHit(buf,ix,hitRow,baseWord);
251 //Even if there aren't digits for a given chip
252 //the chip header and the chip trailer are stored
255 WriteChipTrailer(buf,chipHitCount,baseWord);
257 for(Int_t i=chipNo+1;i<=end;i++){
258 WriteChipHeader(i,(mod/2),baseWord);
259 WriteChipTrailer(buf,0,baseWord);
264 //In this module there aren't digits but
265 //the chip header and chip trailer are store anyway
266 if(fHalfStaveModule){
270 for(Int_t i=0;i<5;i++){
271 WriteChipHeader(chipNo+i,(mod/2),baseWord);
272 WriteChipTrailer(buf,chipHitCount,baseWord);
281 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
283 void AliITSDDLRawData::PackWord(UInt_t &BaseWord, UInt_t Word, Int_t StartBit, Int_t StopBit){
284 //This method packs a word into the Baseword buffer starting form the "StartBit"
285 //and tacking StopBit-StertBit+1 bits
286 UInt_t dummyWord,offSet;
289 //The BaseWord is being filled with 1 from StartBit to StopBit
290 length=StopBit-StartBit+1;
291 sum=(UInt_t)TMath::Power(2,length)-1;
293 Error("PackWord", "Word to be filled is not within desired length\n"
294 "Word:%d Start bit:%d Stop Bit:%d",Word,StartBit,StopBit);
299 BaseWord=BaseWord|offSet;
300 //The Word to be filled is shifted to the position StartBit
301 //and the remaining Left and Right bits are filled with 1
302 sum=(UInt_t)TMath::Power(2,StartBit)-1;
303 dummyWord=0xFFFFFFFF<<length;
305 dummyWord<<=StartBit;
307 BaseWord=BaseWord&dummyWord;
311 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
313 void AliITSDDLRawData::UnpackWord(UInt_t PackedWord, Int_t StartBit, Int_t StopBit, UInt_t &Word){
314 //This method unpacks a words of StopBit-StertBit+1 bits starting from "StopBits"
317 length=StopBit-StartBit+1;
318 offSet=(UInt_t)TMath::Power(2,length)-1;
320 Word=PackedWord&offSet;
325 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
327 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
328 //This method creates the Raw data files for SPD detectors
329 const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
330 UInt_t buf[kSize]; //One buffer cell can contain 2 digits
333 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
335 ofstream outfile; // logical name of the output file
336 AliRawDataHeader header;
339 for(Int_t i=0;i<AliITSRawStreamSPD::kDDLsNumber;i++){
340 sprintf(fileName,"ITSSPD_%d.ddl",i+AliITSRawStreamSPD::kDDLOffset); //The name of the output file.
342 outfile.open(fileName,ios::binary);
344 outfile.open(fileName);
346 //write Dummy DATA HEADER
347 UInt_t dataHeaderPosition=outfile.tellp();
348 outfile.write((char*)(&header),sizeof(header));
349 //Loops over Modules of a particular DDL
350 for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
351 Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
353 branch->GetEvent(moduleNumber);
354 //For each Module, buf contains the array of data words in Binary format
355 //fIndex gives the number of 32 bits words in the buffer for each module
356 GetDigitsSPD(digits,moduleNumber,i,buf);
357 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
358 for(Int_t i=0;i<(fIndex+1);i++){
364 //Write REAL DATA HEADER
365 UInt_t currentFilePosition=outfile.tellp();
366 outfile.seekp(dataHeaderPosition);
367 header.fSize=currentFilePosition-dataHeaderPosition;
368 header.SetAttribute(0); // valid data
369 outfile.write((char*)(&header),sizeof(header));
376 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
378 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
379 //This method creates the Raw data files for SSD detectors
380 const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
384 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
386 ofstream outfile; // logical name of the output file
387 AliRawDataHeader header;
390 for(Int_t i=0;i<AliITSRawStreamSSD::kDDLsNumber;i++){
391 sprintf(fileName,"ITSSSD_%d.ddl",i+AliITSRawStreamSSD::kDDLOffset); //The name of the output file
393 outfile.open(fileName,ios::binary);
395 outfile.open(fileName);
397 //write Dummy DATA HEADER
398 UInt_t dataHeaderPosition=outfile.tellp();
399 outfile.write((char*)(&header),sizeof(header));
401 //Loops over Modules of a particular DDL
402 for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
403 Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
404 if(moduleNumber!=-1){
406 branch->GetEvent(moduleNumber);
407 //For each Module, buf contains the array of data words in Binary format
408 //fIndex gives the number of 32 bits words in the buffer for each module
409 GetDigitsSSD(digits,mod,moduleNumber,i,buf);
410 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
415 //Write REAL DATA HEADER
416 UInt_t currentFilePosition=outfile.tellp();
417 outfile.seekp(dataHeaderPosition);
418 header.fSize=currentFilePosition-dataHeaderPosition;
419 header.SetAttribute(0); // valid data
420 outfile.write((char*)(&header),sizeof(header));
427 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
429 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
430 //This method creates the Raw data files for SDD detectors
431 const Int_t kSize=131072; //256*512
435 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
437 ofstream outfile; // logical name of the output file
438 AliRawDataHeader header;
441 for(Int_t i=0;i<AliITSRawStreamSDD::kDDLsNumber;i++){
442 sprintf(fileName,"ITSSDD_%d.ddl",i+AliITSRawStreamSDD::kDDLOffset); //The name of the output file
444 outfile.open(fileName,ios::binary);
446 outfile.open(fileName);
448 //write Dummy DATA HEADER
449 UInt_t dataHeaderPosition=outfile.tellp();
450 outfile.write((char*)(&header),sizeof(header));
452 //Loops over Modules of a particular DDL
453 for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
454 Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
455 if(moduleNumber!=-1){
457 branch->GetEvent(moduleNumber);
458 //For each Module, buf contains the array of data words in Binary format
459 //fIndex gives the number of 32 bits words in the buffer for each module
460 // cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
461 GetDigitsSDD(digits,mod,moduleNumber,i,buf);
462 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
467 //Write REAL DATA HEADER
468 UInt_t currentFilePosition=outfile.tellp();
469 outfile.seekp(dataHeaderPosition);
470 header.fSize=currentFilePosition-dataHeaderPosition;
471 header.SetAttribute(0); // valid data
472 outfile.write((char*)(&header),sizeof(header));
479 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
481 void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t EventCnt,UInt_t &BaseWord){
482 //This method writes a chip header
483 //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
485 PackWord(BaseWord,ChipAddr,0,3);
486 PackWord(BaseWord,EventCnt,4,10);
487 PackWord(BaseWord,0x7,11,13);
488 PackWord(BaseWord,0x1,14,15);
490 }//end WriteChipHeader
492 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
494 void AliITSDDLRawData::ReadChipHeader(Int_t &ChipAddr,Int_t &EventCnt,UInt_t BaseWord){
495 //This method reads a chip header
497 UnpackWord(BaseWord,0,3,temp);
498 ChipAddr=(Int_t)temp;
499 UnpackWord(BaseWord,4,10,temp);
500 EventCnt=(Int_t)temp;
502 Info("ReadChipHeader", "Chip:&d Half Stave module:%d",ChipAddr,EventCnt);
504 }//end ReadChipHeader
506 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
508 void AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
509 //This method writes a chip trailer
511 if((ChipHitCount%2)!=0){
512 PackWord(BaseWord,0xFEDC,0,15);
514 PackWord(BaseWord,ChipHitCount,16,28);
515 PackWord(BaseWord,0x0,30,31);
517 buf[fIndex]=BaseWord;
520 }//end WriteChipTrailer
522 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
524 void AliITSDDLRawData::ReadChipTrailer(Int_t &ChipHitCount,UInt_t BaseWord){
525 //This method reads a chip trailer
527 UnpackWord(BaseWord,16,28,temp);
528 ChipHitCount=(Int_t)temp;
530 }//end ReadChipTrailer
532 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
534 void AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
535 //This method writs an hit
537 PackWord(BaseWord,HitAddr,0,4);
538 PackWord(BaseWord,RowAddr,5,12);
539 PackWord(BaseWord,2,14,15);
542 PackWord(BaseWord,HitAddr,16,20);
543 PackWord(BaseWord,RowAddr,21,28);
544 PackWord(BaseWord,2,30,31);
546 buf[fIndex]=BaseWord;