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 ClassImp(AliITSDDLRawData)
38 ////////////////////////////////////////////////////////////////////////////////////////
39 AliITSDDLRawData::AliITSDDLRawData(){
46 ////////////////////////////////////////////////////////////////////////////////////////
48 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) :
51 this->fIndex=source.fIndex;
52 this->fHalfStaveModule=source.fHalfStaveModule;
53 this->fVerbose=source.fVerbose;
57 ////////////////////////////////////////////////////////////////////////////////////////
59 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
61 this->fIndex=source.fIndex;
62 this->fHalfStaveModule=source.fHalfStaveModule;
63 this->fVerbose=source.fVerbose;
67 ////////////////////////////////////////////////////////////////////////////////////////
71 void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
72 //This method packs the SSD digits in a proper 32 bits structure
78 Int_t ndigits = ITSdigits->GetEntries();
83 ftxt.open("SSDdigits.txt",ios::app);
85 for (Int_t digit=0;digit<ndigits;digit++) {
86 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
87 iz=digs->GetCoord1(); // If iz==0, N side and if iz=1 P side
88 ix=digs->GetCoord2(); // Strip Numbar
89 is=digs->GetCompressedSignal(); // ADC Signal
90 // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
92 ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
95 AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
97 AliBitPacking::PackWord(word,baseWord,10,19);//Strip Number
99 AliBitPacking::PackWord(word,baseWord,20,20);//ADC Channel ID (N or P side)
101 AliBitPacking::PackWord(word,baseWord,21,31);//ADC module ID
103 buf[fIndex]=baseWord;
111 ////////////////////////////////////////////////////////////////////////////////////////
112 //Silicon Drift Detector
115 void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
116 //This method packs the SSD digits in a proper 32 bits structure
122 Int_t ndigits = ITSdigits->GetEntries();
126 //cout<<"Mudule "<<mod<<" number of digits "<<ndigits<<endl;
128 ftxt.open("SDDdigits.txt",ios::app);
129 for (Int_t digit=0;digit<ndigits;digit++) {
130 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
131 iz=digs->GetCoord1(); // Anode
132 ix=digs->GetCoord2(); // Time
133 is=digs->GetCompressedSignal(); // ADC Signal
135 ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
136 // cout<<"Amplitude value:"<<is<<" Time Bucket:"<<ix<<" Anode:"<<iz<<endl;
137 if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
140 //10 bits words for amplitude value
142 AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
144 AliBitPacking::PackWord(word,baseWord,10,17);//Time bucket
146 AliBitPacking::PackWord(word,baseWord,18,26);//Anode Number
148 AliBitPacking::PackWord(word,baseWord,27,31);//Module number
151 //8bits words for amplitude value
153 AliBitPacking::PackWord(word,baseWord,0,7);//ADC data
155 AliBitPacking::PackWord(word,baseWord,8,15);//Time bucket
157 AliBitPacking::PackWord(word,baseWord,16,24);//Anode Number
159 AliBitPacking::PackWord(word,baseWord,25,31);//Module number
162 buf[fIndex]=baseWord;
170 ////////////////////////////////////////////////////////////////////////////////////////
174 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
175 //This method packs the SPD digits in a proper 32 structure
176 //Since data is zero suppressed,the coordinates for the chip having zero digits
177 //doesn't get listed in the galice.root file. However the SPD format requires
178 //the empty chip to be written with chip header and chip trailer.
184 Int_t chipHitCount=0; //Number of Hit in the current chip
185 Int_t previousChip=-1; //Previuos chip respect to the actual aone
186 Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
187 //cout<<" Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
189 fHalfStaveModule++; //It's a private variable used to distinguish between the firs
190 //and the second module of an Half Stave Module
195 ftxt.open("SPDdigits.txt",ios::app);
196 for (Int_t digit=0;digit<ndigits;digit++){
197 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
198 /*---------------------------------------------------------------------------
199 * Each module contains 5 read out chips of 256 rows and 32 columns.
200 * So, the cell number in Z direction varies from 0 to 159. Therefore,
201 * to get the chip address (0 to 4), we need to divide column number by 32.
202 * ---------------------------------------------------------------------*/
203 iz=digs->GetCoord1(); // Cell number in Z direction
204 ix=digs->GetCoord2(); // Cell number in X direction
207 ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
209 if(fHalfStaveModule){
213 if(previousChip==-1){
214 //loop over chip without digits
215 //Even if there aren't digits for a given chip
216 //the chip header and the chip trailer are stored
217 for(Int_t i=0;i<(iz/32);i++){
219 WriteChipHeader(i+5,(mod/2),baseWord);
221 WriteChipHeader(i,(mod/2),baseWord);
222 WriteChipTrailer(buf,chipHitCount,baseWord);
225 WriteChipHeader(chipNo,(mod/2),baseWord);
227 WriteHit(buf,ix,hitRow,baseWord);
231 if(previousChip!=chipNo){
232 WriteChipTrailer(buf,chipHitCount,baseWord);
234 for(Int_t i=previousChip+1;i<chipNo;i++){
235 WriteChipHeader(i,(mod/2),baseWord);
236 WriteChipTrailer(buf,0,baseWord);
239 WriteChipHeader(chipNo,(mod/2),baseWord);
243 WriteHit(buf,ix,hitRow,baseWord);
246 //Even if there aren't digits for a given chip
247 //the chip header and the chip trailer are stored
250 WriteChipTrailer(buf,chipHitCount,baseWord);
252 for(Int_t i=chipNo+1;i<=end;i++){
253 WriteChipHeader(i,(mod/2),baseWord);
254 WriteChipTrailer(buf,0,baseWord);
259 //In this module there aren't digits but
260 //the chip header and chip trailer are store anyway
261 if(fHalfStaveModule){
265 for(Int_t i=0;i<5;i++){
266 WriteChipHeader(chipNo+i,(mod/2),baseWord);
267 WriteChipTrailer(buf,chipHitCount,baseWord);
276 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
278 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
279 //This method creates the Raw data files for SPD detectors
280 const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
281 UInt_t buf[kSize]; //One buffer cell can contain 2 digits
284 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
286 ofstream outfile; // logical name of the output file
287 AliRawDataHeader header;
290 for(Int_t i=0;i<AliITSRawStreamSPD::kDDLsNumber;i++){
291 sprintf(fileName,"ITSSPD_%d.ddl",i+AliITSRawStreamSPD::kDDLOffset); //The name of the output file.
293 outfile.open(fileName,ios::binary);
295 outfile.open(fileName);
297 //write Dummy DATA HEADER
298 UInt_t dataHeaderPosition=outfile.tellp();
299 outfile.write((char*)(&header),sizeof(header));
300 //Loops over Modules of a particular DDL
301 for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
302 Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
304 branch->GetEvent(moduleNumber);
305 //For each Module, buf contains the array of data words in Binary format
306 //fIndex gives the number of 32 bits words in the buffer for each module
307 GetDigitsSPD(digits,moduleNumber,i,buf);
308 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
309 for(Int_t i=0;i<(fIndex+1);i++){
315 //Write REAL DATA HEADER
316 UInt_t currentFilePosition=outfile.tellp();
317 outfile.seekp(dataHeaderPosition);
318 header.fSize=currentFilePosition-dataHeaderPosition;
319 outfile.write((char*)(&header),sizeof(header));
326 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
328 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
329 //This method creates the Raw data files for SSD detectors
330 const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
334 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
336 ofstream outfile; // logical name of the output file
337 AliRawDataHeader header;
340 for(Int_t i=0;i<AliITSRawStreamSSD::kDDLsNumber;i++){
341 sprintf(fileName,"ITSSSD_%d.ddl",i+AliITSRawStreamSSD::kDDLOffset); //The name of the output file
343 outfile.open(fileName,ios::binary);
345 outfile.open(fileName);
347 //write Dummy DATA HEADER
348 UInt_t dataHeaderPosition=outfile.tellp();
349 outfile.write((char*)(&header),sizeof(header));
351 //Loops over Modules of a particular DDL
352 for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
353 Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
354 if(moduleNumber!=-1){
356 branch->GetEvent(moduleNumber);
357 //For each Module, buf contains the array of data words in Binary format
358 //fIndex gives the number of 32 bits words in the buffer for each module
359 GetDigitsSSD(digits,mod,moduleNumber,i,buf);
360 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
365 //Write REAL DATA HEADER
366 UInt_t currentFilePosition=outfile.tellp();
367 outfile.seekp(dataHeaderPosition);
368 header.fSize=currentFilePosition-dataHeaderPosition;
369 header.SetAttribute(0); // valid data
370 outfile.write((char*)(&header),sizeof(header));
377 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
379 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
380 //This method creates the Raw data files for SDD detectors
381 const Int_t kSize=131072; //256*512
385 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
387 ofstream outfile; // logical name of the output file
388 AliRawDataHeader header;
391 for(Int_t i=0;i<AliITSRawStreamSDD::kDDLsNumber;i++){
392 sprintf(fileName,"ITSSDD_%d.ddl",i+AliITSRawStreamSDD::kDDLOffset); //The name of the output file
394 outfile.open(fileName,ios::binary);
396 outfile.open(fileName);
398 //write Dummy DATA HEADER
399 UInt_t dataHeaderPosition=outfile.tellp();
400 outfile.write((char*)(&header),sizeof(header));
402 //Loops over Modules of a particular DDL
403 for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
404 Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
405 if(moduleNumber!=-1){
407 branch->GetEvent(moduleNumber);
408 //For each Module, buf contains the array of data words in Binary format
409 //fIndex gives the number of 32 bits words in the buffer for each module
410 // cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
411 GetDigitsSDD(digits,mod,moduleNumber,i,buf);
412 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
417 //Write REAL DATA HEADER
418 UInt_t currentFilePosition=outfile.tellp();
419 outfile.seekp(dataHeaderPosition);
420 header.fSize=currentFilePosition-dataHeaderPosition;
421 header.SetAttribute(0); // valid data
422 outfile.write((char*)(&header),sizeof(header));
429 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
431 void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t /*EventCnt*/,UInt_t &BaseWord){
432 //This method writes a chip header
433 //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
435 AliBitPacking::PackWord(ChipAddr,BaseWord,0,3);
436 // AliBitPacking::PackWord(EventCnt,BaseWord,4,10);
437 AliBitPacking::PackWord(0,BaseWord,4,10);
438 AliBitPacking::PackWord(0x7,BaseWord,11,13);
439 AliBitPacking::PackWord(0x1,BaseWord,14,15);
441 }//end WriteChipHeader
443 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
445 void AliITSDDLRawData::ReadChipHeader(Int_t &ChipAddr,Int_t &EventCnt,UInt_t BaseWord){
446 //This method reads a chip header
447 UInt_t temp=AliBitPacking::UnpackWord(BaseWord,0,3);
448 ChipAddr=(Int_t)temp;
449 temp=AliBitPacking::UnpackWord(BaseWord,4,10);
450 EventCnt=(Int_t)temp;
452 Info("ReadChipHeader", "Chip:&d Half Stave module:%d",ChipAddr,EventCnt);
454 }//end ReadChipHeader
456 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
458 void AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
459 //This method writes a chip trailer
461 if((ChipHitCount%2)!=0){
462 AliBitPacking::PackWord(0xC000,BaseWord,0,15);
464 AliBitPacking::PackWord(ChipHitCount,BaseWord,16,29);
465 AliBitPacking::PackWord(0x0,BaseWord,30,31);
467 buf[fIndex]=BaseWord;
470 }//end WriteChipTrailer
472 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
474 void AliITSDDLRawData::ReadChipTrailer(Int_t &ChipHitCount,UInt_t BaseWord){
475 //This method reads a chip trailer
476 UInt_t temp=AliBitPacking::UnpackWord(BaseWord,16,29);
477 ChipHitCount=(Int_t)temp;
479 }//end ReadChipTrailer
481 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
483 void AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
484 //This method writs an hit
486 AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
487 AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
488 AliBitPacking::PackWord(2,BaseWord,14,15);
491 AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
492 AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
493 AliBitPacking::PackWord(2,BaseWord,30,31);
495 buf[fIndex]=BaseWord;