]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx
bb0a250051f7ccd4d1eb86fd15d9816f8c61dc08
[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
38 ClassImp(AliHLTMUONMansoTrackerFSMComponent);
39
40
41 AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
42         AliHLTProcessor(),
43         AliHLTMUONMansoTrackerFSMCallback(),
44         fTracker(NULL),
45         fTrackCount(0),
46         fBlock(NULL),
47         fWarnForUnexpecedBlock(false)
48 {
49         ///
50         /// Default constructor.
51         ///
52 }
53
54
55 AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
56 {
57         ///
58         /// Default destructor.
59         ///
60         
61         assert( fTracker == NULL );
62 }
63
64
65 const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
66 {
67         ///
68         /// Inherited from AliHLTComponent. Returns the component ID.
69         ///
70         
71         return AliHLTMUONConstants::MansoTrackerFSMId();
72 }
73
74
75 void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
76                 vector<AliHLTComponentDataType>& list
77         )
78 {
79         ///
80         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
81         ///
82         
83         assert( list.empty() );
84         list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
85         list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
86 }
87
88
89 AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
90 {
91         ///
92         /// Inherited from AliHLTComponent. Returns the output data type.
93         ///
94         
95         return AliHLTMUONConstants::MansoTracksBlockDataType();
96 }
97
98
99 void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
100                 unsigned long& constBase, double& inputMultiplier
101         )
102 {
103         ///
104         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
105         ///
106         
107         constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
108         inputMultiplier = 1;
109 }
110
111
112 AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
113 {
114         ///
115         /// Inherited from AliHLTComponent. Creates a new object instance.
116         ///
117         
118         return new AliHLTMUONMansoTrackerFSMComponent;
119 }
120
121
122 int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
123 {
124         ///
125         /// Inherited from AliHLTComponent.
126         /// Parses the command line parameters and initialises the component.
127         ///
128         
129         fTracker = new AliHLTMUONMansoTrackerFSM();
130         fTracker->SetCallback(this);
131         
132         fWarnForUnexpecedBlock = false;
133         
134         for (int i = 0; i < argc; i++)
135         {
136                 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
137                         fWarnForUnexpecedBlock = true;
138         }
139         
140         return 0;
141 }
142
143
144 int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
145 {
146         ///
147         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
148         ///
149         
150         if (fTracker != NULL)
151         {
152                 delete fTracker;
153                 fTracker = NULL;
154         }
155         return 0;
156 }
157
158
159 int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
160                 const AliHLTComponentEventData& evtData,
161                 const AliHLTComponentBlockData* blocks,
162                 AliHLTComponentTriggerData& /*trigData*/,
163                 AliHLTUInt8_t* outputPtr,
164                 AliHLTUInt32_t& size,
165                 std::vector<AliHLTComponentBlockData>& outputBlocks
166         )
167 {
168         ///
169         /// Inherited from AliHLTProcessor. Processes the new event data.
170         ///
171         
172         Reset();
173         AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
174         
175         AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
176         fBlock = &block;
177         
178         if (not block.InitCommonHeader())
179         {
180                 Logging(kHLTLogError,
181                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
182                         "Buffer overflow",
183                         "The buffer is only %d bytes in size. We need a minimum of %d bytes.",
184                         size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
185                 );
186                 size = 0; // Important to tell framework that nothing was generated.
187                 return ENOBUFS;
188         }
189
190         // Loop over all input blocks in the event and add the ones that contain
191         // reconstructed hits into the hit buffers. The blocks containing trigger
192         // records are ignored for now and will be processed later.
193         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
194         {
195                 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
196                 {
197                         specification |= blocks[n].fSpecification;
198                         
199                         AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
200                         if (not inblock.BufferSizeOk())
201                         {
202                                 size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType);
203                                 if (blocks[n].fSize < headerSize)
204                                 {
205                                         HLTError("Received a reconstructed hits data block with a size of %d bytes,"
206                                                 " which is smaller than the minimum valid header size of %d bytes."
207                                                 " The block must be corrupt.",
208                                                 blocks[n].fSize, headerSize
209                                         );
210                                         continue;
211                                 }
212                                 
213                                 size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType);
214                                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
215                                 {
216                                         HLTError("Received a reconstructed hits data block with a record"
217                                                 " width of %d bytes, but the expected value is %d bytes."
218                                                 " The block might be corrupt.",
219                                                 blocks[n].fSize, headerSize
220                                         );
221                                         continue;
222                                 }
223                                 
224                                 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
225                                         " but the block header claims the block should be %d bytes."
226                                         " The block might be corrupt.",
227                                         blocks[n].fSize, inblock.BytesUsed()
228                                 );
229                                 continue;
230                         }
231                         
232                         if (inblock.Nentries() != 0)
233                                 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
234                         else
235                         {
236                                 Logging(kHLTLogDebug,
237                                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
238                                         "Block empty",
239                                         "Received a reconstructed hits data block which contains no entries."
240                                 );
241                         }
242                 }
243                 else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
244                 {
245                         // Log a message indicating that we got a data block that we
246                         // do not know how to handle.
247                         char id[kAliHLTComponentDataTypefIDsize+1];
248                         for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
249                                 id[i] = blocks[n].fDataType.fID[i];
250                         id[kAliHLTComponentDataTypefIDsize] = '\0';
251                         char origin[kAliHLTComponentDataTypefOriginSize+1];
252                         for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
253                                 origin[i] = blocks[n].fDataType.fOrigin[i];
254                         origin[kAliHLTComponentDataTypefOriginSize] = '\0';
255                         
256                         if (fWarnForUnexpecedBlock)
257                                 HLTWarning("Received a data block of a type we cannot handle: %s origin: %s",
258                                         static_cast<char*>(id), static_cast<char*>(origin)
259                                 );
260                         else
261                                 HLTDebug("Received a data block of a type we cannot handle: %s origin: %s",
262                                         static_cast<char*>(id), static_cast<char*>(origin)
263                                 );
264                 }
265         }
266   
267         // Again loop over all input blocks in the event, but this time look for
268         // the trigger record blocks and process these.
269         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
270         {
271                 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
272                         continue;
273                 
274                 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
275                 if (not inblock.BufferSizeOk())
276                 {
277                         size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType);
278                         if (blocks[n].fSize < headerSize)
279                         {
280                                 HLTError("Received a trigger records data block with a size of %d bytes,"
281                                         " which is smaller than the minimum valid header size of %d bytes."
282                                         " The block must be corrupt.",
283                                         blocks[n].fSize, headerSize
284                                 );
285                                 continue;
286                         }
287                         
288                         size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType);
289                         if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
290                         {
291                                 HLTError("Received a trigger records data block with a record"
292                                         " width of %d bytes, but the expected value is %d bytes."
293                                         " The block might be corrupt.",
294                                         blocks[n].fSize, headerSize
295                                 );
296                                 continue;
297                         }
298                         
299                         HLTError("Received a trigger records data block with a size of %d bytes,"
300                                 " but the block header claims the block should be %d bytes."
301                                 " The block might be corrupt.",
302                                 blocks[n].fSize, inblock.BytesUsed()
303                         );
304                         continue;
305                 }
306                 DebugTrace("Processing a trigger block with "
307                         << inblock.Nentries() << " entries."
308                 );
309                 
310                 specification |= blocks[n].fSpecification;
311                 
312                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
313                 {
314                         fTracker->FindTrack(inblock[i]);
315                         
316                         // Reset the tracker so that we do not double count tracks.
317                         fTracker->Reset();
318                 }
319         }
320         
321         AliHLTComponentBlockData bd;
322         FillBlockData(bd);
323         bd.fPtr = outputPtr;
324         bd.fOffset = 0;
325         bd.fSize = block.BytesUsed();
326         bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
327         bd.fSpecification = specification;
328         outputBlocks.push_back(bd);
329         size = block.BytesUsed();
330
331         return 0;
332 }
333
334
335 void AliHLTMUONMansoTrackerFSMComponent::Reset()
336 {
337         ///
338         /// Reset the track count and reconstructed hit data block arrays.
339         ///
340         
341         DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent.");
342
343         //fTracker->Reset();  // Not necessary here because it is done after every FindTrack call.
344         fTrackCount = 0;
345         fBlock = NULL;  // Do not delete. Already done implicitly at the end of DoEvent.
346         for (int i = 0; i < 4; i++)
347         {
348                 fRecHitBlock[i].erase(fRecHitBlock[i].begin(), fRecHitBlock[i].end());
349         }
350 }
351
352
353 void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
354                 AliHLTUInt32_t specification,
355                 const AliHLTMUONRecHitStruct* recHits,
356                 AliHLTUInt32_t count
357         )
358 {
359         ///
360         /// Adds a new reconstructed hit data block to the internal list of blocks
361         /// for the tracker to process.
362         /// These lists will later be used when the tracker requests them through
363         /// the callback method 'RequestClusters'.
364         ///
365         
366         DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x"
367                  << std::hex << specification << std::dec << " and count = "
368                  << count << " rec hits."
369         );
370         
371         AliHLTUInt8_t chamberMap[20] = {
372                 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10
373         };
374         
375         // Identify the chamber the rec hits came from using the specifications field.
376         bool gotDataFromDDL[22];
377         AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL);
378                 
379         AliHLTInt8_t chamber = -1;
380         for (int i = 0; i < 20; i++)
381         {
382                 if (not gotDataFromDDL[i]) continue;
383                 if (7 <= chamberMap[i] and chamberMap[i] <= 10)
384                 {
385                         if (chamber != -1 and chamber != chamberMap[i])
386                         {
387                                 Logging(kHLTLogError,
388                                         "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
389                                         "Invalid block",
390                                         "Received a data block with data from multiple chambers."
391                                           " This component cannot handle such a case."
392                                 );
393                                 return;
394                         }
395                         else
396                                 chamber = chamberMap[i];
397                 }
398                 else
399                 {
400                         Logging(kHLTLogError,
401                                 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
402                                 "Invalid chamber",
403                                 "Received a data block with data from chamber %d"
404                                   " which is outside the expected range: [7..10].",
405                                 chamberMap[i]
406                         );
407                         return;
408                 }
409         }
410         
411         // Make sure we got one chamber number.
412         if (chamber < 7 or 10 < chamber)
413         {
414                 Logging(kHLTLogError,
415                         "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
416                         "Invalid block",
417                         "Received a reconstructed hit data block with a null specification."
418                          " Cannot know which chamber the data comes from."
419                 );
420                 return;
421         }
422         
423         DebugTrace("Added " << count << " reconstructed hits from chamber "
424                 << (int)chamber << " to the internal arrays."
425         );
426         
427         RecHitBlockInfo info;
428         info.fCount = count;
429         info.fData = recHits;
430         fRecHitBlock[chamber-7].push_back(info);
431 }
432
433
434 void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
435                 AliHLTMUONMansoTrackerFSM* tracker,
436                 AliHLTFloat32_t left, AliHLTFloat32_t right,
437                 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
438                 AliHLTMUONChamberName chamber, const void* tag
439         )
440 {
441         ///
442         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
443         /// This is the call back method used by the tracker algorithm to request
444         /// clusters on a certain chamber.
445         ///
446
447         DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
448         void* ctag = const_cast<void*>(tag);
449         int chNo = -1;
450         std::vector<RecHitBlockInfo>* recHitsBlock = NULL;
451         switch (chamber)
452         {
453         case kChamber7:
454                 recHitsBlock = &fRecHitBlock[0];
455                 chNo = 7;
456                 break;
457
458         case kChamber8:
459                 recHitsBlock = &fRecHitBlock[1];
460                 chNo = 8;
461                 break;
462
463         case kChamber9:
464                 recHitsBlock = &fRecHitBlock[2];
465                 chNo = 9;
466                 break;
467
468         case kChamber10:
469                 recHitsBlock = &fRecHitBlock[3];
470                 chNo = 10;
471                 break;
472
473         default: return;
474         }
475         
476         DebugTrace("Returning requested hits for chamber " << chNo << ":");
477         for (AliHLTUInt32_t i = 0; i < recHitsBlock->size(); i++)
478         for (AliHLTUInt32_t j = 0; j < (*recHitsBlock)[i].fCount; j++)
479         {
480                 const AliHLTMUONRecHitStruct* hit = &((*recHitsBlock)[i].fData[j]);
481                 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
482                         tracker->ReturnClusters(ctag, hit, 1);
483         }
484         DebugTrace("Done returning hits from chamber " << chNo << ".");
485         tracker->EndOfClusters(ctag);
486 }
487
488
489 void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
490                 AliHLTMUONMansoTrackerFSM* /*tracker*/
491         )
492 {
493         ///
494         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
495         /// Nothing special to do here.
496         ///
497         
498         DebugTrace("End of cluster requests.");
499 }
500
501
502 void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
503 {
504         ///
505         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
506         /// This is the call back method used by the tracker algorithm to declare
507         /// that a new track has been found.
508         ///
509         
510         DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
511         
512         AliHLTMUONMansoTracksBlockWriter* block =
513                 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
514         
515         AliHLTMUONMansoTrackStruct* track = block->AddEntry();
516         if (track == NULL)
517         {
518                 Logging(kHLTLogError,
519                         "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
520                         "Buffer overflow",
521                         "We have overflowed the output buffer for Manso track data."
522                           " The output buffer size is only %d bytes.",
523                         block->BufferSize()
524                 );
525                 return;
526         }
527  
528         fTrackCount++;
529         tracker->FillTrackData(*track);
530         DebugTrace("\tTrack data = " << *track);
531 }
532
533
534 void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
535 {
536         ///
537         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
538         /// Nothing special to do here.
539         ///
540         
541         DebugTrace("No track found.");
542 }
543