]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCZeroSuppressionComponent.cxx
added skeleton for HLTpendolino library
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCZeroSuppressionComponent.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: Kenneth Aamodt <Kenneth.Aamodt@student.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTTPCZeroSuppressionComponent.cxx
20     @author Kenneth Aamodt
21     @date   
22     @brief  The TPC ZeroSuppression component
23 */
24
25 // see header file for class documentation                                   //
26 // or                                                                        //
27 // refer to README to build package                                          //
28 // or                                                                        //
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt                          //
30
31 #if __GNUC__>= 3
32 using namespace std;
33 #endif
34 #include "AliHLTTPCZeroSuppressionComponent.h"
35 #include "AliHLTTPCDigitReaderDecoder.h"
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCDefinitions.h"
38 #include "AliHLTTPCDigitData.h"
39 #include <cstdlib>
40 #include <cerrno>
41 #include "TString.h"
42 #include <sys/time.h>
43 #include "AliHLTAltroEncoder.h"
44 #include "AliRawDataHeader.h"
45
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTTPCZeroSuppressionComponent)
48
49 AliHLTTPCZeroSuppressionComponent::AliHLTTPCZeroSuppressionComponent()
50     :
51     fDigitReader(NULL),
52     fRowPadVector(),
53     fNumberOfPadsInRow(NULL),
54     fNumberOfRows(0),
55     fCurrentPatch(0),
56     fFirstRow(0),
57     fLastRow(0),
58     fStartTimeBin(0),
59     fEndTimeBin(AliHLTTPCTransform::GetNTimeBins()),
60     fNTimeBins(0),
61     fNRMSThreshold(0),
62     fSignalThreshold(0),
63     fMinimumNumberOfSignals(AliHLTTPCTransform::GetNTimeBins()/2),
64     fOldRCUFormat(0),
65     fSortPads(0),
66     fVectorInitialized(kFALSE),
67     fValueBelowAverage(5),
68     fLeftTimeBin(5),
69     fRightTimeBin(5),
70     fGetActivePads(kFALSE),
71     fHwAddressList()
72 {
73   // see header file for class documentation
74   // or
75   // refer to README to build package
76   // or
77   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
78 }
79
80 AliHLTTPCZeroSuppressionComponent::~AliHLTTPCZeroSuppressionComponent()
81 {
82   // see header file for class documentation
83   if(fVectorInitialized){
84     DeInitializePadArray();
85   }
86   if(fNumberOfPadsInRow){
87     delete [] fNumberOfPadsInRow;
88     fNumberOfPadsInRow=NULL;
89   }
90   if(fDigitReader){
91     delete fDigitReader;
92     fDigitReader=NULL;
93   }
94 }
95
96 // Public functions to implement AliHLTComponent's interface.
97 // These functions are required for the registration process
98
99 const char* AliHLTTPCZeroSuppressionComponent::GetComponentID()
100 {
101   // see header file for class documentation
102   return "TPCZeroSuppression";
103 }
104
105 void AliHLTTPCZeroSuppressionComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
106 {
107   // see header file for class documentation
108   list.clear(); 
109   list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
110 }
111
112 AliHLTComponentDataType AliHLTTPCZeroSuppressionComponent::GetOutputDataType()
113 {
114   // see header file for class documentation
115   return kAliHLTMultipleDataType;
116   //return kAliHLTDataTypeDDLRaw;
117   //  return AliHLTTPCDefinitions::fgkUnpackedRawDataType;
118 }
119
120 int AliHLTTPCZeroSuppressionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
121 {
122   // see header file for class documentation
123   tgtList.clear();
124   tgtList.push_back(kAliHLTDataTypeDDLRaw);
125   tgtList.push_back(kAliHLTDataTypeHwAddr16);
126   return tgtList.size();
127 }
128
129 void AliHLTTPCZeroSuppressionComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
130 {
131   // see header file for class documentation
132   constBase=0;
133   inputMultiplier=2.0;
134 }
135
136 AliHLTComponent* AliHLTTPCZeroSuppressionComponent::Spawn()
137 {
138   // see header file for class documentation
139   return new AliHLTTPCZeroSuppressionComponent();
140 }
141         
142 int AliHLTTPCZeroSuppressionComponent::DoInit( int argc, const char** argv )
143 {
144   // see header file for class documentation
145
146   Int_t i = 0;
147   Char_t* cpErr;
148
149   while ( i < argc ) {      
150
151     // -- zero suppression threshold
152     if ( !strcmp( argv[i], "signal-threshold" ) ) {
153       fSignalThreshold = strtoul( argv[i+1], &cpErr ,0);
154       if ( *cpErr ) {
155         HLTError("Cannot convert signal-threshold specifier '%s'.", argv[i+1]);
156         return EINVAL;
157       }
158       i+=2;
159       continue;
160     }
161
162     // -- checking for nsigma-threshold, used in 2007 December run in ZeroSuppression
163     if ( !strcmp( argv[i], "rms-threshold" ) ) {
164       fNRMSThreshold = strtoul( argv[i+1], &cpErr ,0);
165       if ( *cpErr ){
166         HLTError("Cannot convert rms-threshold specifier '%s'. Must be integer", argv[i+1]);
167         return EINVAL;
168       }
169       i+=2;
170       continue;
171     }
172
173     // -- number of timebins
174     if ( !strcmp( argv[i], "ntimebins" ) ) {
175       fNTimeBins = strtoul( argv[i+1], &cpErr ,0);
176       if ( *cpErr ) {
177         HLTError("Cannot convert ntimebins specifier '%s'.", argv[i+1]);
178         return EINVAL;
179       }
180       i+=2;
181       continue;
182     }
183
184     // -- first timebin
185     if ( !strcmp( argv[i], "start-timebin" ) ) {
186       fStartTimeBin = strtoul( argv[i+1], &cpErr ,0);
187       if ( *cpErr ) {
188         HLTError("Cannot convert start-timebin specifier '%s'.", argv[i+1]);
189         return EINVAL;
190       }
191       i+=2;
192       continue;
193     }
194
195     // -- last timebin
196     if ( !strcmp( argv[i], "end-timebin" ) ) {
197       if(strtoul( argv[i+1], &cpErr ,0)<=(UInt_t)AliHLTTPCTransform::GetNTimeBins()){
198         fEndTimeBin = strtoul( argv[i+1], &cpErr ,0);
199       }
200       if ( *cpErr ) {
201         HLTError("Cannot convert end-timebin specifier '%s'.", argv[i+1]);
202         return EINVAL;
203       }
204       i+=2;
205       continue;
206     }
207
208     // -- timebins to keep left of signal
209     if ( !strcmp( argv[i], "timebin-left" ) ) {
210       fLeftTimeBin = strtoul( argv[i+1], &cpErr ,0);
211       if ( *cpErr ) {
212         HLTError("Cannot convert timebin-left specifier '%s'.", argv[i+1]);
213         return EINVAL;
214       }
215       i+=2;
216       continue;
217     }
218
219     // -- timebin to keep right of signal
220     if ( !strcmp( argv[i], "timebin-right" ) ) {
221       fRightTimeBin = strtoul( argv[i+1], &cpErr ,0);
222       if ( *cpErr ) {
223         HLTError("Cannot convert timebin-right specifier '%s'.", argv[i+1]);
224         return EINVAL;
225       }
226       i+=2;
227       continue;
228     }
229
230     // -- value below average to subtract
231     if ( !strcmp( argv[i], "value-below-average" ) ) {
232       fValueBelowAverage = strtoul( argv[i+1], &cpErr ,0);
233       if ( *cpErr ) {
234         HLTError("Cannot convert value-below-average specifier '%s'.", argv[i+1]);
235         return EINVAL;
236       }
237       i+=2;
238       continue;
239     }
240
241     // -- pad occupancy limit
242     if ( !strcmp( argv[i], "occupancy-limit" ) ) {
243       fMinimumNumberOfSignals = strtoul( argv[i+1], &cpErr ,0);
244       if ( *cpErr ) {
245         HLTError("Cannot convert occupancy-limit specifier '%s'.", argv[i+1]);
246         return EINVAL;
247       }
248       i+=2;
249       continue;
250     }
251
252     // -- checking for rcu format
253     if ( !strcmp( argv[i], "oldrcuformat" ) ) {
254       fOldRCUFormat = strtoul( argv[i+1], &cpErr ,0);
255       if ( *cpErr ){
256         HLTError("Cannot convert oldrcuformat specifier '%s'. Should  be 0(off) or 1(on), must be integer", argv[i+1]);
257         return EINVAL;
258       }
259       i+=2;
260       continue;
261     }
262
263     // -- checking for rcu format
264     if ( !strcmp( argv[i], "sort-pads" ) ) {
265       fSortPads = strtoul( argv[i+1], &cpErr ,0);
266       if ( *cpErr ){
267         HLTError("Cannot convert sort-pads specifier '%s'. Should  be 0(off) or 1(on), must be integer", argv[i+1]);
268         return EINVAL;
269       }
270       i+=2;
271       continue;
272     }
273       
274     Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
275     return EINVAL;
276
277   }
278
279   HLTDebug("using AliHLTTPCDigitReaderDecoder");
280   fDigitReader = new AliHLTTPCDigitReaderDecoder();
281
282   fHwAddressList.clear();
283
284   return 0;
285 }
286
287 int AliHLTTPCZeroSuppressionComponent::DoDeinit()
288 {
289   // see header file for class documentation
290   return 0;
291 }
292
293 Int_t AliHLTTPCZeroSuppressionComponent::DeInitializePadArray()
294 {
295   // see header file for class documentation
296   if(fVectorInitialized){
297     for(Int_t i=0;i<fNumberOfRows;i++){
298       for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
299         delete fRowPadVector[i][j];
300         fRowPadVector[i][j]=NULL;
301       }
302       fRowPadVector[i].clear();
303     }
304     fRowPadVector.clear();
305   }
306   return 1;
307
308
309 void AliHLTTPCZeroSuppressionComponent::InitializePadArray(){
310   // see header file for class documentation
311   if(fCurrentPatch>5){
312     HLTFatal("Patch is not set");
313     return;
314   }
315
316   fFirstRow = AliHLTTPCTransform::GetFirstRow(fCurrentPatch);
317   fLastRow = AliHLTTPCTransform::GetLastRow(fCurrentPatch);
318
319   fNumberOfRows=fLastRow-fFirstRow+1;
320   fNumberOfPadsInRow= new Int_t[fNumberOfRows];
321
322   memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
323
324   for(Int_t i=0;i<fNumberOfRows;i++){
325     fNumberOfPadsInRow[i]=AliHLTTPCTransform::GetNPads(i+fFirstRow);
326     AliHLTTPCPadVector tmpRow;
327     for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
328       AliHLTTPCPad *tmpPad = new AliHLTTPCPad();
329       tmpPad->SetID(i,j);
330       tmpRow.push_back(tmpPad);
331     }
332     fRowPadVector.push_back(tmpRow);
333   }
334   fVectorInitialized=kTRUE;
335 }
336
337
338 int AliHLTTPCZeroSuppressionComponent::DoEvent( const AliHLTComponentEventData& evtData, 
339                                                 const AliHLTComponentBlockData* blocks, 
340                                                 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
341                                                 AliHLTUInt32_t& size, 
342                                                 vector<AliHLTComponentBlockData>& outputBlocks )
343 {
344   // see header file for class documentation
345
346   //  HLTInfo("Entered DoEvent in AliHLTTPCZeroSuppressionComponent");
347
348   //  == init iter (pointer to datablock)
349   const AliHLTComponentBlockData* iter = NULL;
350   unsigned long ndx;
351   //  HLTInfo("Number of blocks: ",evtData.fBlockCnt);
352
353   Bool_t wasInput = 0;
354
355   fHwAddressList.clear();
356   //reading the data
357   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
358     {
359       iter = blocks+ndx;
360       
361       HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
362                evtData.fEventID, evtData.fEventID, 
363                DataType2Text( iter->fDataType).c_str(), 
364                DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
365
366       if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
367           GetEventCount()<2) {
368         HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
369                    DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
370                    DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
371       }
372       
373       if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
374            iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ){
375         continue;
376       }
377
378       wasInput = 1;
379
380       UInt_t slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
381       UInt_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
382
383       if(!fVectorInitialized){
384         fCurrentPatch=patch;
385         InitializePadArray();
386       }
387       
388       fDigitReader->InitBlock(iter->fPtr,iter->fSize,patch,slice);
389
390       //Here the reading of the data and the zerosuppression takes place
391       while(fDigitReader->NextChannel()){//Pad
392         Int_t row=fDigitReader->GetRow();
393         Int_t pad=fDigitReader->GetPad();
394         if(row==1000 || pad==1000){
395           continue;
396         }
397         if(row>=fNumberOfRows||row<0){
398           continue;
399         }
400         else if(pad>=fNumberOfPadsInRow[row]||pad<0){
401             continue;
402         }  
403         
404         AliHLTTPCPad *tmpPad = fRowPadVector[row][pad];
405         tmpPad->SetDataToDefault();
406         
407         //reading data to pad
408         while(fDigitReader->NextBunch()){
409           const UInt_t *bunchData= fDigitReader->GetSignals();
410           Int_t time=fDigitReader->GetTime();
411           for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
412             if(bunchData[i]>0){// disregarding 0 data.
413               if(time+i>=fStartTimeBin && time+i<=fEndTimeBin){
414                 tmpPad->SetDataSignal(time+i,bunchData[i]);
415               }
416             }
417           }
418         }
419         if(tmpPad->GetNAddedSignals()>=(UInt_t)fMinimumNumberOfSignals){
420           fHwAddressList.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr());
421           tmpPad->ZeroSuppress(fNRMSThreshold, fSignalThreshold, fMinimumNumberOfSignals, fStartTimeBin, fEndTimeBin, fLeftTimeBin, fRightTimeBin, fValueBelowAverage);
422         }
423       }
424     }
425
426   //  HLTDebug("Max number of signals: %d",size/sizeof(Int_t));
427
428   if(wasInput>0){
429   //if(wasInput && fHwAddressList.size()>0){
430   
431     AliHLTAltroEncoder altroEncoder;
432     altroEncoder.SetBuffer(outputPtr,size); //tests if one overwrite the buffer is done in the encoder
433
434     // TODO: read the CDH from the data input
435     AliRawDataHeader cdh;
436     altroEncoder.SetCDH((AliHLTUInt8_t*)&cdh,32);
437     for(Int_t row=0;row<fNumberOfRows;row++){
438       for(Int_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
439         AliHLTTPCPad * zeroSuppressedPad= fRowPadVector[row][pad];
440         Int_t currentTime=0;
441         Int_t bunchSize=0;
442         if(zeroSuppressedPad->GetNAddedSignals()>0){
443           while(zeroSuppressedPad->GetNextGoodSignal(currentTime, bunchSize)){
444             for(Int_t i=0;i<bunchSize;i++){
445               altroEncoder.AddSignal(zeroSuppressedPad->GetDataSignal(currentTime+i), currentTime+i);
446             }
447           }
448           altroEncoder.SetChannel(fDigitReader->GetAltroBlockHWaddr(row, pad));
449         }
450       }
451     }
452
453     // TODO: read the RCU trailer from the data input
454     AliHLTUInt8_t dummyTrailer=0;
455     altroEncoder.SetRCUTrailer(&dummyTrailer, sizeof(dummyTrailer));
456     int sizeOfData=altroEncoder.SetLength();
457
458     if (sizeOfData<0) {
459       HLTError("data encoding failed");
460       return sizeOfData;
461     }
462     if(sizeOfData>(int)size){
463       HLTWarning("Buffer too small too add the altrodata: %d of %d byte(s) already used", sizeOfData, size);
464       return -ENOSPC;
465     }
466
467     //Push back the zerosuppressed altro data to the output
468     AliHLTComponentBlockData bd;
469     FillBlockData( bd );
470     bd.fOffset = 0;
471     bd.fSize = sizeOfData;
472     bd.fDataType = kAliHLTDataTypeDDLRaw;
473     bd.fSpecification = iter->fSpecification;
474     Logging( kHLTLogDebug, "HLT::TPCZeroSuppressionComponent::DoEvent", "Event received", 
475              "Event 0x%08LX (%Lu) output data block %lu of %lu bytes at offset %lu",
476              evtData.fEventID, evtData.fEventID, ndx,size ,0);
477     outputBlocks.push_back( bd );
478
479     //Push back the list of hardware addresses to the output
480     AliHLTUInt32_t dataOffsetBeforeHW=sizeOfData;
481     AliHLTUInt32_t sizeOfHWArray=fHwAddressList.size()*sizeof(AliHLTUInt16_t);
482
483     if(dataOffsetBeforeHW+sizeOfHWArray>size){
484       HLTWarning("Buffer too small too add the active channels: %d of %d byte(s) already used", dataOffsetBeforeHW + sizeOfHWArray, size);
485       return -ENOSPC;
486     }
487
488     AliHLTUInt16_t*outputHWPtr=(AliHLTUInt16_t*)(outputPtr+dataOffsetBeforeHW);
489     outputHWPtr = &fHwAddressList[0];
490     AliHLTComponentBlockData bdHW;
491     FillBlockData( bdHW );
492     bdHW.fOffset = dataOffsetBeforeHW;
493     bdHW.fSize = sizeOfHWArray;
494     bdHW.fDataType = kAliHLTDataTypeHwAddr16;
495     bdHW.fSpecification = iter->fSpecification;
496     Logging( kHLTLogDebug, "HLT::TPCZeroSuppressionComponent::DoEvent", "Event received", 
497              "Event 0x%08LX (%Lu) output data block %lu of %lu bytes at offset %lu",
498              evtData.fEventID, evtData.fEventID, ndx,size ,0);
499     outputBlocks.push_back( bdHW );
500     
501     size = dataOffsetBeforeHW+sizeOfHWArray;
502
503   } else {
504     size=0;
505   }
506   return 0;
507 }