]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx
Reset method added in AliBin in order to avoid multiple delete/new calls (F. Prino)
[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 <cerrno>
36
37 namespace
38 {
39         // The global object used for automatic component registration.
40         // Note DO NOT use this component for calculation!
41         AliHLTMUONMansoTrackerFSMComponent gAliHLTMUONMansoTrackerFSMComponent;
42
43 } // end of namespace
44
45
46 ClassImp(AliHLTMUONMansoTrackerFSMComponent);
47
48
49 AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
50         AliHLTProcessor(),
51         AliHLTMUONMansoTrackerFSMCallback(),
52         fTracker(NULL),
53         fTrackCount(0),
54         fBlock(NULL)
55 {
56 }
57
58
59 AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
60 {
61         assert( fTracker == NULL );
62 }
63
64
65 const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
66 {
67         return AliHLTMUONConstants::MansoTrackerFSMId();
68 }
69
70
71 void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
72                 vector<AliHLTComponentDataType>& list
73         )
74 {
75         assert( list.empty() );
76         list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
77         list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
78 }
79
80
81 AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
82 {
83         return AliHLTMUONConstants::MansoTracksBlockDataType();
84 }
85
86
87 void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
88                 unsigned long& constBase, double& inputMultiplier
89         )
90 {
91         constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
92         inputMultiplier = 1;
93 }
94
95
96 AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
97 {
98         return new AliHLTMUONMansoTrackerFSMComponent;
99 }
100
101
102 int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
103 {
104         fTracker = new AliHLTMUONMansoTrackerFSM();
105         fTracker->SetCallback(this);
106         return 0;
107 }
108
109
110 int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
111 {
112         if (fTracker != NULL)
113         {
114                 delete fTracker;
115                 fTracker = NULL;
116         }
117         return 0;
118 }
119
120
121 int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
122                 const AliHLTComponentEventData& evtData,
123                 const AliHLTComponentBlockData* blocks, 
124                 AliHLTComponentTriggerData& trigData,
125                 AliHLTUInt8_t* outputPtr, 
126                 AliHLTUInt32_t& size,
127                 std::vector<AliHLTComponentBlockData>& outputBlocks
128         )
129 {
130         Reset();
131         AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
132         
133         AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
134         fBlock = &block;
135         
136         if (not block.InitCommonHeader())
137         {
138                 Logging(kHLTLogError,
139                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
140                         "Buffer overflow",
141                         "The buffer is only %d bytes in size. We need a minimum of %d bytes.",
142                         size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
143                 );
144                 size = 0; // Important to tell framework that nothing was generated.
145                 return ENOBUFS;
146         }
147
148         // Loop over all input blocks in the event and add the ones that contain
149         // reconstructed hits into the hit buffers. The blocks containing trigger
150         // records are ignored for now and will be processed later.
151         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
152         {
153                 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
154                 {
155                         specification |= blocks[n].fSpecification;
156                         
157                         AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
158                         if (not inblock.BufferSizeOk())
159                         {
160                                 Logging(kHLTLogError,
161                                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
162                                         "Invalid block",
163                                         "Received a reconstructed hits data block with an incorrect size: %d,"
164                                           " it might be corrupt.",
165                                         blocks[n].fSize
166                                 );
167                                 continue;
168                         }
169                         
170                         if (inblock.Nentries() != 0)
171                                 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
172                         else
173                         {
174                                 Logging(kHLTLogWarning,
175                                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
176                                         "Block empty",
177                                         "Received a reconstructed hits data block which contains no entries."
178                                 );
179                         }
180                 }
181                 else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
182                 {
183                         // Log a message indicating that we got a data block that we
184                         // do not know how to handle.
185                         char id[kAliHLTComponentDataTypefIDsize+1];
186                         for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
187                                 id[i] = blocks[n].fDataType.fID[i];
188                         id[kAliHLTComponentDataTypefIDsize] = '\0';
189                         char origin[kAliHLTComponentDataTypefOriginSize+1];
190                         for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
191                                 origin[i] = blocks[n].fDataType.fOrigin[i];
192                         origin[kAliHLTComponentDataTypefOriginSize] = '\0';
193                         
194                         Logging(kHLTLogError,
195                                 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
196                                 "Unexpected data",
197                                 "Received a data block of an unexpected type: %s origin %s",
198                                 static_cast<char*>(id), static_cast<char*>(origin)
199                         );
200                 }
201         }
202   
203         // Again loop over all input blocks in the event, but this time look for
204         // the trigger record blocks and process these.
205         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
206         {
207                 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
208                         continue;
209                 
210                 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
211                 if (not inblock.BufferSizeOk())
212                 {
213                         Logging(kHLTLogError,
214                                 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
215                                 "Invalid block",
216                                 "Received a trigger record data block with an incorrect size: %d,"
217                                   " it might be corrupt.",
218                                 blocks[n].fSize
219                         );
220                         continue;
221                 }
222                 DebugTrace("Processing a trigger block with "
223                         << inblock.Nentries() << " entries."
224                 );
225                 
226                 specification |= blocks[n].fSpecification;
227                 
228                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
229                 {
230                         fTracker->FindTrack(inblock[i]);
231                         
232                         // Reset the tracker so that we do not double count tracks.
233                         fTracker->Reset();
234                 }
235         }
236         
237         AliHLTComponentBlockData bd;
238         FillBlockData(bd);
239         bd.fPtr = outputPtr;
240         bd.fOffset = 0;
241         bd.fSize = block.BytesUsed();
242         bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
243         bd.fSpecification = specification;
244         outputBlocks.push_back(bd);
245         size = block.BytesUsed();
246
247         return 0;
248 }
249
250
251 void AliHLTMUONMansoTrackerFSMComponent::Reset()
252 {
253         DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent.");
254
255         //fTracker->Reset();  // Not necessary here because it is done after every FindTrack call.
256         fTrackCount = 0;
257         fBlock = NULL;  // Do not delete. Already done implicitly at the end of DoEvent.
258         for (int i = 0; i < 4; i++)
259         {
260                 fRecHitBlock[i].erase(fRecHitBlock[i].begin(), fRecHitBlock[i].end());
261         }
262 }
263
264
265 void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
266                 AliHLTUInt32_t specification,   
267                 const AliHLTMUONRecHitStruct* recHits,
268                 AliHLTUInt32_t count
269         )
270 {
271         DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x"
272                  << std::hex << specification << std::dec << " and count = "
273                  << count << " rec hits."
274         );
275         
276         AliHLTUInt8_t chamberMap[20] = {
277                 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10
278         };
279         
280         // Identify the chamber the rec hits came from using the specifications field.
281         bool gotDataFromDDL[22];
282         AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL);
283                 
284         AliHLTInt8_t chamber = -1;
285         for (int i = 0; i < 20; i++)
286         {
287                 if (not gotDataFromDDL[i]) continue;
288                 if (7 <= chamberMap[i] and chamberMap[i] <= 10)
289                 {
290                         if (chamber != -1 and chamber != chamberMap[i])
291                         {
292                                 Logging(kHLTLogError,
293                                         "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
294                                         "Invalid block",
295                                         "Received a data block with data from multiple chambers."
296                                           " This component cannot handle such a case."
297                                 );
298                                 return;
299                         }
300                         else
301                                 chamber = chamberMap[i];
302                 }
303                 else
304                 {
305                         Logging(kHLTLogError,
306                                 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
307                                 "Invalid chamber",
308                                 "Received a data block with data from chamber %d"
309                                   " which is outside the expected range: [7..10].",
310                                 chamberMap[i]
311                         );
312                         return;
313                 }
314         }
315         
316         // Make sure we got one chamber number.
317         if (chamber < 7 or 10 < chamber)
318         {
319                 Logging(kHLTLogError,
320                         "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
321                         "Invalid block",
322                         "Received a reconstructed hit data block with a null specification."
323                          " Cannot know which chamber the data comes from."
324                 );
325                 return;
326         }
327         
328         DebugTrace("Added " << count << " reconstructed hits from chamber "
329                 << (int)chamber << " to the internal arrays.")
330         ;
331         
332         RecHitBlockInfo info;
333         info.fCount = count;
334         info.fData = recHits;
335         fRecHitBlock[chamber-7].push_back(info);
336 }
337
338
339 void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
340                 AliHLTMUONMansoTrackerFSM* tracker,
341                 AliHLTFloat32_t /*left*/, AliHLTFloat32_t /*right*/,
342                 AliHLTFloat32_t /*bottom*/, AliHLTFloat32_t /*top*/,
343                 AliHLTMUONChamberName chamber, const void* tag
344         )
345 {
346         DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
347         void* ctag = const_cast<void*>(tag);
348         int chNo = -1;
349         std::vector<RecHitBlockInfo>* recHitsBlock = NULL;
350         switch (chamber)
351         {
352         case kChamber7:
353                 recHitsBlock = &fRecHitBlock[0];
354                 chNo = 7;
355                 break;
356
357         case kChamber8:
358                 recHitsBlock = &fRecHitBlock[1];
359                 chNo = 8;
360                 break;
361
362         case kChamber9:
363                 recHitsBlock = &fRecHitBlock[2];
364                 chNo = 9;
365                 break;
366
367         case kChamber10:
368                 recHitsBlock = &fRecHitBlock[3];
369                 chNo = 10;
370                 break;
371
372         default: return;
373         }
374         
375         DebugTrace("Returning requested hits for chamber " << chNo << ":");
376         for (AliHLTUInt32_t i = 0; i < recHitsBlock->size(); i++)
377         {
378                 tracker->ReturnClusters(
379                                 ctag,
380                                 (*recHitsBlock)[i].fData,
381                                 (*recHitsBlock)[i].fCount
382                         );
383         }
384         DebugTrace("Done returning hits from chamber " << chNo << ".");
385         tracker->EndOfClusters(ctag);
386 }
387
388
389 void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
390                 AliHLTMUONMansoTrackerFSM* tracker
391         )
392 {
393         DebugTrace("End of cluster requests.");
394 }
395
396
397 void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
398 {
399         DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
400         
401         AliHLTMUONMansoTracksBlockWriter* block =
402                 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
403         
404         AliHLTMUONMansoTrackStruct* track = block->AddEntry();
405         if (track == NULL)
406         {
407                 Logging(kHLTLogError,
408                         "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
409                         "Buffer overflow",
410                         "We have overflowed the output buffer for Manso track data."
411                           " The output buffer size is only %d bytes.",
412                         block->BufferSize()
413                 );
414                 return;
415         }
416  
417         fTrackCount++;
418         tracker->FillTrackData(*track);
419         DebugTrace("\tTrack data = " << *track);
420 }
421
422
423 void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* tracker)
424 {
425         DebugTrace("No track found.");
426 }
427