]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - HLT/MUON/OnlineAnalysis/AliHLTMUONHitReconstructorComponent.cxx
Bug fix. There was a comma in a variable parameter list function that should not...
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONHitReconstructorComponent.cxx
... / ...
CommitLineData
1/**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
4 * *
5 * Primary Authors: *
6 * Indranil Das <indra.das@saha.ac.in> *
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///
21/// The HitRec Component is designed to deal the rawdata inputfiles to findout the
22/// the reconstructed hits. The output is send to the output block for further
23/// processing.
24///
25/// Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
26///
27
28#include "AliHLTMUONRecHitsBlockStruct.h"
29#include "AliHLTMUONHitReconstructorComponent.h"
30#include "AliHLTMUONHitReconstructor.h"
31#include "AliHLTMUONConstants.h"
32#include "AliHLTMUONUtils.h"
33#include "AliHLTMUONDataBlockWriter.h"
34#include "AliHLTMUONHitReconstructor.h"
35#include "AliHLTLogging.h"
36#include "AliHLTSystem.h"
37#include "AliHLTDefinitions.h"
38#include <cstdlib>
39#include <cerrno>
40#include <cassert>
41#include <fstream>
42
43//STEER
44#include "AliCDBManager.h"
45#include "AliCDBStorage.h"
46#include "AliGeomManager.h"
47
48//MUON
49#include "AliMUONGeometryTransformer.h"
50#include "AliMUONCalibrationData.h"
51#include "AliMUONVCalibParam.h"
52
53//MUON/mapping
54#include "AliMpCDB.h"
55#include "AliMpPad.h"
56#include "AliMpSegmentation.h"
57#include "AliMpDDLStore.h"
58#include "AliMpDEIterator.h"
59#include "AliMpVSegmentation.h"
60#include "AliMpDEManager.h"
61#include "AliMpDetElement.h"
62
63ClassImp(AliHLTMUONHitReconstructorComponent)
64
65
66AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() :
67 AliHLTProcessor(),
68 fHitRec(NULL),
69 fDDL(-1),
70 fLutSize(0),
71 fLut(NULL),
72 fIdToEntry(),
73 fWarnForUnexpecedBlock(false)
74{
75 ///
76 /// Default constructor.
77 ///
78}
79
80
81AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent()
82{
83 ///
84 /// Default destructor.
85 ///
86
87 if (fHitRec != NULL)
88 {
89 delete fHitRec;
90 }
91 if (fLut != NULL)
92 {
93 delete fLut;
94 }
95}
96
97const char* AliHLTMUONHitReconstructorComponent::GetComponentID()
98{
99 ///
100 /// Inherited from AliHLTComponent. Returns the component ID.
101 ///
102
103 return AliHLTMUONConstants::HitReconstructorId();
104}
105
106
107void AliHLTMUONHitReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
108{
109 ///
110 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
111 ///
112
113 list.clear();
114 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
115}
116
117
118AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType()
119{
120 ///
121 /// Inherited from AliHLTComponent. Returns the output data type.
122 ///
123
124 return AliHLTMUONConstants::RecHitsBlockDataType();
125}
126
127
128void AliHLTMUONHitReconstructorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
129{
130 ///
131 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
132 ///
133
134 constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType);
135 inputMultiplier = 1;
136}
137
138
139AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn()
140{
141 ///
142 /// Inherited from AliHLTComponent. Creates a new object instance.
143 ///
144
145 return new AliHLTMUONHitReconstructorComponent;
146}
147
148
149int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv)
150{
151 ///
152 /// Inherited from AliHLTComponent.
153 /// Parses the command line parameters and initialises the component.
154 ///
155
156 HLTInfo("Initialising dHLT hit reconstruction component.");
157
158 // Must make sure that fHitRec and fLut is deleted if it is still
159 // allocated for whatever reason.
160 FreeMemory();
161
162 try
163 {
164 fHitRec = new AliHLTMUONHitReconstructor();
165 }
166 catch (const std::bad_alloc&)
167 {
168 HLTError("Could not allocate more memory for the hit reconstructor component.");
169 return -ENOMEM;
170 }
171
172 // Initialise fields with default values then parse the command line.
173 fDDL = -1;
174 fIdToEntry.clear();
175 fWarnForUnexpecedBlock = false;
176
177 const char* lutFileName = NULL;
178 const char* cdbPath = NULL;
179 Int_t run = -1;
180 bool useCDB = false;
181
182 for (int i = 0; i < argc; i++)
183 {
184 HLTDebug("argv[%d] == %s", i, argv[i]);
185
186 if (strcmp( argv[i], "-ddl" ) == 0)
187 {
188 if (argc <= i+1)
189 {
190 HLTError("The DDL number was not specified. Must be in the range [13..20].");
191 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
192 return -EINVAL;
193 }
194
195 char* cpErr = NULL;
196 unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
197 if (cpErr == NULL or *cpErr != '\0')
198 {
199 HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] );
200 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
201 return -EINVAL;
202 }
203 if (num < 13 or 20 < num)
204 {
205 HLTError("The DDL number must be in the range [13..20].");
206 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
207 return -EINVAL;
208 }
209 fDDL = num - 1; // convert to range [12..19]
210
211 i++;
212 continue;
213 } // -ddl argument
214
215 if (strcmp( argv[i], "-lut" ) == 0)
216 {
217 if (argc <= i+1)
218 {
219 HLTError("The lookup table filename was not specified.");
220 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
221 return -EINVAL;
222 }
223 lutFileName = argv[i+1];
224 i++;
225 continue;
226 } // -lut argument
227
228 if (strcmp( argv[i], "-cdb" ) == 0)
229 {
230 useCDB = true;
231 continue;
232 } // -cdb argument
233
234 if (strcmp( argv[i], "-cdbpath" ) == 0)
235 {
236 if ( argc <= i+1 )
237 {
238 HLTError("The CDB path was not specified." );
239 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
240 return -EINVAL;
241 }
242 cdbPath = argv[i+1];
243 useCDB = true;
244 i++;
245 continue;
246 } // -cdb argument
247
248 if (strcmp( argv[i], "-run" ) == 0)
249 {
250 if ( argc <= i+1 )
251 {
252 HLTError("The RUN number was not specified." );
253 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
254 return -EINVAL;
255 }
256
257 char* cpErr = NULL;
258 run = Int_t( strtoul(argv[i+1], &cpErr, 0) );
259 if (cpErr == NULL or *cpErr != '\0')
260 {
261 HLTError("Cannot convert '%s' to a valid run number."
262 " Expected an integer value.", argv[i+1]
263 );
264 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
265 return -EINVAL;
266 }
267
268 i++;
269 continue;
270 } // -run argument
271
272 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
273 {
274 fWarnForUnexpecedBlock = true;
275 continue;
276 }
277
278 HLTError("Unknown option '%s'", argv[i]);
279 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
280 return -EINVAL;
281
282 } // for loop
283
284 if (lutFileName == NULL) useCDB = true;
285
286 if (fDDL == -1)
287 {
288 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
289 }
290
291 int result = 0;
292 if (useCDB)
293 {
294 HLTInfo("Loading lookup table information from CDB for DDL %d.", fDDL+1);
295 if (fDDL == -1)
296 HLTWarning("DDL number not specified. The lookup table loaded from CDB will be empty!");
297 result = ReadCDB(cdbPath, run);
298 }
299 else
300 {
301 HLTInfo("Loading lookup table information from file %s.", lutFileName);
302 result = ReadLookUpTable(lutFileName);
303 }
304 if (result != 0)
305 {
306 // Error messages already generated in ReadCDB or ReadLookUpTable.
307 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
308 return result;
309 }
310
311 fHitRec->SetLookUpTable(fLut, &fIdToEntry);
312
313 return 0;
314}
315
316
317int AliHLTMUONHitReconstructorComponent::DoDeinit()
318{
319 ///
320 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
321 ///
322
323 HLTInfo("Deinitialising dHLT hit reconstruction component.");
324 FreeMemory();
325 return 0;
326}
327
328
329int AliHLTMUONHitReconstructorComponent::DoEvent(
330 const AliHLTComponentEventData& evtData,
331 const AliHLTComponentBlockData* blocks,
332 AliHLTComponentTriggerData& /*trigData*/,
333 AliHLTUInt8_t* outputPtr,
334 AliHLTUInt32_t& size,
335 std::vector<AliHLTComponentBlockData>& outputBlocks
336 )
337{
338 ///
339 /// Inherited from AliHLTProcessor. Processes the new event data.
340 ///
341
342 // Process an event
343 unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
344
345 HLTDebug("Processing event %llu with %u input data blocks.",
346 evtData.fEventID, evtData.fBlockCnt
347 );
348
349 // Loop over all input blocks in the event
350 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
351 {
352 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
353 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
354 );
355
356 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
357 or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
358 )
359 {
360 // Log a message indicating that we got a data block that we
361 // do not know how to handle.
362 if (fWarnForUnexpecedBlock)
363 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
364 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
365 );
366 else
367 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
368 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
369 );
370
371 continue;
372 }
373
374 if (fDDL != -1)
375 {
376 bool ddl[22];
377 AliHLTMUONUtils::UnpackSpecBits(blocks[n].fSpecification, ddl);
378 if (not ddl[fDDL])
379 {
380 HLTWarning("Received raw data from an unexpected DDL.");
381 }
382 }
383
384 // Create a new output data block and initialise the header.
385 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
386 if (not block.InitCommonHeader())
387 {
388 HLTError("There is not enough space in the output buffer for the new data block."
389 " We require at least %u bytes, but have %u bytes left.",
390 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
391 block.BufferSize()
392 );
393 break;
394 }
395
396 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
397 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
398 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
399 + fHitRec->GetkDDLHeaderSize();
400 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
401
402#ifdef DEBUG
403 HLTDebug("=========== Dumping DDL payload buffer ==========");
404 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
405 HLTDebug("buffer[%d] : %x",j,buffer[j]);
406 HLTDebug("================== End of dump =================");
407#endif // DEBUG
408
409 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
410 {
411 HLTError("Error while processing of hit reconstruction algorithm.");
412 size = totalSize; // Must tell the framework how much buffer space was used.
413 return -EIO;
414 }
415
416 // nofHit should now contain the number of reconstructed hits actually found
417 // and filled into the output data block, so we can set this number.
418 assert( nofHit <= block.MaxNumberOfEntries() );
419 block.SetNumberOfEntries(nofHit);
420
421 HLTDebug("Number of reconstructed hits found is %d", nofHit);
422
423 // Fill a block data structure for our output block.
424 AliHLTComponentBlockData bd;
425 FillBlockData(bd);
426 bd.fPtr = outputPtr;
427 // This block's start (offset) is after all other blocks written so far.
428 bd.fOffset = totalSize;
429 bd.fSize = block.BytesUsed();
430 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
431 bd.fSpecification = blocks[n].fSpecification;
432 outputBlocks.push_back(bd);
433
434 // Increase the total amount of data written so far to our output memory
435 totalSize += block.BytesUsed();
436 }
437 // Finally we set the total size of output memory we consumed.
438 size = totalSize;
439
440 return 0;
441}
442
443
444void AliHLTMUONHitReconstructorComponent::FreeMemory()
445{
446 /// Deletes any allocated objects if they are allocated else nothing is
447 /// done for objects not yet allocated.
448 /// This is used as a helper method to make sure the corresponding pointers
449 /// are NULL and we get back to a well defined state.
450
451 if (fHitRec != NULL)
452 {
453 delete fHitRec;
454 fHitRec = NULL;
455 }
456 if (fLut != NULL)
457 {
458 delete fLut;
459 fLut = NULL;
460 fLutSize = 0;
461 }
462
463 fIdToEntry.clear();
464}
465
466
467int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
468{
469 /// Read in the lookup table from a text file.
470 /// Note that this method could leave fLut allocated which is cleaned up
471 /// by DoInit with a call to FreeMemory().
472
473 assert( fLut == NULL );
474 assert( fLutSize == 0 );
475 assert( fIdToEntry.empty() );
476
477 std::ifstream file(lutFileName);
478 if (not file.good())
479 {
480 HLTError("Could not open the LUT file %s", lutFileName);
481 return -ENOENT;
482 }
483
484 // First count the number of lines of text in the LUT file before decoding.
485 // This is not the most optimal. It would be better to read and decode at the
486 // same time but we are not allowed to use STL and ROOT containers are too
487 // heavy for this task. At least this is done only at the start of run.
488 std::string str;
489 AliHLTUInt32_t lineCount = 0;
490 while (std::getline(file, str)) lineCount++;
491 if (not file.eof())
492 {
493 HLTError("There was a problem reading the LUT file %s", lutFileName);
494 return -EIO;
495 }
496 if (lineCount == 0)
497 {
498 HLTWarning("The LUT file %s was empty.", lutFileName);
499 }
500
501 // Add one extra LUT line for the first element which is used as a sentinel value.
502 lineCount++;
503
504 try
505 {
506 fLut = new AliHLTMUONHitRecoLutRow[lineCount];
507 fLutSize = lineCount;
508 }
509 catch (const std::bad_alloc&)
510 {
511 HLTError("Could not allocate more memory for the lookuptable.");
512 return -ENOMEM;
513 }
514
515 // Initialise the sentinel value.
516 fLut[0].fDetElemId = 0;
517 fLut[0].fIX = 0;
518 fLut[0].fIY = 0;
519 fLut[0].fRealX = 0.0;
520 fLut[0].fRealY = 0.0;
521 fLut[0].fRealZ = 0.0;
522 fLut[0].fHalfPadSize = 0.0;
523 fLut[0].fPlane = -1;
524 fLut[0].fPed = -1;
525 fLut[0].fSigma = -1;
526 fLut[0].fA0 = -1;
527 fLut[0].fA1 = -1;
528 fLut[0].fThres = -1;
529 fLut[0].fSat = -1;
530
531 // Clear the eof flag and start reading from the beginning of the file again.
532 file.clear();
533 file.seekg(0, std::ios::beg);
534 if (not file.good())
535 {
536 HLTError("There was a problem seeking in the LUT file %s", lutFileName);
537 return -EIO;
538 }
539
540 AliHLTInt32_t idManuChannel;
541 for (AliHLTUInt32_t i = 1; i < fLutSize; i++)
542 {
543 if (std::getline(file, str).fail())
544 {
545 HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName);
546 return -EIO;
547 }
548
549 int result = sscanf(
550 str.c_str(), "%d\t%d\t%d\t%d\t%e\t%e\t%e\t%e\t%d\t%e\t%e\t%e\t%e\t%d\t%d",
551 &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX,
552 &fLut[i].fIY, &fLut[i].fRealX,
553 &fLut[i].fRealY, &fLut[i].fRealZ,
554 &fLut[i].fHalfPadSize, &fLut[i].fPlane,
555 &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0,
556 &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat
557 );
558
559 if (result != 15)
560 {
561 HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName);
562 return -EIO;
563 }
564
565 fIdToEntry[idManuChannel] = i;
566 }
567
568 return 0;
569}
570
571
572int AliHLTMUONHitReconstructorComponent::ReadCDB(const char* cdbPath, Int_t run)
573{
574 // Reads LUT from CDB.
575 // TODO: merge this with CreateHitRecoLookupTables.C, make this static and use in the macro for example.
576
577 assert( fLut == NULL );
578 assert( fLutSize == 0 );
579 assert( fIdToEntry.empty() );
580
581 std::vector<AliHLTMUONHitRecoLutRow> lutList;
582 AliHLTMUONHitRecoLutRow lut;
583 AliHLTUInt32_t iEntry = 0;
584
585 Bool_t warn = kFALSE;
586
587 AliCDBManager* cdbManager = AliCDBManager::Instance();
588 if (cdbManager == NULL)
589 {
590 HLTError("CDB manager instance does not exist.");
591 return -EIO;
592 }
593
594 const char* cdbPathUsed = "unknown (not set)";
595 if (cdbPath != NULL)
596 {
597 cdbManager->SetDefaultStorage(cdbPath);
598 cdbPathUsed = cdbPath;
599 }
600 else
601 {
602 AliCDBStorage* store = cdbManager->GetDefaultStorage();
603 if (store != NULL) cdbPathUsed = store->GetURI().Data();
604 }
605
606 if (run != -1) cdbManager->SetRun(run);
607 Int_t runUsed = cdbManager->GetRun();
608
609 if (not AliMpCDB::LoadDDLStore(warn))
610 {
611 HLTError("Failed to load DDL store specified for CDB path '%s' and run no. %d",
612 cdbPathUsed, runUsed
613 );
614 return -ENOENT;
615 }
616 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
617 if (ddlStore == NULL)
618 {
619 HLTError("Could not find DDL store instance.");
620 return -EIO;
621 }
622 AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance();
623 if (mpSegFactory == NULL)
624 {
625 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
626 return -EIO;
627 }
628
629 AliGeomManager::LoadGeometry();
630 AliMUONGeometryTransformer chamberGeometryTransformer;
631 if (not chamberGeometryTransformer.LoadGeometryData())
632 {
633 HLTError("Failed to load geomerty data.");
634 return -ENOENT;
635 }
636
637 AliMUONCalibrationData calibData(run);
638
639 Int_t chamberId;
640
641 for(Int_t iCh = 6; iCh < 10; iCh++)
642 {
643 chamberId = iCh;
644
645 AliMpDEIterator it;
646 for ( it.First(chamberId); ! it.IsDone(); it.Next() )
647 {
648 Int_t detElemId = it.CurrentDEId();
649 int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId();
650 if (iDDL != fDDL) continue;
651
652 for (Int_t iCath = 0 ; iCath <= 1 ; iCath++)
653 {
654 AliMp::CathodType cath;
655
656 if(iCath == 0)
657 cath = AliMp::kCath0;
658 else
659 cath = AliMp::kCath1;
660
661 const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath);
662 AliMp::PlaneType plane = seg->PlaneType();
663 Int_t maxIX = seg->MaxPadIndexX();
664 Int_t maxIY = seg->MaxPadIndexY();
665
666 Int_t idManuChannel, manuId, channelId, buspatchId;
667 AliHLTFloat32_t padSizeX, padSizeY;
668 AliHLTFloat32_t halfPadSize;
669 Double_t realX, realY, realZ;
670 Double_t localX, localY, localZ;
671 Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma;
672 Int_t thresold,saturation;
673
674 // Pad Info of a slat to print in lookuptable
675 for (Int_t iX = 0; iX<= maxIX ; iX++)
676 for (Int_t iY = 0; iY<= maxIY ; iY++)
677 {
678 if (not seg->HasPad(AliMpIntPair(iX,iY))) continue;
679
680 AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE);
681
682 // Getting Manu id
683 manuId = pad.GetLocation().GetFirst();
684 manuId &= 0x7FF; // 11 bits
685
686 buspatchId = ddlStore->GetBusPatchId(detElemId,manuId);
687
688 // Getting channel id
689 channelId = pad.GetLocation().GetSecond();
690 channelId &= 0x3F; // 6 bits
691
692 idManuChannel = buspatchId << 11;
693 idManuChannel = (idManuChannel | manuId) << 6;
694 idManuChannel |= channelId;
695
696 localX = pad.Position().X();
697 localY = pad.Position().Y();
698 localZ = 0.0;
699
700 chamberGeometryTransformer.Local2Global(
701 detElemId,localX,localY,localZ,
702 realX,realY,realZ
703 );
704
705 padSizeX = pad.Dimensions().X();
706 padSizeY = pad.Dimensions().Y();
707
708 calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0);
709 calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1);
710 thresold = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 2);
711 saturation = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 4);
712
713 pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0);
714 sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1);
715
716 if (plane == 0)
717 halfPadSize = padSizeX;
718 else
719 halfPadSize = padSizeY;
720
721 fIdToEntry[idManuChannel] = iEntry+1;
722
723 lut.fDetElemId = detElemId;
724 lut.fIX = iX;
725 lut.fIY = iY;
726 lut.fRealX = realX;
727 lut.fRealY = realY;
728 lut.fRealZ = realZ;
729 lut.fHalfPadSize = halfPadSize;
730 lut.fPlane = plane;
731 lut.fPed = pedestal;
732 lut.fSigma = sigma;
733 lut.fA0 = calibA0Coeff;
734 lut.fA1 = calibA1Coeff;
735 lut.fThres = thresold;
736 lut.fSat = saturation;
737
738 lutList.push_back(lut);
739 iEntry++;
740 } // iX, iY loop
741 } // iCath loop
742 } // detElemId loop
743 } // ichamber loop
744
745 try
746 {
747 // Use iEntry+1 since we add one extra LUT line for the first element
748 // which is used as a sentinel value.
749 fLut = new AliHLTMUONHitRecoLutRow[iEntry+1];
750 fLutSize = iEntry+1;
751 }
752 catch (const std::bad_alloc&)
753 {
754 HLTError("Could not allocate more memory for the lookuptable.");
755 return -ENOMEM;
756 }
757
758 // Initialise the sentinel value.
759 fLut[0].fDetElemId = 0;
760 fLut[0].fIX = 0;
761 fLut[0].fIY = 0;
762 fLut[0].fRealX = 0.0;
763 fLut[0].fRealY = 0.0;
764 fLut[0].fRealZ = 0.0;
765 fLut[0].fHalfPadSize = 0.0;
766 fLut[0].fPlane = -1;
767 fLut[0].fPed = -1;
768 fLut[0].fSigma = -1;
769 fLut[0].fA0 = -1;
770 fLut[0].fA1 = -1;
771 fLut[0].fThres = -1;
772 fLut[0].fSat = -1;
773
774 for (AliHLTUInt32_t i = 0; i < iEntry; i++)
775 fLut[i+1] = lutList[i];
776
777 return 0;
778}
779
780
781bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
782 AliHLTInt32_t ddl, const char* filename,
783 const char* cdbPath, Int_t run
784 )
785{
786 /// Generates a ASCII text file containing the lookup table (LUT) from
787 /// the CDB, which can be used for the hit reconstructor component later.
788 /// @param ddl Must be the DDL for which to generate the DDL,
789 /// in the range [13..20].
790 /// @param filename The name of the LUT file to generate.
791 /// @param cdbPath The CDB path to use.
792 /// @param run The run number to use for the CDB.
793 /// @return True if the generation of the LUT file succeeded.
794
795 AliHLTMUONHitReconstructorComponent comp;
796
797 if (ddl < 12 or 19 < ddl)
798 {
799 std::cerr << "ERROR: the DDL number must be in the range [12..19]." << std::endl;
800 return false;
801 }
802
803 comp.fDDL = ddl;
804 if (comp.ReadCDB(cdbPath, run) != 0) return false;
805
806 char str[1024*4];
807 std::fstream file(filename, std::ios::out);
808 if (not file)
809 {
810 std::cerr << "ERROR: could not open file: " << filename << std::endl;
811 return false;
812 }
813
814 assert( comp.fLut != NULL );
815
816 for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin();
817 id != comp.fIdToEntry.end();
818 id++
819 )
820 {
821 AliHLTInt32_t idManuChannel = id->first;
822 AliHLTInt32_t row = id->second;
823
824 assert( row < comp.fLutSize );
825
826 sprintf(str, "%d\t%d\t%d\t%d\t%.15e\t%.15e\t%.15e\t%.15e\t%d\t%.15e\t%.15e\t%.15e\t%.15e\t%d\t%d",
827 idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX,
828 comp.fLut[row].fIY, comp.fLut[row].fRealX,
829 comp.fLut[row].fRealY, comp.fLut[row].fRealZ,
830 comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane,
831 comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0,
832 comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat
833 );
834
835 file << str << endl;
836 if (file.fail())
837 {
838 std::cerr << "ERROR: There was an I/O error when writing to the file: "
839 << filename << std::endl;
840 return false;
841 }
842 }
843
844 return true;
845}