3 //*************************************************************************
4 // This file is property of and copyright by the ALICE HLT Project *
5 // ALICE Experiment at CERN, All rights reserved. *
7 // Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 // Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9 // Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *
10 // for The ALICE HLT Project. *
12 // Permission to use, copy, modify and distribute this software and its *
13 // documentation strictly for non-commercial purposes is hereby granted *
14 // without fee, provided that the above copyright notice appears in all *
15 // copies and that both the copyright notice and this permission notice *
16 // appear in the supporting documentation. The authors make no claims *
17 // about the suitability of this software for any purpose. It is *
18 // provided "as is" without express or implied warranty. *
19 //*************************************************************************/
21 /** @file AliHLTTPCDigitReaderUnpacked.cxx
22 @author Timm Steinbeck, Jochen Thaeder, Matthias Richter
24 @brief A digit reader implementation for unpacked TPC data.
32 #include "AliHLTTPCDigitReaderUnpacked.h"
33 #include "AliHLTTPCDigitData.h"
34 #include "AliHLTTPCTransform.h"
35 #include "AliHLTStdIncludes.h"
36 #include "AliHLTTPCMapping.h"
38 ClassImp(AliHLTTPCDigitReaderUnpacked)
40 AliHLTTPCDigitReaderUnpacked::AliHLTTPCDigitReaderUnpacked()
55 fEndOfDataReached(kFALSE),
56 fEndOfChannelReached(kFALSE),
58 fEndTimeBinOfBunch(0),
62 fNextChannelIsAlreadyConfirmed(kFALSE),
65 fBinRowPositionSorted(),
68 // see header file for class documentation
70 // refer to README to build package
72 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
75 AliHLTTPCDigitReaderUnpacked::~AliHLTTPCDigitReaderUnpacked(){
76 // see header file for class documentation
83 int AliHLTTPCDigitReaderUnpacked::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
84 // see header file for class documentation
86 AliHLTTPCUnpackedRawData *tmpptr=NULL;
91 fEndOfDataReached=kFALSE;
92 fEndOfChannelReached=kFALSE;
98 fNextChannelIsAlreadyConfirmed=kFALSE;
99 fDigitsVector.clear();
101 tmpptr = reinterpret_cast<AliHLTTPCUnpackedRawData*>(fPtr);
102 fDigitRowData = (AliHLTTPCDigitRowData*) tmpptr->fDigits;
103 fActRowData = fDigitRowData;
106 fMapping = new AliHLTTPCMapping(patch);
109 while (fActRowData && ((iResult=GetNextRowData(fActRowData))>=0)) {/* empty body */};
112 fActRowData = fDigitRowData;
116 AliHLTTPCTransform::Slice2Sector(slice, AliHLTTPCTransform::GetFirstRow(patch), dummy, fFirstRow);
117 AliHLTTPCTransform::Slice2Sector(slice, AliHLTTPCTransform::GetLastRow(patch), dummy, fLastRow);
121 if ((Int_t)fActRowData->fRow != fRow){
122 HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
130 int AliHLTTPCDigitReaderUnpacked::GetNextRowData(AliHLTTPCDigitRowData*& pRow) const
132 // get new row data from the current row data
134 AliHLTTPCDigitRowData* pCurrent=pRow;
137 if (!pCurrent) return -EINVAL;
138 Byte_t *tmp = (Byte_t*) pCurrent;
139 Int_t size = sizeof(AliHLTTPCDigitRowData) + pCurrent->fNDigit*sizeof(AliHLTTPCDigitData);
141 pRow = reinterpret_cast<AliHLTTPCDigitRowData*>(tmp);
143 // check if the new pointer is within the range
144 if (((Byte_t*)fPtr) + fSize <= tmp){
145 if (((Byte_t*)fPtr) + fSize < tmp) {
146 // if the increment does not match exactly there is a format error
147 HLTError("input format not recognized: buffer %p %d, current row data %p, %d digits", fPtr, fSize, pCurrent, pCurrent->fNDigit);
152 // check if the current row structure has the right format
153 size = sizeof(AliHLTTPCDigitRowData) + pRow->fNDigit*sizeof(AliHLTTPCDigitData);
155 if (((Byte_t*)fPtr) + fSize < tmp){
156 HLTError("Current row data not recognized %p (buffer %p %d) %d digits", pRow, fPtr, fSize, pRow->fNDigit);
164 void AliHLTTPCDigitReaderUnpacked::SortBunchBinVector(){
165 fBinRowPositionSorted.clear();
167 fBinRowPositionSorted.push_back(0);
169 Int_t beginningOfPadIndex=0;
171 for(Int_t i=1;i<(Int_t)fActRowData->fNDigit;i++){
172 if(fData[i-1].fPad == fData[i].fPad){// means that these sinals belong to the same pad
173 if(fData[i-1].fTime+1 == fData[i].fTime){ //means that the signal belong to the same bunch
176 fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex+nAdded,i);
178 else{//we have a new bunch on this pad, put it in fornt of the previous bunch
181 fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex,i);
186 beginningOfPadIndex=totalAdded;
187 fBinRowPositionSorted.push_back(i);
193 bool AliHLTTPCDigitReaderUnpacked::NextSignal(){
194 // see header file for class documentation
195 if (fActRowData==NULL) return false;
197 bool rreadvalue = true;
201 while ( fBin >= (Int_t)fActRowData->fNDigit ){
203 if ((fRow >= fFirstRow) && (fRow <= fLastRow)){
206 if (GetNextRowData(fActRowData)<0) {
219 if ((Int_t)fActRowData->fRow != fRow){
220 HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
224 fData = fActRowData->fDigitData;
227 SortBunchBinVector();
231 fPrevPad = GetSortedPad();
237 int AliHLTTPCDigitReaderUnpacked::GetRow(){
238 // see header file for class documentation
241 if(fUnsorted == kFALSE){
245 rrow = fRow-AliHLTTPCTransform::GetFirstRow(fPatch);
247 rrow += AliHLTTPCTransform::GetFirstRow(2);
254 int AliHLTTPCDigitReaderUnpacked::GetPad(){
255 // see header file for class documentation
257 if(fUnsorted == kFALSE){
258 rpad = GetSortedPad();
266 int AliHLTTPCDigitReaderUnpacked::GetSignal(){
267 // see header file for class documentation
269 if(fUnsorted == kFALSE){
270 rsignal = GetSortedSignal();
273 rsignal = fPrevSignal;
278 int AliHLTTPCDigitReaderUnpacked::GetTime(){
279 // see header file for class documentation
281 if(fUnsorted==kFALSE){
282 rtime = GetSortedTime();
285 rtime = fPrevTime+1-fDataBunch.size();
290 AliHLTUInt32_t AliHLTTPCDigitReaderUnpacked::GetAltroBlockHWaddr() const
292 // see header file for class documentation
293 return (AliHLTUInt32_t)(fMapping->GetHwAddress((UInt_t)GetSortedRow(),(UInt_t)GetSortedPad()));//fTPCRawStream->GetHWAddress();
296 AliHLTTPCDigitData AliHLTTPCDigitReaderUnpacked::GetSortedDigit(){
297 // see header file for class documentation
299 if (!fData) return AliHLTTPCDigitData();
300 return fData[fBinRowPositionSorted.at(fBin)];
303 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedTime(){
304 // see header file for class documentation
306 if (!fData) return -1;
308 rtime = (int)fData[fBinRowPositionSorted.at(fBin)].fTime;
309 if(fDataBunch.size()>1){
310 fEndTimeBinOfBunch=rtime;
315 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedSignal(){
316 // see header file for class documentation
318 if (!fData) return -1;
320 rsignal = (int)fData[fBinRowPositionSorted.at(fBin)].fCharge;
325 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedPad() const{
326 // see header file for class documentation
328 if (!fData) return -1;
330 rpad = (int)fData[fBinRowPositionSorted.at(fBin)].fPad;
334 int AliHLTTPCDigitReaderUnpacked::GetSortedRow() const {
335 // see header file for class documentation
337 rrow = fRow-AliHLTTPCTransform::GetFirstRow(fPatch);
339 rrow += AliHLTTPCTransform::GetFirstRow(2);
344 bool AliHLTTPCDigitReaderUnpacked::NextChannel()
346 // see header file for class documentation
348 // If the next channel is already confirmed by the next bunch function
349 // or there are more signals (this will only be for the first signal)
351 if(fEndOfDataReached == kTRUE){
354 if(fNextChannelIsAlreadyConfirmed){
355 fNextChannelIsAlreadyConfirmed = kFALSE;
356 fPrevTime=GetSortedTime();
357 fPrevSignal=GetSortedSignal();
358 fPrevPad = GetSortedPad();
359 fPrevRow = GetSortedRow();
361 if(GetAltroBlockHWaddr() == (UInt_t)-1){
363 return NextChannel();
368 else if(NextSignal()) { // there is data
370 if(GetAltroBlockHWaddr() == (UInt_t)-1){
372 return NextChannel();
379 int AliHLTTPCDigitReaderUnpacked::NextBunch()
381 // see header file for class documentation
383 if(fEndOfDataReached == kTRUE || fEndOfChannelReached == kTRUE){
384 // sets fEndOfChannelReached back to false, for the next channel
385 // and returns 0 to tell stop the NextBunch calls for this channel.
386 fEndOfChannelReached=kFALSE;
392 fDigitsVector.clear();
394 //adding the first signal (will always be the leftover from either NextChannel call or previous bunch)
395 fPrevTime=GetSortedTime();
396 fPrevSignal=GetSortedSignal();
397 fPrevPad = GetSortedPad();
398 fPrevRow = GetSortedRow();
399 fDataBunch.push_back(GetSortedSignal());
400 fDigitsVector.push_back(GetSortedDigit());
404 if((fPrevPad == GetSortedPad()) && (fPrevRow == GetSortedRow())){//check if there is a change in channel(new pad or row)
405 if(fPrevTime+1 == GetSortedTime()){//if true means that we have consecutive signals
406 fPrevTime = GetSortedTime();
407 //fDataBunch.insert(fDataBunch.begin(), GetSortedSignal());// add the signal to the beginning of the buffer
408 fDataBunch.push_back(GetSortedSignal());// add the signal to the beginning of the buffer
409 fDigitsVector.push_back(GetSortedDigit());
411 else{//end of bunch but not of channel
416 // end of channel, last bunch will be completed
417 fEndOfChannelReached = kTRUE;
418 // the next channel is already confirmed since the next channel returned true
419 fNextChannelIsAlreadyConfirmed = kTRUE;
424 // end of data, but there is one bunch to be completed.
425 fEndOfDataReached = kTRUE;
430 return fDataBunch.size();
433 int AliHLTTPCDigitReaderUnpacked::GetBunchSize(){
434 // see header file for class documentation
435 return fDataBunch.size();
438 const UInt_t* AliHLTTPCDigitReaderUnpacked::GetSignals()
440 // see header file for class documentation
441 return &fDataBunch[0];
444 const AliHLTTPCDigitData* AliHLTTPCDigitReaderUnpacked::GetBunchDigits()
446 // see header file for class documentation
447 return &fDigitsVector[0];
449 int AliHLTTPCDigitReaderUnpacked::GetRowOffset() const
451 // see header file for class documentation
452 return AliHLTTPCTransform::GetFirstRow(fPatch);