]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCClusterFinderComponent.cxx
6d9ffb2bff15f11af01fd87cb46f872971b62b43
[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 #if __GNUC__>= 3
28 using namespace std;
29 #endif
30 #include "AliHLTTPCLogging.h"
31 #include "AliHLTTPCClusterFinderComponent.h"
32 #include "AliHLTTPCDigitReaderPacked.h"
33 #include "AliHLTTPCDigitReaderUnpacked.h"
34 #include "AliHLTTPCDigitReaderRaw.h"
35 #include "AliHLTTPCClusterFinder.h"
36 #include "AliHLTTPCSpacePointData.h"
37 #include "AliHLTTPCRawDataFormat.h"
38 #include "AliHLTTPCClusterDataFormat.h"
39 #include "AliHLTTPCTransform.h"
40 #include <stdlib.h>
41 #include <errno.h>
42 #include "TString.h"
43
44 // this is a global object used for automatic component registration, do not use this
45 // use fPackedSwitch = true for packed inputtype "gkDDLPackedRawDataType"
46 // use fPackedSwitch = false for unpacked inputtype "gkUnpackedRawDataType"
47 AliHLTTPCClusterFinderComponent gAliHLTTPCClusterFinderComponentPacked(true);
48 AliHLTTPCClusterFinderComponent gAliHLTTPCClusterFinderComponentUnpacked(false);
49
50 ClassImp(AliHLTTPCClusterFinderComponent)
51
52 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(bool packed)
53   :
54   fClusterFinder(NULL),
55   fReader(NULL),
56   fClusterDeconv(true),
57   fXYClusterError(-1),
58   fZClusterError(-1),
59   fPackedSwitch(packed)
60 {
61   // see header file for class documentation
62   // or
63   // refer to README to build package
64   // or
65   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
66 }
67
68 AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent(const AliHLTTPCClusterFinderComponent&)
69   :
70   fClusterFinder(NULL),
71   fReader(NULL),
72   fClusterDeconv(true),
73   fXYClusterError(-1),
74   fZClusterError(-1),
75   fPackedSwitch(0)
76 {
77   // see header file for class documentation
78   HLTFatal("copy constructor untested");
79 }
80
81 AliHLTTPCClusterFinderComponent& AliHLTTPCClusterFinderComponent::operator=(const AliHLTTPCClusterFinderComponent&)
82
83   // see header file for class documentation
84   HLTFatal("assignment operator untested");
85   return *this;
86 }
87
88 AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
89 {
90   // see header file for class documentation
91 }
92
93 // Public functions to implement AliHLTComponent's interface.
94 // These functions are required for the registration process
95
96 const char* AliHLTTPCClusterFinderComponent::GetComponentID()
97 {
98   // see header file for class documentation
99   if (fPackedSwitch) return "TPCClusterFinderPacked";
100   else return "TPCClusterFinderUnpacked";
101 }
102
103 void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
104 {
105   // see header file for class documentation
106   list.clear(); 
107   if (fPackedSwitch) list.push_back( AliHLTTPCDefinitions::fgkDDLPackedRawDataType );
108   else list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
109    
110 }
111
112 AliHLTComponentDataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
113 {
114   // see header file for class documentation
115   return AliHLTTPCDefinitions::fgkClustersDataType;
116 }
117
118 void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
119 {
120   // see header file for class documentation
121   // XXX TODO: Find more realistic values.  
122   constBase = 0;
123   if (fPackedSwitch)  inputMultiplier = (6 * 0.4);
124   else  inputMultiplier = 0.4;
125 }
126
127 AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
128 {
129   // see header file for class documentation
130   return new AliHLTTPCClusterFinderComponent(fPackedSwitch);
131 }
132         
133 int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
134 {
135   // see header file for class documentation
136   if ( fClusterFinder )
137     return EINPROGRESS;
138
139   fClusterFinder = new AliHLTTPCClusterFinder();
140
141   Int_t rawreadermode =  -1;
142   Int_t sigthresh = -1;
143   Float_t occulimit = 1.0;
144   Int_t oldRCUFormat=0;
145   // Data Format version numbers:
146   // 0: RCU Data format as delivered during TPC commissioning, pads/padrows are sorted, RCU trailer is one 32 bit word.
147   // 1: As 0, but pads/padrows are delivered "as is", without sorting
148   // 2: As 0, but RCU trailer is 3 32 bit words.
149   // 3: As 1, but RCU trailer is 3 32 bit words.
150   // -1: use offline raw reader
151
152   Int_t i = 0;
153   Char_t* cpErr;
154
155   while ( i < argc ) {      
156
157     // -- raw reader mode option
158     if ( !strcmp( argv[i], "rawreadermode" ) ) {
159       if ( argc <= i+1 ) {
160         Logging( kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Missing rawreadermode", "Raw Reader Mode not specified" );
161         return ENOTSUP;
162       }
163
164       // Decodes the rawreader mode: either number or string and returns the rawreadermode
165       // -1 on failure, -2 for offline
166       rawreadermode = AliHLTTPCDigitReaderRaw::DecodeMode( argv[i+1] );
167
168       if (rawreadermode == -1 ) {
169         Logging( kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Missing rawreadermode", "Cannot convert rawreadermode specifier '%s'.", argv[i+1] );
170         return EINVAL;
171       }
172
173       i += 2;
174       continue;
175     }
176
177     // -- pp run option
178     if ( !strcmp( argv[i], "pp-run" ) ) {
179       fClusterDeconv = false;
180       i++;
181       continue;
182     }
183
184     // -- zero suppression threshold
185     if ( !strcmp( argv[i], "adc-threshold" ) ) {
186       sigthresh = strtoul( argv[i+1], &cpErr ,0);
187       if ( *cpErr ) {
188         HLTError("Cannot convert threshold specifier '%s'.", argv[i+1]);
189         return EINVAL;
190       }
191       i+=2;
192       continue;
193     }
194
195     // -- pad occupancy limit
196     if ( !strcmp( argv[i], "occupancy-limit" ) ) {
197       occulimit = strtof( argv[i+1], &cpErr);
198       if ( *cpErr ) {
199         HLTError("Cannot convert occupancy specifier '%s'.", argv[i+1]);
200         return EINVAL;
201       }
202       i+=2;
203       continue;
204     }
205
206     // -- number of timebins (default 1024)
207     if ( !strcmp( argv[i], "timebins" ) ) {
208       TString parameter(argv[i+1]);
209       parameter.Remove(TString::kLeading, ' '); // remove all blanks
210       if (parameter.IsDigit()) {
211         AliHLTTPCTransform::SetNTimeBins(parameter.Atoi());
212         HLTInfo("number of timebins set to %d", AliHLTTPCTransform::GetNTimeBins());
213       } else {
214         HLTError("Cannot timebin specifier '%s'.", argv[i+1]);
215         return EINVAL;
216       }
217       i+=2;
218       continue;
219     }
220
221     // -- checking for rcu format
222     if ( !strcmp( argv[i], "oldrcuformat" ) ) {
223       oldRCUFormat = strtoul( argv[i+1], &cpErr ,0);
224       if ( *cpErr ){
225         HLTError("Cannot convert oldrcuformat specifier '%s'. Should  be 0(off) or 1(on), must be integer", argv[i+1]);
226         return EINVAL;
227       }
228       i+=2;
229       continue;
230     }
231       
232     Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
233     return EINVAL;
234
235   }
236
237   // Choose reader
238
239   if (fPackedSwitch) { 
240     if (rawreadermode == -2) {
241 #if defined(HAVE_ALIRAWDATA) && defined(HAVE_ALITPCRAWSTREAM_H)
242       fReader = new AliHLTTPCDigitReaderPacked();
243       if(oldRCUFormat==1){
244         fReader->SetOldRCUFormat(kTRUE);
245       }
246       else if(oldRCUFormat!=0){
247         HLTWarning("Wrong oldrcuformat specifier %d; oldrcuformat set to default(kFALSE)",oldRCUFormat);
248       }
249       fClusterFinder->SetReader(fReader);
250 #else // ! defined(HAVE_ALIRAWDATA) && defined(HAVE_ALITPCRAWSTREAM_H)
251       HLTFatal("DigitReaderPacked not available - check your build");
252       return -ENODEV;
253 #endif //  defined(HAVE_ALIRAWDATA) && defined(HAVE_ALITPCRAWSTREAM_H)
254     } else {
255 #if defined(HAVE_TPC_MAPPING)
256       fReader = new AliHLTTPCDigitReaderRaw(rawreadermode);
257       fClusterFinder->SetReader(fReader);
258 #else //! defined(HAVE_TPC_MAPPING)
259       HLTFatal("DigitReaderRaw not available - check your build");
260       return -ENODEV;
261 #endif //defined(HAVE_TPC_MAPPING)
262     }
263   }
264   else {
265     fReader = new AliHLTTPCDigitReaderUnpacked();
266     fClusterFinder->SetReader(fReader);
267   }
268
269   // if pp-run use occupancy limit else set to 1. ==> use all 
270   if ( !fClusterDeconv )
271     fClusterFinder->SetOccupancyLimit(occulimit);
272   else 
273     fClusterFinder->SetOccupancyLimit(1.0);
274       
275   // Variables to setup the Clusterfinder
276   // TODO: this sounds strange and has to be verified; is the cluster finder not working when
277   // fClusterDeconv = false ?
278   fClusterDeconv = true;
279   fXYClusterError = -1;
280   fZClusterError = -1;
281
282  
283   fClusterFinder->SetDeconv( fClusterDeconv );
284   fClusterFinder->SetXYError( fXYClusterError );
285   fClusterFinder->SetZError( fZClusterError );
286   if ( (fXYClusterError>0) && (fZClusterError>0) )
287     fClusterFinder->SetCalcErr( false );
288   fClusterFinder->SetSignalThreshold(sigthresh);
289     
290   return 0;
291 }
292
293 int AliHLTTPCClusterFinderComponent::DoDeinit()
294 {
295   // see header file for class documentation
296
297   if ( fClusterFinder )
298     delete fClusterFinder;
299   fClusterFinder = NULL;
300  
301   if ( fReader )
302     delete fReader;
303   fReader = NULL;
304     
305   return 0;
306 }
307
308 int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponentEventData& evtData, 
309                                               const AliHLTComponentBlockData* blocks, 
310                                               AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, 
311                                               AliHLTUInt32_t& size, 
312                                               vector<AliHLTComponentBlockData>& outputBlocks )
313 {
314   // see header file for class documentation
315
316   //  == init iter (pointer to datablock)
317   const AliHLTComponentBlockData* iter = NULL;
318   unsigned long ndx;
319
320   //  == OUTdatatype pointer
321   AliHLTTPCClusterData* outPtr;
322
323   AliHLTUInt8_t* outBPtr;
324   UInt_t offset, mysize, nSize, tSize = 0;
325
326   outBPtr = outputPtr;
327   outPtr = (AliHLTTPCClusterData*)outBPtr;
328
329   Int_t slice, patch, row[2];
330   unsigned long maxPoints, realPoints = 0;
331
332   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
333     {
334       iter = blocks+ndx;
335       mysize = 0;
336       offset = tSize;
337
338
339       if (fPackedSwitch) {      
340         char tmp1[14], tmp2[14];
341         DataType2Text( iter->fDataType, tmp1 );
342         DataType2Text( AliHLTTPCDefinitions::fgkDDLPackedRawDataType, tmp2 );
343         Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Event received", 
344                  "Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
345                  evtData.fEventID, evtData.fEventID, tmp1, tmp2 );
346
347         if ( iter->fDataType != AliHLTTPCDefinitions::fgkDDLPackedRawDataType ) continue;
348
349       }
350       else {
351         char tmp1[14], tmp2[14];
352         DataType2Text( iter->fDataType, tmp1 );
353         DataType2Text( AliHLTTPCDefinitions::fgkUnpackedRawDataType, tmp2 );
354         Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Event received", 
355                  "Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
356                  evtData.fEventID, evtData.fEventID, tmp1, tmp2 );
357
358         if ( iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
359
360       }
361         
362       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
363       patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
364       row[0] = AliHLTTPCTransform::GetFirstRow( patch );
365       row[1] = AliHLTTPCTransform::GetLastRow( patch );
366         
367       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Input Spacepoints", 
368                "Input: Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
369                realPoints, slice, patch, row[0], row[1] );
370         
371       outPtr = (AliHLTTPCClusterData*)outBPtr;
372
373       maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
374
375       fClusterFinder->InitSlice( slice, patch, row[0], row[1], maxPoints );
376       fClusterFinder->SetOutputArray( outPtr->fSpacePoints );
377       fClusterFinder->Read(iter->fPtr, iter->fSize );
378       fClusterFinder->ProcessDigits();
379       realPoints = fClusterFinder->GetNumberOfClusters();
380         
381       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints", 
382                "Number of spacepoints found: %lu.", realPoints );
383         
384       outPtr->fSpacePointCnt = realPoints;
385       nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
386       mysize += nSize+sizeof(AliHLTTPCClusterData);
387         
388       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Input Spacepoints", 
389                "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
390                realPoints, slice, patch, row[0], row[1] );
391       AliHLTComponentBlockData bd;
392       FillBlockData( bd );
393       bd.fOffset = offset;
394       bd.fSize = mysize;
395       bd.fSpecification = iter->fSpecification;
396       //AliHLTSubEventDescriptor::FillBlockAttributes( bd.fAttributes );
397       outputBlocks.push_back( bd );
398         
399       tSize += mysize;
400       outBPtr += mysize;
401       outPtr = (AliHLTTPCClusterData*)outBPtr;
402         
403       if ( tSize > size )
404         {
405           Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data", 
406                    "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
407                    tSize, size );
408           return EMSGSIZE;
409         }
410     }
411     
412   size = tSize;
413
414   return 0;
415 }