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