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.
28 #include "AliHLTTPCDigitReaderUnpacked.h"
29 #include "AliHLTTPCDigitData.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTStdIncludes.h"
32 #include "AliHLTTPCMapping.h"
36 ClassImp(AliHLTTPCDigitReaderUnpacked)
38 AliHLTTPCDigitReaderUnpacked::AliHLTTPCDigitReaderUnpacked()
53 fEndOfDataReached(kFALSE),
54 fEndOfChannelReached(kFALSE),
56 fEndTimeBinOfBunch(0),
60 fNextChannelIsAlreadyConfirmed(kFALSE),
63 fBinRowPositionSorted(),
66 // see header file for class documentation
68 // refer to README to build package
70 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
73 AliHLTTPCDigitReaderUnpacked::~AliHLTTPCDigitReaderUnpacked(){
74 // see header file for class documentation
81 int AliHLTTPCDigitReaderUnpacked::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
82 // see header file for class documentation
84 AliHLTTPCUnpackedRawData *tmpptr=NULL;
89 fEndOfDataReached=kFALSE;
90 fEndOfChannelReached=kFALSE;
96 fNextChannelIsAlreadyConfirmed=kFALSE;
97 fDigitsVector.clear();
99 tmpptr = reinterpret_cast<AliHLTTPCUnpackedRawData*>(fPtr);
100 fDigitRowData = (AliHLTTPCDigitRowData*) tmpptr->fDigits;
101 fActRowData = fDigitRowData;
104 fMapping = new AliHLTTPCMapping(patch);
107 while (fActRowData && ((iResult=GetNextRowData(fActRowData))>=0)) {/* empty body */};
110 fActRowData = fDigitRowData;
114 AliHLTTPCTransform::Slice2Sector(slice, AliHLTTPCTransform::GetFirstRow(patch), dummy, fFirstRow);
115 AliHLTTPCTransform::Slice2Sector(slice, AliHLTTPCTransform::GetLastRow(patch), dummy, fLastRow);
119 if ((Int_t)fActRowData->fRow != fRow){
120 HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
128 int AliHLTTPCDigitReaderUnpacked::GetNextRowData(AliHLTTPCDigitRowData*& pRow) const
130 // get new row data from the current row data
132 AliHLTTPCDigitRowData* pCurrent=pRow;
135 if (!pCurrent) return -EINVAL;
136 Byte_t *tmp = (Byte_t*) pCurrent;
137 Int_t size = sizeof(AliHLTTPCDigitRowData) + pCurrent->fNDigit*sizeof(AliHLTTPCDigitData);
139 pRow = reinterpret_cast<AliHLTTPCDigitRowData*>(tmp);
141 // check if the new pointer is within the range
142 if (((Byte_t*)fPtr) + fSize <= tmp){
143 if (((Byte_t*)fPtr) + fSize < tmp) {
144 // if the increment does not match exactly there is a format error
145 HLTError("input format not recognized: buffer %p %d, current row data %p, %d digits", fPtr, fSize, pCurrent, pCurrent->fNDigit);
150 // check if the current row structure has the right format
151 size = sizeof(AliHLTTPCDigitRowData) + pRow->fNDigit*sizeof(AliHLTTPCDigitData);
153 if (((Byte_t*)fPtr) + fSize < tmp){
154 HLTError("Current row data not recognized %p (buffer %p %d) %d digits", pRow, fPtr, fSize, pRow->fNDigit);
162 void AliHLTTPCDigitReaderUnpacked::SortBunchBinVector(){
163 fBinRowPositionSorted.clear();
165 fBinRowPositionSorted.push_back(0);
167 Int_t beginningOfPadIndex=0;
169 for(Int_t i=1;i<(Int_t)fActRowData->fNDigit;i++){
170 if(fData[i-1].fPad == fData[i].fPad){// means that these sinals belong to the same pad
171 if(fData[i-1].fTime+1 == fData[i].fTime){ //means that the signal belong to the same bunch
174 fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex+nAdded,i);
176 else{//we have a new bunch on this pad, put it in fornt of the previous bunch
179 fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex,i);
184 beginningOfPadIndex=totalAdded;
185 fBinRowPositionSorted.push_back(i);
191 bool AliHLTTPCDigitReaderUnpacked::NextSignal(){
192 // see header file for class documentation
193 if (fActRowData==NULL) return false;
195 bool rreadvalue = true;
199 while ( fBin >= (Int_t)fActRowData->fNDigit ){
201 if ((fRow >= fFirstRow) && (fRow <= fLastRow)){
204 if (GetNextRowData(fActRowData)<0) {
217 if ((Int_t)fActRowData->fRow != fRow){
218 HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
222 fData = fActRowData->fDigitData;
225 SortBunchBinVector();
229 fPrevPad = GetSortedPad();
235 int AliHLTTPCDigitReaderUnpacked::GetRow(){
236 // see header file for class documentation
239 if(fUnsorted == kFALSE){
243 rrow = fRow-AliHLTTPCTransform::GetFirstRow(fPatch);
245 rrow += AliHLTTPCTransform::GetFirstRow(2);
252 int AliHLTTPCDigitReaderUnpacked::GetPad(){
253 // see header file for class documentation
255 if(fUnsorted == kFALSE){
256 rpad = GetSortedPad();
264 int AliHLTTPCDigitReaderUnpacked::GetSignal(){
265 // see header file for class documentation
267 if(fUnsorted == kFALSE){
268 rsignal = GetSortedSignal();
271 rsignal = fPrevSignal;
276 int AliHLTTPCDigitReaderUnpacked::GetTime(){
277 // see header file for class documentation
279 if(fUnsorted==kFALSE){
280 rtime = GetSortedTime();
283 rtime = fPrevTime+1-fDataBunch.size();
288 AliHLTUInt32_t AliHLTTPCDigitReaderUnpacked::GetAltroBlockHWaddr() const
290 // see header file for class documentation
291 return (AliHLTUInt32_t)(fMapping->GetHwAddress((UInt_t)GetSortedRow(),(UInt_t)GetSortedPad()));//fTPCRawStream->GetHWAddress();
294 AliHLTTPCDigitData AliHLTTPCDigitReaderUnpacked::GetSortedDigit(){
295 // see header file for class documentation
297 if (!fData) return AliHLTTPCDigitData();
298 return fData[fBinRowPositionSorted.at(fBin)];
301 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedTime(){
302 // see header file for class documentation
304 if (!fData) return -1;
306 rtime = (int)fData[fBinRowPositionSorted.at(fBin)].fTime;
307 if(fDataBunch.size()>1){
308 fEndTimeBinOfBunch=rtime;
313 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedSignal(){
314 // see header file for class documentation
316 if (!fData) return -1;
318 rsignal = (int)fData[fBinRowPositionSorted.at(fBin)].fCharge;
323 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedPad() const{
324 // see header file for class documentation
326 if (!fData) return -1;
328 rpad = (int)fData[fBinRowPositionSorted.at(fBin)].fPad;
332 int AliHLTTPCDigitReaderUnpacked::GetSortedRow() const {
333 // see header file for class documentation
335 rrow = fRow-AliHLTTPCTransform::GetFirstRow(fPatch);
337 rrow += AliHLTTPCTransform::GetFirstRow(2);
342 bool AliHLTTPCDigitReaderUnpacked::NextChannel()
344 // see header file for class documentation
346 // If the next channel is already confirmed by the next bunch function
347 // or there are more signals (this will only be for the first signal)
349 if(fEndOfDataReached == kTRUE){
352 if(fNextChannelIsAlreadyConfirmed){
353 fNextChannelIsAlreadyConfirmed = kFALSE;
354 fPrevTime=GetSortedTime();
355 fPrevSignal=GetSortedSignal();
356 fPrevPad = GetSortedPad();
357 fPrevRow = GetSortedRow();
359 if(GetAltroBlockHWaddr() == (UInt_t)-1){
361 return NextChannel();
366 else if(NextSignal()) { // there is data
368 if(GetAltroBlockHWaddr() == (UInt_t)-1){
370 return NextChannel();
377 int AliHLTTPCDigitReaderUnpacked::NextBunch()
379 // see header file for class documentation
381 if(fEndOfDataReached == kTRUE || fEndOfChannelReached == kTRUE){
382 // sets fEndOfChannelReached back to false, for the next channel
383 // and returns 0 to tell stop the NextBunch calls for this channel.
384 fEndOfChannelReached=kFALSE;
390 fDigitsVector.clear();
392 //adding the first signal (will always be the leftover from either NextChannel call or previous bunch)
393 fPrevTime=GetSortedTime();
394 fPrevSignal=GetSortedSignal();
395 fPrevPad = GetSortedPad();
396 fPrevRow = GetSortedRow();
397 fDataBunch.push_back(GetSortedSignal());
398 fDigitsVector.push_back(GetSortedDigit());
402 if((fPrevPad == GetSortedPad()) && (fPrevRow == GetSortedRow())){//check if there is a change in channel(new pad or row)
403 if(fPrevTime+1 == GetSortedTime()){//if true means that we have consecutive signals
404 fPrevTime = GetSortedTime();
405 //fDataBunch.insert(fDataBunch.begin(), GetSortedSignal());// add the signal to the beginning of the buffer
406 fDataBunch.push_back(GetSortedSignal());// add the signal to the beginning of the buffer
407 fDigitsVector.push_back(GetSortedDigit());
409 else{//end of bunch but not of channel
414 // end of channel, last bunch will be completed
415 fEndOfChannelReached = kTRUE;
416 // the next channel is already confirmed since the next channel returned true
417 fNextChannelIsAlreadyConfirmed = kTRUE;
422 // end of data, but there is one bunch to be completed.
423 fEndOfDataReached = kTRUE;
428 return fDataBunch.size();
431 int AliHLTTPCDigitReaderUnpacked::GetBunchSize(){
432 // see header file for class documentation
433 return fDataBunch.size();
436 const UInt_t* AliHLTTPCDigitReaderUnpacked::GetSignals()
438 // see header file for class documentation
439 return &fDataBunch[0];
442 const AliHLTTPCDigitData* AliHLTTPCDigitReaderUnpacked::GetBunchDigits()
444 // see header file for class documentation
445 return &fDigitsVector[0];
447 int AliHLTTPCDigitReaderUnpacked::GetRowOffset() const
449 // see header file for class documentation
450 return AliHLTTPCTransform::GetFirstRow(fPatch);