2506c8bcad56872876ca8880a0d292e9dd2cc3dc
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONHitReconstructorComponent.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        * 
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Indranil Das <indra.das@saha.ac.in>                                  *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          * 
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 /* $Id$ */
18
19 ///
20 ///
21 ///  The HitRec Component is designed to deal the rawdata inputfiles to findout the 
22 ///  the reconstructed hits. The output is send to the output block for further 
23 ///  processing.
24 ///
25 ///  Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
26 ///
27
28 #include "AliHLTMUONRecHitsBlockStruct.h"
29 #include "AliHLTMUONHitReconstructorComponent.h"
30 #include "AliHLTMUONHitReconstructor.h"
31 #include "AliHLTMUONConstants.h"
32 #include "AliHLTMUONDataBlockWriter.h"
33 #include "AliHLTLogging.h"
34 #include "AliHLTSystem.h"
35 #include "AliHLTDefinitions.h"
36 #include <cstdlib>
37 #include <cerrno>
38 #include <cassert>
39
40 ClassImp(AliHLTMUONHitReconstructorComponent)
41
42
43 AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() :
44         AliHLTProcessor(),
45         fHitRec(NULL),
46         fDDLDir(""),
47         fDDL(0),
48         fReaderType(false),
49         fWarnForUnexpecedBlock(false)
50 {
51         ///
52         /// Default constructor.
53         ///
54 }
55
56
57 AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent()
58 {
59         ///
60         /// Default destructor.
61         ///
62 }
63
64 const char* AliHLTMUONHitReconstructorComponent::GetComponentID()
65 {
66         ///
67         /// Inherited from AliHLTComponent. Returns the component ID.
68         ///
69         
70         return AliHLTMUONConstants::HitReconstructorId();
71 }
72
73
74 void AliHLTMUONHitReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
75 {
76         ///
77         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
78         ///
79         
80         list.clear();
81         list.push_back( AliHLTMUONConstants::TrackingDDLRawDataType() );
82 }
83
84
85 AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType()
86 {
87         ///
88         /// Inherited from AliHLTComponent. Returns the output data type.
89         ///
90         
91         return AliHLTMUONConstants::RecHitsBlockDataType();
92 }
93
94
95 void AliHLTMUONHitReconstructorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
96 {
97         ///
98         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
99         ///
100         
101         constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType);
102         inputMultiplier = 1;
103 }
104
105
106 AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn()
107 {
108         ///
109         /// Inherited from AliHLTComponent. Creates a new object instance.
110         ///
111         
112         return new AliHLTMUONHitReconstructorComponent;
113 }
114
115
116 int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv)
117 {
118         ///
119         /// Inherited from AliHLTComponent.
120         /// Parses the command line parameters and initialises the component.
121         ///
122         
123   // perform initialization. We check whether our relative output size is specified in the arguments.
124      
125   HLTInfo("Initialising DHLT HitReconstruction Component");
126
127   fHitRec = new AliHLTMUONHitReconstructor();
128   fWarnForUnexpecedBlock = false;
129
130   // this is to get rid of the warning "unused parameter"
131   if (argc==0 && argv==NULL) {
132     HLTError("Arguments missing", " no arguments" );
133   }
134
135   char lutFileName[500],buspatchFileName[500];
136
137   int i = 0;
138   char* cpErr;
139   while ( i < argc )
140     {
141       HLTDebug("argv[%d] == %s", i, argv[i] );
142       
143       if ( !strcmp( argv[i], "-lut" ) ) {
144         if ( argc <= i+1 ) {
145           HLTError("LookupTable filename not specified" );
146           return EINVAL; /* Invalid argument */ 
147         }
148             
149         sprintf(lutFileName,"%s",argv[i+1]);
150         
151         i += 2;
152         continue;
153       }// lut argument
154           
155           
156       if ( !strcmp( argv[i], "-ddl" ) ) {
157         if ( argc <= i+1 ) {
158           HLTError("DDL number not specified" );
159           return EINVAL;  /* Invalid argument */
160         }
161             
162         unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
163         if (cpErr == NULL or *cpErr != '\0')
164           {
165             HLTError("Cannot convert '%s' to DDL Number ", argv[i+1] );
166             return EINVAL;
167           }
168         if (num < 13 or 20 < num)
169         {
170                 HLTError("The DDL number must be in the range [13..20].");
171                 return EINVAL;
172         }
173         fDDL = num - 1;
174         
175         i += 2;
176         continue;
177       }// ddl argument
178       
179
180       if ( !strcmp( argv[i], "-rawdir" ) ) {
181         if ( argc <= i+1 ) {
182           HLTError("DDL directory not specified" );
183           return EINVAL;  /* Invalid argument */
184         }
185             
186         fDDLDir = argv[i+1] ;
187             
188         i += 2;
189         continue;
190       }// ddl directory argument
191           
192           
193       if ( !strcmp( argv[i], "-buspatchmap" ) ) {
194         if ( argc <= i+1 ) {
195           HLTError("Buspatch filename not specified" );
196           return EINVAL; /* Invalid argument */
197         }
198             
199         sprintf(buspatchFileName,"%s",argv[i+1]);
200         
201         i += 2;
202         continue;
203       }// buspatch argument
204
205       if ( !strcmp( argv[i], "-rawreader" ) ) {
206         fReaderType = true; // true when using rawreader for standalone it is set to false.
207         i += 1;
208         continue;
209       }
210           
211       if ( !strcmp( argv[i], "-warn_on_unexpected_block" ) ) {
212         fWarnForUnexpecedBlock = true;
213         i++;
214         continue;
215       }
216
217       HLTError("Unknown option '%s'", argv[i] );
218       return EINVAL;
219       
220     }//while loop
221
222   int lutline = fHitRec->GetLutLine(fDDL);
223   AliHLTMUONHitReconstructor::DHLTLut* lookupTable = new AliHLTMUONHitReconstructor::DHLTLut[lutline];
224   if(!ReadLookUpTable(lookupTable,lutFileName)){
225     HLTError("Failed to read lut, lut cannot be read, DoInit");
226     return ENOENT ; /* No such file or directory */
227   }else{
228     
229     BusToDetElem busToDetElem;
230     BusToDDL busToDDL;
231     if(!ReadBusPatchToDetElemFile(busToDetElem,busToDDL,buspatchFileName)){
232       HLTError("Failed to read buspatchmap, buspatchmap cannot be read, DoInit");
233       return ENOENT ; /* No such file or directory */
234     }
235     
236     fHitRec->SetBusToDetMap(busToDetElem);
237     fHitRec->SetBusToDDLMap(busToDDL);
238     fHitRec->LoadLookUpTable(lookupTable,fDDL);
239     
240   }// reading lut
241
242   delete []lookupTable;
243   
244   HLTInfo("Initialisation of DHLT HitReconstruction Component is done");
245   
246   return 0;
247 }
248
249
250 int AliHLTMUONHitReconstructorComponent::DoDeinit()
251 {
252         ///
253         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
254         ///
255         
256   if(fHitRec)
257     delete fHitRec;
258   
259   HLTInfo(" Deinitialising DHLT HitReconstruction Component");
260   
261   return 0;
262 }
263
264
265 int AliHLTMUONHitReconstructorComponent::DoEvent(
266                 const AliHLTComponentEventData& evtData,
267                 const AliHLTComponentBlockData* blocks,
268                 AliHLTComponentTriggerData& /*trigData*/,
269                 AliHLTUInt8_t* outputPtr,
270                 AliHLTUInt32_t& size,
271                 std::vector<AliHLTComponentBlockData>& outputBlocks
272         )
273 {
274         ///
275         /// Inherited from AliHLTProcessor. Processes the new event data.
276         ///
277         
278         // Process an event
279         unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
280
281         HLTDebug("Processing event %llu with %u input data blocks.",
282                 evtData.fEventID, evtData.fBlockCnt
283         );
284
285         // Loop over all input blocks in the event
286         for ( unsigned long n = 0; n < evtData.fBlockCnt; n++ )
287         {
288 #ifdef __DEBUG
289                 char id[kAliHLTComponentDataTypefIDsize+1];
290                 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
291                         id[i] = blocks[n].fDataType.fID[i];
292                 id[kAliHLTComponentDataTypefIDsize] = '\0';
293                 char origin[kAliHLTComponentDataTypefOriginSize+1];
294                 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
295                         origin[i] = blocks[n].fDataType.fOrigin[i];
296                 origin[kAliHLTComponentDataTypefOriginSize] = '\0';
297 #endif // __DEBUG
298                 HLTDebug("Handling block: %u, with fDataType.fID = '%s',"
299                           " fDataType.fID = '%s', fPtr = %p and fSize = %u bytes.",
300                         n, static_cast<char*>(id), static_cast<char*>(origin),
301                         blocks[n].fPtr, blocks[n].fSize
302                 );
303
304                 if (blocks[n].fDataType != AliHLTMUONConstants::TrackingDDLRawDataType())
305                 {
306                         // Log a message indicating that we got a data block that we
307                         // do not know how to handle.
308                         char id[kAliHLTComponentDataTypefIDsize+1];
309                         for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
310                                 id[i] = blocks[n].fDataType.fID[i];
311                         id[kAliHLTComponentDataTypefIDsize] = '\0';
312                         char origin[kAliHLTComponentDataTypefOriginSize+1];
313                         for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
314                                 origin[i] = blocks[n].fDataType.fOrigin[i];
315                         origin[kAliHLTComponentDataTypefOriginSize] = '\0';
316                         
317                         if (fWarnForUnexpecedBlock)
318                                 HLTWarning("Received a data block of a type we cannot handle: '%s' origin: '%s'",
319                                         static_cast<char*>(id), static_cast<char*>(origin)
320                                 );
321                         else
322                                 HLTDebug("Received a data block of a type we cannot handle: '%s' origin: '%s'",
323                                         static_cast<char*>(id), static_cast<char*>(origin)
324                                 );
325                         
326                         continue;
327                 }
328                 
329                 // Create a new output data block and initialise the header.
330                 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
331                 if (not block.InitCommonHeader())
332                 {
333                         HLTError("There is not enough space in the output buffer for the new data block.",
334                                  " We require at least %u bytes, but have %u bytes left.",
335                                 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
336                                 block.BufferSize()
337                         );
338                         break;
339                 }
340                 
341                 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
342                 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
343                 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
344                         + fHitRec->GetkDDLHeaderSize();
345                 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
346
347                 HLTDebug("=========== Dumping DDL payload buffer ==========");
348                 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
349                         HLTDebug("buffer[%d] : %x",j,buffer[j]);
350                 HLTDebug("================== End of dump =================");
351
352                 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
353                 {
354                         HLTError("Error while processing of hit reconstruction algorithm.");
355                         size = totalSize; // Must tell the framework how much buffer space was used.
356                         return EIO;
357                 }
358                 
359                 // nofHit should now contain the number of reconstructed hits actually found
360                 // and filled into the output data block, so we can set this number.
361                 assert( nofHit <= block.MaxNumberOfEntries() );
362                 block.SetNumberOfEntries(nofHit);
363                 
364                 HLTDebug("Number of reconstructed hits found is %d", nofHit);
365
366                 // Fill a block data structure for our output block.
367                 AliHLTComponentBlockData bd;
368                 FillBlockData(bd);
369                 bd.fPtr = outputPtr;
370                 // This block's start (offset) is after all other blocks written so far.
371                 bd.fOffset = totalSize;
372                 bd.fSize = block.BytesUsed();
373                 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
374                 bd.fSpecification = blocks[n].fSpecification;
375                 outputBlocks.push_back(bd);
376
377                 // Increase the total amount of data written so far to our output memory
378                 totalSize += block.BytesUsed();
379         }
380         // Finally we set the total size of output memory we consumed.
381         size = totalSize;
382
383         return 0;
384 }
385
386
387 bool AliHLTMUONHitReconstructorComponent::ReadLookUpTable(AliHLTMUONHitReconstructor::DHLTLut* lookupTable, const char* lutpath)
388 {
389         ///
390         /// Read in the lookup table from a text file.
391         ///
392         
393   if (fDDL < AliHLTMUONHitReconstructor::GetkDDLOffSet() ||
394       fDDL >= AliHLTMUONHitReconstructor::GetkDDLOffSet() + AliHLTMUONHitReconstructor::GetkNofDDL()){
395     HLTError("DDL number is out of range");
396     return false;
397   }
398   
399   int lutLine = fHitRec->GetLutLine(fDDL);
400   
401   FILE* fin = fopen(lutpath, "r");
402   if (fin == NULL){
403     HLTError("Failed to open file: %s",lutpath);
404     return false;
405   }
406   
407   for(int i=0;i<lutLine;i++){
408     fscanf(
409            fin,
410            "%d\t%d\t%d\t%f\t%f\t%f\t%d\t%d\n",
411            &lookupTable[i].fIdManuChannel,
412            &lookupTable[i].fIX,
413            &lookupTable[i].fIY,
414            &lookupTable[i].fRealX,
415            &lookupTable[i].fRealY,
416            &lookupTable[i].fRealZ,
417            &lookupTable[i].fPcbZone,
418            &lookupTable[i].fPlane
419            );
420   }
421   
422   fclose(fin);
423   return true;
424 }
425
426
427 bool AliHLTMUONHitReconstructorComponent::ReadBusPatchToDetElemFile(BusToDetElem& busToDetElem, BusToDDL& busToDDL, const char* buspatchmappath)
428 {
429         ///
430         /// Read in the lookup table for bus patch to detector element IDs from a text file.
431         ///
432         
433   char getLine[80];
434   char temp;
435   int detElem, minBusPatch, maxBusPatch, ddl;
436   
437   FILE* fin = fopen(buspatchmappath, "r");
438   if (fin == NULL){
439     HLTError("Failed to open file: %s",buspatchmappath);
440     return false;
441   }
442   
443   while (feof(fin)==0){
444     fgets(getLine,80,fin);
445     sscanf(getLine, "%d\t%d %c %d\t%d", &detElem, &minBusPatch, &temp, &maxBusPatch,&ddl);
446     if (detElem >= 700 && detElem <= 1025){
447       
448       for(int i = minBusPatch; i <= maxBusPatch; i++){
449         busToDetElem[i] = detElem;
450         busToDDL[i] = ddl;
451       }//for loop
452     } // detElem condn
453   } // while loop for file
454   
455   fclose(fin);
456   return true;
457 }