]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OfflineInterface/AliHLTMUONRecHitsSource.cxx
Adding class AliHLTMUONTriggerRecordsSource
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONRecHitsSource.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 /**
19  * @file   AliHLTMUONRecHitsSource.cxx
20  * @author Artur Szostak <artursz@iafrica.com>
21  * @date   
22  * @brief  Implementation of the AliHLTMUONRecHitsSource component.
23  */
24
25 #include "AliHLTMUONRecHitsSource.h"
26 #include "AliHLTMUONConstants.h"
27 #include "AliHLTMUONDataBlockWriter.h"
28 #include "AliMUONMCDataInterface.h"
29 #include "AliMUONDataInterface.h"
30 #include "AliMUONHit.h"
31 #include "AliMUONRawCluster.h"
32 #include "AliMUONConstants.h"
33 #include "AliMUONVClusterStore.h"
34 #include "AliMUONVHitStore.h"
35 #include "TClonesArray.h"
36 #include <cstdlib>
37 #include <cstdio>
38 #include <cerrno>
39 #include <cassert>
40 #include <new>
41
42 namespace
43 {
44         // The global object used for automatic component registration.
45         // Note DO NOT use this component for calculation!
46         AliHLTMUONRecHitsSource gAliHLTMUONRecHitsSource;
47 }
48
49
50 ClassImp(AliHLTMUONRecHitsSource);
51
52
53 AliHLTMUONRecHitsSource::AliHLTMUONRecHitsSource() :
54         AliHLTOfflineDataSource(),
55         fMCDataInterface(NULL), fDataInterface(NULL),
56         fSelection(kWholePlane)
57 {
58         for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
59                 fServeChamber[i] = false;
60 }
61
62
63 AliHLTMUONRecHitsSource::~AliHLTMUONRecHitsSource()
64 {
65         assert( fMCDataInterface == NULL );
66         assert( fDataInterface == NULL );
67 }
68
69
70 int AliHLTMUONRecHitsSource::DoInit(int argc, const char** argv)
71 {
72         // Parse the command line arguments:
73         bool simdata = false;
74         bool recdata = false;
75         bool chamberWasSet = false;
76         
77         for (int i = 0; i < argc; i++)
78         {
79                 if (strcmp(argv[i], "-simdata") == 0)
80                 {
81                         simdata = true;
82                 }
83                 else if (strcmp(argv[i], "-recdata") == 0)
84                 {
85                         recdata = true;
86                 }
87                 else if (strcmp(argv[i], "-plane") == 0)
88                 {
89                         i++;
90                         if (i >= argc)
91                         {
92                                 Logging(kHLTLogError,
93                                         "AliHLTMUONRecHitsSource::DoInit",
94                                         "Missing parameter",
95                                         "Expected one of 'left', 'right' or 'all' after '-plane'."
96                                 );
97                                 return EINVAL;
98                         }
99                         if (strcmp(argv[i], "left") == 0)
100                                 fSelection = kLeftPlane;
101                         else if (strcmp(argv[i], "right") == 0)
102                                 fSelection = kRightPlane;
103                         else if (strcmp(argv[i], "all") == 0)
104                                 fSelection = kWholePlane;
105                         else
106                         {
107                                 Logging(kHLTLogError,
108                                         "AliHLTMUONRecHitsSource::DoInit",
109                                         "Invalid parameter",
110                                         "The parameter '%s' is invalid and must be one of 'left',"
111                                           " 'right' or 'all'.",
112                                         argv[i]
113                                 );
114                                 return EINVAL;
115                         }
116                 }
117                 else if (strcmp(argv[i], "-chamber") == 0)
118                 {
119                         i++;
120                         if (i >= argc)
121                         {
122                                 Logging(kHLTLogError,
123                                         "AliHLTMUONRecHitsSource::DoInit",
124                                         "Missing parameter",
125                                         "Expected a chamber number, range eg. '1-10' or list eg."
126                                           " '1,2,3' after '-chamber'."
127                                 );
128                                 return EINVAL;
129                         }
130                         int result = ParseChamberString(argv[i]);
131                         if (result != 0) return result;
132                         chamberWasSet = true;
133                 }
134                 else
135                 {
136                         Logging(kHLTLogError,
137                                 "AliHLTMUONRecHitsSource::DoInit",
138                                 "Unknown argument",
139                                 "The argument '%s' is invalid.",
140                                 argv[i]
141                         );
142                         return EINVAL;
143                 }
144         }
145
146         // Check the parameters we have parsed.
147         if (simdata and recdata)
148         {
149                 Logging(kHLTLogError,
150                         "AliHLTMUONRecHitsSource::DoInit",
151                         "Invalid arguments",
152                         "Cannot have both -simdata and -recdata set."
153                 );
154                 return EINVAL;
155         }
156         
157         if (not simdata and not recdata)
158         {
159                 Logging(kHLTLogError,
160                         "AliHLTMUONRecHitsSource::DoInit",
161                         "Missing arguments",
162                         "Must have either -simdata or -recdata specified."
163                 );
164                 return EINVAL;
165         }
166         
167         if (not chamberWasSet)
168         {
169                 Logging(kHLTLogInfo,
170                         "AliHLTMUONRecHitsSource::DoInit",
171                         "Setting Parameters",
172                         "No chambers were selected so we will publish for all chambers."
173                 );
174                 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
175                         fServeChamber[i] = true;
176         }
177         
178         // Now we can initialise the data interface objects and loaders.
179         if (simdata)
180         {
181                 Logging(kHLTLogDebug,
182                         "AliHLTMUONRecHitsSource::DoInit",
183                         "Data interface",
184                         "Loading simulated GEANT hits with AliMUONSimData."
185                 );
186                 
187                 try
188                 {
189                         fMCDataInterface = new AliMUONMCDataInterface("galice.root");
190                 }
191                 catch (const std::bad_alloc&)
192                 {
193                         Logging(kHLTLogError,
194                                 "AliHLTMUONRecHitsSource::DoInit",
195                                 "Out of memory",
196                                 "Not enough memory to allocate AliMUONMCDataInterface."
197                         );
198                         return ENOMEM;
199                 }
200         }
201         else if (recdata)
202         {
203                 Logging(kHLTLogDebug,
204                         "AliHLTMUONRecHitsSource::DoInit",
205                         "Data interface",
206                         "Loading reconstructed clusters with AliMUONRecData."
207                 );
208                 
209                 try
210                 {
211                         fDataInterface = new AliMUONDataInterface("galice.root");
212                 }
213                 catch (const std::bad_alloc&)
214                 {
215                         Logging(kHLTLogError,
216                                 "AliHLTMUONRecHitsSource::DoInit",
217                                 "Out of memory",
218                                 "Not enough memory to allocate AliMUONDataInterface."
219                         );
220                         return ENOMEM;
221                 }
222         }
223         
224         return 0;
225 }
226
227
228 int AliHLTMUONRecHitsSource::DoDeinit()
229 {
230   delete fMCDataInterface;
231   fMCDataInterface = NULL;
232   delete fDataInterface;
233   fDataInterface = NULL;
234         return 0;
235 }
236
237
238 const char* AliHLTMUONRecHitsSource::GetComponentID()
239 {
240         return AliHLTMUONConstants::RecHitsSourceId();
241 }
242
243
244 AliHLTComponentDataType AliHLTMUONRecHitsSource::GetOutputDataType()
245 {
246         return AliHLTMUONConstants::RecHitsBlockDataType();
247 }
248
249
250 void AliHLTMUONRecHitsSource::GetOutputDataSize(
251                 unsigned long& constBase, double& inputMultiplier
252         )
253 {
254         constBase = sizeof(AliHLTMUONRecHitsBlockStruct) + 1024*4*8;
255         inputMultiplier = 0;
256 }
257
258
259 AliHLTComponent* AliHLTMUONRecHitsSource::Spawn()
260 {
261         return new AliHLTMUONRecHitsSource();
262 }
263
264
265 int AliHLTMUONRecHitsSource::GetEvent(
266                 const AliHLTComponentEventData& evtData,
267                 AliHLTComponentTriggerData& /*trigData*/,
268                 AliHLTUInt8_t* outputPtr, 
269                 AliHLTUInt32_t& size,
270                 vector<AliHLTComponentBlockData>& outputBlocks
271         )
272 {
273         assert( fMCDataInterface != NULL or fDataInterface != NULL );
274
275         // Check the size of the event descriptor structure.
276         if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
277         {
278                 Logging(kHLTLogError,
279                         "AliHLTMUONRecHitsSource::GetEvent",
280                         "Invalid event descriptor",
281                         "The event descriptor (AliHLTComponentEventData) size is"
282                           " smaller than expected. It claims to be %d bytes, but"
283                           " we expect it to be %d bytes.",
284                         evtData.fStructSize,
285                         sizeof(AliHLTComponentEventData)
286                 );
287                 size = 0; // Important to tell framework that nothing was generated.
288                 return EINVAL;
289         }
290         
291         // Use the fEventID as the event number to load, check it and load that
292         // event with the runloader.
293         UInt_t eventnumber = UInt_t(evtData.fEventID);
294   UInt_t maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
295         if ( eventnumber >= maxevent )
296         {
297                 Logging(kHLTLogError,
298                         "AliHLTMUONRecHitsSource::GetEvent",
299                         "Bad event ID",
300                         "The event number (%d) is larger than the available number"
301                           " of events on file (%d).",
302                         eventnumber,
303       maxevent
304     );
305                 size = 0; // Important to tell framework that nothing was generated.
306                 return EINVAL;
307         }
308         
309         // Create and initialise a new data block.
310         AliHLTMUONRecHitsBlockWriter block(outputPtr, size);
311         if (not block.InitCommonHeader())
312         {
313                 Logging(kHLTLogError,
314                         "AliHLTMUONRecHitsSource::GetEvent",
315                         "Buffer too small",
316                         "There is not enough buffer space to create a new data block."
317                           " We require at least %d bytes but the buffer is only %d bytes.",
318                         sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
319                         block.BufferSize()
320                 );
321                 size = 0; // Important to tell framework that nothing was generated.
322                 return ENOBUFS;
323         }
324         
325         if (fMCDataInterface != NULL)
326         {
327                 Logging(kHLTLogDebug,
328                         "AliHLTMUONRecHitsSource::GetEvent",
329                         "Filling hits",
330                         "Filling data block with GEANT hits for event %d.",
331                         eventnumber
332                 );
333                 
334                 // Loop over all tracks, extract the hits and write them to the
335                 // data block.
336     Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
337                 for (Int_t i = 0; i < ntracks; ++i)
338                 {
339       AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
340       AliMUONHit* hit;
341       TIter next(hitStore->CreateIterator());
342       while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
343       {
344                                 // Select only hits on selected chambers.
345                                 Int_t chamber = hit->Chamber() - 1;
346                                 if (chamber > AliMUONConstants::NTrackingCh()) continue;
347                                 if (not fServeChamber[chamber]) continue;
348                                 
349                                 // Only select hits from the given part of the plane
350                                 if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
351                                 if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
352                                 
353                                 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
354                                 if (rechit == NULL)
355                                 {
356                                         Logging(kHLTLogError,
357                                                 "AliHLTMUONRecHitsSource::GetEvent",
358                                                 "Buffer overflow",
359                                                 "There is not enough buffer space to add more hits."
360                                                   " We overflowed the buffer which is only %d bytes.",
361                                                 block.BufferSize()
362                                         );
363                                         size = 0; // Important to tell framework that nothing was generated.
364                                         return ENOBUFS;
365                                 }
366                                 
367                                 rechit->fX = hit->Xref();
368                                 rechit->fY = hit->Yref();
369                                 rechit->fZ = hit->Zref();
370                         }
371       delete hitStore;
372                 }
373         }
374         else if (fDataInterface != NULL)
375         {
376                 Logging(kHLTLogDebug,
377                         "AliHLTMUONRecHitsSource::GetEvent",
378                         "Filling hits",
379                         "Filling data block with reconstructed raw clusters for event %d.",
380                         eventnumber
381                 );
382                 
383                 AliMUONVClusterStore* clusterStore = fDataInterface->ClusterStore(eventnumber);
384     
385                 // Loop over selected chambers and extract the raw clusters.
386                 for (Int_t chamber = 0; chamber < AliMUONConstants::NTrackingCh(); chamber++)
387                 {
388                         // Select only hits on selected chambers.
389                         if (not fServeChamber[chamber]) continue;
390                         
391       TIter next(clusterStore->CreateChamberIterator(chamber,chamber));
392       AliMUONRawCluster* cluster;
393       
394                         while ( ( cluster = static_cast<AliMUONRawCluster*>(next()) ) )
395       {                         
396                                 // Only select hits from the given part of the plane
397                                 if (fSelection == kLeftPlane and not (cluster->GetX() < 0)) continue;
398                                 if (fSelection == kRightPlane and not (cluster->GetX() >= 0)) continue;
399                         
400                                 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
401                                 if (rechit == NULL)
402                                 {
403                                         Logging(kHLTLogError,
404                                                 "AliHLTMUONRecHitsSource::GetEvent",
405                                                 "Buffer overflow",
406                                                 "There is not enough buffer space to add more hits."
407                                                   " We overflowed the buffer which is only %d bytes.",
408                                                 block.BufferSize()
409                                         );
410                                         size = 0; // Important to tell framework that nothing was generated.
411                                         return ENOBUFS;
412                                 }
413                                 
414                                 rechit->fX = cluster->GetX();
415                                 rechit->fY = cluster->GetY();
416                                 rechit->fZ = cluster->GetZ();
417                         }
418                 }
419     delete clusterStore;
420         }
421         else
422         {
423                 Logging(kHLTLogError,
424                         "AliHLTMUONRecHitsSource::GetEvent",
425                         "Missing data interface",
426                         "Neither AliMUONSimData or AliMUONRecData were created."
427                 );
428                 size = 0; // Important to tell framework that nothing was generated.
429                 return EFAULT;
430         }
431         
432         AliHLTComponentBlockData bd;
433         FillBlockData(bd);
434         bd.fPtr = outputPtr;
435         bd.fOffset = 0;
436         bd.fSize = block.BytesUsed();
437         bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
438         bd.fSpecification = 7;
439         outputBlocks.push_back(bd);
440         size = block.BytesUsed();
441
442         return 0;
443 }
444
445
446 int AliHLTMUONRecHitsSource::ParseChamberString(const char* str)
447 {
448         char* end = const_cast<char*>(str);
449         long lastChamber = -1;
450         do
451         {
452                 // Parse the next number.
453                 char* current = end;
454                 long chamber = strtol(current, &end, 0);
455                 
456                 // Check for parse errors of the number.
457                 if (current == end)
458                 {
459                         Logging(kHLTLogError,
460                                 "AliHLTMUONRecHitsSource::GetEvent",
461                                 "Parse error",
462                                 "Expected a number in the range [1..%d] but got '%s'.",
463                                 AliMUONConstants::NTrackingCh(), current
464                         );
465                         return EINVAL;
466                 }
467                 if (chamber < 1 or AliMUONConstants::NTrackingCh() < chamber)
468                 {
469                         Logging(kHLTLogError,
470                                 "AliHLTMUONRecHitsSource::GetEvent",
471                                 "Parse error",
472                                 "Got the chamber number %d which is outside the valid range of [1..%d].",
473                                 AliMUONConstants::NTrackingCh(), chamber
474                         );
475                         return EINVAL;
476                 }
477                 
478                 // Skip any whitespace after the number
479                 while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
480                 
481                 // Check if we are dealing with a list or range, or if we are at
482                 // the end of the string.
483                 if (*end == '-')
484                 {
485                         lastChamber = chamber;
486                         end++;
487                         continue;
488                 }
489                 else if (*end == ',')
490                 {
491                         assert( 1 <= chamber and chamber <= 10 );
492                         fServeChamber[chamber-1] = true;
493                         end++;
494                 }
495                 else if (*end == '\0')
496                 {
497                         assert( 1 <= chamber and chamber <= 10 );
498                         fServeChamber[chamber-1] = true;
499                 }
500                 else
501                 {
502                         Logging(kHLTLogError,
503                                 "AliHLTMUONRecHitsSource::GetEvent",
504                                 "Parse error",
505                                 "Could not understand parameter list '%s'. Expected '-', ','"
506                                   " or end of line but got '%c' at character %d.",
507                                 str, *end, (int)(end - str) +1
508                         );
509                         return EINVAL;
510                 }
511                 
512                 // Set the range of chambers to publish for.
513                 if (lastChamber > 0)
514                 {
515                         Int_t min, max;
516                         if (lastChamber < chamber)
517                         {
518                                 min = lastChamber;
519                                 max = chamber;
520                         }
521                         else
522                         {
523                                 min = chamber;
524                                 max = lastChamber;
525                         }
526                         assert( min >= 1 );
527                         assert( max <= 10 );
528                         for (Int_t i = min; i <= max; i++)
529                                 fServeChamber[i-1] = true;
530                 }
531                 lastChamber = -1;
532         }
533         while (*end != '\0');
534         return 0;
535 }