correcting compilation warnings (Theodor)
[u/mrichter/AliRoot.git] / HLT / TRD / AliHLTTRDClusterizerComponent.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:                                                       *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
10 //* Permission to use, copy, modify and distribute this software and its   *
11 //* documentation strictly for non-commercial purposes is hereby granted   *
12 //* without fee, provided that the above copyright notice appears in all   *
13 //* copies and that both the copyright notice and this permission notice   *
14 //* appear in the supporting documentation. The authors make no claims     *
15 //* about the suitability of this software for any purpose. It is          *
16 //* provided "as is" without express or implied warranty.                  *
17 //**************************************************************************
18
19 /** @file   AliHLTTRDClusterizerComponent.cxx
20     @author 
21     @date   
22     @brief  A TRDClusterizer processing component for the HLT. 
23 */
24
25 // see header file for class documentation                                   //
26 // or                                                                        //
27 // refer to README to build package                                          //
28 // or                                                                        //
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt                          //
30
31 #if __GNUC__ >= 3
32 using namespace std;
33 #endif
34
35 #include "TTree.h"
36 #include "TFile.h"
37 #include "TBranch.h"
38
39 #include "AliHLTTRDClusterizerComponent.h"
40 #include "AliHLTTRDDefinitions.h"
41 #include "AliHLTTRDCluster.h"
42
43 #include "AliGeomManager.h"
44 #include "AliTRDReconstructor.h"
45 #include "AliCDBManager.h"
46 #include "AliCDBStorage.h"
47 #include "AliCDBEntry.h"
48 #include "AliHLTTRDClusterizer.h"
49 #include "AliTRDrecoParam.h"
50 #include "AliTRDrawStreamBase.h"
51 #include "AliTRDcluster.h"
52
53 #include "AliRawReaderMemory.h"
54
55 #ifdef HAVE_VALGRIND_CALLGRIND_H
56 #include <valgrind/callgrind.h>
57 #else
58 #define CALLGRIND_START_INSTRUMENTATION do { } while (0)
59 #define CALLGRIND_STOP_INSTRUMENTATION do { } while (0)
60 #endif
61
62 #include <cstdlib>
63 #include <cerrno>
64 #include <string>
65
66 #include "AliTRDrawStream.h"
67 #include "AliTRDrawFastStream.h"
68
69 ClassImp(AliHLTTRDClusterizerComponent)
70    
71 AliHLTTRDClusterizerComponent::AliHLTTRDClusterizerComponent()
72 : AliHLTProcessor(),
73   fOutputPercentage(500),
74   fOutputConst(0),
75   fClusterizer(NULL),
76   fRecoParam(NULL),
77   fMemReader(NULL),
78   fReconstructor(NULL),
79   fRecoParamType(-1),
80   fRecoDataType(-1),
81   fRawDataVersion(2),
82   fyPosMethod(1),
83   fgeometryFileName(""),
84   fProcessTracklets(kFALSE),
85   fHLTstreamer(kTRUE)
86 {
87   // Default constructor
88
89 }
90
91 AliHLTTRDClusterizerComponent::~AliHLTTRDClusterizerComponent()
92 {
93   // Destructor
94   // Work is Done in DoDeInit()
95 }
96
97
98 const char* AliHLTTRDClusterizerComponent::GetComponentID()
99 {
100   // Return the component ID const char *
101   return "TRDClusterizer"; // The ID of this component
102 }
103
104 void AliHLTTRDClusterizerComponent::GetInputDataTypes( vector<AliHLTComponent_DataType>& list)
105 {
106   // Get the list of input data
107   list.clear(); // We do not have any requirements for our input data type(s).
108   list.push_back(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTRD);
109 }
110
111 AliHLTComponentDataType AliHLTTRDClusterizerComponent::GetOutputDataType()
112 {
113   // Get the output data type
114   return kAliHLTMultipleDataType;
115 }
116
117 int AliHLTTRDClusterizerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
118 {
119   // Get the output data type
120   tgtList.clear();
121   tgtList.push_back(AliHLTTRDDefinitions::fgkClusterDataType);
122   tgtList.push_back(AliHLTTRDDefinitions::fgkMCMtrackletDataType);
123   return tgtList.size();
124 }
125
126
127 void AliHLTTRDClusterizerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
128 {
129   // Get the output data size
130   constBase = fOutputConst;
131   inputMultiplier = ((double)fOutputPercentage)/100.0;
132 }
133
134 AliHLTComponent* AliHLTTRDClusterizerComponent::Spawn()
135 {
136   // Spawn function, return new instance of this class
137   return new AliHLTTRDClusterizerComponent;
138 };
139
140 int AliHLTTRDClusterizerComponent::DoInit( int argc, const char** argv )
141 {
142   // perform initialization. We check whether our relative output size is specified in the arguments.
143   int iResult=0;
144   
145   fReconstructor = new AliTRDReconstructor();
146   HLTDebug("TRDReconstructor at 0x%x", fReconstructor);
147
148   TString configuration="";
149   TString argument="";
150   for (int i=0; i<argc && iResult>=0; i++) {
151     argument=argv[i];
152     if (!configuration.IsNull()) configuration+=" ";
153     configuration+=argument;
154   }
155
156   if (!configuration.IsNull()) {
157     iResult=Configure(configuration.Data());
158   } else {
159     iResult=Reconfigure(NULL, NULL);
160   }
161
162   if(!fClusterizer){
163     HLTFatal("Clusterizer was not initialized!");
164     return -1;
165   }
166
167   if(iResult<0) return iResult;
168
169   fMemReader = new AliRawReaderMemory;
170   fClusterizer->SetReconstructor(fReconstructor);
171   fClusterizer->SetUseLabels(kFALSE);
172
173   if(fReconstructor->IsProcessingTracklets())
174     fOutputConst = fClusterizer->GetTrMemBlockSize();
175
176   AliTRDrawStream::SetSubtractBaseline(10);
177   AliTRDrawFastStream::SetSubtractBaseline(10);
178
179   return iResult;
180 }
181
182 int AliHLTTRDClusterizerComponent::DoDeinit()
183 {
184   // Deinitialization of the component
185   delete fMemReader;
186   fMemReader = 0;
187   delete fClusterizer;
188   fClusterizer = 0;
189   
190   fReconstructor->SetClusters(0x0);
191   delete fReconstructor;
192   fReconstructor = 0x0;
193   return 0;
194
195   if (fRecoParam)
196     {
197       HLTDebug("Deleting fRecoParam");
198       delete fRecoParam;
199       fRecoParam = 0;
200     }
201 }
202
203 int AliHLTTRDClusterizerComponent::DoEvent( const AliHLTComponentEventData& evtData, 
204                                             const AliHLTComponentBlockData* blocks, 
205                                             AliHLTComponent_TriggerData& /*trigData*/, 
206                                             AliHLTUInt8_t* outputPtr, 
207                                             AliHLTUInt32_t& size, 
208                                             vector<AliHLTComponent_BlockData>& outputBlocks )
209 {
210   // Process an event
211
212   if (evtData.fEventID == 1)
213     CALLGRIND_START_INSTRUMENTATION;
214
215   HLTDebug( "NofBlocks %i", evtData.fBlockCnt );
216   // Process an event
217   AliHLTUInt32_t totalSize = 0, offset = 0;
218
219   //implement a usage of the following
220   //   AliHLTUInt32_t triggerDataStructSize = trigData.fStructSize;
221   //   AliHLTUInt32_t triggerDataSize = trigData.fDataSize;
222   //   void *triggerData = trigData.fData;
223   //HLTDebug( "Trigger data received. Struct size %d Data size %d Data location 0x%x", trigData.fStructSize, trigData.fDataSize, (UInt_t*)trigData.fData);
224
225   // Loop over all input blocks in the event
226   AliHLTComponentDataType expectedDataType = (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTRD);
227   for ( UInt_t iBlock = 0; iBlock < evtData.fBlockCnt; iBlock++ )
228     {      
229       const AliHLTComponentBlockData &block = blocks[iBlock];
230       // lets not use the internal TRD data types here : AliHLTTRDDefinitions::fgkDDLRawDataType
231       // which is depreciated - we use HLT global defs instead
232       //      if ( block.fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTRD) )
233       AliHLTComponentDataType inputDataType = block.fDataType;
234       if ( inputDataType != expectedDataType)
235         {
236           HLTDebug( "Block # %i/%i; Event 0x%08LX (%Lu) Wrong received datatype: %s - required datatype: %s; Skipping",
237                     iBlock, evtData.fBlockCnt,
238                     evtData.fEventID, evtData.fEventID, 
239                     DataType2Text(inputDataType).c_str(), 
240                     DataType2Text(expectedDataType).c_str());
241           continue;
242         }
243       else 
244         {
245           HLTDebug("We get the right data type: Block # %i/%i; Event 0x%08LX (%Lu) Received datatype: %s; Block Size: %i",
246                    iBlock, evtData.fBlockCnt,
247                    evtData.fEventID, evtData.fEventID, 
248                    DataType2Text(inputDataType).c_str(),
249                    block.fSize);
250         }
251       
252 #ifndef NDEBUG
253       unsigned long constBase;
254       double inputMultiplier;
255       GetOutputDataSize(constBase,inputMultiplier);
256       if(size<(constBase+block.fSize*inputMultiplier)){
257         HLTWarning("Memory Block given might be too small: %i < %i; Event %Lu", size, constBase+block.fSize*inputMultiplier, evtData.fEventID);
258       }
259 #endif
260
261       // fMemReader->Reset();
262       fMemReader->SetMemory((UChar_t*) block.fPtr, block.fSize);
263
264       AliHLTUInt32_t spec = block.fSpecification;
265       
266       Int_t id = 1024;
267       
268       for ( Int_t ii = 0; ii < 18 ; ii++ ) {
269         if ( spec & 0x1 ) {
270           id += ii;
271           break;
272         }
273         spec = spec >> 1 ;
274       }
275
276       fMemReader->SetEquipmentID( id ); 
277       
278       fClusterizer->SetMemBlock(outputPtr+offset);
279       Bool_t bclustered = fClusterizer->Raw2ClustersChamber(fMemReader);
280       if(bclustered)
281         {
282           HLTDebug("Clustered successfully");
283         }
284       else
285         {
286           HLTError("Clustering ERROR");
287           return -1;
288         }
289
290       AliHLTUInt32_t addedSize;
291       if(fReconstructor->IsProcessingTracklets()){
292         addedSize = fClusterizer->GetAddedTrSize();
293         totalSize += fClusterizer->GetTrMemBlockSize();  //if IsProcessingTracklets() is enabled we always reserve a data block of size GetTrMemBlockSize() for the tracklets
294         if (addedSize > 0){
295           // Using low-level interface 
296           // with interface classes
297           if ( totalSize > size )
298             {
299               HLTError("Too much data; Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
300                        totalSize, size );
301               return EMSGSIZE;
302             }
303
304           // Fill block 
305           AliHLTComponentBlockData bd;
306           FillBlockData( bd );
307           bd.fOffset = offset;
308           bd.fSize = addedSize;
309           bd.fSpecification = block.fSpecification;
310           bd.fDataType = AliHLTTRDDefinitions::fgkMCMtrackletDataType;
311           outputBlocks.push_back( bd );
312           HLTDebug( "BD ptr 0x%x, offset %i, size %i, dataType %s, spec 0x%x ", bd.fPtr, bd.fOffset, bd.fSize, DataType2Text(bd.fDataType).c_str(), spec);
313         }
314         offset = totalSize;
315       }
316
317       addedSize = fClusterizer->GetAddedClSize();
318       if (addedSize > 0){
319         
320         Int_t* nTimeBins = (Int_t*)(outputPtr+offset+fClusterizer->GetAddedClSize());
321         *nTimeBins = fClusterizer->GetNTimeBins();
322         addedSize += sizeof(*nTimeBins);
323
324         totalSize += addedSize;
325         if ( totalSize > size )
326           {
327             HLTError("Too much data; Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
328                      totalSize, size );
329             return EMSGSIZE;
330           }
331
332         // Fill block 
333         AliHLTComponentBlockData bd;
334         FillBlockData( bd );
335         bd.fOffset = offset;
336         bd.fSize = addedSize;
337         bd.fSpecification = block.fSpecification;
338         bd.fDataType = AliHLTTRDDefinitions::fgkClusterDataType;
339         outputBlocks.push_back( bd );
340         HLTDebug( "BD ptr 0x%x, offset %i, size %i, dataType %s, spec 0x%x ", bd.fPtr, bd.fOffset, bd.fSize, DataType2Text(bd.fDataType).c_str(), spec);
341         offset = totalSize;
342       }
343       else{
344         HLTDebug("Array of clusters is empty!");
345       }
346     }
347   fReconstructor->SetClusters(0x0);
348
349   size = totalSize;
350   HLTDebug("Event is done. size written to the output is %i", size);
351   return 0;
352 }
353
354 void AliHLTTRDClusterizerComponent::PrintObject( TClonesArray* inClustersArray)
355 {
356   AliTRDcluster* cluster=0x0;
357   
358   for (Int_t i=0; i < inClustersArray->GetEntriesFast(); i++){
359     cluster = dynamic_cast<AliTRDcluster*>(inClustersArray->At(i));
360     HLTDebug("cluster[%i]",i);
361     HLTDebug("  PadCol = %i; PadRow = %i; PadTime = %i", cluster->GetPadCol(), cluster->GetPadRow(), cluster->GetPadTime());
362     HLTDebug("  Detector = %i, Amplitude = %f, Center = %f", cluster->GetDetector(), cluster->GetQ(), cluster->GetCenter());
363     HLTDebug("  LocalTimeBin =  %i; NPads = %i; maskedPosition: %s, status: %s", cluster->GetLocalTimeBin(), cluster->GetNPads(),cluster->GetPadMaskedPosition(),cluster->GetPadMaskedPosition());
364   }
365   
366 }
367
368 int AliHLTTRDClusterizerComponent::Configure(const char* arguments){
369   int iResult=0;
370   if (!arguments) return iResult;
371   
372   TString allArgs=arguments;
373   TString argument;
374   int bMissingParam=0;
375
376   TObjArray* pTokens=allArgs.Tokenize(" ");
377   if (pTokens) {
378     for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
379       argument=((TObjString*)pTokens->At(i))->GetString();
380       if (argument.IsNull()) continue;
381       
382       if (argument.CompareTo("output_percentage")==0) {
383         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
384         HLTInfo("Setting output percentage to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
385         fOutputPercentage=((TObjString*)pTokens->At(i))->GetString().Atoi();
386         continue;
387       } 
388       else if (argument.CompareTo("-geometry")==0) {
389         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
390         HLTInfo("Setting geometry to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
391         fgeometryFileName=((TObjString*)pTokens->At(i))->GetString();
392         continue;
393       } 
394       else if (argument.CompareTo("-lowflux")==0) {
395         fRecoParamType = 0;
396         HLTInfo("Low flux reconstruction selected");
397         continue;
398       }
399       else if (argument.CompareTo("-highflux")==0) {
400         fRecoParamType = 1;
401         HLTInfo("High flux reconstruction selected");
402         continue;
403       }
404       else if (argument.CompareTo("-cosmics")==0) {
405         fRecoParamType = 2;
406         HLTInfo("Cosmics reconstruction selected");
407         continue;
408       }
409       else if (argument.CompareTo("-simulation")==0) {
410         fRecoDataType = 0;
411         HLTInfo("Awaiting simulated data");
412         continue;
413       }
414       else if (argument.CompareTo("-experiment")==0) {
415         fRecoDataType = 1;
416         HLTInfo("Awaiting real data");
417         continue;
418       }
419       else if (argument.CompareTo("-processTracklets")==0) {
420         fProcessTracklets = kTRUE;
421         HLTInfo("Writing L1 tracklets to output");
422         continue;
423       }
424       else if (argument.CompareTo("-noZS")==0) {
425         fOutputPercentage = 100;
426         HLTInfo("Awaiting non zero surpressed data");
427         continue;
428       }
429       else if (argument.CompareTo("-faststreamer")==0) {
430         fHLTstreamer = kTRUE;
431         HLTInfo("Useing fast raw streamer");
432         continue;
433       }
434       else if (argument.CompareTo("-nofaststreamer")==0) {
435         fHLTstreamer = kFALSE;
436         HLTInfo("Don't use fast raw streamer");
437         continue;
438       }
439       else if (argument.CompareTo("-rawver")==0) {
440         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
441         HLTInfo("Raw data version is: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
442         fRawDataVersion=((TObjString*)pTokens->At(i))->GetString().Atoi();
443         continue;
444       } 
445       else if (argument.CompareTo("-yPosMethod")==0) {
446         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
447         TString toCompareTo=((TObjString*)pTokens->At(i))->GetString();
448         if (toCompareTo.CompareTo("COG")==0){
449           HLTInfo("Setting yPosMethod method to: %s", toCompareTo.Data());
450           fyPosMethod=0;
451         }
452         else if (toCompareTo.CompareTo("LUT")==0){
453           HLTInfo("Setting yPosMethod method to: %s", toCompareTo.Data());
454           fyPosMethod=1;
455         }
456         else if (toCompareTo.CompareTo("Gauss")==0){
457           HLTInfo("Setting yPosMethod method to: %s", toCompareTo.Data());
458           fyPosMethod=2;
459         }
460         else {
461           HLTError("unknown argument for yPosMethod: %s", toCompareTo.Data());
462           iResult=-EINVAL;
463           break;
464         }
465         continue;
466       }
467       
468       else {
469         HLTError("unknown argument: %s", argument.Data());
470         iResult=-EINVAL;
471         break;
472       }
473     }
474     delete pTokens;
475   }
476   if (bMissingParam) {
477     HLTError("missing parameter for argument %s", argument.Data());
478     iResult=-EINVAL;
479   }
480   if(iResult>=0){
481     iResult=SetParams();
482   }
483   return iResult;
484 }
485
486 int AliHLTTRDClusterizerComponent::SetParams()
487 {
488   Int_t iResult=0;
489   if(!AliCDBManager::Instance()->IsDefaultStorageSet()){
490     HLTError("DefaultStorage is not set in CDBManager");
491     return -EINVAL;
492   }
493   if(AliCDBManager::Instance()->GetRun()<0){
494     HLTError("Run Number is not set in CDBManager");
495     return -EINVAL;
496   }
497   HLTInfo("CDB default storage: %s; RunNo: %i", (AliCDBManager::Instance()->GetDefaultStorage()->GetBaseFolder()).Data(), AliCDBManager::Instance()->GetRun());
498
499   if(!AliGeomManager::GetGeometry()){
500     if(fgeometryFileName.CompareTo("")==0 || !TFile::Open(fgeometryFileName.Data())){
501       HLTInfo("Loading standard geometry file");
502       AliGeomManager::LoadGeometry();
503     }else{
504       HLTWarning("Loading NON-standard geometry file");
505       AliGeomManager::LoadGeometry(fgeometryFileName.Data());
506     }
507     if(!AliGeomManager::GetGeometry()){
508       HLTError("Could not load geometry");
509       return -EINVAL;
510     }
511   }
512   else{
513     HLTInfo("Geometry Already Loaded!");
514   }
515
516   TString recoOptions="hlt,!cw,sl_cl_0";
517
518   switch(fRecoDataType){
519   case 0: recoOptions += ",tc"; break;
520   case 1: recoOptions += ",!tc"; break;
521   }
522   switch(fyPosMethod){
523   case 0: recoOptions += ",!gs,!lut"; break;
524   case 1: recoOptions += ",!gs,lut"; break;
525   case 2: recoOptions += ",gs,!lut"; break;
526   }
527   if(fProcessTracklets) recoOptions += ",tp";
528   else  recoOptions += ",!tp";
529
530
531   if (fRecoParamType == 0)
532     {
533       HLTDebug("Low flux params init.");
534       fRecoParam = AliTRDrecoParam::GetLowFluxParam();
535     }
536
537   if (fRecoParamType == 1)
538     {
539       HLTDebug("High flux params init.");
540       fRecoParam = AliTRDrecoParam::GetHighFluxParam();
541     }
542   
543   if (fRecoParamType == 2)
544     {
545       HLTDebug("Cosmic Test params init.");
546       fRecoParam = AliTRDrecoParam::GetCosmicTestParam();
547     }
548
549   if (fRecoParam == 0)
550     {
551       HLTError("No reco params initialized. Sniffing big trouble!");
552       return -EINVAL;
553     }
554
555   fRecoParam->SetStreamLevel(AliTRDrecoParam::kClusterizer, 0);
556   fReconstructor->SetRecoParam(fRecoParam);
557
558   HLTDebug("Reconstructor options are: %s",recoOptions.Data());
559   fReconstructor->SetOption(recoOptions.Data());
560
561   if (fRecoDataType < 0 || fRecoDataType > 1)
562     {
563       HLTWarning("No data type selected. Use -simulation or -experiment flag. Defaulting to simulation.");
564       fRecoDataType = 0;
565     }
566
567   if (fRecoDataType == 0)
568     {
569       AliTRDrawStreamBase::SetRawStreamVersion(AliTRDrawStreamBase::kTRDsimStream);
570       HLTDebug("Data type expected is SIMULATION!");
571     }
572
573   if (fRecoDataType == 1)
574     {
575       AliTRDrawStreamBase::SetRawStreamVersion(AliTRDrawStreamBase::kTRDrealStream);
576       HLTDebug("Data type expected is EXPERIMENT!");
577     }
578
579   if (fHLTstreamer)
580     {
581       AliTRDrawStreamBase::SetRawStreamVersion("FAST");
582       HLTDebug("fast rawstreamer used");  
583     }
584
585   if(!fClusterizer){
586     fClusterizer = new AliHLTTRDClusterizer("TRDCclusterizer", "TRDCclusterizer");  
587     HLTDebug("TRDClusterizer at 0x%x", fClusterizer);
588   }
589
590   fClusterizer->SetRawVersion(fRawDataVersion);
591
592   return iResult;
593 }
594
595 int AliHLTTRDClusterizerComponent::Reconfigure(const char* cdbEntry, const char* chainId)
596 {
597   // see header file for class documentation
598
599   int iResult=0;
600   const char* path="HLT/ConfigTRD/ClusterizerComponent";
601   const char* defaultNotify="";
602   if (cdbEntry) {
603     path=cdbEntry;
604     defaultNotify=" (default)";
605   }
606   if (path) {
607     HLTInfo("reconfigure from entry %s%s, chain id %s", path, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
608     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
609     if (pEntry) {
610       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
611       if (pString) {
612         HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
613         iResult=Configure(pString->GetString().Data());
614       } else {
615         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
616       }
617     } else {
618       HLTError("cannot fetch object \"%s\" from CDB", path);
619     }
620   }
621
622   return iResult;
623 }