in AliShuttle.cxx: SHUTTLE logbook is updated in case of invalid run times:
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONMansoTrackerFSMComponent.cxx
CommitLineData
b92524d0 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 * Indranil Das <indra.das@saha.ac.in> *
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 *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
18/* $Id$ */
19
6253e09b 20///
21/// @file AliHLTMUONMansoTrackerFSMComponent.cxx
22/// @author Artur Szostak <artursz@iafrica.com>,
23/// Indranil Das <indra.das@saha.ac.in>
24/// @date
25/// @brief Implementation of AliHLTMUONMansoTrackerFSMComponent class.
26///
b92524d0 27
28#include "AliHLTMUONMansoTrackerFSMComponent.h"
29#include "AliHLTMUONConstants.h"
30#include "AliHLTMUONUtils.h"
31#include "AliHLTMUONMansoTrackerFSM.h"
32#include "AliHLTMUONDataBlockReader.h"
33#include "AliHLTMUONDataBlockWriter.h"
34#include <cstdlib>
d42549e3 35#include <cstring>
b92524d0 36#include <cerrno>
5bf92d6f 37#include <new>
b92524d0 38
b92524d0 39ClassImp(AliHLTMUONMansoTrackerFSMComponent);
40
41
42AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
43 AliHLTProcessor(),
44 AliHLTMUONMansoTrackerFSMCallback(),
45 fTracker(NULL),
46 fTrackCount(0),
d42549e3 47 fBlock(NULL),
5bf92d6f 48 fRecHitBlockArraySize(0),
d42549e3 49 fWarnForUnexpecedBlock(false)
b92524d0 50{
6253e09b 51 ///
52 /// Default constructor.
53 ///
5bf92d6f 54
55 for (Int_t i = 0; i < 4; i++)
56 {
57 fRecHitBlockCount[i] = 0;
58 fRecHitBlock[i] = NULL;
59 }
b92524d0 60}
61
62
63AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
64{
6253e09b 65 ///
66 /// Default destructor.
67 ///
68
b92524d0 69 assert( fTracker == NULL );
5bf92d6f 70 assert( fRecHitBlock[0] == NULL );
b92524d0 71}
72
73
74const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
75{
6253e09b 76 ///
77 /// Inherited from AliHLTComponent. Returns the component ID.
78 ///
79
b92524d0 80 return AliHLTMUONConstants::MansoTrackerFSMId();
81}
82
83
84void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
85 vector<AliHLTComponentDataType>& list
86 )
87{
6253e09b 88 ///
89 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
90 ///
91
b92524d0 92 assert( list.empty() );
93 list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
94 list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
95}
96
97
98AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
99{
6253e09b 100 ///
101 /// Inherited from AliHLTComponent. Returns the output data type.
102 ///
103
b92524d0 104 return AliHLTMUONConstants::MansoTracksBlockDataType();
105}
106
107
108void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
109 unsigned long& constBase, double& inputMultiplier
110 )
111{
6253e09b 112 ///
113 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
114 ///
115
b92524d0 116 constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
117 inputMultiplier = 1;
118}
119
120
121AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
122{
6253e09b 123 ///
124 /// Inherited from AliHLTComponent. Creates a new object instance.
125 ///
126
b92524d0 127 return new AliHLTMUONMansoTrackerFSMComponent;
128}
129
130
131int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
132{
6253e09b 133 ///
134 /// Inherited from AliHLTComponent.
135 /// Parses the command line parameters and initialises the component.
136 ///
137
5bf92d6f 138 try
139 {
140 fTracker = new AliHLTMUONMansoTrackerFSM();
141 }
142 catch (const std::bad_alloc&)
143 {
144 HLTError("Could not allocate more memory for the tracker component.");
145 return -ENOMEM;
146 }
b92524d0 147 fTracker->SetCallback(this);
d42549e3 148
149 fWarnForUnexpecedBlock = false;
150
151 for (int i = 0; i < argc; i++)
152 {
153 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
154 fWarnForUnexpecedBlock = true;
155 }
156
5bf92d6f 157 const int initArraySize = 10;
158 // allocate some initial memory for the reconstructed hit arrays.
159 try
160 {
161 fRecHitBlock[0] = new AliRecHitBlockInfo[initArraySize*4];
162 }
163 catch (const std::bad_alloc&)
164 {
165 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
166 return -ENOMEM;
167 }
168 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
169 fRecHitBlockArraySize = initArraySize;
170 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
171 for (Int_t i = 1; i < 4; i++)
172 {
173 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
174 }
175 // And reset the number of records actually stored in the arrays.
176 for (Int_t i = 0; i < 4; i++)
177 {
178 fRecHitBlockCount[i] = 0;
179 }
180
b92524d0 181 return 0;
182}
183
184
185int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
186{
6253e09b 187 ///
188 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
189 ///
190
b92524d0 191 if (fTracker != NULL)
192 {
193 delete fTracker;
194 fTracker = NULL;
195 }
5bf92d6f 196
197 // Remember that only fRecHitBlock[0] stores the pointer to the allocated memory.
198 // The other pointers are just reletive to this.
199 if (fRecHitBlock[0] != NULL)
200 delete [] fRecHitBlock[0];
201
202 fRecHitBlockArraySize = 0;
203 for (Int_t i = 0; i < 4; i++)
204 {
205 fRecHitBlockCount[i] = 0;
206 fRecHitBlock[i] = NULL;
207 }
208
b92524d0 209 return 0;
210}
211
212
213int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
214 const AliHLTComponentEventData& evtData,
5def1693 215 const AliHLTComponentBlockData* blocks,
216 AliHLTComponentTriggerData& /*trigData*/,
217 AliHLTUInt8_t* outputPtr,
b92524d0 218 AliHLTUInt32_t& size,
219 std::vector<AliHLTComponentBlockData>& outputBlocks
220 )
221{
6253e09b 222 ///
223 /// Inherited from AliHLTProcessor. Processes the new event data.
224 ///
225
b92524d0 226 Reset();
227 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
228
5bf92d6f 229 // Resize the rec hit arrays if we need to. To guarantee that they will not overflow
230 // we need to make sure each array is at least as big as the number of input data block.
231 if (fRecHitBlockArraySize < evtData.fBlockCnt)
232 {
233 // Release the old memory block and allocate more memory.
234 delete [] fRecHitBlock[0];
235 // Reset the number of records actually stored in the arrays.
236 for (Int_t i = 0; i < 4; i++)
237 {
238 fRecHitBlockCount[i] = 0;
239 }
240
241 try
242 {
243 fRecHitBlock[0] = new AliRecHitBlockInfo[evtData.fBlockCnt*4];
244 }
245 catch (const std::bad_alloc&)
246 {
247 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
248 // Ok so now we need to clear all the pointers because we actually
249 // deleted the memory.
250 fRecHitBlockArraySize = 0;
251 for (Int_t i = 0; i < 4; i++)
252 {
253 fRecHitBlock[i] = NULL;
254 }
255 return -ENOMEM;
256 }
257 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
258 fRecHitBlockArraySize = evtData.fBlockCnt;
259 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
260 for (Int_t i = 1; i < 4; i++)
261 {
262 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
263 }
264 }
265
b92524d0 266 AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
267 fBlock = &block;
268
269 if (not block.InitCommonHeader())
270 {
271 Logging(kHLTLogError,
272 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
273 "Buffer overflow",
274 "The buffer is only %d bytes in size. We need a minimum of %d bytes.",
275 size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
276 );
277 size = 0; // Important to tell framework that nothing was generated.
5bf92d6f 278 return -ENOBUFS;
b92524d0 279 }
280
281 // Loop over all input blocks in the event and add the ones that contain
282 // reconstructed hits into the hit buffers. The blocks containing trigger
283 // records are ignored for now and will be processed later.
284 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
285 {
286 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
287 {
288 specification |= blocks[n].fSpecification;
289
290 AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
291 if (not inblock.BufferSizeOk())
292 {
d42549e3 293 size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType);
294 if (blocks[n].fSize < headerSize)
295 {
296 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
297 " which is smaller than the minimum valid header size of %d bytes."
298 " The block must be corrupt.",
299 blocks[n].fSize, headerSize
300 );
301 continue;
302 }
303
304 size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType);
305 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
306 {
307 HLTError("Received a reconstructed hits data block with a record"
308 " width of %d bytes, but the expected value is %d bytes."
309 " The block might be corrupt.",
310 blocks[n].fSize, headerSize
311 );
312 continue;
313 }
314
315 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
316 " but the block header claims the block should be %d bytes."
317 " The block might be corrupt.",
318 blocks[n].fSize, inblock.BytesUsed()
b92524d0 319 );
320 continue;
321 }
322
4a9f11d4 323 if (inblock.Nentries() != 0)
324 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
325 else
326 {
d42549e3 327 Logging(kHLTLogDebug,
4a9f11d4 328 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
329 "Block empty",
330 "Received a reconstructed hits data block which contains no entries."
331 );
332 }
b92524d0 333 }
334 else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
335 {
336 // Log a message indicating that we got a data block that we
337 // do not know how to handle.
338 char id[kAliHLTComponentDataTypefIDsize+1];
339 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
340 id[i] = blocks[n].fDataType.fID[i];
341 id[kAliHLTComponentDataTypefIDsize] = '\0';
342 char origin[kAliHLTComponentDataTypefOriginSize+1];
343 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
344 origin[i] = blocks[n].fDataType.fOrigin[i];
345 origin[kAliHLTComponentDataTypefOriginSize] = '\0';
346
d42549e3 347 if (fWarnForUnexpecedBlock)
348 HLTWarning("Received a data block of a type we cannot handle: %s origin: %s",
349 static_cast<char*>(id), static_cast<char*>(origin)
350 );
351 else
352 HLTDebug("Received a data block of a type we cannot handle: %s origin: %s",
353 static_cast<char*>(id), static_cast<char*>(origin)
354 );
b92524d0 355 }
356 }
357
358 // Again loop over all input blocks in the event, but this time look for
359 // the trigger record blocks and process these.
360 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
361 {
362 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
363 continue;
364
365 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
366 if (not inblock.BufferSizeOk())
367 {
d42549e3 368 size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType);
369 if (blocks[n].fSize < headerSize)
370 {
371 HLTError("Received a trigger records data block with a size of %d bytes,"
372 " which is smaller than the minimum valid header size of %d bytes."
373 " The block must be corrupt.",
374 blocks[n].fSize, headerSize
375 );
376 continue;
377 }
378
379 size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType);
380 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
381 {
382 HLTError("Received a trigger records data block with a record"
383 " width of %d bytes, but the expected value is %d bytes."
384 " The block might be corrupt.",
385 blocks[n].fSize, headerSize
386 );
387 continue;
388 }
389
390 HLTError("Received a trigger records data block with a size of %d bytes,"
391 " but the block header claims the block should be %d bytes."
392 " The block might be corrupt.",
393 blocks[n].fSize, inblock.BytesUsed()
b92524d0 394 );
395 continue;
396 }
397 DebugTrace("Processing a trigger block with "
398 << inblock.Nentries() << " entries."
399 );
400
401 specification |= blocks[n].fSpecification;
402
403 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
404 {
405 fTracker->FindTrack(inblock[i]);
406
407 // Reset the tracker so that we do not double count tracks.
408 fTracker->Reset();
409 }
410 }
411
412 AliHLTComponentBlockData bd;
413 FillBlockData(bd);
414 bd.fPtr = outputPtr;
415 bd.fOffset = 0;
416 bd.fSize = block.BytesUsed();
417 bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
418 bd.fSpecification = specification;
419 outputBlocks.push_back(bd);
420 size = block.BytesUsed();
421
422 return 0;
423}
424
425
426void AliHLTMUONMansoTrackerFSMComponent::Reset()
427{
6253e09b 428 ///
429 /// Reset the track count and reconstructed hit data block arrays.
430 ///
431
b92524d0 432 DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent.");
433
434 //fTracker->Reset(); // Not necessary here because it is done after every FindTrack call.
435 fTrackCount = 0;
436 fBlock = NULL; // Do not delete. Already done implicitly at the end of DoEvent.
437 for (int i = 0; i < 4; i++)
438 {
5bf92d6f 439 fRecHitBlockCount[i] = 0;
b92524d0 440 }
441}
442
443
444void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
6253e09b 445 AliHLTUInt32_t specification,
b92524d0 446 const AliHLTMUONRecHitStruct* recHits,
447 AliHLTUInt32_t count
448 )
449{
6253e09b 450 ///
451 /// Adds a new reconstructed hit data block to the internal list of blocks
452 /// for the tracker to process.
453 /// These lists will later be used when the tracker requests them through
454 /// the callback method 'RequestClusters'.
455 ///
456
b92524d0 457 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x"
458 << std::hex << specification << std::dec << " and count = "
459 << count << " rec hits."
460 );
461
462 AliHLTUInt8_t chamberMap[20] = {
463 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10
464 };
465
466 // Identify the chamber the rec hits came from using the specifications field.
467 bool gotDataFromDDL[22];
468 AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL);
469
470 AliHLTInt8_t chamber = -1;
471 for (int i = 0; i < 20; i++)
472 {
473 if (not gotDataFromDDL[i]) continue;
474 if (7 <= chamberMap[i] and chamberMap[i] <= 10)
475 {
476 if (chamber != -1 and chamber != chamberMap[i])
477 {
478 Logging(kHLTLogError,
479 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
480 "Invalid block",
481 "Received a data block with data from multiple chambers."
482 " This component cannot handle such a case."
483 );
484 return;
485 }
486 else
487 chamber = chamberMap[i];
488 }
489 else
490 {
491 Logging(kHLTLogError,
492 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
493 "Invalid chamber",
494 "Received a data block with data from chamber %d"
495 " which is outside the expected range: [7..10].",
496 chamberMap[i]
497 );
498 return;
499 }
500 }
501
502 // Make sure we got one chamber number.
503 if (chamber < 7 or 10 < chamber)
504 {
505 Logging(kHLTLogError,
506 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
507 "Invalid block",
508 "Received a reconstructed hit data block with a null specification."
509 " Cannot know which chamber the data comes from."
510 );
511 return;
512 }
513
514 DebugTrace("Added " << count << " reconstructed hits from chamber "
d42549e3 515 << (int)chamber << " to the internal arrays."
516 );
b92524d0 517
5bf92d6f 518 assert( fRecHitBlockCount[chamber-7] < fRecHitBlockArraySize );
519 AliRecHitBlockInfo info(count, recHits);
520 fRecHitBlock[chamber-7][fRecHitBlockCount[chamber-7]] = info;
521 fRecHitBlockCount[chamber-7]++;
b92524d0 522}
523
524
525void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
526 AliHLTMUONMansoTrackerFSM* tracker,
f1169efa 527 AliHLTFloat32_t left, AliHLTFloat32_t right,
528 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
b92524d0 529 AliHLTMUONChamberName chamber, const void* tag
530 )
531{
6253e09b 532 ///
533 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
534 /// This is the call back method used by the tracker algorithm to request
535 /// clusters on a certain chamber.
536 ///
537
b92524d0 538 DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
539 void* ctag = const_cast<void*>(tag);
540 int chNo = -1;
5bf92d6f 541 AliHLTUInt32_t recHitsCount = 0;
542 AliRecHitBlockInfo* recHitsBlock = NULL;
b92524d0 543 switch (chamber)
544 {
545 case kChamber7:
5bf92d6f 546 recHitsCount = fRecHitBlockCount[0];
547 recHitsBlock = fRecHitBlock[0];
b92524d0 548 chNo = 7;
549 break;
550
551 case kChamber8:
5bf92d6f 552 recHitsCount = fRecHitBlockCount[1];
553 recHitsBlock = fRecHitBlock[1];
b92524d0 554 chNo = 8;
555 break;
556
557 case kChamber9:
5bf92d6f 558 recHitsCount = fRecHitBlockCount[2];
559 recHitsBlock = fRecHitBlock[2];
b92524d0 560 chNo = 9;
561 break;
562
563 case kChamber10:
5bf92d6f 564 recHitsCount = fRecHitBlockCount[3];
565 recHitsBlock = fRecHitBlock[3];
b92524d0 566 chNo = 10;
567 break;
568
569 default: return;
570 }
571
572 DebugTrace("Returning requested hits for chamber " << chNo << ":");
5bf92d6f 573 for (AliHLTUInt32_t i = 0; i < recHitsCount; i++)
574 for (AliHLTUInt32_t j = 0; j < recHitsBlock[i].Count(); j++)
b92524d0 575 {
5bf92d6f 576 const AliHLTMUONRecHitStruct* hit = &(recHitsBlock[i].Data()[j]);
f1169efa 577 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
578 tracker->ReturnClusters(ctag, hit, 1);
b92524d0 579 }
580 DebugTrace("Done returning hits from chamber " << chNo << ".");
581 tracker->EndOfClusters(ctag);
582}
583
584
585void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
5def1693 586 AliHLTMUONMansoTrackerFSM* /*tracker*/
b92524d0 587 )
588{
6253e09b 589 ///
590 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
591 /// Nothing special to do here.
592 ///
593
b92524d0 594 DebugTrace("End of cluster requests.");
595}
596
597
598void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
599{
6253e09b 600 ///
601 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
602 /// This is the call back method used by the tracker algorithm to declare
603 /// that a new track has been found.
604 ///
605
b92524d0 606 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
607
608 AliHLTMUONMansoTracksBlockWriter* block =
609 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
610
611 AliHLTMUONMansoTrackStruct* track = block->AddEntry();
612 if (track == NULL)
613 {
614 Logging(kHLTLogError,
615 "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
616 "Buffer overflow",
617 "We have overflowed the output buffer for Manso track data."
618 " The output buffer size is only %d bytes.",
619 block->BufferSize()
620 );
621 return;
622 }
623
624 fTrackCount++;
625 tracker->FillTrackData(*track);
626 DebugTrace("\tTrack data = " << *track);
627}
628
629
5def1693 630void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
b92524d0 631{
6253e09b 632 ///
633 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
634 /// Nothing special to do here.
635 ///
636
b92524d0 637 DebugTrace("No track found.");
638}
6253e09b 639