]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDHeader.cxx
ALIROOT-5643 Detector AD. The list of detectors was reordered an EMPTY detector
[u/mrichter/AliRoot.git] / STEER / ESD / AliESDHeader.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 //-------------------------------------------------------------------------
17 //                      Implementation of   Class AliESDHeader
18 //   Header data
19 //   for the ESD   
20 //   Origin: Christian Klein-Boesing, CERN, Christian.Klein-Boesing@cern.ch 
21 //-------------------------------------------------------------------------
22
23 #include "AliESDHeader.h"
24 #include "AliTriggerScalersESD.h"
25 #include "AliTriggerScalersRecordESD.h"
26 #include "AliTriggerIR.h"
27 #include "AliTriggerConfiguration.h"
28 #include "AliLog.h" 
29
30 ClassImp(AliESDHeader)
31
32 //______________________________________________________________________________
33 AliESDHeader::AliESDHeader() :
34   AliVHeader(),
35   fTriggerMask(0),
36   fTriggerMaskNext50(0),
37   fOrbitNumber(0),
38   fTimeStamp(0),
39   fEventType(0),
40   fEventSpecie(0),
41   fPeriodNumber(0),
42   fEventNumberInFile(0),
43   fBunchCrossNumber(0),
44   fTriggerCluster(0),
45   fL0TriggerInputs(0),
46   fL1TriggerInputs(0),
47   fL2TriggerInputs(0),
48   fTriggerScalers(),
49   fTriggerScalersDeltaEvent(),
50   fTriggerScalersDeltaRun(),
51   fTriggerInputsNames(kNTriggerInputs),
52   fCTPConfig(NULL),
53   fIRBufferArray(),
54   fIRInt2InteractionsMap(0),
55   fIRInt1InteractionsMap(0)
56 {
57   // default constructor
58
59   SetName("AliESDHeader");
60   for(Int_t i = 0; i<kNMaxIR ; i++) fIRArray[i] = 0;
61   fTriggerInputsNames.SetOwner(kTRUE);
62   for (Int_t itype=0; itype<3; itype++) fTPCNoiseFilterCounter[itype]=0;
63 }
64
65 AliESDHeader::~AliESDHeader() 
66 {
67   // destructor
68   for(Int_t i=0;i<kNMaxIR;i++)if(fIRArray[i])delete fIRArray[i];
69   delete fCTPConfig;
70
71   fIRBufferArray.Delete();
72 }
73
74
75 AliESDHeader::AliESDHeader(const AliESDHeader &header) :
76   AliVHeader(header),
77   fTriggerMask(header.fTriggerMask),
78   fTriggerMaskNext50(header.fTriggerMaskNext50),
79   fOrbitNumber(header.fOrbitNumber),
80   fTimeStamp(header.fTimeStamp),
81   fEventType(header.fEventType),
82   fEventSpecie(header.fEventSpecie),
83   fPeriodNumber(header.fPeriodNumber),
84   fEventNumberInFile(header.fEventNumberInFile),
85   fBunchCrossNumber(header.fBunchCrossNumber),
86   fTriggerCluster(header.fTriggerCluster),
87   fL0TriggerInputs(header.fL0TriggerInputs),
88   fL1TriggerInputs(header.fL1TriggerInputs),
89   fL2TriggerInputs(header.fL2TriggerInputs),
90   fTriggerScalers(header.fTriggerScalers),
91   fTriggerScalersDeltaEvent(header.fTriggerScalersDeltaEvent),
92   fTriggerScalersDeltaRun(header.fTriggerScalersDeltaRun),
93   fTriggerInputsNames(TObjArray(kNTriggerInputs)),
94   fCTPConfig(header.fCTPConfig),
95   fIRBufferArray(),
96   fIRInt2InteractionsMap(header.fIRInt2InteractionsMap),
97   fIRInt1InteractionsMap(header.fIRInt1InteractionsMap)
98 {
99   // copy constructor
100   for(Int_t i = 0; i<kNMaxIR ; i++) {
101     if(header.fIRArray[i])fIRArray[i] = new AliTriggerIR(*header.fIRArray[i]);
102     else fIRArray[i]=0;
103   }
104   for(Int_t i = 0; i < kNTriggerInputs; i++) {
105     TNamed *str = (TNamed *)((header.fTriggerInputsNames).At(i));
106     if (str) fTriggerInputsNames.AddAt(new TNamed(*str),i);
107   }
108
109   for(Int_t i = 0; i < (header.fIRBufferArray).GetEntries(); ++i) {
110     AliTriggerIR *ir = (AliTriggerIR*)((header.fIRBufferArray).At(i));
111     if (ir) fIRBufferArray.Add(new AliTriggerIR(*ir));
112   }
113   for (Int_t itype=0; itype<3; itype++) fTPCNoiseFilterCounter[itype]=header.fTPCNoiseFilterCounter[itype];
114 }
115
116 AliESDHeader& AliESDHeader::operator=(const AliESDHeader &header)
117
118   // assigment operator
119   if(this!=&header) {
120     AliVHeader::operator=(header);
121     fTriggerMask = header.fTriggerMask;
122     fTriggerMaskNext50 = header.fTriggerMaskNext50;
123     fOrbitNumber = header.fOrbitNumber;
124     fTimeStamp = header.fTimeStamp;
125     fEventType = header.fEventType;
126     fEventSpecie = header.fEventSpecie;
127     fPeriodNumber = header.fPeriodNumber;
128     fEventNumberInFile = header.fEventNumberInFile;
129     fBunchCrossNumber = header.fBunchCrossNumber;
130     fTriggerCluster = header.fTriggerCluster;
131     fL0TriggerInputs = header.fL0TriggerInputs;
132     fL1TriggerInputs = header.fL1TriggerInputs;
133     fL2TriggerInputs = header.fL2TriggerInputs;
134     fTriggerScalers = header.fTriggerScalers;
135     fTriggerScalersDeltaEvent = header.fTriggerScalersDeltaEvent;
136     fTriggerScalersDeltaRun = header.fTriggerScalersDeltaRun;
137     fIRInt2InteractionsMap = header.fIRInt2InteractionsMap;
138     fIRInt1InteractionsMap = header.fIRInt1InteractionsMap;
139
140     delete fCTPConfig;
141     fCTPConfig = header.fCTPConfig;
142
143     fTriggerInputsNames.Clear();
144     for(Int_t i = 0; i < kNTriggerInputs; i++) {
145       TNamed *str = (TNamed *)((header.fTriggerInputsNames).At(i));
146       if (str) fTriggerInputsNames.AddAt(new TNamed(*str),i);
147     }
148     for(Int_t i = 0; i<kNMaxIR ; i++) {
149       delete fIRArray[i];
150        if(header.fIRArray[i])fIRArray[i] = new AliTriggerIR(*header.fIRArray[i]);
151        else fIRArray[i]=0;
152     }
153
154     fIRBufferArray.Delete();
155     for(Int_t i = 0; i < (header.fIRBufferArray).GetEntries(); ++i) {
156       AliTriggerIR *ir = (AliTriggerIR*)((header.fIRBufferArray).At(i));
157       if (ir) fIRBufferArray.Add(new AliTriggerIR(*ir));
158     }
159     for (Int_t itype=0; itype<3; itype++) fTPCNoiseFilterCounter[itype]=header.fTPCNoiseFilterCounter[itype];
160   }
161   return *this;
162 }
163
164 void AliESDHeader::Copy(TObject &obj) const 
165 {  
166   // this overwrites the virtual TOBject::Copy()
167   // to allow run time copying without casting
168   // in AliESDEvent
169
170   if(this==&obj)return;
171   AliESDHeader *robj = dynamic_cast<AliESDHeader*>(&obj);
172   if(!robj)return; // not an AliESDHeader
173   *robj = *this;
174
175 }
176 //______________________________________________________________________________
177 void AliESDHeader::Reset()
178 {
179   // reset all data members
180   fTriggerMask       = 0;
181   fTriggerMaskNext50 = 0;
182   fOrbitNumber       = 0;
183   fTimeStamp         = 0;
184   fEventType         = 0;
185   fEventSpecie       = 0;
186   fPeriodNumber      = 0;
187   fEventNumberInFile = 0;
188   fBunchCrossNumber  = 0;
189   fTriggerCluster    = 0;
190   fL0TriggerInputs   = 0;
191   fL1TriggerInputs   = 0;
192   fL2TriggerInputs   = 0;
193   fTriggerScalers.Reset();
194   fTriggerScalersDeltaEvent.Reset();
195   fTriggerScalersDeltaRun.Reset();
196   fTriggerInputsNames.Clear();
197
198   fIRInt2InteractionsMap.ResetAllBits();
199   fIRInt1InteractionsMap.ResetAllBits();
200
201   delete fCTPConfig;
202   fCTPConfig = 0;
203   for(Int_t i=0;i<kNMaxIR;i++)if(fIRArray[i]){
204    delete fIRArray[i];
205    fIRArray[i]=0;
206   }
207   for (Int_t itype=0; itype<3; itype++) fTPCNoiseFilterCounter[itype]=0;
208   fIRBufferArray.Delete();
209 }
210 //______________________________________________________________________________
211 Bool_t AliESDHeader::AddTriggerIR(const AliTriggerIR* ir)
212 {
213   // Add an IR object into the array
214   // of IRs in the ESD header
215
216  fIRBufferArray.Add(new AliTriggerIR(*ir));
217
218  return kTRUE;
219 }
220 //______________________________________________________________________________
221 void AliESDHeader::Print(const Option_t *) const
222 {
223   // Print some data members
224   printf("Event # %d in file Bunch crossing # %d Orbit # %d Trigger %lld %lld\n",
225          GetEventNumberInFile(),
226          GetBunchCrossNumber(),
227          GetOrbitNumber(),
228          GetTriggerMask(),
229          GetTriggerMaskNext50());
230          printf("List of the active trigger inputs: ");
231          for(Int_t i = 0; i < kNTriggerInputs; i++) {
232            TNamed *str = (TNamed *)((fTriggerInputsNames).At(i));
233            if (str) printf("%i %s ",i,str->GetName());
234          }
235          printf("\n");
236 }
237
238 //______________________________________________________________________________
239 void AliESDHeader::SetActiveTriggerInputs(const char*name, Int_t index)
240 {
241   // Fill the active trigger inputs names
242   // into the corresponding fTriggerInputsNames (TObjArray of TNamed)
243   if (index >= kNTriggerInputs || index < 0) {
244     AliError(Form("Index (%d) is outside the allowed range (0,59)!",index));
245     return;
246   }
247
248   fTriggerInputsNames.AddAt(new TNamed(name,NULL),index);
249 }
250 //______________________________________________________________________________
251 const char* AliESDHeader::GetTriggerInputName(Int_t index, Int_t trglevel) const
252 {
253   // Get the trigger input name
254   // at the specified position in the trigger mask and trigger level (0,1,2)
255   TNamed *trginput = 0;
256   if (trglevel == 0) trginput = (TNamed *)fTriggerInputsNames.At(index);
257   if (trglevel == 1) trginput = (TNamed *)fTriggerInputsNames.At(index+24);  
258   if (trglevel == 2) trginput = (TNamed *)fTriggerInputsNames.At(index+48); 
259   if (trginput) return trginput->GetName();
260   else return "";
261 }
262 //______________________________________________________________________________
263 TString AliESDHeader::GetActiveTriggerInputs() const
264 {
265   // Returns the list with the names of the active trigger inputs
266   TString trginputs;
267   for(Int_t i = 0; i < kNTriggerInputs; i++) {
268     TNamed *str = (TNamed *)((fTriggerInputsNames).At(i));
269     if (str) {
270       trginputs += " ";
271       trginputs += str->GetName();
272       trginputs += " ";
273     }
274   }
275
276   return trginputs;
277 }
278 //______________________________________________________________________________
279 TString AliESDHeader::GetFiredTriggerInputs() const
280 {
281   // Returns the list with the names of the fired trigger inputs
282   TString trginputs;
283   for(Int_t i = 0; i < kNTriggerInputs; i++) {
284       TNamed *str = (TNamed *)((fTriggerInputsNames.At(i)));
285       if (i < 24 && (fL0TriggerInputs & (1ul << i))) {
286         if (str) {
287           trginputs += " ";
288           trginputs += str->GetName();
289           trginputs += " ";
290         }
291       }
292       if (i >= 24 && i < 48 && (fL1TriggerInputs & (1ul << (i-24)))) {
293         if (str) {
294           trginputs += " ";
295           trginputs += str->GetName();
296           trginputs += " ";
297         }
298       }
299       if (i >= 48 && (fL2TriggerInputs & (1u << (i-48)))) {
300         if (str) {
301           trginputs += " ";
302           trginputs += str->GetName();
303           trginputs += " ";
304         }
305       }
306
307   }
308   return trginputs;
309 }
310 //______________________________________________________________________________
311 Bool_t AliESDHeader::IsTriggerInputFired(const char *name) const
312 {
313   // Checks if the trigger input is fired 
314  
315   TNamed *trginput = (TNamed *)fTriggerInputsNames.FindObject(name);
316   if (!trginput) return kFALSE;
317
318   Int_t inputIndex = fTriggerInputsNames.IndexOf(trginput);
319   if (inputIndex < 0) return kFALSE;
320   
321   if (fL0TriggerInputs & (1lu << inputIndex)) return kTRUE;
322   else if (fL1TriggerInputs & (1lu << (inputIndex-24))) return kTRUE;
323   else if (fL2TriggerInputs & (1u << (inputIndex-48))) return kTRUE;
324   else return kFALSE;
325 }
326 //________________________________________________________________________________
327 Int_t  AliESDHeader::GetTriggerIREntries(Int_t int1, Int_t int2, Float_t deltaTime) const
328 {
329   // returns number of IR-s within time window deltaTime
330   // all possible combinations of int1 and int2 int1 - zdc bit, int2 v0 bit
331   //
332   const AliTriggerIR *IR;
333   // triggered event 
334   Int_t nIR = GetTriggerIREntries();
335   UInt_t orbit1 = GetOrbitNumber();
336   const Double_t ot=0.0889218; //orbit time msec
337   Float_t timediff; // time difference between orbits (msec)
338   //
339   Int_t nofIR;
340   nofIR=0;
341   // loop over IR-s
342     for(Int_t i=0;i<nIR;i++){//1
343       IR=GetTriggerIR(i);
344       //
345       UInt_t orbit2 = IR->GetOrbit();
346       timediff = (orbit2<=orbit1) ? (Float_t)((orbit1-orbit2))*ot : 
347         (Float_t)((16777215-orbit1+orbit2))*ot;
348       if (timediff>deltaTime) continue; //timediff outside time window
349       if((int1&int2) == -1){ //ignore both bits, just count IR-s within time window
350         nofIR++;
351         continue;
352       }
353       // now check if int1, int2 bits are set
354       UInt_t nw = IR->GetNWord();
355       Bool_t *bint1 = IR->GetInt1s();
356       Bool_t *bint2 = IR->GetInt2s();
357       //
358       Int_t flag1,flag2;
359       flag1=0;
360       flag2=0;
361       for(UInt_t j=0;j<nw;j++){//2
362         if(bint1[j]) flag1=1; // at least one int1 set
363         if(bint2[j]) flag2=1; //  at least one int2 set
364         //printf("IR %d, bint1 %d, bint2 %d\n",i,bint1[j],bint2[j]);
365       }//2
366       // checking combinations
367       //
368       
369       if((flag1*int1*flag2*int2)==1){// int1=1 & int2=1  
370           nofIR++;
371           continue;       
372       }
373       if(int1 == -1){// ignore int1
374         if(flag2&int2){// int2=1
375           nofIR++;
376           continue;
377         }
378         else if (!flag2&!int2){ //int2=0 
379           nofIR++;
380           continue;          
381         }
382       }
383       
384       if(int2 ==-1){//ignore int2
385         if(flag1&int1){//int1=1
386           nofIR++;
387           continue;  
388         }
389         else if(!flag1&!int1){ //int1=0
390           nofIR++;
391           continue;  
392         }
393       }
394       
395       if((flag1*int1)&!flag2&!int2){// int1=1, int2=0
396           nofIR++;
397           continue;  
398       }
399       
400       if((int2*flag2)&!int1&!flag1){// int1=0, int2=1
401           nofIR++;
402           continue;  
403       } 
404          
405       
406
407     }//1
408   
409     return nofIR;
410 }
411 //__________________________________________________________________________
412 TObjArray AliESDHeader::GetIRArray(Int_t int1, Int_t int2, Float_t deltaTime) const
413 {
414   //
415   // returns an array of IR-s within time window deltaTime
416   // all possible combinations of int1 and int2 int1 - zdc bit, int2 v0 bit
417   //
418   const AliTriggerIR *IR;
419   TObjArray arr;
420   // triggered event 
421   Int_t nIR = GetTriggerIREntries();
422   UInt_t orbit1 = GetOrbitNumber();
423   const Double_t ot=0.0889218; //orbit time msec
424   Float_t timediff; // time difference between orbits (msec)
425   //
426   // loop over IR-s
427     for(Int_t i=0;i<nIR;i++){//1
428       IR=GetTriggerIR(i);
429       //
430       UInt_t orbit2 = IR->GetOrbit();
431       timediff = (orbit2<=orbit1) ? (Float_t)((orbit1-orbit2))*ot : 
432         (Float_t)((16777215-orbit1+orbit2))*ot;
433       if (timediff>deltaTime) continue; //timediff outside time window
434       if((int1&int2) == -1){ //ignore both bits, just count IR-s within time window
435         arr.Add((AliTriggerIR*)IR); //add this IR
436         continue;
437       }
438       // now check if int1, int2 bits are set
439       UInt_t nw = IR->GetNWord();
440       Bool_t *bint1 = IR->GetInt1s();
441       Bool_t *bint2 = IR->GetInt2s();
442       //
443       Int_t flag1,flag2;
444       flag1=0;
445       flag2=0;
446       for(UInt_t j=0;j<nw;j++){//2
447         if(bint1[j]) flag1=1; // at least one int1 set
448         if(bint2[j]) flag2=1; //  at least one int2 set
449       }//2
450       // checking combinations
451       //
452       if((flag1*int1*flag2*int2)==1){// int1=1 & int2=1
453           arr.Add((AliTriggerIR*)IR); //add this IR
454           continue;       
455       }
456       if(int1 == -1){// ignore int1
457         if(flag2&int2){// int2=1
458           arr.Add((AliTriggerIR*)IR); //add this IR
459           continue;
460         }
461         else if (!flag2&!int2){ //int2=0 
462           arr.Add((AliTriggerIR*)IR); //add this IR
463           continue;          
464         }
465       }
466       if(int2 ==-1){//ignore int2
467         if(flag1&int1){//int1=1
468           arr.Add((AliTriggerIR*)IR); //add this IR
469           continue;  
470         }
471         else if(!flag1&!int1){ //int1=0
472           arr.Add((AliTriggerIR*)IR); //add this IR
473           continue;  
474         }
475       }
476       if ((flag1*int1)&!flag2&!int2){// int1=1, int2=0
477           arr.Add((AliTriggerIR*)IR); //add this IR
478           continue;  
479       }
480       if ((int2*flag2)&!int1&!flag1){// int1=0, int2=1
481           arr.Add((AliTriggerIR*)IR); //add this IR
482           continue;  
483       }      
484
485     }//1
486   
487   return arr;
488 }
489
490 //__________________________________________________________________________
491 void AliESDHeader::SetIRInteractionMap() const
492 {
493   //
494   // Function to compute the map of interations 
495   // within 0TVX (int2) or V0A&V0C (int1) and the Event Id 
496   // Note, the zero value is excluded
497   //
498   const AliTriggerIR *ir[5] = {GetTriggerIR(0),GetTriggerIR(1),GetTriggerIR(2),GetTriggerIR(3),GetTriggerIR(4)};
499
500   Long64_t orb = (Long64_t)GetOrbitNumber();
501   Long64_t bc = (Long64_t)GetBunchCrossNumber();
502   
503   Long64_t evId = orb*3564 + bc;
504
505   for(Int_t i = 0; i < 5; ++i) {
506     if (ir[i] == NULL || ir[i]->GetNWord() == 0) continue;
507     Long64_t irOrb = (Long64_t)ir[i]->GetOrbit();
508     Bool_t* int2 = ir[i]->GetInt2s();
509     Bool_t* int1 = ir[i]->GetInt1s();
510     UShort_t* bcs = ir[i]->GetBCs();
511     for(UInt_t nW = 0; nW < ir[i]->GetNWord(); ++nW) {
512       Long64_t intId = irOrb*3564 + (Long64_t)bcs[nW];
513       if (int2[nW] == kTRUE) {
514           Int_t item = (intId-evId);
515           Int_t bin = FindIRIntInteractionsBXMap(item);
516           if(bin>=0) {
517             fIRInt2InteractionsMap.SetBitNumber(bin,kTRUE);
518           }
519       }
520       if (int1[nW] == kTRUE) {
521           Int_t item = (intId-evId);
522           Int_t bin = FindIRIntInteractionsBXMap(item);
523           if(bin>=0) {
524             fIRInt1InteractionsMap.SetBitNumber(bin,kTRUE);
525           }
526       }
527     }
528   }
529
530   fIRInt2InteractionsMap.Compact();
531   fIRInt1InteractionsMap.Compact();
532 }
533
534 //__________________________________________________________________________
535 Int_t AliESDHeader::FindIRIntInteractionsBXMap(Int_t difference) const
536 {
537   //
538   // The mapping is of 181 bits, from -90 to +90
539   //
540   Int_t bin=-1;
541
542   if(difference<-90 || difference>90) return bin;
543   else { bin = 90 + difference; }
544   
545   return bin;
546 }
547
548 //__________________________________________________________________________
549 Int_t AliESDHeader::GetIRInt2ClosestInteractionMap() const
550 {
551   //
552   // Calculation of the closest interaction
553   //
554   SetIRInteractionMap();
555
556   Int_t firstNegative=100;
557   for(Int_t item=-1; item>=-90; item--) {
558     Int_t bin = FindIRIntInteractionsBXMap(item);
559     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
560     if(isFired) {
561       firstNegative = item;
562       break;
563     }
564   }
565   Int_t firstPositive=100;
566   for(Int_t item=1; item<=90; item++) {
567     Int_t bin = FindIRIntInteractionsBXMap(item);
568     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
569     if(isFired) {
570       firstPositive = item;
571       break;
572     }
573   }
574
575   Int_t closest = firstPositive < TMath::Abs(firstNegative) ? firstPositive : TMath::Abs(firstNegative);
576   if(firstPositive==100 && firstNegative==100) closest=0;
577   return closest;
578 }
579
580 //__________________________________________________________________________
581 Int_t AliESDHeader::GetIRInt1ClosestInteractionMap(Int_t gap) const
582 {
583   //
584   // Calculation of the closest interaction
585   // In case of VZERO (Int1) one has to introduce a gap
586   // in order to avoid false positivies from after-pulses
587
588   SetIRInteractionMap();
589
590   Int_t firstNegative=100;
591   for(Int_t item=-1; item>=-90; item--) {
592     Int_t bin = FindIRIntInteractionsBXMap(item);
593     Bool_t isFired = fIRInt1InteractionsMap.TestBitNumber(bin);
594     if(isFired) {
595       firstNegative = item;
596       break;
597     }
598   }
599   Int_t firstPositive=100;
600   for(Int_t item=1+gap; item<=90; item++) {
601     Int_t bin = FindIRIntInteractionsBXMap(item);
602     Bool_t isFired = fIRInt1InteractionsMap.TestBitNumber(bin);
603     if(isFired) {
604       firstPositive = item;
605       break;
606     }
607   }
608
609   Int_t closest = firstPositive < TMath::Abs(firstNegative) ? firstPositive : TMath::Abs(firstNegative);
610   if(firstPositive==100 && firstNegative==100) closest=0;
611   return closest;
612 }
613
614 //__________________________________________________________________________
615 Int_t  AliESDHeader::GetIRInt2LastInteractionMap() const
616 {
617   //
618   // Calculation of the last interaction
619   //
620   SetIRInteractionMap();
621
622   Int_t lastNegative=0;
623   for(Int_t item=-90; item<=-1; item++) {
624     Int_t bin = FindIRIntInteractionsBXMap(item);
625     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
626     if(isFired) {
627       lastNegative = item;
628       break;
629     }
630   }
631   Int_t lastPositive=0;
632   for(Int_t item=90; item>=1; item--) {
633     Int_t bin = FindIRIntInteractionsBXMap(item);
634     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
635     if(isFired) {
636       lastPositive = item;
637       break;
638     }
639   }
640
641   Int_t last = lastPositive > TMath::Abs(lastNegative) ? lastPositive : TMath::Abs(lastNegative);
642   return last;
643 }