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"
37 ClassImp(AliITSDDLRawData)
39 ////////////////////////////////////////////////////////////////////////////////////////
40 AliITSDDLRawData::AliITSDDLRawData():
48 ////////////////////////////////////////////////////////////////////////////////////////
50 AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) :
52 fVerbose(source.fVerbose),
53 fIndex(source.fIndex),
54 fHalfStaveModule(source.fHalfStaveModule){
58 ////////////////////////////////////////////////////////////////////////////////////////
60 AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
62 this->fIndex=source.fIndex;
63 this->fHalfStaveModule=source.fHalfStaveModule;
64 this->fVerbose=source.fVerbose;
68 ////////////////////////////////////////////////////////////////////////////////////////
72 void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
73 //This method packs the SSD digits in a proper 32 bits structure
79 Int_t ndigits = ITSdigits->GetEntries();
84 ftxt.open("SSDdigits.txt",ios::app);
86 for (Int_t digit=0;digit<ndigits;digit++) {
87 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
88 iz=digs->GetCoord1(); // If iz==0, N side and if iz=1 P side
89 ix=digs->GetCoord2(); // Strip Numbar
90 is=digs->GetCompressedSignal(); // ADC Signal
91 // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
93 ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
96 AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
98 AliBitPacking::PackWord(word,baseWord,10,19);//Strip Number
100 AliBitPacking::PackWord(word,baseWord,20,20);//ADC Channel ID (N or P side)
102 AliBitPacking::PackWord(word,baseWord,21,31);//ADC module ID
104 buf[fIndex]=baseWord;
112 ////////////////////////////////////////////////////////////////////////////////////////
113 //Silicon Drift Detector
116 void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){
117 //This method packs the SSD digits in a proper 32 bits structure
123 Int_t ndigits = ITSdigits->GetEntries();
127 //cout<<"Mudule "<<mod<<" number of digits "<<ndigits<<endl;
129 ftxt.open("SDDdigits.txt",ios::app);
130 for (Int_t digit=0;digit<ndigits;digit++) {
131 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
132 iz=digs->GetCoord1(); // Anode
133 ix=digs->GetCoord2(); // Time
134 is=digs->GetCompressedSignal(); // ADC Signal
136 ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
137 // cout<<"Amplitude value:"<<is<<" Time Bucket:"<<ix<<" Anode:"<<iz<<endl;
138 if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");}
141 //10 bits words for amplitude value
143 AliBitPacking::PackWord(word,baseWord,0,9);//ADC data
145 AliBitPacking::PackWord(word,baseWord,10,17);//Time bucket
147 AliBitPacking::PackWord(word,baseWord,18,26);//Anode Number
149 AliBitPacking::PackWord(word,baseWord,27,31);//Module number
152 //8bits words for amplitude value
154 AliBitPacking::PackWord(word,baseWord,0,7);//ADC data
156 AliBitPacking::PackWord(word,baseWord,8,15);//Time bucket
158 AliBitPacking::PackWord(word,baseWord,16,24);//Anode Number
160 AliBitPacking::PackWord(word,baseWord,25,31);//Module number
163 buf[fIndex]=baseWord;
171 ////////////////////////////////////////////////////////////////////////////////////////
175 void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf){
176 //This method packs the SPD digits in a proper 32 structure
177 //Since data is zero suppressed,the coordinates for the chip having zero digits
178 //doesn't get listed in the galice.root file. However the SPD format requires
179 //the empty chip to be written with chip header and chip trailer.
180 //The index of the half stave is calculated as (mod/2).
186 Int_t chipHitCount=0; //Number of Hit in the current chip
187 Int_t previousChip=-1; //Previuos chip respect to the actual aone
188 Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
189 //cout<<" Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
191 fHalfStaveModule++; //It's a private variable used to distinguish between the firs
192 //and the second module of an Half Stave Module
197 ftxt.open("SPDdigits.txt",ios::app);
198 for (Int_t digit=0;digit<ndigits;digit++){
199 digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
200 /*---------------------------------------------------------------------------
201 * Each module contains 5 read out chips of 256 rows and 32 columns.
202 * So, the cell number in Z direction varies from 0 to 159. Therefore,
203 * to get the chip address (0 to 4), we need to divide column number by 32.
204 * ---------------------------------------------------------------------*/
205 iz=digs->GetCoord1(); // Cell number in Z direction
206 ix=digs->GetCoord2(); // Cell number in X direction
209 ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
211 if(fHalfStaveModule){
215 if(previousChip==-1){
216 //loop over chip without digits
217 //Even if there aren't digits for a given chip
218 //the chip header and the chip trailer are stored
219 for(Int_t i=0;i<(iz/32);i++){
221 WriteChipHeader(i+5,(mod/2),baseWord);
223 WriteChipHeader(i,(mod/2),baseWord);
224 WriteChipTrailer(buf,chipHitCount,baseWord);
227 WriteChipHeader(chipNo,(mod/2),baseWord);
229 WriteHit(buf,ix,hitRow,baseWord);
233 if(previousChip!=chipNo){
234 WriteChipTrailer(buf,chipHitCount,baseWord);
236 for(Int_t i=previousChip+1;i<chipNo;i++){
237 WriteChipHeader(i,(mod/2),baseWord);
238 WriteChipTrailer(buf,0,baseWord);
241 WriteChipHeader(chipNo,(mod/2),baseWord);
245 WriteHit(buf,ix,hitRow,baseWord);
248 //Even if there aren't digits for a given chip
249 //the chip header and the chip trailer are stored
252 WriteChipTrailer(buf,chipHitCount,baseWord);
254 for(Int_t i=chipNo+1;i<=end;i++){
255 WriteChipHeader(i,(mod/2),baseWord);
256 WriteChipTrailer(buf,0,baseWord);
261 //In this module there aren't digits but
262 //the chip header and chip trailer are store anyway
263 if(fHalfStaveModule){
267 for(Int_t i=0;i<5;i++){
268 WriteChipHeader(chipNo+i,(mod/2),baseWord);
269 WriteChipTrailer(buf,chipHitCount,baseWord);
278 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
280 Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch){
281 //This method creates the Raw data files for SPD detectors
282 const Int_t kSize=21000; //256*32*5=40960 max number of digits per module
283 UInt_t buf[kSize]; //One buffer cell can contain 2 digits
286 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
288 ofstream outfile; // logical name of the output file
289 AliRawDataHeader header;
292 for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSPD");i++){
293 strcpy(fileName,AliDAQ::DdlFileName("ITSSPD",i)); //The name of the output file.
295 outfile.open(fileName,ios::binary);
297 outfile.open(fileName);
299 //write Dummy DATA HEADER
300 UInt_t dataHeaderPosition=outfile.tellp();
301 outfile.write((char*)(&header),sizeof(header));
302 //Loops over Modules of a particular DDL
303 for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){
304 Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(i, mod);
306 branch->GetEvent(moduleNumber);
307 //For each Module, buf contains the array of data words in Binary format
308 //fIndex gives the number of 32 bits words in the buffer for each module
309 GetDigitsSPD(digits,mod,i,buf);
310 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
311 for(Int_t i=0;i<(fIndex+1);i++){
317 //Write REAL DATA HEADER
318 UInt_t currentFilePosition=outfile.tellp();
319 outfile.seekp(dataHeaderPosition);
320 header.fSize=currentFilePosition-dataHeaderPosition;
321 outfile.write((char*)(&header),sizeof(header));
328 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
330 Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){
331 //This method creates the Raw data files for SSD detectors
332 const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P)
336 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
338 ofstream outfile; // logical name of the output file
339 AliRawDataHeader header;
342 for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSSD");i++){
343 strcpy(fileName,AliDAQ::DdlFileName("ITSSSD",i)); //The name of the output file.
345 outfile.open(fileName,ios::binary);
347 outfile.open(fileName);
349 //write Dummy DATA HEADER
350 UInt_t dataHeaderPosition=outfile.tellp();
351 outfile.write((char*)(&header),sizeof(header));
353 //Loops over Modules of a particular DDL
354 for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){
355 Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod);
356 if(moduleNumber!=-1){
358 branch->GetEvent(moduleNumber);
359 //For each Module, buf contains the array of data words in Binary format
360 //fIndex gives the number of 32 bits words in the buffer for each module
361 GetDigitsSSD(digits,mod,moduleNumber,i,buf);
362 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
367 //Write REAL DATA HEADER
368 UInt_t currentFilePosition=outfile.tellp();
369 outfile.seekp(dataHeaderPosition);
370 header.fSize=currentFilePosition-dataHeaderPosition;
371 header.SetAttribute(0); // valid data
372 outfile.write((char*)(&header),sizeof(header));
379 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
381 Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch){
382 //This method creates the Raw data files for SDD detectors
383 const Int_t kSize=131072; //256*512
387 TClonesArray*& digits = * (TClonesArray**) branch->GetAddress();
389 ofstream outfile; // logical name of the output file
390 AliRawDataHeader header;
393 for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSDD");i++){
394 strcpy(fileName,AliDAQ::DdlFileName("ITSSDD",i)); //The name of the output file.
396 outfile.open(fileName,ios::binary);
398 outfile.open(fileName);
400 //write Dummy DATA HEADER
401 UInt_t dataHeaderPosition=outfile.tellp();
402 outfile.write((char*)(&header),sizeof(header));
404 //Loops over Modules of a particular DDL
405 for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){
406 Int_t moduleNumber = AliITSRawStreamSDD::GetModuleNumber(i, mod);
407 if(moduleNumber!=-1){
409 branch->GetEvent(moduleNumber);
410 //For each Module, buf contains the array of data words in Binary format
411 //fIndex gives the number of 32 bits words in the buffer for each module
412 // cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
413 GetDigitsSDD(digits,mod,moduleNumber,i,buf);
414 outfile.write((char *)buf,((fIndex+1)*sizeof(UInt_t)));
419 //Write REAL DATA HEADER
420 UInt_t currentFilePosition=outfile.tellp();
421 outfile.seekp(dataHeaderPosition);
422 header.fSize=currentFilePosition-dataHeaderPosition;
423 header.SetAttribute(0); // valid data
424 outfile.write((char*)(&header),sizeof(header));
431 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
433 void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t halfStave,UInt_t &BaseWord){
434 //This method writes a chip header
435 //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<halfStave<<endl;
437 AliBitPacking::PackWord(ChipAddr,BaseWord,16,19);
438 // At the moment the event count is always 0 (bits 20-26)
439 AliBitPacking::PackWord(0,BaseWord,20,26);
440 AliBitPacking::PackWord(halfStave,BaseWord,27,29);
441 AliBitPacking::PackWord(0x1,BaseWord,30,31);
443 }//end WriteChipHeader
445 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
447 void AliITSDDLRawData::WriteChipTrailer(UInt_t *buf,Int_t ChipHitCount,UInt_t &BaseWord){
448 //This method writes a chip trailer
450 if((ChipHitCount%2)!=0){
451 AliBitPacking::PackWord(0xC000,BaseWord,16,31);
453 AliBitPacking::PackWord(ChipHitCount,BaseWord,0,13);
454 AliBitPacking::PackWord(0x0,BaseWord,14,15);
456 buf[fIndex]=BaseWord;
459 }//end WriteChipTrailer
461 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
463 void AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){
464 //This method writs an hit
466 AliBitPacking::PackWord(HitAddr,BaseWord,16,20);
467 AliBitPacking::PackWord(RowAddr,BaseWord,21,28);
468 AliBitPacking::PackWord(2,BaseWord,30,31);
471 AliBitPacking::PackWord(HitAddr,BaseWord,0,4);
472 AliBitPacking::PackWord(RowAddr,BaseWord,5,12);
473 AliBitPacking::PackWord(2,BaseWord,14,15);
475 buf[fIndex]=BaseWord;