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