Unnacessary printout removed
[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      pbuffer.AddFirst(partEvent2);
973      tbuffer.AddFirst(trackEvent2);
974      partEvent2 = 0x0;
975      trackEvent2 = 0x0;
976      ninbuffer++;
977
978   }//end of loop over events (1)
979  pbuffer.SetOwner();  //to clean stored events by the way of buffer destruction
980  tbuffer.SetOwner();  
981  delete partEvent1;
982  delete trackEvent1;
983  delete partpair;
984  delete trackpair;
985  if ( fBufferSize == 0)
986   {//in that case we did not add these events to list
987     delete partEvent2;
988     delete trackEvent2;
989   }
990
991 }
992 /*************************************************************************************/  
993  
994 void AliHBTAnalysis::ProcessTracksNonIdentAnal()
995 {
996   AliHBTParticle * track1, * track2;
997
998   AliHBTEvent * trackEvent1=0x0;
999   AliHBTEvent * trackEvent2=0x0;
1000   AliHBTEvent * trackEvent3=0x0;
1001
1002   AliHBTEvent * rawtrackEvent;
1003   
1004   Int_t Nev = fReader->GetNumberOfTrackEvents();
1005
1006   AliHBTPair * trackpair = new AliHBTPair();
1007
1008   TList tbuffer;
1009   Int_t ninbuffer = 0;
1010   register UInt_t ii;
1011
1012   trackEvent1 = new AliHBTEvent();
1013   trackEvent1->SetOwner(kFALSE);
1014   
1015   Info("ProcessTracksNonIdentAnal","**************************************");
1016   Info("ProcessTracksNonIdentAnal","*****  NON IDENT MODE ****************");
1017   Info("ProcessTracksNonIdentAnal","**************************************");
1018   
1019   for (Int_t i = 0;i<Nev;i++)
1020     {
1021       rawtrackEvent = fReader->GetTrackEvent(i);
1022       if (rawtrackEvent == 0x0)  continue;//in case of any error
1023
1024       /********************************/
1025       /*      Filtering out           */
1026       /********************************/
1027       if ( (fBufferSize != 0) || ( trackEvent2==0x0) )//in case fBufferSize == 0 and pointers are created do not eneter
1028        if ((ninbuffer > fBufferSize) && (fBufferSize > 0))
1029         {//if we have in buffer desired number of events, use the last. If fBufferSize<0 mix all events for background
1030          trackEvent2 = (AliHBTEvent*)tbuffer.Remove(tbuffer.Last());
1031          ninbuffer--;
1032         }
1033        else
1034         {
1035          trackEvent2 = new AliHBTEvent();
1036          trackEvent2->SetOwner(kFALSE);
1037         }
1038       FilterOut(trackEvent1, trackEvent2, rawtrackEvent);
1039       
1040       for (Int_t j = 0; j<trackEvent1->GetNumberOfParticles() ; j++)
1041        {
1042          if ( (j%fDisplayMixingInfo) == 0) 
1043            Info("ProcessTracksNonIdentAnal",
1044                 "Mixing particle %d from event %d with particles from event %d",j,i,i);
1045
1046          track1= trackEvent1->GetParticle(j);
1047
1048          for(ii = 0; ii<fNTrackMonitorFunctions; ii++)
1049            fTrackMonitorFunctions[ii]->ProcessSameEventParticles(track1);
1050
1051          /***************************************/
1052          /******   filling numerators    ********/
1053          /****** (particles from event2) ********/
1054          /***************************************/
1055          for (Int_t k = 0; k < trackEvent2->GetNumberOfParticles() ; k++)
1056           {
1057             track2= trackEvent2->GetParticle(k);
1058             trackpair->SetParticles(track1,track2);
1059
1060
1061             if( fPairCut->PassPairProp(trackpair)) //check pair cut
1062               { //do not meets crietria of the pair cut
1063                   continue; 
1064               }
1065             else
1066              {//meets criteria of the pair cut
1067               UInt_t ii;
1068               for(ii = 0;ii<fNTrackFunctions;ii++)
1069                      fTrackFunctions[ii]->ProcessSameEventParticles(trackpair);
1070              }
1071            }
1072      if ( fBufferSize == 0) continue;//do not mix diff histograms
1073      /***************************************/
1074      /***** Filling denominators    *********/
1075      /***************************************/
1076      TIter titer(&tbuffer);
1077      Int_t nmonitor = 0;
1078      
1079      while ( (trackEvent3 = (AliHBTEvent*)titer.Next()) != 0x0)
1080       {
1081         
1082         if ( (j%fDisplayMixingInfo) == 0) 
1083             Info("ProcessTracksNonIdentAnal",
1084                  "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1085         
1086         for (Int_t k = 0; k < trackEvent3->GetNumberOfParticles() ; k++)
1087           {
1088
1089             track2= trackEvent3->GetParticle(k);
1090             trackpair->SetParticles(track1,track2);
1091
1092
1093             if( fPairCut->PassPairProp(trackpair)) //check pair cut
1094              { //do not meets crietria of the pair cut
1095                continue; 
1096              }
1097             else
1098              {//meets criteria of the pair cut
1099                for(ii = 0;ii<fNTrackFunctions;ii++)
1100                    fTrackFunctions[ii]->ProcessDiffEventParticles(trackpair);
1101              }
1102            }// for particles event2
1103          }//while event2
1104        }//for over particles in event1
1105      
1106      if ( fBufferSize == 0) continue;//do not mix diff histograms     
1107      tbuffer.AddFirst(trackEvent2);
1108      trackEvent2 = 0x0;
1109      ninbuffer++;
1110
1111   }//end of loop over events (1)
1112
1113  delete trackpair;
1114  delete trackEvent1;
1115  if (fBufferSize == 0) delete trackEvent2;
1116  tbuffer.SetOwner();  
1117 }
1118 /*************************************************************************************/  
1119
1120 void AliHBTAnalysis::ProcessParticlesNonIdentAnal()
1121 {
1122   AliHBTParticle * part1 = 0x0, * part2 = 0x0;
1123
1124   AliHBTEvent * partEvent1 = 0x0;
1125   AliHBTEvent * partEvent2 = 0x0;
1126   AliHBTEvent * partEvent3 = 0x0;
1127
1128   AliHBTEvent * rawpartEvent = 0x0;
1129
1130   Int_t Nev = fReader->GetNumberOfPartEvents();
1131
1132   AliHBTPair * partpair = new AliHBTPair();
1133
1134   TList pbuffer;
1135   Int_t ninbuffer = 0;
1136
1137   partEvent1 = new AliHBTEvent();
1138   partEvent1->SetOwner(kFALSE);;
1139   
1140   Info("ProcessParticlesNonIdentAnal","**************************************");
1141   Info("ProcessParticlesNonIdentAnal","*****  NON IDENT MODE ****************");
1142   Info("ProcessParticlesNonIdentAnal","**************************************");
1143
1144   for (Int_t i = 0;i<Nev;i++)
1145     {
1146       rawpartEvent  = fReader->GetParticleEvent(i);
1147       if ( rawpartEvent == 0x0  ) continue;//in case of any error
1148
1149       /********************************/
1150       /*      Filtering out           */
1151       /********************************/
1152       if ( (fBufferSize != 0) || ( partEvent2==0x0) )//in case fBufferSize == 0 and pointers are created do not eneter
1153        if ((ninbuffer > fBufferSize) && (fBufferSize > 0))
1154         {//if we have in buffer desired number of events, use the last. If fBufferSize<0 mix all events for background
1155          partEvent2  = (AliHBTEvent*)pbuffer.Remove(pbuffer.Last()); //remove from the end to be reset, filled and put on the beginning
1156          ninbuffer--; 
1157         }
1158        else
1159         {
1160          partEvent2  = new AliHBTEvent();
1161          partEvent2->SetOwner(kFALSE);
1162         }
1163       FilterOut(partEvent1, partEvent2, rawpartEvent);
1164       
1165       for (Int_t j = 0; j<partEvent1->GetNumberOfParticles() ; j++)
1166        {
1167          if ( (j%fDisplayMixingInfo) == 0) 
1168             Info("ProcessParticlesNonIdentAnal",
1169                  "Mixing particle %d from event %d with particles from event %d",j,i,i);
1170
1171          part1= partEvent1->GetParticle(j);
1172
1173          UInt_t zz;
1174          for(zz = 0; zz<fNParticleMonitorFunctions; zz++)
1175            fParticleMonitorFunctions[zz]->ProcessSameEventParticles(part1);
1176
1177          /***************************************/
1178          /******   filling numerators    ********/
1179          /****** (particles from event2) ********/
1180          /***************************************/
1181          for (Int_t k = 0; k < partEvent2->GetNumberOfParticles() ; k++)
1182           {
1183             part2= partEvent2->GetParticle(k);
1184             partpair->SetParticles(part1,part2);
1185
1186             if(fPairCut->PassPairProp(partpair) ) //check pair cut
1187               { //do not meets crietria of the pair cut
1188                   continue; 
1189               }
1190             else
1191              {//meets criteria of the pair cut
1192               UInt_t ii;
1193               for(ii = 0;ii<fNParticleFunctions;ii++)
1194                 {
1195                   fParticleFunctions[ii]->ProcessSameEventParticles(partpair);
1196                 }
1197              }
1198            }
1199      if ( fBufferSize == 0) continue;//do not mix diff histograms
1200      /***************************************/
1201      /***** Filling denominators    *********/
1202      /***************************************/
1203      TIter piter(&pbuffer);
1204      Int_t nmonitor = 0;
1205
1206      while ( (partEvent3 = (AliHBTEvent*)piter.Next()) != 0x0)
1207       {
1208         if ( (j%fDisplayMixingInfo) == 0) 
1209             Info("ProcessParticlesNonIdentAnal",
1210                  "Mixing particle %d from event %d with particles from event %d",j,i,i-(++nmonitor));
1211
1212         for (Int_t k = 0; k < partEvent3->GetNumberOfParticles() ; k++)
1213           {
1214             part2= partEvent3->GetParticle(k);
1215             partpair->SetParticles(part1,part2);
1216
1217             if(fPairCut->PassPairProp(partpair) ) //check pair cut
1218               { //do not meets crietria of the pair cut
1219                   continue; 
1220               }
1221             else
1222              {//meets criteria of the pair cut
1223               UInt_t ii;
1224               for(ii = 0;ii<fNParticleFunctions;ii++)
1225                {
1226                  fParticleFunctions[ii]->ProcessDiffEventParticles(partpair);
1227                }
1228              }
1229            }// for particles event2
1230          }//while event2
1231        }//for over particles in event1
1232      if ( fBufferSize == 0) continue;//do not mix diff histograms
1233      pbuffer.AddFirst(partEvent2);
1234      partEvent2 = 0x0; 
1235      ninbuffer++;
1236
1237   }//end of loop over events (1)
1238  delete partpair;
1239  delete partEvent1;
1240  if ( fBufferSize == 0) delete partEvent2;
1241  pbuffer.SetOwner();//to delete stered events.
1242 }
1243
1244 /*************************************************************************************/  
1245 void AliHBTAnalysis::FilterOut(AliHBTEvent* outpart1, AliHBTEvent* outpart2, AliHBTEvent* inpart,
1246                      AliHBTEvent* outtrack1, AliHBTEvent* outtrack2, AliHBTEvent* intrack)
1247 {
1248  //Puts particles accepted as a first particle by global cut in out1
1249  //and as a second particle in out2
1250
1251   AliHBTParticle* part, *track;
1252
1253   outpart1->Reset();
1254   outpart2->Reset();
1255   outtrack1->Reset();
1256   outtrack2->Reset();
1257   
1258   AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1259   AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1260   
1261   Bool_t in1, in2;
1262   
1263   for (Int_t i = 0; i < inpart->GetNumberOfParticles(); i++)
1264    {
1265      in1 = in2 = kTRUE;
1266      part = inpart->GetParticle(i);
1267      track = intrack->GetParticle(i);
1268      
1269      if ( (cut1->Pass(part))  ) in1 = kFALSE; //if part  is rejected by cut1, in1 is false
1270      if ( (cut2->Pass(part))  ) in2 = kFALSE; //if part  is rejected by cut2, in2 is false
1271      
1272      if (gDebug)//to be removed in real analysis     
1273      if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1274       {
1275       //Particle accpted by both cuts
1276        Error("FilterOut","Particle accepted by both cuts");
1277        continue;
1278       }
1279
1280      if (in1)
1281       {
1282         outpart1->AddParticle(part);
1283         outtrack1->AddParticle(track);
1284         continue;
1285       }
1286      
1287      if (in2)
1288       {
1289         outpart2->AddParticle(part);
1290         outtrack2->AddParticle(track);
1291         continue;
1292       }
1293    }
1294 }
1295 /*************************************************************************************/  
1296
1297 void AliHBTAnalysis::FilterOut(AliHBTEvent* out1, AliHBTEvent* out2, AliHBTEvent* in)
1298 {
1299  //Puts particles accepted as a first particle by global cut in out1
1300  //and as a second particle in out2
1301   AliHBTParticle* part;
1302   
1303   out1->Reset();
1304   out2->Reset();
1305   
1306   AliHBTParticleCut *cut1 = fPairCut->GetFirstPartCut();
1307   AliHBTParticleCut *cut2 = fPairCut->GetSecondPartCut();
1308   
1309   Bool_t in1, in2;
1310   
1311   for (Int_t i = 0; i < in->GetNumberOfParticles(); i++)
1312    {
1313      in1 = in2 = kTRUE;
1314      part = in->GetParticle(i);
1315      
1316      if ( cut1->Pass(part) ) in1 = kFALSE; //if part is rejected by cut1, in1 is false
1317      if ( cut2->Pass(part) ) in2 = kFALSE; //if part is rejected by cut2, in2 is false
1318      
1319      if (gDebug)//to be removed in real analysis     
1320      if ( in1 && in2 ) //both cuts accepted, should never happen, just in case
1321       {
1322       //Particle accpted by both cuts
1323        Error("FilterOut","Particle accepted by both cuts");
1324        continue;
1325       }
1326
1327      if (in1)
1328       { 
1329         out1->AddParticle(part);
1330         continue;
1331       }
1332      
1333      if (in2)
1334       {
1335         out2->AddParticle(part);
1336         continue;
1337       }
1338    }
1339 }
1340 /*************************************************************************************/ 
1341
1342 Bool_t AliHBTAnalysis::IsNonIdentAnalysis()
1343 {
1344  //checks if it is possible to use special analysis for non identical particles
1345  //it means - in global pair cut first particle id is different than second one 
1346  //and both are different from 0
1347  //in the future is possible to perform more sophisticated check 
1348  //if cuts have excluding requirements
1349  
1350  if (fPairCut->IsEmpty()) 
1351    return kFALSE;
1352  
1353  if (fPairCut->GetFirstPartCut()->IsEmpty()) 
1354    return kFALSE;
1355
1356  if (fPairCut->GetSecondPartCut()->IsEmpty()) 
1357    return kFALSE;
1358  
1359  Int_t id1 = fPairCut->GetFirstPartCut()->GetPID();
1360  Int_t id2 = fPairCut->GetSecondPartCut()->GetPID();
1361
1362  if ( (id1==0) || (id2==0) || (id1==id2) ) 
1363    return kFALSE;
1364  
1365  return kTRUE;
1366 }