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"
33 #include <TBenchmark.h>
37 ClassImp(AliHBTAnalysis)
39 const UInt_t AliHBTAnalysis::fgkFctnArraySize = 100;
40 const UInt_t AliHBTAnalysis::fgkDefaultMixingInfo = 1000;
41 const Int_t AliHBTAnalysis::fgkDefaultBufferSize = 5;
43 AliHBTAnalysis::AliHBTAnalysis():
46 fNParticleFunctions(0),
47 fNParticleAndTrackFunctions(0),
48 fNTrackMonitorFunctions(0),
49 fNParticleMonitorFunctions(0),
50 fNParticleAndTrackMonitorFunctions(0),
52 fDisplayMixingInfo(fgkDefaultMixingInfo),
56 fTrackFunctions = new AliHBTOnePairFctn* [fgkFctnArraySize];
57 fParticleFunctions = new AliHBTOnePairFctn* [fgkFctnArraySize];
58 fParticleAndTrackFunctions = new AliHBTTwoPairFctn* [fgkFctnArraySize];
60 fParticleMonitorFunctions = new AliHBTMonOneParticleFctn* [fgkFctnArraySize];
61 fTrackMonitorFunctions = new AliHBTMonOneParticleFctn* [fgkFctnArraySize];
62 fParticleAndTrackMonitorFunctions = new AliHBTMonTwoParticleFctn* [fgkFctnArraySize];
64 fPairCut = new AliHBTEmptyPairCut();//empty cut - accepts all particles
66 /*************************************************************************************/
68 AliHBTAnalysis::AliHBTAnalysis(const AliHBTAnalysis& in):
72 fNParticleFunctions(0),
73 fNParticleAndTrackFunctions(0),
74 fNTrackMonitorFunctions(0),
75 fNParticleMonitorFunctions(0),
76 fNParticleAndTrackMonitorFunctions(0),
78 fParticleFunctions(0x0),
79 fParticleAndTrackFunctions(0x0),
80 fParticleMonitorFunctions(0x0),
81 fTrackMonitorFunctions(0x0),
82 fParticleAndTrackMonitorFunctions(0x0),
84 fBufferSize(fgkDefaultBufferSize),
85 fDisplayMixingInfo(fgkDefaultMixingInfo),
89 Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
91 /*************************************************************************************/
92 const AliHBTAnalysis& AliHBTAnalysis::operator=(const AliHBTAnalysis& /*right*/)
95 Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
98 /*************************************************************************************/
99 AliHBTAnalysis::~AliHBTAnalysis()
102 //note that we do not delete functions itself
103 // they should be deleted by whom where created
104 //we only store pointers, and we use "new" only for pointers array
107 delete [] fTrackFunctions;
108 delete [] fParticleFunctions;
109 delete [] fParticleAndTrackFunctions;
111 delete [] fParticleMonitorFunctions;
112 delete [] fTrackMonitorFunctions;
113 delete [] fParticleAndTrackMonitorFunctions;
115 delete fPairCut; // always have an copy of an object - we create we dstroy
118 /*************************************************************************************/
120 void AliHBTAnalysis::DeleteFunctions()
122 //Deletes all functions added to analysis
124 for(ii = 0;ii<fNParticleFunctions;ii++)
125 delete fParticleFunctions[ii];
126 fNParticleFunctions = 0;
128 for(ii = 0;ii<fNTrackFunctions;ii++)
129 delete fTrackFunctions[ii];
130 fNTrackFunctions = 0;
132 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
133 delete fParticleAndTrackFunctions[ii];
134 fNParticleAndTrackFunctions = 0;
136 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
137 delete fParticleMonitorFunctions[ii];
138 fNParticleMonitorFunctions = 0;
140 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
141 delete fTrackMonitorFunctions[ii];
142 fNTrackMonitorFunctions = 0;
144 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
145 delete fParticleAndTrackMonitorFunctions[ii];
146 fNParticleAndTrackMonitorFunctions = 0;
149 /*************************************************************************************/
151 void AliHBTAnalysis::Init()
153 //Initializeation method
154 //calls Init for all functions
156 for(ii = 0;ii<fNParticleFunctions;ii++)
157 fParticleFunctions[ii]->Init();
159 for(ii = 0;ii<fNTrackFunctions;ii++)
160 fTrackFunctions[ii]->Init();
162 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
163 fParticleAndTrackFunctions[ii]->Init();
165 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
166 fParticleMonitorFunctions[ii]->Init();
168 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
169 fTrackMonitorFunctions[ii]->Init();
171 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
172 fParticleAndTrackMonitorFunctions[ii]->Init();
176 /*************************************************************************************/
178 void AliHBTAnalysis::ResetFunctions()
180 //In case fOwner is true, deletes all functions
181 //in other case, just set number of analysis to 0
182 if (fIsOwner) DeleteFunctions();
185 fNParticleFunctions = 0;
186 fNTrackFunctions = 0;
187 fNParticleAndTrackFunctions = 0;
188 fNParticleMonitorFunctions = 0;
189 fNTrackMonitorFunctions = 0;
190 fNParticleAndTrackMonitorFunctions = 0;
193 /*************************************************************************************/
195 void AliHBTAnalysis::Process(Option_t* option)
197 //default option = "TracksAndParticles"
198 //Main method of the HBT Analysis Package
199 //It triggers reading with the global cut (default is an empty cut)
200 //Than it checks options and data which are read
201 //if everything is OK, then it calls one of the looping methods
202 //depending on tfReaderhe option
203 //These methods differs on what thay are looping on
206 //--------------------------------------------------------------------
207 //ProcessTracksAndParticles - "TracksAndParticles"
209 // it loops over both, tracks(reconstructed) and particles(simulated)
210 // all function gethered in all 3 lists are called for each (double)pair
212 //ProcessTracks - "Tracks"
213 // it loops only on tracks(reconstructed),
214 // functions ONLY from fTrackFunctions list are called
216 //ProcessParticles - "Particles"
217 // it loops only on particles(simulated),
218 // functions ONLY from fParticleAndTrackFunctions list are called
223 Error("Process","The reader is not set");
227 const char *oT = strstr(option,"Tracks");
228 const char *oP = strstr(option,"Particles");
230 Bool_t nonid = IsNonIdentAnalysis();
236 if (nonid) ProcessTracksAndParticlesNonIdentAnal();
237 else ProcessTracksAndParticles();
243 if (nonid) ProcessTracksNonIdentAnal();
244 else ProcessTracks();
250 if (nonid) ProcessParticlesNonIdentAnal();
251 else ProcessParticles();
256 /*************************************************************************************/
258 void AliHBTAnalysis::ProcessTracksAndParticles()
260 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
261 //the loops are splited
264 AliHBTParticle * part1, * part2;
265 AliHBTParticle * track1, * track2;
267 AliHBTEvent * trackEvent, *partEvent;
268 AliHBTEvent * trackEvent1 = 0x0,*partEvent1 = 0x0;
269 AliHBTEvent * trackEvent2,*partEvent2;
271 // Int_t N1, N2, N=0; //number of particles in current event(we prcess two events in one time)
273 // Int_t nev = fReader->GetNumberOfTrackEvents();
274 AliHBTPair * trackpair = new AliHBTPair();
275 AliHBTPair * partpair = new AliHBTPair();
277 AliHBTPair * tmptrackpair;//temprary pointers to pairs
278 AliHBTPair * tmppartpair;
280 AliHBTEventBuffer partbuffer(fBufferSize);
281 AliHBTEventBuffer trackbuffer(fBufferSize);
287 Bool_t nocorrfctns = (fNParticleFunctions == 0) && (fNTrackFunctions == 0) && (fNParticleAndTrackFunctions == 0);
291 while (fReader->Next() == kFALSE)
295 partEvent= fReader->GetParticleEvent();
296 trackEvent = fReader->GetTrackEvent();
298 if ( !partEvent || !trackEvent )
300 Error("ProcessTracksAndParticles","Can not get event");
304 if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
306 Fatal("ProcessTracksAndParticles",
307 "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
308 i,partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
312 if(partEvent1 == 0x0)
314 partEvent1 = new AliHBTEvent();
315 partEvent1->SetOwner(kTRUE);
317 trackEvent1 = new AliHBTEvent();
318 trackEvent1->SetOwner(kTRUE);
323 trackEvent1->Reset();
326 for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
328 /***************************************/
329 /****** Looping same events ********/
330 /****** filling numerators ********/
331 /***************************************/
332 if ( (j%fDisplayMixingInfo) == 0)
333 Info("ProcessTracksAndParticles",
334 "Mixing particle %d from event %d with particles from event %d",j,i,i);
336 part1= partEvent->GetParticle(j);
337 track1= trackEvent->GetParticle(j);
339 //PID imperfections ???
340 // if( part1->GetPdgCode() != track1->GetPdgCode() )
342 // Fatal("ProcessTracksAndParticles",
343 // "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
344 // i,j, part1->GetPdgCode(),track1->GetPdgCode() );
348 Bool_t firstcut = fPairCut->GetFirstPartCut()->Pass(part1);
349 if (fBufferSize != 0)
350 if ( (firstcut == kFALSE) || (fPairCut->GetSecondPartCut()->Pass(part1) == kFALSE) )
352 //accepted by any cut
353 // we have to copy because reader keeps only one event
355 partEvent1->AddParticle(new AliHBTParticle(*part1));
356 trackEvent1->AddParticle(new AliHBTParticle(*track1));
359 if (firstcut) continue;
363 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
364 fParticleMonitorFunctions[ii]->Process(part1);
365 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
366 fTrackMonitorFunctions[ii]->Process(track1);
367 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
368 fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
370 if (nocorrfctns) continue;
372 for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
374 part2= partEvent->GetParticle(k);
375 if (part1->GetUID() == part2->GetUID()) continue;
376 partpair->SetParticles(part1,part2);
378 track2= trackEvent->GetParticle(k);
379 trackpair->SetParticles(track1,track2);
381 if(fPairCut->Pass(trackpair) ) //check pair cut
382 { //do not meets crietria of the pair cut, try with swapped pairs
383 if( fPairCut->Pass(trackpair->GetSwapedPair()) )
384 continue; //swaped pairs do not meet criteria of pair cut as well, take next particle
386 { //swaped pair meets all the criteria
387 tmppartpair = partpair->GetSwapedPair();
388 tmptrackpair = trackpair->GetSwapedPair();
392 {//meets criteria of the pair cut
393 tmptrackpair = trackpair;
394 tmppartpair = partpair;
396 for(ii = 0;ii<fNParticleFunctions;ii++)
397 fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
399 for(ii = 0;ii<fNTrackFunctions;ii++)
400 fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
402 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
403 fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair,tmppartpair);
404 //end of 2nd loop over particles from the same event
405 }//for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
407 /***************************************/
408 /***** Filling denominators *********/
409 /***************************************/
410 if (fBufferSize == 0) continue;
412 partbuffer.ResetIter();
413 trackbuffer.ResetIter();
415 while (( partEvent2 = partbuffer.Next() ))
417 trackEvent2 = trackbuffer.Next();
420 if ( (j%fDisplayMixingInfo) == 0)
421 Info("ProcessTracksAndParticles",
422 "Mixing particle %d from event %d with particles from event %d",j,i,i-m);
424 for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++) // ... on all particles
426 part2= partEvent2->GetParticle(l);
427 partpair->SetParticles(part1,part2);
429 track2= trackEvent2->GetParticle(l);
430 trackpair->SetParticles(track1,track2);
432 if( fPairCut->Pass(partpair) ) //check pair cut
433 { //do not meets crietria of the
434 if( fPairCut->Pass(partpair->GetSwapedPair()) )
438 tmppartpair = partpair->GetSwapedPair();
439 tmptrackpair = trackpair->GetSwapedPair();
443 {//meets criteria of the pair cut
444 tmptrackpair = trackpair;
445 tmppartpair = partpair;
447 for(ii = 0;ii<fNParticleFunctions;ii++)
448 fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
450 for(ii = 0;ii<fNTrackFunctions;ii++)
451 fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
453 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
454 fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair,tmppartpair);
455 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
458 //end of loop over particles from first event
459 }//for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
460 partEvent1 = partbuffer.Push(partEvent1);
461 trackEvent1 = trackbuffer.Push(trackEvent1);
462 //end of loop over events
463 }//while (fReader->Next() == kFALSE)
465 /*************************************************************************************/
467 void AliHBTAnalysis::ProcessTracks()
469 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
470 //the loops are splited
471 AliHBTParticle * track1, * track2;
472 AliHBTEvent * trackEvent;
473 AliHBTEvent * trackEvent1 = 0x0;
474 AliHBTEvent * trackEvent2;
478 AliHBTPair * trackpair = new AliHBTPair();
479 AliHBTPair * tmptrackpair; //temporary pointer
481 AliHBTEventBuffer trackbuffer(fBufferSize);
485 while (fReader->Next() == kFALSE)
488 trackEvent = fReader->GetTrackEvent();
489 if (!trackEvent) continue;
491 if(trackEvent1 == 0x0)
493 trackEvent1 = new AliHBTEvent();
494 trackEvent1->SetOwner(kTRUE);
498 trackEvent1->Reset();
501 for (Int_t j = 0; j<trackEvent->GetNumberOfParticles() ; j++)
503 /***************************************/
504 /****** Looping same events ********/
505 /****** filling numerators ********/
506 /***************************************/
507 if ( (j%fDisplayMixingInfo) == 0)
508 Info("ProcessTracks",
509 "Mixing particle %d from event %d with particles from event %d",j,i,i);
511 track1= trackEvent->GetParticle(j);
512 Bool_t firstcut = fPairCut->GetFirstPartCut()->Pass(track1);
514 if (fBufferSize != 0)
515 if ( (firstcut == kFALSE) || (fPairCut->GetSecondPartCut()->Pass(track1) == kFALSE) )
517 //accepted by any cut
518 // we have to copy because reader keeps only one event
519 trackEvent1->AddParticle(new AliHBTParticle(*track1));
522 if (firstcut) continue;
524 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
525 fTrackMonitorFunctions[ii]->Process(track1);
527 if ( fNTrackFunctions ==0 ) continue;
529 for (Int_t k =j+1; k < trackEvent->GetNumberOfParticles() ; k++)
531 track2= trackEvent->GetParticle(k);
532 if (track1->GetUID() == track2->GetUID()) continue;
534 trackpair->SetParticles(track1,track2);
535 if(fPairCut->Pass(trackpair)) //check pair cut
536 { //do not meets crietria of the
537 if( fPairCut->Pass(trackpair->GetSwapedPair()) ) continue;
538 else tmptrackpair = trackpair->GetSwapedPair();
542 tmptrackpair = trackpair;
544 for(ii = 0;ii<fNTrackFunctions;ii++)
545 fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
547 /***************************************/
548 /***** Filling denominators *********/
549 /***************************************/
551 if (fBufferSize == 0) continue;
553 trackbuffer.ResetIter();
556 while (( trackEvent2 = trackbuffer.Next() ))
559 if ( (j%fDisplayMixingInfo) == 0)
560 Info("ProcessTracks",
561 "Mixing track %d from event %d with tracks from event %d",j,i,i-m);
562 for(Int_t l = 0; l<trackEvent2->GetNumberOfParticles();l++) // ... on all particles
565 track2= trackEvent2->GetParticle(l);
566 trackpair->SetParticles(track1,track2);
568 if( fPairCut->Pass(trackpair) ) //check pair cut
569 { //do not meets crietria of the
570 if( fPairCut->Pass(trackpair->GetSwapedPair()) )
574 tmptrackpair = trackpair->GetSwapedPair();
578 {//meets criteria of the pair cut
579 tmptrackpair = trackpair;
582 for(ii = 0;ii<fNTrackFunctions;ii++)
583 fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
585 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
589 trackEvent1 = trackbuffer.Push(trackEvent1);
590 }//while (fReader->Next() == kFALSE)
593 /*************************************************************************************/
595 void AliHBTAnalysis::ProcessParticles()
597 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
598 //the loops are splited
599 AliHBTParticle * part1, * part2;
600 AliHBTEvent * partEvent;
601 AliHBTEvent * partEvent1 = 0x0;
602 AliHBTEvent * partEvent2;
606 AliHBTPair * partpair = new AliHBTPair();
607 AliHBTPair * tmppartpair; //temporary pointer
609 AliHBTEventBuffer partbuffer(fBufferSize);
613 while (fReader->Next() == kFALSE)
616 partEvent = fReader->GetParticleEvent();
617 if (!partEvent) continue;
619 if(partEvent1 == 0x0)
621 partEvent1 = new AliHBTEvent();
622 partEvent1->SetOwner(kTRUE);
629 for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
631 /***************************************/
632 /****** Looping same events ********/
633 /****** filling numerators ********/
634 /***************************************/
635 if ( (j%fDisplayMixingInfo) == 0)
636 Info("ProcessParticles",
637 "Mixing particle %d from event %d with particles from event %d",j,i,i);
639 part1 = partEvent->GetParticle(j);
640 Bool_t firstcut = fPairCut->GetFirstPartCut()->Pass(part1);
642 if (fBufferSize != 0) //useless in case
643 if ( (firstcut == kFALSE) || (fPairCut->GetSecondPartCut()->Pass(part1) == kFALSE) )
645 //accepted by any cut
646 // we have to copy because reader keeps only one event
647 partEvent1->AddParticle(new AliHBTParticle(*part1));
650 if (firstcut) continue;
652 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
653 fParticleMonitorFunctions[ii]->Process(part1);
655 if ( fNParticleFunctions == 0 ) continue;
657 for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
659 part2= partEvent->GetParticle(k);
660 if (part1->GetUID() == part2->GetUID()) continue;
662 partpair->SetParticles(part1,part2);
663 if(fPairCut->Pass(partpair)) //check pair cut
664 { //do not meets crietria of the
665 if( fPairCut->Pass(partpair->GetSwapedPair()) ) continue;
666 else tmppartpair = partpair->GetSwapedPair();
670 tmppartpair = partpair;
672 for(ii = 0;ii<fNParticleFunctions;ii++)
673 fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
675 /***************************************/
676 /***** Filling denominators *********/
677 /***************************************/
679 if (fBufferSize == 0) continue;
681 partbuffer.ResetIter();
684 while (( partEvent2 = partbuffer.Next() ))
687 if ( (j%fDisplayMixingInfo) == 0)
688 Info("ProcessParticles",
689 "Mixing particle %d from event %d with particles from event %d",j,i,i-m);
690 for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++) // ... on all particles
693 part2= partEvent2->GetParticle(l);
694 partpair->SetParticles(part1,part2);
696 if( fPairCut->Pass(partpair) ) //check pair cut
697 { //do not meets crietria of the
698 if( fPairCut->Pass(partpair->GetSwapedPair()) )
702 tmppartpair = partpair->GetSwapedPair();
706 {//meets criteria of the pair cut
707 tmppartpair = partpair;
710 for(ii = 0;ii<fNParticleFunctions;ii++)
711 fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
713 }//for(Int_t l = 0; l<N2;l++) // ... on all particles
716 partEvent1 = partbuffer.Push(partEvent1);
717 }//while (fReader->Next() == kFALSE)
719 /*************************************************************************************/
721 void AliHBTAnalysis::WriteFunctions()
723 //Calls Write for all defined functions in analysis
724 //== writes all results
726 for(ii = 0;ii<fNParticleFunctions;ii++)
727 fParticleFunctions[ii]->Write();
729 for(ii = 0;ii<fNTrackFunctions;ii++)
730 fTrackFunctions[ii]->Write();
732 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
733 fParticleAndTrackFunctions[ii]->Write();
735 for(ii = 0;ii<fNParticleMonitorFunctions;ii++)
736 fParticleMonitorFunctions[ii]->Write();
738 for(ii = 0;ii<fNTrackMonitorFunctions;ii++)
739 fTrackMonitorFunctions[ii]->Write();
741 for(ii = 0;ii<fNParticleAndTrackMonitorFunctions;ii++)
742 fParticleAndTrackMonitorFunctions[ii]->Write();
744 /*************************************************************************************/
746 void AliHBTAnalysis::SetGlobalPairCut(AliHBTPairCut* cut)
748 //Sets the global cut
751 Error("AliHBTAnalysis::SetGlobalPairCut","Pointer is NULL. Ignoring");
754 fPairCut = (AliHBTPairCut*)cut->Clone();
757 /*************************************************************************************/
759 void AliHBTAnalysis::AddTrackFunction(AliHBTOnePairFctn* f)
761 //Adds track function
762 if (f == 0x0) return;
763 if (fNTrackFunctions == fgkFctnArraySize)
765 Error("AliHBTAnalysis::AddTrackFunction","Can not add this function, not enough place in the array.");
767 fTrackFunctions[fNTrackFunctions] = f;
770 /*************************************************************************************/
772 void AliHBTAnalysis::AddParticleFunction(AliHBTOnePairFctn* f)
774 //adds particle function
775 if (f == 0x0) return;
777 if (fNParticleFunctions == fgkFctnArraySize)
779 Error("AliHBTAnalysis::AddParticleFunction","Can not add this function, not enough place in the array.");
781 fParticleFunctions[fNParticleFunctions] = f;
782 fNParticleFunctions++;
784 /*************************************************************************************/
786 void AliHBTAnalysis::AddParticleAndTrackFunction(AliHBTTwoPairFctn* f)
788 //add resolution function
789 if (f == 0x0) return;
790 if (fNParticleAndTrackFunctions == fgkFctnArraySize)
792 Error("AliHBTAnalysis::AddParticleAndTrackFunction","Can not add this function, not enough place in the array.");
794 fParticleAndTrackFunctions[fNParticleAndTrackFunctions] = f;
795 fNParticleAndTrackFunctions++;
797 /*************************************************************************************/
799 void AliHBTAnalysis::AddParticleMonitorFunction(AliHBTMonOneParticleFctn* f)
801 //add particle monitoring function
802 if (f == 0x0) return;
804 if (fNParticleMonitorFunctions == fgkFctnArraySize)
806 Error("AliHBTAnalysis::AddParticleMonitorFunction","Can not add this function, not enough place in the array.");
808 fParticleMonitorFunctions[fNParticleMonitorFunctions] = f;
809 fNParticleMonitorFunctions++;
811 /*************************************************************************************/
813 void AliHBTAnalysis::AddTrackMonitorFunction(AliHBTMonOneParticleFctn* f)
815 //add track monitoring function
816 if (f == 0x0) return;
818 if (fNTrackMonitorFunctions == fgkFctnArraySize)
820 Error("AliHBTAnalysis::AddTrackMonitorFunction","Can not add this function, not enough place in the array.");
822 fTrackMonitorFunctions[fNTrackMonitorFunctions] = f;
823 fNTrackMonitorFunctions++;
825 /*************************************************************************************/
827 void AliHBTAnalysis::AddParticleAndTrackMonitorFunction(AliHBTMonTwoParticleFctn* f)
829 //add resolution monitoring function
830 if (f == 0x0) return;
831 if (fNParticleAndTrackMonitorFunctions == fgkFctnArraySize)
833 Error("AliHBTAnalysis::AddParticleAndTrackMonitorFunction","Can not add this function, not enough place in the array.");
835 fParticleAndTrackMonitorFunctions[fNParticleAndTrackMonitorFunctions] = f;
836 fNParticleAndTrackMonitorFunctions++;
840 /*************************************************************************************/
841 /*************************************************************************************/
843 Bool_t AliHBTAnalysis::RunCoherencyCheck()
845 //Checks if both HBTRuns are similar
846 //return true if error found
847 //if they seem to be OK return false
849 Info("RunCoherencyCheck","Checking HBT Runs Coherency");
851 Info("RunCoherencyCheck","Number of events ...");
852 if (fReader->GetNumberOfPartEvents() == fReader->GetNumberOfTrackEvents() ) //check whether there is the same number of events
854 Info("RunCoherencyCheck","OK. %d found\n",fReader->GetNumberOfTrackEvents());
857 { //if not the same - ERROR
858 Error("AliHBTAnalysis::RunCoherencyCheck()",
859 "Number of simulated events (%d) is not equal to number of reconstructed events(%d)",
860 fReader->GetNumberOfPartEvents(),fReader->GetNumberOfTrackEvents());
864 Info("RunCoherencyCheck","Checking number of Particles AND Particles Types in each event ...");
866 AliHBTEvent *partEvent;
867 AliHBTEvent *trackEvent;
868 for( i = 0; i<fReader->GetNumberOfTrackEvents();i++)
870 partEvent= fReader->GetParticleEvent(i); //gets the "ith" event
871 trackEvent = fReader->GetTrackEvent(i);
873 if ( (partEvent == 0x0) && (partEvent == 0x0) ) continue;
874 if ( (partEvent == 0x0) || (partEvent == 0x0) )
876 Error("AliHBTAnalysis::RunCoherencyCheck()",
877 "One event is NULL and the other one not. Event Number %d",i);
881 if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
883 Error("AliHBTAnalysis::RunCoherencyCheck()",
884 "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
885 i,partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
889 for (Int_t j = 0; j<partEvent->GetNumberOfParticles(); j++)
891 if( partEvent->GetParticle(j)->GetPdgCode() != trackEvent->GetParticle(j)->GetPdgCode() )
893 Error("AliHBTAnalysis::RunCoherencyCheck()",
894 "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
895 i,j, partEvent->GetParticle(j)->GetPdgCode(),trackEvent->GetParticle(j)->GetPdgCode() );
901 Info("RunCoherencyCheck"," Done");
902 Info("RunCoherencyCheck"," Everything looks OK");
906 /*************************************************************************************/
908 void AliHBTAnalysis::ProcessTracksAndParticlesNonIdentAnal()
910 //Performs analysis for both, tracks and particles
912 AliHBTParticle * part1, * part2;
913 AliHBTParticle * track1, * track2;
915 AliHBTEvent * trackEvent1=0x0,*partEvent1=0x0;
916 AliHBTEvent * trackEvent2=0x0,*partEvent2=0x0;
917 AliHBTEvent * trackEvent3=0x0,*partEvent3=0x0;
919 AliHBTEvent * rawtrackEvent, *rawpartEvent;//this we get from Reader
921 AliHBTPair * trackpair = new AliHBTPair();
922 AliHBTPair * partpair = new AliHBTPair();
924 AliHBTEventBuffer partbuffer(fBufferSize);
925 AliHBTEventBuffer trackbuffer(fBufferSize);
929 trackEvent1 = new AliHBTEvent();
930 partEvent1 = new AliHBTEvent();
931 trackEvent1->SetOwner(kFALSE);
932 partEvent1->SetOwner(kFALSE);;
934 Bool_t nocorrfctns = (fNParticleFunctions == 0) && (fNTrackFunctions == 0) && (fNParticleAndTrackFunctions == 0);
938 Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
939 Info("ProcessTracksAndParticlesNonIdentAnal","***** NON IDENT MODE ****************");
940 Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
942 for (Int_t i = 0;;i++)//infinite loop
944 if (fReader->Next()) break; //end when no more events available
946 rawpartEvent = fReader->GetParticleEvent();
947 rawtrackEvent = fReader->GetTrackEvent();
948 if ( (rawpartEvent == 0x0) || (rawtrackEvent == 0x0) ) continue;//in case of any error
950 if ( rawpartEvent->GetNumberOfParticles() != rawtrackEvent->GetNumberOfParticles() )
952 Fatal("ProcessTracksAndParticlesNonIdentAnal",
953 "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
954 i,rawpartEvent->GetNumberOfParticles() , rawtrackEvent->GetNumberOfParticles());
958 /********************************/
960 /********************************/
961 if ( ( (partEvent2==0x0) || (trackEvent2==0x0)) )//in case fBufferSize == 0 and pointers are created do not eneter
963 partEvent2 = new AliHBTEvent();
964 trackEvent2 = new AliHBTEvent();
965 partEvent2->SetOwner(kTRUE);
966 trackEvent2->SetOwner(kTRUE);
969 FilterOut(partEvent1, partEvent2, rawpartEvent, trackEvent1, trackEvent2, rawtrackEvent);
971 for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
973 if ( (j%fDisplayMixingInfo) == 0)
974 Info("ProcessTracksAndParticlesNonIdentAnal",
975 "Mixing particle %d from event %d with particles from event %d",j,i,i);
977 part1= partEvent1->GetParticle(j);
978 track1= trackEvent1->GetParticle(j);
980 //PID reconstruction imperfections
981 // if( part1->GetPdgCode() != track1->GetPdgCode() )
983 // Fatal("ProcessTracksAndParticlesNonIdentAnal",
984 // "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
985 // i,j, part1->GetPdgCode(),track1->GetPdgCode() );
989 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
990 fParticleMonitorFunctions[ii]->Process(part1);
991 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
992 fTrackMonitorFunctions[ii]->Process(track1);
993 for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
994 fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
996 if (nocorrfctns) continue;
998 /***************************************/
999 /****** filling numerators ********/
1000 /****** (particles from event2) ********/
1001 /***************************************/
1003 for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups
1005 part2= partEvent2->GetParticle(k);
1006 if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
1007 partpair->SetParticles(part1,part2);
1009 track2= trackEvent2->GetParticle(k);
1010 trackpair->SetParticles(track1,track2);
1012 if( (fPairCut->PassPairProp(trackpair)) ) //check pair cut
1013 { //do not meets crietria of the pair cut
1017 {//meets criteria of the pair cut
1018 for(ii = 0;ii<fNParticleFunctions;ii++)
1019 fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1021 for(ii = 0;ii<fNTrackFunctions;ii++)
1022 fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1024 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
1025 fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(trackpair,partpair);
1029 if ( fBufferSize == 0) continue;//do not mix diff histograms
1030 /***************************************/
1031 /***** Filling denominators *********/
1032 /***************************************/
1033 partbuffer.ResetIter();
1034 trackbuffer.ResetIter();
1038 while ( (partEvent3 = partbuffer.Next() ) != 0x0)
1040 trackEvent3 = trackbuffer.Next();
1042 if ( (j%fDisplayMixingInfo) == 0)
1043 Info("ProcessTracksAndParticlesNonIdentAnal",
1044 "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1046 for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1048 part2= partEvent3->GetParticle(k);
1049 partpair->SetParticles(part1,part2);
1051 track2= trackEvent3->GetParticle(k);
1052 trackpair->SetParticles(track1,track2);
1054 if( (fPairCut->PassPairProp(trackpair)) ) //check pair cut
1055 { //do not meets crietria of the pair cut
1059 {//meets criteria of the pair cut
1061 for(ii = 0;ii<fNParticleFunctions;ii++)
1062 fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1064 for(ii = 0;ii<fNTrackFunctions;ii++)
1065 fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1067 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
1068 fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(trackpair,partpair);
1070 }// for particles event2
1072 }//for over particles in event1
1074 partEvent2 = partbuffer.Push(partEvent2);
1075 trackEvent2 = trackbuffer.Push(trackEvent2);
1077 }//end of loop over events (1)
1079 partbuffer.SetOwner(kTRUE);
1080 trackbuffer.SetOwner(kTRUE);
1090 /*************************************************************************************/
1092 void AliHBTAnalysis::ProcessTracksNonIdentAnal()
1094 //Process Tracks only with non identical mode
1095 AliHBTParticle * track1, * track2;
1097 AliHBTEvent * trackEvent1=0x0;
1098 AliHBTEvent * trackEvent2=0x0;
1099 AliHBTEvent * trackEvent3=0x0;
1101 AliHBTEvent * rawtrackEvent;
1103 AliHBTPair * trackpair = new AliHBTPair();
1104 AliHBTEventBuffer trackbuffer(fBufferSize);
1108 trackEvent1 = new AliHBTEvent();
1109 trackEvent1->SetOwner(kFALSE);
1113 Info("ProcessTracksNonIdentAnal","**************************************");
1114 Info("ProcessTracksNonIdentAnal","***** NON IDENT MODE ****************");
1115 Info("ProcessTracksNonIdentAnal","**************************************");
1118 for (Int_t i = 0;;i++)//infinite loop
1120 if (fReader->Next()) break; //end when no more events available
1121 rawtrackEvent = fReader->GetTrackEvent();
1123 if (rawtrackEvent == 0x0) continue;//in case of any error
1125 /********************************/
1127 /********************************/
1128 if ( trackEvent2==0x0 )//in case fBufferSize == 0 and pointers are created do not eneter
1130 trackEvent2 = new AliHBTEvent();
1131 trackEvent2->SetOwner(kTRUE);
1134 FilterOut(trackEvent1, trackEvent2, rawtrackEvent);
1136 for (Int_t j = 0; j<trackEvent1->GetNumberOfParticles() ; j++)
1138 if ( (j%fDisplayMixingInfo) == 0)
1139 Info("ProcessTracksNonIdentAnal",
1140 "Mixing particle %d from event %d with particles from event %d",j,i,i);
1142 track1= trackEvent1->GetParticle(j);
1144 for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
1145 fTrackMonitorFunctions[ii]->Process(track1);
1147 if (fNTrackFunctions == 0x0) continue;
1149 /***************************************/
1150 /****** filling numerators ********/
1151 /****** (particles from event2) ********/
1152 /***************************************/
1153 for (Int_t k = 0; k < trackEvent2->GetNumberOfParticles() ; k++)
1155 track2= trackEvent2->GetParticle(k);
1156 if (track1->GetUID() == track2->GetUID()) continue;//this is the same particle but with different PID
1157 trackpair->SetParticles(track1,track2);
1160 if( fPairCut->PassPairProp(trackpair)) //check pair cut
1161 { //do not meets crietria of the pair cut
1165 {//meets criteria of the pair cut
1167 for(ii = 0;ii<fNTrackFunctions;ii++)
1168 fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1171 if ( fBufferSize == 0) continue;//do not mix diff histograms
1172 /***************************************/
1173 /***** Filling denominators *********/
1174 /***************************************/
1175 trackbuffer.ResetIter();
1178 while ( (trackEvent3 = trackbuffer.Next() ) != 0x0)
1181 if ( (j%fDisplayMixingInfo) == 0)
1182 Info("ProcessTracksNonIdentAnal",
1183 "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1185 for (Int_t k = 0; k < trackEvent3->GetNumberOfParticles() ; k++)
1188 track2= trackEvent3->GetParticle(k);
1189 trackpair->SetParticles(track1,track2);
1192 if( fPairCut->PassPairProp(trackpair)) //check pair cut
1193 { //do not meets crietria of the pair cut
1197 {//meets criteria of the pair cut
1198 for(ii = 0;ii<fNTrackFunctions;ii++)
1199 fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1201 }// for particles event2
1203 }//for over particles in event1
1205 trackEvent2 = trackbuffer.Push(trackEvent2);
1207 }//end of loop over events (1)
1209 trackbuffer.SetOwner(kTRUE);
1214 /*************************************************************************************/
1216 void AliHBTAnalysis::ProcessParticlesNonIdentAnal()
1218 //process paricles only with non identical mode
1219 AliHBTParticle * part1 = 0x0, * part2 = 0x0;
1221 AliHBTEvent * partEvent1 = 0x0;
1222 AliHBTEvent * partEvent2 = 0x0;
1223 AliHBTEvent * partEvent3 = 0x0;
1225 AliHBTEvent * rawpartEvent = 0x0;
1227 AliHBTPair * partpair = new AliHBTPair();
1228 AliHBTEventBuffer partbuffer(fBufferSize);
1232 partEvent1 = new AliHBTEvent();
1233 partEvent1->SetOwner(kFALSE);
1237 Info("ProcessParticlesNonIdentAnal","**************************************");
1238 Info("ProcessParticlesNonIdentAnal","***** NON IDENT MODE ****************");
1239 Info("ProcessParticlesNonIdentAnal","**************************************");
1241 for (Int_t i = 0;;i++)//infinite loop
1243 if (fReader->Next()) break; //end when no more events available
1245 rawpartEvent = fReader->GetParticleEvent();
1246 if ( rawpartEvent == 0x0 ) continue;//in case of any error
1248 /********************************/
1250 /********************************/
1251 if (partEvent2==0x0)//in case fBufferSize == 0 and pointers are created do not eneter
1253 partEvent2 = new AliHBTEvent();
1254 partEvent2->SetOwner(kTRUE);
1257 FilterOut(partEvent1, partEvent2, rawpartEvent);
1259 for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
1261 if ( (j%fDisplayMixingInfo) == 0)
1262 Info("ProcessParticlesNonIdentAnal",
1263 "Mixing particle %d from event %d with particles from event %d",j,i,i);
1265 part1= partEvent1->GetParticle(j);
1267 for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
1268 fParticleMonitorFunctions[ii]->Process(part1);
1270 if (fNParticleFunctions == 0) continue;
1272 /***************************************/
1273 /****** filling numerators ********/
1274 /****** (particles from event2) ********/
1275 /***************************************/
1276 for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++)
1278 part2= partEvent2->GetParticle(k);
1279 if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
1280 partpair->SetParticles(part1,part2);
1282 if(fPairCut->PassPairProp(partpair) ) //check pair cut
1283 { //do not meets crietria of the pair cut
1287 {//meets criteria of the pair cut
1288 for(ii = 0;ii<fNParticleFunctions;ii++)
1289 fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1292 if ( fBufferSize == 0) continue;//do not mix diff histograms
1293 /***************************************/
1294 /***** Filling denominators *********/
1295 /***************************************/
1296 partbuffer.ResetIter();
1299 while ( (partEvent3 = partbuffer.Next() ) != 0x0)
1301 if ( (j%fDisplayMixingInfo) == 0)
1302 Info("ProcessParticlesNonIdentAnal",
1303 "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1305 for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1307 part2= partEvent3->GetParticle(k);
1308 partpair->SetParticles(part1,part2);
1310 if(fPairCut->PassPairProp(partpair) ) //check pair cut
1311 { //do not meets crietria of the pair cut
1315 {//meets criteria of the pair cut
1316 for(ii = 0;ii<fNParticleFunctions;ii++)
1318 fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1321 }// for particles event2
1323 }//for over particles in event1
1324 partEvent2 = partbuffer.Push(partEvent2);
1325 }//end of loop over events (1)
1327 partbuffer.SetOwner(kTRUE);
1333 /*************************************************************************************/
1334 void AliHBTAnalysis::FilterOut(AliHBTEvent* outpart1, AliHBTEvent* outpart2, AliHBTEvent* inpart,
1335 AliHBTEvent* outtrack1, AliHBTEvent* outtrack2, AliHBTEvent* intrack)
1337 //Puts particles accepted as a first particle by global cut in out1
1338 //and as a second particle in out2
1340 AliHBTParticle* part, *track;
1347 AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1348 AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1352 for (Int_t i = 0; i < inpart->GetNumberOfParticles(); i++)
1355 part = inpart->GetParticle(i);
1356 track = intrack->GetParticle(i);
1358 if ( (cut1->Pass(track)) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1359 if ( (cut2->Pass(track)) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
1361 if (gDebug)//to be removed in real analysis
1362 if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1364 //Particle accpted by both cuts
1365 Error("FilterOut","Particle accepted by both cuts");
1371 outpart1->AddParticle(part);
1372 outtrack1->AddParticle(track);
1378 outpart2->AddParticle(new AliHBTParticle(*part));
1379 outtrack2->AddParticle(new AliHBTParticle(*track));
1384 /*************************************************************************************/
1386 void AliHBTAnalysis::FilterOut(AliHBTEvent* out1, AliHBTEvent* out2, AliHBTEvent* in)
1388 //Puts particles accepted as a first particle by global cut in out1
1389 //and as a second particle in out2
1390 AliHBTParticle* part;
1395 AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1396 AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1400 for (Int_t i = 0; i < in->GetNumberOfParticles(); i++)
1403 part = in->GetParticle(i);
1405 if ( cut1->Pass(part) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1406 if ( cut2->Pass(part) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
1408 if (gDebug)//to be removed in real analysis
1409 if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1411 //Particle accpted by both cuts
1412 Error("FilterOut","Particle accepted by both cuts");
1418 out1->AddParticle(part);
1424 out2->AddParticle(part);
1429 /*************************************************************************************/
1431 Bool_t AliHBTAnalysis::IsNonIdentAnalysis()
1433 //checks if it is possible to use special analysis for non identical particles
1434 //it means - in global pair cut first particle id is different than second one
1435 //and both are different from 0
1436 //in the future is possible to perform more sophisticated check
1437 //if cuts have excluding requirements
1439 if (fPairCut->IsEmpty())
1442 if (fPairCut->GetFirstPartCut()->IsEmpty())
1445 if (fPairCut->GetSecondPartCut()->IsEmpty())
1448 Int_t id1 = fPairCut->GetFirstPartCut()->GetPID();
1449 Int_t id2 = fPairCut->GetSecondPartCut()->GetPID();
1451 if ( (id1==0) || (id2==0) || (id1==id2) )