Lines getting the matched track moved to a method in AliCalorimeterUtils. Lines copie...
[u/mrichter/AliRoot.git] / PWG2 / FEMTOSCOPY / AliFemto / AliFemtoSimpleAnalysis.cxx
1 ///////////////////////////////////////////////////////////////////////////
2 //                                                                       //
3 // AliFemtoSimpleAnalysis - the most basic analysis there is. All other        //
4 // inherit from this one. Provides basic functionality for the analysis. //
5 // To properly set up the analysis the following steps should be taken:  //
6 //                                                                       //
7 // - create particle cuts and add them via SetFirstParticleCut and       //
8 //   SetSecondParticleCut. If one analyzes identical particle            //
9 //   correlations, the first particle cut must be also the second        //
10 //   particle cut.                                                       //
11 //                                                                       //
12 // - create pair cuts and add them via SetPairCut                        //
13 //                                                                       //
14 // - create one or many correlation functions and add them via           //
15 //   AddCorrFctn method.                                                 //
16 //                                                                       //
17 // - specify how many events are to be strored in the mixing buffer for  //
18 //   background construction                                             //
19 //                                                                       //
20 // Then, when the analysis is run, for each event, the EventBegin is     //
21 // called before any processing is done, then the ProcessEvent is called //
22 // which takes care of creating real and mixed pairs and sending them    //
23 // to all the registered correlation functions. At the end of each event,//
24 // after all pairs are processed, EventEnd is called. After the whole    //
25 // analysis finishes (there is no more events to process) Finish() is    //
26 // called.                                                               //
27 //                                                                       //
28 ///////////////////////////////////////////////////////////////////////////
29 #include "AliFemtoSimpleAnalysis.h"
30 #include "AliFemtoTrackCut.h"
31 #include "AliFemtoV0Cut.h"
32 #include "AliFemtoKinkCut.h"
33 #include <string>
34 #include <iostream>
35
36 // blah blah
37
38 #ifdef __ROOT__ 
39 ClassImp(AliFemtoSimpleAnalysis)
40 #endif
41
42 AliFemtoEventCut*    copyTheCut(AliFemtoEventCut*);
43 AliFemtoParticleCut* copyTheCut(AliFemtoParticleCut*);
44 AliFemtoPairCut*     copyTheCut(AliFemtoPairCut*);
45 AliFemtoCorrFctn*    copyTheCorrFctn(AliFemtoCorrFctn*);
46
47 // this little function used to apply ParticleCuts (TrackCuts or V0Cuts) and fill ParticleCollections of picoEvent
48 //  it is called from AliFemtoSimpleAnalysis::ProcessEvent()
49 void FillHbtParticleCollection(AliFemtoParticleCut*         partCut,
50                                AliFemtoEvent*               hbtEvent,
51                                AliFemtoParticleCollection*  partCollection)
52 {
53   // Fill particle collections from the event
54   // by the particles that pass all the cuts
55   switch (partCut->Type()) {
56   case hbtTrack:       // cut is cutting on Tracks
57     {
58       AliFemtoTrackCut* pCut = (AliFemtoTrackCut*) partCut;
59       AliFemtoTrack* pParticle;
60       AliFemtoTrackIterator pIter;
61       AliFemtoTrackIterator startLoop = hbtEvent->TrackCollection()->begin();
62       AliFemtoTrackIterator endLoop   = hbtEvent->TrackCollection()->end();
63       for (pIter=startLoop;pIter!=endLoop;pIter++){
64         pParticle = *pIter;
65         bool tmpPassParticle = pCut->Pass(pParticle);
66         pCut->FillCutMonitor(pParticle, tmpPassParticle);
67         if (tmpPassParticle){   
68           AliFemtoParticle* particle = new AliFemtoParticle(pParticle,pCut->Mass());
69           partCollection->push_back(particle);
70         }
71       }
72       break;
73     }
74   case hbtV0:          // cut is cutting on V0s
75     {
76       AliFemtoV0Cut* pCut = (AliFemtoV0Cut*) partCut;
77       AliFemtoV0* pParticle;
78       AliFemtoV0Iterator pIter;
79       AliFemtoV0Iterator startLoop = hbtEvent->V0Collection()->begin();
80       AliFemtoV0Iterator endLoop   = hbtEvent->V0Collection()->end();
81       // this following "for" loop is identical to the one above, but because of scoping, I can's see how to avoid repitition...
82       for (pIter=startLoop;pIter!=endLoop;pIter++){
83         pParticle = *pIter; 
84         bool tmpPassV0 = pCut->Pass(pParticle);
85         pCut->FillCutMonitor(pParticle,tmpPassV0);
86         if (tmpPassV0){
87           AliFemtoParticle* particle = new AliFemtoParticle(pParticle,partCut->Mass());
88           partCollection->push_back(particle);
89         }
90       }
91       pCut->FillCutMonitor(hbtEvent,partCollection);// Gael 19/06/02
92       break;
93     }
94   case hbtKink:          // cut is cutting on Kinks  -- mal 25May2001
95     {
96       AliFemtoKinkCut* pCut = (AliFemtoKinkCut*) partCut;
97       AliFemtoKink* pParticle;
98       AliFemtoKinkIterator pIter;
99       AliFemtoKinkIterator startLoop = hbtEvent->KinkCollection()->begin();
100       AliFemtoKinkIterator endLoop   = hbtEvent->KinkCollection()->end();
101       // this following "for" loop is identical to the one above, but because of scoping, I can's see how to avoid repitition...
102       for (pIter=startLoop;pIter!=endLoop;pIter++){
103         pParticle = *pIter; 
104         bool tmpPass = pCut->Pass(pParticle);
105         pCut->FillCutMonitor(pParticle,tmpPass);
106         if (tmpPass){
107           AliFemtoParticle* particle = new AliFemtoParticle(pParticle,partCut->Mass());
108           partCollection->push_back(particle);
109         }
110       }
111       break;
112     }
113   default:
114     cout << "FillHbtParticleCollection function (in AliFemtoSimpleAnalysis.cxx) - undefined Particle Cut type!!! \n";
115   }
116 }
117 //____________________________
118 AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis() :
119   fPicoEventCollectionVectorHideAway(0), 
120   fPairCut(0),            
121   fCorrFctnCollection(0), 
122   fEventCut(0),           
123   fFirstParticleCut(0),   
124   fSecondParticleCut(0),  
125   fMixingBuffer(0),       
126   fPicoEvent(0),          
127   fNumEventsToMix(0),                     
128   fNeventsProcessed(0),                   
129   fMinSizePartCollection(0)
130 {
131   // Default constructor
132   //  mControlSwitch     = 0;
133   fCorrFctnCollection = new AliFemtoCorrFctnCollection;
134   fMixingBuffer = new AliFemtoPicoEventCollection;
135 }
136 //____________________________
137
138 AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) : 
139   AliFemtoAnalysis(),
140   fPicoEventCollectionVectorHideAway(0), 
141   fPairCut(0),            
142   fCorrFctnCollection(0), 
143   fEventCut(0),           
144   fFirstParticleCut(0),   
145   fSecondParticleCut(0),  
146   fMixingBuffer(0),       
147   fPicoEvent(0),          
148   fNumEventsToMix(0),                     
149   fNeventsProcessed(0),                   
150   fMinSizePartCollection(0)
151 {
152   // Copy constructor
153   //AliFemtoSimpleAnalysis();
154   fCorrFctnCollection = new AliFemtoCorrFctnCollection;
155   fMixingBuffer = new AliFemtoPicoEventCollection;
156
157   // find the right event cut
158   fEventCut = a.fEventCut->Clone();
159   // find the right first particle cut
160   fFirstParticleCut = a.fFirstParticleCut->Clone();
161   // find the right second particle cut
162   if (a.fFirstParticleCut==a.fSecondParticleCut) 
163     SetSecondParticleCut(fFirstParticleCut); // identical particle hbt
164   else
165   fSecondParticleCut = a.fSecondParticleCut->Clone();
166
167   fPairCut = a.fPairCut->Clone();
168   
169   if ( fEventCut ) {
170       SetEventCut(fEventCut); // this will set the myAnalysis pointer inside the cut
171       cout << " AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) - event cut set " << endl;
172   }
173   if ( fFirstParticleCut ) {
174       SetFirstParticleCut(fFirstParticleCut); // this will set the myAnalysis pointer inside the cut
175       cout << " AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) - first particle cut set " << endl;
176   }
177   if ( fSecondParticleCut ) {
178       SetSecondParticleCut(fSecondParticleCut); // this will set the myAnalysis pointer inside the cut
179       cout << " AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) - second particle cut set " << endl;
180   }  if ( fPairCut ) {
181       SetPairCut(fPairCut); // this will set the myAnalysis pointer inside the cut
182       cout << " AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) - pair cut set " << endl;
183   }
184
185   AliFemtoCorrFctnIterator iter;
186   for (iter=a.fCorrFctnCollection->begin(); iter!=a.fCorrFctnCollection->end();iter++){
187     cout << " AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) - looking for correlation functions " << endl;
188     AliFemtoCorrFctn* fctn = (*iter)->Clone();
189     if (fctn) AddCorrFctn(fctn);
190     else cout << " AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) - correlation function not found " << endl;
191   }
192
193   fNumEventsToMix = a.fNumEventsToMix;
194
195   fMinSizePartCollection = a.fMinSizePartCollection;  // minimum # particles in ParticleCollection
196
197   cout << " AliFemtoSimpleAnalysis::AliFemtoSimpleAnalysis(const AliFemtoSimpleAnalysis& a) - analysis copied " << endl;
198
199 }
200 //____________________________
201 AliFemtoSimpleAnalysis::~AliFemtoSimpleAnalysis(){
202   // destructor
203   cout << " AliFemtoSimpleAnalysis::~AliFemtoSimpleAnalysis()" << endl;
204   if (fEventCut) delete fEventCut; fEventCut=0;
205   if (fFirstParticleCut == fSecondParticleCut) fSecondParticleCut=0;
206   if (fFirstParticleCut)  delete fFirstParticleCut; fFirstParticleCut=0;
207   if (fSecondParticleCut) delete fSecondParticleCut; fSecondParticleCut=0;
208   if (fPairCut) delete fPairCut; fPairCut=0;
209   // now delete every CorrFunction in the Collection, and then the Collection itself
210   AliFemtoCorrFctnIterator iter;
211   for (iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
212     delete *iter;
213   }
214   delete fCorrFctnCollection;
215   // now delete every PicoEvent in the EventMixingBuffer and then the Buffer itself
216   if (fMixingBuffer) {
217     AliFemtoPicoEventIterator piter;
218     for (piter=fMixingBuffer->begin();piter!=fMixingBuffer->end();piter++){
219       delete *piter;
220     }
221     delete fMixingBuffer;
222   }
223 }
224 //______________________
225 AliFemtoSimpleAnalysis& AliFemtoSimpleAnalysis::operator=(const AliFemtoSimpleAnalysis& aAna) 
226 {
227   // Assignment operator
228   if (this == &aAna)
229     return *this;
230
231   if (fCorrFctnCollection) delete fCorrFctnCollection;
232   fCorrFctnCollection = new AliFemtoCorrFctnCollection;
233   if (fMixingBuffer) delete fMixingBuffer;
234   fMixingBuffer = new AliFemtoPicoEventCollection;
235
236   // find the right event cut
237   if (fEventCut) delete fEventCut;
238   fEventCut = aAna.fEventCut->Clone();
239   // find the right first particle cut
240   if (fFirstParticleCut) delete fFirstParticleCut;
241   fFirstParticleCut = aAna.fFirstParticleCut->Clone();
242   // find the right second particle cut
243   if (fSecondParticleCut) delete fSecondParticleCut;
244   if (aAna.fFirstParticleCut==aAna.fSecondParticleCut) 
245     SetSecondParticleCut(fFirstParticleCut); // identical particle hbt
246   else
247     fSecondParticleCut = aAna.fSecondParticleCut->Clone();
248
249   if (fPairCut) delete fPairCut;
250   fPairCut = aAna.fPairCut->Clone();
251   
252   if ( fEventCut ) {
253     SetEventCut(fEventCut); // this will set the myAnalysis pointer inside the cut
254   }
255   if ( fFirstParticleCut ) {
256     SetFirstParticleCut(fFirstParticleCut); // this will set the myAnalysis pointer inside the cut
257   }
258   if ( fSecondParticleCut ) {
259     SetSecondParticleCut(fSecondParticleCut); // this will set the myAnalysis pointer inside the cut
260   }  
261   if ( fPairCut ) {
262     SetPairCut(fPairCut); // this will set the myAnalysis pointer inside the cut
263   }
264
265   AliFemtoCorrFctnIterator iter;
266   for (iter=aAna.fCorrFctnCollection->begin(); iter!=aAna.fCorrFctnCollection->end();iter++){
267     AliFemtoCorrFctn* fctn = (*iter)->Clone();
268     if (fctn) AddCorrFctn(fctn);
269   }
270
271   fNumEventsToMix = aAna.fNumEventsToMix;
272
273   fMinSizePartCollection = aAna.fMinSizePartCollection;  // minimum # particles in ParticleCollection
274
275   return *this;
276 }
277 //______________________
278 AliFemtoCorrFctn* AliFemtoSimpleAnalysis::CorrFctn(int n){  
279   // return pointer to n-th correlation function
280   if ( n<0 || n > (int)fCorrFctnCollection->size() )
281     return NULL;
282   AliFemtoCorrFctnIterator iter=fCorrFctnCollection->begin();
283   for (int i=0; i<n ;i++){
284     iter++;
285   }
286   return *iter;
287 }
288 //____________________________
289 AliFemtoString AliFemtoSimpleAnalysis::Report()
290 {
291   // Create a simple report from the analysis execution
292   cout << "AliFemtoSimpleAnalysis - constructing Report..."<<endl;
293   string temp = "-----------\nHbt Analysis Report:\n";
294   temp += "\nEvent Cuts:\n";
295   temp += fEventCut->Report();
296   temp += "\nParticle Cuts - First Particle:\n";
297   temp += fFirstParticleCut->Report();
298   temp += "\nParticle Cuts - Second Particle:\n";
299   temp += fSecondParticleCut->Report();
300   temp += "\nPair Cuts:\n";
301   temp += fPairCut->Report();
302   temp += "\nCorrelation Functions:\n";
303   AliFemtoCorrFctnIterator iter;
304   if ( fCorrFctnCollection->size()==0 ) {
305     cout << "AliFemtoSimpleAnalysis-Warning : no correlations functions in this analysis " << endl;
306   }
307   for (iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
308     temp += (*iter)->Report();
309     temp += "\n";
310   }
311   temp += "-------------\n";
312   AliFemtoString returnThis=temp;
313   return returnThis;
314 }
315 //_________________________
316 void AliFemtoSimpleAnalysis::ProcessEvent(const AliFemtoEvent* hbtEvent) {
317   // Add event to processed events
318   fPicoEvent=0; // we will get a new pico event, if not prevent corr. fctn to access old pico event
319   AddEventProcessed();
320   // startup for EbyE 
321   EventBegin(hbtEvent);  
322   // event cut and event cut monitor
323   bool tmpPassEvent = fEventCut->Pass(hbtEvent);
324   if (!tmpPassEvent) 
325     fEventCut->FillCutMonitor(hbtEvent, tmpPassEvent);
326   if (tmpPassEvent) {
327 //     cout << "AliFemtoSimpleAnalysis::ProcessEvent() - Event has passed cut - build picoEvent from " <<
328 //       hbtEvent->TrackCollection()->size() << " tracks in TrackCollection" << endl;
329 //    cout << "Event has passed cut with " << hbtEvent->TrackCollection()->size() << " tracks" << endl;
330     // OK, analysis likes the event-- build a pico event from it, using tracks the analysis likes...
331     fPicoEvent = new AliFemtoPicoEvent; // this is what we will make pairs from and put in Mixing Buffer
332     // no memory leak. we will delete picoevents when they come out of the mixing buffer
333     FillHbtParticleCollection(fFirstParticleCut,(AliFemtoEvent*)hbtEvent,fPicoEvent->FirstParticleCollection());
334     if ( !(AnalyzeIdenticalParticles()) )
335       FillHbtParticleCollection(fSecondParticleCut,(AliFemtoEvent*)hbtEvent,fPicoEvent->SecondParticleCollection());
336 //     cout <<"AliFemtoSimpleAnalysis::ProcessEvent - #particles in First, Second Collections: " <<
337 //       fPicoEvent->FirstParticleCollection()->size() << " " <<
338 //       fPicoEvent->SecondParticleCollection()->size() << endl;
339     
340     cout << "#particles in Collection 1, 2: " <<
341       fPicoEvent->FirstParticleCollection()->size() << " " <<
342       fPicoEvent->SecondParticleCollection()->size() << endl;
343     
344     // mal - implement a switch which allows only using events with ParticleCollections containing a minimum
345     // number of entries (jun2002)
346     if ((fPicoEvent->FirstParticleCollection()->size() >= fMinSizePartCollection )
347         && ( AnalyzeIdenticalParticles() || (fPicoEvent->SecondParticleCollection()->size() >= fMinSizePartCollection ))) {
348       fEventCut->FillCutMonitor(hbtEvent, tmpPassEvent);
349       
350
351 //------------------------------------------------------------------------------
352 //   Temporary comment:
353 //      This whole section rewritten so that all pairs are built using the
354 //      same code... easier to read and manage, and MakePairs() can be called by
355 //      derived classes.  Also, the requirement of a full mixing buffer before
356 //      mixing is removed.
357 //                          Dan Magestro, 11/2002
358
359       //------ Make real pairs. If identical, make pairs for one collection ------//
360
361       if (AnalyzeIdenticalParticles()) {
362         MakePairs("real", fPicoEvent->FirstParticleCollection() );
363       }
364       else {
365         MakePairs("real", fPicoEvent->FirstParticleCollection(),
366                           fPicoEvent->SecondParticleCollection() );
367       }
368       cout << "AliFemtoSimpleAnalysis::ProcessEvent() - reals done ";
369
370       //---- Make pairs for mixed events, looping over events in mixingBuffer ----//
371
372       AliFemtoPicoEvent* storedEvent;
373       AliFemtoPicoEventIterator fPicoEventIter;
374       for (fPicoEventIter=MixingBuffer()->begin();fPicoEventIter!=MixingBuffer()->end();fPicoEventIter++){
375         storedEvent = *fPicoEventIter;
376         if (AnalyzeIdenticalParticles()) {
377           MakePairs("mixed",fPicoEvent->FirstParticleCollection(),
378                             storedEvent->FirstParticleCollection() );
379         }
380         else {
381           MakePairs("mixed",fPicoEvent->FirstParticleCollection(),
382                             storedEvent->SecondParticleCollection() );
383
384           MakePairs("mixed",storedEvent->FirstParticleCollection(),
385                             fPicoEvent->SecondParticleCollection() );
386         }
387       }
388       cout << " - mixed done   " << endl;
389
390       //--------- If mixing buffer is full, delete oldest event ---------//
391
392       if ( MixingBufferFull() ) {
393         delete MixingBuffer()->back();
394         MixingBuffer()->pop_back();
395       }
396
397       //-------- Add current event (fPicoEvent) to mixing buffer --------//
398
399       MixingBuffer()->push_front(fPicoEvent);
400
401
402 // Temporary comment: End of rewritten section... Dan Magestro, 11/2002
403 //------------------------------------------------------------------------------
404
405
406     }  // if ParticleCollections are big enough (mal jun2002)
407     else{
408       fEventCut->FillCutMonitor(hbtEvent, !tmpPassEvent);
409       delete fPicoEvent;
410     }
411   }   // if currentEvent is accepted by currentAnalysis
412   EventEnd(hbtEvent);  // cleanup for EbyE 
413   //cout << "AliFemtoSimpleAnalysis::ProcessEvent() - return to caller ... " << endl;
414 }
415 //_________________________
416 void AliFemtoSimpleAnalysis::MakePairs(const char* typeIn, AliFemtoParticleCollection *partCollection1,
417                                        AliFemtoParticleCollection *partCollection2){
418 // Build pairs, check pair cuts, and call CFs' AddRealPair() or
419 // AddMixedPair() methods. If no second particle collection is
420 // specfied, make pairs within first particle collection.
421
422   string type = typeIn;
423
424   //  int swpart = ((long int) partCollection1) % 2;
425   int swpart = fNeventsProcessed % 2;
426
427   AliFemtoPair* tPair = new AliFemtoPair;
428
429   AliFemtoCorrFctnIterator tCorrFctnIter;
430
431   AliFemtoParticleIterator tPartIter1, tPartIter2;
432
433   AliFemtoParticleIterator tStartOuterLoop = partCollection1->begin();  // always
434   AliFemtoParticleIterator tEndOuterLoop   = partCollection1->end();    // will be one less if identical
435   AliFemtoParticleIterator tStartInnerLoop;
436   AliFemtoParticleIterator tEndInnerLoop;
437   if (partCollection2) {                        // Two collections:
438     tStartInnerLoop = partCollection2->begin();  //   Full inner & outer loops
439     tEndInnerLoop   = partCollection2->end();    //
440   }
441   else {                                        // One collection:
442     tEndOuterLoop--;                             //   Outer loop goes to next-to-last particle
443     tEndInnerLoop = partCollection1->end() ;     //   Inner loop goes to last particle
444   }
445   for (tPartIter1=tStartOuterLoop;tPartIter1!=tEndOuterLoop;tPartIter1++) {
446     if (!partCollection2){
447       tStartInnerLoop = tPartIter1;
448       tStartInnerLoop++;
449     }
450     tPair->SetTrack1(*tPartIter1);
451     for (tPartIter2 = tStartInnerLoop; tPartIter2!=tEndInnerLoop;tPartIter2++) {
452       tPair->SetTrack2(*tPartIter2);
453
454       // The following lines have to be uncommented if you want pairCutMonitors
455       // they are not in for speed reasons
456       // bool tmpPassPair = fPairCut->Pass(tPair);
457       // fPairCut->FillCutMonitor(tPair, tmpPassPair);
458       // if ( tmpPassPair )
459
460       //---- If pair passes cut, loop over CF's and add pair to real/mixed ----//
461
462       if (!partCollection2) {
463         if (swpart) {
464           tPair->SetTrack1(*tPartIter2);
465           tPair->SetTrack2(*tPartIter1);
466           swpart = 0;
467         }
468         else {
469           tPair->SetTrack1(*tPartIter1);
470           tPair->SetTrack2(*tPartIter2);
471           swpart = 1;
472         }
473       }
474
475       if (fPairCut->Pass(tPair)){
476         for (tCorrFctnIter=fCorrFctnCollection->begin();
477              tCorrFctnIter!=fCorrFctnCollection->end();tCorrFctnIter++){
478           AliFemtoCorrFctn* tCorrFctn = *tCorrFctnIter;
479           if(type == "real")
480             tCorrFctn->AddRealPair(tPair);
481           else if(type == "mixed")
482             tCorrFctn->AddMixedPair(tPair);
483           else
484             cout << "Problem with pair type, type = " << type.c_str() << endl;
485         }
486       }
487
488     }    // loop over second particle
489
490   }      // loop over first particle
491
492   delete tPair;
493
494 }
495 //_________________________
496 void AliFemtoSimpleAnalysis::EventBegin(const AliFemtoEvent* ev){
497   // Perform initialization operations at the beginning of the event processing
498   //cout << " AliFemtoSimpleAnalysis::EventBegin(const AliFemtoEvent* ev) " << endl;
499   fFirstParticleCut->EventBegin(ev);
500   fSecondParticleCut->EventBegin(ev);
501   fPairCut->EventBegin(ev);
502   for (AliFemtoCorrFctnIterator iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
503     (*iter)->EventBegin(ev);
504   }
505 }
506 //_________________________
507 void AliFemtoSimpleAnalysis::EventEnd(const AliFemtoEvent* ev){
508   // Fiinsh operations at the end of event processing
509   fFirstParticleCut->EventEnd(ev);
510   fSecondParticleCut->EventEnd(ev);
511   fPairCut->EventEnd(ev);
512   for (AliFemtoCorrFctnIterator iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
513     (*iter)->EventEnd(ev);
514   }
515 }
516 //_________________________
517 void AliFemtoSimpleAnalysis::Finish(){
518   // Perform finishing operations after all events are processed
519   AliFemtoCorrFctnIterator iter;
520   for (iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
521     (*iter)->Finish();
522   }
523 }
524 //_________________________
525 void AliFemtoSimpleAnalysis::AddEventProcessed() {
526   // Increase count of processed events
527   fNeventsProcessed++;
528 }
529 //_________________________
530 TList* AliFemtoSimpleAnalysis::ListSettings()
531 {
532   // Collect settings list
533   TList *tListSettings = new TList();
534
535   TList *p1Cut = fFirstParticleCut->ListSettings();
536
537   TListIter nextp1(p1Cut);
538   while (TObject *obj = nextp1.Next()) {
539     TString cuts(obj->GetName());
540     cuts.Prepend("AliFemtoSimpleAnalysis.");
541     tListSettings->Add(new TObjString(cuts.Data()));
542   }
543
544   if (fSecondParticleCut != fFirstParticleCut) {
545     TList *p2Cut = fSecondParticleCut->ListSettings();
546     
547     TIter nextp2(p2Cut);
548     while (TObject *obj = nextp2()) {
549       TString cuts(obj->GetName());
550       cuts.Prepend("AliFemtoSimpleAnalysis.");
551       tListSettings->Add(new TObjString(cuts.Data()));
552     }
553   }
554
555   TList *pairCut = fPairCut->ListSettings();
556
557   TIter nextpair(pairCut);
558   while (TObject *obj = nextpair()) {
559     TString cuts(obj->GetName());
560     cuts.Prepend("AliFemtoSimpleAnalysis.");
561     tListSettings->Add(new TObjString(cuts.Data()));
562   }
563
564   return tListSettings;
565   
566 }
567
568 //_________________________
569 TList* AliFemtoSimpleAnalysis::GetOutputList()
570 {
571   // Collect the list of output objects
572   // to be written 
573   TList *tOutputList = new TList();
574
575   TList *p1Cut = fFirstParticleCut->GetOutputList();
576
577   TListIter nextp1(p1Cut);
578   while (TObject *obj = nextp1.Next()) {
579     tOutputList->Add(obj);
580   }
581
582   if (fSecondParticleCut != fFirstParticleCut) {
583     TList *p2Cut = fSecondParticleCut->GetOutputList();
584     
585     TIter nextp2(p2Cut);
586     while (TObject *obj = nextp2()) {
587       tOutputList->Add(obj);
588     }
589   }
590
591   TList *pairCut = fPairCut->GetOutputList();
592
593   TIter nextpair(pairCut);
594   while (TObject *obj = nextpair()) {
595     tOutputList->Add(obj);
596   }
597
598   TList *eventCut = fEventCut->GetOutputList();
599
600   TIter nextevent(eventCut);
601   while (TObject *obj = nextevent()) {
602     tOutputList->Add(obj);
603   }
604
605   AliFemtoCorrFctnIterator iter;
606   for (iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
607     TList *tListCf = (*iter)->GetOutputList();
608     
609     TIter nextListCf(tListCf);
610     while (TObject *obj = nextListCf()) {
611       tOutputList->Add(obj);
612     }
613   }
614
615   return tOutputList;
616   
617 }