]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCDigitReaderPacked.cxx
removing DigitReaderPacked and DigitReaderDecoder, all raw data processing goes via...
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCDigitReaderPacked.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   AliHLTTPCDigitReaderPacked.cxx
22     @author Timm Steinbeck, Jochen Thaeder, Matthias Richter, Kenneth Aamodt
23     @date   
24     @brief  A digit reader implementation for raw data, using the offline
25             AliAltroRawStream/AliTPCRawStream.
26 */
27
28 #if __GNUC__>= 3
29 using namespace std;
30 #endif
31
32 #include "AliHLTTPCDigitReaderPacked.h"
33
34 #include "AliTPCRawStream.h"
35 #include "AliRawReaderMemory.h"
36 #include "AliRawDataHeader.h"
37
38 #include "AliHLTTPCTransform.h"
39 #include "AliHLTStdIncludes.h"
40
41 ClassImp(AliHLTTPCDigitReaderPacked)
42
43 AliHLTTPCDigitReaderPacked::AliHLTTPCDigitReaderPacked()
44   :
45   fTPCRawStream(NULL),
46   fCurrentRow(0),
47   fCurrentPad(0),
48   fCurrentBin(-1),
49   fRowOffset(0),
50   fNRows(0),
51   fNPads(0),
52   fData(NULL),
53   fUnsorted(kFALSE),
54   fDataBunch(),
55   fCurrentChannel(-1),
56   fbHaveData(false),
57   fCurrentPatch(0)
58 {
59   // see header file for class documentation
60   // or
61   // refer to README to build package
62   // or
63   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
64
65
66   // Matthias Sep 2008: the pad sorting functionality needs a deep
67   // revision of the code
68   // I just stumbled over a few awkward implementation
69   // - each instance allocates the buffer for sorted data, this is
70   //   approx. 8 MByte each
71   // - each instance loops to extract the buffer size
72   // - the AliTPCRawStream reads the Altro mapping for each instance
73   //
74   // There is now an instance handling of the buffer and the buffer size
75   // is only calculated once The sorting of pads is going to be a common
76   // functionality of the DigitReader base class in the future.
77   //
78   // Same applies to the instance of the AliRawReaderMemory and
79   // AliTPCRawStream. Since processing of multiple instances is always
80   // sequential, one instance can be used for all readers.
81
82   // get max number of rows
83   if (fNMaxRows<0) {
84   for (Int_t ii=0; ii < 6; ii++)
85       if (AliHLTTPCTransform::GetNRows(ii) > fNMaxRows) 
86           fNMaxRows = AliHLTTPCTransform::GetNRows(ii);
87   }
88
89   // get max number of pads
90   if (fNMaxPads<0) {
91   for (Int_t ii=0; ii < AliHLTTPCTransform::GetNRows();ii++ )
92       if (AliHLTTPCTransform::GetNPads(ii) > fNMaxPads) 
93           fNMaxPads = AliHLTTPCTransform::GetNPads(ii);
94   }
95
96   // get max number of bins
97   if (fNTimeBins<0) {
98   fNTimeBins = AliHLTTPCTransform::GetNTimeBins();
99   }
100
101   fgObjectCount++;
102 }
103
104 Int_t AliHLTTPCDigitReaderPacked::fNMaxRows=-1;
105 Int_t AliHLTTPCDigitReaderPacked::fNMaxPads=-1;
106 Int_t AliHLTTPCDigitReaderPacked::fNTimeBins=-1;
107 Int_t* AliHLTTPCDigitReaderPacked::fgpFreeBufferInstance=NULL;
108 Int_t* AliHLTTPCDigitReaderPacked::fgpIssuedBufferInstance=NULL;
109 AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* AliHLTTPCDigitReaderPacked::fgpFreeStreamInstance=NULL;
110 AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* AliHLTTPCDigitReaderPacked::fgpIssuedStreamInstance=NULL;
111 Int_t AliHLTTPCDigitReaderPacked::fgObjectCount=0;
112
113 AliHLTTPCDigitReaderPacked::~AliHLTTPCDigitReaderPacked()
114 {
115   // see header file for class documentation
116   if (fData) ReleaseBufferInstance(fData);
117   fData=NULL;
118
119   if (fTPCRawStream) ReleaseRawStreamInstance(fTPCRawStream);
120   fTPCRawStream=NULL;
121
122   if (--fgObjectCount==0) {
123     if (fgpFreeBufferInstance) delete fgpFreeBufferInstance;
124     fgpFreeBufferInstance=NULL;
125     if (fgpIssuedBufferInstance) delete fgpIssuedBufferInstance;
126     fgpIssuedBufferInstance=NULL;
127     if (fgpFreeStreamInstance) delete fgpFreeStreamInstance;
128     fgpFreeStreamInstance=NULL;
129     if (fgpIssuedStreamInstance) delete fgpIssuedStreamInstance;
130     fgpIssuedStreamInstance=NULL;
131   }
132 }
133
134 Int_t AliHLTTPCDigitReaderPacked::InitBlock(void* ptr,ULong_t size, Int_t patch, Int_t slice)
135 {
136   // see header file for class documentation
137   fTPCRawStream=GetRawStreamInstance();
138   if (!fTPCRawStream) return -ENODEV;
139
140   fCurrentPatch=patch;
141   
142   //get DDL ID in order to tell the memory reader which slice/patch to use
143   Int_t DDLid= 0;
144   if (patch < 2)
145     DDLid = 768 + 2*slice + patch;
146   else 
147     DDLid = 840 + 4*slice + patch-2;
148
149   fTPCRawStream->SetMemory(DDLid, reinterpret_cast<UChar_t*>( ptr ), size );
150
151   // fCurrentRow always is the row number within a partition, whereas the TPCRawStream
152   // counts rows within the inner and outer sector, i.e. 0 to 62 for the inner and
153   // 63 to 158 for the outer sector
154   // fRowOffset is the offset of the first row of the current partition with respect
155   // to inner or outer sector.
156   fCurrentRow = 0;
157   fCurrentPad = 0;
158   fCurrentBin = -1;
159
160   Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch);
161   Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch);
162   fNRows = lastrow - firstrow + 1;
163   for (Int_t ii=firstrow; ii <= lastrow;ii++ ) {
164     if (AliHLTTPCTransform::GetNPads(ii) > fNPads) 
165       fNPads = AliHLTTPCTransform::GetNPads(ii);
166   }
167
168   Int_t offset=0;
169   if (patch > 1) offset =  AliHLTTPCTransform::GetFirstRow( 2 );
170
171   fRowOffset = firstrow - offset;
172   firstrow -= offset;
173   lastrow  -= offset;
174
175   fbHaveData=false;
176
177   if(!fUnsorted){
178
179   // get the global instance of the array
180   fData=GetBufferInstance();
181   if (!fData) return -ENOMEM;
182
183   // Init array with -1
184   memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) );
185
186   // read data and fill in array
187   while( fTPCRawStream->Next()){
188
189       Int_t row = fTPCRawStream->GetRow();
190       Int_t pad = fTPCRawStream->GetPad();
191       Int_t bin = fTPCRawStream->GetTime();
192
193       if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins){
194         HLTFatal("Index out of Range Probably wrong patch! %d - %d", slice, patch);
195         if ( row < firstrow || row > lastrow ) 
196           HLTFatal("Row out of Range %d < %d < %d",firstrow, row, lastrow);
197         if ( pad > AliHLTTPCTransform::GetNPads(row + offset) ) 
198           HLTFatal("Pad out of Range %d < %d < %d",pad, AliHLTTPCTransform::GetNPads(row + offset));
199         if ( bin > fNTimeBins )
200           HLTFatal("Bin out of Range %d < %d < %d",bin, fNTimeBins);
201       }
202       else {  
203           if ((row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
204               HLTFatal("Index out of array range PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
205               continue;
206           }
207           else {
208               fData[ (row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin ] = fTPCRawStream->GetSignal() ;
209           }
210       }
211   }
212   }
213   return 0;
214 }
215
216 int AliHLTTPCDigitReaderPacked::Reset()
217 {
218   // see header file for class documentation
219   if (fData) ReleaseBufferInstance(fData);
220   fData=NULL;
221   if (fTPCRawStream) ReleaseRawStreamInstance(fTPCRawStream);
222   fTPCRawStream=NULL;
223   return 0;
224 }
225
226 Bool_t AliHLTTPCDigitReaderPacked::NextSignal()
227 {
228   // see header file for class documentation
229   Bool_t readvalue = kTRUE;
230
231   if(!fUnsorted) {
232     if (!fData) return false;
233     while (1) {
234       fCurrentBin++;
235       if (fCurrentBin >= fNTimeBins){
236           fCurrentBin = 0;
237           fCurrentPad++;
238      
239           if (fCurrentPad >=fNPads){
240               fCurrentPad = 0;
241               fCurrentRow++;
242               
243               if (fCurrentRow >= fNRows){
244                   readvalue = kFALSE;
245                   break;
246               }
247           }
248       }
249
250       if (fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
251           HLTFatal("Overflow: row=%d pad=%d bin=%d", fCurrentRow, fCurrentPad, fCurrentBin);
252           readvalue = kFALSE;
253           break;
254       }
255
256       if (fData[ fCurrentRow*fNMaxPads*fNTimeBins + fCurrentPad*fNTimeBins + fCurrentBin  ] != -1) break;
257     }
258   } else{
259     if ((readvalue = fTPCRawStream->Next())) {
260       fCurrentBin=fTPCRawStream->GetTime();
261     }
262   }
263
264   fbHaveData=readvalue;
265   return readvalue;
266 }
267
268 Int_t AliHLTTPCDigitReaderPacked::GetRow()
269 {
270   // see header file for class documentation
271   if(!fUnsorted){
272   return (fCurrentRow + fRowOffset);
273   }
274   else{
275     return (Int_t) fTPCRawStream->GetRow()-fRowOffset;
276   }
277 }
278
279 int AliHLTTPCDigitReaderPacked::GetPad()
280 {
281   // see header file for class documentation
282   if(!fUnsorted){
283     return fCurrentPad;
284   }
285   else{
286     return fTPCRawStream->GetPad();
287   }
288 }
289
290 AliHLTUInt32_t AliHLTTPCDigitReaderPacked::GetAltroBlockHWaddr() const
291 {
292   // see header file for class documentation
293   return fTPCRawStream->GetHWAddress();
294 }
295
296 int AliHLTTPCDigitReaderPacked::GetRCUTrailerSize()
297 {
298   // see header file for class documentation
299   if(fTPCRawStream){
300     return fTPCRawStream->GetRCUTrailerSize();
301   }
302   return 0;
303 }
304
305 bool AliHLTTPCDigitReaderPacked::GetRCUTrailerData(UChar_t*& trData)
306 {
307   // see header file for class documentation
308   if(fTPCRawStream){
309     return fTPCRawStream->GetRCUTrailerData(trData);
310   }
311   return false;
312 }
313
314 Int_t AliHLTTPCDigitReaderPacked::GetSignal()
315
316   // see header file for class documentation
317   if(!fUnsorted){
318     // check for validity of fData is in NextSignal, no check at here
319     return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
320   }
321   else{
322     return fTPCRawStream->GetSignal();
323   }
324 }
325
326 Int_t AliHLTTPCDigitReaderPacked::GetTime()
327 {
328   // see header file for class documentation
329   return fCurrentBin;
330 }
331
332 Int_t AliHLTTPCDigitReaderPacked::GetTimeOfUnsortedSignal(){
333   return fTPCRawStream->GetTime();
334 }
335
336 bool AliHLTTPCDigitReaderPacked::NextChannel()
337 {
338   // see header file for class documentation
339
340   // return true if a channel is available. This is true if
341   // 1. the current row position >=0 : a signal has already been read in the stream
342   //    but it was not part of the previous bunch
343   // 2. the current row position <0 : this is the first invocation at all, read
344   //    signal and send result according to the availability
345   if(fbHaveData || // data available from the last NextSignal call?
346      NextSignal()) { // there is data
347     fCurrentChannel=GetAltroBlockHWaddr();
348     return true;
349   }
350   return false;
351 }
352
353 int AliHLTTPCDigitReaderPacked::NextBunch()
354 {  
355   // see header file for class documentation
356   if (fCurrentChannel<0) return 0;
357
358   fDataBunch.clear();
359   //adding the first signal (will always be the leftover from either NextChannel call or Previous bunch)
360   fDataBunch.push_back(GetSignal());
361
362   Int_t prevTime=GetTimeOfUnsortedSignal();
363   do{
364     if(NextSignal()){
365       if((int)GetAltroBlockHWaddr()==fCurrentChannel){//check if there is a change in channel(new row and pad)
366         if(prevTime==GetTimeOfUnsortedSignal()+1){//if true means that we have consecutive signals
367           prevTime=GetTimeOfUnsortedSignal();
368           fDataBunch.insert(fDataBunch.begin(), GetSignal());
369         }
370         else{//end of bunch but not of channel
371           break;
372         }
373       }
374       else{
375         fCurrentChannel=-1;
376         break;
377       }
378     }
379     else{
380       // end of data, but there is one bunch to be completed
381       fCurrentChannel=-1;
382       break;
383     }
384   }while(1);
385
386   fCurrentBin=prevTime;
387   return fDataBunch.size();
388
389 }
390
391 int AliHLTTPCDigitReaderPacked::GetBunchSize(){
392   // see header file for class documentation
393   return fDataBunch.size();
394 }
395
396 const UInt_t* AliHLTTPCDigitReaderPacked::GetSignals()
397 {
398   // see header file for class documentation
399   return &fDataBunch[0];
400 }
401
402 Int_t* AliHLTTPCDigitReaderPacked::GetBufferInstance()
403 {
404   // see header file for class documentation
405
406   // for the moment only a singleton of the buffer is foreseen
407   // could be extended but very unlikly to be worth the effort
408   // because pad sorting is just a debug feature.
409
410   // This is just a poor man's solution, no synchronization for the
411   // moment
412   AliHLTLogging log;
413   if (fgpIssuedBufferInstance) {
414     log.LoggingVarargs(kHLTLogError, "AliHLTTPCDigitReaderPacked", "GetBufferInstance" , __FILE__ , __LINE__ ,
415                        "instance of sorted buffer has not been released or multiple instances requested. Only available as global singleton for DigitReaderPacked");
416     return NULL;
417   }
418
419   if (!fgpFreeBufferInstance) {
420     if (fNMaxRows<0 || fNMaxPads<0 || fNTimeBins<0) {
421       log.LoggingVarargs(kHLTLogError, "AliHLTTPCDigitReaderPacked", "GetBufferInstance" , __FILE__ , __LINE__ ,
422                          "can not determine size of buffer for sorted data");
423       return NULL;
424     }
425     fgpFreeBufferInstance=new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ];
426     log.LoggingVarargs(kHLTLogDebug, "AliHLTTPCDigitReaderPacked", "GetBufferInstance" , __FILE__ , __LINE__ , 
427                        "Array Borders  ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d", 
428                        fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
429   }
430
431   fgpIssuedBufferInstance=fgpFreeBufferInstance;
432   fgpFreeBufferInstance=NULL;
433   return fgpIssuedBufferInstance;
434 }
435
436 void AliHLTTPCDigitReaderPacked::ReleaseBufferInstance(Int_t* pInstance)
437 {
438   // see header file for class documentation
439   if (!pInstance) return;
440   if (pInstance!=fgpIssuedBufferInstance) {
441     AliHLTLogging log;
442     log.LoggingVarargs(kHLTLogError, "AliHLTTPCDigitReaderPacked", "ReleaseBufferInstance" , __FILE__ , __LINE__ ,
443                        "wrong instance %p, expecting %p", pInstance, fgpIssuedBufferInstance);
444     return;
445   }
446   fgpFreeBufferInstance=fgpIssuedBufferInstance;
447   fgpIssuedBufferInstance=NULL;
448 }
449
450 AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* AliHLTTPCDigitReaderPacked::GetRawStreamInstance()
451 {
452   // see header file for class documentation
453   if (fgpIssuedStreamInstance) {
454     HLTError("instance of TPCRawStream has not been released or multiple instances requested. Only available as global singleton for DigitReaderPacked");
455     return NULL;
456   }
457
458   if (!fgpFreeStreamInstance) {
459     fgpFreeStreamInstance=new AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream;
460   }
461
462   fgpIssuedStreamInstance=fgpFreeStreamInstance;
463   fgpFreeStreamInstance=NULL;
464   return fgpIssuedStreamInstance;
465 }
466
467 void AliHLTTPCDigitReaderPacked::ReleaseRawStreamInstance(AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* pInstance)
468 {
469   // see header file for class documentation
470   if (!pInstance) return;
471   if (pInstance!=fgpIssuedStreamInstance) {
472     HLTError("wrong instance %p, expecting %p", pInstance, fgpIssuedStreamInstance);
473     return;
474   }
475   fgpFreeStreamInstance=fgpIssuedStreamInstance;
476   fgpIssuedStreamInstance=NULL;
477 }
478
479 AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::AliHLTTPCRawStream()
480   :
481   fRawMemoryReader(new AliRawReaderMemory),
482   fTPCRawStream(new AliTPCRawStream(fRawMemoryReader))
483 {
484   // see header file for class documentation
485 }
486
487 AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::~AliHLTTPCRawStream()
488 {
489   // see header file for class documentation
490   if (fRawMemoryReader) delete fRawMemoryReader;
491   fRawMemoryReader=NULL;
492   if (fTPCRawStream) delete fTPCRawStream;
493   fTPCRawStream=NULL;
494 }
495
496 Bool_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::SetMemory(Int_t ddlId, UChar_t* memory, ULong_t size )
497 {
498   // see header file for class documentation
499   if (!fRawMemoryReader) return false;
500   Bool_t result=fRawMemoryReader->SetMemory(memory, size );
501   fRawMemoryReader->SetEquipmentID(ddlId);
502   fRawMemoryReader->RewindEvents();
503   fRawMemoryReader->NextEvent();
504   return result;
505 }
506
507 bool AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::Next()
508 {
509   // see header file for class documentation
510   if (!fTPCRawStream) return -1;
511   return fTPCRawStream->Next();
512 }
513
514 Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetRow() const
515 {
516   // see header file for class documentation
517   if (!fTPCRawStream) return -1;
518   return fTPCRawStream->GetRow();
519 }
520
521 Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetPad() const
522 {
523   // see header file for class documentation
524   if (!fTPCRawStream) return -1;
525   return fTPCRawStream->GetPad();
526 }
527
528 Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetTime() const
529 {
530   // see header file for class documentation
531   if (!fTPCRawStream) return -1;
532   return fTPCRawStream->GetTime();
533 }
534
535 Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetSignal() const
536 {
537   // see header file for class documentation
538   if (!fTPCRawStream) return -1;
539   return fTPCRawStream->GetSignal();
540 }
541
542 Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetHWAddress() const
543 {
544   // see header file for class documentation
545   if (!fTPCRawStream) return -1;
546   return fTPCRawStream->GetHWAddress();
547 }
548
549 Bool_t  AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetRCUTrailerData(UChar_t*& data) const
550 {
551   // see header file for class documentation
552   if (!fTPCRawStream) return -1;
553   return fTPCRawStream->GetRCUTrailerData(data);
554 }
555
556 Int_t   AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetRCUTrailerSize() const
557 {
558   // see header file for class documentation
559   if (!fTPCRawStream) return -1;
560   return fTPCRawStream->GetRCUTrailerSize();
561 }