]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDHeader.cxx
doxy: do not show whitespace diffs on bulk edit
[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 == 0) return kFALSE;
317
318   Int_t inputIndex = fTriggerInputsNames.IndexOf(trginput);
319   if (inputIndex < 0) return kFALSE;
320  
321   if(inputIndex < 24){
322     if (fL0TriggerInputs & (1lu << inputIndex)) return kTRUE;
323   } else if(inputIndex < 48){
324     if (fL1TriggerInputs & (1lu << (inputIndex-24))) return kTRUE;
325   } else if(inputIndex < 60){
326     if (fL2TriggerInputs & (1u << (inputIndex-48))) return kTRUE;
327   }
328   else {
329     AliError(Form("Index (%d) is outside the allowed range (0,59)!",inputIndex));
330     return kFALSE;
331   }
332   return kFALSE;
333 }
334 //________________________________________________________________________________
335 Int_t  AliESDHeader::GetTriggerIREntries(Int_t int1, Int_t int2, Float_t deltaTime) const
336 {
337   // returns number of IR-s within time window deltaTime
338   // all possible combinations of int1 and int2 int1 - zdc bit, int2 v0 bit
339   //
340   const AliTriggerIR *IR;
341   // triggered event 
342   Int_t nIR = GetTriggerIREntries();
343   UInt_t orbit1 = GetOrbitNumber();
344   const Double_t ot=0.0889218; //orbit time msec
345   Float_t timediff; // time difference between orbits (msec)
346   //
347   Int_t nofIR;
348   nofIR=0;
349   // loop over IR-s
350     for(Int_t i=0;i<nIR;i++){//1
351       IR=GetTriggerIR(i);
352       //
353       UInt_t orbit2 = IR->GetOrbit();
354       timediff = (orbit2<=orbit1) ? (Float_t)((orbit1-orbit2))*ot : 
355         (Float_t)((16777215-orbit1+orbit2))*ot;
356       if (timediff>deltaTime) continue; //timediff outside time window
357       if((int1&int2) == -1){ //ignore both bits, just count IR-s within time window
358         nofIR++;
359         continue;
360       }
361       // now check if int1, int2 bits are set
362       UInt_t nw = IR->GetNWord();
363       Bool_t *bint1 = IR->GetInt1s();
364       Bool_t *bint2 = IR->GetInt2s();
365       //
366       Int_t flag1,flag2;
367       flag1=0;
368       flag2=0;
369       for(UInt_t j=0;j<nw;j++){//2
370         if(bint1[j]) flag1=1; // at least one int1 set
371         if(bint2[j]) flag2=1; //  at least one int2 set
372         //printf("IR %d, bint1 %d, bint2 %d\n",i,bint1[j],bint2[j]);
373       }//2
374       // checking combinations
375       //
376       
377       if((flag1*int1*flag2*int2)==1){// int1=1 & int2=1  
378           nofIR++;
379           continue;       
380       }
381       if(int1 == -1){// ignore int1
382         if(flag2&int2){// int2=1
383           nofIR++;
384           continue;
385         }
386         else if (!flag2&!int2){ //int2=0 
387           nofIR++;
388           continue;          
389         }
390       }
391       
392       if(int2 ==-1){//ignore int2
393         if(flag1&int1){//int1=1
394           nofIR++;
395           continue;  
396         }
397         else if(!flag1&!int1){ //int1=0
398           nofIR++;
399           continue;  
400         }
401       }
402       
403       if((flag1*int1)&!flag2&!int2){// int1=1, int2=0
404           nofIR++;
405           continue;  
406       }
407       
408       if((int2*flag2)&!int1&!flag1){// int1=0, int2=1
409           nofIR++;
410           continue;  
411       } 
412          
413       
414
415     }//1
416   
417     return nofIR;
418 }
419 //__________________________________________________________________________
420 TObjArray AliESDHeader::GetIRArray(Int_t int1, Int_t int2, Float_t deltaTime) const
421 {
422   //
423   // returns an array of IR-s within time window deltaTime
424   // all possible combinations of int1 and int2 int1 - zdc bit, int2 v0 bit
425   //
426   const AliTriggerIR *IR;
427   TObjArray arr;
428   // triggered event 
429   Int_t nIR = GetTriggerIREntries();
430   UInt_t orbit1 = GetOrbitNumber();
431   const Double_t ot=0.0889218; //orbit time msec
432   Float_t timediff; // time difference between orbits (msec)
433   //
434   // loop over IR-s
435     for(Int_t i=0;i<nIR;i++){//1
436       IR=GetTriggerIR(i);
437       //
438       UInt_t orbit2 = IR->GetOrbit();
439       timediff = (orbit2<=orbit1) ? (Float_t)((orbit1-orbit2))*ot : 
440         (Float_t)((16777215-orbit1+orbit2))*ot;
441       if (timediff>deltaTime) continue; //timediff outside time window
442       if((int1&int2) == -1){ //ignore both bits, just count IR-s within time window
443         arr.Add((AliTriggerIR*)IR); //add this IR
444         continue;
445       }
446       // now check if int1, int2 bits are set
447       UInt_t nw = IR->GetNWord();
448       Bool_t *bint1 = IR->GetInt1s();
449       Bool_t *bint2 = IR->GetInt2s();
450       //
451       Int_t flag1,flag2;
452       flag1=0;
453       flag2=0;
454       for(UInt_t j=0;j<nw;j++){//2
455         if(bint1[j]) flag1=1; // at least one int1 set
456         if(bint2[j]) flag2=1; //  at least one int2 set
457       }//2
458       // checking combinations
459       //
460       if((flag1*int1*flag2*int2)==1){// int1=1 & int2=1
461           arr.Add((AliTriggerIR*)IR); //add this IR
462           continue;       
463       }
464       if(int1 == -1){// ignore int1
465         if(flag2&int2){// int2=1
466           arr.Add((AliTriggerIR*)IR); //add this IR
467           continue;
468         }
469         else if (!flag2&!int2){ //int2=0 
470           arr.Add((AliTriggerIR*)IR); //add this IR
471           continue;          
472         }
473       }
474       if(int2 ==-1){//ignore int2
475         if(flag1&int1){//int1=1
476           arr.Add((AliTriggerIR*)IR); //add this IR
477           continue;  
478         }
479         else if(!flag1&!int1){ //int1=0
480           arr.Add((AliTriggerIR*)IR); //add this IR
481           continue;  
482         }
483       }
484       if ((flag1*int1)&!flag2&!int2){// int1=1, int2=0
485           arr.Add((AliTriggerIR*)IR); //add this IR
486           continue;  
487       }
488       if ((int2*flag2)&!int1&!flag1){// int1=0, int2=1
489           arr.Add((AliTriggerIR*)IR); //add this IR
490           continue;  
491       }      
492
493     }//1
494   
495   return arr;
496 }
497
498 //__________________________________________________________________________
499 void AliESDHeader::SetIRInteractionMap() const
500 {
501   //
502   // Function to compute the map of interations 
503   // within 0TVX (int2) or V0A&V0C (int1) and the Event Id 
504   // Note, the zero value is excluded
505   //
506   const AliTriggerIR *ir[5] = {GetTriggerIR(0),GetTriggerIR(1),GetTriggerIR(2),GetTriggerIR(3),GetTriggerIR(4)};
507
508   Long64_t orb = (Long64_t)GetOrbitNumber();
509   Long64_t bc = (Long64_t)GetBunchCrossNumber();
510   
511   Long64_t evId = orb*3564 + bc;
512
513   for(Int_t i = 0; i < 5; ++i) {
514     if (ir[i] == NULL || ir[i]->GetNWord() == 0) continue;
515     Long64_t irOrb = (Long64_t)ir[i]->GetOrbit();
516     Bool_t* int2 = ir[i]->GetInt2s();
517     Bool_t* int1 = ir[i]->GetInt1s();
518     UShort_t* bcs = ir[i]->GetBCs();
519     for(UInt_t nW = 0; nW < ir[i]->GetNWord(); ++nW) {
520       Long64_t intId = irOrb*3564 + (Long64_t)bcs[nW];
521       if (int2[nW] == kTRUE) {
522           Int_t item = (intId-evId);
523           Int_t bin = FindIRIntInteractionsBXMap(item);
524           if(bin>=0) {
525             fIRInt2InteractionsMap.SetBitNumber(bin,kTRUE);
526           }
527       }
528       if (int1[nW] == kTRUE) {
529           Int_t item = (intId-evId);
530           Int_t bin = FindIRIntInteractionsBXMap(item);
531           if(bin>=0) {
532             fIRInt1InteractionsMap.SetBitNumber(bin,kTRUE);
533           }
534       }
535     }
536   }
537
538   fIRInt2InteractionsMap.Compact();
539   fIRInt1InteractionsMap.Compact();
540 }
541
542 //__________________________________________________________________________
543 Int_t AliESDHeader::FindIRIntInteractionsBXMap(Int_t difference) const
544 {
545   //
546   // The mapping is of 181 bits, from -90 to +90
547   //
548   Int_t bin=-1;
549
550   if(difference<-90 || difference>90) return bin;
551   else { bin = 90 + difference; }
552   
553   return bin;
554 }
555
556 //__________________________________________________________________________
557 Int_t AliESDHeader::GetIRInt2ClosestInteractionMap() const
558 {
559   //
560   // Calculation of the closest interaction
561   //
562   SetIRInteractionMap();
563
564   Int_t firstNegative=100;
565   for(Int_t item=-1; item>=-90; item--) {
566     Int_t bin = FindIRIntInteractionsBXMap(item);
567     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
568     if(isFired) {
569       firstNegative = item;
570       break;
571     }
572   }
573   Int_t firstPositive=100;
574   for(Int_t item=1; item<=90; item++) {
575     Int_t bin = FindIRIntInteractionsBXMap(item);
576     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
577     if(isFired) {
578       firstPositive = item;
579       break;
580     }
581   }
582
583   Int_t closest = firstPositive < TMath::Abs(firstNegative) ? firstPositive : TMath::Abs(firstNegative);
584   if(firstPositive==100 && firstNegative==100) closest=0;
585   return closest;
586 }
587
588 //__________________________________________________________________________
589 Int_t AliESDHeader::GetIRInt1ClosestInteractionMap(Int_t gap) const
590 {
591   //
592   // Calculation of the closest interaction
593   // In case of VZERO (Int1) one has to introduce a gap
594   // in order to avoid false positivies from after-pulses
595
596   SetIRInteractionMap();
597
598   Int_t firstNegative=100;
599   for(Int_t item=-1; item>=-90; item--) {
600     Int_t bin = FindIRIntInteractionsBXMap(item);
601     Bool_t isFired = fIRInt1InteractionsMap.TestBitNumber(bin);
602     if(isFired) {
603       firstNegative = item;
604       break;
605     }
606   }
607   Int_t firstPositive=100;
608   for(Int_t item=1+gap; item<=90; item++) {
609     Int_t bin = FindIRIntInteractionsBXMap(item);
610     Bool_t isFired = fIRInt1InteractionsMap.TestBitNumber(bin);
611     if(isFired) {
612       firstPositive = item;
613       break;
614     }
615   }
616
617   Int_t closest = firstPositive < TMath::Abs(firstNegative) ? firstPositive : TMath::Abs(firstNegative);
618   if(firstPositive==100 && firstNegative==100) closest=0;
619   return closest;
620 }
621
622 //__________________________________________________________________________
623 Int_t  AliESDHeader::GetIRInt2LastInteractionMap() const
624 {
625   //
626   // Calculation of the last interaction
627   //
628   SetIRInteractionMap();
629
630   Int_t lastNegative=0;
631   for(Int_t item=-90; item<=-1; item++) {
632     Int_t bin = FindIRIntInteractionsBXMap(item);
633     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
634     if(isFired) {
635       lastNegative = item;
636       break;
637     }
638   }
639   Int_t lastPositive=0;
640   for(Int_t item=90; item>=1; item--) {
641     Int_t bin = FindIRIntInteractionsBXMap(item);
642     Bool_t isFired = fIRInt2InteractionsMap.TestBitNumber(bin);
643     if(isFired) {
644       lastPositive = item;
645       break;
646     }
647   }
648
649   Int_t last = lastPositive > TMath::Abs(lastNegative) ? lastPositive : TMath::Abs(lastNegative);
650   return last;
651 }