Memory leaks removed in non ident mode
[u/mrichter/AliRoot.git] / HBTAN / AliHBTAnalysis.cxx
1 #include "AliHBTAnalysis.h"
2 #include "AliHBTRun.h"
3 #include "AliHBTEvent.h"
4 #include "AliHBTReader.h"
5 #include "AliHBTParticle.h"
6 #include "AliHBTParticleCut.h"
7 #include "AliHBTPair.h"
8 #include "AliHBTPairCut.h"
9 #include "AliHBTFunction.h"
10 #include "AliHBTMonitorFunction.h"
11  
12 #include <TBenchmark.h>
13 #include <TList.h>
14
15 ClassImp(AliHBTAnalysis)
16
17 const UInt_t AliHBTAnalysis::fgkFctnArraySize = 100;
18 const UInt_t AliHBTAnalysis::fgkDefaultMixingInfo = 1000;
19 const Int_t  AliHBTAnalysis::fgkDefaultBufferSize = 5;
20
21 AliHBTAnalysis::AliHBTAnalysis():
22  fReader(0x0),
23  fNTrackFunctions(0),
24  fNParticleFunctions(0),
25  fNParticleAndTrackFunctions(0),
26  fNTrackMonitorFunctions(0),
27  fNParticleMonitorFunctions(0), 
28  fNParticleAndTrackMonitorFunctions(0),
29  fBufferSize(2),
30  fDisplayMixingInfo(fgkDefaultMixingInfo),
31  fIsOwner(kFALSE)
32  {
33    fTrackFunctions = new AliHBTOnePairFctn* [fgkFctnArraySize];
34    fParticleFunctions = new AliHBTOnePairFctn* [fgkFctnArraySize];
35    fParticleAndTrackFunctions = new AliHBTTwoPairFctn* [fgkFctnArraySize];
36    
37    fParticleMonitorFunctions = new AliHBTMonOneParticleFctn* [fgkFctnArraySize];    
38    fTrackMonitorFunctions = new AliHBTMonOneParticleFctn* [fgkFctnArraySize];    
39    fParticleAndTrackMonitorFunctions = new AliHBTMonTwoParticleFctn* [fgkFctnArraySize];    
40
41    fPairCut = new AliHBTEmptyPairCut();//empty cut - accepts all particles
42  }
43 /*************************************************************************************/ 
44
45 AliHBTAnalysis::AliHBTAnalysis(const AliHBTAnalysis& in):
46  fReader(0x0),
47  fNTrackFunctions(0),
48  fNParticleFunctions(0),
49  fNParticleAndTrackFunctions(0),
50  fNTrackMonitorFunctions(0),
51  fNParticleMonitorFunctions(0), 
52  fNParticleAndTrackMonitorFunctions(0),
53  fTrackFunctions(0x0),
54  fParticleFunctions(0x0),
55  fParticleAndTrackFunctions(0x0),
56  fParticleMonitorFunctions(0x0),
57  fTrackMonitorFunctions(0x0),
58  fParticleAndTrackMonitorFunctions(0x0),
59  fPairCut(0x0),
60  fBufferSize(fgkDefaultBufferSize),
61  fDisplayMixingInfo(fgkDefaultMixingInfo),
62  fIsOwner(kFALSE)
63  {
64    Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
65  }
66 /*************************************************************************************/ 
67 const AliHBTAnalysis& AliHBTAnalysis::operator=(const AliHBTAnalysis& right)
68  {
69    Fatal("AliHBTAnalysis(const AliHBTAnalysis&)","Sensless");
70    return *this;
71  }
72 /*************************************************************************************/ 
73 AliHBTAnalysis::~AliHBTAnalysis()
74  {
75  //destructor
76  //note that we do not delete functions itself
77  // they should be deleted by whom where created
78  //we only store pointers, and we use "new" only for pointers array
79    if (fIsOwner) 
80     DeleteFunctions();
81    delete [] fTrackFunctions;
82    delete [] fParticleFunctions;
83    delete [] fParticleAndTrackFunctions;
84    
85    delete [] fParticleMonitorFunctions; 
86    delete [] fTrackMonitorFunctions; 
87    delete [] fParticleAndTrackMonitorFunctions; 
88
89    delete fPairCut; // always have an copy of an object - we create we dstroy
90  }
91
92 /*************************************************************************************/ 
93 void AliHBTAnalysis::DeleteFunctions()
94 {
95  UInt_t ii;
96  for(ii = 0;ii<fNParticleFunctions;ii++)
97    delete fParticleFunctions[ii];
98                 
99  for(ii = 0;ii<fNTrackFunctions;ii++)
100    delete fTrackFunctions[ii];
101
102  for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
103    delete fParticleAndTrackFunctions[ii];
104  
105  for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
106    delete fParticleMonitorFunctions[ii];
107    
108  for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
109    delete fTrackMonitorFunctions[ii];
110    
111  for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
112    delete fParticleAndTrackMonitorFunctions[ii];
113 }
114 void AliHBTAnalysis::Process(Option_t* option)
115 {
116  //default option  = "TracksAndParticles"
117  //Main method of the HBT Analysis Package
118  //It triggers reading with the global cut (default is an empty cut)
119  //Than it checks options and data which are read
120  //if everything is OK, then it calls one of the looping methods
121  //depending on tfReaderhe option
122  //These methods differs on what thay are looping on
123  //
124  //        METHOD                           OPTION
125  //--------------------------------------------------------------------
126  //ProcessTracksAndParticles    -     "TracksAndParticles"
127  //     DEFAULT
128  //     it loops over both, tracks(reconstructed) and particles(simulated)
129  //     all function gethered in all 3 lists are called for each (double)pair
130  //                             
131  //ProcessTracks                -          "Tracks" 
132  //     it loops only on tracks(reconstructed),
133  //     functions ONLY from fTrackFunctions list are called
134  //
135  //ProcessParticles             -         "Particles"
136  //     it loops only on particles(simulated),
137  //     functions ONLY from fParticleAndTrackFunctions list are called
138  //
139  //
140  if (!fReader) 
141   {
142    Error("Process","The reader is not set");
143    return;
144   }
145  
146  
147  const char *oT = strstr(option,"Tracks");
148  const char *oP = strstr(option,"Particles");
149  
150  Bool_t nonid = IsNonIdentAnalysis();
151  
152  if(oT && oP)
153   { 
154     if (fReader->GetNumberOfPartEvents() <1)
155      {
156        Error("Process","There is no Particles. Maybe change the option?");
157        return;
158      }
159     if (fReader->GetNumberOfTrackEvents() <1)
160      {
161        Error("Process","There is no Tracks. Maybe change the option?");
162        return;
163      }
164     
165     if ( RunCoherencyCheck() )
166       {
167         Error("Process",
168               "Coherency check not passed. Maybe change the option?\n");
169         return;
170       }
171     if (nonid) ProcessTracksAndParticlesNonIdentAnal();
172     else ProcessTracksAndParticles();
173     return;
174   }
175
176  if(oT)
177   {
178     if (fReader->GetNumberOfTrackEvents() <1)
179      {
180        Error("Process","There is no data to analyze.");
181        return;
182      }
183     if (nonid) ProcessTracksNonIdentAnal();
184     else ProcessTracks();
185     return;
186   }
187  
188  if(oP)
189   {
190     if (fReader->GetNumberOfPartEvents() <1)
191      {
192        Error("Process","There is no data to analyze.");
193        return;
194      }
195     if (nonid) ProcessParticlesNonIdentAnal();
196     else ProcessParticles();
197     return;
198   }
199  
200 }
201
202 /*************************************************************************************/ 
203
204 void AliHBTAnalysis::ProcessTracksAndParticles()
205 {
206
207 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
208 //the loops are splited
209   
210   
211   AliHBTParticle * part1, * part2;
212   AliHBTParticle * track1, * track2;
213   
214   AliHBTEvent * trackEvent, *partEvent;
215   AliHBTEvent * trackEvent2,*partEvent2;
216   
217 //  Int_t N1, N2, N=0; //number of particles in current event(we prcess two events in one time)
218   
219   Int_t Nev = fReader->GetNumberOfTrackEvents();
220   
221   /***************************************/
222   /******   Looping same events   ********/
223   /******   filling numerators    ********/
224   /***************************************/
225   AliHBTPair * trackpair = new AliHBTPair();
226   AliHBTPair * partpair = new AliHBTPair();
227
228   AliHBTPair * tmptrackpair;//temprary pointers to pairs
229   AliHBTPair * tmppartpair;
230
231   register UInt_t ii;
232   
233   for (Int_t i = 0;i<Nev;i++)
234     {
235       partEvent= fReader->GetParticleEvent(i);
236       trackEvent = fReader->GetTrackEvent(i);
237       
238       if (!partEvent) continue;
239       
240       //N = 0;
241       
242       for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
243        {
244
245          if ( (j%fDisplayMixingInfo) == 0) 
246             Info("ProcessTracksAndParticles",
247                  "Mixing particle %d from event %d with particles from event %d",j,i,i);
248
249          part1= partEvent->GetParticle(j);
250          track1= trackEvent->GetParticle(j);       
251
252          if (fPairCut->GetFirstPartCut()->Pass(part1)) continue;
253
254          for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
255            fParticleMonitorFunctions[ii]->ProcessSameEventParticles(part1);
256          for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
257            fTrackMonitorFunctions[ii]->ProcessSameEventParticles(track1);
258          for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
259            fParticleAndTrackMonitorFunctions[ii]->ProcessSameEventParticles(track1,part1);
260
261          if ( (fNParticleFunctions == 0) && (fNTrackFunctions ==0) && (fNParticleAndTrackFunctions == 0))
262            continue; 
263         
264          for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
265           {
266             part2= partEvent->GetParticle(k);
267             partpair->SetParticles(part1,part2);
268            
269             track2= trackEvent->GetParticle(k);       
270             trackpair->SetParticles(track1,track2);
271
272             if(fPairCut->Pass(partpair) ) //check pair cut
273               { //do not meets crietria of the pair cut, try with swaped pairs
274                 if( fPairCut->Pass(partpair->GetSwapedPair()) )
275                   continue; //swaped pairs do not meet criteria of pair cut as well, take next particle
276                 else 
277                { //swaped pair meets all the criteria
278                    tmppartpair = partpair->GetSwapedPair();
279                    tmptrackpair = trackpair->GetSwapedPair();
280                  }
281               }
282             else
283              {//meets criteria of the pair cut
284                tmptrackpair = trackpair;
285                tmppartpair = partpair;
286              }
287             for(ii = 0;ii<fNParticleFunctions;ii++)
288                    fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
289                 
290             for(ii = 0;ii<fNTrackFunctions;ii++)
291                    fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
292                  
293             for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
294                    fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair,tmppartpair);
295            }
296        }
297     }
298
299   /***************************************/
300   /***** Filling denominators    *********/
301   /***************************************/
302   if (fBufferSize != 0)
303    for (Int_t i = 0;i<Nev-1;i++)   //In each event (but last) ....
304     {
305   
306       if ((fNParticleFunctions == 0) && (fNTrackFunctions ==0) && (fNParticleAndTrackFunctions == 0))
307         continue;  
308
309       partEvent= fReader->GetParticleEvent(i);
310       if (!partEvent) continue;
311       
312       trackEvent = fReader->GetTrackEvent(i); 
313       
314       for (Int_t j = 0; j< partEvent->GetNumberOfParticles(); j++) // ... Loop over all particles ...
315        {
316            part1= partEvent->GetParticle(j);
317            track1= trackEvent->GetParticle(j);
318
319            if (fPairCut->GetFirstPartCut()->Pass(part1)) continue;
320  
321            Int_t NNN;
322            
323            if ( ((i+fBufferSize) >= Nev) ||( fBufferSize < 0) ) //if buffer size is negative 
324                                                                 //or current event+buffersize is greater
325                                                                 //than max nuber of events
326              {
327                NNN = Nev; //set the max event number 
328              }
329            else 
330              {
331                NNN = i+fBufferSize; //set the current event number + fBufferSize
332              }
333  
334            for (Int_t k = i+1; k<NNN;k++)  // ... Loop over next event
335             {
336              
337              partEvent2= fReader->GetParticleEvent(k);
338              if (!partEvent2) continue;
339               
340              trackEvent2 = fReader->GetTrackEvent(k);
341              
342              if ( (j%fDisplayMixingInfo) == 0) 
343                  Info("ProcessTracksAndParticles",
344                       "Mixing particle %d from event %d with particles from event %d",j,i,k);
345             
346              for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++)   //  ... on all particles
347               {
348                 part2= partEvent2->GetParticle(l);
349                 partpair->SetParticles(part1,part2);
350
351                 track2= trackEvent2->GetParticle(l);
352                 trackpair->SetParticles(track1,track2);
353
354                 if( fPairCut->Pass(partpair) ) //check pair cut
355                   { //do not meets crietria of the 
356                     if( fPairCut->Pass(partpair->GetSwapedPair()) )
357                       continue;
358                     else 
359                      {
360                        tmppartpair = partpair->GetSwapedPair();
361                        tmptrackpair = trackpair->GetSwapedPair();
362                      }
363                   }
364                 else
365                  {//meets criteria of the pair cut
366                   tmptrackpair = trackpair;
367                   tmppartpair = partpair;
368                  }
369                 for(ii = 0;ii<fNParticleFunctions;ii++)
370                   fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
371                  
372                 for(ii = 0;ii<fNTrackFunctions;ii++)
373                   fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
374                  
375                 for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
376                   fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair,tmppartpair);
377               }//for(Int_t l = 0; l<N2;l++)   //  ... on all particles
378             }//for (Int_t k = i+1; k<NNN;k++)  // ... Loop over next event
379        }
380     } 
381   /***************************************/
382
383 /*************************************************************************************/
384
385 void AliHBTAnalysis::ProcessTracks()
386 {
387   //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
388 //the loops are splited
389   AliHBTParticle * track1, * track2;
390   AliHBTEvent * trackEvent;
391   AliHBTEvent * trackEvent2;
392
393   UInt_t ii;
394   Int_t Nev = fReader->GetNumberOfTrackEvents();
395
396   AliHBTPair * trackpair = new AliHBTPair();
397   AliHBTPair * tmptrackpair; //temporary pointer 
398   
399   /***************************************/
400   /******   Looping same events   ********/
401   /******   filling numerators    ********/
402   /***************************************/
403   for (Int_t i = 0;i<Nev;i++)
404     {
405       trackEvent = fReader->GetTrackEvent(i);
406       if (!trackEvent) continue;
407       
408       for (Int_t j = 0; j<trackEvent->GetNumberOfParticles() ; j++)
409        {
410          if ( (j%fDisplayMixingInfo) == 0) 
411                Info("ProcessTracks",
412                     "Mixing particle %d from event %d with particles from event %d",j,i,i);
413          
414          track1= trackEvent->GetParticle(j);       
415          if (fPairCut->GetFirstPartCut()->Pass(track1)) continue;
416
417          for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
418            fTrackMonitorFunctions[ii]->ProcessSameEventParticles(track1);
419
420          if ( fNTrackFunctions ==0 )
421            continue; 
422         
423          for (Int_t k =j+1; k < trackEvent->GetNumberOfParticles() ; k++)
424           {
425            track2= trackEvent->GetParticle(k);       
426            trackpair->SetParticles(track1,track2);
427            if(fPairCut->Pass(trackpair)) //check pair cut
428             { //do not meets crietria of the 
429               if( fPairCut->Pass(trackpair->GetSwapedPair()) ) continue;
430               else tmptrackpair = trackpair->GetSwapedPair();
431             }
432            else
433             {
434               tmptrackpair = trackpair;
435             }
436            for(ii = 0;ii<fNTrackFunctions;ii++)
437                fTrackFunctions[ii]->ProcessSameEventParticles(tmptrackpair);
438           }
439        }
440     }
441
442   /***************************************/
443   /***** Filling diff histogram *********/
444   /***************************************/
445   if (fBufferSize != 0)
446    for (Int_t i = 0;i<Nev-1;i++)   //In each event (but last) ....
447     {
448       if ( fNTrackFunctions ==0 )
449         continue; 
450
451       trackEvent = fReader->GetTrackEvent(i);
452       if (!trackEvent) continue;
453
454       for (Int_t j = 0; j< trackEvent->GetNumberOfParticles(); j++) // ... Loop over all particles ...
455        {
456          track1= trackEvent->GetParticle(j);
457          if (fPairCut->GetFirstPartCut()->Pass(track1)) continue;
458
459          Int_t NNN;
460            
461          if ( ((i+fBufferSize) >= Nev) ||( fBufferSize < 0) ) //if buffer size is negative 
462                                                               //or current event+buffersize is greater
463                                                               //than max nuber of events
464           {
465             NNN = Nev; //set the max event number 
466           }
467          else 
468           {
469             NNN = i+fBufferSize; //set the current event number + fBufferSize
470           }
471  
472          for (Int_t k = i+1; k<NNN;k++)  // ... Loop over next event
473           {
474             trackEvent2 = fReader->GetTrackEvent(k);
475             if (!trackEvent2) continue;
476              
477             if ( (j%fDisplayMixingInfo) == 0) 
478                  Info("ProcessTracksAndParticles",
479                       "Mixing particle %d from event %d with particles from event %d",j,i,k);
480             
481             for(Int_t l = 0; l<trackEvent2->GetNumberOfParticles();l++)   //  ... on all particles
482              {
483                track2= trackEvent2->GetParticle(l);
484                trackpair->SetParticles(track1,track2);
485                 
486                if(fPairCut->Pass(trackpair)) //check pair cut
487                 { //do not meets crietria of the 
488                   if( fPairCut->Pass(trackpair->GetSwapedPair()) ) continue;
489                   else tmptrackpair = trackpair->GetSwapedPair();
490                 }
491                else
492                 {
493                   tmptrackpair = trackpair;
494                 }
495                for(ii = 0;ii<fNTrackFunctions;ii++)
496                    fTrackFunctions[ii]->ProcessDiffEventParticles(tmptrackpair);
497                
498              }//for(Int_t l = 0; l<N2;l++)   //  ... on all particles
499           }//for (Int_t k = i+1; k<NNN;k++)  // ... Loop over next event
500        }
501     } 
502   /***************************************/
503 }
504
505 /*************************************************************************************/
506
507 void AliHBTAnalysis::ProcessParticles()
508 {
509 //In order to minimize calling AliRun::GetEvent (we need at one time particles from different events),
510 //the loops are splited
511   AliHBTParticle * part1, * part2;
512   
513   AliHBTEvent * partEvent;
514   AliHBTEvent * partEvent2;
515
516   AliHBTPair * partpair = new AliHBTPair();
517   AliHBTPair * tmppartpair; //temporary pointer to the pair
518   
519   Int_t Nev = fReader->GetNumberOfPartEvents();
520   
521   /***************************************/
522   /******   Looping same events   ********/
523   /******   filling numerators    ********/
524   /***************************************/
525   for (Int_t i = 0;i<Nev;i++)
526     {
527       partEvent= fReader->GetParticleEvent(i);
528       if (!partEvent) continue;
529       //N = 0;
530       
531       for (Int_t j = 0; j<partEvent->GetNumberOfParticles() ; j++)
532        {
533          if ( (j%fDisplayMixingInfo) == 0) 
534                  Info("ProcessParticles",
535                       "Mixing particle %d from event %d with particles from event %d",j,i,i);
536
537          part1= partEvent->GetParticle(j);
538          if (fPairCut->GetFirstPartCut()->Pass(part1)) continue;
539         
540          UInt_t zz;
541          for(zz = 0; zz<fNParticleMonitorFunctions; zz++)
542            fParticleMonitorFunctions[zz]->ProcessSameEventParticles(part1);
543
544          if ( fNParticleFunctions ==0 )
545            continue; 
546
547          for (Int_t k =j+1; k < partEvent->GetNumberOfParticles() ; k++)
548           {
549             part2= partEvent->GetParticle(k);
550             partpair->SetParticles(part1,part2);
551             
552             if( fPairCut->Pass(partpair) ) //check pair cut
553               { //do not meets crietria of the pair cut, try with swaped pairs
554                 if(  fPairCut->Pass(partpair->GetSwapedPair() )  ) 
555                   continue; //swaped pairs do not meet criteria of pair cut as well, take next particle
556                 else 
557                  { //swaped pair meets all the criteria
558                    tmppartpair = partpair->GetSwapedPair();
559                  }
560               }
561             else
562               {
563                 tmppartpair = partpair;
564               }
565             
566             UInt_t ii;
567             for(ii = 0;ii<fNParticleFunctions;ii++)
568                    fParticleFunctions[ii]->ProcessSameEventParticles(tmppartpair);
569            }
570        }
571     }
572
573   /***************************************/
574   /***** Filling diff histogram *********/
575   /***************************************/
576   if (fBufferSize != 0) //less then 0 mix everything, == 0 do not mix denominator
577    for (Int_t i = 0;i<Nev-1;i++)   //In each event (but last)....
578     {
579       if ( fNParticleFunctions ==0 )
580         continue; 
581
582       partEvent= fReader->GetParticleEvent(i);
583       if (!partEvent) continue;
584
585       for (Int_t j = 0; j< partEvent->GetNumberOfParticles(); j++) // ... Loop over all particles ...
586        {
587            part1= partEvent->GetParticle(j);
588            if (fPairCut->GetFirstPartCut()->Pass(part1)) continue;
589            Int_t NNN;
590
591            if ( ((i+fBufferSize) >= Nev) ||( fBufferSize < 0) ) //if buffer size is negative 
592                                                                 //or current event+buffersize is greater
593                                                                 //than max nuber of events
594             {
595              NNN = Nev; //set the max event number 
596             }
597            else 
598             {
599              NNN = i+fBufferSize; //set the current event number + fBufferSize
600             }
601            
602            for (Int_t k = i+1; k<NNN;k++)  // ... Loop over next event
603             {
604              
605              partEvent2= fReader->GetParticleEvent(k);
606              if (!partEvent2) continue;
607              
608              if ( (j%fDisplayMixingInfo) == 0) 
609                 Info("ProcessParticles",
610                      "Mixing particle %d from event %d with particles from event %d",j,i,k);
611             
612              for(Int_t l = 0; l<partEvent2->GetNumberOfParticles();l++)   //  ... on all particles
613               {
614                 part2= partEvent2->GetParticle(l);
615                 partpair->SetParticles(part1,part2);
616                 
617                 if(fPairCut->Pass(partpair)) //check pair cut
618                   { //do not meets crietria of the 
619                     if( fPairCut->Pass(partpair->GetSwapedPair()) ) continue;
620                     else tmppartpair = partpair->GetSwapedPair();
621                   }
622                 else
623                   {
624                     tmppartpair = partpair;
625                   }
626                 UInt_t ii;
627                 for(ii = 0;ii<fNParticleFunctions;ii++)
628                   fParticleFunctions[ii]->ProcessDiffEventParticles(tmppartpair);
629                
630               }//for(Int_t l = 0; l<N2;l++)   //  ... on all particles
631             }//for (Int_t k = i+1; k<NNN;k++)  // ... Loop over next event
632        }
633     } 
634   /***************************************/
635
636 }
637 /*************************************************************************************/
638
639 void AliHBTAnalysis::WriteFunctions()
640 {
641 //Calls Write for all defined functions in analysis
642 //== writes all results
643   UInt_t ii;
644   for(ii = 0;ii<fNParticleFunctions;ii++)
645     fParticleFunctions[ii]->Write();
646                  
647   for(ii = 0;ii<fNTrackFunctions;ii++)
648     fTrackFunctions[ii]->Write();
649                  
650   for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
651    fParticleAndTrackFunctions[ii]->Write();
652
653   for(ii = 0;ii<fNParticleMonitorFunctions;ii++)
654     fParticleMonitorFunctions[ii]->Write();
655
656   for(ii = 0;ii<fNTrackMonitorFunctions;ii++)
657     fTrackMonitorFunctions[ii]->Write();
658
659   for(ii = 0;ii<fNParticleAndTrackMonitorFunctions;ii++)
660    fParticleAndTrackMonitorFunctions[ii]->Write();
661 }
662 /*************************************************************************************/
663
664 void AliHBTAnalysis::SetGlobalPairCut(AliHBTPairCut* cut)
665 {
666 //Sets the global cut
667   if (cut == 0x0)
668    {
669      Error("AliHBTAnalysis::SetGlobalPairCut","Pointer is NULL. Ignoring");
670    }
671   delete fPairCut;
672   fPairCut = (AliHBTPairCut*)cut->Clone();
673 }
674
675 /*************************************************************************************/
676
677 void AliHBTAnalysis::AddTrackFunction(AliHBTOnePairFctn* f)
678 {
679 //Adds track function
680   if (f == 0x0) return;
681   if (fNTrackFunctions == fgkFctnArraySize)
682    {
683     Error("AliHBTAnalysis::AddTrackFunction","Can not add this function, not enough place in the array.");
684    }
685   fTrackFunctions[fNTrackFunctions] = f;
686   fNTrackFunctions++;
687 }
688 /*************************************************************************************/ 
689
690 void AliHBTAnalysis::AddParticleFunction(AliHBTOnePairFctn* f)
691 {
692 //adds particle function
693   if (f == 0x0) return;
694   
695   if (fNParticleFunctions == fgkFctnArraySize)
696    {
697     Error("AliHBTAnalysis::AddParticleFunction","Can not add this function, not enough place in the array.");
698    }
699   fParticleFunctions[fNParticleFunctions] = f;
700   fNParticleFunctions++;
701 }
702 /*************************************************************************************/ 
703
704 void AliHBTAnalysis::AddParticleAndTrackFunction(AliHBTTwoPairFctn* f)
705 {
706 //add resolution function
707   if (f == 0x0) return;
708   if (fNParticleAndTrackFunctions == fgkFctnArraySize)
709    {
710     Error("AliHBTAnalysis::AddParticleAndTrackFunction","Can not add this function, not enough place in the array.");
711    }  
712   fParticleAndTrackFunctions[fNParticleAndTrackFunctions] = f;
713   fNParticleAndTrackFunctions++;
714 }
715 /*************************************************************************************/ 
716
717 void AliHBTAnalysis::AddParticleMonitorFunction(AliHBTMonOneParticleFctn* f)
718 {
719 //add particle monitoring function
720   if (f == 0x0) return;
721
722   if (fNParticleMonitorFunctions == fgkFctnArraySize)
723     {
724       Error("AliHBTAnalysis::AddParticleMonitorFunction","Can not add this function, not enough place in the array.");
725    }
726   fParticleMonitorFunctions[fNParticleMonitorFunctions] = f;
727   fNParticleMonitorFunctions++;
728 }
729 /*************************************************************************************/ 
730
731 void AliHBTAnalysis::AddTrackMonitorFunction(AliHBTMonOneParticleFctn* f)
732 {
733 //add track monitoring function
734   if (f == 0x0) return;
735
736   if (fNTrackMonitorFunctions == fgkFctnArraySize)
737    {
738     Error("AliHBTAnalysis::AddTrackMonitorFunction","Can not add this function, not enough place in the array.");
739    }
740   fTrackMonitorFunctions[fNTrackMonitorFunctions] = f;
741   fNTrackMonitorFunctions++;
742 }
743 /*************************************************************************************/ 
744
745 void AliHBTAnalysis::AddParticleAndTrackMonitorFunction(AliHBTMonTwoParticleFctn* f)
746 {
747 //add resolution monitoring function
748   if (f == 0x0) return;
749   if (fNParticleAndTrackMonitorFunctions == fgkFctnArraySize)
750     {
751       Error("AliHBTAnalysis::AddParticleAndTrackMonitorFunction","Can not add this function, not enough place in the array.");
752     }
753   fParticleAndTrackMonitorFunctions[fNParticleAndTrackMonitorFunctions] = f;
754   fNParticleAndTrackMonitorFunctions++;
755 }
756
757
758 /*************************************************************************************/ 
759 /*************************************************************************************/  
760
761 Bool_t AliHBTAnalysis::RunCoherencyCheck()
762 {
763  //Checks if both HBTRuns are similar
764  //return true if error found
765  //if they seem to be OK return false
766  Int_t i;  
767  Info("RunCoherencyCheck","Checking HBT Runs Coherency");
768
769  Info("RunCoherencyCheck","Number of events ...");
770  if (fReader->GetNumberOfPartEvents() == fReader->GetNumberOfTrackEvents() ) //check whether there is the same  number of events
771   {
772     Info("RunCoherencyCheck","OK. %d found\n",fReader->GetNumberOfTrackEvents());
773   }
774  else
775   { //if not the same - ERROR
776    Error("AliHBTAnalysis::RunCoherencyCheck()",
777          "Number of simulated events (%d) is not equal to number of reconstructed events(%d)",
778          fReader->GetNumberOfPartEvents(),fReader->GetNumberOfTrackEvents());
779    return kTRUE;
780   }
781  
782  Info("RunCoherencyCheck","Checking number of Particles AND Particles Types in each event ...");
783  
784  AliHBTEvent *partEvent;
785  AliHBTEvent *trackEvent;
786  for( i = 0; i<fReader->GetNumberOfTrackEvents();i++)
787   {
788     partEvent= fReader->GetParticleEvent(i); //gets the "ith" event 
789     trackEvent = fReader->GetTrackEvent(i);
790     
791     if ( (partEvent == 0x0) && (partEvent == 0x0) ) continue;
792     if ( (partEvent == 0x0) || (partEvent == 0x0) )
793      {
794        Error("AliHBTAnalysis::RunCoherencyCheck()",
795              "One event is NULL and the other one not. Event Number %d",i);
796        return kTRUE;    
797      }
798     
799     if ( partEvent->GetNumberOfParticles() != trackEvent->GetNumberOfParticles() )
800      {
801        Error("AliHBTAnalysis::RunCoherencyCheck()",
802              "Event %d: Number of simulated particles (%d) not equal to number of reconstructed tracks (%d)",
803              i,partEvent->GetNumberOfParticles() , trackEvent->GetNumberOfParticles());
804        return kTRUE;
805      }
806     else
807      for (Int_t j = 0; j<partEvent->GetNumberOfParticles(); j++)
808       {
809         if( partEvent->GetParticle(j)->GetPdgCode() != trackEvent->GetParticle(j)->GetPdgCode() )
810          {
811            Error("AliHBTAnalysis::RunCoherencyCheck()",
812                  "Event %d: Particle %d: PID of simulated particle (%d) not the same of reconstructed track (%d)",
813                  i,j, partEvent->GetParticle(j)->GetPdgCode(),trackEvent->GetParticle(j)->GetPdgCode() );
814            return kTRUE;
815            
816          }
817       }
818   }
819  Info("RunCoherencyCheck","  Done");
820  Info("RunCoherencyCheck","  Everything looks OK");
821  return kFALSE;
822 }
823
824 /*************************************************************************************/  
825  
826 void AliHBTAnalysis::ProcessTracksAndParticlesNonIdentAnal()
827 {
828 //Performs analysis for both, tracks and particles
829
830   AliHBTParticle * part1, * part2;
831   AliHBTParticle * track1, * track2;
832
833   AliHBTEvent * trackEvent1=0x0,*partEvent1=0x0;
834   AliHBTEvent * trackEvent2=0x0,*partEvent2=0x0;
835   AliHBTEvent * trackEvent3=0x0,*partEvent3=0x0;
836
837   AliHBTEvent * rawtrackEvent, *rawpartEvent;
838   
839   Int_t Nev = fReader->GetNumberOfTrackEvents();
840
841   AliHBTPair * trackpair = new AliHBTPair();
842   AliHBTPair * partpair = new AliHBTPair();
843
844   TList tbuffer;
845   TList pbuffer;
846   Int_t ninbuffer = 0;
847   UInt_t ii;
848
849   trackEvent1 = new AliHBTEvent();
850   partEvent1 = new AliHBTEvent();
851   trackEvent1->SetOwner(kFALSE);
852   partEvent1->SetOwner(kFALSE);;
853   
854   Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
855   Info("ProcessTracksAndParticlesNonIdentAnal","*****  NON IDENT MODE ****************");
856   Info("ProcessTracksAndParticlesNonIdentAnal","**************************************");
857   
858   for (Int_t i = 0;i<Nev;i++)
859     {
860       rawpartEvent  = fReader->GetParticleEvent(i);
861       rawtrackEvent = fReader->GetTrackEvent(i);
862       if ( (rawpartEvent == 0x0) || (rawtrackEvent == 0x0) ) continue;//in case of any error
863
864       /********************************/
865       /*      Filtering out           */
866       /********************************/
867       if ( (fBufferSize != 0) || ( (partEvent2==0x0)||(trackEvent2==0x0)) )//in case fBufferSize == 0 and pointers are created do not eneter
868        if ((ninbuffer > fBufferSize) && (fBufferSize > 0))
869         {//if we have in buffer desired number of events, use the last. If fBufferSize<0 mix all events for background
870          partEvent2  = (AliHBTEvent*)pbuffer.Remove(pbuffer.Last()); //remove from the end to be reset, filled and put on the beginning
871          trackEvent2 = (AliHBTEvent*)tbuffer.Remove(tbuffer.Last());
872          ninbuffer--;
873         }
874        else
875         {
876          partEvent2  = new AliHBTEvent();
877          trackEvent2 = new AliHBTEvent();
878          partEvent2->SetOwner(kFALSE);
879          trackEvent2->SetOwner(kFALSE);
880         }
881       FilterOut(partEvent1, partEvent2, rawpartEvent, trackEvent1, trackEvent2, rawtrackEvent);
882       
883       for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
884        {
885          if ( (j%fDisplayMixingInfo) == 0) 
886             Info("ProcessTracksAndParticlesNonIdentAnal",
887                  "Mixing particle %d from event %d with particles from event %d",j,i,i);
888
889          part1= partEvent1->GetParticle(j);
890          track1= trackEvent1->GetParticle(j);
891
892          for(ii = 0; ii<fNParticleMonitorFunctions; ii++)
893            fParticleMonitorFunctions[ii]->ProcessSameEventParticles(part1);
894          for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
895            fTrackMonitorFunctions[ii]->ProcessSameEventParticles(track1);
896          for(ii = 0; ii<fNParticleAndTrackMonitorFunctions; ii++)
897            fParticleAndTrackMonitorFunctions[ii]->ProcessSameEventParticles(track1,part1);
898
899          /***************************************/
900          /******   filling numerators    ********/
901          /****** (particles from event2) ********/
902          /***************************************/
903          for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++)
904           {
905             part2= partEvent2->GetParticle(k);
906             partpair->SetParticles(part1,part2);
907
908             track2= trackEvent2->GetParticle(k);
909             trackpair->SetParticles(track1,track2);
910
911             if( (fPairCut->PassPairProp(partpair)) ) //check pair cut
912              { //do not meets crietria of the pair cut
913               continue; 
914              }
915             else
916              {//meets criteria of the pair cut
917               for(ii = 0;ii<fNParticleFunctions;ii++)
918                      fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
919
920               for(ii = 0;ii<fNTrackFunctions;ii++)
921                      fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
922
923               for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
924                      fParticleAndTrackFunctions[ii]->ProcessSameEventParticles(trackpair,partpair);
925              }
926            }
927         
928      if ( fBufferSize == 0) continue;//do not mix diff histograms
929      /***************************************/
930      /***** Filling denominators    *********/
931      /***************************************/
932      TIter piter(&pbuffer);
933      TIter titer(&tbuffer);
934      Int_t nmonitor = 0;
935      
936      while ( (partEvent3 = (AliHBTEvent*)piter.Next()) != 0x0)
937       {
938         trackEvent3 = (AliHBTEvent*)titer.Next();
939         if ( (j%fDisplayMixingInfo) == 0) 
940           Info("ProcessTracksAndParticlesNonIdentAnal",
941                "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
942         
943         for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
944           {
945             part2= partEvent3->GetParticle(k);
946             partpair->SetParticles(part1,part2);
947
948             track2= trackEvent3->GetParticle(k);
949             trackpair->SetParticles(track1,track2);
950
951             if( (fPairCut->PassPairProp(partpair)) ) //check pair cut
952              { //do not meets crietria of the pair cut
953               continue; 
954              }
955             else
956              {//meets criteria of the pair cut
957               UInt_t ii;
958               for(ii = 0;ii<fNParticleFunctions;ii++)
959                      fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
960
961               for(ii = 0;ii<fNTrackFunctions;ii++)
962                      fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
963
964               for(ii = 0;ii<fNParticleAndTrackFunctions;ii++)
965                      fParticleAndTrackFunctions[ii]->ProcessDiffEventParticles(trackpair,partpair);
966              }
967            }// for particles event2
968          }//while event2
969        }//for over particles in event1
970      
971      if ( fBufferSize == 0) continue;//do not mix diff histograms-> do not add to buffer list
972      Info("ProcessTracksAndParticlesNonIdentAnal","Adding Event2's to lists and setting to null");
973      pbuffer.AddFirst(partEvent2);
974      tbuffer.AddFirst(trackEvent2);
975      partEvent2 = 0x0;
976      trackEvent2 = 0x0;
977      ninbuffer++;
978
979   }//end of loop over events (1)
980  pbuffer.SetOwner();  //to clean stored events by the way of buffer destruction
981  tbuffer.SetOwner();  
982  delete partEvent1;
983  delete trackEvent1;
984  delete partpair;
985  delete trackpair;
986  if ( fBufferSize == 0)
987   {//in that case we did not add these events to list
988     delete partEvent2;
989     delete trackEvent2;
990   }
991
992 }
993 /*************************************************************************************/  
994  
995 void AliHBTAnalysis::ProcessTracksNonIdentAnal()
996 {
997   AliHBTParticle * track1, * track2;
998
999   AliHBTEvent * trackEvent1=0x0;
1000   AliHBTEvent * trackEvent2=0x0;
1001   AliHBTEvent * trackEvent3=0x0;
1002
1003   AliHBTEvent * rawtrackEvent;
1004   
1005   Int_t Nev = fReader->GetNumberOfTrackEvents();
1006
1007   AliHBTPair * trackpair = new AliHBTPair();
1008
1009   TList tbuffer;
1010   Int_t ninbuffer = 0;
1011   register UInt_t ii;
1012
1013   trackEvent1 = new AliHBTEvent();
1014   trackEvent1->SetOwner(kFALSE);
1015   
1016   Info("ProcessTracksNonIdentAnal","**************************************");
1017   Info("ProcessTracksNonIdentAnal","*****  NON IDENT MODE ****************");
1018   Info("ProcessTracksNonIdentAnal","**************************************");
1019   
1020   for (Int_t i = 0;i<Nev;i++)
1021     {
1022       rawtrackEvent = fReader->GetTrackEvent(i);
1023       if (rawtrackEvent == 0x0)  continue;//in case of any error
1024
1025       /********************************/
1026       /*      Filtering out           */
1027       /********************************/
1028       if ( (fBufferSize != 0) || ( trackEvent2==0x0) )//in case fBufferSize == 0 and pointers are created do not eneter
1029        if ((ninbuffer > fBufferSize) && (fBufferSize > 0))
1030         {//if we have in buffer desired number of events, use the last. If fBufferSize<0 mix all events for background
1031          trackEvent2 = (AliHBTEvent*)tbuffer.Remove(tbuffer.Last());
1032          ninbuffer--;
1033         }
1034        else
1035         {
1036          trackEvent2 = new AliHBTEvent();
1037          trackEvent2->SetOwner(kFALSE);
1038         }
1039       FilterOut(trackEvent1, trackEvent2, rawtrackEvent);
1040       
1041       for (Int_t j = 0; j<trackEvent1->GetNumberOfParticles() ; j++)
1042        {
1043          if ( (j%fDisplayMixingInfo) == 0) 
1044            Info("ProcessTracksNonIdentAnal",
1045                 "Mixing particle %d from event %d with particles from event %d",j,i,i);
1046
1047          track1= trackEvent1->GetParticle(j);
1048
1049          for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
1050            fTrackMonitorFunctions[ii]->ProcessSameEventParticles(track1);
1051
1052          /***************************************/
1053          /******   filling numerators    ********/
1054          /****** (particles from event2) ********/
1055          /***************************************/
1056          for (Int_t k = 0; k < trackEvent2->GetNumberOfParticles() ; k++)
1057           {
1058             track2= trackEvent2->GetParticle(k);
1059             trackpair->SetParticles(track1,track2);
1060
1061
1062             if( fPairCut->PassPairProp(trackpair)) //check pair cut
1063               { //do not meets crietria of the pair cut
1064                   continue; 
1065               }
1066             else
1067              {//meets criteria of the pair cut
1068               UInt_t ii;
1069               for(ii = 0;ii<fNTrackFunctions;ii++)
1070                      fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1071              }
1072            }
1073      if ( fBufferSize == 0) continue;//do not mix diff histograms
1074      /***************************************/
1075      /***** Filling denominators    *********/
1076      /***************************************/
1077      TIter titer(&tbuffer);
1078      Int_t nmonitor = 0;
1079      
1080      while ( (trackEvent3 = (AliHBTEvent*)titer.Next()) != 0x0)
1081       {
1082         
1083         if ( (j%fDisplayMixingInfo) == 0) 
1084             Info("ProcessTracksNonIdentAnal",
1085                  "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1086         
1087         for (Int_t k = 0; k < trackEvent3->GetNumberOfParticles() ; k++)
1088           {
1089
1090             track2= trackEvent3->GetParticle(k);
1091             trackpair->SetParticles(track1,track2);
1092
1093
1094             if( fPairCut->PassPairProp(trackpair)) //check pair cut
1095              { //do not meets crietria of the pair cut
1096                continue; 
1097              }
1098             else
1099              {//meets criteria of the pair cut
1100                for(ii = 0;ii<fNTrackFunctions;ii++)
1101                    fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1102              }
1103            }// for particles event2
1104          }//while event2
1105        }//for over particles in event1
1106      
1107      if ( fBufferSize == 0) continue;//do not mix diff histograms     
1108      tbuffer.AddFirst(trackEvent2);
1109      trackEvent2 = 0x0;
1110      ninbuffer++;
1111
1112   }//end of loop over events (1)
1113
1114  delete trackpair;
1115  delete trackEvent1;
1116  if (fBufferSize == 0) delete trackEvent2;
1117  tbuffer.SetOwner();  
1118 }
1119 /*************************************************************************************/  
1120
1121 void AliHBTAnalysis::ProcessParticlesNonIdentAnal()
1122 {
1123   AliHBTParticle * part1 = 0x0, * part2 = 0x0;
1124
1125   AliHBTEvent * partEvent1 = 0x0;
1126   AliHBTEvent * partEvent2 = 0x0;
1127   AliHBTEvent * partEvent3 = 0x0;
1128
1129   AliHBTEvent * rawpartEvent = 0x0;
1130
1131   Int_t Nev = fReader->GetNumberOfPartEvents();
1132
1133   AliHBTPair * partpair = new AliHBTPair();
1134
1135   TList pbuffer;
1136   Int_t ninbuffer = 0;
1137
1138   partEvent1 = new AliHBTEvent();
1139   partEvent1->SetOwner(kFALSE);;
1140   
1141   Info("ProcessParticlesNonIdentAnal","**************************************");
1142   Info("ProcessParticlesNonIdentAnal","*****  NON IDENT MODE ****************");
1143   Info("ProcessParticlesNonIdentAnal","**************************************");
1144
1145   for (Int_t i = 0;i<Nev;i++)
1146     {
1147       rawpartEvent  = fReader->GetParticleEvent(i);
1148       if ( rawpartEvent == 0x0  ) continue;//in case of any error
1149
1150       /********************************/
1151       /*      Filtering out           */
1152       /********************************/
1153       if ( (fBufferSize != 0) || ( partEvent2==0x0) )//in case fBufferSize == 0 and pointers are created do not eneter
1154        if ((ninbuffer > fBufferSize) && (fBufferSize > 0))
1155         {//if we have in buffer desired number of events, use the last. If fBufferSize<0 mix all events for background
1156          partEvent2  = (AliHBTEvent*)pbuffer.Remove(pbuffer.Last()); //remove from the end to be reset, filled and put on the beginning
1157          ninbuffer--; 
1158         }
1159        else
1160         {
1161          partEvent2  = new AliHBTEvent();
1162          partEvent2->SetOwner(kFALSE);
1163         }
1164       FilterOut(partEvent1, partEvent2, rawpartEvent);
1165       
1166       for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
1167        {
1168          if ( (j%fDisplayMixingInfo) == 0) 
1169             Info("ProcessParticlesNonIdentAnal",
1170                  "Mixing particle %d from event %d with particles from event %d",j,i,i);
1171
1172          part1= partEvent1->GetParticle(j);
1173
1174          UInt_t zz;
1175          for(zz = 0; zz<fNParticleMonitorFunctions; zz++)
1176            fParticleMonitorFunctions[zz]->ProcessSameEventParticles(part1);
1177
1178          /***************************************/
1179          /******   filling numerators    ********/
1180          /****** (particles from event2) ********/
1181          /***************************************/
1182          for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++)
1183           {
1184             part2= partEvent2->GetParticle(k);
1185             partpair->SetParticles(part1,part2);
1186
1187             if(fPairCut->PassPairProp(partpair) ) //check pair cut
1188               { //do not meets crietria of the pair cut
1189                   continue; 
1190               }
1191             else
1192              {//meets criteria of the pair cut
1193               UInt_t ii;
1194               for(ii = 0;ii<fNParticleFunctions;ii++)
1195                 {
1196                   fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1197                 }
1198              }
1199            }
1200      if ( fBufferSize == 0) continue;//do not mix diff histograms
1201      /***************************************/
1202      /***** Filling denominators    *********/
1203      /***************************************/
1204      TIter piter(&pbuffer);
1205      Int_t nmonitor = 0;
1206
1207      while ( (partEvent3 = (AliHBTEvent*)piter.Next()) != 0x0)
1208       {
1209         if ( (j%fDisplayMixingInfo) == 0) 
1210             Info("ProcessParticlesNonIdentAnal",
1211                  "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1212
1213         for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1214           {
1215             part2= partEvent3->GetParticle(k);
1216             partpair->SetParticles(part1,part2);
1217
1218             if(fPairCut->PassPairProp(partpair) ) //check pair cut
1219               { //do not meets crietria of the pair cut
1220                   continue; 
1221               }
1222             else
1223              {//meets criteria of the pair cut
1224               UInt_t ii;
1225               for(ii = 0;ii<fNParticleFunctions;ii++)
1226                {
1227                  fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1228                }
1229              }
1230            }// for particles event2
1231          }//while event2
1232        }//for over particles in event1
1233      if ( fBufferSize == 0) continue;//do not mix diff histograms
1234      pbuffer.AddFirst(partEvent2);
1235      partEvent2 = 0x0; 
1236      ninbuffer++;
1237
1238   }//end of loop over events (1)
1239  delete partpair;
1240  delete partEvent1;
1241  if ( fBufferSize == 0) delete partEvent2;
1242  pbuffer.SetOwner();//to delete stered events.
1243 }
1244
1245 /*************************************************************************************/  
1246 void AliHBTAnalysis::FilterOut(AliHBTEvent* outpart1, AliHBTEvent* outpart2, AliHBTEvent* inpart,
1247                      AliHBTEvent* outtrack1, AliHBTEvent* outtrack2, AliHBTEvent* intrack)
1248 {
1249  //Puts particles accepted as a first particle by global cut in out1
1250  //and as a second particle in out2
1251
1252   AliHBTParticle* part, *track;
1253
1254   outpart1->Reset();
1255   outpart2->Reset();
1256   outtrack1->Reset();
1257   outtrack2->Reset();
1258   
1259   AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1260   AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1261   
1262   Bool_t in1, in2;
1263   
1264   for (Int_t i = 0; i < inpart->GetNumberOfParticles(); i++)
1265    {
1266      in1 = in2 = kTRUE;
1267      part = inpart->GetParticle(i);
1268      track = intrack->GetParticle(i);
1269      
1270      if ( (cut1->Pass(part))  ) in1 = kFALSE; //if part  is rejected by cut1, in1 is false
1271      if ( (cut2->Pass(part))  ) in2 = kFALSE; //if part  is rejected by cut2, in2 is false
1272      
1273      if (gDebug)//to be removed in real analysis     
1274      if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1275       {
1276       //Particle accpted by both cuts
1277        Error("FilterOut","Particle accepted by both cuts");
1278        continue;
1279       }
1280
1281      if (in1)
1282       {
1283         outpart1->AddParticle(part);
1284         outtrack1->AddParticle(track);
1285         continue;
1286       }
1287      
1288      if (in2)
1289       {
1290         outpart2->AddParticle(part);
1291         outtrack2->AddParticle(track);
1292         continue;
1293       }
1294    }
1295 }
1296 /*************************************************************************************/  
1297
1298 void AliHBTAnalysis::FilterOut(AliHBTEvent* out1, AliHBTEvent* out2, AliHBTEvent* in)
1299 {
1300  //Puts particles accepted as a first particle by global cut in out1
1301  //and as a second particle in out2
1302   AliHBTParticle* part;
1303   
1304   out1->Reset();
1305   out2->Reset();
1306   
1307   AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1308   AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1309   
1310   Bool_t in1, in2;
1311   
1312   for (Int_t i = 0; i < in->GetNumberOfParticles(); i++)
1313    {
1314      in1 = in2 = kTRUE;
1315      part = in->GetParticle(i);
1316      
1317      if ( cut1->Pass(part) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1318      if ( cut2->Pass(part) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
1319      
1320      if (gDebug)//to be removed in real analysis     
1321      if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1322       {
1323       //Particle accpted by both cuts
1324        Error("FilterOut","Particle accepted by both cuts");
1325        continue;
1326       }
1327
1328      if (in1)
1329       { 
1330         out1->AddParticle(part);
1331         continue;
1332       }
1333      
1334      if (in2)
1335       {
1336         out2->AddParticle(part);
1337         continue;
1338       }
1339    }
1340 }
1341 /*************************************************************************************/ 
1342
1343 Bool_t AliHBTAnalysis::IsNonIdentAnalysis()
1344 {
1345  //checks if it is possible to use special analysis for non identical particles
1346  //it means - in global pair cut first particle id is different than second one 
1347  //and both are different from 0
1348  //in the future is possible to perform more sophisticated check 
1349  //if cuts have excluding requirements
1350  
1351  if (fPairCut->IsEmpty()) 
1352    return kFALSE;
1353  
1354  if (fPairCut->GetFirstPartCut()->IsEmpty()) 
1355    return kFALSE;
1356
1357  if (fPairCut->GetSecondPartCut()->IsEmpty()) 
1358    return kFALSE;
1359  
1360  Int_t id1 = fPairCut->GetFirstPartCut()->GetPID();
1361  Int_t id2 = fPairCut->GetSecondPartCut()->GetPID();
1362
1363  if ( (id1==0) || (id2==0) || (id1==id2) ) 
1364    return kFALSE;
1365  
1366  return kTRUE;
1367 }