1 //_________________________________________________________
2 ////////////////////////////////////////////////////////////////////////////
4 // class AliHBTAnalysis
6 // Central Object Of HBTAnalyser:
7 // This class performs main looping within HBT Analysis
8 // User must plug a reader of Type AliHBTReader
9 // User plugs in coorelation and monitor functions
10 // as well as monitor functions
12 // HBT Analysis Tool, which is integral part of AliRoot,
13 // ALICE Off-Line framework:
15 // Piotr.Skowronski@cern.ch
16 // more info: http://alisoft.cern.ch/people/skowron/analyzer/index.html
18 ////////////////////////////////////////////////////////////////////////////
19 //_________________________________________________________
21 #include "AliHBTAnalysis.h"
22 #include "AliHBTRun.h"
23 #include "AliHBTEvent.h"
24 #include "AliHBTReader.h"
25 #include "AliHBTParticle.h"
26 #include "AliHBTParticleCut.h"
27 #include "AliHBTPair.h"
28 #include "AliHBTPairCut.h"
29 #include "AliHBTFunction.h"
30 #include "AliHBTMonitorFunction.h"
31 #include "AliHBTEventBuffer.h"
32 #include "AliHBTPairCut.h"
35 #include <TBenchmark.h>
38 #include <sys/types.h>
43 ClassImp(AliHBTAnalysis)
45 const UInt_t AliHBTAnalysis::fgkFctnArraySize = 100;
46 const UInt_t AliHBTAnalysis::fgkDefaultMixingInfo = 1000;
47 const Int_t AliHBTAnalysis::fgkDefaultBufferSize = 5;
49 AliHBTAnalysis::AliHBTAnalysis():
52 fNParticleFunctions(0),
53 fNParticleAndTrackFunctions(0),
54 fNTrackMonitorFunctions(0),
55 fNParticleMonitorFunctions(0),
56 fNParticleAndTrackMonitorFunctions(0),
57 fTrackFunctions ( new AliHBTOnePairFctn* [fgkFctnArraySize]),
58 fParticleFunctions ( new AliHBTOnePairFctn* [fgkFctnArraySize]),
59 fParticleAndTrackFunctions ( new AliHBTTwoPairFctn* [fgkFctnArraySize]),
60 fParticleMonitorFunctions ( new AliHBTMonOneParticleFctn* [fgkFctnArraySize]),
61 fTrackMonitorFunctions ( new AliHBTMonOneParticleFctn* [fgkFctnArraySize]),
62 fParticleAndTrackMonitorFunctions ( new AliHBTMonTwoParticleFctn* [fgkFctnArraySize]),
63 fPairCut(new AliHBTEmptyPairCut()),//empty cut - accepts all particles
66 fDisplayMixingInfo(fgkDefaultMixingInfo),
71 /*************************************************************************************/
73 AliHBTAnalysis::AliHBTAnalysis(const AliHBTAnalysis& in):
77 fNParticleFunctions(0),
78 fNParticleAndTrackFunctions(0),
79 fNTrackMonitorFunctions(0),
80 fNParticleMonitorFunctions(0),
81 fNParticleAndTrackMonitorFunctions(0),
83 fParticleFunctions(0x0),
84 fParticleAndTrackFunctions(0x0),
85 fParticleMonitorFunctions(0x0),
86 fTrackMonitorFunctions(0x0),
87 fParticleAndTrackMonitorFunctions(0x0),
90 fBufferSize(fgkDefaultBufferSize),
91 fDisplayMixingInfo(fgkDefaultMixingInfo),
95 Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
97 /*************************************************************************************/
98 const AliHBTAnalysis& AliHBTAnalysis::operator=(const AliHBTAnalysis& /*right*/)
101 Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
104 /*************************************************************************************/
105 AliHBTAnalysis::~AliHBTAnalysis()
108 //note that we do not delete functions itself
109 // they should be deleted by whom where created
110 //we only store pointers, and we use "new" only for pointers array
113 delete [] fTrackFunctions;
114 delete [] fParticleFunctions;
115 delete [] fParticleAndTrackFunctions;
117 delete [] fParticleMonitorFunctions;
118 delete [] fTrackMonitorFunctions;
119 delete [] fParticleAndTrackMonitorFunctions;
121 delete fPairCut; // always have an copy of an object - we create we dstroy
122 delete fAntiMergingCut;
125 /*************************************************************************************/
127 void AliHBTAnalysis::DeleteFunctions()
129 //Deletes all functions added to analysis
131 for(ii = 0;ii<fNParticleFunctions;ii++)
132 delete fParticleFunctions[ii];
133 fNParticleFunctions = 0;
135 for(ii = 0;ii<fNTrackFunctions;ii++)
136 delete fTrackFunctions[ii];
137 fNTrackFunctions = 0;
139 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
140 delete fParticleAndTrackFunctions[ii];
141 fNParticleAndTrackFunctions = 0;
143 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
144 delete fParticleMonitorFunctions[ii];
145 fNParticleMonitorFunctions = 0;
147 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
148 delete fTrackMonitorFunctions[ii];
149 fNTrackMonitorFunctions = 0;
151 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
152 delete fParticleAndTrackMonitorFunctions[ii];
153 fNParticleAndTrackMonitorFunctions = 0;
156 /*************************************************************************************/
158 void AliHBTAnalysis::Init()
160 //Initializeation method
161 //calls Init for all functions
163 for(ii = 0;ii<fNParticleFunctions;ii++)
164 fParticleFunctions[ii]->Init();
166 for(ii = 0;ii<fNTrackFunctions;ii++)
167 fTrackFunctions[ii]->Init();
169 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
170 fParticleAndTrackFunctions[ii]->Init();
172 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
173 fParticleMonitorFunctions[ii]->Init();
175 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
176 fTrackMonitorFunctions[ii]->Init();
178 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
179 fParticleAndTrackMonitorFunctions[ii]->Init();
183 /*************************************************************************************/
185 void AliHBTAnalysis::ResetFunctions()
187 //In case fOwner is true, deletes all functions
188 //in other case, just set number of analysis to 0
189 if (fIsOwner) DeleteFunctions();
192 fNParticleFunctions = 0;
193 fNTrackFunctions = 0;
194 fNParticleAndTrackFunctions = 0;
195 fNParticleMonitorFunctions = 0;
196 fNTrackMonitorFunctions = 0;
197 fNParticleAndTrackMonitorFunctions = 0;
200 /*************************************************************************************/
202 void AliHBTAnalysis::Process(Option_t* option)
204 //default option = "TracksAndParticles"
205 //Main method of the HBT Analysis Package
206 //It triggers reading with the global cut (default is an empty cut)
207 //Than it checks options and data which are read
208 //if everything is OK, then it calls one of the looping methods
209 //depending on tfReaderhe option
210 //These methods differs on what thay are looping on
213 //--------------------------------------------------------------------
214 //ProcessTracksAndParticles - "TracksAndParticles"
216 // it loops over both, tracks(reconstructed) and particles(simulated)
217 // all function gethered in all 3 lists are called for each (double)pair
219 //ProcessTracks - "Tracks"
220 // it loops only on tracks(reconstructed),
221 // functions ONLY from fTrackFunctions list are called
223 //ProcessParticles - "Particles"
224 // it loops only on particles(simulated),
225 // functions ONLY from fParticleAndTrackFunctions list are called
230 Error("Process","The reader is not set");
234 const char *oT = strstr(option,"Tracks");
235 const char *oP = strstr(option,"Particles");
237 Bool_t nonid = IsNonIdentAnalysis();
243 if (nonid) ProcessTracksAndParticlesNonIdentAnal();
244 else ProcessTracksAndParticles();
250 if (nonid) ProcessTracksNonIdentAnal();
251 else ProcessTracks();
257 if (nonid) ProcessParticlesNonIdentAnal();
258 else ProcessParticles();
263 /*************************************************************************************/
265 void AliHBTAnalysis::ProcessTracksAndParticles()
267 //Makes analysis for both tracks and particles
268 //mainly for resolution study and analysies with weighting algirithms
269 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
270 //the loops are splited
272 // cuta on particles only
274 AliHBTParticle * part1, * part2;
275 AliHBTParticle * track1, * track2;
277 AliHBTEvent * trackEvent, *partEvent;
278 AliHBTEvent * trackEvent1 = 0x0,*partEvent1 = 0x0;
279 AliHBTEvent * trackEvent2,*partEvent2;
281 // Int_t N1, N2, N=0; //number of particles in current event(we prcess two events in one time)
283 // Int_t nev = fReader->GetNumberOfTrackEvents();
284 AliHBTPair * trackpair = new AliHBTPair();
285 AliHBTPair * partpair = new AliHBTPair();
287 AliHBTPair * tmptrackpair;//temprary pointers to pairs
288 AliHBTPair * tmppartpair;
290 AliHBTEventBuffer partbuffer(fBufferSize);
291 AliHBTEventBuffer trackbuffer(fBufferSize);
295 Bool_t nocorrfctns = (fNParticleFunctions == 0) && (fNTrackFunctions == 0) && (fNParticleAndTrackFunctions == 0);
299 while (fReader->Next() == kFALSE)
302 partEvent= fReader->GetParticleEvent();
303 trackEvent = fReader->GetTrackEvent();
305 if ( !partEvent || !trackEvent )
307 Error("ProcessTracksAndParticles","Can not get event");
311 if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
313 Fatal("ProcessTracksAndParticles",
314 "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
315 i,partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
319 if(partEvent1 == 0x0)
321 partEvent1 = new AliHBTEvent();
322 partEvent1->SetOwner(kTRUE);
324 trackEvent1 = new AliHBTEvent();
325 trackEvent1->SetOwner(kTRUE);
330 trackEvent1->Reset();
333 for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
335 /***************************************/
336 /****** Looping same events ********/
337 /****** filling numerators ********/
338 /***************************************/
339 if ( (j%fDisplayMixingInfo) == 0)
340 Info("ProcessTracksAndParticles",
341 "Mixing particle %d from event %d with particles from event %d",j,i,i);
343 part1= partEvent->GetParticle(j);
344 track1= trackEvent->GetParticle(j);
346 //PID imperfections ???
347 // if( part1->GetPdgCode() != track1->GetPdgCode() )
349 // Fatal("ProcessTracksAndParticles",
350 // "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
351 // i,j, part1->GetPdgCode(),track1->GetPdgCode() );
355 Bool_t firstcut = fPairCut->GetFirstPartCut()->Pass(part1);
356 if (fBufferSize != 0)
357 if ( (firstcut == kFALSE) || (fPairCut->GetSecondPartCut()->Pass(part1) == kFALSE) )
359 //accepted by any cut
360 // we have to copy because reader keeps only one event
362 partEvent1->AddParticle(new AliHBTParticle(*part1));
363 trackEvent1->AddParticle(new AliHBTParticle(*track1));
366 if (firstcut) continue;
368 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
369 fParticleMonitorFunctions[ii]->Process(part1);
370 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
371 fTrackMonitorFunctions[ii]->Process(track1);
372 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
373 fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
375 if (nocorrfctns) continue;
377 for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
379 part2= partEvent->GetParticle(k);
380 if (part1->GetUID() == part2->GetUID()) continue;
381 partpair->SetParticles(part1,part2);
383 track2= trackEvent->GetParticle(k);
384 trackpair->SetParticles(track1,track2);
386 if(fPairCut->Pass(partpair) ) //check pair cut
387 { //do not meets crietria of the pair cut, try with swapped pairs
388 if( fPairCut->Pass(partpair->GetSwapedPair()) )
389 continue; //swaped pairs do not meet criteria of pair cut as well, take next particle
391 { //swaped pair meets all the criteria
392 tmppartpair = partpair->GetSwapedPair();
393 tmptrackpair = trackpair->GetSwapedPair();
397 {//meets criteria of the pair cut
398 tmptrackpair = trackpair;
399 tmppartpair = partpair;
402 for(ii = 0;ii<fNParticleFunctions;ii++)
403 fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
405 for(ii = 0;ii<fNTrackFunctions;ii++)
406 fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
408 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
409 fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair,tmppartpair);
410 //end of 2nd loop over particles from the same event
411 }//for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
413 /***************************************/
414 /***** Filling denominators *********/
415 /***************************************/
416 if (fBufferSize == 0) continue;
418 partbuffer.ResetIter();
419 trackbuffer.ResetIter();
421 while (( partEvent2 = partbuffer.Next() ))
423 trackEvent2 = trackbuffer.Next();
426 if ( (j%fDisplayMixingInfo) == 0)
427 Info("ProcessTracksAndParticles",
428 "Mixing particle %d from event %d with particles from event %d",j,i,i-m);
430 for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++) // ... on all particles
432 part2= partEvent2->GetParticle(l);
433 partpair->SetParticles(part1,part2);
435 track2= trackEvent2->GetParticle(l);
436 trackpair->SetParticles(track1,track2);
438 if( fPairCut->Pass(partpair) ) //check pair cut
439 { //do not meets crietria of the
440 if( fPairCut->Pass(partpair->GetSwapedPair()) )
444 tmppartpair = partpair->GetSwapedPair();
445 tmptrackpair = trackpair->GetSwapedPair();
449 {//meets criteria of the pair cut
450 tmptrackpair = trackpair;
451 tmppartpair = partpair;
454 //Anti merging cut is only on tracks makes the background
456 if (fAntiMergingCut->Pass(trackpair)) continue;
458 for(ii = 0;ii<fNParticleFunctions;ii++)
459 fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
461 for(ii = 0;ii<fNTrackFunctions;ii++)
462 fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
464 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
465 fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair,tmppartpair);
466 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
469 //end of loop over particles from first event
470 }//for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
471 partEvent1 = partbuffer.Push(partEvent1);
472 trackEvent1 = trackbuffer.Push(trackEvent1);
473 //end of loop over events
474 }//while (fReader->Next() == kFALSE)
476 /*************************************************************************************/
478 void AliHBTAnalysis::ProcessTracks()
480 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
481 //the loops are splited
482 AliHBTParticle * track1, * track2;
483 AliHBTEvent * trackEvent;
484 AliHBTEvent * trackEvent1 = 0x0;
485 AliHBTEvent * trackEvent2;
489 AliHBTPair * trackpair = new AliHBTPair();
490 AliHBTPair * tmptrackpair; //temporary pointer
492 AliHBTEventBuffer trackbuffer(fBufferSize);
496 while (fReader->Next() == kFALSE)
499 trackEvent = fReader->GetTrackEvent();
500 if (!trackEvent) continue;
502 if(trackEvent1 == 0x0)
504 trackEvent1 = new AliHBTEvent();
505 trackEvent1->SetOwner(kTRUE);
509 trackEvent1->Reset();
512 for (Int_t j = 0; j<trackEvent->GetNumberOfParticles() ; j++)
514 /***************************************/
515 /****** Looping same events ********/
516 /****** filling numerators ********/
517 /***************************************/
518 if ( (j%fDisplayMixingInfo) == 0)
519 Info("ProcessTracks",
520 "Mixing particle %d from event %d with particles from event %d",j,i,i);
522 track1= trackEvent->GetParticle(j);
523 Bool_t firstcut = fPairCut->GetFirstPartCut()->Pass(track1);
525 if (fBufferSize != 0)
526 if ( (firstcut == kFALSE) || (fPairCut->GetSecondPartCut()->Pass(track1) == kFALSE) )
528 //accepted by any cut
529 // we have to copy because reader keeps only one event
530 trackEvent1->AddParticle(new AliHBTParticle(*track1));
533 if (firstcut) continue;
535 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
536 fTrackMonitorFunctions[ii]->Process(track1);
538 if ( fNTrackFunctions ==0 ) continue;
540 for (Int_t k =j+1; k < trackEvent->GetNumberOfParticles() ; k++)
542 track2= trackEvent->GetParticle(k);
543 if (track1->GetUID() == track2->GetUID()) continue;
545 trackpair->SetParticles(track1,track2);
546 if(fPairCut->Pass(trackpair)) //check pair cut
547 { //do not meets crietria of the
548 if( fPairCut->Pass(trackpair->GetSwapedPair()) ) continue;
549 else tmptrackpair = trackpair->GetSwapedPair();
553 tmptrackpair = trackpair;
555 for(ii = 0;ii<fNTrackFunctions;ii++)
556 fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
558 /***************************************/
559 /***** Filling denominators *********/
560 /***************************************/
562 if (fBufferSize == 0) continue;
564 trackbuffer.ResetIter();
567 while (( trackEvent2 = trackbuffer.Next() ))
570 if ( (j%fDisplayMixingInfo) == 0)
571 Info("ProcessTracks",
572 "Mixing track %d from event %d with tracks from event %d",j,i,i-m);
573 for(Int_t l = 0; l<trackEvent2->GetNumberOfParticles();l++) // ... on all particles
576 track2= trackEvent2->GetParticle(l);
577 trackpair->SetParticles(track1,track2);
579 if( fPairCut->Pass(trackpair) ) //check pair cut
580 { //do not meets crietria of the
581 if( fPairCut->Pass(trackpair->GetSwapedPair()) )
585 tmptrackpair = trackpair->GetSwapedPair();
589 {//meets criteria of the pair cut
590 tmptrackpair = trackpair;
593 //Anti merging cut is only on tracks makes the background
595 if (fAntiMergingCut->Pass(trackpair)) continue;
597 for(ii = 0;ii<fNTrackFunctions;ii++)
598 fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
600 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
603 trackEvent1 = trackbuffer.Push(trackEvent1);
604 }//while (fReader->Next() == kFALSE)
607 /*************************************************************************************/
609 void AliHBTAnalysis::ProcessParticles()
611 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
612 //the loops are splited
613 AliHBTParticle * part1, * part2;
614 AliHBTEvent * partEvent;
615 AliHBTEvent * partEvent1 = 0x0;
616 AliHBTEvent * partEvent2;
620 AliHBTPair * partpair = new AliHBTPair();
621 AliHBTPair * tmppartpair; //temporary pointer
623 AliHBTEventBuffer partbuffer(fBufferSize);
627 while (fReader->Next() == kFALSE)
630 partEvent = fReader->GetParticleEvent();
631 if (!partEvent) continue;
633 if(partEvent1 == 0x0)
635 partEvent1 = new AliHBTEvent();
636 partEvent1->SetOwner(kTRUE);
643 for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
645 /***************************************/
646 /****** Looping same events ********/
647 /****** filling numerators ********/
648 /***************************************/
649 if ( (j%fDisplayMixingInfo) == 0)
650 Info("ProcessParticles",
651 "Mixing particle %d from event %d with particles from event %d",j,i,i);
653 part1 = partEvent->GetParticle(j);
654 Bool_t firstcut = fPairCut->GetFirstPartCut()->Pass(part1);
656 if (fBufferSize != 0) //useless in case
657 if ( (firstcut == kFALSE) || (fPairCut->GetSecondPartCut()->Pass(part1) == kFALSE) )
659 //accepted by any cut
660 // we have to copy because reader keeps only one event
661 partEvent1->AddParticle(new AliHBTParticle(*part1));
664 if (firstcut) continue;
666 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
667 fParticleMonitorFunctions[ii]->Process(part1);
669 if ( fNParticleFunctions == 0 ) continue;
671 for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
673 part2= partEvent->GetParticle(k);
674 if (part1->GetUID() == part2->GetUID()) continue;
676 partpair->SetParticles(part1,part2);
677 if(fPairCut->Pass(partpair)) //check pair cut
678 { //do not meets crietria of the
679 if( fPairCut->Pass(partpair->GetSwapedPair()) ) continue;
680 else tmppartpair = partpair->GetSwapedPair();
684 tmppartpair = partpair;
686 for(ii = 0;ii<fNParticleFunctions;ii++)
687 fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
689 /***************************************/
690 /***** Filling denominators *********/
691 /***************************************/
693 if (fBufferSize == 0) continue;
695 partbuffer.ResetIter();
698 while (( partEvent2 = partbuffer.Next() ))
701 if ( (j%fDisplayMixingInfo) == 0)
702 Info("ProcessParticles",
703 "Mixing particle %d from event %d with particles from event %d",j,i,i-m);
704 for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++) // ... on all particles
707 part2= partEvent2->GetParticle(l);
708 partpair->SetParticles(part1,part2);
710 if( fPairCut->Pass(partpair) ) //check pair cut
711 { //do not meets crietria of the
712 if( fPairCut->Pass(partpair->GetSwapedPair()) )
716 tmppartpair = partpair->GetSwapedPair();
720 {//meets criteria of the pair cut
721 tmppartpair = partpair;
724 for(ii = 0;ii<fNParticleFunctions;ii++)
725 fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
727 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
730 partEvent1 = partbuffer.Push(partEvent1);
731 }//while (fReader->Next() == kFALSE)
733 /*************************************************************************************/
735 void AliHBTAnalysis::SetAntiMergingCut(Float_t x)
739 Error("SetAntiMergingCut","Value less then 0");
742 if (fAntiMergingCut == 0x0) fAntiMergingCut = new AliHBTAvSeparationCut(x);
743 else fAntiMergingCut->SetMinimum(x);
745 /*************************************************************************************/
747 void AliHBTAnalysis::WriteFunctions()
749 //Calls Write for all defined functions in analysis
750 //== writes all results
752 for(ii = 0;ii<fNParticleFunctions;ii++)
753 fParticleFunctions[ii]->Write();
755 for(ii = 0;ii<fNTrackFunctions;ii++)
756 fTrackFunctions[ii]->Write();
758 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
759 fParticleAndTrackFunctions[ii]->Write();
761 for(ii = 0;ii<fNParticleMonitorFunctions;ii++)
762 fParticleMonitorFunctions[ii]->Write();
764 for(ii = 0;ii<fNTrackMonitorFunctions;ii++)
765 fTrackMonitorFunctions[ii]->Write();
767 for(ii = 0;ii<fNParticleAndTrackMonitorFunctions;ii++)
768 fParticleAndTrackMonitorFunctions[ii]->Write();
770 /*************************************************************************************/
772 void AliHBTAnalysis::SetGlobalPairCut(AliHBTPairCut* cut)
774 //Sets the global cut
777 Error("AliHBTAnalysis::SetGlobalPairCut","Pointer is NULL. Ignoring");
780 fPairCut = (AliHBTPairCut*)cut->Clone();
783 /*************************************************************************************/
785 void AliHBTAnalysis::AddTrackFunction(AliHBTOnePairFctn* f)
787 //Adds track function
788 if (f == 0x0) return;
789 if (fNTrackFunctions == fgkFctnArraySize)
791 Error("AliHBTAnalysis::AddTrackFunction","Can not add this function, not enough place in the array.");
793 fTrackFunctions[fNTrackFunctions] = f;
796 /*************************************************************************************/
798 void AliHBTAnalysis::AddParticleFunction(AliHBTOnePairFctn* f)
800 //adds particle function
801 if (f == 0x0) return;
803 if (fNParticleFunctions == fgkFctnArraySize)
805 Error("AliHBTAnalysis::AddParticleFunction","Can not add this function, not enough place in the array.");
807 fParticleFunctions[fNParticleFunctions] = f;
808 fNParticleFunctions++;
810 /*************************************************************************************/
812 void AliHBTAnalysis::AddParticleAndTrackFunction(AliHBTTwoPairFctn* f)
814 //add resolution function
815 if (f == 0x0) return;
816 if (fNParticleAndTrackFunctions == fgkFctnArraySize)
818 Error("AliHBTAnalysis::AddParticleAndTrackFunction","Can not add this function, not enough place in the array.");
820 fParticleAndTrackFunctions[fNParticleAndTrackFunctions] = f;
821 fNParticleAndTrackFunctions++;
823 /*************************************************************************************/
825 void AliHBTAnalysis::AddParticleMonitorFunction(AliHBTMonOneParticleFctn* f)
827 //add particle monitoring function
828 if (f == 0x0) return;
830 if (fNParticleMonitorFunctions == fgkFctnArraySize)
832 Error("AliHBTAnalysis::AddParticleMonitorFunction","Can not add this function, not enough place in the array.");
834 fParticleMonitorFunctions[fNParticleMonitorFunctions] = f;
835 fNParticleMonitorFunctions++;
837 /*************************************************************************************/
839 void AliHBTAnalysis::AddTrackMonitorFunction(AliHBTMonOneParticleFctn* f)
841 //add track monitoring function
842 if (f == 0x0) return;
844 if (fNTrackMonitorFunctions == fgkFctnArraySize)
846 Error("AliHBTAnalysis::AddTrackMonitorFunction","Can not add this function, not enough place in the array.");
848 fTrackMonitorFunctions[fNTrackMonitorFunctions] = f;
849 fNTrackMonitorFunctions++;
851 /*************************************************************************************/
853 void AliHBTAnalysis::AddParticleAndTrackMonitorFunction(AliHBTMonTwoParticleFctn* f)
855 //add resolution monitoring function
856 if (f == 0x0) return;
857 if (fNParticleAndTrackMonitorFunctions == fgkFctnArraySize)
859 Error("AliHBTAnalysis::AddParticleAndTrackMonitorFunction","Can not add this function, not enough place in the array.");
861 fParticleAndTrackMonitorFunctions[fNParticleAndTrackMonitorFunctions] = f;
862 fNParticleAndTrackMonitorFunctions++;
866 /*************************************************************************************/
867 /*************************************************************************************/
869 Bool_t AliHBTAnalysis::RunCoherencyCheck()
871 //Checks if both HBTRuns are similar
872 //return true if error found
873 //if they seem to be OK return false
875 Info("RunCoherencyCheck","Checking HBT Runs Coherency");
877 Info("RunCoherencyCheck","Number of events ...");
878 if (fReader->GetNumberOfPartEvents() == fReader->GetNumberOfTrackEvents() ) //check whether there is the same number of events
880 Info("RunCoherencyCheck","OK. %d found\n",fReader->GetNumberOfTrackEvents());
883 { //if not the same - ERROR
884 Error("AliHBTAnalysis::RunCoherencyCheck()",
885 "Number of simulated events (%d) is not equal to number of reconstructed events(%d)",
886 fReader->GetNumberOfPartEvents(),fReader->GetNumberOfTrackEvents());
890 Info("RunCoherencyCheck","Checking number of Particles AND Particles Types in each event ...");
892 AliHBTEvent *partEvent;
893 AliHBTEvent *trackEvent;
894 for( i = 0; i<fReader->GetNumberOfTrackEvents();i++)
896 partEvent= fReader->GetParticleEvent(i); //gets the "ith" event
897 trackEvent = fReader->GetTrackEvent(i);
899 if ( (partEvent == 0x0) && (partEvent == 0x0) ) continue;
900 if ( (partEvent == 0x0) || (partEvent == 0x0) )
902 Error("AliHBTAnalysis::RunCoherencyCheck()",
903 "One event is NULL and the other one not. Event Number %d",i);
907 if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
909 Error("AliHBTAnalysis::RunCoherencyCheck()",
910 "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
911 i,partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
915 for (Int_t j = 0; j<partEvent->GetNumberOfParticles(); j++)
917 if( partEvent->GetParticle(j)->GetPdgCode() != trackEvent->GetParticle(j)->GetPdgCode() )
919 Error("AliHBTAnalysis::RunCoherencyCheck()",
920 "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
921 i,j, partEvent->GetParticle(j)->GetPdgCode(),trackEvent->GetParticle(j)->GetPdgCode() );
927 Info("RunCoherencyCheck"," Done");
928 Info("RunCoherencyCheck"," Everything looks OK");
932 /*************************************************************************************/
934 void AliHBTAnalysis::ProcessTracksAndParticlesNonIdentAnal()
936 //Performs analysis for both, tracks and particles
938 AliHBTParticle * part1, * part2;
939 AliHBTParticle * track1, * track2;
941 AliHBTEvent * trackEvent1=0x0,*partEvent1=0x0;
942 AliHBTEvent * trackEvent2=0x0,*partEvent2=0x0;
943 AliHBTEvent * trackEvent3=0x0,*partEvent3=0x0;
945 AliHBTEvent * rawtrackEvent, *rawpartEvent;//this we get from Reader
947 AliHBTPair * trackpair = new AliHBTPair();
948 AliHBTPair * partpair = new AliHBTPair();
950 AliHBTEventBuffer partbuffer(fBufferSize);
951 AliHBTEventBuffer trackbuffer(fBufferSize);
955 trackEvent1 = new AliHBTEvent();
956 partEvent1 = new AliHBTEvent();
957 trackEvent1->SetOwner(kFALSE);
958 partEvent1->SetOwner(kFALSE);;
960 Bool_t nocorrfctns = (fNParticleFunctions == 0) && (fNTrackFunctions == 0) && (fNParticleAndTrackFunctions == 0);
964 Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
965 Info("ProcessTracksAndParticlesNonIdentAnal","***** NON IDENT MODE ****************");
966 Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
968 for (Int_t i = 0;;i++)//infinite loop
970 if (fReader->Next()) break; //end when no more events available
972 rawpartEvent = fReader->GetParticleEvent();
973 rawtrackEvent = fReader->GetTrackEvent();
974 if ( (rawpartEvent == 0x0) || (rawtrackEvent == 0x0) ) continue;//in case of any error
976 if ( rawpartEvent->GetNumberOfParticles() != rawtrackEvent->GetNumberOfParticles() )
978 Fatal("ProcessTracksAndParticlesNonIdentAnal",
979 "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
980 i,rawpartEvent->GetNumberOfParticles() , rawtrackEvent->GetNumberOfParticles());
984 /********************************/
986 /********************************/
987 if ( ( (partEvent2==0x0) || (trackEvent2==0x0)) )//in case fBufferSize == 0 and pointers are created do not eneter
989 partEvent2 = new AliHBTEvent();
990 trackEvent2 = new AliHBTEvent();
991 partEvent2->SetOwner(kTRUE);
992 trackEvent2->SetOwner(kTRUE);
995 FilterOut(partEvent1, partEvent2, rawpartEvent, trackEvent1, trackEvent2, rawtrackEvent);
997 for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
999 if ( (j%fDisplayMixingInfo) == 0)
1000 Info("ProcessTracksAndParticlesNonIdentAnal",
1001 "Mixing particle %d from event %d with particles from event %d",j,i,i);
1003 part1= partEvent1->GetParticle(j);
1004 track1= trackEvent1->GetParticle(j);
1006 //PID reconstruction imperfections
1007 // if( part1->GetPdgCode() != track1->GetPdgCode() )
1009 // Fatal("ProcessTracksAndParticlesNonIdentAnal",
1010 // "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
1011 // i,j, part1->GetPdgCode(),track1->GetPdgCode() );
1015 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
1016 fParticleMonitorFunctions[ii]->Process(part1);
1017 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
1018 fTrackMonitorFunctions[ii]->Process(track1);
1019 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
1020 fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
1022 if (nocorrfctns) continue;
1024 /***************************************/
1025 /****** filling numerators ********/
1026 /****** (particles from event2) ********/
1027 /***************************************/
1029 for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups
1031 part2= partEvent2->GetParticle(k);
1032 if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
1033 partpair->SetParticles(part1,part2);
1035 track2= trackEvent2->GetParticle(k);
1036 trackpair->SetParticles(track1,track2);
1038 if( (fPairCut->PassPairProp(trackpair)) ) //check pair cut
1039 { //do not meets crietria of the pair cut
1043 {//meets criteria of the pair cut
1044 for(ii = 0;ii<fNParticleFunctions;ii++)
1045 fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1047 for(ii = 0;ii<fNTrackFunctions;ii++)
1048 fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1050 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
1051 fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(trackpair,partpair);
1055 if ( fBufferSize == 0) continue;//do not mix diff histograms
1056 /***************************************/
1057 /***** Filling denominators *********/
1058 /***************************************/
1059 partbuffer.ResetIter();
1060 trackbuffer.ResetIter();
1064 while ( (partEvent3 = partbuffer.Next() ) != 0x0)
1066 trackEvent3 = trackbuffer.Next();
1068 if ( (j%fDisplayMixingInfo) == 0)
1069 Info("ProcessTracksAndParticlesNonIdentAnal",
1070 "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1072 for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1074 part2= partEvent3->GetParticle(k);
1075 partpair->SetParticles(part1,part2);
1077 track2= trackEvent3->GetParticle(k);
1078 trackpair->SetParticles(track1,track2);
1080 if( (fPairCut->PassPairProp(trackpair)) ) //check pair cut
1081 { //do not meets crietria of the pair cut
1085 {//meets criteria of the pair cut
1087 for(ii = 0;ii<fNParticleFunctions;ii++)
1088 fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1090 for(ii = 0;ii<fNTrackFunctions;ii++)
1091 fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1093 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
1094 fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(trackpair,partpair);
1096 }// for particles event2
1098 }//for over particles in event1
1100 partEvent2 = partbuffer.Push(partEvent2);
1101 trackEvent2 = trackbuffer.Push(trackEvent2);
1103 }//end of loop over events (1)
1105 partbuffer.SetOwner(kTRUE);
1106 trackbuffer.SetOwner(kTRUE);
1116 /*************************************************************************************/
1118 void AliHBTAnalysis::ProcessTracksNonIdentAnal()
1120 //Process Tracks only with non identical mode
1121 AliHBTParticle * track1, * track2;
1123 AliHBTEvent * trackEvent1=0x0;
1124 AliHBTEvent * trackEvent2=0x0;
1125 AliHBTEvent * trackEvent3=0x0;
1127 AliHBTEvent * rawtrackEvent;
1129 AliHBTPair * trackpair = new AliHBTPair();
1130 AliHBTEventBuffer trackbuffer(fBufferSize);
1134 trackEvent1 = new AliHBTEvent();
1135 trackEvent1->SetOwner(kFALSE);
1139 Info("ProcessTracksNonIdentAnal","**************************************");
1140 Info("ProcessTracksNonIdentAnal","***** NON IDENT MODE ****************");
1141 Info("ProcessTracksNonIdentAnal","**************************************");
1144 for (Int_t i = 0;;i++)//infinite loop
1146 if (fReader->Next()) break; //end when no more events available
1147 rawtrackEvent = fReader->GetTrackEvent();
1149 if (rawtrackEvent == 0x0) continue;//in case of any error
1151 /********************************/
1153 /********************************/
1154 if ( trackEvent2==0x0 )//in case fBufferSize == 0 and pointers are created do not eneter
1156 trackEvent2 = new AliHBTEvent();
1157 trackEvent2->SetOwner(kTRUE);
1160 FilterOut(trackEvent1, trackEvent2, rawtrackEvent);
1162 for (Int_t j = 0; j<trackEvent1->GetNumberOfParticles() ; j++)
1164 if ( (j%fDisplayMixingInfo) == 0)
1165 Info("ProcessTracksNonIdentAnal",
1166 "Mixing particle %d from event %d with particles from event %d",j,i,i);
1168 track1= trackEvent1->GetParticle(j);
1170 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
1171 fTrackMonitorFunctions[ii]->Process(track1);
1173 if (fNTrackFunctions == 0x0) continue;
1175 /***************************************/
1176 /****** filling numerators ********/
1177 /****** (particles from event2) ********/
1178 /***************************************/
1179 for (Int_t k = 0; k < trackEvent2->GetNumberOfParticles() ; k++)
1181 track2= trackEvent2->GetParticle(k);
1182 if (track1->GetUID() == track2->GetUID()) continue;//this is the same particle but with different PID
1183 trackpair->SetParticles(track1,track2);
1186 if( fPairCut->PassPairProp(trackpair)) //check pair cut
1187 { //do not meets crietria of the pair cut
1191 {//meets criteria of the pair cut
1193 for(ii = 0;ii<fNTrackFunctions;ii++)
1194 fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1197 if ( fBufferSize == 0) continue;//do not mix diff histograms
1198 /***************************************/
1199 /***** Filling denominators *********/
1200 /***************************************/
1201 trackbuffer.ResetIter();
1204 while ( (trackEvent3 = trackbuffer.Next() ) != 0x0)
1207 if ( (j%fDisplayMixingInfo) == 0)
1208 Info("ProcessTracksNonIdentAnal",
1209 "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1211 for (Int_t k = 0; k < trackEvent3->GetNumberOfParticles() ; k++)
1214 track2= trackEvent3->GetParticle(k);
1215 trackpair->SetParticles(track1,track2);
1218 if( fPairCut->PassPairProp(trackpair)) //check pair cut
1219 { //do not meets crietria of the pair cut
1223 {//meets criteria of the pair cut
1224 for(ii = 0;ii<fNTrackFunctions;ii++)
1225 fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1227 }// for particles event2
1229 }//for over particles in event1
1231 trackEvent2 = trackbuffer.Push(trackEvent2);
1233 }//end of loop over events (1)
1235 trackbuffer.SetOwner(kTRUE);
1240 /*************************************************************************************/
1242 void AliHBTAnalysis::ProcessParticlesNonIdentAnal()
1244 //process paricles only with non identical mode
1245 AliHBTParticle * part1 = 0x0, * part2 = 0x0;
1247 AliHBTEvent * partEvent1 = 0x0;
1248 AliHBTEvent * partEvent2 = 0x0;
1249 AliHBTEvent * partEvent3 = 0x0;
1251 AliHBTEvent * rawpartEvent = 0x0;
1253 AliHBTPair * partpair = new AliHBTPair();
1254 AliHBTEventBuffer partbuffer(fBufferSize);
1258 partEvent1 = new AliHBTEvent();
1259 partEvent1->SetOwner(kFALSE);
1263 Info("ProcessParticlesNonIdentAnal","**************************************");
1264 Info("ProcessParticlesNonIdentAnal","***** NON IDENT MODE ****************");
1265 Info("ProcessParticlesNonIdentAnal","**************************************");
1267 for (Int_t i = 0;;i++)//infinite loop
1269 if (fReader->Next()) break; //end when no more events available
1271 rawpartEvent = fReader->GetParticleEvent();
1272 if ( rawpartEvent == 0x0 ) continue;//in case of any error
1274 /********************************/
1276 /********************************/
1277 if (partEvent2==0x0)//in case fBufferSize == 0 and pointers are created do not eneter
1279 partEvent2 = new AliHBTEvent();
1280 partEvent2->SetOwner(kTRUE);
1283 FilterOut(partEvent1, partEvent2, rawpartEvent);
1285 for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
1287 if ( (j%fDisplayMixingInfo) == 0)
1288 Info("ProcessParticlesNonIdentAnal",
1289 "Mixing particle %d from event %d with particles from event %d",j,i,i);
1291 part1= partEvent1->GetParticle(j);
1293 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
1294 fParticleMonitorFunctions[ii]->Process(part1);
1296 if (fNParticleFunctions == 0) continue;
1298 /***************************************/
1299 /****** filling numerators ********/
1300 /****** (particles from event2) ********/
1301 /***************************************/
1302 for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++)
1304 part2= partEvent2->GetParticle(k);
1305 if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
1306 partpair->SetParticles(part1,part2);
1308 if(fPairCut->PassPairProp(partpair) ) //check pair cut
1309 { //do not meets crietria of the pair cut
1313 {//meets criteria of the pair cut
1314 for(ii = 0;ii<fNParticleFunctions;ii++)
1315 fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1318 if ( fBufferSize == 0) continue;//do not mix diff histograms
1319 /***************************************/
1320 /***** Filling denominators *********/
1321 /***************************************/
1322 partbuffer.ResetIter();
1325 while ( (partEvent3 = partbuffer.Next() ) != 0x0)
1327 if ( (j%fDisplayMixingInfo) == 0)
1328 Info("ProcessParticlesNonIdentAnal",
1329 "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1331 for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1333 part2= partEvent3->GetParticle(k);
1334 partpair->SetParticles(part1,part2);
1336 if(fPairCut->PassPairProp(partpair) ) //check pair cut
1337 { //do not meets crietria of the pair cut
1341 {//meets criteria of the pair cut
1342 for(ii = 0;ii<fNParticleFunctions;ii++)
1344 fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1347 }// for particles event2
1349 }//for over particles in event1
1350 partEvent2 = partbuffer.Push(partEvent2);
1351 }//end of loop over events (1)
1353 partbuffer.SetOwner(kTRUE);
1359 /*************************************************************************************/
1360 void AliHBTAnalysis::FilterOut(AliHBTEvent* outpart1, AliHBTEvent* outpart2, AliHBTEvent* inpart,
1361 AliHBTEvent* outtrack1, AliHBTEvent* outtrack2, AliHBTEvent* intrack)
1363 //Puts particles accepted as a first particle by global cut in out1
1364 //and as a second particle in out2
1366 AliHBTParticle* part, *track;
1373 AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1374 AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1378 for (Int_t i = 0; i < inpart->GetNumberOfParticles(); i++)
1381 part = inpart->GetParticle(i);
1382 track = intrack->GetParticle(i);
1384 if ( (cut1->Pass(track)) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1385 if ( (cut2->Pass(track)) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
1387 if (gDebug)//to be removed in real analysis
1388 if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1390 //Particle accpted by both cuts
1391 Error("FilterOut","Particle accepted by both cuts");
1397 outpart1->AddParticle(part);
1398 outtrack1->AddParticle(track);
1404 outpart2->AddParticle(new AliHBTParticle(*part));
1405 outtrack2->AddParticle(new AliHBTParticle(*track));
1410 /*************************************************************************************/
1412 void AliHBTAnalysis::FilterOut(AliHBTEvent* out1, AliHBTEvent* out2, AliHBTEvent* in)
1414 //Puts particles accepted as a first particle by global cut in out1
1415 //and as a second particle in out2
1416 AliHBTParticle* part;
1421 AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1422 AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1426 for (Int_t i = 0; i < in->GetNumberOfParticles(); i++)
1429 part = in->GetParticle(i);
1431 if ( cut1->Pass(part) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1432 if ( cut2->Pass(part) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
1434 if (gDebug)//to be removed in real analysis
1435 if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1437 //Particle accpted by both cuts
1438 Error("FilterOut","Particle accepted by both cuts");
1444 out1->AddParticle(part);
1450 out2->AddParticle(part);
1455 /*************************************************************************************/
1457 Bool_t AliHBTAnalysis::IsNonIdentAnalysis()
1459 //checks if it is possible to use special analysis for non identical particles
1460 //it means - in global pair cut first particle id is different than second one
1461 //and both are different from 0
1462 //in the future is possible to perform more sophisticated check
1463 //if cuts have excluding requirements
1465 if (fPairCut->IsEmpty())
1468 if (fPairCut->GetFirstPartCut()->IsEmpty())
1471 if (fPairCut->GetSecondPartCut()->IsEmpty())
1474 Int_t id1 = fPairCut->GetFirstPartCut()->GetPID();
1475 Int_t id2 = fPairCut->GetSecondPartCut()->GetPID();
1477 if ( (id1==0) || (id2==0) || (id1==id2) )
1483 /*************************************************************************************/
1485 void AliHBTAnalysis::PressAnyKey()
1486 { //small utility function that helps to make comfortable macros
1489 fcntl(0, F_SETFL, O_NONBLOCK);
1490 ::Info("","Press Any Key to continue ...");
1493 nread = read(0, &c, 1);
1494 gSystem->ProcessEvents();