]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONClusterFinderComponent.cxx
Improving documentation and macros.
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONClusterFinderComponent.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        *
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Artur Szostak <artursz@iafrica.com>                                  *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          *
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 // $Id:  $
18
19 ///
20 /// @file   AliHLTMUONClusterFinderComponent.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @date   28 May 2007
23 /// @brief  Implementation of the offline algorithm cluster finding processing component.
24 ///
25 /// The cluster finder component interfaces the offline MUON reconstruction
26 /// algorithms for cluster finding with the online HLT system.
27 ///
28
29 #include "AliHLTMUONClusterFinderComponent.h"
30 #include "AliHLTMUONConstants.h"
31 #include "AliHLTMUONUtils.h"
32 #include "AliHLTMUONDataBlockWriter.h"
33 #include "AliHLTLogging.h"
34 #include "AliHLTSystem.h"
35 #include "AliHLTDefinitions.h"
36 #include "AliMUONGeometryTransformer.h"
37 #include "AliMUONCalibrationData.h"
38 #include "AliMUONVCalibParam.h"
39 #include "AliMUONVDigitStore.h"
40 #include "AliMUONVClusterStore.h"
41 #include "AliMUONClusterStoreV2.h"
42 #include "AliMUONDigitMaker.h"
43 #include "AliMUONDigitCalibrator.h"
44 #include "AliMUONCalibrationData.h"
45 #include "AliMUONGeometryTransformer.h"
46 #include "AliMUONVClusterFinder.h"
47 #include "AliMUONSimpleClusterServer.h"
48 #include "AliMUONRecoParam.h"
49 #include "AliMUONReconstructor.h"
50 #include "AliMUONVCluster.h"
51 #include "AliMUONRawStreamTrackerHP.h"
52 #include "AliMpConstants.h"
53 #include "AliMpCDB.h"
54 #include "AliMpArea.h"
55 #include "AliRawReader.h"
56 #include "AliRawReaderMemory.h"
57 #include "AliCDBManager.h"
58 #include "AliGeomManager.h"
59 #include "TMap.h"
60 #include <cstdlib>
61 #include <cerrno>
62 #include <cassert>
63
64
65 ClassImp(AliHLTMUONClusterFinderComponent)
66
67
68 AliHLTMUONClusterFinderComponent::AliHLTMUONClusterFinderComponent() :
69         AliHLTMUONProcessor(),
70         fRawReader(NULL),
71         fDigitMaker(NULL),
72         fTransformer(NULL),
73         fCalibrationData(NULL),
74         fDigitCalibrator(NULL),
75         fClusterFinder(NULL),
76         fClusterServer(NULL),
77         fRecoParam(NULL),
78         fMakeClusterStore(true),
79         fMakeRecHits(false)
80 {
81         /// Default constructor.
82 }
83
84
85 AliHLTMUONClusterFinderComponent::~AliHLTMUONClusterFinderComponent()
86 {
87         /// Default destructor.
88         
89         FreeObjects();
90 }
91
92 const char* AliHLTMUONClusterFinderComponent::GetComponentID()
93 {
94         /// Inherited from AliHLTComponent. Returns the component ID.
95         
96         return AliHLTMUONConstants::ClusterFinderId();
97 }
98
99
100 void AliHLTMUONClusterFinderComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
101 {
102         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
103         
104         list.clear();
105         list.push_back( AliHLTMUONConstants::DDLRawDataType() );
106 }
107
108
109 AliHLTComponentDataType AliHLTMUONClusterFinderComponent::GetOutputDataType()
110 {
111         /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
112         /// refer to GetOutputDataTypes for all returned data types.
113         
114         return kAliHLTMultipleDataType;
115 }
116
117
118 int AliHLTMUONClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
119 {
120         /// Inherited from AliHLTComponent. Returns the output data types.
121         
122         assert( list.empty() );
123         list.push_back( AliHLTMUONConstants::ClusterStoreDataType() );
124         list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
125         return list.size();
126 }
127
128
129 void AliHLTMUONClusterFinderComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
130 {
131         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
132         
133         constBase = sizeof(AliMUONVClusterStore) + 1024*1024;
134         inputMultiplier = 1;
135 }
136
137
138 AliHLTComponent* AliHLTMUONClusterFinderComponent::Spawn()
139 {
140         /// Inherited from AliHLTComponent. Creates a new object instance.
141         
142         return new AliHLTMUONClusterFinderComponent;
143 }
144
145
146 int AliHLTMUONClusterFinderComponent::DoInit(int argc, const char** argv)
147 {
148         /// Inherited from AliHLTComponent.
149         /// Parses the command line parameters and initialises the component.
150
151         HLTInfo("Initialising dHLT cluster finder component.");
152
153         // Inherit the parents functionality.
154         int result = AliHLTMUONProcessor::DoInit(argc, argv);
155         if (result != 0) return result;
156         
157         // Must make sure that all the offline reconstruction objects are released in case
158         // they are still allocated for whatever reason.
159         FreeObjects();
160         
161         // Initialise fields with default values then parse the command line.
162         fMakeClusterStore = true;
163         fMakeRecHits = false;
164         bool tryRecover = false;
165         
166         for (int i = 0; i < argc; i++)
167         {
168                 if (ArgumentAlreadyHandled(i, argv[i])) continue;
169                 
170                 if (strcmp( argv[i], "-tryrecover" ) == 0)
171                 {
172                         tryRecover = true;
173                         continue;
174                 }
175                 
176                 if (strcmp( argv[i], "-nostore" ) == 0)
177                 {
178                         fMakeClusterStore = false;
179                         continue;
180                 }
181                 
182                 if (strcmp( argv[i], "-makehits" ) == 0)
183                 {
184                         fMakeRecHits = true;
185                         continue;
186                 }
187                 
188                 HLTError("Unknown option '%s'", argv[i]);
189                 return -EINVAL;
190         
191         } // for loop
192
193         try
194         {
195                 fRawReader = new AliRawReaderMemory();
196                 fDigitMaker = new AliMUONDigitMaker(true, true, true);
197                 fTransformer = new AliMUONGeometryTransformer();
198         }
199         catch (const std::bad_alloc&)
200         {
201                 HLTError("Could not allocate more memory for the MUON offline reconstruction objects.");
202                 FreeObjects();
203                 return -ENOMEM;
204         }
205         
206         if (not DelaySetup())
207         {
208                 result = ReadConfigFromCDB();
209                 if (result != 0)
210                 {
211                         // Error messages already generated in ReadConfigFromCDB.
212                         FreeObjects(); // Make sure we cleanup to avoid partial initialisation.
213                         return result;
214                 }
215         }
216
217 #ifndef HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM   
218         AliMUONRawStreamTrackerHP* stream = static_cast<AliMUONRawStreamTrackerHP*>(
219                         fDigitMaker->GetRawStreamTracker()
220                 );
221         stream->TryRecover(tryRecover);
222 #endif //HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM
223         
224         return 0;
225 }
226
227
228 int AliHLTMUONClusterFinderComponent::DoDeinit()
229 {
230         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
231         
232         HLTInfo("Deinitialising dHLT cluster finder component.");
233         FreeObjects();
234         return 0;
235 }
236
237
238 int AliHLTMUONClusterFinderComponent::Reconfigure(
239                 const char* cdbEntry, const char* componentId
240         )
241 {
242         /// Inherited from AliHLTComponent. This method will reload CDB configuration
243         /// entries for this component from the CDB.
244         /// \param cdbEntry If set to NULL or starts with "MUON/" then the DDL store
245         ///      for MUON will be loaded which contains the mapping and also the
246         ///      calibration data will be updated.
247         /// \param componentId  The name of the component in the current chain.
248         
249         bool startsWithMUON = TString(cdbEntry).Index("MUON/", 5, 0, TString::kExact) == 0;
250         
251         if (cdbEntry == NULL or startsWithMUON)
252         {
253                 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
254                 
255                 //TODO: add more granularity to the loading.
256                 return ReadConfigFromCDB();
257         }
258         
259         return 0;
260 }
261
262
263 int AliHLTMUONClusterFinderComponent::ReadPreprocessorValues(const char* modules)
264 {
265         /// Inherited from AliHLTComponent. 
266         /// Updates the configuration of this component if either HLT or MUON have
267         /// been specified in the 'modules' list.
268
269         TString mods = modules;
270         if (mods.Contains("ALL") or mods.Contains("MUON"))
271         {
272                 return Reconfigure(NULL, GetComponentID());
273         }
274         if (mods.Contains("MUON"))
275         {
276                 return Reconfigure("MUON/*", GetComponentID());
277         }
278         return 0;
279 }
280
281
282 int AliHLTMUONClusterFinderComponent::DoEvent(
283                 const AliHLTComponentEventData& evtData,
284                 const AliHLTComponentBlockData* blocks,
285                 AliHLTComponentTriggerData& trigData,
286                 AliHLTUInt8_t* outputPtr,
287                 AliHLTUInt32_t& size,
288                 AliHLTComponentBlockDataList& outputBlocks
289         )
290 {
291         /// Inherited from AliHLTProcessor. Processes the new event data by
292         /// applying the offline cluster finding algorithms.
293         
294         // Initialise the mapping and calibration from CDB if we were requested
295         // to initialise only when the first event was received.
296         if (DelaySetup())
297         {
298                 int result = ReadConfigFromCDB();
299                 if (result != 0) return result;
300                 DoneDelayedSetup();
301         }
302         
303         assert(fRawReader != NULL);
304         assert(fDigitMaker != NULL);
305         assert(fTransformer != NULL);
306         assert(fCalibrationData != NULL);
307         assert(fDigitCalibrator != NULL);
308         assert(fClusterFinder != NULL);
309         assert(fClusterServer != NULL);
310         
311         AliHLTUInt32_t specification = 0x0;  // Accumulated specification to use for output blocks.
312         
313         HLTDebug("Processing event %llu with %u input data blocks.",
314                 evtData.fEventID, evtData.fBlockCnt
315         );
316
317         AliMUONVDigitStore* digitStore = NULL;
318         AliMUONVClusterStore* clusterStore = NULL;
319         try
320         {
321                 digitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
322                 clusterStore = new AliMUONClusterStoreV2();
323         }
324         catch (const std::bad_alloc&)
325         {
326                 HLTError("Could not allocate more memory for the digit or cluster store object.");
327                 if (digitStore != NULL) delete digitStore;
328                 if (clusterStore != NULL) delete clusterStore;
329                 size = 0;
330                 return -ENOMEM;
331         }
332
333         const AliHLTComponentBlockData* block = NULL;
334         const AliHLTComponentDataType& rawType = AliHLTMUONConstants::DDLRawDataType();
335         for (block = GetFirstInputBlock(rawType); block != NULL; block = GetNextInputBlock())
336         {
337                 HLTDebug("Handling block with fDataType = '%s', fSpecification = 0x%8.8X, fPtr = %p and fSize = %u bytes.",
338                         DataType2Text(block->fDataType).c_str(), block->fSpecification,
339                         block->fPtr, block->fSize
340                 );
341
342                 if (not AliHLTMUONUtils::IsTrackerDDL(block->fSpecification))
343                 {
344                         HLTError("Received raw data from a DDL that was not a tracker DDL."
345                                 " The data block specification was: 0x%8.8X."
346                                 " Will skip the data block.",
347                                 block->fSpecification
348                         );
349                         continue;
350                 }
351
352                 specification |= block->fSpecification;
353
354                 fRawReader->SetMemory(reinterpret_cast<UChar_t*>(block->fPtr), ULong_t(block->fSize));
355                 fRawReader->SetEquipmentID(AliHLTMUONUtils::SpecToEquipId(block->fSpecification));
356                 fRawReader->Reset();
357                 fRawReader->NextEvent();
358                 fDigitMaker->Raw2Digits(fRawReader, digitStore, NULL);
359 #ifndef HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM
360                 if (fDigitMaker->GetRawStreamTracker()->IsErrorMessage() and DumpDataOnError())
361                 {
362                         DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
363                 }
364 #endif //HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM
365         }
366
367         fDigitCalibrator->Calibrate(*digitStore);
368         TIter next(digitStore->CreateIterator());
369         fClusterServer->UseDigits(next);
370         AliMpArea area;
371         for (Int_t i = 0; i < AliMpConstants::NofTrackingChambers(); ++i)
372         {
373                 if (fRecoParam->UseChamber(i))
374                 {
375                         if ( ( i == 6 or i == 7 ) and fRecoParam->BypassSt4() ) continue;
376                         if ( ( i == 8 or i == 9 ) and fRecoParam->BypassSt5() ) continue;
377                         fClusterServer->Clusterize(i, *clusterStore, area);
378                 }
379         }
380         
381         // Now write the clusters to output blocks.
382         AliHLTUInt8_t* buffer = outputPtr;
383         AliHLTUInt32_t bufferSize = size;
384
385         if (fMakeClusterStore)
386         {
387                 PushBack(clusterStore, AliHLTMUONConstants::ClusterStoreDataType(), specification);
388         
389                 if (fMakeRecHits)
390                 {
391                         try
392                         {
393                                 bufferSize = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType)
394                                         + sizeof(AliHLTMUONRecHitsBlockWriter::ElementType) * clusterStore->GetSize();
395                                 buffer = new AliHLTUInt8_t[size];
396                         }
397                         catch (const std::bad_alloc&)
398                         {
399                                 HLTError("Could not allocate more memory for the reconstructed hit buffer.");
400                                 if (digitStore != NULL) delete digitStore;
401                                 if (clusterStore != NULL) delete clusterStore;
402                                 return -ENOMEM;
403                         }
404                 }
405         }
406
407         if (fMakeRecHits)
408         {
409                 AliHLTMUONRecHitsBlockWriter outBlock(buffer, bufferSize);
410                 outBlock.InitCommonHeader();
411                 AliHLTUInt32_t i = 0;
412                 TIter next2(clusterStore->CreateIterator());
413                 AliMUONVCluster* cluster = NULL;
414                 while ( (cluster = static_cast<AliMUONVCluster*>(next2())) != NULL )
415                 {
416                         AliHLTMUONRecHitStruct& hit = outBlock[i++];
417                         hit.fFlags = AliHLTMUONUtils::PackRecHitFlags(
418                                         AliHLTUInt8_t(cluster->GetChamberId()),
419                                         AliHLTUInt16_t(cluster->GetDetElemId())
420                                 );
421                         hit.fX = cluster->GetX();
422                         hit.fY = cluster->GetY();
423                         hit.fZ = cluster->GetZ();
424                 }
425                 outBlock.SetNumberOfEntries(i);
426
427                 PushBack(
428                         buffer, outBlock.BytesUsed(),
429                         AliHLTMUONConstants::RecHitsBlockDataType(), specification
430                 );
431
432                 if (fMakeClusterStore)
433                 {
434                         delete [] buffer;
435                 }
436         }
437
438         delete digitStore;
439         delete clusterStore;
440
441         return 0;
442 }
443
444
445 void AliHLTMUONClusterFinderComponent::FreeObjects()
446 {
447         /// Deletes any allocated objects, if they are allocated, else nothing is
448         /// done for objects not yet allocated.
449         /// This is used as a helper method to make sure the corresponding pointers
450         /// are NULL and we get back to a well defined state.
451
452         if (fRawReader != NULL)
453         {
454                 delete fRawReader;
455                 fRawReader = NULL;
456         }
457         if (fDigitMaker != NULL)
458         {
459                 delete fDigitMaker;
460                 fDigitMaker = NULL;
461         }
462         if (fTransformer != NULL)
463         {
464                 delete fTransformer;
465                 fTransformer = NULL;
466         }
467         if (fCalibrationData != NULL)
468         {
469                 delete fCalibrationData;
470                 fCalibrationData = NULL;
471         }
472         if (fDigitCalibrator != NULL)
473         {
474                 delete fDigitCalibrator;
475                 fDigitCalibrator = NULL;
476         }
477         if (fClusterServer != NULL)
478         {
479                 delete fClusterServer;
480                 fClusterServer = NULL;
481                 fClusterFinder = NULL;  // The cluster server takes ownership.
482         }
483
484         // The following is just in case we created the cluster finder, but could
485         // not yet create the cluster server.
486         if (fClusterFinder != NULL)
487         {
488                 delete fClusterFinder;
489                 fClusterFinder = NULL;
490         }
491
492         if (fRecoParam != NULL)
493         {
494                 delete fRecoParam;
495                 fRecoParam = NULL;
496         }
497 }
498
499
500 int AliHLTMUONClusterFinderComponent::ReadConfigFromCDB(
501                 bool loadParams, bool loadMapping, bool loadGeom, bool loadCalib
502         )
503 {
504         /// Loads the various configuration, calibration, mapping and geometry
505         /// data from CDB.
506
507         if (loadMapping)
508         {
509                 HLTInfo("Loading mapping information from CDB.");
510                 int result = FetchMappingStores();
511                 if (result != 0) return result;
512         }
513
514         if (loadParams)
515         {
516                 HLTInfo("Loading reconstruction parameters from CDB.");
517                 AliMUONRecoParam* recoParam = NULL;
518                 try
519                 {
520                         //TODO:
521                         HLTWarning("Have not yet implemented loading reco params from CDB! Using AliMUONRecoParam::GetLowFluxParam().");
522                         //result = LoadRecoParamsFromCDB(recoParam);
523                         //if (result != 0) return result;
524                         recoParam = AliMUONRecoParam::GetLowFluxParam();
525                 }
526                 catch (const std::bad_alloc&)
527                 {
528                         HLTError("Could not allocate more memory for the reconstruction parameter object.");
529                         return -ENOMEM;
530                 }
531                 if (fRecoParam != NULL) delete fRecoParam;
532                 fRecoParam = recoParam;
533         }
534
535         if (loadGeom)
536         {
537                 HLTInfo("Loading geometry data from CDB.");
538                 // Only load geometry if not already loaded.
539                 if (AliGeomManager::GetGeometry() == NULL)
540                 {
541                         AliGeomManager::LoadGeometry();
542                 }
543                 assert(fTransformer != NULL);
544                 if (not fTransformer->LoadGeometryData())
545                 {
546                         HLTError("Could not load geometry data for transformation.");
547                         return -ENOENT;
548                 }
549         }
550
551         if (loadCalib)
552         {
553                 assert(fRecoParam != NULL);
554
555                 HLTInfo("Loading calibration information from CDB.");
556                 AliMUONCalibrationData* calibData = NULL;
557                 try
558                 {
559                         assert(AliCDBManager::Instance() != NULL);
560                         Int_t runNumber = AliCDBManager::Instance()->GetRun();
561                         calibData = new AliMUONCalibrationData(runNumber);
562                 }
563                 catch (const std::bad_alloc&)
564                 {
565                         HLTError("Could not allocate more memory for the calibration data object.");
566                         return -ENOMEM;
567                 }
568                 
569                 if (not calibData->IsValid())
570                 {
571                         HLTError("Could not retrieve calibrations!");
572                         delete calibData;
573                         return -ENOENT;
574                 }
575
576                 // Check that we get all the calibrations we'll need.
577                 if (not calibData->Pedestals() or
578                     not calibData->Gains() or
579                     not calibData->HV() )
580                 {
581                         HLTError("Could not access all required calibration data.");
582                         delete calibData;
583                         return -ENOENT;
584                 }
585                 
586                 if (fCalibrationData != NULL) delete fCalibrationData;
587                 fCalibrationData = calibData;
588
589
590                 AliMUONDigitCalibrator* calibrator = NULL;
591                 AliMUONVClusterFinder* clusterFinder = NULL;
592                 AliMUONSimpleClusterServer* clusterServer = NULL;
593                 try
594                 {
595                         calibrator = new AliMUONDigitCalibrator(
596                                         *fCalibrationData, fRecoParam->GetCalibrationMode()
597                                 );
598                 
599                         clusterFinder = AliMUONReconstructor::CreateClusterFinder(
600                                         fRecoParam->GetClusteringMode()
601                                 );
602         
603                         clusterServer = new AliMUONSimpleClusterServer(clusterFinder, *fTransformer);
604                 }
605                 catch (const std::bad_alloc&)
606                 {
607                         HLTError("Could not allocate more memory for a offline reconstruction object.");
608                         if (calibrator != NULL) delete calibrator;
609                         if (clusterFinder != NULL) delete clusterFinder;
610                         if (clusterServer != NULL) delete clusterServer;
611                         return -ENOMEM;
612                 }
613                 
614                 if (fDigitCalibrator != NULL) delete fDigitCalibrator;
615                 fDigitCalibrator = calibrator;
616                 if (fClusterFinder != NULL) delete fClusterFinder;
617                 fClusterFinder = clusterFinder;
618                 if (fClusterServer != NULL) delete fClusterServer;
619                 fClusterServer = clusterServer;
620         }
621
622         return 0;
623 }
624