]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx
Getting rid of naming violation and unecessary use of std::vector.
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONMansoTrackerFSMComponent.cxx
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
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 ///
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>
35 #include <cstring>
36 #include <cerrno>
37 #include <new>
38
39 ClassImp(AliHLTMUONMansoTrackerFSMComponent);
40
41
42 AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
43         AliHLTProcessor(),
44         AliHLTMUONMansoTrackerFSMCallback(),
45         fTracker(NULL),
46         fTrackCount(0),
47         fBlock(NULL),
48         fRecHitBlockArraySize(0),
49         fWarnForUnexpecedBlock(false)
50 {
51         ///
52         /// Default constructor.
53         ///
54         
55         for (Int_t i = 0; i < 4; i++)
56         {
57                 fRecHitBlockCount[i] = 0;
58                 fRecHitBlock[i] = NULL;
59         }
60 }
61
62
63 AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
64 {
65         ///
66         /// Default destructor.
67         ///
68         
69         assert( fTracker == NULL );
70         assert( fRecHitBlock[0] == NULL );
71 }
72
73
74 const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
75 {
76         ///
77         /// Inherited from AliHLTComponent. Returns the component ID.
78         ///
79         
80         return AliHLTMUONConstants::MansoTrackerFSMId();
81 }
82
83
84 void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
85                 vector<AliHLTComponentDataType>& list
86         )
87 {
88         ///
89         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
90         ///
91         
92         assert( list.empty() );
93         list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
94         list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
95 }
96
97
98 AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
99 {
100         ///
101         /// Inherited from AliHLTComponent. Returns the output data type.
102         ///
103         
104         return AliHLTMUONConstants::MansoTracksBlockDataType();
105 }
106
107
108 void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
109                 unsigned long& constBase, double& inputMultiplier
110         )
111 {
112         ///
113         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
114         ///
115         
116         constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
117         inputMultiplier = 1;
118 }
119
120
121 AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
122 {
123         ///
124         /// Inherited from AliHLTComponent. Creates a new object instance.
125         ///
126         
127         return new AliHLTMUONMansoTrackerFSMComponent;
128 }
129
130
131 int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
132 {
133         ///
134         /// Inherited from AliHLTComponent.
135         /// Parses the command line parameters and initialises the component.
136         ///
137         
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         }
147         fTracker->SetCallback(this);
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         
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         
181         return 0;
182 }
183
184
185 int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
186 {
187         ///
188         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
189         ///
190         
191         if (fTracker != NULL)
192         {
193                 delete fTracker;
194                 fTracker = NULL;
195         }
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         
209         return 0;
210 }
211
212
213 int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
214                 const AliHLTComponentEventData& evtData,
215                 const AliHLTComponentBlockData* blocks,
216                 AliHLTComponentTriggerData& /*trigData*/,
217                 AliHLTUInt8_t* outputPtr,
218                 AliHLTUInt32_t& size,
219                 std::vector<AliHLTComponentBlockData>& outputBlocks
220         )
221 {
222         ///
223         /// Inherited from AliHLTProcessor. Processes the new event data.
224         ///
225         
226         Reset();
227         AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
228         
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         
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.
278                 return -ENOBUFS;
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                         {
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()
319                                 );
320                                 continue;
321                         }
322                         
323                         if (inblock.Nentries() != 0)
324                                 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
325                         else
326                         {
327                                 Logging(kHLTLogDebug,
328                                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
329                                         "Block empty",
330                                         "Received a reconstructed hits data block which contains no entries."
331                                 );
332                         }
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                         
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                                 );
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                 {
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()
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
426 void AliHLTMUONMansoTrackerFSMComponent::Reset()
427 {
428         ///
429         /// Reset the track count and reconstructed hit data block arrays.
430         ///
431         
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         {
439                 fRecHitBlockCount[i] = 0;
440         }
441 }
442
443
444 void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
445                 AliHLTUInt32_t specification,
446                 const AliHLTMUONRecHitStruct* recHits,
447                 AliHLTUInt32_t count
448         )
449 {
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         
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 "
515                 << (int)chamber << " to the internal arrays."
516         );
517         
518         assert( fRecHitBlockCount[chamber-7] < fRecHitBlockArraySize );
519         AliRecHitBlockInfo info(count, recHits);
520         fRecHitBlock[chamber-7][fRecHitBlockCount[chamber-7]] = info;
521         fRecHitBlockCount[chamber-7]++;
522 }
523
524
525 void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
526                 AliHLTMUONMansoTrackerFSM* tracker,
527                 AliHLTFloat32_t left, AliHLTFloat32_t right,
528                 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
529                 AliHLTMUONChamberName chamber, const void* tag
530         )
531 {
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
538         DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
539         void* ctag = const_cast<void*>(tag);
540         int chNo = -1;
541         AliHLTUInt32_t recHitsCount = 0;
542         AliRecHitBlockInfo* recHitsBlock = NULL;
543         switch (chamber)
544         {
545         case kChamber7:
546                 recHitsCount = fRecHitBlockCount[0];
547                 recHitsBlock = fRecHitBlock[0];
548                 chNo = 7;
549                 break;
550
551         case kChamber8:
552                 recHitsCount = fRecHitBlockCount[1];
553                 recHitsBlock = fRecHitBlock[1];
554                 chNo = 8;
555                 break;
556
557         case kChamber9:
558                 recHitsCount = fRecHitBlockCount[2];
559                 recHitsBlock = fRecHitBlock[2];
560                 chNo = 9;
561                 break;
562
563         case kChamber10:
564                 recHitsCount = fRecHitBlockCount[3];
565                 recHitsBlock = fRecHitBlock[3];
566                 chNo = 10;
567                 break;
568
569         default: return;
570         }
571         
572         DebugTrace("Returning requested hits for chamber " << chNo << ":");
573         for (AliHLTUInt32_t i = 0; i < recHitsCount; i++)
574         for (AliHLTUInt32_t j = 0; j < recHitsBlock[i].Count(); j++)
575         {
576                 const AliHLTMUONRecHitStruct* hit = &(recHitsBlock[i].Data()[j]);
577                 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
578                         tracker->ReturnClusters(ctag, hit, 1);
579         }
580         DebugTrace("Done returning hits from chamber " << chNo << ".");
581         tracker->EndOfClusters(ctag);
582 }
583
584
585 void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
586                 AliHLTMUONMansoTrackerFSM* /*tracker*/
587         )
588 {
589         ///
590         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
591         /// Nothing special to do here.
592         ///
593         
594         DebugTrace("End of cluster requests.");
595 }
596
597
598 void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
599 {
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         
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
630 void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
631 {
632         ///
633         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
634         /// Nothing special to do here.
635         ///
636         
637         DebugTrace("No track found.");
638 }
639