Tasks derive now from AliAnalysisTaskSE
[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)
47415aa9 154 {
d42549e3 155 fWarnForUnexpecedBlock = true;
47415aa9 156 continue;
157 }
158
159 HLTError("Unknown option '%s'.", argv[i]);
160 return EINVAL;
d42549e3 161 }
162
5bf92d6f 163 const int initArraySize = 10;
164 // allocate some initial memory for the reconstructed hit arrays.
165 try
166 {
167 fRecHitBlock[0] = new AliRecHitBlockInfo[initArraySize*4];
168 }
169 catch (const std::bad_alloc&)
170 {
171 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
172 return -ENOMEM;
173 }
174 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
175 fRecHitBlockArraySize = initArraySize;
176 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
177 for (Int_t i = 1; i < 4; i++)
178 {
179 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
180 }
181 // And reset the number of records actually stored in the arrays.
182 for (Int_t i = 0; i < 4; i++)
183 {
184 fRecHitBlockCount[i] = 0;
185 }
186
b92524d0 187 return 0;
188}
189
190
191int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
192{
6253e09b 193 ///
194 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
195 ///
196
b92524d0 197 if (fTracker != NULL)
198 {
199 delete fTracker;
200 fTracker = NULL;
201 }
5bf92d6f 202
203 // Remember that only fRecHitBlock[0] stores the pointer to the allocated memory.
204 // The other pointers are just reletive to this.
205 if (fRecHitBlock[0] != NULL)
206 delete [] fRecHitBlock[0];
207
208 fRecHitBlockArraySize = 0;
209 for (Int_t i = 0; i < 4; i++)
210 {
211 fRecHitBlockCount[i] = 0;
212 fRecHitBlock[i] = NULL;
213 }
214
b92524d0 215 return 0;
216}
217
218
219int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
220 const AliHLTComponentEventData& evtData,
5def1693 221 const AliHLTComponentBlockData* blocks,
222 AliHLTComponentTriggerData& /*trigData*/,
223 AliHLTUInt8_t* outputPtr,
b92524d0 224 AliHLTUInt32_t& size,
225 std::vector<AliHLTComponentBlockData>& outputBlocks
226 )
227{
6253e09b 228 ///
229 /// Inherited from AliHLTProcessor. Processes the new event data.
230 ///
231
b92524d0 232 Reset();
233 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
234
5bf92d6f 235 // Resize the rec hit arrays if we need to. To guarantee that they will not overflow
236 // we need to make sure each array is at least as big as the number of input data block.
237 if (fRecHitBlockArraySize < evtData.fBlockCnt)
238 {
239 // Release the old memory block and allocate more memory.
240 delete [] fRecHitBlock[0];
241 // Reset the number of records actually stored in the arrays.
242 for (Int_t i = 0; i < 4; i++)
243 {
244 fRecHitBlockCount[i] = 0;
245 }
246
247 try
248 {
249 fRecHitBlock[0] = new AliRecHitBlockInfo[evtData.fBlockCnt*4];
250 }
251 catch (const std::bad_alloc&)
252 {
253 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
254 // Ok so now we need to clear all the pointers because we actually
255 // deleted the memory.
256 fRecHitBlockArraySize = 0;
257 for (Int_t i = 0; i < 4; i++)
258 {
259 fRecHitBlock[i] = NULL;
260 }
261 return -ENOMEM;
262 }
263 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
264 fRecHitBlockArraySize = evtData.fBlockCnt;
265 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
266 for (Int_t i = 1; i < 4; i++)
267 {
268 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
269 }
270 }
271
b92524d0 272 AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
273 fBlock = &block;
274
275 if (not block.InitCommonHeader())
276 {
277 Logging(kHLTLogError,
278 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
279 "Buffer overflow",
280 "The buffer is only %d bytes in size. We need a minimum of %d bytes.",
281 size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
282 );
283 size = 0; // Important to tell framework that nothing was generated.
5bf92d6f 284 return -ENOBUFS;
b92524d0 285 }
286
287 // Loop over all input blocks in the event and add the ones that contain
288 // reconstructed hits into the hit buffers. The blocks containing trigger
289 // records are ignored for now and will be processed later.
290 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
291 {
292 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
293 {
294 specification |= blocks[n].fSpecification;
295
296 AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
297 if (not inblock.BufferSizeOk())
298 {
d42549e3 299 size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType);
300 if (blocks[n].fSize < headerSize)
301 {
302 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
303 " which is smaller than the minimum valid header size of %d bytes."
304 " The block must be corrupt.",
305 blocks[n].fSize, headerSize
306 );
307 continue;
308 }
309
310 size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType);
311 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
312 {
313 HLTError("Received a reconstructed hits data block with a record"
314 " width of %d bytes, but the expected value is %d bytes."
315 " The block might be corrupt.",
47415aa9 316 inblock.CommonBlockHeader().fRecordWidth, expectedWidth
d42549e3 317 );
318 continue;
319 }
320
321 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
322 " but the block header claims the block should be %d bytes."
323 " The block might be corrupt.",
324 blocks[n].fSize, inblock.BytesUsed()
b92524d0 325 );
326 continue;
327 }
328
4a9f11d4 329 if (inblock.Nentries() != 0)
330 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
331 else
332 {
d42549e3 333 Logging(kHLTLogDebug,
4a9f11d4 334 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
335 "Block empty",
336 "Received a reconstructed hits data block which contains no entries."
337 );
338 }
b92524d0 339 }
340 else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
341 {
342 // Log a message indicating that we got a data block that we
343 // do not know how to handle.
344 char id[kAliHLTComponentDataTypefIDsize+1];
345 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
346 id[i] = blocks[n].fDataType.fID[i];
347 id[kAliHLTComponentDataTypefIDsize] = '\0';
348 char origin[kAliHLTComponentDataTypefOriginSize+1];
349 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
350 origin[i] = blocks[n].fDataType.fOrigin[i];
351 origin[kAliHLTComponentDataTypefOriginSize] = '\0';
352
d42549e3 353 if (fWarnForUnexpecedBlock)
354 HLTWarning("Received a data block of a type we cannot handle: %s origin: %s",
355 static_cast<char*>(id), static_cast<char*>(origin)
356 );
357 else
358 HLTDebug("Received a data block of a type we cannot handle: %s origin: %s",
359 static_cast<char*>(id), static_cast<char*>(origin)
360 );
b92524d0 361 }
362 }
363
364 // Again loop over all input blocks in the event, but this time look for
365 // the trigger record blocks and process these.
366 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
367 {
368 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
369 continue;
370
371 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
372 if (not inblock.BufferSizeOk())
373 {
d42549e3 374 size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType);
375 if (blocks[n].fSize < headerSize)
376 {
377 HLTError("Received a trigger records data block with a size of %d bytes,"
378 " which is smaller than the minimum valid header size of %d bytes."
379 " The block must be corrupt.",
380 blocks[n].fSize, headerSize
381 );
382 continue;
383 }
384
385 size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType);
386 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
387 {
388 HLTError("Received a trigger records data block with a record"
389 " width of %d bytes, but the expected value is %d bytes."
390 " The block might be corrupt.",
47415aa9 391 inblock.CommonBlockHeader().fRecordWidth, expectedWidth
d42549e3 392 );
393 continue;
394 }
395
396 HLTError("Received a trigger records data block with a size of %d bytes,"
397 " but the block header claims the block should be %d bytes."
398 " The block might be corrupt.",
399 blocks[n].fSize, inblock.BytesUsed()
b92524d0 400 );
401 continue;
402 }
403 DebugTrace("Processing a trigger block with "
404 << inblock.Nentries() << " entries."
405 );
406
407 specification |= blocks[n].fSpecification;
408
409 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
410 {
411 fTracker->FindTrack(inblock[i]);
412
413 // Reset the tracker so that we do not double count tracks.
414 fTracker->Reset();
415 }
416 }
417
418 AliHLTComponentBlockData bd;
419 FillBlockData(bd);
420 bd.fPtr = outputPtr;
421 bd.fOffset = 0;
422 bd.fSize = block.BytesUsed();
423 bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
424 bd.fSpecification = specification;
425 outputBlocks.push_back(bd);
426 size = block.BytesUsed();
427
428 return 0;
429}
430
431
432void AliHLTMUONMansoTrackerFSMComponent::Reset()
433{
6253e09b 434 ///
435 /// Reset the track count and reconstructed hit data block arrays.
436 ///
437
b92524d0 438 DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent.");
439
440 //fTracker->Reset(); // Not necessary here because it is done after every FindTrack call.
441 fTrackCount = 0;
442 fBlock = NULL; // Do not delete. Already done implicitly at the end of DoEvent.
443 for (int i = 0; i < 4; i++)
444 {
5bf92d6f 445 fRecHitBlockCount[i] = 0;
b92524d0 446 }
447}
448
449
450void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
6253e09b 451 AliHLTUInt32_t specification,
b92524d0 452 const AliHLTMUONRecHitStruct* recHits,
453 AliHLTUInt32_t count
454 )
455{
6253e09b 456 ///
457 /// Adds a new reconstructed hit data block to the internal list of blocks
458 /// for the tracker to process.
459 /// These lists will later be used when the tracker requests them through
460 /// the callback method 'RequestClusters'.
461 ///
462
b92524d0 463 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x"
464 << std::hex << specification << std::dec << " and count = "
465 << count << " rec hits."
466 );
467
468 AliHLTUInt8_t chamberMap[20] = {
469 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10
470 };
471
472 // Identify the chamber the rec hits came from using the specifications field.
473 bool gotDataFromDDL[22];
474 AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL);
475
476 AliHLTInt8_t chamber = -1;
477 for (int i = 0; i < 20; i++)
478 {
479 if (not gotDataFromDDL[i]) continue;
480 if (7 <= chamberMap[i] and chamberMap[i] <= 10)
481 {
482 if (chamber != -1 and chamber != chamberMap[i])
483 {
484 Logging(kHLTLogError,
485 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
486 "Invalid block",
487 "Received a data block with data from multiple chambers."
488 " This component cannot handle such a case."
489 );
490 return;
491 }
492 else
493 chamber = chamberMap[i];
494 }
495 else
496 {
497 Logging(kHLTLogError,
498 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
499 "Invalid chamber",
500 "Received a data block with data from chamber %d"
501 " which is outside the expected range: [7..10].",
502 chamberMap[i]
503 );
504 return;
505 }
506 }
507
508 // Make sure we got one chamber number.
509 if (chamber < 7 or 10 < chamber)
510 {
511 Logging(kHLTLogError,
512 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
513 "Invalid block",
514 "Received a reconstructed hit data block with a null specification."
515 " Cannot know which chamber the data comes from."
516 );
517 return;
518 }
519
520 DebugTrace("Added " << count << " reconstructed hits from chamber "
d42549e3 521 << (int)chamber << " to the internal arrays."
522 );
b92524d0 523
5bf92d6f 524 assert( fRecHitBlockCount[chamber-7] < fRecHitBlockArraySize );
525 AliRecHitBlockInfo info(count, recHits);
526 fRecHitBlock[chamber-7][fRecHitBlockCount[chamber-7]] = info;
527 fRecHitBlockCount[chamber-7]++;
b92524d0 528}
529
530
531void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
532 AliHLTMUONMansoTrackerFSM* tracker,
f1169efa 533 AliHLTFloat32_t left, AliHLTFloat32_t right,
534 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
b92524d0 535 AliHLTMUONChamberName chamber, const void* tag
536 )
537{
6253e09b 538 ///
539 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
540 /// This is the call back method used by the tracker algorithm to request
541 /// clusters on a certain chamber.
542 ///
543
b92524d0 544 DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
545 void* ctag = const_cast<void*>(tag);
546 int chNo = -1;
5bf92d6f 547 AliHLTUInt32_t recHitsCount = 0;
548 AliRecHitBlockInfo* recHitsBlock = NULL;
b92524d0 549 switch (chamber)
550 {
551 case kChamber7:
5bf92d6f 552 recHitsCount = fRecHitBlockCount[0];
553 recHitsBlock = fRecHitBlock[0];
b92524d0 554 chNo = 7;
555 break;
556
557 case kChamber8:
5bf92d6f 558 recHitsCount = fRecHitBlockCount[1];
559 recHitsBlock = fRecHitBlock[1];
b92524d0 560 chNo = 8;
561 break;
562
563 case kChamber9:
5bf92d6f 564 recHitsCount = fRecHitBlockCount[2];
565 recHitsBlock = fRecHitBlock[2];
b92524d0 566 chNo = 9;
567 break;
568
569 case kChamber10:
5bf92d6f 570 recHitsCount = fRecHitBlockCount[3];
571 recHitsBlock = fRecHitBlock[3];
b92524d0 572 chNo = 10;
573 break;
574
575 default: return;
576 }
577
578 DebugTrace("Returning requested hits for chamber " << chNo << ":");
5bf92d6f 579 for (AliHLTUInt32_t i = 0; i < recHitsCount; i++)
580 for (AliHLTUInt32_t j = 0; j < recHitsBlock[i].Count(); j++)
b92524d0 581 {
5bf92d6f 582 const AliHLTMUONRecHitStruct* hit = &(recHitsBlock[i].Data()[j]);
f1169efa 583 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
584 tracker->ReturnClusters(ctag, hit, 1);
b92524d0 585 }
586 DebugTrace("Done returning hits from chamber " << chNo << ".");
587 tracker->EndOfClusters(ctag);
588}
589
590
591void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
5def1693 592 AliHLTMUONMansoTrackerFSM* /*tracker*/
b92524d0 593 )
594{
6253e09b 595 ///
596 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
597 /// Nothing special to do here.
598 ///
599
b92524d0 600 DebugTrace("End of cluster requests.");
601}
602
603
604void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
605{
6253e09b 606 ///
607 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
608 /// This is the call back method used by the tracker algorithm to declare
609 /// that a new track has been found.
610 ///
611
b92524d0 612 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
613
614 AliHLTMUONMansoTracksBlockWriter* block =
615 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
616
617 AliHLTMUONMansoTrackStruct* track = block->AddEntry();
618 if (track == NULL)
619 {
620 Logging(kHLTLogError,
621 "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
622 "Buffer overflow",
623 "We have overflowed the output buffer for Manso track data."
624 " The output buffer size is only %d bytes.",
625 block->BufferSize()
626 );
627 return;
628 }
629
630 fTrackCount++;
631 tracker->FillTrackData(*track);
632 DebugTrace("\tTrack data = " << *track);
633}
634
635
5def1693 636void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
b92524d0 637{
6253e09b 638 ///
639 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
640 /// Nothing special to do here.
641 ///
642
b92524d0 643 DebugTrace("No track found.");
644}
6253e09b 645