]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/src/AliRoot/TriggerSource.cxx
Renaming files to fall inline with coding conventions.
[u/mrichter/AliRoot.git] / HLT / MUON / src / AliRoot / TriggerSource.cxx
CommitLineData
8356cc1d 1////////////////////////////////////////////////////////////////////////////////
2//
3// Author: Artur Szostak
4// Email: artur@alice.phy.uct.ac.za | artursz@iafrica.com
5//
6////////////////////////////////////////////////////////////////////////////////
7
3a682eae 8/* AliHLTMUONTriggerSource is used to extract L0 trigger information for
9 the muon spectrometer from a simulated event stored in .root files by AliRoot.
10 It is used by the AliHLTMUONMicrodHLT class as a input data set for the
11 dHLT algorithm.
12 */
13
8356cc1d 14#include "AliRoot/TriggerSource.hpp"
15#include "AliRoot/Base.hpp"
16#include "Tracking/Calculations.hpp"
17#include "AliRun.h"
18#include "AliRunLoader.h"
19#include "AliModule.h"
20#include "AliMUON.h"
21#include "AliMUONConstants.h"
22#include "AliMUONHit.h"
23#include "AliMUONLocalTrigger.h"
24#include "AliMUONTriggerCircuit.h"
25#include "AliMUONDataInterface.h"
26#include "TDatabasePDG.h"
98af1577 27#ifndef __alpha
28#include <math.h>
29#else
30#include <float.h>
31#endif
8356cc1d 32
69d7cf2e 33ClassImp(AliHLTMUONTriggerSource)
3a682eae 34ClassImp(AliHLTMUONTriggerSource::AliEventData)
8356cc1d 35
8356cc1d 36
69d7cf2e 37AliHLTMUONTriggerSource::AliHLTMUONTriggerSource()
3a682eae 38 : TObject(), fEventList(AliHLTMUONTriggerSource::AliEventData::Class())
8356cc1d 39{
3a682eae 40// Default constructor.
41
42 fAreaToUse = kFromWholePlane;
43 fDataToUse = kFromLocalTriggers;
8356cc1d 44 fMaxBlockSize = 0xFFFFFFFF;
45 fUseLookupTable = kTRUE;
46 fFilename = "";
47 fFoldername = "";
48 ResetAllPointers();
49 fHadToLoadgAlice = kFALSE;
cbee67e7 50}
8356cc1d 51
52
69d7cf2e 53AliHLTMUONTriggerSource::AliHLTMUONTriggerSource(AliMUONDataInterface* data)
3a682eae 54 : TObject(), fEventList(AliHLTMUONTriggerSource::AliEventData::Class())
8356cc1d 55{
3a682eae 56// Creates a new trigger source object by filling data from the data interface.
57
58 fAreaToUse = kFromWholePlane;
59 fDataToUse = kFromLocalTriggers;
8356cc1d 60 fMaxBlockSize = 0xFFFFFFFF;
61 fUseLookupTable = kTRUE;
62 fFilename = "";
63 fFoldername = "";
64 ResetAllPointers();
65 fHadToLoadgAlice = kFALSE;
66 FillFrom(data);
cbee67e7 67}
8356cc1d 68
69
69d7cf2e 70AliHLTMUONTriggerSource::~AliHLTMUONTriggerSource()
8356cc1d 71{
12ab84fc 72 fEventList.Delete();
cbee67e7 73}
8356cc1d 74
75
69d7cf2e 76void AliHLTMUONTriggerSource::FillFrom(AliMUONDataInterface* data)
8356cc1d 77{
3a682eae 78// Fills the internal data structures from the specified data interface
79// for all the events found in AliMUONDataInterface.
80
8356cc1d 81 DebugMsg(1, "FillFrom(AliMUONDataInterface*)");
82
83 if (FileAndFolderOk(data))
84 {
85 AliMUON* module = NULL;
f086c81b 86 if ( ! FetchAliMUON(module) ) return;
8356cc1d 87
88 for (Int_t i = 0; i < data->NumberOfEvents(); i++)
89 {
90 AddEventFrom(data, module, i);
cbee67e7 91 }
8356cc1d 92
93 FinishedWithAliMUON();
cbee67e7 94 }
95}
8356cc1d 96
97
69d7cf2e 98void AliHLTMUONTriggerSource::FillFrom(AliMUONDataInterface* data, Int_t event)
8356cc1d 99{
3a682eae 100// Fills the internal data structures from the specified data interface
101// for the given event.
102
8356cc1d 103 DebugMsg(1, "FillFrom(AliMUONDataInterface*, Int_t)");
104
105 if (FileAndFolderOk(data))
106 {
107 AliMUON* module = NULL;
f086c81b 108 if ( ! FetchAliMUON(module) ) return;
8356cc1d 109 AddEventFrom(data, module, event);
110 FinishedWithAliMUON();
cbee67e7 111 }
112}
8356cc1d 113
114
69d7cf2e 115void AliHLTMUONTriggerSource::FillFrom(
8356cc1d 116 AliMUONDataInterface* data,
e33f3609 117 Int_t event, Int_t trigger, Bool_t newblock
8356cc1d 118 )
119{
3a682eae 120// Fills the internal data structures from the specified data interface
121// for the given event and trigger number.
122// If 'newblock' is set to true then the new trigger record is added to
123// a new block. Otherwise the point is added to the current block.
124// Note: This method ignores the fAreaToUse and fMaxBlockSize flags.
125// This is very usefull for custom trigger source filling.
126// For the case of adding data from AliMUONHit objects the 'trigger'
127// parameter becomes the track number in TreeH and not the index of the
128// AliMUONLocalTrigger object.
129
8356cc1d 130 DebugMsg(1, "FillFrom(AliMUONDataInterface*, Int_t, Int_t, Bool_t)");
131
132 if (FileAndFolderOk(data))
133 {
134 data->GetEvent(event);
135 AliMUON* module = NULL;
f086c81b 136 if ( ! FetchAliMUON(module) ) return;
8356cc1d 137
138 // Check if the current event corresponds to the event number we are
139 // attempting to add to. If they do not or no event is selected then
140 // try find the event or create a new one.
141 if ( fCurrentEvent == NULL )
142 {
143 Bool_t found = GetEvent(event);
f086c81b 144 if ( ! found) AddEvent(event);
8356cc1d 145 }
146 else
147 {
3a682eae 148 if (fCurrentEvent->EventNumber() != event)
8356cc1d 149 {
150 Bool_t found = GetEvent(event);
f086c81b 151 if ( ! found) AddEvent(event);
152 }
153 }
8356cc1d 154
155 if ( fCurrentBlock != NULL )
156 {
157 Assert( fCurrentEvent != NULL );
158 // If the newblock flag is set then force a new block.
159 if (newblock) AddBlock();
160 }
161 else
162 AddBlock(); // No block selected so we need to create a new block.
163
164 AddTriggerFrom(data, module, trigger);
165 FinishedWithAliMUON();
cbee67e7 166 }
167}
8356cc1d 168
169
69d7cf2e 170void AliHLTMUONTriggerSource::Clear(Option_t* /*option*/)
8356cc1d 171{
3a682eae 172// Clears all the internal arrays.
173
8356cc1d 174 fFilename = "";
175 fFoldername = "";
176 ResetAllPointers();
177 fEventList.Clear("C");
cbee67e7 178}
8356cc1d 179
180
69d7cf2e 181Bool_t AliHLTMUONTriggerSource::GetEvent(Int_t eventnumber) const
8356cc1d 182{
3a682eae 183// Fetches the specified event number stored in this AliHLTMUONTriggerSource.
184// Sets the current block and trigger to the first block and trigger record in
185// the event. If there are no blocks or trigger records then these pointers are
186// set to NULL. kTRUE is returned if the event was found, kFALSE otherwise.
187
69d7cf2e 188 DebugMsg(1, "AliHLTMUONTriggerSource::GetEvent(" << eventnumber << ")" );
8356cc1d 189
190 // Try find the corresponding event in the list of events.
191 for (Int_t i = 0; i < fEventList.GetEntriesFast(); i++)
192 {
3a682eae 193 AliEventData* current = (AliEventData*) fEventList[i];
194 if (current->EventNumber() == eventnumber)
8356cc1d 195 {
196 fEventIndex = i;
197 fCurrentEvent = current;
198 GetFirstBlock();
199 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
200 << " , fTriggerIndex = " << fTriggerIndex
201 );
202 return kTRUE;
f086c81b 203 }
204 }
8356cc1d 205 return kFALSE;
cbee67e7 206}
8356cc1d 207
208
69d7cf2e 209Bool_t AliHLTMUONTriggerSource::GetFirstEvent() const
8356cc1d 210{
3a682eae 211// Fetches the first event stored in this AliHLTMUONTriggerSource.
212// Sets the current block and trigger record to the first block and trigger
213// in the event. If there are no blocks or trigger records then these pointers
214// are set to NULL. kTRUE is returned if the event was found, kFALSE otherwise.
215
69d7cf2e 216 DebugMsg(1, "AliHLTMUONTriggerSource::GetFirstEvent()");
8356cc1d 217 if (fEventList.GetEntriesFast() > 0)
218 {
219 fEventIndex = 0;
3a682eae 220 fCurrentEvent = (AliEventData*) fEventList[0];
8356cc1d 221 GetFirstBlock();
222 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
223 << " , fTriggerIndex = " << fTriggerIndex
224 );
225 return kTRUE;
226 }
227 else
228 {
229 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
230 << " , fTriggerIndex = " << fTriggerIndex
231 );
232 return kFALSE;
cbee67e7 233 }
234}
8356cc1d 235
236
69d7cf2e 237Bool_t AliHLTMUONTriggerSource::MoreEvents() const
8356cc1d 238{
3a682eae 239// Returns kTRUE if there are more events to iterate over.
240
f086c81b 241 return 0 <= fEventIndex && fEventIndex < fEventList.GetEntriesFast();
cbee67e7 242}
8356cc1d 243
244
69d7cf2e 245Bool_t AliHLTMUONTriggerSource::GetNextEvent() const
8356cc1d 246{
3a682eae 247// Fetches the next event stored following the currently selected one.
248// kTRUE is returned if the event was found, kFALSE otherwise.
249// The internal pointers are reset if we reached the last event.
250
69d7cf2e 251 DebugMsg(1, "AliHLTMUONTriggerSource::GetNextEvent()");
8356cc1d 252 if (fEventIndex < fEventList.GetEntriesFast() - 1)
253 {
3a682eae 254 fCurrentEvent = (AliEventData*) fEventList[ ++fEventIndex ];
8356cc1d 255 GetFirstBlock();
256 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
257 << " , fTriggerIndex = " << fTriggerIndex
258 );
259 return kTRUE;
260 }
261 else
262 {
263 ResetAllPointers();
264 return kFALSE;
cbee67e7 265 }
266}
8356cc1d 267
268
69d7cf2e 269Int_t AliHLTMUONTriggerSource::CurrentEvent() const
8356cc1d 270{
3a682eae 271// Returns the corresponding AliRoot event number for the current event.
272// -1 is returned if no event is selected.
273
8356cc1d 274 if (fCurrentEvent != NULL)
3a682eae 275 return fCurrentEvent->EventNumber();
8356cc1d 276 else
277 return -1;
cbee67e7 278}
8356cc1d 279
280
69d7cf2e 281Int_t AliHLTMUONTriggerSource::NumberOfBlocks() const
8356cc1d 282{
3a682eae 283// Returns the number of trigger record blocks in the current event.
284// -1 is returned if no event is selected.
285
69d7cf2e 286 DebugMsg(1, "AliHLTMUONTriggerSource::NumberOfBlocks()");
8356cc1d 287 if (fCurrentEvent == NULL)
288 {
289 Error("NumberOfBlocks", "No event selected.");
290 return -1;
291 }
292 else
3a682eae 293 return fCurrentEvent->Blocks().GetEntriesFast();
cbee67e7 294}
8356cc1d 295
296
69d7cf2e 297Bool_t AliHLTMUONTriggerSource::GetBlock(Int_t index) const
8356cc1d 298{
3a682eae 299// Fetches the index'th block in the current event.
300// Sets the current trigger record to the first trigger in the block.
301// If there are no trigger records then this pointer is set to NULL.
302// kTRUE is returned if the block was found, kFALSE otherwise.
303
69d7cf2e 304 DebugMsg(1, "AliHLTMUONTriggerSource::GetBlock(" << index << ")");
8356cc1d 305
306 // Note NumberOfBlocks() also checks if the event was selected.
307 Int_t numberofblocks = NumberOfBlocks();
308 if (numberofblocks < 0) return kFALSE;
309
f086c81b 310 if ( 0 <= index && index < numberofblocks )
8356cc1d 311 {
312 fBlockIndex = index;
3a682eae 313 fCurrentBlock = (TClonesArray*) fCurrentEvent->Blocks()[index];
8356cc1d 314 GetFirstTrigger();
315 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
316 << " , fTriggerIndex = " << fTriggerIndex
317 );
318 return kTRUE;
319 }
320 else
321 {
322 // The index is out of bounds so inform the user.
323 if (numberofblocks > 0)
324 Error( "GetBlock",
325 "The block index (%d) is out of bounds. Valid range is [0, %d]",
326 index, numberofblocks - 1
327 );
328 else
329 Error( "GetBlock",
330 "The block index (%d) is out of bounds. No blocks found.",
331 index
332 );
333 return kFALSE;
cbee67e7 334 }
335}
8356cc1d 336
337
69d7cf2e 338Bool_t AliHLTMUONTriggerSource::GetFirstBlock() const
8356cc1d 339{
3a682eae 340// Fetches the first block in the current event.
341// Sets the current trigger record to the first trigger in the block.
342// If there are no trigger records then this pointer is set to NULL.
343// kTRUE is returned if the block was found, kFALSE otherwise.
344
69d7cf2e 345 DebugMsg(1, "AliHLTMUONTriggerSource::GetFirstBlock()");
8356cc1d 346 // Note: NumberOfBlocks() also checks if fCurrentEvent != NULL.
347 if (NumberOfBlocks() > 0)
348 {
349 fBlockIndex = 0;
3a682eae 350 fCurrentBlock = (TClonesArray*) fCurrentEvent->Blocks()[fBlockIndex];
8356cc1d 351 GetFirstTrigger();
352 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
353 << " , fTriggerIndex = " << fTriggerIndex
354 );
355 return kTRUE;
356 }
357 else
358 return kFALSE;
cbee67e7 359}
8356cc1d 360
361
69d7cf2e 362Bool_t AliHLTMUONTriggerSource::MoreBlocks() const
8356cc1d 363{
3a682eae 364// Returns kTRUE if there are more blocks to be traversed.
365
f086c81b 366 return 0 <= fBlockIndex && fBlockIndex < NumberOfBlocks();
cbee67e7 367}
8356cc1d 368
369
69d7cf2e 370Bool_t AliHLTMUONTriggerSource::GetNextBlock() const
8356cc1d 371{
3a682eae 372// Fetches the next block in the current event.
373// kTRUE is returned if the block was found, kFALSE otherwise.
374
69d7cf2e 375 DebugMsg(1, "AliHLTMUONTriggerSource::GetNextBlock()");
8356cc1d 376
377 // Note: NumberOfBlocks() checks if fCurrentEvent != NULL. If it is then it returns -1
378 // and since fBlockIndex is always >= -1 the if statement must go to the else part.
379 if (fBlockIndex < NumberOfBlocks() - 1)
380 {
3a682eae 381 fCurrentBlock = (TClonesArray*) fCurrentEvent->Blocks()[ ++fBlockIndex ];
8356cc1d 382 GetFirstTrigger();
383 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
384 << " , fTriggerIndex = " << fTriggerIndex
385 );
386 return kTRUE;
387 }
388 else
389 {
390 ResetBlockPointers();
391 return kFALSE;
cbee67e7 392 }
393}
8356cc1d 394
395
69d7cf2e 396Int_t AliHLTMUONTriggerSource::NumberOfTriggers() const
8356cc1d 397{
3a682eae 398// Returns the number of trigger records in the current block.
399// -1 is returned if no block is selected.
400
69d7cf2e 401 DebugMsg(1, "AliHLTMUONTriggerSource::NumberOfTriggers()");
8356cc1d 402 if (fCurrentBlock == NULL)
403 {
404 Error("NumberOfTriggers", "No block selected.");
405 return -1;
406 }
407 else
408 return fCurrentBlock->GetEntriesFast();
cbee67e7 409}
8356cc1d 410
411
69d7cf2e 412const AliHLTMUONTriggerRecord* AliHLTMUONTriggerSource::GetTrigger(Int_t triggernumber) const
8356cc1d 413{
3a682eae 414// Fetches the trigger record with the specified trigger number from
415// the current block.
416// NULL is returned if the record was not found.
417
69d7cf2e 418 DebugMsg(1, "AliHLTMUONTriggerSource::GetTrigger(" << triggernumber << ")");
8356cc1d 419
420 if (fCurrentBlock == NULL)
421 {
422 Error("GetTrigger", "No block selected.");
423 return NULL;
f086c81b 424 }
8356cc1d 425
426 // Try find the corresponding trigger record in the list of events.
427 for (Int_t i = 0; i < fCurrentBlock->GetEntriesFast(); i++)
428 {
69d7cf2e 429 AliHLTMUONTriggerRecord* current = (AliHLTMUONTriggerRecord*) fCurrentBlock->At(i);
8356cc1d 430 if (current->TriggerNumber() == triggernumber)
431 {
432 fTriggerIndex = i;
433 fCurrentTrigger = current;
434 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
435 << " , fTriggerIndex = " << fTriggerIndex
436 );
437 return current;
cbee67e7 438 }
439 }
8356cc1d 440 return NULL;
cbee67e7 441}
8356cc1d 442
443
69d7cf2e 444const AliHLTMUONTriggerRecord* AliHLTMUONTriggerSource::GetFirstTrigger() const
8356cc1d 445{
3a682eae 446// Fetches the first trigger record in the current block.
447// NULL is returned if the record was not found.
448
69d7cf2e 449 DebugMsg(1, "AliHLTMUONTriggerSource::GetFirstTrigger()");
8356cc1d 450 // Note: NumberOfTriggers() also checks if fCurrentBlock != NULL.
451 if (NumberOfTriggers() > 0)
452 {
453 fTriggerIndex = 0;
69d7cf2e 454 fCurrentTrigger = (AliHLTMUONTriggerRecord*) fCurrentBlock->At(0);
8356cc1d 455 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
456 << " , fTriggerIndex = " << fTriggerIndex
457 );
458 return fCurrentTrigger;
459 }
460 else
461 return NULL;
f086c81b 462}
8356cc1d 463
464
69d7cf2e 465Bool_t AliHLTMUONTriggerSource::MoreTriggers() const
8356cc1d 466{
3a682eae 467// Returns kTRUE if there are more triggers to iterate over.
468
f086c81b 469 return 0 <= fTriggerIndex && fTriggerIndex < NumberOfTriggers();
cbee67e7 470}
8356cc1d 471
472
69d7cf2e 473const AliHLTMUONTriggerRecord* AliHLTMUONTriggerSource::GetNextTrigger() const
8356cc1d 474{
3a682eae 475// Fetches the next trigger record in the current block.
476// NULL is returned if the record was not found.
477
69d7cf2e 478 DebugMsg(1, "AliHLTMUONTriggerSource::GetNextTrigger()");
8356cc1d 479
480 // Note: NumberOfTriggers() checks if fCurrentBlock != NULL. If it is then it returns -1
481 // and since fTriggerIndex is always >= -1 the if statement must go to the else part.
482 if (fTriggerIndex < NumberOfTriggers() - 1)
483 {
69d7cf2e 484 fCurrentTrigger = (AliHLTMUONTriggerRecord*) fCurrentBlock->At( ++fTriggerIndex );
8356cc1d 485 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
486 << " , fTriggerIndex = " << fTriggerIndex
487 );
488 return fCurrentTrigger;
489 }
490 else
491 {
492 ResetTriggerPointers();
493 return NULL;
f086c81b 494 }
495}
8356cc1d 496
497
69d7cf2e 498Int_t AliHLTMUONTriggerSource::CurrentTrigger() const
8356cc1d 499{
3a682eae 500// Returns the trigger record number for the currently selected trigger record.
501// This number corresponds to the index'th AliMUONLocalTrigger object for the
502// current event.
503// -1 is returned if no trigger record is selected.
504
8356cc1d 505 if (fCurrentTrigger != NULL)
506 {
507 return fCurrentTrigger->TriggerNumber();
508 }
509 else
510 {
511 Error("CurrentTrigger", "No trigger record selected.");
512 return -1;
cbee67e7 513 }
514}
8356cc1d 515
516
69d7cf2e 517void AliHLTMUONTriggerSource::AddEvent(Int_t eventnumber)
8356cc1d 518{
3a682eae 519// Adds a new AliEventData block to the fEventList and updates the fCurrentEvent,
520// fCurrentBlock and fCurrentTrigger pointers.
521
69d7cf2e 522 DebugMsg(1, "AliHLTMUONTriggerSource::AddEvent(" << eventnumber << ")");
8356cc1d 523 Assert( eventnumber >= 0 );
524
525 // Assume the eventnumber does not already exist in the event list.
526 fEventIndex = fEventList.GetEntriesFast();
3a682eae 527 new ( fEventList[fEventIndex] ) AliEventData(eventnumber);
528 fCurrentEvent = (AliEventData*) fEventList[fEventIndex];
8356cc1d 529
530 // Remember to reset the other pointers because the new event is empty.
531 ResetBlockPointers();
532
533 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
534 << " , fTriggerIndex = " << fTriggerIndex
535 );
cbee67e7 536}
8356cc1d 537
538
69d7cf2e 539void AliHLTMUONTriggerSource::AddBlock()
8356cc1d 540{
3a682eae 541// Adds a new block to the current event and updates fCurrentBlock and fCurrentTrigger.
542
69d7cf2e 543 DebugMsg(1, "AliHLTMUONTriggerSource::AddBlock()");
8356cc1d 544
545 if (fCurrentEvent == NULL)
546 {
547 Error("AddBlock", "No event selected.");
548 return;
f086c81b 549 }
8356cc1d 550
3a682eae 551 fBlockIndex = fCurrentEvent->Blocks().GetEntriesFast();
552 new ( fCurrentEvent->Blocks()[fBlockIndex] ) TClonesArray(AliHLTMUONTriggerRecord::Class());
553 fCurrentBlock = (TClonesArray*) fCurrentEvent->Blocks()[fBlockIndex];
8356cc1d 554
555 // Remember to reset the trigger pointer because the new block is empty.
556 ResetTriggerPointers();
557
558 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
559 << " , fTriggerIndex = " << fTriggerIndex
560 );
cbee67e7 561}
8356cc1d 562
563
69d7cf2e 564void AliHLTMUONTriggerSource::AddTrigger(const AliHLTMUONTriggerRecord& data)
8356cc1d 565{
3a682eae 566// Adds a new trigger record to the current event and block.
567// The fCurrentTrigger is updated appropriately.
568
69d7cf2e 569 DebugMsg(1, "AliHLTMUONTriggerSource::AddTrigger(" << (void*)&data << ")");
8356cc1d 570
571 if (fCurrentBlock == NULL)
572 {
573 Error("AddTrigger", "No block selected.");
574 return;
cbee67e7 575 }
8356cc1d 576
577 fTriggerIndex = fCurrentBlock->GetEntriesFast();
69d7cf2e 578 new ( (*fCurrentBlock)[fTriggerIndex] ) AliHLTMUONTriggerRecord(data);
579 fCurrentTrigger = (AliHLTMUONTriggerRecord*) (*fCurrentBlock)[fTriggerIndex];
8356cc1d 580
581 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
582 << " , fTriggerIndex = " << fTriggerIndex
583 );
cbee67e7 584}
8356cc1d 585
586
69d7cf2e 587Bool_t AliHLTMUONTriggerSource::FileAndFolderOk(AliMUONDataInterface* data)
8356cc1d 588{
3a682eae 589// Checks if the file and folder names correspond to this AliHLTMUONTriggerSource's
590// file and folder names. kTRUE is returned if they do.
591// If the file and folder names are empty then they are assigned the names
592// as found in the data interface and kTRUE is returned.
593
8356cc1d 594 if (fFilename == "")
595 {
596 // Nothing filled yet so set the file and folder names.
597 fFilename = data->CurrentFile();
598 fFoldername = data->CurrentFolder();
599 return kTRUE;
f086c81b 600 }
8356cc1d 601
602 if ( fFilename != data->CurrentFile() )
603 {
604 Error( "FileAndFolderOk",
605 "The Trigger source already contains data from file '%s', cannot add data from file '%s'",
606 fFilename.Data(), data->CurrentFile().Data()
607 );
608 return kFALSE;
f086c81b 609 }
8356cc1d 610
611 if ( fFoldername != data->CurrentFolder() )
612 {
613 Error( "FileAndFolderOk",
614 "The Trigger source already contains data from folder '%s', cannot add data from folder '%s'",
615 fFoldername.Data(), data->CurrentFolder().Data()
616 );
617 return kFALSE;
f086c81b 618 }
8356cc1d 619
620 return kTRUE;
cbee67e7 621}
8356cc1d 622
623
69d7cf2e 624void AliHLTMUONTriggerSource::AddEventFrom(AliMUONDataInterface* data, AliMUON* module, Int_t event)
8356cc1d 625{
3a682eae 626// Adds the whole event from the data interface to the internal data structures.
627// It is assumed that FileAndFolderOk(data) returns true just before calling
628// this method.
629
8356cc1d 630 if ( data->GetEvent(event) )
631 {
632 AddEvent(event);
633
634 AddBlock();
635 UInt_t currentblocksize = 0;
69d7cf2e 636 AliHLTMUONTriggerRecord trigdata;
8356cc1d 637
638 switch (fDataToUse)
639 {
3a682eae 640 case kFromHits:
8356cc1d 641 for (Int_t track = 0; track < data->NumberOfTracks(); track++)
642 {
f086c81b 643 if ( ! FillTriggerFromHits(data, track, trigdata) )
8356cc1d 644 continue; // Continue if unable to find hits.
645
646 if (InFillRegion(trigdata))
647 {
648 AddTrigger(trigdata);
649
650 // Create a new block if we reached the maximum block size.
651 if ( ++currentblocksize == fMaxBlockSize )
652 {
653 AddBlock();
654 currentblocksize = 0;
f086c81b 655 }
656 }
657 }
8356cc1d 658 break;
659
3a682eae 660 case kFromLocalTriggers:
8356cc1d 661 Assert( module != NULL );
3a682eae 662 DebugMsg(4, "Taking kFromLocalTriggers branch...");
8356cc1d 663 for (Int_t i = 0; i < data->NumberOfLocalTriggers(); i++)
664 {
665 DebugMsg(4, "for loop: i = " << i);
666 AliMUONLocalTrigger* lt = data->LocalTrigger(i);
667 FillTriggerFromLocalTrigger(lt, module, trigdata);
668 trigdata.TriggerNumber(i);
669
670 if (InFillRegion(trigdata))
671 {
672 AddTrigger(trigdata);
673
674 // Create a new block if we reached the maximum block size.
675 if ( ++currentblocksize == fMaxBlockSize )
676 {
677 AddBlock();
678 currentblocksize = 0;
f086c81b 679 }
680 }
681 }
8356cc1d 682 break;
683
684 default:
685 Error("AddChamberFrom", "fDataToUse is not set to a valid value.");
cbee67e7 686 }
687 } // Loop on events.
688}
8356cc1d 689
690
69d7cf2e 691void AliHLTMUONTriggerSource::AddTriggerFrom(AliMUONDataInterface* data, AliMUON* module, Int_t trigger)
8356cc1d 692{
3a682eae 693// Adds the specified trigger record from the given data interface.
694// The data interface should be initialised correctly, that is the event
695// should already be selected before calling this method.
696
8356cc1d 697 DebugMsg(1, "Entering AddTriggerFrom");
698
69d7cf2e 699 AliHLTMUONTriggerRecord trigdata;
8356cc1d 700
701 switch (fDataToUse)
702 {
3a682eae 703 case kFromHits:
8356cc1d 704 {
705 // Note: in this case we treat the trigger parameter as a track number.
f086c81b 706 if ( ! FillTriggerFromHits(data, trigger, trigdata) )
8356cc1d 707 return; // Continue if unable to find hits.
708 }
709 break;
710
3a682eae 711 case kFromLocalTriggers:
8356cc1d 712 {
713 Assert( module != NULL );
714 AliMUONLocalTrigger* lt = data->LocalTrigger(trigger);
715 FillTriggerFromLocalTrigger(lt, module, trigdata);
716 trigdata.TriggerNumber(trigger);
717 }
718 break;
719
720 default:
721 Error("AddTriggerFrom", "fDataToUse is not set to a valid value.");
722 return;
f086c81b 723 }
8356cc1d 724
725 AddTrigger(trigdata);
726
727 DebugMsg(1, "Leaving AddTriggerFrom");
cbee67e7 728}
8356cc1d 729
730
3a682eae 731Bool_t AliHLTMUONTriggerSource::InFillRegion(const AliHLTMUONTriggerRecord& data) const
8356cc1d 732{
3a682eae 733// Checks to see if the specified trigger record is in the chamber region
734// we want to fill from.
735// kTRUE is returned if (x, y) is in the region, and kFALSE otherwise.
736
8356cc1d 737 switch (fAreaToUse)
738 {
3a682eae 739 case kFromWholePlane: return kTRUE;
26538635 740 case kFromLeftHalfPlane: return data.Station1Point().X() <= 0;
741 case kFromRightHalfPlane: return data.Station1Point().X() > 0;
8356cc1d 742
743 default:
744 Error("InFillRegion", "fAreaToUse is not set to a valid value.");
745 return kFALSE;
cbee67e7 746 }
747}
8356cc1d 748
749
69d7cf2e 750void AliHLTMUONTriggerSource::FillTriggerFromLocalTrigger(
751 AliMUONLocalTrigger* trigger, AliMUON* module, AliHLTMUONTriggerRecord& record
8356cc1d 752 )
753{
3a682eae 754// Fills the trigger data from the AliMUONLocalTrigger object.
755// if the fUseLookupTable is set to true then we use the L0 lookup table to
756// fill the Pt value otherwise we use the PtCal method in AliMUONTriggerCircuit.
757// Note the fTriggerNumber parameter is not filled in to 'record'.
758
8356cc1d 759 DebugMsg(2, "Creating TriggerRecord from AliMUONLocalTrigger object: " << (void*)trigger );
760 AliMUONTriggerCircuit& circuit = module->TriggerCircuit(trigger->LoCircuit());
761
762 // Get the sign of the particle the sign of the muon.
763 if (trigger->LoLpt() == 1 || trigger->LoHpt() == 1 || trigger->LoApt() == 1)
764 {
765 record.ParticleSign(-1);
766 }
767 else
768 if (trigger->LoLpt() == 2 || trigger->LoHpt() == 2 || trigger->LoApt() == 2)
769 {
770 record.ParticleSign(+1);
771 }
772 else
773 {
774 record.ParticleSign(0);
f086c81b 775 }
8356cc1d 776 DebugMsg(2, "Particle sign = " << record.ParticleSign() );
777
778 // Compute the transverse momentum.
779 if (fUseLookupTable)
780 {
781 // TODO: implement use of the L0 lookup table.
782 Error("FillTriggerFromLocalTrigger", "Use of L0 lookup table is not yet implemented!");
783 }
784 else
785 {
786 Float_t pt = circuit.PtCal( trigger->LoStripX(), trigger->LoDev(), trigger->LoStripY() );
787 record.Pt(pt);
f086c81b 788 }
8356cc1d 789 DebugMsg(2, "Pt = " << record.Pt() );
790
791 // Build the impact points.
26538635 792 record.Station1Point().X() = circuit.GetX11Pos(trigger->LoStripY());
793 record.Station1Point().Y() = circuit.GetY11Pos(trigger->LoStripX());
794 record.Station2Point().Y() = circuit.GetY21Pos(trigger->LoStripX() + trigger->LoDev() + 1); // Why + 1?
795 record.Station2Point().X() = AliMUONConstants::DefaultChamberZ(12) * record.Station1Point().X() / AliMUONConstants::DefaultChamberZ(10);
796 DebugMsg(2, "fStation1x = " << record.Station1Point().X());
797 DebugMsg(2, "fStation1y = " << record.Station1Point().Y());
798 DebugMsg(2, "fStation2x = " << record.Station2Point().X());
799 DebugMsg(2, "fStation2y = " << record.Station2Point().Y());
cbee67e7 800}
8356cc1d 801
802
69d7cf2e 803Bool_t AliHLTMUONTriggerSource::FillTriggerFromHits(
804 AliMUONDataInterface* data, Int_t track, AliHLTMUONTriggerRecord& record
805 )
8356cc1d 806{
3a682eae 807// Fills the TriggerRecord structure from AliMUONHit objects.
808// The hits on the last 4 chambers are used (i.e. chambers 11 to 14).
809// kTRUE is returned if the structure was filled successfully.
810
8356cc1d 811 DebugMsg(2, "Creating TriggerRecord from hits on track: " << track );
812
813 Float_t x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
98af1577 814#ifndef __alpha
8f6d5890 815#ifndef __sun
f086c81b 816 x1 = y1 = z1 = x2 = y2 = z2 = x3 = y3 = z3 = x4 = y4 = z4 = nanf("");
cbee67e7 817#else
818 x1 = y1 = z1 = x2 = y2 = z2 = x3 = y3 = z3 = x4 = y4 = z4 = 0;
819#endif
98af1577 820#else
821 x1 = y1 = z1 = x2 = y2 = z2 = x3 = y3 = z3 = x4 = y4 = z4 = FLT_QNAN;
822#endif
8356cc1d 823 // Find the hit that corresponds to chambers. 11 to 14. We can ignore any
824 // hits above the first 14. If there are that many it means the particle
825 // is cycling in the detector.
f086c81b 826 for (Int_t i = 0; i < data->NumberOfHits(track) && i < 14; i++)
8356cc1d 827 {
828 AliMUONHit* h = data->Hit(track, i);
829
830 // Note AliMUONHit::Chamber() returns a value in the range 1..14
831 // It is also important to have positive Z coordinates and under the
832 // new version of Aliroot we use GEANT coordinates which return
833 // negatives. So we use the fabs routine.
834 switch ( h->Chamber() )
835 {
836 case 11: x1 = h->X(); y1 = h->Y(); z1 = (Float_t)fabs(h->Z()); break;
837 case 12: x2 = h->X(); y2 = h->Y(); z2 = (Float_t)fabs(h->Z()); break;
838 case 13: x3 = h->X(); y3 = h->Y(); z3 = (Float_t)fabs(h->Z()); break;
839 case 14: x4 = h->X(); y4 = h->Y(); z4 = (Float_t)fabs(h->Z()); break;
f086c81b 840 }
841 }
8356cc1d 842 DebugMsg(4, "Found: x1 = " << x1 << ", y1 = " << y1 << ", z1 = " << z1);
843 DebugMsg(4, "Found: x2 = " << x2 << ", y2 = " << y2 << ", z2 = " << z2);
844 DebugMsg(4, "Found: x3 = " << x3 << ", y3 = " << y3 << ", z3 = " << z3);
845 DebugMsg(4, "Found: x4 = " << x4 << ", y4 = " << y4 << ", z4 = " << z4);
846
847 // Get a coordinate for station 1, perferably from chamber 11 otherwise
848 // use hits from chamber 12.
f086c81b 849 if ( ! TMath::IsNaN(x1))
8356cc1d 850 {
26538635 851 record.Station1Point().X() = x1;
852 record.Station1Point().Y() = y1;
8356cc1d 853 DebugMsg(3, "Using value from chamber 11: x1 = " << x1 << ", y1 = " << y1 << ", z1 = " << z1 );
854 }
f086c81b 855 else if ( ! TMath::IsNaN(x2))
8356cc1d 856 {
26538635 857 record.Station1Point().X() = x2;
858 record.Station1Point().Y() = y2;
8356cc1d 859 z1 = z2;
860 DebugMsg(3, "Using value from chamber 12: x2 = " << x2 << ", y2 = " << y2 << ", z2 = " << z2 );
861 }
862 else
863 {
864 // Return false if we could not find any hits on chambers 11 or 12.
865 Warning("FillTriggerFromHits", "Could not find any hits on chambers 11 and 12.");
866 return kFALSE;
f086c81b 867 }
8356cc1d 868
869 // Get a coordinate for station 2, perferably from chamber 13 otherwise
870 // use hits from chamber 14.
f086c81b 871 if ( ! TMath::IsNaN(x3))
8356cc1d 872 {
26538635 873 record.Station2Point().X() = x3;
874 record.Station2Point().Y() = y3;
8356cc1d 875 z2 = z3;
876 DebugMsg(3, "Using value from chamber 13: x3 = " << x3 << ", y3 = " << y3 << ", z3 = " << z3 );
877 }
f086c81b 878 else if ( ! TMath::IsNaN(x4))
8356cc1d 879 {
26538635 880 record.Station2Point().X() = x4;
881 record.Station2Point().Y() = y4;
8356cc1d 882 z2 = z4;
883 DebugMsg(3, "Using value from chamber 14: x4 = " << x4 << ", y4 = " << y4 << ", z4 = " << z4 );
884 }
885 else
886 {
887 // Return false if we could not find any hits on chambers 13 or 14.
888 Warning("FillTriggerFromHits", "Could not find any hits on chambers 13 and 14.");
889 return kFALSE;
f086c81b 890 }
8356cc1d 891
892 record.TriggerNumber(track);
893
894 // Get the sign of the particle.
895 Int_t particlecode = (Int_t) data->Hit(track, 0)->Particle();
896 DebugMsg(3, "particle code = " << particlecode);
897 TDatabasePDG* pdb = TDatabasePDG::Instance();
898 TParticlePDG* pdata = pdb->GetParticle(particlecode);
899 if (pdata->Charge() < 0)
900 record.ParticleSign(-1);
901 else if (pdata->Charge() > 0)
902 record.ParticleSign(+1);
903 else
904 record.ParticleSign(0);
905 DebugMsg(3, "Particle sign = " << record.ParticleSign());
906
26538635 907 DebugMsg(3, "Calculating Pt: x1 = " << record.Station1Point().X()
908 << ", y1 = " << record.Station1Point().Y()
909 << ", y2 = " << record.Station2Point().Y()
8356cc1d 910 << ", z1 = " << z1
911 << ", z2 = " << z2
912 );
913 // Calculate and assign the transverse momentum.
69d7cf2e 914 Float_t pt = AliHLTMUONCoreCalculatePt(
26538635 915 record.Station1Point().X(),
916 record.Station1Point().Y(), record.Station2Point().Y(),
8356cc1d 917 z1, z2
918 );
919 record.Pt(pt);
920
921 DebugMsg(3, "Pt = " << record.Pt());
922
923 return kTRUE;
cbee67e7 924}
8356cc1d 925
926
69d7cf2e 927Bool_t AliHLTMUONTriggerSource::FetchAliMUON(AliMUON*& module)
8356cc1d 928{
3a682eae 929// Fetches the AliMUON module from the AliRun global object. AliRun will be loaded
930// by the runloader if it has not yet been loaded. In such a case the AliRun object
931// will also we unloaded when we are done with it.
932// kTRUE is returned if no error occured and kFALSE otherwise.
933// Note that if fDataToUse is set to kFromHits then gAlice is not loaded and 'module'
934// will be left untouched. The method will still return kTRUE however since this is
935// not an error. We do not need the AliMUON module when filling from hits.
936
8356cc1d 937 // Check if we even need the MUON module. Not having to load it will
938 // save a lot of loading time for AliRoot.
3a682eae 939 if (fDataToUse == kFromHits)
8356cc1d 940 {
941 // Make sure we do not attempt to unload gAlice in FinishedWithAliMUON,
942 // by setting the fHadToLoadgAlice to false.
943 fHadToLoadgAlice = kFALSE;
944 return kTRUE;
f086c81b 945 }
8356cc1d 946
947 AliRunLoader* runloader = AliRunLoader::GetRunLoader();
948 if ( runloader == NULL )
949 {
950 Error("FetchAliMUON", "AliRunLoader not initialised!");
951 return kFALSE;
f086c81b 952 }
8356cc1d 953
954 // Try fetch the AliRun object. If it is not found then try load it using
955 // the runloader.
956 AliRun* alirun = runloader->GetAliRun();
957 if (alirun == NULL)
958 {
959 if (runloader->LoadgAlice() != 0)
960 {
961 // Error.
962 DebugMsg(1, "Leaving FillFrom(AliMUONDataInterface*)");
963 return kFALSE;
f086c81b 964 }
8356cc1d 965 fHadToLoadgAlice = kTRUE;
966 alirun = runloader->GetAliRun();
967 }
968 else
969 fHadToLoadgAlice = kFALSE;
970
971 // Get the MUON module pointer and return it.
972 module = dynamic_cast<AliMUON*>( alirun->GetModule("MUON") );
973 return kTRUE;
cbee67e7 974}
8356cc1d 975
976
69d7cf2e 977void AliHLTMUONTriggerSource::FinishedWithAliMUON()
8356cc1d 978{
3a682eae 979// After one is finished with the AliMUON object returned by GetAliMUON, one
980// should call this method.
981// If the gAlice object was loaded by GetAliMUON then it will be unloaded at
982// this point, otherwise nothing is done.
983
8356cc1d 984 // Only unload the gAlice object if we had to load it ourselves.
985 if (fHadToLoadgAlice)
986 AliRunLoader::GetRunLoader()->UnloadgAlice();
cbee67e7 987}
8356cc1d 988
989
69d7cf2e 990void AliHLTMUONTriggerSource::ResetAllPointers() const
8356cc1d 991{
3a682eae 992// Sets all the current pointers to NULL and indices to -1.
993
8356cc1d 994 fEventIndex = -1;
995 fCurrentEvent = NULL;
996 fBlockIndex = -1;
997 fCurrentBlock = NULL;
998 fTriggerIndex = -1;
999 fCurrentTrigger = NULL;
1000 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
1001 << " , fTriggerIndex = " << fTriggerIndex
1002 );
cbee67e7 1003}
8356cc1d 1004
1005
69d7cf2e 1006void AliHLTMUONTriggerSource::ResetBlockPointers() const
8356cc1d 1007{
3a682eae 1008// Sets the block and trigger pointers to NULL and indices to -1.
1009
8356cc1d 1010 fBlockIndex = -1;
1011 fCurrentBlock = NULL;
1012 fTriggerIndex = -1;
1013 fCurrentTrigger = NULL;
1014 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
1015 << " , fTriggerIndex = " << fTriggerIndex
1016 );
cbee67e7 1017}
8356cc1d 1018
1019
69d7cf2e 1020void AliHLTMUONTriggerSource::ResetTriggerPointers() const
8356cc1d 1021{
3a682eae 1022// Sets just the current trigger record pointer to NULL and index to -1.
1023
8356cc1d 1024 fTriggerIndex = -1;
1025 fCurrentTrigger = NULL;
1026 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
1027 << " , fTriggerIndex = " << fTriggerIndex
1028 );
cbee67e7 1029}
8356cc1d 1030
1031
3a682eae 1032AliHLTMUONTriggerSource::AliEventData::AliEventData() : fBlocks(TClonesArray::Class())
8356cc1d 1033{
1034 fEventNumber = -1;
cbee67e7 1035}
8356cc1d 1036
1037
3a682eae 1038AliHLTMUONTriggerSource::AliEventData::AliEventData(Int_t eventnumber)
8356cc1d 1039 : fBlocks(TClonesArray::Class())
1040{
3a682eae 1041// Create a new event data block with specified event number.
1042
8356cc1d 1043 fEventNumber = eventnumber;
1044
1045 // If the following is not set then we do not write the fBlocks properly.
1046 fBlocks.BypassStreamer(kFALSE);
cbee67e7 1047}
8356cc1d 1048
1049
3a682eae 1050AliHLTMUONTriggerSource::AliEventData::~AliEventData()
8356cc1d 1051{
12ab84fc 1052 //fBlocks.Clear("C"); // Done in fBlocks destructor
cbee67e7 1053}
8356cc1d 1054