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