Bugfix, comparison of string -sorted was not correct.
[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         fClusterFinder->SetDeconvTime(fDeconvTime);
440       }
441       else if (argument.CompareTo("-deconvolute-pad")==0){
442         HLTDebug("Switching on deconvolution in pad direction.");
443         fDeconvPad = kTRUE;
444         fClusterFinder->SetDeconvPad(fDeconvPad);
445       }
446       else if (argument.CompareTo("-timebins")==0 || argument.CompareTo("timebins" )==0){
447         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
448         AliHLTTPCTransform::SetNTimeBins(((TObjString*)pTokens->At(i))->GetString().Atoi());
449         fClusterFinder->UpdateLastTimeBin();
450         HLTInfo("number of timebins set to %d, zbin=%f", AliHLTTPCTransform::GetNTimeBins(), AliHLTTPCTransform::GetZWidth());
451         if(argument.CompareTo("timebins")==0){
452           HLTWarning("Argument 'timebins' is old, please switch to new argument naming convention (-timebins). The timebins argument will still work, but please change anyway.");
453         }
454       }
455       else if (argument.CompareTo("-first-timebin")==0){
456         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
457         fFirstTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
458         if(fFirstTimeBin>=0){
459           HLTDebug("fFirstTimeBin set to %d",fFirstTimeBin);
460           fClusterFinder->SetFirstTimeBin(fFirstTimeBin);
461         }
462         else{
463           HLTError("-first-timebin specifier is negative: %d",fFirstTimeBin);
464         }
465       }
466       else if (argument.CompareTo("-last-timebin")==0){
467         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
468         fLastTimeBin = ((TObjString*)pTokens->At(i))->GetString().Atoi();
469         if(fLastTimeBin<AliHLTTPCTransform::GetNTimeBins()){
470           HLTDebug("fLastTimeBin set to %d",fLastTimeBin);
471         }
472         else{
473           HLTError("fLastTimeBins is too big: %d. Maximum: %d",fLastTimeBin,AliHLTTPCTransform::GetNTimeBins());
474         }
475       }
476       else if (argument.CompareTo("-sorted")==0) {
477         fUnsorted=0;
478         HLTDebug("Swithching unsorted off.");
479         fClusterFinder->SetUnsorted(0);
480       }
481       else if (argument.CompareTo("-active-pads")==0 || argument.CompareTo("activepads")==0){
482         if(argument.CompareTo("activepads" )==0){
483           HLTWarning("Please change to new component argument naming scheme and use '-active-pads' instead of 'activepads'");
484         }
485         HLTDebug("Switching on ActivePads");
486         fGetActivePads = 1;
487         fClusterFinder->SetDoPadSelection(kTRUE);
488       }
489       else if (argument.CompareTo("-occupancy-limit")==0 || argument.CompareTo("occupancy-limit")==0){
490         if(argument.CompareTo("occupancy-limit" )==0){
491           HLTWarning("Please switch to new component argument naming convention, use '-occupancy-limit' instead of 'occupancy-limit'");
492         }
493         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
494         fClusterFinder->SetOccupancyLimit(((TObjString*)pTokens->At(i))->GetString().Atof());
495         HLTDebug("Occupancy limit set to occulimit %f", ((TObjString*)pTokens->At(i))->GetString().Atof());
496       }
497       else if (argument.CompareTo("rawreadermode")==0){
498         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
499         HLTWarning("Argument 'rawreadermode' is deprecated");      
500       }
501       else if (argument.CompareTo("pp-run")==0){
502         HLTWarning("Argument 'pp-run' is obsolete, deconvolution is swiched off in both time and pad directions by default.");
503         fClusterDeconv = false;
504       }
505       else if (argument.CompareTo("adc-threshold" )==0){
506         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
507         HLTWarning("'adc-threshold' is no longer a valid argument, please use TPCZeroSuppression component if you want to zerosuppress data.");
508       }
509       else if (argument.CompareTo("oldrcuformat" )==0){
510         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
511         HLTWarning("Argument 'oldrcuformat' is deprecated.");
512       }
513       else if (argument.CompareTo("unsorted" )==0){
514         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
515         HLTDebug("Using unsorted reading.");
516         fClusterFinder->SetUnsorted(1);
517       }
518       else if (argument.CompareTo("nsigma-threshold")==0){
519         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
520         HLTWarning("Argument 'nsigma-threshold' argument is obsolete.");
521       }
522       else {
523         HLTError("unknown argument %s", argument.Data());
524         iResult=-EINVAL;
525         break;
526       }
527     }
528     delete pTokens;
529   }
530   if (bMissingParam) {
531     HLTError("missing parameter for argument %s", argument.Data());
532     iResult=-EINVAL;
533   }
534   return iResult;
535 }
536
537 int AliHLTTPCClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
538 {
539   
540   int iResult=0;
541   // see header file for class documentation
542   const char* path="HLT/ConfigTPC/ClusterFinderComponent";
543   if (cdbEntry) path=cdbEntry;
544   if (path) {
545     HLTInfo("reconfigure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
546     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
547     if (pEntry) {
548       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
549       if (pString) {
550         HLTInfo("received configuration object: %s", pString->GetString().Data());
551         iResult = Configure(pString->GetString().Data());
552       } else {
553         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
554       }
555     } else {
556       HLTError("can not fetch object \"%s\" from CDB", path);
557     }
558   }
559   return iResult;
560 }