]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCClusterFinderComponent.cxx
- added skeleton of of offline clusterizer and tracker components
[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   return tgtList.size();
134 }
135
136 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
137 {
138   // see header file for class documentation
139   // XXX TODO: Find more realistic values.  
140   constBase = 0;
141   switch(fModeSwitch){
142   case 0:
143     inputMultiplier = (6 * 0.4);
144     break;
145   case 1:
146     inputMultiplier = 0.4;
147     break;
148   case 2:
149     inputMultiplier = (6 * 0.4);
150     break;
151   }
152 }
153
154 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
155 {
156   // see header file for class documentation
157   return new AliHLTTPCClusterFinderComponent(fModeSwitch);
158 }
159         
160 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
161 {
162   // see header file for class documentation
163   if ( fClusterFinder )
164     return EINPROGRESS;
165
166   fClusterFinder = new AliHLTTPCClusterFinder();
167
168   Int_t rawreadermode =  -1;
169   Int_t sigthresh = -1;
170   Double_t sigmathresh= -1;
171   Float_t occulimit = 1.0;
172   Int_t oldRCUFormat=0;
173   // Data Format version numbers:
174   // 0: RCU Data format as delivered during TPC commissioning, pads/padrows are sorted, RCU trailer is one 32 bit word.
175   // 1: As 0, but pads/padrows are delivered "as is", without sorting
176   // 2: As 0, but RCU trailer is 3 32 bit words.
177   // 3: As 1, but RCU trailer is 3 32 bit words.
178   // -1: use offline raw reader
179
180   Int_t i = 0;
181   Char_t* cpErr;
182
183   while ( i < argc ) {      
184
185     // -- raw reader mode option
186     if ( !strcmp( argv[i], "rawreadermode" ) ) {
187       if ( argc <= i+1 ) {
188         Logging( kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Missing rawreadermode", "Raw Reader Mode not specified" );
189         return ENOTSUP;
190       }
191
192       // Decodes the rawreader mode: either number or string and returns the rawreadermode
193       // -1 on failure, -2 for offline
194       rawreadermode = AliHLTTPCDigitReaderRaw::DecodeMode( argv[i+1] );
195
196       if (rawreadermode == -1 ) {
197         Logging( kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Missing rawreadermode", "Cannot convert rawreadermode specifier '%s'.", argv[i+1] );
198         return EINVAL;
199       }
200
201       i += 2;
202       continue;
203     }
204
205     // -- pp run option
206     if ( !strcmp( argv[i], "pp-run" ) ) {
207       fClusterDeconv = false;
208       i++;
209       continue;
210     }
211
212     // -- zero suppression threshold
213     if ( !strcmp( argv[i], "adc-threshold" ) ) {
214       sigthresh = strtoul( argv[i+1], &cpErr ,0);
215       if ( *cpErr ) {
216         HLTError("Cannot convert threshold specifier '%s'.", argv[i+1]);
217         return EINVAL;
218       }
219       i+=2;
220       continue;
221     }
222
223     // -- pad occupancy limit
224     if ( !strcmp( argv[i], "occupancy-limit" ) ) {
225       occulimit = strtod( argv[i+1], &cpErr);
226       if ( *cpErr ) {
227         HLTError("Cannot convert occupancy specifier '%s'.", argv[i+1]);
228         return EINVAL;
229       }
230       i+=2;
231       continue;
232     }
233
234     // -- number of timebins (default 1024)
235     if ( !strcmp( argv[i], "timebins" ) ) {
236       TString parameter(argv[i+1]);
237       parameter.Remove(TString::kLeading, ' '); // remove all blanks
238       if (parameter.IsDigit()) {
239         AliHLTTPCTransform::SetNTimeBins(parameter.Atoi());
240         HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
241       } else {
242         HLTError("Cannot timebin specifier '%s'.", argv[i+1]);
243         return EINVAL;
244       }
245       i+=2;
246       continue;
247     }
248
249     // -- checking for rcu format
250     if ( !strcmp( argv[i], "oldrcuformat" ) ) {
251       oldRCUFormat = strtoul( argv[i+1], &cpErr ,0);
252       if ( *cpErr ){
253         HLTError("Cannot convert oldrcuformat specifier '%s'. Should  be 0(off) or 1(on), must be integer", argv[i+1]);
254         return EINVAL;
255       }
256       i+=2;
257       continue;
258     }
259       
260     // -- checking for unsorted clusterfinding
261     if ( !strcmp( argv[i], "unsorted" ) ) {
262       fUnsorted = strtoul( argv[i+1], &cpErr ,0);
263       if ( *cpErr ){
264         HLTError("Cannot convert unsorted specifier '%s'. Should  be 0(off) or 1(on), must be integer", argv[i+1]);
265         return EINVAL;
266       }
267       i+=2;
268       continue;
269     }
270       
271     // -- checking for active pads, used in 2007 December run
272     if ( !strcmp( argv[i], "activepads" ) ) {
273       fGetActivePads = strtoul( argv[i+1], &cpErr ,0);
274       if ( *cpErr ){
275         HLTError("Cannot convert activepads specifier '%s'. Should  be 0(off) or 1(on), must be integer", argv[i+1]);
276         return EINVAL;
277       }
278       i+=2;
279       continue;
280     }
281
282     // -- checking for nsigma-threshold, used in 2007 December run in ZeroSuppression
283     if ( !strcmp( argv[i], "nsigma-threshold" ) ) {
284        sigmathresh = strtoul( argv[i+1], &cpErr ,0);
285       if ( *cpErr ){
286         HLTError("Cannot convert nsigma-threshold specifier '%s'. Must be integer", argv[i+1]);
287         return EINVAL;
288       }
289       i+=2;
290       continue;
291     }
292
293     Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
294     return EINVAL;
295
296   }
297
298   // Choose reader
299   if (fModeSwitch==kClusterFinderPacked) { 
300     if (rawreadermode == -2) {
301       HLTDebug("using AliHLTTPCDigitReaderPacked");
302       fReader = new AliHLTTPCDigitReaderPacked();
303       if(oldRCUFormat==1){
304         fReader->SetOldRCUFormat(kTRUE);
305       }
306       else if(oldRCUFormat!=0){
307         HLTWarning("Wrong oldrcuformat specifier %d; oldrcuformat set to default(kFALSE)",oldRCUFormat);
308       }
309       if(fUnsorted==1){
310         fReader->SetUnsorted(kTRUE);
311       }
312       fClusterFinder->SetReader(fReader);
313     } 
314     else {
315 #if defined(HAVE_TPC_MAPPING)
316       HLTDebug("using AliHLTTPCDigitReaderRaw mode %d", rawreadermode);
317       fReader = new AliHLTTPCDigitReaderRaw(rawreadermode);
318       fClusterFinder->SetReader(fReader);
319 #else //! defined(HAVE_TPC_MAPPING)
320       HLTFatal("DigitReaderRaw not available - check your build");
321       return -ENODEV;
322 #endif //defined(HAVE_TPC_MAPPING)
323     }
324   }
325   else if(fModeSwitch==kClusterFinderUnpacked){
326     HLTDebug("using AliHLTTPCDigitReaderUnpacked");
327     fReader = new AliHLTTPCDigitReaderUnpacked();
328     fClusterFinder->SetReader(fReader);
329   }
330   else if(fModeSwitch==kClusterFinderDecoder){
331     fReader = new AliHLTTPCDigitReaderDecoder();
332     fClusterFinder->SetReader(fReader);
333   }
334   else{
335     HLTFatal("No mode set for clusterfindercomponent");
336   }
337   // if pp-run use occupancy limit else set to 1. ==> use all 
338   if ( !fClusterDeconv )
339     fClusterFinder->SetOccupancyLimit(occulimit);
340   else 
341     fClusterFinder->SetOccupancyLimit(1.0);
342       
343   // Variables to setup the Clusterfinder
344   // TODO: this sounds strange and has to be verified; is the cluster finder not working when
345   // fClusterDeconv = false ?
346   fClusterDeconv = true;
347   fXYClusterError = -1;
348   fZClusterError = -1;
349
350  
351   fClusterFinder->SetDeconv( fClusterDeconv );
352   fClusterFinder->SetXYError( fXYClusterError );
353   fClusterFinder->SetZError( fZClusterError );
354   if ( (fXYClusterError>0) && (fZClusterError>0) )
355     fClusterFinder->SetCalcErr( false );
356   fClusterFinder->SetSignalThreshold(sigthresh);
357   fClusterFinder->SetNSigmaThreshold(sigmathresh);
358
359   return 0;
360 }
361
362 int AliHLTTPCClusterFinderComponent::DoDeinit()
363 {
364   // see header file for class documentation
365
366   if ( fClusterFinder )
367     delete fClusterFinder;
368   fClusterFinder = NULL;
369  
370   if ( fReader )
371     delete fReader;
372   fReader = NULL;
373     
374   return 0;
375 }
376
377 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData, 
378                                               const AliHLTComponentBlockData* blocks, 
379                                               AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
380                                               AliHLTUInt32_t& size, 
381                                               vector<AliHLTComponentBlockData>& outputBlocks )
382 {
383   // see header file for class documentation
384
385   //  == init iter (pointer to datablock)
386   const AliHLTComponentBlockData* iter = NULL;
387   unsigned long ndx;
388
389   //  == OUTdatatype pointer
390   AliHLTTPCClusterData* outPtr;
391
392   AliHLTUInt8_t* outBPtr;
393   UInt_t offset, mysize, nSize, tSize = 0;
394
395   outBPtr = outputPtr;
396   outPtr = (AliHLTTPCClusterData*)outBPtr;
397
398   Int_t slice, patch, row[2];
399   unsigned long maxPoints, realPoints = 0;
400
401   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
402     {
403       iter = blocks+ndx;
404       mysize = 0;
405       offset = tSize;
406
407
408       if (fModeSwitch==0 || fModeSwitch==2) {
409         HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
410                  evtData.fEventID, evtData.fEventID, 
411                  DataType2Text( iter->fDataType).c_str(), 
412                  DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
413
414         if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
415             GetEventCount()<2) {
416           HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
417                      DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
418                      DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
419           }
420
421         if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
422              iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
423
424       }
425       else if(fModeSwitch==1){
426         HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
427                  evtData.fEventID, evtData.fEventID, 
428                  DataType2Text( iter->fDataType).c_str(), 
429                  DataType2Text(AliHLTTPCDefinitions::fgkUnpackedRawDataType).c_str());
430
431         if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
432
433       }
434         
435       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
436       patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
437       row[0] = AliHLTTPCTransform::GetFirstRow( patch );
438       row[1] = AliHLTTPCTransform::GetLastRow( patch );
439
440
441       if(fUnsorted){
442         fClusterFinder->SetUnsorted(fUnsorted);
443         fClusterFinder->SetPatch(patch);
444       }
445
446       outPtr = (AliHLTTPCClusterData*)outBPtr;
447
448       maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
449
450       fClusterFinder->InitSlice( slice, patch, row[0], row[1], maxPoints );
451       fClusterFinder->SetOutputArray( (AliHLTTPCSpacePointData*)outPtr->fSpacePoints );
452         
453       if(fUnsorted){
454         fClusterFinder->ReadDataUnsorted(iter->fPtr, iter->fSize);
455
456         fClusterFinder->FindClusters();
457       }
458       else{
459         fClusterFinder->Read(iter->fPtr, iter->fSize );
460         fClusterFinder->ProcessDigits();
461       }
462       realPoints = fClusterFinder->GetNumberOfClusters();
463         
464       outPtr->fSpacePointCnt = realPoints;
465       nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
466       mysize += nSize+sizeof(AliHLTTPCClusterData);
467
468       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints", 
469                "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
470                realPoints, slice, patch, row[0], row[1] );
471       AliHLTComponentBlockData bd;
472       FillBlockData( bd );
473       bd.fOffset = offset;
474       bd.fSize = mysize;
475       bd.fSpecification = iter->fSpecification;
476       bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
477       //AliHLTSubEventDescriptor::FillBlockAttributes( bd.fAttributes );
478       outputBlocks.push_back( bd );
479         
480       tSize += mysize;
481       outBPtr += mysize;
482       outPtr = (AliHLTTPCClusterData*)outBPtr;
483         
484
485       if ( tSize > size )
486         {
487           Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data", 
488                    "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
489                    tSize, size );
490           return EMSGSIZE;
491         }
492     }
493     
494   size = tSize;
495
496   return 0;
497 }
498
499 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
500 {
501   // see header file for class documentation
502   const char* path="HLT/ConfigTPC";
503   if (cdbEntry) path=cdbEntry;
504   if (path) {
505     HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
506     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
507     if (pEntry) {
508       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
509       if (pString) {
510         HLTInfo("received configuration object: %s", pString->GetString().Data());
511       } else {
512         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
513       }
514     } else {
515       HLTError("can not fetch object \"%s\" from CDB", path);
516     }
517   }
518   return 0;
519 }