]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCClusterFinderComponent.cxx
converting to component registration by library agent - getting rid of global objects
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCClusterFinderComponent.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   AliHLTTPCClusterFinderComponent.cxx
22     @author Timm Steinbeck, Matthias Richter, Jochen Thaeder, Kenneth Aamodt
23     @date   
24     @brief  The TPC cluster finder processing component
25 */
26
27 // see header file for class documentation                                   //
28 // or                                                                        //
29 // refer to README to build package                                          //
30 // or                                                                        //
31 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt                          //
32
33 #if __GNUC__>= 3
34 using namespace std;
35 #endif
36 #include "AliHLTTPCClusterFinderComponent.h"
37 #include "AliHLTTPCDigitReaderPacked.h"
38 #include "AliHLTTPCDigitReaderUnpacked.h"
39 #include "AliHLTTPCDigitReaderRaw.h"
40 #include "AliHLTTPCDigitReaderDecoder.h"
41 #include "AliHLTTPCClusterFinder.h"
42 #include "AliHLTTPCSpacePointData.h"
43 #include "AliHLTTPCClusterDataFormat.h"
44 #include "AliHLTTPCTransform.h"
45 #include "AliHLTTPCClusters.h"
46 #include "AliHLTTPCDefinitions.h"
47 #include "AliCDBEntry.h"
48 #include "AliCDBManager.h"
49
50 #include <cstdlib>
51 #include <cerrno>
52 #include "TString.h"
53 #include "TObjString.h"
54 #include <sys/time.h>
55
56 /** ROOT macro for the implementation of ROOT specific class methods */
57 ClassImp(AliHLTTPCClusterFinderComponent)
58
59 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(int mode)
60   :
61   fClusterFinder(NULL),
62   fReader(NULL),
63   fClusterDeconv(true),
64   fXYClusterError(-1),
65   fZClusterError(-1),
66   fModeSwitch(mode),
67   fUnsorted(0),
68   fPatch(0),
69   fGetActivePads(0)
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 AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
79 {
80   // see header file for class documentation
81 }
82
83 // Public functions to implement AliHLTComponent's interface.
84 // These functions are required for the registration process
85
86 const char* AliHLTTPCClusterFinderComponent::GetComponentID()
87 {
88   // see header file for class documentation
89   switch(fModeSwitch){
90   case kClusterFinderPacked:
91     return "TPCClusterFinderPacked";
92     break;
93   case kClusterFinderUnpacked:
94     return "TPCClusterFinderUnpacked";
95     break;
96   case kClusterFinderDecoder:
97     return "TPCClusterFinderDecoder";
98     break;
99   }
100   HLTFatal("unknown digit reader type");
101   return "";
102 }
103
104 void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
105 {
106   // see header file for class documentation
107   list.clear(); 
108   switch(fModeSwitch){
109   case kClusterFinderPacked:
110     list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
111     break;
112   case kClusterFinderUnpacked:
113     list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
114     break;
115   case kClusterFinderDecoder:
116     list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
117     break;
118   }
119 }
120
121 AliHLTComponentDataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
122 {
123   // see header file for class documentation
124   return kAliHLTMultipleDataType;
125 }
126
127 int AliHLTTPCClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
128
129 {
130   // see header file for class documentation
131   tgtList.clear();
132   tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType);
133   tgtList.push_back(AliHLTTPCDefinitions::fgkActivePadsDataType);
134   return tgtList.size();
135 }
136
137 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
138 {
139   // see header file for class documentation
140   // XXX TODO: Find more realistic values.  
141   constBase = 0;
142   switch(fModeSwitch){
143   case 0:
144     inputMultiplier = (6 * 0.4);
145     break;
146   case 1:
147     inputMultiplier = 0.4;
148     break;
149   case 2:
150     inputMultiplier = (6 * 0.4);
151     break;
152   }
153 }
154
155 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
156 {
157   // see header file for class documentation
158   return new AliHLTTPCClusterFinderComponent(fModeSwitch);
159 }
160         
161 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
162 {
163   // see header file for class documentation
164   if ( fClusterFinder )
165     return EINPROGRESS;
166
167   fClusterFinder = new AliHLTTPCClusterFinder();
168
169   Int_t rawreadermode =  -1;
170   Int_t sigthresh = -1;
171   Double_t sigmathresh= -1;
172   Float_t occulimit = 1.0;
173   Int_t oldRCUFormat=0;
174   // Data Format version numbers:
175   // 0: RCU Data format as delivered during TPC commissioning, pads/padrows are sorted, RCU trailer is one 32 bit word.
176   // 1: As 0, but pads/padrows are delivered "as is", without sorting
177   // 2: As 0, but RCU trailer is 3 32 bit words.
178   // 3: As 1, but RCU trailer is 3 32 bit words.
179   // -1: use offline raw reader
180
181   Int_t i = 0;
182   Char_t* cpErr;
183
184   while ( i < argc ) {      
185
186     // -- raw reader mode option
187     if ( !strcmp( argv[i], "rawreadermode" ) ) {
188       if ( argc <= i+1 ) {
189         Logging( kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Missing rawreadermode", "Raw Reader Mode not specified" );
190         return ENOTSUP;
191       }
192
193       // Decodes the rawreader mode: either number or string and returns the rawreadermode
194       // -1 on failure, -2 for offline
195       rawreadermode = AliHLTTPCDigitReaderRaw::DecodeMode( argv[i+1] );
196
197       if (rawreadermode == -1 ) {
198         Logging( kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Missing rawreadermode", "Cannot convert rawreadermode specifier '%s'.", argv[i+1] );
199         return EINVAL;
200       }
201
202       i += 2;
203       continue;
204     }
205
206     // -- pp run option
207     if ( !strcmp( argv[i], "pp-run" ) ) {
208       fClusterDeconv = false;
209       i++;
210       continue;
211     }
212
213     // -- zero suppression threshold
214     if ( !strcmp( argv[i], "adc-threshold" ) ) {
215       sigthresh = strtoul( argv[i+1], &cpErr ,0);
216       if ( *cpErr ) {
217         HLTError("Cannot convert threshold specifier '%s'.", argv[i+1]);
218         return EINVAL;
219       }
220       i+=2;
221       continue;
222     }
223
224     // -- pad occupancy limit
225     if ( !strcmp( argv[i], "occupancy-limit" ) ) {
226       occulimit = strtod( argv[i+1], &cpErr);
227       if ( *cpErr ) {
228         HLTError("Cannot convert occupancy specifier '%s'.", argv[i+1]);
229         return EINVAL;
230       }
231       i+=2;
232       continue;
233     }
234
235     // -- number of timebins (default 1024)
236     if ( !strcmp( argv[i], "timebins" ) ) {
237       TString parameter(argv[i+1]);
238       parameter.Remove(TString::kLeading, ' '); // remove all blanks
239       if (parameter.IsDigit()) {
240         AliHLTTPCTransform::SetNTimeBins(parameter.Atoi());
241         HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
242       } else {
243         HLTError("Cannot timebin 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       oldRCUFormat = 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 unsorted clusterfinding
262     if ( !strcmp( argv[i], "unsorted" ) ) {
263       fUnsorted = strtoul( argv[i+1], &cpErr ,0);
264       if ( *cpErr ){
265         HLTError("Cannot convert unsorted 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     // -- checking for active pads, used in 2007 December run
273     if ( !strcmp( argv[i], "activepads" ) ) {
274       fGetActivePads = strtoul( argv[i+1], &cpErr ,0);
275       if ( *cpErr ){
276         HLTError("Cannot convert activepads specifier '%s'. Should  be 0(off) or 1(on), must be integer", argv[i+1]);
277         return EINVAL;
278       }
279       i+=2;
280       continue;
281     }
282
283     // -- checking for nsigma-threshold, used in 2007 December run in ZeroSuppression
284     if ( !strcmp( argv[i], "nsigma-threshold" ) ) {
285        sigmathresh = strtoul( argv[i+1], &cpErr ,0);
286       if ( *cpErr ){
287         HLTError("Cannot convert nsigma-threshold specifier '%s'. Must be integer", argv[i+1]);
288         return EINVAL;
289       }
290       i+=2;
291       continue;
292     }
293
294     Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
295     return EINVAL;
296
297   }
298
299   // Choose reader
300   if (fModeSwitch==kClusterFinderPacked) { 
301     if (rawreadermode == -2) {
302       HLTDebug("using AliHLTTPCDigitReaderPacked");
303       fReader = new AliHLTTPCDigitReaderPacked();
304       if(oldRCUFormat==1){
305         fReader->SetOldRCUFormat(kTRUE);
306       }
307       else if(oldRCUFormat!=0){
308         HLTWarning("Wrong oldrcuformat specifier %d; oldrcuformat set to default(kFALSE)",oldRCUFormat);
309       }
310       if(fUnsorted==1){
311         fReader->SetUnsorted(kTRUE);
312       }
313       fClusterFinder->SetReader(fReader);
314     } 
315     else {
316 #if defined(HAVE_TPC_MAPPING)
317       HLTDebug("using AliHLTTPCDigitReaderRaw mode %d", rawreadermode);
318       fReader = new AliHLTTPCDigitReaderRaw(rawreadermode);
319       fClusterFinder->SetReader(fReader);
320 #else //! defined(HAVE_TPC_MAPPING)
321       HLTFatal("DigitReaderRaw not available - check your build");
322       return -ENODEV;
323 #endif //defined(HAVE_TPC_MAPPING)
324     }
325   }
326   else if(fModeSwitch==kClusterFinderUnpacked){
327     HLTDebug("using AliHLTTPCDigitReaderUnpacked");
328     fReader = new AliHLTTPCDigitReaderUnpacked();
329     fClusterFinder->SetReader(fReader);
330   }
331   else if(fModeSwitch==kClusterFinderDecoder){
332     fReader = new AliHLTTPCDigitReaderDecoder();
333     fClusterFinder->SetReader(fReader);
334   }
335   else{
336     HLTFatal("No mode set for clusterfindercomponent");
337   }
338   // if pp-run use occupancy limit else set to 1. ==> use all 
339   if ( !fClusterDeconv )
340     fClusterFinder->SetOccupancyLimit(occulimit);
341   else 
342     fClusterFinder->SetOccupancyLimit(1.0);
343       
344   // Variables to setup the Clusterfinder
345   // TODO: this sounds strange and has to be verified; is the cluster finder not working when
346   // fClusterDeconv = false ?
347   fClusterDeconv = true;
348   fXYClusterError = -1;
349   fZClusterError = -1;
350
351  
352   fClusterFinder->SetDeconv( fClusterDeconv );
353   fClusterFinder->SetXYError( fXYClusterError );
354   fClusterFinder->SetZError( fZClusterError );
355   if ( (fXYClusterError>0) && (fZClusterError>0) )
356     fClusterFinder->SetCalcErr( false );
357   fClusterFinder->SetSignalThreshold(sigthresh);
358   fClusterFinder->SetNSigmaThreshold(sigmathresh);
359
360   return 0;
361 }
362
363 int AliHLTTPCClusterFinderComponent::DoDeinit()
364 {
365   // see header file for class documentation
366
367   if ( fClusterFinder )
368     delete fClusterFinder;
369   fClusterFinder = NULL;
370  
371   if ( fReader )
372     delete fReader;
373   fReader = NULL;
374     
375   return 0;
376 }
377
378 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData, 
379                                               const AliHLTComponentBlockData* blocks, 
380                                               AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
381                                               AliHLTUInt32_t& size, 
382                                               vector<AliHLTComponentBlockData>& outputBlocks )
383 {
384   // see header file for class documentation
385
386   //  == init iter (pointer to datablock)
387   const AliHLTComponentBlockData* iter = NULL;
388   unsigned long ndx;
389
390   //  == OUTdatatype pointer
391   AliHLTTPCClusterData* outPtr;
392
393   AliHLTUInt8_t* outBPtr;
394   UInt_t offset, mysize, nSize, tSize = 0;
395
396   outBPtr = outputPtr;
397   outPtr = (AliHLTTPCClusterData*)outBPtr;
398
399   Int_t slice, patch, row[2];
400   unsigned long maxPoints, realPoints = 0;
401
402   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
403     {
404       iter = blocks+ndx;
405       mysize = 0;
406       offset = tSize;
407
408
409       if (fModeSwitch==0 || fModeSwitch==2) {
410         HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
411                  evtData.fEventID, evtData.fEventID, 
412                  DataType2Text( iter->fDataType).c_str(), 
413                  DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
414
415         if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
416             GetEventCount()<2) {
417           HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
418                      DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
419                      DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
420           }
421
422         if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
423              iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
424
425       }
426       else if(fModeSwitch==1){
427         HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
428                  evtData.fEventID, evtData.fEventID, 
429                  DataType2Text( iter->fDataType).c_str(), 
430                  DataType2Text(AliHLTTPCDefinitions::fgkUnpackedRawDataType).c_str());
431
432         if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
433
434       }
435         
436       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
437       patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
438       row[0] = AliHLTTPCTransform::GetFirstRow( patch );
439       row[1] = AliHLTTPCTransform::GetLastRow( patch );
440
441
442       if(fUnsorted){
443         fClusterFinder->SetUnsorted(fUnsorted);
444         fClusterFinder->SetPatch(patch);
445       }
446
447       outPtr = (AliHLTTPCClusterData*)outBPtr;
448
449       maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
450
451       fClusterFinder->InitSlice( slice, patch, row[0], row[1], maxPoints );
452       fClusterFinder->SetOutputArray( (AliHLTTPCSpacePointData*)outPtr->fSpacePoints );
453         
454       if(fUnsorted){
455         fClusterFinder->ReadDataUnsorted(iter->fPtr, iter->fSize);
456
457         fClusterFinder->FindClusters();
458       }
459       else{
460         fClusterFinder->Read(iter->fPtr, iter->fSize );
461         fClusterFinder->ProcessDigits();
462       }
463       realPoints = fClusterFinder->GetNumberOfClusters();
464         
465       outPtr->fSpacePointCnt = realPoints;
466       nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
467       mysize += nSize+sizeof(AliHLTTPCClusterData);
468
469       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints", 
470                "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
471                realPoints, slice, patch, row[0], row[1] );
472       AliHLTComponentBlockData bd;
473       FillBlockData( bd );
474       bd.fOffset = offset;
475       bd.fSize = mysize;
476       bd.fSpecification = iter->fSpecification;
477       bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
478       //AliHLTSubEventDescriptor::FillBlockAttributes( bd.fAttributes );
479       outputBlocks.push_back( bd );
480         
481       tSize += mysize;
482       outBPtr += mysize;
483       outPtr = (AliHLTTPCClusterData*)outBPtr;
484         
485
486       if ( tSize > size )
487         {
488           Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data", 
489                    "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
490                    tSize, size );
491           return EMSGSIZE;
492         }
493     }
494     
495   size = tSize;
496
497   return 0;
498 }
499
500 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
501 {
502   // see header file for class documentation
503   const char* path="HLT/ConfigTPC";
504   if (cdbEntry) path=cdbEntry;
505   if (path) {
506     HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
507     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
508     if (pEntry) {
509       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
510       if (pString) {
511         HLTInfo("received configuration object: %s", pString->GetString().Data());
512       } else {
513         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
514       }
515     } else {
516       HLTError("can not fetch object \"%s\" from CDB", path);
517     }
518   }
519   return 0;
520 }