]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.cxx
Fixing error codes so that components return negative codes according to HLT convention.
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONTriggerRecordsSource.cxx
CommitLineData
e6357f88 1/**************************************************************************
d328bad2 2 * This file is property of and copyright by the ALICE HLT Project *
e6357f88 3 * All rights reserved. *
4 * *
5 * Primary Authors: *
6 * Artur Szostak <artursz@iafrica.com> *
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 *
d328bad2 13 * about the suitability of this software for any purpose. It is *
e6357f88 14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id$ */
18
19/**
20 * @file AliHLTMUONTriggerRecordsSource.cxx
21 * @author Artur Szostak <artursz@iafrica.com>
22 * @date
23 * @brief Implementation of the AliHLTMUONTriggerRecordsSource component.
24 */
25
26#include "AliHLTMUONTriggerRecordsSource.h"
27#include "AliHLTMUONConstants.h"
28#include "AliHLTMUONUtils.h"
29#include "AliHLTMUONDataBlockWriter.h"
30#include "AliHLTMUONCalculations.h"
31#include "AliMUONMCDataInterface.h"
32#include "AliMUONDataInterface.h"
33#include "AliMUONHit.h"
34#include "AliMUONRawCluster.h"
35#include "AliMUONConstants.h"
36#include "AliMUONVClusterStore.h"
37#include "AliMUONVHitStore.h"
38#include "mapping/AliMpCDB.h"
39#include "mapping/AliMpDDLStore.h"
40#include "mapping/AliMpLocalBoard.h"
41#include "mapping/AliMpTriggerCrate.h"
42#include "mapping/AliMpDEManager.h"
43#include "mapping/AliMpDetElement.h"
44#include "AliLog.h"
45#include "TClonesArray.h"
46#include <cstdlib>
47#include <cstdio>
48#include <cerrno>
49#include <cassert>
50#include <new>
51
52namespace
53{
e6357f88 54
55 //TODO: The following method should be in MUON/mapping
56 Int_t FindDDLOfDetElement(Int_t detElemId)
57 {
58 // Find what the DDL ID number is for a detector element from
59 // trigger chambers 11 to 14. We first have to find the local
60 // board associated with the detector element and then we can
61 // associate that local board to the trigger crate which has
62 // the DDL number specified.
63 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
64 if (ddlStore == NULL) return -1;
65 Int_t ddl = -1, boardIndex = 1;
66 do
67 {
68 AliMpLocalBoard* board = ddlStore->GetLocalBoard(boardIndex++);
69 if (board == NULL) break;
70 if (board->HasDEId(detElemId))
71 {
72 AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(board->GetCrate());
73 if (crate == NULL) continue;
74 ddl = crate->GetDdlId();
75 break;
76 }
77 }
78 while (ddl == -1);
79 return ddl;
80 }
81
82}
83
84
85ClassImp(AliHLTMUONTriggerRecordsSource);
86
87
88AliHLTMUONTriggerRecordsSource::AliHLTMUONTriggerRecordsSource() :
89 AliHLTOfflineDataSource(),
90 fMCDataInterface(NULL),
91 fDataInterface(NULL),
92 fBuildFromHits(false),
c06fe66f 93 fSelection(kWholePlane),
6253e09b 94 fCurrentEventIndex(0)
e6357f88 95{
6253e09b 96 ///
97 /// Default constructor.
98 ///
e6357f88 99}
100
101
102AliHLTMUONTriggerRecordsSource::~AliHLTMUONTriggerRecordsSource()
103{
6253e09b 104 ///
105 /// Default destructor.
106 ///
107
e6357f88 108 assert( fMCDataInterface == NULL );
109 assert( fDataInterface == NULL );
110}
111
112
113int AliHLTMUONTriggerRecordsSource::DoInit(int argc, const char** argv)
114{
6253e09b 115 ///
116 /// Inherited from AliHLTComponent.
117 /// Parses the command line parameters and initialises the component.
118 ///
119
e6357f88 120 assert( fMCDataInterface == NULL );
121 assert( fDataInterface == NULL );
122
123 // Parse the command line arguments:
124 bool hitdata = false;
125 bool simdata = false;
126 bool recdata = false;
6253e09b 127 fCurrentEventIndex = 0;
c06fe66f 128 bool firstEventSet = false;
129 bool eventNumLitSet = false;
e6357f88 130
131 for (int i = 0; i < argc; i++)
132 {
133 if (strcmp(argv[i], "-hitdata") == 0)
134 {
135 hitdata = true;
136 }
137 else if (strcmp(argv[i], "-simdata") == 0)
138 {
139 simdata = true;
140 }
141 else if (strcmp(argv[i], "-recdata") == 0)
142 {
143 recdata = true;
144 }
145 else if (strcmp(argv[i], "-plane") == 0)
146 {
147 i++;
148 if (i >= argc)
149 {
150 Logging(kHLTLogError,
151 "AliHLTMUONTriggerRecordsSource::DoInit",
152 "Missing parameter",
153 "Expected one of 'left', 'right' or 'all' after '-plane'."
154 );
d328bad2 155 return -EINVAL;
e6357f88 156 }
157 if (strcmp(argv[i], "left") == 0)
158 fSelection = kLeftPlane;
159 else if (strcmp(argv[i], "right") == 0)
160 fSelection = kRightPlane;
161 else if (strcmp(argv[i], "all") == 0)
162 fSelection = kWholePlane;
163 else
164 {
165 Logging(kHLTLogError,
166 "AliHLTMUONTriggerRecordsSource::DoInit",
167 "Invalid parameter",
168 "The parameter '%s' is invalid and must be one of 'left',"
169 " 'right' or 'all'.",
170 argv[i]
171 );
d328bad2 172 return -EINVAL;
e6357f88 173 }
174 }
c06fe66f 175 else if (strcmp(argv[i], "-firstevent") == 0)
176 {
177 if (eventNumLitSet)
178 {
179 HLTWarning("The -firstevent flag is overridden by a"
180 " previous use of -event_number_literal."
181 );
182 }
183 i++;
184 if (i >= argc)
185 {
186 HLTError("Expected a positive number after -firstevent.");
d328bad2 187 return -EINVAL;
c06fe66f 188 }
189 char* end = "";
190 long num = strtol(argv[i], &end, 0);
191 if (*end != '\0' or num < 0) // Check if the conversion is OK.
192 {
193 HLTError(Form(
194 "Expected a positive number after -firstevent"
195 " but got: %s", argv[i]
196 ));
d328bad2 197 return -EINVAL;
c06fe66f 198 }
6253e09b 199 fCurrentEventIndex = Int_t(num);
c06fe66f 200 firstEventSet = true;
201 }
202 else if (strcmp(argv[i], "-event_number_literal") == 0)
203 {
204 if (firstEventSet)
205 {
206 HLTWarning("The -event_number_literal option will"
207 " override -firstevent."
208 );
209 }
6253e09b 210 fCurrentEventIndex = -1;
c06fe66f 211 eventNumLitSet = true;
212 }
e6357f88 213 else
214 {
215 Logging(kHLTLogError,
216 "AliHLTMUONTriggerRecordsSource::DoInit",
217 "Unknown argument",
218 "The argument '%s' is invalid.",
219 argv[i]
220 );
d328bad2 221 return -EINVAL;
e6357f88 222 }
223 }
224
225 // Check that one and only one of the the -hitdata, -simdata or
226 // -recdata parameters was specified on the command line.
227 if ((not hitdata and not simdata and not recdata) or
228 (not hitdata and simdata and recdata) or
229 (hitdata and not simdata and recdata) or
230 (hitdata and simdata and not recdata) or
231 (hitdata and simdata and recdata)
232 )
233 {
234 Logging(kHLTLogError,
235 "AliHLTMUONTriggerRecordsSource::DoInit",
236 "Missing arguments",
237 "Must have one and only one of -hitdata, -simdata or -recdata specified."
238 );
d328bad2 239 return -EINVAL;
e6357f88 240 }
241
242 // Must load the mapping data for AliMpTriggerCrate::GetDdlId() //TODO AliMpTriggerCrate => AliMpDetElement
243 // to return useful information later on.
244 AliMpCDB::LoadDDLStore();
245
246 // Now we can initialise the data interface objects and loaders.
247 fBuildFromHits = hitdata;
248 if (hitdata or simdata)
249 {
250 const char* message = fBuildFromHits ?
251 "Loading simulated GEANT hits with AliMUONMCDataInterface."
252 : "Loading simulated local trigger objects with AliMUONMCDataInterface.";
253
254 Logging(kHLTLogDebug, "AliHLTMUONTriggerRecordsSource::DoInit",
255 "Data interface", message
256 );
257
258 try
259 {
260 fMCDataInterface = new AliMUONMCDataInterface("galice.root");
261 }
262 catch (const std::bad_alloc&)
263 {
264 Logging(kHLTLogError,
265 "AliHLTMUONTriggerRecordsSource::DoInit",
266 "Out of memory",
267 "Not enough memory to allocate AliMUONMCDataInterface."
268 );
d328bad2 269 return -ENOMEM;
e6357f88 270 }
271 }
272 else if (recdata)
273 {
274 Logging(kHLTLogDebug,
275 "AliHLTMUONTriggerRecordsSource::DoInit",
276 "Data interface",
277 "Loading reconstructed local trigger objects with AliMUONDataInterface."
278 );
279
280 try
281 {
282 fDataInterface = new AliMUONDataInterface("galice.root");
283 }
284 catch (const std::bad_alloc&)
285 {
286 Logging(kHLTLogError,
287 "AliHLTMUONTriggerRecordsSource::DoInit",
288 "Out of memory",
289 "Not enough memory to allocate AliMUONDataInterface."
290 );
d328bad2 291 return -ENOMEM;
e6357f88 292 }
293 }
294
6253e09b 295 // Check that the fCurrentEventIndex number falls within the correct range.
c06fe66f 296 UInt_t maxevent = 0;
297 if (fMCDataInterface != NULL)
298 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
299 else if (fDataInterface != NULL)
300 maxevent = UInt_t(fDataInterface->NumberOfEvents());
6253e09b 301 if (fCurrentEventIndex != -1 and UInt_t(fCurrentEventIndex) >= maxevent and maxevent != 0)
c06fe66f 302 {
6253e09b 303 fCurrentEventIndex = 0;
c06fe66f 304 HLTWarning(Form("The selected first event number (%d) was larger than"
305 " the available number of events (%d). Resetting the event"
6253e09b 306 " counter to zero.", fCurrentEventIndex, maxevent
c06fe66f 307 ));
308 }
309
e6357f88 310 return 0;
311}
312
313
314int AliHLTMUONTriggerRecordsSource::DoDeinit()
315{
6253e09b 316 ///
317 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
318 ///
319
e6357f88 320 if (fMCDataInterface != NULL)
321 {
322 delete fMCDataInterface;
323 fMCDataInterface = NULL;
324 }
325 if (fDataInterface != NULL)
326 {
327 delete fDataInterface;
328 fDataInterface = NULL;
329 }
330 return 0;
331}
332
333
334const char* AliHLTMUONTriggerRecordsSource::GetComponentID()
335{
6253e09b 336 ///
337 /// Inherited from AliHLTComponent. Returns the component ID.
338 ///
339
e6357f88 340 return AliHLTMUONConstants::TriggerRecordsSourceId();
341}
342
343
344AliHLTComponentDataType AliHLTMUONTriggerRecordsSource::GetOutputDataType()
345{
6253e09b 346 ///
347 /// Inherited from AliHLTComponent. Returns the output data type.
348 ///
349
e6357f88 350 return AliHLTMUONConstants::TriggerRecordsBlockDataType();
351}
352
353
354void AliHLTMUONTriggerRecordsSource::GetOutputDataSize(
355 unsigned long& constBase, double& inputMultiplier
356 )
357{
6253e09b 358 ///
359 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
360 ///
361
e6357f88 362 constBase = sizeof(AliHLTMUONTriggerRecordsBlockStruct) +
363 sizeof(AliHLTMUONTriggerRecordStruct) * AliMUONConstants::NTriggerCircuit();
364 inputMultiplier = 0;
365}
366
367
368AliHLTComponent* AliHLTMUONTriggerRecordsSource::Spawn()
369{
6253e09b 370 ///
371 /// Inherited from AliHLTComponent. Creates a new object instance.
372 ///
373
e6357f88 374 return new AliHLTMUONTriggerRecordsSource();
375}
376
377
378int AliHLTMUONTriggerRecordsSource::GetEvent(
379 const AliHLTComponentEventData& evtData,
380 AliHLTComponentTriggerData& /*trigData*/,
381 AliHLTUInt8_t* outputPtr,
382 AliHLTUInt32_t& size,
383 vector<AliHLTComponentBlockData>& outputBlocks
384 )
385{
6253e09b 386 ///
387 /// Inherited from AliHLTOfflineDataSource. Creates new event data blocks.
388 ///
389
e6357f88 390 assert( fMCDataInterface != NULL or fDataInterface != NULL );
391
392 AliHLTInt32_t trigRecId = 0;
393
394 // Check the size of the event descriptor structure.
395 if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
396 {
397 Logging(kHLTLogError,
398 "AliHLTMUONTriggerRecordsSource::GetEvent",
399 "Invalid event descriptor",
400 "The event descriptor (AliHLTComponentEventData) size is"
401 " smaller than expected. It claims to be %d bytes, but"
402 " we expect it to be %d bytes.",
403 evtData.fStructSize,
404 sizeof(AliHLTComponentEventData)
405 );
406 size = 0; // Important to tell framework that nothing was generated.
d328bad2 407 return -EINVAL;
e6357f88 408 }
409
6253e09b 410 // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
c06fe66f 411 // check it and load that event with the runloader.
6253e09b 412 // If fCurrentEventIndex is a positive number then us it instead and
c06fe66f 413 // increment it.
e6357f88 414 UInt_t eventnumber = UInt_t(evtData.fEventID);
415 UInt_t maxevent = fMCDataInterface != NULL ?
416 UInt_t(fMCDataInterface->NumberOfEvents())
417 : UInt_t(fDataInterface->NumberOfEvents());
6253e09b 418 if (fCurrentEventIndex != -1)
c06fe66f 419 {
6253e09b 420 eventnumber = UInt_t(fCurrentEventIndex);
421 fCurrentEventIndex++;
422 if (UInt_t(fCurrentEventIndex) >= maxevent)
423 fCurrentEventIndex = 0;
c06fe66f 424 }
e6357f88 425 if ( eventnumber >= maxevent )
426 {
427 Logging(kHLTLogError,
428 "AliHLTMUONTriggerRecordsSource::GetEvent",
429 "Bad event ID",
430 "The event number (%d) is larger than the available number"
431 " of events on file (%d).",
432 eventnumber,
433 maxevent
434 );
435 size = 0; // Important to tell framework that nothing was generated.
d328bad2 436 return -EINVAL;
e6357f88 437 }
438
439 // Create and initialise a new data block.
440 AliHLTMUONTriggerRecordsBlockWriter block(outputPtr, size);
441 if (not block.InitCommonHeader())
442 {
443 Logging(kHLTLogError,
444 "AliHLTMUONTriggerRecordsSource::GetEvent",
445 "Buffer too small",
446 "There is not enough buffer space to create a new data block."
447 " We require at least %d bytes but the buffer is only %d bytes.",
448 sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
449 block.BufferSize()
450 );
451 size = 0; // Important to tell framework that nothing was generated.
d328bad2 452 return -ENOBUFS;
e6357f88 453 }
454
455 // Initialise the DDL list containing the DDLs which contributed to the
456 // data block. These are required to create the specification word later.
457 bool ddlList[22];
458 for (Int_t i = 0; i < 22; i++)
459 ddlList[i] = false;
460
461 if (fMCDataInterface != NULL and fBuildFromHits)
462 {
463 Logging(kHLTLogDebug,
464 "AliHLTMUONTriggerRecordsSource::GetEvent",
465 "Filling triggers",
466 "Filling data block with trigger records from GEANT hits for event %d.",
467 eventnumber
468 );
469
470 // Loop over all tracks, extract the hits from chambers 11 to 14 and
471 // create trigger records from them to write to the data block.
472 Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
473 for (Int_t i = 0; i < ntracks; ++i)
474 {
475 AliMUONHit* hit11 = NULL;
476 AliMUONHit* hit12 = NULL;
477 AliMUONHit* hit13 = NULL;
478 AliMUONHit* hit14 = NULL;
479 Int_t ddl11 = -1;
480 Int_t ddl12 = -1;
481 Int_t ddl13 = -1;
482 Int_t ddl14 = -1;
483
484 AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
485 AliMUONHit* hit;
486 TIter next(hitStore->CreateIterator());
487 while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
488 {
489 // Select only hits on trigger chambers.
490 if (hit->Chamber() <= AliMUONConstants::NTrackingCh()) continue;
491
492 // Only select hits from the given part of the plane
493 if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
494 if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
495
496 // Workout which DDL this hit should be readout of.
497 Int_t ddl = FindDDLOfDetElement(hit->DetElemId());
498 if (not (0 <= ddl and ddl < 22))
499 {
500 ddl = -1;
501 Logging(kHLTLogError,
502 "AliHLTMUONTriggerRecordsSource::GetEvent",
503 "No DDL ID",
504 "Could not find the DDL ID from which readout would take place."
505 );
506 }
507
508 switch (hit->Chamber())
509 {
510 case 11: hit11 = hit; ddl11 = ddl; break;
511 case 12: hit12 = hit; ddl12 = ddl; break;
512 case 13: hit13 = hit; ddl13 = ddl; break;
513 case 14: hit14 = hit; ddl14 = ddl; break;
514 default: break;
515 }
516 }
517
518 // Check that there are at least 3 of 4 hits on the trigger chambers.
519 Int_t hitCount = 0;
520 if (hit11 != NULL) hitCount++;
521 if (hit12 != NULL) hitCount++;
522 if (hit13 != NULL) hitCount++;
523 if (hit14 != NULL) hitCount++;
524 if (hitCount < 3) continue;
525
526 AliHLTMUONTriggerRecordStruct* trigRec = block.AddEntry();
527 if (trigRec == NULL)
528 {
529 Logging(kHLTLogError,
530 "AliHLTMUONTriggerRecordsSource::GetEvent",
531 "Buffer overflow",
532 "There is not enough buffer space to add more trigger records."
533 " We overflowed the buffer which is only %d bytes.",
534 block.BufferSize()
535 );
536 size = 0; // Important to tell framework that nothing was generated.
d328bad2 537 return -ENOBUFS;
e6357f88 538 }
539
540 // Fill the new trigger record with the hit information.
541 bool hitset[4] = {false, false, false, false};
542 AliHLTFloat32_t x1 = 0, y1 = 0, y2 = 0, z1 = 0, z2 = 0;
543 if (hit11 != NULL)
544 {
545 trigRec->fHit[0].fX = hit11->Xref();
546 trigRec->fHit[0].fY = hit11->Yref();
547 trigRec->fHit[0].fZ = hit11->Zref();
548 hitset[0] = true;
549 x1 = hit11->Xref();
550 y1 = hit11->Yref();
551 z1 = hit11->Zref();
552 }
553 if (hit12 != NULL)
554 {
555 trigRec->fHit[1].fX = hit12->Xref();
556 trigRec->fHit[1].fY = hit12->Yref();
557 trigRec->fHit[1].fZ = hit12->Zref();
558 hitset[1] = true;
559 x1 = hit12->Xref();
560 y1 = hit12->Yref();
561 z1 = hit12->Zref();
562 }
563 if (hit13 != NULL)
564 {
565 trigRec->fHit[2].fX = hit13->Xref();
566 trigRec->fHit[2].fY = hit13->Yref();
567 trigRec->fHit[2].fZ = hit13->Zref();
568 hitset[2] = true;
569 y2 = hit13->Yref();
570 z2 = hit13->Zref();
571 }
572 if (hit14 != NULL)
573 {
574 trigRec->fHit[3].fX = hit14->Xref();
575 trigRec->fHit[3].fY = hit14->Yref();
576 trigRec->fHit[3].fZ = hit14->Zref();
577 hitset[3] = true;
578 y2 = hit14->Yref();
579 z2 = hit14->Zref();
580 }
581
582 bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
583 if (not calculated)
584 Logging(kHLTLogDebug,
585 "AliHLTMUONTriggerRecordsSource::GetEvent",
586 "Calculation failure",
587 "Something went wrong when calculating the momentum from"
588 " x1 = %f, y1 = %f, y2 = %f, z1 = %f, z2 = %f.",
589 x1, y1, y2, z1, z2
590 );
591
592 trigRec->fId = trigRecId++;
593 trigRec->fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
594 AliHLTMUONCalculations::Sign(), hitset
595 );
596 trigRec->fPx = AliHLTMUONCalculations::Px();
597 trigRec->fPy = AliHLTMUONCalculations::Py();
598 trigRec->fPz = AliHLTMUONCalculations::Pz();
599
600 // Mark the DDLs over which this trigger record would be readout.
601 if (ddl11 != -1) ddlList[ddl11] = true;
602 if (ddl12 != -1) ddlList[ddl12] = true;
603 if (ddl13 != -1) ddlList[ddl13] = true;
604 if (ddl14 != -1) ddlList[ddl14] = true;
605 }
606 }
607 else if (fMCDataInterface != NULL and not fBuildFromHits)
608 {
609 Logging(kHLTLogDebug,
610 "AliHLTMUONTriggerRecordsSource::GetEvent",
611 "Filling triggers",
612 "Filling data block with simulated local triggers for event %d.",
613 eventnumber
614 );
615
616 AliFatal("Sorry, -simdata option not yet implemented!");
617 // TODO
618 }
619 else if (fDataInterface != NULL)
620 {
621 Logging(kHLTLogDebug,
622 "AliHLTMUONTriggerRecordsSource::GetEvent",
623 "Filling triggers",
624 "Filling data block with reconstructed local triggers for event %d.",
625 eventnumber
626 );
627 // TODO
628 AliFatal("Sorry, -recdata option not yet implemented!");
629 }
630 else
631 {
632 Logging(kHLTLogError,
633 "AliHLTMUONTriggerRecordsSource::GetEvent",
634 "Missing data interface",
635 "Neither AliMUONDataInterface nor AliMUONMCDataInterface were created."
636 );
637 size = 0; // Important to tell framework that nothing was generated.
d328bad2 638 return -EFAULT;
e6357f88 639 }
640
641 AliHLTComponentBlockData bd;
642 FillBlockData(bd);
643 bd.fPtr = outputPtr;
644 bd.fOffset = 0;
645 bd.fSize = block.BytesUsed();
646 bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
647 bd.fSpecification = AliHLTMUONUtils::PackSpecBits(ddlList);
648 outputBlocks.push_back(bd);
649 size = block.BytesUsed();
650
651 return 0;
652}