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