added AliFlatExternalTrackParam to HLT global library
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCDigitReaderUnpacked.cxx
1 // $Id$
2
3 //*************************************************************************
4 // This file is property of and copyright by the ALICE HLT Project        * 
5 // ALICE Experiment at CERN, All rights reserved.                         *
6 //                                                                        *
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.                            *
11 //                                                                        *
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 //*************************************************************************/
20
21 /** @file   AliHLTTPCDigitReaderUnpacked.cxx
22     @author Timm Steinbeck, Jochen Thaeder, Matthias Richter
23     @date   
24     @brief  A digit reader implementation for unpacked TPC data.
25 */
26
27 #include <cassert>
28 #include "AliHLTTPCDigitReaderUnpacked.h"
29 #include "AliHLTTPCDigitData.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTStdIncludes.h"
32 #include "AliHLTTPCMapping.h"
33
34 using namespace std;
35
36 ClassImp(AliHLTTPCDigitReaderUnpacked)
37
38 AliHLTTPCDigitReaderUnpacked::AliHLTTPCDigitReaderUnpacked()
39   :
40   fDigitRowData(NULL),
41   fActRowData(NULL),
42   fData(NULL),
43   fPtr(NULL),
44   fSize(0),
45   fBin(0),
46   fRow(0),
47   fFirstRow(0),
48   fLastRow(0),
49   fUnsorted(kFALSE),
50   fDataBunch(),
51   fTrackIDs(),
52   fTrackIDCounts(),
53   fEndOfDataReached(kFALSE),
54   fEndOfChannelReached(kFALSE),
55   fPrevTime(0),
56   fEndTimeBinOfBunch(0),
57   fPrevSignal(0),
58   fPrevPad(-1),
59   fPrevRow(-1),
60   fNextChannelIsAlreadyConfirmed(kFALSE),
61   fMapping(NULL),
62   fDigitsVector(),
63   fBinRowPositionSorted(),
64   fPatch(0)
65 {
66   // see header file for class documentation
67   // or
68   // refer to README to build package
69   // or
70   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
71 }
72
73 AliHLTTPCDigitReaderUnpacked::~AliHLTTPCDigitReaderUnpacked(){
74   // see header file for class documentation
75   if(fMapping){
76     delete fMapping;
77   }
78   fMapping=NULL;
79 }
80
81 int AliHLTTPCDigitReaderUnpacked::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
82   // see header file for class documentation
83   int iResult=0;
84   AliHLTTPCUnpackedRawData *tmpptr=NULL;
85   fPtr = ptr;
86   fSize = size;
87
88   fPatch=patch;
89   fEndOfDataReached=kFALSE;
90   fEndOfChannelReached=kFALSE;
91   fPrevTime=0;
92   fEndTimeBinOfBunch=0;
93   fPrevSignal=0;
94   fPrevPad=-1;
95   fPrevRow=-1;
96   fNextChannelIsAlreadyConfirmed=kFALSE;
97   fDigitsVector.clear();
98
99   tmpptr = reinterpret_cast<AliHLTTPCUnpackedRawData*>(fPtr);
100   fDigitRowData = (AliHLTTPCDigitRowData*) tmpptr->fDigits;
101   fActRowData = fDigitRowData;
102
103   if(!fMapping){
104     fMapping = new AliHLTTPCMapping(patch);
105   }
106
107   while (fActRowData && ((iResult=GetNextRowData(fActRowData))>=0)) {/* empty body */};
108
109   if (iResult>=0) {
110   fActRowData = fDigitRowData;
111   fBin = -1;
112
113   int dummy=0;
114   AliHLTTPCTransform::Slice2Sector(slice, AliHLTTPCTransform::GetFirstRow(patch), dummy, fFirstRow);
115   AliHLTTPCTransform::Slice2Sector(slice, AliHLTTPCTransform::GetLastRow(patch), dummy, fLastRow);
116
117   fRow = fFirstRow; 
118
119   if ((Int_t)fActRowData->fRow != fRow){
120       HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
121   }
122   } else {
123     fActRowData=NULL;
124   }
125   return iResult;
126 }
127
128 int AliHLTTPCDigitReaderUnpacked::GetNextRowData(AliHLTTPCDigitRowData*& pRow) const
129 {
130   // get new row data from the current row data
131   int iResult=0;
132   AliHLTTPCDigitRowData* pCurrent=pRow;
133   assert(pCurrent);
134   pRow=NULL;
135   if (!pCurrent) return -EINVAL;
136   Byte_t *tmp = (Byte_t*) pCurrent;
137   Int_t size = sizeof(AliHLTTPCDigitRowData) + pCurrent->fNDigit*sizeof(AliHLTTPCDigitData);
138   tmp += size;
139   pRow = reinterpret_cast<AliHLTTPCDigitRowData*>(tmp);
140   
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);
146       iResult=-EBADF;
147     }
148     pRow=NULL;
149   } else {
150     // check if the current row structure has the right format
151     size = sizeof(AliHLTTPCDigitRowData) + pRow->fNDigit*sizeof(AliHLTTPCDigitData);
152     tmp += size;
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);
155       pRow=NULL;
156       iResult=-EBADF;
157     }
158   }
159     
160   return iResult;
161 }
162 void AliHLTTPCDigitReaderUnpacked::SortBunchBinVector(){
163   fBinRowPositionSorted.clear();
164
165   fBinRowPositionSorted.push_back(0);
166   Int_t nAdded=0;
167   Int_t beginningOfPadIndex=0;
168   Int_t totalAdded=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
172         nAdded++;
173         totalAdded++;
174         fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex+nAdded,i);
175       }
176       else{//we have a new bunch on this pad, put it in fornt of the previous bunch
177         totalAdded++;
178         nAdded=0;
179         fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex,i);
180       }
181     }
182     else{
183       totalAdded++;
184       beginningOfPadIndex=totalAdded;
185       fBinRowPositionSorted.push_back(i);
186       nAdded=0;
187     }
188   }
189 }
190
191 bool AliHLTTPCDigitReaderUnpacked::NextSignal(){
192   // see header file for class documentation
193   if (fActRowData==NULL) return false;
194
195   bool rreadvalue = true;
196
197   fBin++;
198
199   while ( fBin >= (Int_t)fActRowData->fNDigit ){
200     fRow++;
201     if ((fRow >= fFirstRow) && (fRow <= fLastRow)){
202       
203       //new row 
204       if (GetNextRowData(fActRowData)<0) {
205         rreadvalue = false;
206         return rreadvalue;
207       }
208       fBin = 0;
209     }
210     else {
211       rreadvalue = false;
212       return rreadvalue;
213     }
214     if(!fActRowData){
215       return false;
216     }
217     if ((Int_t)fActRowData->fRow != fRow){
218       HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
219     }
220   }
221   
222   fData = fActRowData->fDigitData;
223
224   if(fBin==0){
225     SortBunchBinVector(); 
226   }
227
228   if(fPrevPad == -1){
229     fPrevPad = GetSortedPad();
230   }
231  
232   return rreadvalue;
233 }
234
235 int AliHLTTPCDigitReaderUnpacked::GetRow(){
236   // see header file for class documentation
237   int rrow;
238
239   if(fUnsorted == kFALSE){
240     rrow = fRow;
241   }
242   else{
243    rrow = fRow-AliHLTTPCTransform::GetFirstRow(fPatch);
244    if(fPatch>1){
245     rrow += AliHLTTPCTransform::GetFirstRow(2);
246    }
247   }
248
249   return rrow;
250 }
251
252 int AliHLTTPCDigitReaderUnpacked::GetPad(){
253   // see header file for class documentation
254   int rpad;
255   if(fUnsorted == kFALSE){
256     rpad = GetSortedPad();
257   }
258   else{
259     rpad = fPrevPad;
260   }
261   return rpad   ;
262 }
263
264 int AliHLTTPCDigitReaderUnpacked::GetSignal(){ 
265   // see header file for class documentation
266   int rsignal;
267   if(fUnsorted == kFALSE){
268     rsignal = GetSortedSignal();
269   }
270   else{
271     rsignal = fPrevSignal;
272   }
273   return rsignal;
274 }
275
276 int AliHLTTPCDigitReaderUnpacked::GetTime(){
277   // see header file for class documentation
278   int rtime;
279   if(fUnsorted==kFALSE){
280     rtime = GetSortedTime();
281   }
282   else{
283     rtime = fPrevTime+1-fDataBunch.size();
284   }
285   return rtime;
286 }
287
288 AliHLTUInt32_t AliHLTTPCDigitReaderUnpacked::GetAltroBlockHWaddr() const
289 {
290   // see header file for class documentation
291   return (AliHLTUInt32_t)(fMapping->GetHwAddress((UInt_t)GetSortedRow(),(UInt_t)GetSortedPad()));//fTPCRawStream->GetHWAddress();
292 }
293
294 AliHLTTPCDigitData AliHLTTPCDigitReaderUnpacked::GetSortedDigit(){
295   // see header file for class documentation
296   assert(fData);
297   if (!fData) return AliHLTTPCDigitData();
298   return fData[fBinRowPositionSorted.at(fBin)];
299 }
300
301 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedTime(){
302   // see header file for class documentation
303   assert(fData);
304   if (!fData) return -1;
305   int rtime;
306   rtime = (int)fData[fBinRowPositionSorted.at(fBin)].fTime;
307   if(fDataBunch.size()>1){
308     fEndTimeBinOfBunch=rtime;
309   }
310   return rtime;
311 }
312
313 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedSignal(){
314   // see header file for class documentation
315   assert(fData);
316   if (!fData) return -1;
317   int rsignal;
318   rsignal = (int)fData[fBinRowPositionSorted.at(fBin)].fCharge;
319   return rsignal;
320
321 }
322
323 Int_t AliHLTTPCDigitReaderUnpacked::GetSortedPad() const{
324   // see header file for class documentation
325   assert(fData);
326   if (!fData) return -1;
327   int rpad;
328   rpad = (int)fData[fBinRowPositionSorted.at(fBin)].fPad;
329   return rpad   ;
330 }
331
332 int AliHLTTPCDigitReaderUnpacked::GetSortedRow() const {
333   // see header file for class documentation
334   int rrow;
335   rrow = fRow-AliHLTTPCTransform::GetFirstRow(fPatch);
336   if(fPatch>1){
337     rrow += AliHLTTPCTransform::GetFirstRow(2);
338   }
339   return rrow;
340 }
341
342 bool AliHLTTPCDigitReaderUnpacked::NextChannel()
343 {
344   // see header file for class documentation
345
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)
348   
349   if(fEndOfDataReached == kTRUE){
350     return false;
351   }
352   if(fNextChannelIsAlreadyConfirmed){
353     fNextChannelIsAlreadyConfirmed = kFALSE;
354     fPrevTime=GetSortedTime();
355     fPrevSignal=GetSortedSignal();
356     fPrevPad = GetSortedPad();
357     fPrevRow = GetSortedRow();
358
359     if(GetAltroBlockHWaddr() == (UInt_t)-1){
360       fPrevPad = -1;
361       return NextChannel();
362     }
363
364     return true;
365   }
366   else if(NextSignal()) { // there is data
367
368     if(GetAltroBlockHWaddr() == (UInt_t)-1){
369       fPrevPad = -1;
370       return NextChannel();
371     }
372     return true;
373   }
374   return false;
375 }
376
377 int AliHLTTPCDigitReaderUnpacked::NextBunch()
378 {  
379   // see header file for class documentation
380
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;
385     return 0;
386   }
387
388
389   fDataBunch.clear();
390   fDigitsVector.clear();
391
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());
399
400   do{
401     if(NextSignal()){
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());
408           }
409           else{//end of bunch but not of channel
410             break;
411           }
412         }
413         else{
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;
418           break;
419         }
420     }
421     else{
422       // end of data, but there is one bunch to be completed.
423       fEndOfDataReached = kTRUE;
424       break;
425     }
426   }while(1);
427
428   return fDataBunch.size();
429 }
430
431 int AliHLTTPCDigitReaderUnpacked::GetBunchSize(){
432   // see header file for class documentation
433   return fDataBunch.size();
434 }
435
436 const UInt_t* AliHLTTPCDigitReaderUnpacked::GetSignals()
437 {
438   // see header file for class documentation
439   return &fDataBunch[0];
440 }
441
442 const AliHLTTPCDigitData* AliHLTTPCDigitReaderUnpacked::GetBunchDigits()
443 {
444   // see header file for class documentation
445   return &fDigitsVector[0];
446 }
447 int AliHLTTPCDigitReaderUnpacked::GetRowOffset() const
448 {
449   // see header file for class documentation
450   return AliHLTTPCTransform::GetFirstRow(fPatch);
451 }