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