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