Line data Source code
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 6 : ClassImp(AliHLTMUONClusterFinderComponent)
66 :
67 :
68 : AliHLTMUONClusterFinderComponent::AliHLTMUONClusterFinderComponent() :
69 3 : AliHLTMUONProcessor(),
70 3 : fRawReader(NULL),
71 3 : fDigitMaker(NULL),
72 3 : fTransformer(NULL),
73 3 : fCalibrationData(NULL),
74 3 : fDigitCalibrator(NULL),
75 3 : fClusterFinder(NULL),
76 3 : fClusterServer(NULL),
77 3 : fRecoParam(NULL),
78 3 : fMakeClusterStore(true),
79 3 : fMakeRecHits(false)
80 15 : {
81 : /// Default constructor.
82 6 : }
83 :
84 :
85 : AliHLTMUONClusterFinderComponent::~AliHLTMUONClusterFinderComponent()
86 18 : {
87 : /// Default destructor.
88 :
89 3 : FreeObjects();
90 9 : }
91 :
92 : const char* AliHLTMUONClusterFinderComponent::GetComponentID()
93 : {
94 : /// Inherited from AliHLTComponent. Returns the component ID.
95 :
96 180 : 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 0 : list.clear();
105 0 : list.push_back( AliHLTMUONConstants::DDLRawDataType() );
106 0 : }
107 :
108 :
109 : AliHLTComponentDataType AliHLTMUONClusterFinderComponent::GetOutputDataType()
110 : {
111 : /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
112 : /// refer to GetOutputDataTypes for all returned data types.
113 :
114 0 : return kAliHLTMultipleDataType;
115 : }
116 :
117 :
118 : int AliHLTMUONClusterFinderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
119 : {
120 : /// Inherited from AliHLTComponent. Returns the output data types.
121 :
122 0 : assert( list.empty() );
123 0 : list.push_back( AliHLTMUONConstants::ClusterStoreDataType() );
124 0 : list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
125 0 : 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 0 : constBase = sizeof(AliMUONVClusterStore) + 1024*1024;
134 0 : inputMultiplier = 1;
135 0 : }
136 :
137 :
138 : AliHLTComponent* AliHLTMUONClusterFinderComponent::Spawn()
139 : {
140 : /// Inherited from AliHLTComponent. Creates a new object instance.
141 :
142 0 : return new AliHLTMUONClusterFinderComponent;
143 0 : }
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 0 : HLTInfo("Initialising dHLT cluster finder component.");
152 :
153 : // Inherit the parents functionality.
154 0 : int result = AliHLTMUONProcessor::DoInit(argc, argv);
155 0 : 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 0 : FreeObjects();
160 :
161 : // Initialise fields with default values then parse the command line.
162 0 : fMakeClusterStore = true;
163 0 : fMakeRecHits = false;
164 : bool tryRecover = false;
165 :
166 0 : for (int i = 0; i < argc; i++)
167 : {
168 0 : if (ArgumentAlreadyHandled(i, argv[i])) continue;
169 :
170 0 : if (strcmp( argv[i], "-tryrecover" ) == 0)
171 : {
172 : tryRecover = true;
173 0 : continue;
174 : }
175 :
176 0 : if (strcmp( argv[i], "-nostore" ) == 0)
177 : {
178 0 : fMakeClusterStore = false;
179 0 : continue;
180 : }
181 :
182 0 : if (strcmp( argv[i], "-makehits" ) == 0)
183 : {
184 0 : fMakeRecHits = true;
185 0 : continue;
186 : }
187 :
188 0 : HLTError("Unknown option '%s'", argv[i]);
189 0 : return -EINVAL;
190 :
191 : } // for loop
192 :
193 : try
194 : {
195 0 : fRawReader = new AliRawReaderMemory();
196 0 : fDigitMaker = new AliMUONDigitMaker(true, true, true);
197 0 : fTransformer = new AliMUONGeometryTransformer();
198 0 : }
199 : catch (const std::bad_alloc&)
200 : {
201 0 : HLTError("Could not allocate more memory for the MUON offline reconstruction objects.");
202 0 : FreeObjects();
203 : return -ENOMEM;
204 0 : }
205 :
206 0 : if (not DelaySetup())
207 : {
208 0 : result = ReadConfigFromCDB();
209 0 : if (result != 0)
210 : {
211 : // Error messages already generated in ReadConfigFromCDB.
212 0 : FreeObjects(); // Make sure we cleanup to avoid partial initialisation.
213 0 : return result;
214 : }
215 : }
216 :
217 : #ifndef HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM
218 : AliMUONRawStreamTrackerHP* stream = static_cast<AliMUONRawStreamTrackerHP*>(
219 0 : fDigitMaker->GetRawStreamTracker()
220 : );
221 0 : stream->TryRecover(tryRecover);
222 : #endif //HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM
223 :
224 : return 0;
225 0 : }
226 :
227 :
228 : int AliHLTMUONClusterFinderComponent::DoDeinit()
229 : {
230 : /// Inherited from AliHLTComponent. Performs a cleanup of the component.
231 :
232 0 : HLTInfo("Deinitialising dHLT cluster finder component.");
233 0 : FreeObjects();
234 0 : 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 0 : bool startsWithMUON = TString(cdbEntry).Index("MUON/", 5, 0, TString::kExact) == 0;
250 :
251 0 : if (cdbEntry == NULL or startsWithMUON)
252 : {
253 0 : HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
254 :
255 : //TODO: add more granularity to the loading.
256 0 : return ReadConfigFromCDB();
257 : }
258 :
259 0 : return 0;
260 0 : }
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 0 : TString mods = modules;
270 0 : if (mods.Contains("ALL") or mods.Contains("MUON"))
271 : {
272 0 : return Reconfigure(NULL, GetComponentID());
273 : }
274 0 : if (mods.Contains("MUON"))
275 : {
276 0 : return Reconfigure("MUON/*", GetComponentID());
277 : }
278 0 : return 0;
279 0 : }
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 0 : if (DelaySetup())
297 : {
298 0 : int result = ReadConfigFromCDB();
299 0 : if (result != 0) return result;
300 0 : DoneDelayedSetup();
301 0 : }
302 :
303 0 : assert(fRawReader != NULL);
304 0 : assert(fDigitMaker != NULL);
305 0 : assert(fTransformer != NULL);
306 0 : assert(fCalibrationData != NULL);
307 0 : assert(fDigitCalibrator != NULL);
308 0 : assert(fClusterFinder != NULL);
309 0 : 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 0 : digitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
322 0 : clusterStore = new AliMUONClusterStoreV2();
323 0 : }
324 : catch (const std::bad_alloc&)
325 : {
326 0 : HLTError("Could not allocate more memory for the digit or cluster store object.");
327 0 : if (digitStore != NULL) delete digitStore;
328 0 : if (clusterStore != NULL) delete clusterStore;
329 0 : size = 0;
330 : return -ENOMEM;
331 0 : }
332 :
333 : const AliHLTComponentBlockData* block = NULL;
334 0 : const AliHLTComponentDataType& rawType = AliHLTMUONConstants::DDLRawDataType();
335 0 : 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 0 : if (not AliHLTMUONUtils::IsTrackerDDL(block->fSpecification))
343 : {
344 0 : 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 0 : specification |= block->fSpecification;
353 :
354 0 : fRawReader->SetMemory(reinterpret_cast<UChar_t*>(block->fPtr), ULong_t(block->fSize));
355 0 : fRawReader->SetEquipmentID(AliHLTMUONUtils::SpecToEquipId(block->fSpecification));
356 0 : fRawReader->Reset();
357 0 : fRawReader->NextEvent();
358 0 : fDigitMaker->Raw2Digits(fRawReader, digitStore, NULL);
359 : #ifndef HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM
360 0 : if (fDigitMaker->GetRawStreamTracker()->IsErrorMessage() and DumpDataOnError())
361 : {
362 0 : DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
363 0 : }
364 : #endif //HAVE_NOT_MUON_DIGITMAKER_GETRAWSTREAM
365 : }
366 :
367 0 : fDigitCalibrator->Calibrate(*digitStore);
368 0 : TIter next(digitStore->CreateIterator());
369 0 : fClusterServer->UseDigits(next);
370 0 : AliMpArea area;
371 0 : for (Int_t i = 0; i < AliMpConstants::NofTrackingChambers(); ++i)
372 : {
373 0 : if (fRecoParam->UseChamber(i))
374 : {
375 0 : if ( ( i == 6 or i == 7 ) and fRecoParam->BypassSt4() ) continue;
376 0 : if ( ( i == 8 or i == 9 ) and fRecoParam->BypassSt5() ) continue;
377 0 : fClusterServer->Clusterize(i, *clusterStore, area);
378 : }
379 : }
380 :
381 : // Now write the clusters to output blocks.
382 : AliHLTUInt8_t* buffer = outputPtr;
383 0 : AliHLTUInt32_t bufferSize = size;
384 :
385 0 : if (fMakeClusterStore)
386 : {
387 0 : PushBack(clusterStore, AliHLTMUONConstants::ClusterStoreDataType(), specification);
388 :
389 0 : if (fMakeRecHits)
390 : {
391 : try
392 : {
393 0 : bufferSize = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType)
394 0 : + sizeof(AliHLTMUONRecHitsBlockWriter::ElementType) * clusterStore->GetSize();
395 0 : buffer = new AliHLTUInt8_t[size];
396 0 : }
397 : catch (const std::bad_alloc&)
398 : {
399 0 : HLTError("Could not allocate more memory for the reconstructed hit buffer.");
400 0 : if (digitStore != NULL) delete digitStore;
401 0 : if (clusterStore != NULL) delete clusterStore;
402 : return -ENOMEM;
403 0 : }
404 0 : }
405 : }
406 :
407 0 : if (fMakeRecHits)
408 : {
409 0 : AliHLTMUONRecHitsBlockWriter outBlock(buffer, bufferSize);
410 0 : outBlock.InitCommonHeader();
411 : AliHLTUInt32_t i = 0;
412 0 : TIter next2(clusterStore->CreateIterator());
413 : AliMUONVCluster* cluster = NULL;
414 0 : while ( (cluster = static_cast<AliMUONVCluster*>(next2())) != NULL )
415 : {
416 0 : AliHLTMUONRecHitStruct& hit = outBlock[i++];
417 0 : hit.fFlags = AliHLTMUONUtils::PackRecHitFlags(
418 0 : AliHLTUInt8_t(cluster->GetChamberId()),
419 0 : AliHLTUInt16_t(cluster->GetDetElemId())
420 : );
421 0 : hit.fX = cluster->GetX();
422 0 : hit.fY = cluster->GetY();
423 0 : hit.fZ = cluster->GetZ();
424 : }
425 0 : outBlock.SetNumberOfEntries(i);
426 :
427 0 : PushBack(
428 0 : buffer, outBlock.BytesUsed(),
429 0 : AliHLTMUONConstants::RecHitsBlockDataType(), specification
430 : );
431 :
432 0 : if (fMakeClusterStore)
433 : {
434 0 : delete [] buffer;
435 : }
436 0 : }
437 :
438 0 : delete digitStore;
439 0 : delete clusterStore;
440 :
441 0 : return 0;
442 0 : }
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 6 : if (fRawReader != NULL)
453 : {
454 0 : delete fRawReader;
455 0 : fRawReader = NULL;
456 0 : }
457 3 : if (fDigitMaker != NULL)
458 : {
459 0 : delete fDigitMaker;
460 0 : fDigitMaker = NULL;
461 0 : }
462 3 : if (fTransformer != NULL)
463 : {
464 0 : delete fTransformer;
465 0 : fTransformer = NULL;
466 0 : }
467 3 : if (fCalibrationData != NULL)
468 : {
469 0 : delete fCalibrationData;
470 0 : fCalibrationData = NULL;
471 0 : }
472 3 : if (fDigitCalibrator != NULL)
473 : {
474 0 : delete fDigitCalibrator;
475 0 : fDigitCalibrator = NULL;
476 0 : }
477 3 : if (fClusterServer != NULL)
478 : {
479 0 : delete fClusterServer;
480 0 : fClusterServer = NULL;
481 0 : fClusterFinder = NULL; // The cluster server takes ownership.
482 0 : }
483 :
484 : // The following is just in case we created the cluster finder, but could
485 : // not yet create the cluster server.
486 3 : if (fClusterFinder != NULL)
487 : {
488 0 : delete fClusterFinder;
489 0 : fClusterFinder = NULL;
490 0 : }
491 :
492 3 : if (fRecoParam != NULL)
493 : {
494 0 : delete fRecoParam;
495 0 : fRecoParam = NULL;
496 0 : }
497 3 : }
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 0 : if (loadMapping)
508 : {
509 0 : HLTInfo("Loading mapping information from CDB.");
510 0 : int result = FetchMappingStores();
511 0 : if (result != 0) return result;
512 0 : }
513 :
514 0 : if (loadParams)
515 : {
516 0 : HLTInfo("Loading reconstruction parameters from CDB.");
517 : AliMUONRecoParam* recoParam = NULL;
518 : try
519 : {
520 : //TODO:
521 0 : HLTWarning("Have not yet implemented loading reco params from CDB! Using AliMUONRecoParam::GetLowFluxParam().");
522 : //result = LoadRecoParamsFromCDB(recoParam);
523 : //if (result != 0) return result;
524 0 : recoParam = AliMUONRecoParam::GetLowFluxParam();
525 0 : }
526 : catch (const std::bad_alloc&)
527 : {
528 0 : HLTError("Could not allocate more memory for the reconstruction parameter object.");
529 : return -ENOMEM;
530 0 : }
531 0 : if (fRecoParam != NULL) delete fRecoParam;
532 0 : fRecoParam = recoParam;
533 0 : }
534 :
535 0 : if (loadGeom)
536 : {
537 0 : HLTInfo("Loading geometry data from CDB.");
538 : // Only load geometry if not already loaded.
539 0 : if (AliGeomManager::GetGeometry() == NULL)
540 : {
541 0 : AliGeomManager::LoadGeometry();
542 0 : }
543 0 : assert(fTransformer != NULL);
544 0 : if (not fTransformer->LoadGeometryData())
545 : {
546 0 : HLTError("Could not load geometry data for transformation.");
547 0 : return -ENOENT;
548 : }
549 : }
550 :
551 0 : if (loadCalib)
552 : {
553 0 : assert(fRecoParam != NULL);
554 :
555 0 : HLTInfo("Loading calibration information from CDB.");
556 : AliMUONCalibrationData* calibData = NULL;
557 : try
558 : {
559 0 : assert(AliCDBManager::Instance() != NULL);
560 0 : Int_t runNumber = AliCDBManager::Instance()->GetRun();
561 0 : calibData = new AliMUONCalibrationData(runNumber);
562 0 : }
563 : catch (const std::bad_alloc&)
564 : {
565 0 : HLTError("Could not allocate more memory for the calibration data object.");
566 : return -ENOMEM;
567 0 : }
568 :
569 0 : if (not calibData->IsValid())
570 : {
571 0 : HLTError("Could not retrieve calibrations!");
572 0 : delete calibData;
573 0 : return -ENOENT;
574 : }
575 :
576 : // Check that we get all the calibrations we'll need.
577 0 : if (not calibData->Pedestals() or
578 0 : not calibData->HV() )
579 : {
580 0 : HLTError("Could not access all required calibration data.");
581 0 : delete calibData;
582 0 : return -ENOENT;
583 : }
584 :
585 0 : if (fCalibrationData != NULL) delete fCalibrationData;
586 0 : fCalibrationData = calibData;
587 :
588 :
589 : AliMUONDigitCalibrator* calibrator = NULL;
590 : AliMUONVClusterFinder* clusterFinder = NULL;
591 : AliMUONSimpleClusterServer* clusterServer = NULL;
592 : try
593 : {
594 0 : calibrator = new AliMUONDigitCalibrator(*fCalibrationData, fRecoParam);
595 :
596 0 : clusterFinder = AliMUONReconstructor::CreateClusterFinder(
597 0 : fRecoParam->GetClusteringMode()
598 : );
599 :
600 0 : clusterServer = new AliMUONSimpleClusterServer(clusterFinder, *fTransformer);
601 0 : }
602 : catch (const std::bad_alloc&)
603 : {
604 0 : HLTError("Could not allocate more memory for a offline reconstruction object.");
605 0 : if (calibrator != NULL) delete calibrator;
606 0 : if (clusterFinder != NULL) delete clusterFinder;
607 0 : if (clusterServer != NULL) delete clusterServer;
608 : return -ENOMEM;
609 0 : }
610 :
611 0 : if (fDigitCalibrator != NULL) delete fDigitCalibrator;
612 0 : fDigitCalibrator = calibrator;
613 0 : if (fClusterFinder != NULL) delete fClusterFinder;
614 0 : fClusterFinder = clusterFinder;
615 0 : if (fClusterServer != NULL) delete fClusterServer;
616 0 : fClusterServer = clusterServer;
617 0 : }
618 :
619 0 : return 0;
620 0 : }
621 :
|