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"
40 #include "AliBitPacking.h"
42 ClassImp(AliITSDDLRawData)
44 ////////////////////////////////////////////////////////////////////////////////////////
45 AliITSDDLRawData::AliITSDDLRawData(){
52 ////////////////////////////////////////////////////////////////////////////////////////
54 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) :
57 this->fIndex=source.fIndex;
58 this->fHalfStaveModule=source.fHalfStaveModule;
59 this->fVerbose=source.fVerbose;
63 ////////////////////////////////////////////////////////////////////////////////////////
65 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
67 this->fIndex=source.fIndex;
68 this->fHalfStaveModule=source.fHalfStaveModule;
69 this->fVerbose=source.fVerbose;
73 ////////////////////////////////////////////////////////////////////////////////////////
77 void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
78 //This method packs the SSD digits in a proper 32 bits structure
84 Int_t ndigits = ITSdigits->GetEntries();
89 ftxt.open("SSDdigits.txt",ios::app);
91 for (Int_t digit=0;digit<ndigits;digit++) {
92 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
93 iz=digs->GetCoord1(); // If iz==0, N side and if iz=1 P side
94 ix=digs->GetCoord2(); // Strip Numbar
95 is=digs->GetCompressedSignal(); // ADC Signal
96 // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
98 ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
101 AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
103 AliBitPacking::PackWord(word,baseWord,10,19);//Strip Number
105 AliBitPacking::PackWord(word,baseWord,20,20);//ADC Channel ID (N or P side)
107 AliBitPacking::PackWord(word,baseWord,21,31);//ADC module ID
109 buf[fIndex]=baseWord;
117 ////////////////////////////////////////////////////////////////////////////////////////
118 //Silicon Drift Detector
121 void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
122 //This method packs the SSD digits in a proper 32 bits structure
128 Int_t ndigits = ITSdigits->GetEntries();
132 //cout<<"Mudule "<<mod<<" number of digits "<<ndigits<<endl;
134 ftxt.open("SDDdigits.txt",ios::app);
135 for (Int_t digit=0;digit<ndigits;digit++) {
136 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
137 iz=digs->GetCoord1(); // Anode
138 ix=digs->GetCoord2(); // Time
139 is=digs->GetCompressedSignal(); // ADC Signal
141 ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
142 // cout<<"Amplitude value:"<<is<<" Time Bucket:"<<ix<<" Anode:"<<iz<<endl;
143 if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
146 //10 bits words for amplitude value
148 AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
150 AliBitPacking::PackWord(word,baseWord,10,17);//Time bucket
152 AliBitPacking::PackWord(word,baseWord,18,26);//Anode Number
154 AliBitPacking::PackWord(word,baseWord,27,31);//Module number
157 //8bits words for amplitude value
159 AliBitPacking::PackWord(word,baseWord,0,7);//ADC data
161 AliBitPacking::PackWord(word,baseWord,8,15);//Time bucket
163 AliBitPacking::PackWord(word,baseWord,16,24);//Anode Number
165 AliBitPacking::PackWord(word,baseWord,25,31);//Module number
168 buf[fIndex]=baseWord;
176 ////////////////////////////////////////////////////////////////////////////////////////
180 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
181 //This method packs the SPD digits in a proper 32 structure
182 //Since data is zero suppressed,the coordinates for the chip having zero digits
183 //doesn't get listed in the galice.root file. However the SPD format requires
184 //the empty chip to be written with chip header and chip trailer.
190 Int_t chipHitCount=0; //Number of Hit in the current chip
191 Int_t previousChip=-1; //Previuos chip respect to the actual aone
192 Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
193 //cout<<" Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
195 fHalfStaveModule++; //It's a private variable used to distinguish between the firs
196 //and the second module of an Half Stave Module
201 ftxt.open("SPDdigits.txt",ios::app);
202 for (Int_t digit=0;digit<ndigits;digit++){
203 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
204 /*---------------------------------------------------------------------------
205 * Each module contains 5 read out chips of 256 rows and 32 columns.
206 * So, the cell number in Z direction varies from 0 to 159. Therefore,
207 * to get the chip address (0 to 4), we need to divide column number by 32.
208 * ---------------------------------------------------------------------*/
209 iz=digs->GetCoord1(); // Cell number in Z direction
210 ix=digs->GetCoord2(); // Cell number in X direction
213 ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
215 if(fHalfStaveModule){
219 if(previousChip==-1){
220 //loop over chip without digits
221 //Even if there aren't digits for a given chip
222 //the chip header and the chip trailer are stored
223 for(Int_t i=0;i<(iz/32);i++){
225 WriteChipHeader(i+5,(mod/2),baseWord);
227 WriteChipHeader(i,(mod/2),baseWord);
228 WriteChipTrailer(buf,chipHitCount,baseWord);
231 WriteChipHeader(chipNo,(mod/2),baseWord);
233 WriteHit(buf,ix,hitRow,baseWord);
237 if(previousChip!=chipNo){
238 WriteChipTrailer(buf,chipHitCount,baseWord);
240 for(Int_t i=previousChip+1;i<chipNo;i++){
241 WriteChipHeader(i,(mod/2),baseWord);
242 WriteChipTrailer(buf,0,baseWord);
245 WriteChipHeader(chipNo,(mod/2),baseWord);
249 WriteHit(buf,ix,hitRow,baseWord);
252 //Even if there aren't digits for a given chip
253 //the chip header and the chip trailer are stored
256 WriteChipTrailer(buf,chipHitCount,baseWord);
258 for(Int_t i=chipNo+1;i<=end;i++){
259 WriteChipHeader(i,(mod/2),baseWord);
260 WriteChipTrailer(buf,0,baseWord);
265 //In this module there aren't digits but
266 //the chip header and chip trailer are store anyway
267 if(fHalfStaveModule){
271 for(Int_t i=0;i<5;i++){
272 WriteChipHeader(chipNo+i,(mod/2),baseWord);
273 WriteChipTrailer(buf,chipHitCount,baseWord);
282 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
284 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
285 //This method creates the Raw data files for SPD detectors
286 const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
287 UInt_t buf[kSize]; //One buffer cell can contain 2 digits
290 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
292 ofstream outfile; // logical name of the output file
293 AliRawDataHeader header;
296 for(Int_t i=0;i<AliITSRawStreamSPD::kDDLsNumber;i++){
297 sprintf(fileName,"ITSSPD_%d.ddl",i+AliITSRawStreamSPD::kDDLOffset); //The name of the output file.
299 outfile.open(fileName,ios::binary);
301 outfile.open(fileName);
303 //write Dummy DATA HEADER
304 UInt_t dataHeaderPosition=outfile.tellp();
305 outfile.write((char*)(&header),sizeof(header));
306 //Loops over Modules of a particular DDL
307 for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
308 Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
310 branch->GetEvent(moduleNumber);
311 //For each Module, buf contains the array of data words in Binary format
312 //fIndex gives the number of 32 bits words in the buffer for each module
313 GetDigitsSPD(digits,moduleNumber,i,buf);
314 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
315 for(Int_t i=0;i<(fIndex+1);i++){
321 //Write REAL DATA HEADER
322 UInt_t currentFilePosition=outfile.tellp();
323 outfile.seekp(dataHeaderPosition);
324 header.fSize=currentFilePosition-dataHeaderPosition;
325 header.SetAttribute(0); // valid data
326 outfile.write((char*)(&header),sizeof(header));
333 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
335 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
336 //This method creates the Raw data files for SSD detectors
337 const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
341 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
343 ofstream outfile; // logical name of the output file
344 AliRawDataHeader header;
347 for(Int_t i=0;i<AliITSRawStreamSSD::kDDLsNumber;i++){
348 sprintf(fileName,"ITSSSD_%d.ddl",i+AliITSRawStreamSSD::kDDLOffset); //The name of the output file
350 outfile.open(fileName,ios::binary);
352 outfile.open(fileName);
354 //write Dummy DATA HEADER
355 UInt_t dataHeaderPosition=outfile.tellp();
356 outfile.write((char*)(&header),sizeof(header));
358 //Loops over Modules of a particular DDL
359 for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
360 Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
361 if(moduleNumber!=-1){
363 branch->GetEvent(moduleNumber);
364 //For each Module, buf contains the array of data words in Binary format
365 //fIndex gives the number of 32 bits words in the buffer for each module
366 GetDigitsSSD(digits,mod,moduleNumber,i,buf);
367 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
372 //Write REAL DATA HEADER
373 UInt_t currentFilePosition=outfile.tellp();
374 outfile.seekp(dataHeaderPosition);
375 header.fSize=currentFilePosition-dataHeaderPosition;
376 header.SetAttribute(0); // valid data
377 outfile.write((char*)(&header),sizeof(header));
384 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
386 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
387 //This method creates the Raw data files for SDD detectors
388 const Int_t kSize=131072; //256*512
392 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
394 ofstream outfile; // logical name of the output file
395 AliRawDataHeader header;
398 for(Int_t i=0;i<AliITSRawStreamSDD::kDDLsNumber;i++){
399 sprintf(fileName,"ITSSDD_%d.ddl",i+AliITSRawStreamSDD::kDDLOffset); //The name of the output file
401 outfile.open(fileName,ios::binary);
403 outfile.open(fileName);
405 //write Dummy DATA HEADER
406 UInt_t dataHeaderPosition=outfile.tellp();
407 outfile.write((char*)(&header),sizeof(header));
409 //Loops over Modules of a particular DDL
410 for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
411 Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
412 if(moduleNumber!=-1){
414 branch->GetEvent(moduleNumber);
415 //For each Module, buf contains the array of data words in Binary format
416 //fIndex gives the number of 32 bits words in the buffer for each module
417 // cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
418 GetDigitsSDD(digits,mod,moduleNumber,i,buf);
419 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
424 //Write REAL DATA HEADER
425 UInt_t currentFilePosition=outfile.tellp();
426 outfile.seekp(dataHeaderPosition);
427 header.fSize=currentFilePosition-dataHeaderPosition;
428 header.SetAttribute(0); // valid data
429 outfile.write((char*)(&header),sizeof(header));
436 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
438 void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t EventCnt,UInt_t &BaseWord){
439 //This method writes a chip header
440 //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
442 AliBitPacking::PackWord(ChipAddr,BaseWord,0,3);
443 AliBitPacking::PackWord(EventCnt,BaseWord,4,10);
444 AliBitPacking::PackWord(0x7,BaseWord,11,13);
445 AliBitPacking::PackWord(0x1,BaseWord,14,15);
447 }//end WriteChipHeader
449 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
451 void AliITSDDLRawData::ReadChipHeader(Int_t &ChipAddr,Int_t &EventCnt,UInt_t BaseWord){
452 //This method reads a chip header
453 UInt_t temp=AliBitPacking::UnpackWord(BaseWord,0,3);
454 ChipAddr=(Int_t)temp;
455 temp=AliBitPacking::UnpackWord(BaseWord,4,10);
456 EventCnt=(Int_t)temp;
458 Info("ReadChipHeader", "Chip:&d Half Stave module:%d",ChipAddr,EventCnt);
460 }//end ReadChipHeader
462 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
464 void AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
465 //This method writes a chip trailer
467 if((ChipHitCount%2)!=0){
468 AliBitPacking::PackWord(0xFEDC,BaseWord,0,15);
470 AliBitPacking::PackWord(ChipHitCount,BaseWord,16,28);
471 AliBitPacking::PackWord(0x0,BaseWord,30,31);
473 buf[fIndex]=BaseWord;
476 }//end WriteChipTrailer
478 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
480 void AliITSDDLRawData::ReadChipTrailer(Int_t &ChipHitCount,UInt_t BaseWord){
481 //This method reads a chip trailer
482 UInt_t temp=AliBitPacking::UnpackWord(BaseWord,16,28);
483 ChipHitCount=(Int_t)temp;
485 }//end ReadChipTrailer
487 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
489 void AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
490 //This method writs an hit
492 AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
493 AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
494 AliBitPacking::PackWord(2,BaseWord,14,15);
497 AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
498 AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
499 AliBitPacking::PackWord(2,BaseWord,30,31);
501 buf[fIndex]=BaseWord;