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