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