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