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