]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx
Fix bug in tracklet reconstruction and add option to AliTRDfeeParam
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONTriggerReconstructorComponent.cxx
CommitLineData
6efe69e7 1/**************************************************************************
b39b98c8 2 * This file is property of and copyright by the ALICE HLT Project *
6efe69e7 3 * All rights reserved. *
4 * *
5 * Primary Authors: *
6 * Indranil Das <indra.das@saha.ac.in> *
b39b98c8 7 * Artur Szostak <artursz@iafrica.com> *
6efe69e7 8 * *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
b39b98c8 14 * about the suitability of this software for any purpose. It is *
6efe69e7 15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
18/* $Id$ */
19
6253e09b 20///
21/// @file AliHLTMUONTriggerReconstructorComponent.cxx
22/// @author Indranil Das <indra.das@saha.ac.in>, Artur Szostak <artursz@iafrica.com>
61d982d3 23/// @date 18 Sep 2007
6253e09b 24/// @brief Implementation of the trigger DDL reconstructor component.
25///
6efe69e7 26
6efe69e7 27#include "AliHLTMUONTriggerReconstructorComponent.h"
960d54ad 28#include "AliHLTMUONTriggerReconstructor.h"
29#include "AliHLTMUONHitReconstructor.h"
30#include "AliHLTMUONConstants.h"
b39b98c8 31#include "AliHLTMUONUtils.h"
227e7192 32#include "AliHLTMUONDataBlockWriter.h"
69c14678 33#include "AliRawDataHeader.h"
c95cf30c 34#include "AliCDBManager.h"
35#include "AliCDBStorage.h"
36#include "AliGeomManager.h"
37#include "AliMUONGeometryTransformer.h"
38#include "AliMUONGeometryDetElement.h"
39#include "AliMpCDB.h"
40#include "AliMpDDLStore.h"
41#include "AliMpPad.h"
42#include "AliMpSegmentation.h"
43#include "AliMpDEIterator.h"
44#include "AliMpVSegmentation.h"
45#include "AliMpDEManager.h"
46#include "AliMpLocalBoard.h"
47#include "AliMpTriggerCrate.h"
227e7192 48#include <cstdlib>
49#include <cerrno>
5d1682b9 50#include <cassert>
b39b98c8 51#include <fstream>
6efe69e7 52
c95cf30c 53
6efe69e7 54ClassImp(AliHLTMUONTriggerReconstructorComponent)
b39b98c8 55
56
227e7192 57AliHLTMUONTriggerReconstructorComponent::AliHLTMUONTriggerReconstructorComponent() :
154cba94 58 AliHLTMUONProcessor(),
227e7192 59 fTrigRec(NULL),
b39b98c8 60 fDDL(-1),
80590aa1 61 fWarnForUnexpecedBlock(false),
a3d4b6ba 62 fStopOnOverflow(false),
63 fUseCrateId(true)
960d54ad 64{
6253e09b 65 ///
66 /// Default constructor.
67 ///
960d54ad 68}
69
6efe69e7 70
71AliHLTMUONTriggerReconstructorComponent::~AliHLTMUONTriggerReconstructorComponent()
960d54ad 72{
6253e09b 73 ///
74 /// Default destructor.
75 ///
a6b16447 76
77 if (fTrigRec != NULL) delete fTrigRec;
960d54ad 78}
79
6efe69e7 80
81const char* AliHLTMUONTriggerReconstructorComponent::GetComponentID()
960d54ad 82{
6253e09b 83 ///
84 /// Inherited from AliHLTComponent. Returns the component ID.
85 ///
86
227e7192 87 return AliHLTMUONConstants::TriggerReconstructorId();
960d54ad 88}
89
90
91void AliHLTMUONTriggerReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
92{
6253e09b 93 ///
94 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
95 ///
96
227e7192 97 list.clear();
668eee9f 98 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
960d54ad 99}
6efe69e7 100
6efe69e7 101
102AliHLTComponentDataType AliHLTMUONTriggerReconstructorComponent::GetOutputDataType()
960d54ad 103{
6253e09b 104 ///
105 /// Inherited from AliHLTComponent. Returns the output data type.
106 ///
107
227e7192 108 return AliHLTMUONConstants::TriggerRecordsBlockDataType();
960d54ad 109}
6efe69e7 110
6efe69e7 111
227e7192 112void AliHLTMUONTriggerReconstructorComponent::GetOutputDataSize(
113 unsigned long& constBase, double& inputMultiplier
114 )
960d54ad 115{
6253e09b 116 ///
117 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
118 ///
119
227e7192 120 constBase = sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType);
c2e03d6e 121 inputMultiplier = 4;
960d54ad 122}
6efe69e7 123
124
6efe69e7 125AliHLTComponent* AliHLTMUONTriggerReconstructorComponent::Spawn()
960d54ad 126{
6253e09b 127 ///
128 /// Inherited from AliHLTComponent. Creates a new object instance.
129 ///
130
227e7192 131 return new AliHLTMUONTriggerReconstructorComponent;
960d54ad 132}
133
6efe69e7 134
960d54ad 135int AliHLTMUONTriggerReconstructorComponent::DoInit(int argc, const char** argv)
6efe69e7 136{
6253e09b 137 ///
138 /// Inherited from AliHLTComponent.
139 /// Parses the command line parameters and initialises the component.
140 ///
141
b39b98c8 142 // perform initialization.
143
144 HLTInfo("Initialising dHLT trigger reconstructor component.");
6efe69e7 145
a6b16447 146 // Make sure to cleanup fTrigRec if it is still there for some reason.
147 if (fTrigRec != NULL)
148 {
149 delete fTrigRec;
150 fTrigRec = NULL;
151 }
152
153 try
154 {
155 fTrigRec = new AliHLTMUONTriggerReconstructor();
156 }
157 catch (const std::bad_alloc&)
158 {
159 HLTError("Could not allocate more memory for the trigger reconstructor component.");
160 return -ENOMEM;
161 }
162
163 fDDL = -1;
b39b98c8 164 fWarnForUnexpecedBlock = false;
a3d4b6ba 165 fStopOnOverflow = false;
166 fUseCrateId = true;
960d54ad 167
b39b98c8 168 const char* lutFileName = NULL;
c95cf30c 169 const char* cdbPath = NULL;
170 Int_t run = -1;
171 bool useCDB = false;
a3d4b6ba 172 bool suppressPartialTrigs = true;
a5d4696f 173 bool tryRecover = false;
b39b98c8 174
175 for (int i = 0; i < argc; i++)
176 {
6ec6a7c1 177 if (strcmp( argv[i], "-lut" ) == 0)
b39b98c8 178 {
179 if ( argc <= i+1 )
180 {
181 HLTError("LookupTable filename not specified." );
a6b16447 182 // Make sure to delete fTrigRec to avoid partial initialisation.
183 delete fTrigRec;
184 fTrigRec = NULL;
185 return -EINVAL;
b39b98c8 186 }
187
188 lutFileName = argv[i+1];
189
190 i++;
191 continue;
192 }
193
6ec6a7c1 194 if (strcmp( argv[i], "-ddl" ) == 0)
b39b98c8 195 {
196 if ( argc <= i+1 )
197 {
c95cf30c 198 HLTError("DDL number not specified. It must be in the range [21..22]" );
a6b16447 199 // Make sure to delete fTrigRec to avoid partial initialisation.
200 delete fTrigRec;
201 fTrigRec = NULL;
202 return -EINVAL;
b39b98c8 203 }
204
205 char* cpErr = NULL;
206 unsigned long num = strtoul(argv[i+1], &cpErr, 0);
207 if (cpErr == NULL or *cpErr != '\0')
208 {
5e67b742 209 HLTError("Cannot convert '%s' to a DDL Number.", argv[i+1]);
a6b16447 210 // Make sure to delete fTrigRec to avoid partial initialisation.
211 delete fTrigRec;
212 fTrigRec = NULL;
213 return -EINVAL;
b39b98c8 214 }
215 if (num < 21 or 22 < num)
216 {
a3d4b6ba 217 HLTError("The DDL number must be in the range [21..22].");
a6b16447 218 // Make sure to delete fTrigRec to avoid partial initialisation.
219 delete fTrigRec;
220 fTrigRec = NULL;
221 return -EINVAL;
b39b98c8 222 }
223 fDDL = num - 1; // Convert to DDL number in the range 0..21
224
225 i++;
226 continue;
227 }
c95cf30c 228
a3d4b6ba 229 if (strcmp( argv[i], "-ddlid" ) == 0)
230 {
231 if ( argc <= i+1 )
232 {
233 HLTError("DDL equipment ID number not specified. It must be in the range [2816..2817]" );
234 // Make sure to delete fTrigRec to avoid partial initialisation.
235 delete fTrigRec;
236 fTrigRec = NULL;
237 return -EINVAL;
238 }
239
240 char* cpErr = NULL;
241 unsigned long num = strtoul(argv[i+1], &cpErr, 0);
242 if (cpErr == NULL or *cpErr != '\0')
243 {
244 HLTError("Cannot convert '%s' to a DDL equipment ID Number.", argv[i+1]);
245 // Make sure to delete fTrigRec to avoid partial initialisation.
246 delete fTrigRec;
247 fTrigRec = NULL;
248 return -EINVAL;
249 }
250 fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
251 if (fDDL < 20 or 21 < fDDL)
252 {
253 HLTError("The DDL equipment ID number must be in the range [2816..2817].");
254 // Make sure to delete fTrigRec to avoid partial initialisation.
255 delete fTrigRec;
256 fTrigRec = NULL;
257 return -EINVAL;
258 }
259
260 i++;
261 continue;
262 }
263
c95cf30c 264 if (strcmp( argv[i], "-cdb" ) == 0)
265 {
266 useCDB = true;
267 continue;
268 }
269
270 if (strcmp( argv[i], "-cdbpath" ) == 0)
271 {
272 if ( argc <= i+1 )
273 {
274 HLTError("The CDB path was not specified." );
275 // Make sure to delete fTrigRec to avoid partial initialisation.
276 delete fTrigRec;
277 fTrigRec = NULL;
278 return -EINVAL;
279 }
280 cdbPath = argv[i+1];
281 useCDB = true;
282 i++;
283 continue;
284 }
285
286 if (strcmp( argv[i], "-run" ) == 0)
287 {
288 if ( argc <= i+1 )
289 {
ffc1a6f6 290 HLTError("The run number was not specified." );
c95cf30c 291 // Make sure to delete fTrigRec to avoid partial initialisation.
292 delete fTrigRec;
293 fTrigRec = NULL;
294 return -EINVAL;
295 }
296
297 char* cpErr = NULL;
298 run = Int_t( strtoul(argv[i+1], &cpErr, 0) );
299 if (cpErr == NULL or *cpErr != '\0')
300 {
301 HLTError("Cannot convert '%s' to a valid run number."
ffc1a6f6 302 " Expected a positive integer value.", argv[i+1]
c95cf30c 303 );
304 // Make sure to delete fTrigRec to avoid partial initialisation.
305 delete fTrigRec;
306 fTrigRec = NULL;
307 return -EINVAL;
308 }
b39b98c8 309
c95cf30c 310 i++;
311 continue;
312 }
313
6ec6a7c1 314 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
b39b98c8 315 {
316 fWarnForUnexpecedBlock = true;
317 continue;
318 }
c95cf30c 319
6ec6a7c1 320 if (strcmp( argv[i], "-suppress_partial_triggers" ) == 0)
b39b98c8 321 {
a3d4b6ba 322 suppressPartialTrigs = true;
323 continue;
324 }
325
326 if (strcmp( argv[i], "-generate_partial_triggers" ) == 0)
327 {
328 suppressPartialTrigs = false;
329 continue;
330 }
331
332 if (strcmp( argv[i], "-stop_on_buffer_overflow" ) == 0)
333 {
334 fStopOnOverflow = true;
b39b98c8 335 continue;
336 }
337
a5d4696f 338 if (strcmp( argv[i], "-tryrecover" ) == 0)
339 {
340 tryRecover = true;
341 continue;
342 }
343
a3d4b6ba 344 if (strcmp( argv[i], "-dont_use_crateid" ) == 0)
345 {
346 fUseCrateId = false;
347 continue;
348 }
349
b39b98c8 350 HLTError("Unknown option '%s'.", argv[i] );
a6b16447 351 // Make sure to delete fTrigRec to avoid partial initialisation.
352 delete fTrigRec;
353 fTrigRec = NULL;
354 return -EINVAL;
c95cf30c 355
a6b16447 356 } // for loop
b39b98c8 357
c95cf30c 358 if (lutFileName == NULL) useCDB = true;
359
b39b98c8 360 if (fDDL == -1)
361 {
362 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
960d54ad 363 }
960d54ad 364
c95cf30c 365 int result = 0;
ffc1a6f6 366 if (cdbPath != NULL or run != -1)
367 {
368 result = SetCDBPathAndRunNo(cdbPath, run);
369 }
370
371 if (result == 0 and useCDB)
b39b98c8 372 {
a3d4b6ba 373 HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
374 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
375 );
c95cf30c 376 if (fDDL == -1)
377 HLTWarning("DDL number not specified. The lookup table loaded from CDB will be empty!");
ffc1a6f6 378 result = ReadLutFromCDB();
960d54ad 379 }
ffc1a6f6 380 else if (result == 0)
b39b98c8 381 {
c95cf30c 382 HLTInfo("Loading lookup table information from file %s.", lutFileName);
383 result = ReadLookUpTable(lutFileName);
384 }
385 if (result != 0)
386 {
ffc1a6f6 387 // Error messages already generated in ReadLutFromCDB or ReadLookUpTable.
c95cf30c 388
389 // Make sure to delete fTrigRec to avoid partial initialisation.
390 delete fTrigRec;
391 fTrigRec = NULL;
392 return result;
960d54ad 393 }
b39b98c8 394
a3d4b6ba 395 fTrigRec->SuppressPartialTriggers(suppressPartialTrigs);
a5d4696f 396 fTrigRec->TryRecover(tryRecover);
a3d4b6ba 397 fTrigRec->UseCrateId(fUseCrateId);
a5d4696f 398
b39b98c8 399 return 0;
6efe69e7 400}
401
960d54ad 402
6efe69e7 403int AliHLTMUONTriggerReconstructorComponent::DoDeinit()
960d54ad 404{
6253e09b 405 ///
406 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
407 ///
408
b39b98c8 409 HLTInfo("Deinitialising dHLT trigger reconstructor component.");
227e7192 410
b39b98c8 411 if (fTrigRec != NULL)
227e7192 412 {
413 delete fTrigRec;
414 fTrigRec = NULL;
415 }
416 return 0;
960d54ad 417}
6efe69e7 418
227e7192 419
960d54ad 420int AliHLTMUONTriggerReconstructorComponent::DoEvent(
421 const AliHLTComponentEventData& evtData,
b39b98c8 422 const AliHLTComponentBlockData* blocks,
423 AliHLTComponentTriggerData& /*trigData*/,
424 AliHLTUInt8_t* outputPtr,
960d54ad 425 AliHLTUInt32_t& size,
426 std::vector<AliHLTComponentBlockData>& outputBlocks
427 )
428{
6253e09b 429 ///
430 /// Inherited from AliHLTProcessor. Processes the new event data.
431 ///
432
227e7192 433 // Process an event
434 unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
6efe69e7 435
227e7192 436 HLTDebug("Processing event %llu with %u input data blocks.",
437 evtData.fEventID, evtData.fBlockCnt
438 );
6efe69e7 439
227e7192 440 // Loop over all input blocks in the event and run the trigger DDL
441 // reconstruction algorithm on the raw data.
442 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
443 {
450e0b36 444 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
445 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
227e7192 446 );
447
668eee9f 448 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
449 or not AliHLTMUONUtils::IsTriggerDDL(blocks[n].fSpecification)
450 )
227e7192 451 {
452 // Log a message indicating that we got a data block that we
453 // do not know how to handle.
5d1682b9 454 if (fWarnForUnexpecedBlock)
450e0b36 455 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
456 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
5d1682b9 457 );
458 else
450e0b36 459 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
460 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
5d1682b9 461 );
462
227e7192 463 continue;
464 }
465
406c5bc3 466 AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
a6b16447 467 if (fDDL != -1)
b39b98c8 468 {
406c5bc3 469 if (receivedDDL != fDDL)
a6b16447 470 {
a3d4b6ba 471 HLTWarning("Received raw data from DDL %d (ID = %d),"
472 " but expect data only from DDL %d (ID = %d).",
473 receivedDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(receivedDDL),
474 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
475 );
a6b16447 476 }
b39b98c8 477 }
478
227e7192 479 // Create a new output data block and initialise the header.
480 AliHLTMUONTriggerRecordsBlockWriter block(outputPtr+totalSize, size-totalSize);
481 if (not block.InitCommonHeader())
482 {
69c14678 483 HLTError("There is not enough space in the output buffer for the new data block."
b39b98c8 484 " We require at least %ufTrigRec->GetkDDLHeaderSize() bytes, but have %u bytes left.",
227e7192 485 sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
486 block.BufferSize()
487 );
488 break;
489 }
490
69c14678 491 AliHLTUInt32_t totalDDLSize = blocks[n].fSize;
492 if (totalDDLSize < sizeof(AliRawDataHeader))
493 {
494 HLTError("Raw data block %d is %d bytes in size and is too short to"
495 " possibly contain valid DDL raw data. We expect it to have"
496 " at least %d bytes for the commond data header.",
497 n, totalDDLSize, sizeof(AliRawDataHeader)
498 );
499 continue;
500 }
649ab027 501 AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(
502 reinterpret_cast<char*>(blocks[n].fPtr) + blocks[n].fOffset
503 );
69c14678 504 AliHLTUInt32_t payloadSize = totalDDLSize - sizeof(AliRawDataHeader);
a5d4696f 505 AliHLTUInt8_t* buffer = reinterpret_cast<AliHLTUInt8_t*>(header + 1);
227e7192 506 AliHLTUInt32_t nofTrigRec = block.MaxNumberOfEntries();
a5d4696f 507
508 // Decode if this is a scalar event or not.
509 bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
510
406c5bc3 511 // Remember: the following does NOT change the mapping!
512 // It is just to generate unique trigger record IDs.
513 fTrigRec->SetDDL(receivedDDL);
514
80590aa1 515 bool runOk = fTrigRec->Run(
a5d4696f 516 buffer, payloadSize, scalarEvent,
a3d4b6ba 517 block.GetArray(), nofTrigRec
80590aa1 518 );
519 if (not runOk)
227e7192 520 {
154cba94 521 HLTError("Error while processing the trigger DDL reconstruction algorithm.");
a3d4b6ba 522 if (not fTrigRec->OverflowedOutputBuffer()
523 or (fTrigRec->OverflowedOutputBuffer() and fStopOnOverflow)
524 )
525 {
526 size = totalSize; // Must tell the framework how much buffer space was used.
527 return -EIO;
528 }
227e7192 529 }
530
531 // nofTrigRec should now contain the number of triggers actually found
532 // and filled into the output data block, so we can set this number.
533 assert( nofTrigRec <= block.MaxNumberOfEntries() );
534 block.SetNumberOfEntries(nofTrigRec);
535
536 HLTDebug("Number of trigger records found is %d", nofTrigRec);
537
538 // Fill a block data structure for our output block.
539 AliHLTComponentBlockData bd;
540 FillBlockData(bd);
541 bd.fPtr = outputPtr;
542 // This block's start (offset) is after all other blocks written so far.
543 bd.fOffset = totalSize;
544 bd.fSize = block.BytesUsed();
545 bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
546 bd.fSpecification = blocks[n].fSpecification;
547 outputBlocks.push_back(bd);
548
549 HLTDebug("Created a new output data block at fPtr = %p,"
550 " with fOffset = %u (0x%.X) and fSize = %u bytes.",
551 bd.fPtr, bd.fOffset, bd.fOffset, bd.fSize
552 );
553
554 // Increase the total amount of data written so far to our output memory.
555 totalSize += block.BytesUsed();
556 }
960d54ad 557
227e7192 558 // Finally we set the total size of output memory we consumed.
559 size = totalSize;
560 return 0;
960d54ad 561}
562
6efe69e7 563
c95cf30c 564int AliHLTMUONTriggerReconstructorComponent::ReadLookUpTable(const char* lutpath)
6efe69e7 565{
6253e09b 566 ///
567 /// Read in the lookup table from file.
568 ///
569
b39b98c8 570 assert(fTrigRec != NULL);
6efe69e7 571
b39b98c8 572 fstream file;
573 file.open(lutpath, fstream::binary | fstream::in);
574 if (not file)
575 {
576 HLTError("Could not open file: %s", lutpath);
c95cf30c 577 return -ENOENT;
b39b98c8 578 }
579
580 file.read(reinterpret_cast<char*>(fTrigRec->LookupTableBuffer()), fTrigRec->LookupTableSize());
581 if (file.eof())
582 {
583 HLTError("The file %s was too short to contain a valid lookup table for this component.", lutpath);
584 file.close();
c95cf30c 585 return -EIO;
b39b98c8 586 }
c95cf30c 587 if (file.fail())
b39b98c8 588 {
589 HLTError("Could not read from file: %s", lutpath);
590 file.close();
c95cf30c 591 return -EIO;
592 }
593
594 file.close();
595 return 0;
596}
597
598
ffc1a6f6 599int AliHLTMUONTriggerReconstructorComponent::ReadLutFromCDB()
c95cf30c 600{
601 /// Loads the lookup table containing channel and geometrical position
602 /// information about trigger strips from CDB.
ffc1a6f6 603 ///
604 /// \note To override the default CDB path and / or run number the
605 /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this
606 /// method.
607 ///
c95cf30c 608 /// \return 0 on success and non zero codes for errors.
609
610 if (fDDL == -1)
611 {
612 HLTError("No DDL number specified for which to load LUT data from CDB.");
613 return -EINVAL;
614 }
615
ffc1a6f6 616 int result = FetchMappingStores();
dba14d7d 617 // Error message already generated in FetchMappingStores.
618 if (result != 0) return result;
c95cf30c 619 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
dba14d7d 620
c95cf30c 621 AliMpSegmentation* segmentation = AliMpSegmentation::Instance();
622 if (segmentation == NULL)
623 {
624 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
625 return -EIO;
626 }
627
61d982d3 628 // Only load geometry if not already loaded.
629 if (AliGeomManager::GetGeometry() == NULL)
630 {
631 AliGeomManager::LoadGeometry();
632 }
c95cf30c 633 AliMUONGeometryTransformer transformer;
634 if (not transformer.LoadGeometryData())
635 {
636 HLTError("Could not load geometry into transformer.");
637 return -ENOENT;
638 }
639
640 AliHLTMUONTriggerRecoLookupTable* lookupTable = fTrigRec->LookupTableBuffer();
641
a3d4b6ba 642 for (Int_t i = 0; i < 16; i++)
c95cf30c 643 for (Int_t j = 0; j < 16; j++)
644 for (Int_t k = 0; k < 4; k++)
645 for (Int_t n = 0; n < 2; n++)
646 for (Int_t m = 0; m < 16; m++)
647 {
a090ff22 648 lookupTable->fRow[i][j][k][n][m].fIdFlags = 0x0;
c95cf30c 649 lookupTable->fRow[i][j][k][n][m].fX = 0;
650 lookupTable->fRow[i][j][k][n][m].fY = 0;
651 lookupTable->fRow[i][j][k][n][m].fZ = 0;
652 }
653
654 AliMpDEIterator detElemIter;
655 for (Int_t iReg = 0; iReg < 8; iReg++)
656 {
657 AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(fDDL, iReg);
658 if (crate == NULL)
659 {
a3d4b6ba 660 HLTError("Could not get crate mapping for regional header = %d"
661 " and DDL %d (ID = %d).",
662 iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
663 );
664 continue;
665 }
666 // Depending on the value of fUseCrateId, use either the crate ID as would
667 // be found in the regional header structures or the sequencial index number
668 // of the structure.
669 UInt_t crateId = (fUseCrateId ? crate->GetId() : iReg);
670 if (crateId >= 16)
671 {
672 HLTError("The crate ID number (%d) for regional header = %d and"
673 " DDL %d (ID = %d) is too big. It should be in the range [0..15]",
674 crateId, iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
675 );
c95cf30c 676 continue;
677 }
678
679 for (Int_t iLocBoard = 0; iLocBoard < 16; iLocBoard++)
680 {
681 Int_t boardId = crate->GetLocalBoardId(iLocBoard);
682 if (boardId == 0) continue;
683
684 AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(boardId);
685 if (localBoard == NULL)
686 {
a3d4b6ba 687 HLTError("Could not get local board: %d.", boardId);
c95cf30c 688 continue;
689 }
690
691 // skip copy cards
692 if (! localBoard->IsNotified()) continue;
693
694 for (Int_t iChamber = 0; iChamber < 4; iChamber++)
695 {
696 Int_t detElemId = ddlStore->GetDEfromLocalBoard(boardId, iChamber);
697
a090ff22 698 AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(iChamber+10, detElemId);
699
c95cf30c 700 const AliMUONGeometryDetElement* detElemTransform = transformer.GetDetElement(detElemId);
701 if (detElemTransform == NULL)
702 {
a3d4b6ba 703 HLTError("Got NULL pointer for geometry transformer"
704 " for detection element ID = %d.",
705 detElemId
706 );
c95cf30c 707 continue;
708 }
709
710 for (Int_t iCathode = 0; iCathode <= 1; iCathode++)
711 {
712 const AliMpVSegmentation* seg = segmentation->GetMpSegmentation(
713 detElemId, AliMp::GetCathodType(iCathode)
714 );
715
716 for (Int_t bitxy = 0; bitxy < 16; bitxy++)
717 {
718 Int_t offset = 0;
719 if (iCathode && localBoard->GetSwitch(6)) offset = -8;
720
721 AliMpPad pad = seg->PadByLocation(AliMpIntPair(boardId, bitxy+offset), kFALSE);
722
723 if (! pad.IsValid())
724 {
725 // There is no pad associated with the given local board and bit pattern.
726 continue;
727 }
728
729 // Get the global coodinates of the pad.
730 Float_t lx = pad.Position().X();
731 Float_t ly = pad.Position().Y();
732 Float_t gx, gy, gz;
733 detElemTransform->Local2Global(lx, ly, 0, gx, gy, gz);
734
735 // Fill the LUT
a3d4b6ba 736 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fIdFlags = idflags;
737 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fX = gx;
738 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fY = gy;
739 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fZ = gz;
c95cf30c 740 }
741 }
742 }
743 }
744 }
61d982d3 745
c95cf30c 746 return 0;
747}
748
749
750bool AliHLTMUONTriggerReconstructorComponent::GenerateLookupTable(
751 AliHLTInt32_t ddl, const char* filename,
752 const char* cdbPath, Int_t run
a3d4b6ba 753 //TODO add option fCrateId
c95cf30c 754 )
755{
756 /// Generates a binary file containing the lookup table (LUT) from the
757 /// CDB, which can be used for the trigger reconstructor component later.
758 /// @param ddl Must be the DDL for which to generate the DDL,
759 /// in the range [20..21].
760 /// @param filename The name of the LUT file to generate.
761 /// @param cdbPath The CDB path to use.
762 /// @param run The run number to use for the CDB.
763 /// @return True if the generation of the LUT file succeeded.
764
765 AliHLTMUONTriggerReconstructorComponent comp;
766
767 if (ddl < 20 or 21 < ddl)
768 {
769 std::cerr << "ERROR: the DDL number must be in the range [20..21]." << std::endl;
770 return false;
771 }
772
773 char ddlNum[32];
774 char runNum[32];
775 sprintf(ddlNum, "%d", ddl+1);
776 sprintf(runNum, "%d", run);
777 const char* argv[7] = {"-ddl", ddlNum, "-cdbpath", cdbPath, "-run", runNum, NULL};
778 int result = comp.DoInit(6, argv);
779 if (result != 0)
780 {
781 // Error message already generated in DoInit.
b39b98c8 782 return false;
783 }
784
c95cf30c 785 std::fstream file(filename, std::ios::out);
786 if (not file)
787 {
788 std::cerr << "ERROR: could not open file: " << filename << std::endl;
789 return false;
790 }
791
792 file.write(
793 reinterpret_cast<char*>(comp.fTrigRec->LookupTableBuffer()),
794 comp.fTrigRec->LookupTableSize()
795 );
796 if (not file)
797 {
a3d4b6ba 798 std::cerr << "ERROR: There was a problem writing to the file: " << filename << std::endl;
c95cf30c 799 return false;
800 }
b39b98c8 801 file.close();
c95cf30c 802
803 comp.DoDeinit();
804
b39b98c8 805 return true;
960d54ad 806}