d0624e17da622c7ca9e3bca700b3675ff27cd460
[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: Timm Steinbeck, Matthias Richter                      *
8 //* Developers:      Kenneth Aamodt <kenneth.aamodt@student.uib.no>        *
9 //*                  for The ALICE HLT Project.                            *
10 //*                                                                        *
11 //* Permission to use, copy, modify and distribute this software and its   *
12 //* documentation strictly for non-commercial purposes is hereby granted   *
13 //* without fee, provided that the above copyright notice appears in all   *
14 //* copies and that both the copyright notice and this permission notice   *
15 //* appear in the supporting documentation. The authors make no claims     *
16 //* about the suitability of this software for any purpose. It is          *
17 //* provided "as is" without express or implied warranty.                  *
18 //**************************************************************************
19
20 /** @file   AliHLTTPCClusterFinderComponent.cxx
21     @author Kenneth Aamodt <kenneth.aamodt@student.uib.no>
22     @date   
23     @brief  The TPC cluster finder processing component
24 */
25
26 #if __GNUC__>= 3
27 using namespace std;
28 #endif
29 #include "AliHLTTPCClusterFinderComponent.h"
30 #include "AliHLTTPCDigitReaderPacked.h"
31 #include "AliHLTTPCDigitReaderUnpacked.h"
32 #include "AliHLTTPCDigitReaderDecoder.h"
33 #include "AliHLTTPCClusterFinder.h"
34 #include "AliHLTTPCSpacePointData.h"
35 #include "AliHLTTPCClusterDataFormat.h"
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCClusters.h"
38 #include "AliHLTTPCDefinitions.h"
39 #include "AliCDBEntry.h"
40 #include "AliCDBManager.h"
41
42 #include <cstdlib>
43 #include <cerrno>
44 #include "TString.h"
45 #include "TObjString.h"
46 #include "TObjArray.h"
47 #include "AliCDBEntry.h"
48 #include "AliCDBManager.h"
49 #include "AliCDBStorage.h"
50
51 #include <sys/time.h>
52
53 /** ROOT macro for the implementation of ROOT specific class methods */
54 ClassImp(AliHLTTPCClusterFinderComponent)
55
56 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(int mode)
57   :
58   fClusterFinder(NULL),
59   fReader(NULL),
60   fDeconvTime(kFALSE),
61   fDeconvPad(kFALSE),
62   fClusterDeconv(false),
63   fXYClusterError(-1),
64   fZClusterError(-1),
65   fModeSwitch(mode),
66   fUnsorted(1),
67   fPatch(0),
68   fGetActivePads(0),
69   fFirstTimeBin(-1),
70   fLastTimeBin(-1)
71 {
72   // see header file for class documentation
73   // or
74   // refer to README to build package
75   // or
76   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
77   if (fModeSwitch!=kClusterFinderPacked &&
78       fModeSwitch!=kClusterFinderUnpacked &&
79       fModeSwitch!=kClusterFinderDecoder) {
80     HLTFatal("unknown digit reader type");
81   }
82 }
83
84 AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
85 {
86   // see header file for class documentation
87 }
88
89 // Public functions to implement AliHLTComponent's interface.
90 // These functions are required for the registration process
91
92 const char* AliHLTTPCClusterFinderComponent::GetComponentID()
93 {
94   // see header file for class documentation
95   switch(fModeSwitch){
96   case kClusterFinderPacked:
97     return "TPCClusterFinderPacked";
98     break;
99   case kClusterFinderUnpacked:   
100     return "TPCClusterFinderUnpacked";   
101     break;
102   case kClusterFinderDecoder:
103     return "TPCClusterFinderDecoder";
104     break;
105   }
106   return "";
107 }
108
109 void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
110 {
111   // see header file for class documentation
112   list.clear(); 
113   switch(fModeSwitch){
114   case kClusterFinderPacked:
115     list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
116     break;
117   case kClusterFinderUnpacked:   
118     list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );      
119     break;
120   case kClusterFinderDecoder:
121     list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
122     break;
123   }
124 }
125
126 AliHLTComponentDataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
127 {
128   // see header file for class documentation
129   return kAliHLTMultipleDataType;
130 }
131
132 int AliHLTTPCClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
133
134 {
135   // see header file for class documentation
136   tgtList.clear();
137   tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType);
138   tgtList.push_back(kAliHLTDataTypeHwAddr16);
139   return tgtList.size();
140 }
141
142 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
143 {
144   // see header file for class documentation
145   // XXX TODO: Find more realistic values.  
146   constBase = 0;
147   switch(fModeSwitch){
148   case 0:
149     inputMultiplier = (6 * 0.4);
150     break;
151   case 1:
152     inputMultiplier = 0.4;
153     break;
154   case 2:
155     inputMultiplier = (6 * 0.4);
156     break;
157   }
158 }
159
160 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
161 {
162   // see header file for class documentation
163   return new AliHLTTPCClusterFinderComponent(fModeSwitch);
164 }
165         
166 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
167 {
168   // see header file for class documentation
169   if ( fClusterFinder )
170     return EINPROGRESS;
171
172   fClusterFinder = new AliHLTTPCClusterFinder();
173
174   Int_t iResult=0;
175   TString configuration="";
176   TString argument="";
177   for (int i=0; i<argc && iResult>=0; i++) {
178     argument=argv[i];
179     if (!configuration.IsNull()) configuration+=" ";
180     configuration+=argument;
181   }
182   
183   if (!configuration.IsNull()) {
184     iResult=Configure(configuration.Data());
185   } else {
186     iResult=Reconfigure(NULL, NULL);
187   }
188
189   //Checking for conflicting arguments
190   if(fClusterDeconv){
191     if(fDeconvPad==kTRUE || fDeconvTime==kTRUE){
192       HLTWarning("Conflicting arguments: argument 'pp-run' will be ignored.");
193     }
194   }
195   if(fClusterFinder->GetOccupancyLimit()!=1.0 && fUnsorted){
196     HLTWarning("Argument 'occupancy-limit' is deprecated when doing unsorted data reading.");
197   }
198   if(fGetActivePads==kTRUE && fUnsorted==kFALSE){
199     HLTWarning("Argument '-active-pads' only work with unsorted data reading. Active pads list will not be produced.");
200   }
201   
202
203   // Choose reader
204   if (fModeSwitch==kClusterFinderPacked) {
205       HLTDebug("using AliHLTTPCDigitReaderPacked");
206       fReader = new AliHLTTPCDigitReaderPacked();
207       if(fUnsorted==1){ fReader->SetUnsorted(kTRUE); }
208       fClusterFinder->SetReader(fReader);
209   }
210   else if(fModeSwitch==kClusterFinderUnpacked){          
211     HLTDebug("using AliHLTTPCDigitReaderUnpacked");      
212     fReader = new AliHLTTPCDigitReaderUnpacked();        
213     fClusterFinder->SetReader(fReader);
214   }
215   else if(fModeSwitch==kClusterFinderDecoder){
216     HLTDebug("using AliHLTTPCDigitReaderDecoder");
217     fReader = new AliHLTTPCDigitReaderDecoder();
218     fClusterFinder->SetReader(fReader);
219   }
220   else{
221     HLTFatal("No mode set for clusterfindercomponent");
222   }
223
224   if(fClusterDeconv){
225     fClusterFinder->SetOccupancyLimit(1.0);
226   }
227   
228   fClusterFinder->SetDeconv(fClusterDeconv);
229   fClusterFinder->SetDeconvPad(fDeconvPad);
230   fClusterFinder->SetDeconvTime(fDeconvPad);
231   fClusterFinder->SetXYError( fXYClusterError );
232   fClusterFinder->SetZError( fZClusterError );
233   if ( (fXYClusterError>0) && (fZClusterError>0) ){
234     fClusterFinder->SetCalcErr( false );
235   }
236
237   if(fFirstTimeBin>0){
238     fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
239   }
240   if(fLastTimeBin>0 && fLastTimeBin>fFirstTimeBin && fLastTimeBin<=AliHLTTPCTransform::GetNTimeBins()){
241     fClusterFinder->SetLastTimeBin(fLastTimeBin);
242   }
243
244   return 0;
245 }
246
247 int AliHLTTPCClusterFinderComponent::DoDeinit()
248 {
249   // see header file for class documentation
250
251   if ( fClusterFinder )
252     delete fClusterFinder;
253   fClusterFinder = NULL;
254  
255   if ( fReader )
256     delete fReader;
257   fReader = NULL;
258     
259   return 0;
260 }
261
262 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData, 
263                                               const AliHLTComponentBlockData* blocks, 
264                                               AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
265                                               AliHLTUInt32_t& size, 
266                                               vector<AliHLTComponentBlockData>& outputBlocks )
267 {
268   // see header file for class documentation
269
270   if(fReader == NULL){
271     HLTFatal("Digit reader not initialized, aborting event.");
272     size=0;
273     return 0;    
274   }
275
276   if(GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR )){
277     size=0;
278     return 0;
279   }
280
281   //  == init iter (pointer to datablock)
282   const AliHLTComponentBlockData* iter = NULL;
283   unsigned long ndx;
284
285   //  == OUTdatatype pointer
286   AliHLTTPCClusterData* outPtr;
287
288   AliHLTUInt8_t* outBPtr;
289   UInt_t offset, mysize, nSize, tSize = 0;
290
291   outBPtr = outputPtr;
292   outPtr = (AliHLTTPCClusterData*)outBPtr;
293
294   Int_t slice, patch;
295   unsigned long maxPoints, realPoints = 0;
296
297   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
298     {
299       iter = blocks+ndx;
300       mysize = 0;
301       offset = tSize;
302
303
304       if (fModeSwitch==0 || fModeSwitch==2) {
305         HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
306                  evtData.fEventID, evtData.fEventID, 
307                  DataType2Text( iter->fDataType).c_str(), 
308                  DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
309
310         if (iter->fDataType == AliHLTTPCDefinitions::fgkDDLPackedRawDataType &&
311             GetEventCount()<2) {
312           HLTWarning("data type %s is depricated, use %s (kAliHLTDataTypeDDLRaw)!",
313                      DataType2Text(AliHLTTPCDefinitions::fgkDDLPackedRawDataType).c_str(),
314                      DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
315           }
316
317         if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) &&
318              iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
319
320       }
321       else if(fModeSwitch==1){
322         HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
323                  evtData.fEventID, evtData.fEventID, 
324                  DataType2Text( iter->fDataType).c_str(), 
325                  DataType2Text(AliHLTTPCDefinitions::fgkUnpackedRawDataType).c_str());
326
327         if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
328
329       }
330
331       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
332       patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
333
334       if(fUnsorted){
335         fClusterFinder->SetUnsorted(fUnsorted);
336         fClusterFinder->SetPatch(patch);
337       }
338
339       outPtr = (AliHLTTPCClusterData*)outBPtr;
340
341       maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
342
343       fClusterFinder->InitSlice( slice, patch, maxPoints );
344       fClusterFinder->SetOutputArray( (AliHLTTPCSpacePointData*)outPtr->fSpacePoints );
345         
346       if(fUnsorted){
347         if(fGetActivePads){
348           fClusterFinder->SetDoPadSelection(kTRUE);
349         }       
350         if(fDeconvTime){
351           fClusterFinder->ReadDataUnsortedDeconvoluteTime(iter->fPtr, iter->fSize);
352         }
353         else{
354           fClusterFinder->ReadDataUnsorted(iter->fPtr, iter->fSize);
355         }
356
357         fClusterFinder->FindClusters();
358       }
359       else{
360         fClusterFinder->Read(iter->fPtr, iter->fSize );
361         fClusterFinder->ProcessDigits();
362       }
363
364       realPoints = fClusterFinder->GetNumberOfClusters();
365         
366       outPtr->fSpacePointCnt = realPoints;
367       nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
368       mysize += nSize+sizeof(AliHLTTPCClusterData);
369
370       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints", 
371                "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
372                realPoints, slice, patch,AliHLTTPCTransform::GetFirstRow( patch ) , AliHLTTPCTransform::GetLastRow( patch ) );
373       AliHLTComponentBlockData bd;
374       FillBlockData( bd );
375       bd.fOffset = offset;
376       bd.fSize = mysize;
377       bd.fSpecification = iter->fSpecification;
378       bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
379       outputBlocks.push_back( bd );
380         
381       tSize += mysize;
382       outBPtr += mysize;
383       outPtr = (AliHLTTPCClusterData*)outBPtr;
384         
385
386       if ( tSize > size )
387         {
388           Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data", 
389                    "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
390                    tSize, size );
391           return -ENOSPC;
392         }
393         
394       if(fUnsorted && fGetActivePads){
395        Int_t maxNumberOfHW=(Int_t)((size-tSize)/sizeof(AliHLTUInt16_t)-1);
396        AliHLTUInt16_t* outputHWPtr= (AliHLTUInt16_t*)(outputPtr+tSize);
397        Int_t nHWAdd = fClusterFinder->FillHWAddressList(outputHWPtr, maxNumberOfHW);
398       
399        AliHLTComponentBlockData bdHW;
400        FillBlockData( bdHW );
401        bdHW.fOffset = tSize ;
402        bdHW.fSize = nHWAdd*sizeof(AliHLTUInt16_t);
403        bdHW.fSpecification = iter->fSpecification;
404        bdHW.fDataType = kAliHLTDataTypeHwAddr16;
405        outputBlocks.push_back( bdHW );
406        
407        tSize+=nHWAdd*sizeof(AliHLTUInt16_t);
408       }
409       fReader->Reset();
410     }
411     
412   size = tSize;
413
414   return 0;
415 }
416
417 int AliHLTTPCClusterFinderComponent::Configure(const char* arguments){
418   // see header file for class documentation
419   int iResult=0;
420   if (!arguments) return iResult;
421   
422   TString allArgs=arguments;
423   TString argument;
424   int bMissingParam=0;
425
426   TObjArray* pTokens=allArgs.Tokenize(" ");
427   if (pTokens) {
428     
429     for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
430       argument=((TObjString*)pTokens->At(i))->GetString();
431
432       if (argument.IsNull()) continue;
433       
434
435       // -- deconvolute-time option
436       if (argument.CompareTo("-deconvolute-time")==0){
437         HLTDebug("Switching on deconvolution in time direction.");
438         fDeconvTime = kTRUE;
439       }
440       else if (argument.CompareTo("-deconvolute-pad")==0){
441         HLTDebug("Switching on deconvolution in pad direction.");
442         fDeconvPad = kTRUE;
443       }
444       else if (argument.CompareTo("-timebins")==0 || argument.CompareTo("timebins" )==0){
445         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
446         AliHLTTPCTransform::SetNTimeBins(((TObjString*)pTokens->At(i))->GetString().Atoi());
447         fClusterFinder->UpdateLastTimeBin();
448         HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
449         if(argument.CompareTo("timebins")==0){
450           HLTWarning("Argument 'timebins' is old, please switch to new argument naming convention (-timebins). The timebins argument will still work, but please change anyway.");
451         }
452       }
453       else if (argument.CompareTo("-first-timebin")==0){
454         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
455         fFirstTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
456         HLTDebug("Kenneth fFirstTimeBin set to %d",fFirstTimeBin);
457       }
458       else if (argument.CompareTo("-last-timebin")==0){
459         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
460         fLastTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
461         HLTDebug("fLastTimeBin set to %d",fLastTimeBin);
462       }
463       else if (argument.CompareTo("-sorted")) {
464         fUnsorted=0;
465         HLTDebug("Swithching unsorted off.");
466       }
467       else if (argument.CompareTo("-active-pads")==0 || argument.CompareTo("activepads")==0){
468         if(argument.CompareTo("activepads" )==0){
469           HLTWarning("Please change to new component argument naming scheme and use '-active-pads' instead of 'activepads'");
470         }
471         HLTDebug("Switching on ActivePads");
472         fGetActivePads = 1;
473       }
474       else if (argument.CompareTo("-occupancy-limit")==0 ||argument.CompareTo("occupancy-limit")==0){
475         if(argument.CompareTo("occupancy-limit" )==0){
476           HLTWarning("Please switch to new component argument naming convention, use '-occupancy-limit' instead of 'occupancy-limit'");
477         }
478         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
479         fClusterFinder->SetOccupancyLimit(((TObjString*)pTokens->At(i))->GetString().Atof());
480         HLTDebug("Occupancy limit set to occulimit %f", ((TObjString*)pTokens->At(i))->GetString().Atof());
481       }
482       else if (argument.CompareTo("rawreadermode")==0){
483         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
484         HLTWarning("Argument 'rawreadermode' is deprecated");      
485       }
486       else if (argument.CompareTo("pp-run")==0){
487         HLTWarning("Argument 'pp-run' is obsolete, deconvolution is swiched off in both time and pad directions by default.");
488         fClusterDeconv = false;
489       }
490       else if (argument.CompareTo("adc-threshold" )==0){
491         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
492         HLTWarning("'adc-threshold' is no longer a valid argument, please use TPCZeroSuppression component if you want to zerosuppress data.");
493       }
494       else if (argument.CompareTo("oldrcuformat" )==0){
495         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
496         HLTWarning("Argument 'oldrcuformat' is deprecated.");
497       }
498       else if (argument.CompareTo("unsorted" )==0){
499         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
500         HLTWarning("Argument 'unsorted' is old and does not follow the new argument naming convention. A change has been made, and the clusterfinder will read the data unsorted by default. For sorted reading, please use '-sorted' as argument.");
501       }
502       else if (argument.CompareTo("nsigma-threshold")==0){
503         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
504         HLTWarning("Argument 'nsigma-threshold' argument is obsolete.");
505       }
506       else {
507         HLTError("unknown argument %s", argument.Data());
508         iResult=-EINVAL;
509         break;
510       }
511     }
512     delete pTokens;
513   }
514   if (bMissingParam) {
515     HLTError("missing parameter for argument %s", argument.Data());
516     iResult=-EINVAL;
517   }
518   return iResult;
519 }
520
521 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
522 {
523   // see header file for class documentation
524   const char* path="HLT/ConfigTPC/ClusterFinderComponent";
525   if (cdbEntry) path=cdbEntry;
526   if (path) {
527     HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
528     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
529     if (pEntry) {
530       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
531       if (pString) {
532         HLTInfo("received configuration object: %s", pString->GetString().Data());
533       } else {
534         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
535       }
536     } else {
537       HLTError("can not fetch object \"%s\" from CDB", path);
538     }
539   }
540   return 0;
541 }