ef5c3099700e2b375a518b63f0326bb4092ad1b6
[u/mrichter/AliRoot.git] / HBTAN / AliHBTAnalysis.cxx
1 #include "AliHBTAnalysis.h"
2 //_________________________________________________________
3 ////////////////////////////////////////////////////////////////////////////
4 //
5 // class AliHBTAnalysis
6 //
7 // Central Object Of HBTAnalyser: 
8 // This class performs main looping within HBT Analysis
9 // User must plug a reader of Type AliReader
10 // User plugs in coorelation and monitor functions
11 // as well as monitor functions
12 //
13 // HBT Analysis Tool, which is integral part of AliRoot,
14 // ALICE Off-Line framework:
15 //
16 // Piotr.Skowronski@cern.ch
17 // more info: http://alisoft.cern.ch/people/skowron/analyzer/index.html
18 //
19 ////////////////////////////////////////////////////////////////////////////
20 //_________________________________________________________
21
22
23 #include <TSystem.h>
24 #include <TFile.h>
25
26 #include "AliAOD.h"
27 #include "AliAODParticle.h"
28 #include "AliAODPairCut.h"
29 #include "AliEventCut.h"
30
31 #include "AliEventBuffer.h"
32
33 #include "AliReader.h"
34 #include "AliHBTPair.h"
35 #include "AliHBTFunction.h"
36 #include "AliHBTMonitorFunction.h"
37  
38
39 ClassImp(AliHBTAnalysis)
40
41 const UInt_t AliHBTAnalysis::fgkFctnArraySize = 100;
42 const UInt_t AliHBTAnalysis::fgkDefaultMixingInfo = 1000;
43 const Int_t  AliHBTAnalysis::fgkDefaultBufferSize = 5;
44
45 AliHBTAnalysis::AliHBTAnalysis():
46   fProcEvent(0x0),
47   fReader(0x0),
48   fNTrackFunctions(0),
49   fNParticleFunctions(0),
50   fNParticleAndTrackFunctions(0),
51   fNTrackMonitorFunctions(0),
52   fNParticleMonitorFunctions(0), 
53   fNParticleAndTrackMonitorFunctions(0),
54   fTrackFunctions ( new AliHBTOnePairFctn* [fgkFctnArraySize]),
55   fParticleFunctions ( new AliHBTOnePairFctn* [fgkFctnArraySize]),
56   fParticleAndTrackFunctions ( new AliHBTTwoPairFctn* [fgkFctnArraySize]),
57   fParticleMonitorFunctions ( new AliHBTMonOneParticleFctn* [fgkFctnArraySize]),    
58   fTrackMonitorFunctions ( new AliHBTMonOneParticleFctn* [fgkFctnArraySize]),    
59   fParticleAndTrackMonitorFunctions ( new AliHBTMonTwoParticleFctn* [fgkFctnArraySize]),    
60   fBkgEventCut(0x0),
61   fPartBuffer(0x0),
62   fTrackBuffer(0x0),
63   fBufferSize(2),
64   fDisplayMixingInfo(fgkDefaultMixingInfo),
65   fIsOwner(kFALSE),
66   fProcessOption(kSimulatedAndReconstructed),
67   fNoCorrfctns(kFALSE),
68   fOutputFileName(0x0),
69   fVertexX(0.0),
70   fVertexY(0.0),
71   fVertexZ(0.0)
72  {
73    //default constructor
74    
75  }
76 /*************************************************************************************/ 
77
78 AliHBTAnalysis::AliHBTAnalysis(const AliHBTAnalysis& in):
79   AliAnalysis(in),
80   fProcEvent(0x0),
81   fReader(0x0),
82   fNTrackFunctions(0),
83   fNParticleFunctions(0),
84   fNParticleAndTrackFunctions(0),
85   fNTrackMonitorFunctions(0),
86   fNParticleMonitorFunctions(0), 
87   fNParticleAndTrackMonitorFunctions(0),
88   fTrackFunctions(0x0),
89   fParticleFunctions(0x0),
90   fParticleAndTrackFunctions(0x0),
91   fParticleMonitorFunctions(0x0),
92   fTrackMonitorFunctions(0x0),
93   fParticleAndTrackMonitorFunctions(0x0),
94   fBkgEventCut(0x0),
95   fPartBuffer(0x0),
96   fTrackBuffer(0x0),
97   fBufferSize(fgkDefaultBufferSize),
98   fDisplayMixingInfo(fgkDefaultMixingInfo),
99   fIsOwner(kFALSE),
100   fProcessOption(kSimulatedAndReconstructed),
101   fNoCorrfctns(kFALSE),
102   fOutputFileName(0x0),
103   fVertexX(0.0),
104   fVertexY(0.0),
105   fVertexZ(0.0)
106  {
107 //copy constructor
108    Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
109  }
110 /*************************************************************************************/ 
111 AliHBTAnalysis& AliHBTAnalysis::operator=(const AliHBTAnalysis& /*right*/)
112  {
113 //operator =
114    Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
115    return *this;
116  }
117 /*************************************************************************************/ 
118 AliHBTAnalysis::~AliHBTAnalysis()
119  {
120  //destructor
121  //note that we do not delete functions itself
122  // they should be deleted by whom where created
123  //we only store pointers, and we use "new" only for pointers array
124     
125    if (fIsOwner)
126     {
127       if (AliVAODParticle::GetDebug()>5)Info("~AliHBTAnalysis","Is Owner: Attempting to delete functions");
128       DeleteFunctions();
129       if (AliVAODParticle::GetDebug()>5)Info("~AliHBTAnalysis","Delete functions done");
130     }
131    delete [] fTrackFunctions;
132    delete [] fParticleFunctions;
133    delete [] fParticleAndTrackFunctions;
134    
135    delete [] fParticleMonitorFunctions; 
136    delete [] fTrackMonitorFunctions; 
137    delete [] fParticleAndTrackMonitorFunctions;
138
139    delete fBkgEventCut;
140    delete fOutputFileName;
141  }
142
143 /*************************************************************************************/ 
144
145 Int_t AliHBTAnalysis::ProcessEvent(AliAOD* aodrec, AliAOD* aodsim)
146 {
147   //Processes one event
148   if (fProcEvent == 0x0)
149    {
150      Error("ProcessEvent","Analysis <<%s>> option not specified.",GetName());
151      return 1;
152    }
153   if ( Rejected(aodrec,aodsim) ) 
154    {
155 //     Double_t x = 0, y = 0, z = 0;
156 //     aodrec->GetPrimaryVertex(x,y,z);
157 //     Info("ProcessEvent","Event has vertex at %f %f %f",x,y,z);
158      Info("ProcessEvent","Nch is %d",aodsim->GetNumberOfCharged());
159      Info("ProcessEvent","%s: Event cut rejected this event",GetName());
160      return 0;
161    } 
162   
163   //Move event to the apparent vertex -> must be after the event cut
164   //It is important for any cut that use any spacial coordiantes, 
165   //f.g. anti-merging cut in order to preserve the same bahavior of variables (f.g. distance between tracks)
166   Double_t dvx = 0, dvy = 0, dvz = 0;
167   if (aodrec)
168    {
169      Double_t pvx,pvy,pvz;
170      aodrec->GetPrimaryVertex(pvx,pvy,pvz);
171      
172      dvx = fVertexX - pvx;
173      dvy = fVertexY - pvy;
174      dvz = fVertexZ - pvz;
175      aodrec->Move(dvx,dvy,dvz);
176    }  
177   
178   Int_t result = (this->*fProcEvent)(aodrec,aodsim);
179
180   if (aodrec) aodrec->Move(-dvx,-dvy,-dvz);//move event back to the same spacial coordinates
181   
182   return  result;
183 }
184 /*************************************************************************************/ 
185
186 Int_t AliHBTAnalysis::Finish()
187 {
188 //Finishes analysis
189   WriteFunctions();
190   return 0;
191 }
192 /*************************************************************************************/ 
193
194 void AliHBTAnalysis::DeleteFunctions()
195 {
196  //Deletes all functions added to analysis
197  
198  UInt_t ii;
199  for(ii = 0;ii<fNParticleFunctions;ii++)
200   { 
201     if (AliVAODParticle::GetDebug()>5)
202      {
203        Info("DeleteFunctions","Deleting ParticleFunction %#x",fParticleFunctions[ii]);
204        Info("DeleteFunctions","Deleting ParticleFunction %s",fParticleFunctions[ii]->Name());
205      }
206     delete fParticleFunctions[ii];
207   } 
208  fNParticleFunctions = 0;
209                 
210  for(ii = 0;ii<fNTrackFunctions;ii++)
211   { 
212     if (AliVAODParticle::GetDebug()>5)
213      {
214        Info("DeleteFunctions","Deleting TrackFunction %#x",fTrackFunctions[ii]);
215        Info("DeleteFunctions","Deleting TrackFunction %s",fTrackFunctions[ii]->Name());
216      }
217     delete fTrackFunctions[ii];
218   }  
219  fNTrackFunctions = 0;
220  
221  for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
222   { 
223     if (AliVAODParticle::GetDebug()>5)
224      {
225        Info("DeleteFunctions","Deleting ParticleAndTrackFunction %#x",fParticleAndTrackFunctions[ii]);
226        Info("DeleteFunctions","Deleting ParticleAndTrackFunction %s",fParticleAndTrackFunctions[ii]->Name());
227      } 
228     delete fParticleAndTrackFunctions[ii];
229   }  
230  fNParticleAndTrackFunctions = 0;
231  
232  for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
233   { 
234     if (AliVAODParticle::GetDebug()>5)
235      {
236        Info("DeleteFunctions","Deleting ParticleMonitorFunction %#x",fParticleMonitorFunctions[ii]);
237        Info("DeleteFunctions","Deleting ParticleMonitorFunction %s",fParticleMonitorFunctions[ii]->Name());
238      }
239     delete fParticleMonitorFunctions[ii];
240   } 
241  fNParticleMonitorFunctions = 0;
242    
243  for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
244   { 
245     if (AliVAODParticle::GetDebug()>5)
246      {
247        Info("DeleteFunctions","Deleting TrackMonitorFunction %#x",fTrackMonitorFunctions[ii]);
248        Info("DeleteFunctions","Deleting TrackMonitorFunction %s",fTrackMonitorFunctions[ii]->Name());
249      }
250     delete fTrackMonitorFunctions[ii];
251   } 
252  fNTrackMonitorFunctions = 0;
253    
254  for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
255   { 
256     if (AliVAODParticle::GetDebug()>5)
257      {
258       Info("DeleteFunctions","Deleting ParticleAndTrackMonitorFunction %#x",fParticleAndTrackMonitorFunctions[ii]);
259       Info("DeleteFunctions","Deleting ParticleAndTrackMonitorFunction %s",fParticleAndTrackMonitorFunctions[ii]->Name());
260      }
261     delete fParticleAndTrackMonitorFunctions[ii];
262   } 
263  fNParticleAndTrackMonitorFunctions = 0;
264  
265 }
266 /*************************************************************************************/ 
267
268 Int_t AliHBTAnalysis::Init()
269 {
270 //Initializeation method
271 //calls Init for all functions
272
273  //Depending on option and pair cut assigns proper analysis method
274  Bool_t nonid = IsNonIdentAnalysis();
275  switch(fProcessOption)
276   {
277     case kReconstructed:
278       if (nonid) fProcEvent = &AliHBTAnalysis::ProcessRecNonId;
279       else fProcEvent = &AliHBTAnalysis::ProcessRec;
280       SetCutsOnRec();
281       break;
282
283     case kSimulated:
284       if (nonid) fProcEvent = &AliHBTAnalysis::ProcessSimNonId;
285       else fProcEvent = &AliHBTAnalysis::ProcessSim;
286       SetCutsOnSim();
287       break;
288
289     case kSimulatedAndReconstructed:
290       if (nonid) fProcEvent = &AliHBTAnalysis::ProcessRecAndSimNonId;
291       else fProcEvent = &AliHBTAnalysis::ProcessRecAndSim;
292       break;
293   }
294   
295  if (fPartBuffer == 0x0)  fPartBuffer = new AliEventBuffer (fBufferSize);
296  else fPartBuffer->Reset();
297
298  if (fTrackBuffer == 0x0)  fTrackBuffer = new AliEventBuffer (fBufferSize);
299  else fTrackBuffer->Reset();
300
301
302  fNoCorrfctns = (fNParticleFunctions == 0) && (fNTrackFunctions == 0) && (fNParticleAndTrackFunctions == 0);
303  
304  UInt_t ii;
305  for(ii = 0;ii<fNParticleFunctions;ii++)
306    fParticleFunctions[ii]->Init();
307                 
308  for(ii = 0;ii<fNTrackFunctions;ii++)
309    fTrackFunctions[ii]->Init();
310
311  for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
312    fParticleAndTrackFunctions[ii]->Init();
313  
314  for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
315    fParticleMonitorFunctions[ii]->Init();
316    
317  for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
318    fTrackMonitorFunctions[ii]->Init();
319    
320  for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
321    fParticleAndTrackMonitorFunctions[ii]->Init();
322    
323  return 0;
324 }
325 /*************************************************************************************/ 
326
327 void AliHBTAnalysis::ResetFunctions()
328 {
329 //In case fOwner is true, deletes all functions
330 //in other case, just set number of analysis to 0
331  if (fIsOwner) DeleteFunctions();
332  else
333   {
334     fNParticleFunctions = 0;
335     fNTrackFunctions = 0;
336     fNParticleAndTrackFunctions = 0;
337     fNParticleMonitorFunctions = 0;
338     fNTrackMonitorFunctions = 0;
339     fNParticleAndTrackMonitorFunctions = 0;
340   }
341 }
342 /*************************************************************************************/ 
343 Int_t AliHBTAnalysis::ProcessRecAndSim(AliAOD* aodrec, AliAOD* aodsim)
344 {
345 //Does analysis for both tracks and particles
346 //mainly for resolution study and analysies with weighting algirithms
347   
348 // cut on particles only -- why?
349 // - PID: when we make resolution analysis we want to take only tracks with correct PID
350 // We need cut on tracks because there are data characteristic
351   
352   AliVAODParticle * part1, * part2;
353   AliVAODParticle * track1, * track2;
354   
355   AliAOD * trackEvent = aodrec, *partEvent = aodsim;
356   AliAOD* trackEvent1 = new AliAOD();
357   AliAOD* partEvent1 = new AliAOD();
358
359   AliAOD * trackEvent2,*partEvent2;
360   
361 //  Int_t N1, N2, N=0; //number of particles in current event(we prcess two events in one time)
362   
363 //  Int_t nev = fReader->GetNumberOfTrackEvents();
364   static AliHBTPair tpair;
365   static AliHBTPair ppair;
366
367   AliHBTPair* trackpair = &tpair;
368   AliHBTPair* partpair = &ppair;
369  
370   AliHBTPair * tmptrackpair;//temprary pointers to pairs
371   AliHBTPair * tmppartpair;
372   
373   register UInt_t ii;
374   
375   
376
377   if ( !partEvent || !trackEvent ) 
378    {
379      Error("ProcessRecAndSim","<<%s>> Can not get event",GetName());
380      return 1;
381    }
382
383   if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
384    {
385      Error("ProcessRecAndSim",
386            "Number of simulated particles (%d) not equal to number of reconstructed tracks (%d). Skipping Event.",
387             partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
388      return 2;
389    }
390
391
392   for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
393    {
394      /***************************************/
395      /******   Looping same events   ********/
396      /******   filling numerators    ********/
397      /***************************************/
398      if ( (j%fDisplayMixingInfo) == 0)
399         Info("ProcessRecAndSim",
400              "Mixing particle %d with particles from the same event",j);
401
402      part1= partEvent->GetParticle(j);
403      track1= trackEvent->GetParticle(j);
404      
405      Bool_t firstcut = (this->*fkPass1)(part1,track1);
406      if (fBufferSize != 0) 
407        if ( (firstcut == kFALSE) || ( (this->*fkPass2)(part1,track1) == kFALSE ) )
408         {
409           //accepted by any cut
410           // we have to copy because reader keeps only one event
411
412           partEvent1->AddParticle(part1);
413           trackEvent1->AddParticle(track1);
414         }
415
416      if (firstcut) continue;
417
418      for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
419        fParticleMonitorFunctions[ii]->Process(part1);
420      for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
421        fTrackMonitorFunctions[ii]->Process(track1);
422      for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
423        fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
424
425      if (fNoCorrfctns) continue;
426
427      for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
428       {
429         part2= partEvent->GetParticle(k);
430         if (part1->GetUID() == part2->GetUID()) continue;
431         partpair->SetParticles(part1,part2);
432
433         track2= trackEvent->GetParticle(k);
434         trackpair->SetParticles(track1,track2);
435
436         if( (this->*fkPass)(partpair,trackpair) ) //check pair cut 
437           { //do not meets crietria of the pair cut, try with swapped pairs
438             if( (this->*fkPass)((AliHBTPair*)partpair->GetSwappedPair(),(AliHBTPair*)trackpair->GetSwappedPair()) )
439               continue; //swaped pairs do not meet criteria of pair cut as well, take next particle
440             else 
441              { //swaped pair meets all the criteria
442                tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
443                tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
444              }
445           }
446         else
447          {//meets criteria of the pair cut
448            tmptrackpair = trackpair;
449            tmppartpair = partpair;
450          }
451
452         for(ii = 0;ii<fNParticleFunctions;ii++)
453                fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
454
455         for(ii = 0;ii<fNTrackFunctions;ii++)
456                fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
457
458         for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
459                fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair,tmppartpair);
460        //end of 2nd loop over particles from the same event  
461       }//for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
462
463      /***************************************/
464      /***** Filling denominators    *********/
465      /***************************************/
466      if (fBufferSize == 0) continue;
467
468      fPartBuffer->ResetIter();
469      fTrackBuffer->ResetIter();
470      Int_t m = 0;
471      while (( partEvent2 = fPartBuffer->Next() ))
472       {
473         trackEvent2 = fTrackBuffer->Next();
474
475         m++;
476         if ( (j%fDisplayMixingInfo) == 0)
477            Info("ProcessRecAndSim",
478                 "Mixing particle %d from current event with particles from event %d",j,-m);
479
480         for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++)   //  ... on all particles
481           {
482             part2= partEvent2->GetParticle(l);
483             partpair->SetParticles(part1,part2);
484
485             track2= trackEvent2->GetParticle(l);
486             trackpair->SetParticles(track1,track2);
487
488             if( (this->*fkPass)(partpair,trackpair) ) //check pair cut
489               { //do not meets crietria of the 
490                 if( (this->*fkPass)((AliHBTPair*)partpair->GetSwappedPair(),(AliHBTPair*)trackpair->GetSwappedPair()) )
491                   continue;
492                 else 
493                  {
494                    tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
495                    tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
496                  }
497               }
498             else
499              {//meets criteria of the pair cut
500               tmptrackpair = trackpair;
501               tmppartpair = partpair;
502              }
503
504             for(ii = 0;ii<fNParticleFunctions;ii++)
505               fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
506
507             for(ii = 0;ii<fNTrackFunctions;ii++)
508               fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
509
510             for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
511               fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair,tmppartpair);
512           }//for(Int_t l = 0; l<N2;l++)   //  ... on all particles
513
514       }
515     //end of loop over particles from first event
516    }//for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
517   delete fPartBuffer->Push(partEvent1);
518   delete fTrackBuffer->Push(trackEvent1);
519  //end of loop over events  
520   return 0;
521 }
522 /*************************************************************************************/ 
523
524 Int_t AliHBTAnalysis::ProcessSim(AliAOD* /*aodrec*/, AliAOD* aodsim)
525 {
526   //Does analysis of simulated data
527   AliVAODParticle * part1, * part2;
528   
529   AliAOD* partEvent = aodsim;
530   AliAOD* partEvent1 = new AliAOD();
531
532   AliAOD* partEvent2;
533   
534   AliHBTPair ppair;
535
536   AliHBTPair* partpair = &ppair;
537  
538   AliHBTPair * tmppartpair;
539   
540   register UInt_t ii;
541   
542   
543
544   if ( !partEvent )
545    {
546      Error("ProcessSim","Can not get event");
547      return 1;
548    }
549
550
551   for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
552    {
553    /***************************************/
554    /******   Looping same events   ********/
555    /******   filling numerators    ********/
556    /***************************************/
557    if ( (j%fDisplayMixingInfo) == 0)
558       Info("ProcessSim",
559            "Mixing particle %d with particles from the same event",j);
560
561    part1= partEvent->GetParticle(j);
562
563    Bool_t firstcut = fPairCut->GetFirstPartCut()->Rejected(part1);
564
565    if (fBufferSize != 0) 
566      if ( (firstcut == kFALSE) || ( fPairCut->GetSecondPartCut()->Rejected(part1) == kFALSE ) )
567       {
568         //accepted by any cut
569         // we have to copy because reader keeps only one event
570
571         partEvent1->AddParticle(part1);
572       }
573
574    if (firstcut) continue;
575
576    for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
577      fParticleMonitorFunctions[ii]->Process(part1);
578
579    if ( fNParticleFunctions == 0 ) continue;
580
581    for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
582     {
583       part2= partEvent->GetParticle(k);
584       if (part1->GetUID() == part2->GetUID()) continue;
585       partpair->SetParticles(part1,part2);
586
587          if(fPairCut->Rejected(partpair)) //check pair cut
588           { //do not meets crietria of the 
589             if( fPairCut->Rejected((AliHBTPair*)partpair->GetSwappedPair()) ) continue;
590             else tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
591           }
592          else
593           {
594             tmppartpair = partpair;
595           }
596
597       for(ii = 0;ii<fNParticleFunctions;ii++)
598              fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
599
600      //end of 2nd loop over particles from the same event  
601     }//for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
602
603    /***************************************/
604    /***** Filling denominators    *********/
605    /***************************************/
606    if (fBufferSize == 0) continue;
607
608    fPartBuffer->ResetIter();
609        Int_t m = 0;
610        while (( partEvent2 = fPartBuffer->Next() ))
611         {
612           m++;
613           if ( (j%fDisplayMixingInfo) == 0)
614              Info("ProcessSim",
615                   "Mixing particle %d from current event with particles from event %d",j,-m);
616           for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++)   //  ... on all particles
617             {
618
619               part2= partEvent2->GetParticle(l);
620               partpair->SetParticles(part1,part2);
621
622               if( fPairCut->Rejected(partpair) ) //check pair cut
623                 { //do not meets crietria of the 
624                   if( fPairCut->Rejected((AliHBTPair*)partpair->GetSwappedPair()) )
625                     continue;
626                   else 
627                    {
628                      tmppartpair = (AliHBTPair*)partpair->GetSwappedPair();
629                    }
630                 }
631               else
632                {//meets criteria of the pair cut
633                 tmppartpair = partpair;
634                }
635
636               for(ii = 0;ii<fNParticleFunctions;ii++)
637                 fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
638
639            }//for(Int_t l = 0; l<N2;l++)   //  ... on all particles
640         }
641      }
642
643        
644   delete fPartBuffer->Push(partEvent1);
645  //end of loop over events  
646   return 0;
647 }
648 /*************************************************************************************/ 
649 Int_t AliHBTAnalysis::ProcessRec(AliAOD* aodrec, AliAOD* /*aodsim*/)
650 {
651   //Does analysis of reconstructed data
652   AliVAODParticle * track1, * track2;
653   
654   AliAOD* trackEvent = aodrec;
655   AliAOD* trackEvent1 = new AliAOD();
656
657   AliAOD* trackEvent2;
658   
659   AliHBTPair tpair;
660
661   AliHBTPair* trackpair = &tpair;
662  
663   AliHBTPair * tmptrackpair;
664   
665   register UInt_t ii;
666   
667
668   if ( !trackEvent )
669    {
670      Error("ProcessRecAndSim","Can not get event");
671      return 1;
672    }
673
674
675   for (Int_t j = 0; j<trackEvent->GetNumberOfParticles() ; j++)
676    {
677      /***************************************/
678      /******   Looping same events   ********/
679      /******   filling numerators    ********/
680      /***************************************/
681      if ( (j%fDisplayMixingInfo) == 0)
682         Info("ProcessTracksAndParticles",
683              "Mixing Particle %d with Particles from the same event",j);
684
685      track1= trackEvent->GetParticle(j);
686
687      Bool_t firstcut = fPairCut->GetFirstPartCut()->Rejected(track1);
688
689      if (fBufferSize != 0) 
690        if ( (firstcut == kFALSE) || ( fPairCut->GetSecondPartCut()->Rejected(track1) == kFALSE ) )
691         {
692           //accepted by any cut
693           // we have to copy because reader keeps only one event
694
695           trackEvent1->AddParticle(track1);
696         }
697
698      if (firstcut) continue;
699
700      for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
701        fParticleMonitorFunctions[ii]->Process(track1);
702
703      if ( fNParticleFunctions == 0 ) continue;
704
705      for (Int_t k =j+1; k < trackEvent->GetNumberOfParticles() ; k++)
706       {
707         track2= trackEvent->GetParticle(k);
708         if (track1->GetUID() == track2->GetUID()) continue;
709         trackpair->SetParticles(track1,track2);
710
711            if(fPairCut->Rejected(trackpair)) //check pair cut
712             { //do not meets crietria of the 
713               if( fPairCut->Rejected((AliHBTPair*)trackpair->GetSwappedPair()) ) continue;
714               else tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
715             }
716            else
717             {
718               tmptrackpair = trackpair;
719             }
720
721         for(ii = 0;ii<fNTrackFunctions;ii++)
722                fParticleFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
723
724        //end of 2nd loop over Particles from the same event  
725       }//for (Int_t k =j+1; k < trackEvent->GetNumberOfParticles() ; k++)
726
727      /***************************************/
728      /***** Filling denominators    *********/
729      /***************************************/
730      if (fBufferSize == 0) continue;
731
732      fTrackBuffer->ResetIter();
733          Int_t m = 0;
734          while (( trackEvent2 = fTrackBuffer->Next() ))
735           {
736             m++;
737             if ( (j%fDisplayMixingInfo) == 0)
738                Info("ProcessParticles",
739                     "Mixing Particle %d from current event with Particles from event %d",j,-m);
740             for(Int_t l = 0; l<trackEvent2->GetNumberOfParticles();l++)   //  ... on all Particles
741               {
742
743                 track2= trackEvent2->GetParticle(l);
744                 trackpair->SetParticles(track1,track2);
745
746                 if( fPairCut->Rejected(trackpair) ) //check pair cut
747                   { //do not meets crietria of the 
748                     if( fPairCut->Rejected((AliHBTPair*)trackpair->GetSwappedPair()) )
749                       continue;
750                     else 
751                      {
752                        tmptrackpair = (AliHBTPair*)trackpair->GetSwappedPair();
753                      }
754                   }
755                 else
756                  {//meets criteria of the pair cut
757                   tmptrackpair = trackpair;
758                  }
759                  
760                 for(ii = 0;ii<fNTrackFunctions;ii++)
761                   fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
762                  
763              }//for(Int_t l = 0; l<N2;l++)   //  ... on all Particles
764           }
765        }
766   delete fTrackBuffer->Push(trackEvent1);
767  //end of loop over events  
768   return 0;
769 }
770 /*************************************************************************************/ 
771      
772 Int_t AliHBTAnalysis::ProcessRecAndSimNonId(AliAOD* aodrec, AliAOD* aodsim)
773 {
774 //Analyzes both reconstructed and simulated data
775   if (aodrec == 0x0) 
776    {
777      Error("ProcessTracksAndParticlesNonIdentAnal","Reconstructed event is NULL");
778      return 1;
779    }
780
781   if (aodsim == 0x0) 
782    {
783      Error("ProcessTracksAndParticlesNonIdentAnal","Simulated event is NULL");
784      return 1;
785    }
786
787   if ( aodrec->GetNumberOfParticles() != aodsim->GetNumberOfParticles() )
788    {
789      Error("ProcessTracksAndParticlesNonIdentAnal",
790            "Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
791            aodsim->GetNumberOfParticles() , aodrec->GetNumberOfParticles());
792      return 2;
793    }
794
795  
796   AliVAODParticle * part1, * part2;
797   AliVAODParticle * track1, * track2;
798
799   static AliAOD aodrec1;
800   static AliAOD aodsim1;
801
802   AliAOD * trackEvent1=&aodrec1,*partEvent1=&aodsim1;//Particle that passes first particle cut, this event
803   trackEvent1->Reset();
804   partEvent1->Reset();
805   AliAOD * trackEvent2=0x0,*partEvent2=0x0;//Particle that passes second particle cut, this event
806   AliAOD * trackEvent3=0x0,*partEvent3=0x0;//Particle that passes second particle cut, events from buffer
807
808   AliAOD* rawtrackEvent = aodrec;//this we get from Reader
809   AliAOD* rawpartEvent = aodsim;//this we get from Reader
810
811   static AliHBTPair tpair;
812   static AliHBTPair ppair;
813   
814   AliHBTPair* trackpair = &tpair;
815   AliHBTPair* partpair = &ppair;
816
817   register UInt_t ii;
818   
819   /********************************/
820   /*      Filtering out           */
821   /********************************/
822   if ( ( (partEvent2==0x0) || (trackEvent2==0x0)) )//in case fBufferSize == 0 and pointers are created do not eneter
823    {
824      partEvent2  = new AliAOD();
825      trackEvent2 = new AliAOD();
826    }
827
828   FilterOut(partEvent1, partEvent2, rawpartEvent, trackEvent1, trackEvent2, rawtrackEvent);
829
830   for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
831    {
832      if ( (j%fDisplayMixingInfo) == 0) 
833         Info("ProcessTracksAndParticlesNonIdentAnal",
834              "Mixing particle %d from current event with particles from current event",j);
835
836      part1= partEvent1->GetParticle(j);
837      track1= trackEvent1->GetParticle(j);
838
839
840      for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
841        fParticleMonitorFunctions[ii]->Process(part1);
842      for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
843        fTrackMonitorFunctions[ii]->Process(track1);
844      for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
845        fParticleAndTrackMonitorFunctions[ii]->Process(track1,part1);
846
847      if (fNoCorrfctns) continue;
848
849      /***************************************/
850      /******   filling numerators    ********/
851      /****** (particles from event2) ********/
852      /***************************************/
853
854      for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups 
855       {
856         part2= partEvent2->GetParticle(k);
857         if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
858         partpair->SetParticles(part1,part2);
859
860         track2= trackEvent2->GetParticle(k);
861         trackpair->SetParticles(track1,track2);
862
863         if( (this->*fkPassPairProp)(partpair,trackpair) ) //check pair cut
864          { //do not meets crietria of the pair cut
865           continue; 
866          }
867         else
868          {//meets criteria of the pair cut
869           for(ii = 0;ii<fNParticleFunctions;ii++)
870                  fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
871
872           for(ii = 0;ii<fNTrackFunctions;ii++)
873                  fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
874
875           for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
876                  fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(trackpair,partpair);
877          }
878        }
879
880    if ( fBufferSize == 0) continue;//do not mix diff histograms
881    /***************************************/
882    /***** Filling denominators    *********/
883    /***************************************/
884    fPartBuffer->ResetIter();
885    fTrackBuffer->ResetIter();
886
887    Int_t nmonitor = 0;
888
889    while ( (partEvent3 = fPartBuffer->Next() ) != 0x0)
890     {
891       trackEvent3 = fTrackBuffer->Next();
892
893       if ( (j%fDisplayMixingInfo) == 0) 
894         Info("ProcessTracksAndParticlesNonIdentAnal",
895              "Mixing particle %d from current event with particles from event%d",j,-(++nmonitor));
896
897       for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
898         {
899           part2= partEvent3->GetParticle(k);
900           partpair->SetParticles(part1,part2);
901
902           track2= trackEvent3->GetParticle(k);
903           trackpair->SetParticles(track1,track2);
904
905           if( (this->*fkPassPairProp)(partpair,trackpair) ) //check pair cut
906            { //do not meets crietria of the pair cut
907             continue; 
908            }
909           else
910            {//meets criteria of the pair cut
911             UInt_t ii;
912             for(ii = 0;ii<fNParticleFunctions;ii++)
913                    fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
914
915             for(ii = 0;ii<fNTrackFunctions;ii++)
916                    fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
917
918             for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
919                    fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(trackpair,partpair);
920            }
921          }// for particles event2
922        }//while event2
923    }//for over particles in event1
924
925  delete fPartBuffer->Push(partEvent2);
926  delete fTrackBuffer->Push(trackEvent2);
927  
928  return 0;
929 }
930 /*************************************************************************************/ 
931 Int_t AliHBTAnalysis::ProcessSimNonId(AliAOD* /*aodrec*/, AliAOD* aodsim)
932 {
933 //does analysis of simulated (MC) data in non-identical mode
934 //i.e. when particles selected by first part. cut are a disjunctive set than particles
935 //passed by the second part. cut
936  if (aodsim == 0x0) 
937   {
938     return 1;
939   }
940  
941  
942   AliVAODParticle * part1, * part2;
943
944   static AliAOD aodsim1;
945
946   AliAOD* partEvent1=&aodsim1;//Particle that passes first particle cut, this event
947   partEvent1->Reset();
948   AliAOD* partEvent2=0x0;//Particle that passes second particle cut, this event
949   AliAOD* partEvent3=0x0;//Particle that passes second particle cut, events from buffer
950
951   AliAOD* rawpartEvent = aodsim;//this we get from Reader
952
953   static AliHBTPair ppair;
954   
955   AliHBTPair* partpair = &ppair;
956
957   register UInt_t ii;
958   
959   /********************************/
960   /*      Filtering out           */
961   /********************************/
962   if (partEvent2==0x0)//in case fBufferSize == 0 and pointers are created do not eneter
963    {
964      partEvent2  = new AliAOD();
965    }
966
967   FilterOut(partEvent1, partEvent2, rawpartEvent);
968
969   for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
970    {
971      if ( (j%fDisplayMixingInfo) == 0) 
972         Info("ProcessParticlesNonIdentAnal",
973              "Mixing particle %d from current event with particles from current event",j);
974
975      part1= partEvent1->GetParticle(j);
976
977
978      for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
979        fParticleMonitorFunctions[ii]->Process(part1);
980
981      if (fNParticleFunctions == 0) continue;
982
983      /***************************************/
984      /******   filling numerators    ********/
985      /****** (particles from event2) ********/
986      /***************************************/
987
988      for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups 
989       {
990         part2= partEvent2->GetParticle(k);
991         if (part1->GetUID() == part2->GetUID()) continue;//this is the same particle but with different PID
992         partpair->SetParticles(part1,part2);
993
994
995         if(fPairCut->PassPairProp(partpair) ) //check pair cut
996           { //do not meets crietria of the pair cut
997               continue; 
998           }
999         else
1000          {//meets criteria of the pair cut
1001           for(ii = 0;ii<fNParticleFunctions;ii++)
1002               fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1003          }
1004        }
1005
1006  if ( fBufferSize == 0) continue;//do not mix diff histograms
1007  /***************************************/
1008  /***** Filling denominators    *********/
1009  /***************************************/
1010  fPartBuffer->ResetIter();
1011
1012  Int_t nmonitor = 0;
1013
1014  while ( (partEvent3 = fPartBuffer->Next() ) != 0x0)
1015   {
1016
1017     if ( (j%fDisplayMixingInfo) == 0) 
1018       Info("ProcessParticlesNonIdentAnal",
1019            "Mixing particle %d from current event with particles from event%d",j,-(++nmonitor));
1020
1021     for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1022       {
1023         part2= partEvent3->GetParticle(k);
1024         partpair->SetParticles(part1,part2);
1025
1026
1027         if(fPairCut->PassPairProp(partpair) ) //check pair cut
1028           { //do not meets crietria of the pair cut
1029               continue; 
1030           }
1031         else
1032          {//meets criteria of the pair cut
1033           for(ii = 0;ii<fNParticleFunctions;ii++)
1034            {
1035              fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1036            }
1037          }
1038        }// for particles event2
1039      }//while event2
1040    }//for over particles in event1
1041
1042  delete fPartBuffer->Push(partEvent2);
1043  
1044  return 0;
1045 }
1046 /*************************************************************************************/ 
1047 Int_t AliHBTAnalysis::ProcessRecNonId(AliAOD* aodrec, AliAOD* /*aodsim*/)
1048 {
1049 //Analyzes both reconstructed and simulated data
1050  if (aodrec == 0x0) 
1051   {
1052     return 1;
1053   }
1054  
1055   AliVAODParticle * track1, * track2;
1056
1057   static AliAOD aodrec1;
1058   AliAOD * trackEvent1=&aodrec1;//Particle that passes first particle cut, this event
1059   trackEvent1->Reset();
1060   AliAOD * trackEvent2=0x0;//Particle that passes second particle cut, this event
1061   AliAOD * trackEvent3=0x0;//Particle that passes second particle cut, events from buffer
1062   AliAOD* rawtrackEvent = aodrec;//this we get from Reader
1063
1064   static AliHBTPair tpair;
1065   
1066   AliHBTPair* trackpair = &tpair;
1067
1068   register UInt_t ii;
1069   
1070   
1071   /********************************/
1072   /*      Filtering out           */
1073   /********************************/
1074   if ( trackEvent2==0x0 )//in case fBufferSize == 0 and pointers are created do not eneter
1075    {
1076      trackEvent2 = new AliAOD();
1077    }
1078
1079   FilterOut(trackEvent1, trackEvent2, rawtrackEvent);
1080
1081   for (Int_t j = 0; j<trackEvent1->GetNumberOfParticles() ; j++)
1082    {
1083      if ( (j%fDisplayMixingInfo) == 0) 
1084         Info("ProcessTracksNonIdentAnal",
1085              "Mixing particle %d from current event with particles from current event",j);
1086
1087      track1= trackEvent1->GetParticle(j);
1088
1089
1090      for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
1091        fTrackMonitorFunctions[ii]->Process(track1);
1092
1093      if (fNTrackFunctions == 0x0) continue;
1094
1095      /***************************************/
1096      /******   filling numerators    ********/
1097      /****** (particles from event2) ********/
1098      /***************************************/
1099
1100      for (Int_t k = 0; k < trackEvent2->GetNumberOfParticles() ; k++) //partEvent1 and partEvent2 are particles from the same event but separated to two groups 
1101       {
1102         track2= trackEvent2->GetParticle(k);
1103         if (track1->GetUID() == track2->GetUID()) continue;//this is the same particle but with different PID
1104         trackpair->SetParticles(track1,track2);
1105
1106
1107         if( fPairCut->PassPairProp(trackpair)) //check pair cut
1108          { //do not meets crietria of the pair cut
1109            continue; 
1110          }
1111         else
1112          {//meets criteria of the pair cut
1113            UInt_t ii;
1114            for(ii = 0;ii<fNTrackFunctions;ii++)
1115                   fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1116          }
1117        }
1118
1119  if ( fBufferSize == 0) continue;//do not mix diff histograms
1120  /***************************************/
1121  /***** Filling denominators    *********/
1122  /***************************************/
1123  fTrackBuffer->ResetIter();
1124
1125  Int_t nmonitor = 0;
1126
1127  while ( (trackEvent3 = fTrackBuffer->Next() ) != 0x0)
1128   {
1129     if ( (j%fDisplayMixingInfo) == 0) 
1130       Info("ProcessTracksNonIdentAnal",
1131            "Mixing particle %d from current event with particles from event%d",j,-(++nmonitor));
1132
1133     for (Int_t k = 0; k < trackEvent3->GetNumberOfParticles() ; k++)
1134       {
1135         track2= trackEvent3->GetParticle(k);
1136         trackpair->SetParticles(track1,track2);
1137
1138         if( fPairCut->PassPairProp(trackpair)) //check pair cut
1139          { //do not meets crietria of the pair cut
1140            continue; 
1141          }
1142         else
1143          {//meets criteria of the pair cut
1144            for(ii = 0;ii<fNTrackFunctions;ii++)
1145                fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1146          }
1147        }// for particles event2
1148      }//while event2
1149    }//for over particles in event1
1150
1151  delete fTrackBuffer->Push(trackEvent2);
1152  
1153  return 0;
1154 }
1155 /*************************************************************************************/ 
1156
1157 void AliHBTAnalysis::Process(Option_t* option)
1158 {
1159  //default option  = "TracksAndParticles"
1160  //Main method of the HBT Analysis Package
1161  //It triggers reading with the global cut (default is an empty cut)
1162  //Than it checks options and data which are read
1163  //if everything is OK, then it calls one of the looping methods
1164  //depending on tfReaderhe option
1165  //These methods differs on what thay are looping on
1166  //
1167  //        METHOD                           OPTION
1168  //--------------------------------------------------------------------
1169  //ProcessTracksAndParticles    -     "TracksAndParticles"
1170  //     DEFAULT
1171  //     it loops over both, tracks(reconstructed) and particles(simulated)
1172  //     all function gethered in all 3 lists are called for each (double)pair
1173  //                             
1174  //ProcessTracks                -          "Tracks" 
1175  //     it loops only on tracks(reconstructed),
1176  //     functions ONLY from fTrackFunctions list are called
1177  //
1178  //ProcessParticles             -         "Particles"
1179  //     it loops only on particles(simulated),
1180  //     functions ONLY from fParticleAndTrackFunctions list are called
1181  //
1182  //
1183  if (!fReader) 
1184   {
1185    Error("Process","The reader is not set");
1186    return;
1187   }
1188  
1189  const char *oT = strstr(option,"Tracks");
1190  const char *oP = strstr(option,"Particles");
1191  
1192  Bool_t nonid = IsNonIdentAnalysis();
1193  
1194  Init();
1195  
1196  if(oT && oP)
1197   { 
1198     if (nonid) ProcessTracksAndParticlesNonIdentAnal();
1199     else ProcessTracksAndParticles();
1200     return;
1201   }
1202
1203  if(oT)
1204   {
1205     if (nonid) ProcessTracksNonIdentAnal();
1206     else ProcessTracks();
1207     return;
1208   }
1209  
1210  if(oP)
1211   {
1212     if (nonid) ProcessParticlesNonIdentAnal();
1213     else ProcessParticles();
1214     return;
1215   }
1216  
1217 }
1218 /*************************************************************************************/ 
1219
1220 void AliHBTAnalysis::ProcessTracksAndParticles()
1221 {
1222 //Makes analysis for both tracks and particles
1223 //mainly for resolution study and analysies with weighting algirithms
1224 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
1225 //the loops are splited
1226   
1227 // cut on particles only -- why?
1228 // - PID: when we make resolution analysis we want to take only tracks with correct PID
1229 // We need cut on tracks because there are data characteristic to 
1230   
1231   AliAOD * trackEvent, *partEvent;
1232
1233   fReader->Rewind();
1234   while (fReader->Next() == kFALSE)
1235     {
1236       partEvent = fReader->GetEventSim();
1237       trackEvent = fReader->GetEventRec();
1238       ProcessRecAndSim(trackEvent,partEvent);
1239
1240     }//while (fReader->Next() == kFALSE)
1241     
1242
1243 /*************************************************************************************/
1244
1245 void AliHBTAnalysis::ProcessTracks()
1246 {
1247 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
1248 //the loops are splited
1249   AliAOD * trackEvent;
1250   fReader->Rewind();
1251   while (fReader->Next() == kFALSE)
1252     {
1253       trackEvent = fReader->GetEventRec();
1254       ProcessRec(trackEvent,0x0);
1255     }//while (fReader->Next() == kFALSE)
1256 }
1257
1258 /*************************************************************************************/
1259
1260 void AliHBTAnalysis::ProcessParticles()
1261 {
1262 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
1263 //the loops are splited
1264   AliAOD * partEvent;
1265   fReader->Rewind();
1266   while (fReader->Next() == kFALSE)
1267     {
1268       partEvent = fReader->GetEventSim();
1269       ProcessSim(0x0,partEvent);
1270     }//while (fReader->Next() == kFALSE)
1271 }
1272 /*************************************************************************************/
1273
1274 void AliHBTAnalysis::WriteFunctions()
1275 {
1276 //Calls Write for all defined functions in analysis
1277 //== writes all results
1278   TFile* oututfile = 0x0;
1279   if (fOutputFileName)
1280    {
1281      oututfile = TFile::Open(*fOutputFileName,"update");
1282    }
1283   UInt_t ii;
1284   for(ii = 0;ii<fNParticleFunctions;ii++)
1285    {
1286      if (AliVAODParticle::GetDebug()>5)
1287       {
1288         Info("WriteFunctions","Writing ParticleFunction %#x",fParticleFunctions[ii]);
1289         Info("WriteFunctions","Writing ParticleFunction %s",fParticleFunctions[ii]->Name());
1290       }
1291      fParticleFunctions[ii]->Write();
1292    }
1293                  
1294   for(ii = 0;ii<fNTrackFunctions;ii++)
1295    {
1296      if (AliVAODParticle::GetDebug()>5)
1297       {
1298         Info("WriteFunctions","Writing TrackFunction %#x",fTrackFunctions[ii]);
1299         Info("WriteFunctions","Writing TrackFunction %s",fTrackFunctions[ii]->Name());
1300       }
1301      fTrackFunctions[ii]->Write();
1302    }
1303                  
1304   for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
1305    {
1306      if (AliVAODParticle::GetDebug()>5)
1307       {
1308         Info("WriteFunctions","Writing ParticleAndTrackFunction %#x",fParticleAndTrackFunctions[ii]);
1309         Info("WriteFunctions","Writing ParticleAndTrackFunction %s",fParticleAndTrackFunctions[ii]->Name());
1310       } 
1311      fParticleAndTrackFunctions[ii]->Write();
1312    }
1313
1314   for(ii = 0;ii<fNParticleMonitorFunctions;ii++)
1315    {
1316      if (AliVAODParticle::GetDebug()>5)
1317       {
1318         Info("WriteFunctions","Writing ParticleMonitorFunction %#x",fParticleMonitorFunctions[ii]);
1319         Info("WriteFunctions","Writing ParticleMonitorFunction %s",fParticleMonitorFunctions[ii]->Name());
1320       }
1321      fParticleMonitorFunctions[ii]->Write();
1322    }
1323
1324   for(ii = 0;ii<fNTrackMonitorFunctions;ii++)
1325    {
1326      if (AliVAODParticle::GetDebug()>5)
1327       {
1328         Info("WriteFunctions","Writing TrackMonitorFunction %#x",fTrackMonitorFunctions[ii]);
1329         Info("WriteFunctions","Writing TrackMonitorFunction %s",fTrackMonitorFunctions[ii]->Name());
1330       }
1331      fTrackMonitorFunctions[ii]->Write();
1332    }
1333
1334   for(ii = 0;ii<fNParticleAndTrackMonitorFunctions;ii++)
1335    {
1336      if (AliVAODParticle::GetDebug()>5)
1337       {
1338        Info("WriteFunctions","Writing ParticleAndTrackMonitorFunction %#x",fParticleAndTrackMonitorFunctions[ii]);
1339        Info("WriteFunctions","Writing ParticleAndTrackMonitorFunction %s",fParticleAndTrackMonitorFunctions[ii]->Name());
1340       }
1341      fParticleAndTrackMonitorFunctions[ii]->Write();
1342    }
1343   delete oututfile; 
1344 }
1345 /*************************************************************************************/
1346
1347 void AliHBTAnalysis::SetOutputFileName(const char* fname)
1348 {
1349   //Sets fiele name where to dump results, 
1350   //if not specified reults are written to gDirectory
1351   if (fname == 0x0)
1352    {
1353      delete fOutputFileName;
1354      fOutputFileName = 0x0;
1355      return;
1356    }
1357   if ( strcmp(fname,"") == 0 ) 
1358    {
1359      delete fOutputFileName;
1360      fOutputFileName = 0x0;
1361      return;
1362    }
1363   if (fOutputFileName == 0x0) fOutputFileName = new TString(fname);
1364   else *fOutputFileName = fname;
1365 }
1366 /*************************************************************************************/
1367
1368 void AliHBTAnalysis::SetGlobalPairCut(AliAODPairCut* cut)
1369 {
1370 //Sets the global cut
1371   if (cut == 0x0)
1372    {
1373      Error("AliHBTAnalysis::SetGlobalPairCut","Pointer is NULL. Ignoring");
1374    }
1375   delete fPairCut;
1376   fPairCut = (AliAODPairCut*)cut->Clone();
1377 }
1378
1379 /*************************************************************************************/
1380
1381 void AliHBTAnalysis::AddTrackFunction(AliHBTOnePairFctn* f)
1382 {
1383 //Adds track function
1384   if (f == 0x0) return;
1385   if (fNTrackFunctions == fgkFctnArraySize)
1386    {
1387     Error("AliHBTAnalysis::AddTrackFunction","Can not add this function, not enough place in the array.");
1388    }
1389   fTrackFunctions[fNTrackFunctions] = f;
1390   fNTrackFunctions++;
1391 }
1392 /*************************************************************************************/ 
1393
1394 void AliHBTAnalysis::AddParticleFunction(AliHBTOnePairFctn* f)
1395 {
1396 //adds particle function
1397   if (f == 0x0) return;
1398   
1399   if (fNParticleFunctions == fgkFctnArraySize)
1400    {
1401     Error("AliHBTAnalysis::AddParticleFunction","Can not add this function, not enough place in the array.");
1402    }
1403   fParticleFunctions[fNParticleFunctions] = f;
1404   fNParticleFunctions++;
1405 }
1406 /*************************************************************************************/ 
1407
1408 void AliHBTAnalysis::AddParticleAndTrackFunction(AliHBTTwoPairFctn* f)
1409 {
1410 //add resolution function
1411   if (f == 0x0) return;
1412   if (fNParticleAndTrackFunctions == fgkFctnArraySize)
1413    {
1414     Error("AliHBTAnalysis::AddParticleAndTrackFunction","Can not add this function, not enough place in the array.");
1415    }  
1416   fParticleAndTrackFunctions[fNParticleAndTrackFunctions] = f;
1417   fNParticleAndTrackFunctions++;
1418 }
1419 /*************************************************************************************/ 
1420
1421 void AliHBTAnalysis::AddParticleMonitorFunction(AliHBTMonOneParticleFctn* f)
1422 {
1423 //add particle monitoring function
1424   if (f == 0x0) return;
1425
1426   if (fNParticleMonitorFunctions == fgkFctnArraySize)
1427     {
1428       Error("AliHBTAnalysis::AddParticleMonitorFunction","Can not add this function, not enough place in the array.");
1429    }
1430   fParticleMonitorFunctions[fNParticleMonitorFunctions] = f;
1431   fNParticleMonitorFunctions++;
1432 }
1433 /*************************************************************************************/ 
1434
1435 void AliHBTAnalysis::AddTrackMonitorFunction(AliHBTMonOneParticleFctn* f)
1436 {
1437 //add track monitoring function
1438   if (f == 0x0) return;
1439
1440   if (fNTrackMonitorFunctions == fgkFctnArraySize)
1441    {
1442     Error("AliHBTAnalysis::AddTrackMonitorFunction","Can not add this function, not enough place in the array.");
1443    }
1444   fTrackMonitorFunctions[fNTrackMonitorFunctions] = f;
1445   fNTrackMonitorFunctions++;
1446 }
1447 /*************************************************************************************/ 
1448
1449 void AliHBTAnalysis::AddParticleAndTrackMonitorFunction(AliHBTMonTwoParticleFctn* f)
1450 {
1451 //add resolution monitoring function
1452   if (f == 0x0) return;
1453   if (fNParticleAndTrackMonitorFunctions == fgkFctnArraySize)
1454     {
1455       Error("AliHBTAnalysis::AddParticleAndTrackMonitorFunction","Can not add this function, not enough place in the array.");
1456     }
1457   fParticleAndTrackMonitorFunctions[fNParticleAndTrackMonitorFunctions] = f;
1458   fNParticleAndTrackMonitorFunctions++;
1459 }
1460
1461
1462 /*************************************************************************************/ 
1463 /*************************************************************************************/  
1464
1465 Bool_t AliHBTAnalysis::RunCoherencyCheck()
1466 {
1467  //Checks if both HBTRuns are similar
1468  //return true if error found
1469  //if they seem to be OK return false
1470 /* 
1471
1472  Int_t i;  
1473  Info("RunCoherencyCheck","Checking HBT Runs Coherency");
1474
1475 //When we use non-buffering reader this is a big waste of time -> We need to read all data to check it
1476 //and reader is implemented safe in this case anyway
1477 // Info("RunCoherencyCheck","Number of events ...");
1478 // if (fReader->GetNumberOfPartEvents() == fReader->GetNumberOfTrackEvents() ) //check whether there is the same  number of events
1479 //  {
1480 //    Info("RunCoherencyCheck","OK. %d found\n",fReader->GetNumberOfTrackEvents());
1481 //  }
1482 // else
1483 //  { //if not the same - ERROR
1484 //   Error("RunCoherencyCheck",
1485 //         "Number of simulated events (%d) is not equal to number of reconstructed events(%d)",
1486 //         fReader->GetNumberOfPartEvents(),fReader->GetNumberOfTrackEvents());
1487 //   return kTRUE;
1488 //  }
1489  
1490  Info("RunCoherencyCheck","Checking number of Particles AND Particles Types in each event ...");
1491  
1492  AliAOD *partEvent;
1493  AliAOD *trackEvent;
1494  for( i = 0; i<fReader->GetNumberOfTrackEvents();i++)
1495   {
1496     partEvent= fReader->GetEventSim(i); //gets the "ith" event 
1497     trackEvent = fReader->GetEventRec(i);
1498     
1499     if ( (partEvent == 0x0) && (partEvent == 0x0) ) continue;
1500     if ( (partEvent == 0x0) || (partEvent == 0x0) )
1501      {
1502        Error("RunCoherencyCheck",
1503              "One event is NULL and the other one not. Event Number %d",i);
1504        return kTRUE;    
1505      }
1506     
1507     if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
1508      {
1509        Error("RunCoherencyCheck",
1510              "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
1511              i,partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
1512        return kTRUE;
1513      }
1514     else
1515      for (Int_t j = 0; j<partEvent->GetNumberOfParticles(); j++)
1516       {
1517         if( partEvent->GetParticle(j)->GetPdgCode() != trackEvent->GetParticle(j)->GetPdgCode() )
1518          {
1519            Error("RunCoherencyCheck",
1520                  "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
1521                  i,j, partEvent->GetParticle(j)->GetPdgCode(),trackEvent->GetParticle(j)->GetPdgCode() );
1522            return kTRUE;
1523            
1524          }
1525       }
1526   }
1527  Info("RunCoherencyCheck","  Done");
1528  Info("RunCoherencyCheck","  Everything looks OK");
1529 */ 
1530  return kFALSE;
1531 }
1532
1533 /*************************************************************************************/  
1534  
1535 void AliHBTAnalysis::ProcessTracksAndParticlesNonIdentAnal()
1536 {
1537 //Performs analysis for both, tracks and particles
1538   AliAOD* rawtrackEvent, * rawpartEvent;
1539   fReader->Rewind();
1540  
1541   Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
1542   Info("ProcessTracksAndParticlesNonIdentAnal","*****  NON IDENT MODE ****************");
1543   Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
1544
1545   for (Int_t i = 0;;i++)//infinite loop
1546     {
1547       if (fReader->Next()) break; //end when no more events available
1548       
1549       rawpartEvent  = fReader->GetEventSim();
1550       rawtrackEvent = fReader->GetEventRec();
1551       
1552       ProcessRecAndSimNonId(rawtrackEvent,rawpartEvent);
1553   }//end of loop over events (1)
1554 }
1555 /*************************************************************************************/  
1556  
1557 void AliHBTAnalysis::ProcessTracksNonIdentAnal()
1558 {
1559 //Process Tracks only with non identical mode
1560   AliAOD * rawtrackEvent;
1561   fReader->Rewind();
1562   
1563   Info("ProcessTracksNonIdentAnal","**************************************");
1564   Info("ProcessTracksNonIdentAnal","*****  NON IDENT MODE ****************");
1565   Info("ProcessTracksNonIdentAnal","**************************************");
1566   
1567   for (Int_t i = 0;;i++)//infinite loop
1568     {
1569       if (fReader->Next()) break; //end when no more events available
1570       rawtrackEvent = fReader->GetEventRec();
1571       ProcessRecNonId(rawtrackEvent,0x0);
1572   }//end of loop over events (1)
1573 }
1574 /*************************************************************************************/  
1575
1576 void AliHBTAnalysis::ProcessParticlesNonIdentAnal()
1577 {
1578 //process paricles only with non identical mode
1579   AliAOD * rawpartEvent = 0x0;
1580   fReader->Rewind();
1581   
1582   Info("ProcessParticlesNonIdentAnal","**************************************");
1583   Info("ProcessParticlesNonIdentAnal","*****  NON IDENT MODE ****************");
1584   Info("ProcessParticlesNonIdentAnal","**************************************");
1585
1586   for (Int_t i = 0;;i++)//infinite loop
1587     {
1588       if (fReader->Next()) break; //end when no more events available
1589       
1590       rawpartEvent  = fReader->GetEventSim();
1591       ProcessSimNonId(0x0,rawpartEvent);
1592   }//end of loop over events (1)
1593 }
1594
1595 /*************************************************************************************/  
1596 void AliHBTAnalysis::FilterOut(AliAOD* outpart1, AliAOD* outpart2, AliAOD* inpart,
1597                      AliAOD* outtrack1, AliAOD* outtrack2, AliAOD* intrack) const
1598 {
1599  //Puts particles accepted as a first particle by global cut in out1
1600  //and as a second particle in out2
1601
1602   AliVAODParticle* part, *track;
1603
1604   outpart1->Reset();
1605   outpart2->Reset();
1606   outtrack1->Reset();
1607   outtrack2->Reset();
1608   
1609   Bool_t in1, in2;
1610   
1611   for (Int_t i = 0; i < inpart->GetNumberOfParticles(); i++)
1612    {
1613      in1 = in2 = kTRUE;
1614      part = inpart->GetParticle(i);
1615      track = intrack->GetParticle(i);
1616      
1617      if ( ((this->*fkPass1)(part,track))  ) in1 = kFALSE; //if part  is rejected by cut1, in1 is false
1618      if ( ((this->*fkPass2)(part,track))  ) in2 = kFALSE; //if part  is rejected by cut2, in2 is false
1619      
1620      if (gDebug)//to be removed in real analysis     
1621      if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1622       {
1623       //Particle accpted by both cuts
1624        Error("FilterOut","Particle accepted by both cuts");
1625        continue;
1626       }
1627
1628      if (in1)
1629       {
1630         outpart1->AddParticle(part);
1631         outtrack1->AddParticle(track);
1632         continue;
1633       }
1634      
1635      if (in2)
1636       {
1637         outpart2->AddParticle(part);
1638         outtrack2->AddParticle(track);
1639         continue;
1640       }
1641    }
1642 }
1643 /*************************************************************************************/  
1644
1645 void AliHBTAnalysis::FilterOut(AliAOD* out1, AliAOD* out2, AliAOD* in) const
1646 {
1647  //Puts particles accepted as a first particle by global cut in out1
1648  //and as a second particle in out2
1649   AliVAODParticle* part;
1650   
1651   out1->Reset();
1652   out2->Reset();
1653   
1654   AliAODParticleCut *cut1 = fPairCut->GetFirstPartCut();
1655   AliAODParticleCut *cut2 = fPairCut->GetSecondPartCut();
1656   
1657   Bool_t in1, in2;
1658   
1659   for (Int_t i = 0; i < in->GetNumberOfParticles(); i++)
1660    {
1661      in1 = in2 = kTRUE;
1662      part = in->GetParticle(i);
1663      
1664      if ( cut1->Rejected(part) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1665      if ( cut2->Rejected(part) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
1666      
1667      if (gDebug)//to be removed in real analysis     
1668      if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1669       {
1670       //Particle accpted by both cuts
1671        Error("FilterOut","Particle accepted by both cuts");
1672        continue;
1673       }
1674
1675      if (in1)
1676       { 
1677         out1->AddParticle(part);
1678         continue;
1679       }
1680      
1681      if (in2)
1682       {
1683         out2->AddParticle(part);
1684         continue;
1685       }
1686    }
1687 }
1688 /*************************************************************************************/ 
1689
1690 Bool_t AliHBTAnalysis::IsNonIdentAnalysis()
1691 {
1692  //checks if it is possible to use special analysis for non identical particles
1693  //it means - in global pair cut first particle id is different than second one 
1694  //and both are different from 0
1695  //in the future is possible to perform more sophisticated check 
1696  //if cuts have excluding requirements
1697  
1698  if (fPairCut->IsEmpty()) 
1699    return kFALSE;
1700  
1701  if (fPairCut->GetFirstPartCut()->IsEmpty()) 
1702    return kFALSE;
1703
1704  if (fPairCut->GetSecondPartCut()->IsEmpty()) 
1705    return kFALSE;
1706  
1707  Int_t id1 = fPairCut->GetFirstPartCut()->GetPID();
1708  Int_t id2 = fPairCut->GetSecondPartCut()->GetPID();
1709
1710  if ( (id1==0) || (id2==0) || (id1==id2) ) 
1711    return kFALSE;
1712  
1713  return kTRUE;
1714 }
1715 /*************************************************************************************/ 
1716
1717 void AliHBTAnalysis::SetApparentVertex(Double_t x, Double_t y, Double_t z)
1718
1719   //Sets apparent vertex
1720   // All events have to be moved to the same vertex position in order to
1721   // to be able to comare any space positions (f.g. anti-merging)
1722   // This method defines this position
1723   
1724   fVertexX = x;
1725   fVertexY = y;
1726   fVertexZ = z;
1727 }
1728 /*************************************************************************************/ 
1729
1730 void AliHBTAnalysis::PressAnyKey()
1731
1732  //small utility function that helps to make comfortable macros
1733   char c;
1734   int nread = -1;
1735   fcntl(0,  F_SETFL, O_NONBLOCK);
1736   ::Info("","Press Any Key to continue ...");
1737   while (nread<1) 
1738    {
1739      nread = read(0, &c, 1);
1740      gSystem->ProcessEvents();
1741    }
1742 }
1743
1744 /*************************************************************************************/ 
1745