1 ///////////////////////////////////////////////////////////////////////////
3 // AliFemtoAnalysis - 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: //
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 //
12 // - create pair cuts and add them via SetPairCut //
14 // - create one or many correlation functions and add them via //
15 // AddCorrFctn method. //
17 // - specify how many events are to be strored in the mixing buffer for //
18 // background construction //
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 //
28 ///////////////////////////////////////////////////////////////////////////
29 #include "AliFemtoAnalysis.h"
30 #include "AliFemtoTrackCut.h"
31 #include "AliFemtoV0Cut.h"
32 #include "AliFemtoKinkCut.h"
37 ClassImp(AliFemtoAnalysis)
40 AliFemtoEventCut* copyTheCut(AliFemtoEventCut*);
41 AliFemtoParticleCut* copyTheCut(AliFemtoParticleCut*);
42 AliFemtoPairCut* copyTheCut(AliFemtoPairCut*);
43 AliFemtoCorrFctn* copyTheCorrFctn(AliFemtoCorrFctn*);
45 // this little function used to apply ParticleCuts (TrackCuts or V0Cuts) and fill ParticleCollections of picoEvent
46 // it is called from AliFemtoAnalysis::ProcessEvent()
47 void FillHbtParticleCollection(AliFemtoParticleCut* partCut,
48 AliFemtoEvent* hbtEvent,
49 AliFemtoParticleCollection* partCollection)
51 // Fill particle collections from the event
52 // by the particles that pass all the cuts
53 switch (partCut->Type()) {
54 case hbtTrack: // cut is cutting on Tracks
56 AliFemtoTrackCut* pCut = (AliFemtoTrackCut*) partCut;
57 AliFemtoTrack* pParticle;
58 AliFemtoTrackIterator pIter;
59 AliFemtoTrackIterator startLoop = hbtEvent->TrackCollection()->begin();
60 AliFemtoTrackIterator endLoop = hbtEvent->TrackCollection()->end();
61 for (pIter=startLoop;pIter!=endLoop;pIter++){
63 bool tmpPassParticle = pCut->Pass(pParticle);
64 pCut->FillCutMonitor(pParticle, tmpPassParticle);
66 AliFemtoParticle* particle = new AliFemtoParticle(pParticle,pCut->Mass());
67 partCollection->push_back(particle);
72 case hbtV0: // cut is cutting on V0s
74 AliFemtoV0Cut* pCut = (AliFemtoV0Cut*) partCut;
75 AliFemtoV0* pParticle;
76 AliFemtoV0Iterator pIter;
77 AliFemtoV0Iterator startLoop = hbtEvent->V0Collection()->begin();
78 AliFemtoV0Iterator endLoop = hbtEvent->V0Collection()->end();
79 // this following "for" loop is identical to the one above, but because of scoping, I can's see how to avoid repitition...
80 for (pIter=startLoop;pIter!=endLoop;pIter++){
82 bool tmpPassV0 = pCut->Pass(pParticle);
83 pCut->FillCutMonitor(pParticle,tmpPassV0);
85 AliFemtoParticle* particle = new AliFemtoParticle(pParticle,partCut->Mass());
86 partCollection->push_back(particle);
89 pCut->FillCutMonitor(hbtEvent,partCollection);// Gael 19/06/02
92 case hbtKink: // cut is cutting on Kinks -- mal 25May2001
94 AliFemtoKinkCut* pCut = (AliFemtoKinkCut*) partCut;
95 AliFemtoKink* pParticle;
96 AliFemtoKinkIterator pIter;
97 AliFemtoKinkIterator startLoop = hbtEvent->KinkCollection()->begin();
98 AliFemtoKinkIterator endLoop = hbtEvent->KinkCollection()->end();
99 // this following "for" loop is identical to the one above, but because of scoping, I can's see how to avoid repitition...
100 for (pIter=startLoop;pIter!=endLoop;pIter++){
102 bool tmpPass = pCut->Pass(pParticle);
103 pCut->FillCutMonitor(pParticle,tmpPass);
105 AliFemtoParticle* particle = new AliFemtoParticle(pParticle,partCut->Mass());
106 partCollection->push_back(particle);
112 cout << "FillHbtParticleCollection function (in AliFemtoAnalysis.cxx) - undefined Particle Cut type!!! \n";
115 //____________________________
116 AliFemtoAnalysis::AliFemtoAnalysis() :
117 fPicoEventCollectionVectorHideAway(0),
119 fCorrFctnCollection(0),
121 fFirstParticleCut(0),
122 fSecondParticleCut(0),
126 fNeventsProcessed(0),
127 fMinSizePartCollection(0)
129 // Default constructor
130 // mControlSwitch = 0;
131 fCorrFctnCollection = new AliFemtoCorrFctnCollection;
132 fMixingBuffer = new AliFemtoPicoEventCollection;
134 //____________________________
136 AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) :
137 AliFemtoBaseAnalysis(),
138 fPicoEventCollectionVectorHideAway(0),
140 fCorrFctnCollection(0),
142 fFirstParticleCut(0),
143 fSecondParticleCut(0),
147 fNeventsProcessed(0),
148 fMinSizePartCollection(0)
151 //AliFemtoAnalysis();
152 fCorrFctnCollection = new AliFemtoCorrFctnCollection;
153 fMixingBuffer = new AliFemtoPicoEventCollection;
155 // find the right event cut
156 fEventCut = a.fEventCut->Clone();
157 // find the right first particle cut
158 fFirstParticleCut = a.fFirstParticleCut->Clone();
159 // find the right second particle cut
160 if (a.fFirstParticleCut==a.fSecondParticleCut)
161 SetSecondParticleCut(fFirstParticleCut); // identical particle hbt
163 fSecondParticleCut = a.fSecondParticleCut->Clone();
165 fPairCut = a.fPairCut->Clone();
168 SetEventCut(fEventCut); // this will set the myAnalysis pointer inside the cut
169 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - event cut set " << endl;
171 if ( fFirstParticleCut ) {
172 SetFirstParticleCut(fFirstParticleCut); // this will set the myAnalysis pointer inside the cut
173 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - first particle cut set " << endl;
175 if ( fSecondParticleCut ) {
176 SetSecondParticleCut(fSecondParticleCut); // this will set the myAnalysis pointer inside the cut
177 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - second particle cut set " << endl;
179 SetPairCut(fPairCut); // this will set the myAnalysis pointer inside the cut
180 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - pair cut set " << endl;
183 AliFemtoCorrFctnIterator iter;
184 for (iter=a.fCorrFctnCollection->begin(); iter!=a.fCorrFctnCollection->end();iter++){
185 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - looking for correlation functions " << endl;
186 AliFemtoCorrFctn* fctn = (*iter)->Clone();
187 if (fctn) AddCorrFctn(fctn);
188 else cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - correlation function not found " << endl;
191 fNumEventsToMix = a.fNumEventsToMix;
193 fMinSizePartCollection = a.fMinSizePartCollection; // minimum # particles in ParticleCollection
195 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - analysis copied " << endl;
198 //____________________________
199 AliFemtoAnalysis::~AliFemtoAnalysis(){
201 cout << " AliFemtoAnalysis::~AliFemtoAnalysis()" << endl;
202 if (fEventCut) delete fEventCut; fEventCut=0;
203 if (fFirstParticleCut == fSecondParticleCut) fSecondParticleCut=0;
204 if (fFirstParticleCut) delete fFirstParticleCut; fFirstParticleCut=0;
205 if (fSecondParticleCut) delete fSecondParticleCut; fSecondParticleCut=0;
206 if (fPairCut) delete fPairCut; fPairCut=0;
207 // now delete every CorrFunction in the Collection, and then the Collection itself
208 AliFemtoCorrFctnIterator iter;
209 for (iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
212 delete fCorrFctnCollection;
213 // now delete every PicoEvent in the EventMixingBuffer and then the Buffer itself
215 AliFemtoPicoEventIterator piter;
216 for (piter=fMixingBuffer->begin();piter!=fMixingBuffer->end();piter++){
219 delete fMixingBuffer;
222 //______________________
223 AliFemtoAnalysis& AliFemtoAnalysis::operator=(const AliFemtoAnalysis& aAna)
225 // Assignment operator
229 fCorrFctnCollection = new AliFemtoCorrFctnCollection;
230 fMixingBuffer = new AliFemtoPicoEventCollection;
232 // find the right event cut
233 fEventCut = aAna.fEventCut->Clone();
234 // find the right first particle cut
235 fFirstParticleCut = aAna.fFirstParticleCut->Clone();
236 // find the right second particle cut
237 if (aAna.fFirstParticleCut==aAna.fSecondParticleCut)
238 SetSecondParticleCut(fFirstParticleCut); // identical particle hbt
240 fSecondParticleCut = aAna.fSecondParticleCut->Clone();
242 fPairCut = aAna.fPairCut->Clone();
245 SetEventCut(fEventCut); // this will set the myAnalysis pointer inside the cut
246 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - event cut set " << endl;
248 if ( fFirstParticleCut ) {
249 SetFirstParticleCut(fFirstParticleCut); // this will set the myAnalysis pointer inside the cut
250 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - first particle cut set " << endl;
252 if ( fSecondParticleCut ) {
253 SetSecondParticleCut(fSecondParticleCut); // this will set the myAnalysis pointer inside the cut
254 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - second particle cut set " << endl;
256 SetPairCut(fPairCut); // this will set the myAnalysis pointer inside the cut
257 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - pair cut set " << endl;
260 AliFemtoCorrFctnIterator iter;
261 for (iter=aAna.fCorrFctnCollection->begin(); iter!=aAna.fCorrFctnCollection->end();iter++){
262 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - looking for correlation functions " << endl;
263 AliFemtoCorrFctn* fctn = (*iter)->Clone();
264 if (fctn) AddCorrFctn(fctn);
265 else cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - correlation function not found " << endl;
268 fNumEventsToMix = aAna.fNumEventsToMix;
270 fMinSizePartCollection = aAna.fMinSizePartCollection; // minimum # particles in ParticleCollection
272 cout << " AliFemtoAnalysis::AliFemtoAnalysis(const AliFemtoAnalysis& a) - analysis copied " << endl;
276 //______________________
277 AliFemtoCorrFctn* AliFemtoAnalysis::CorrFctn(int n){
278 // return pointer to n-th correlation function
279 if ( n<0 || n > (int)fCorrFctnCollection->size() )
281 AliFemtoCorrFctnIterator iter=fCorrFctnCollection->begin();
282 for (int i=0; i<n ;i++){
287 //____________________________
288 AliFemtoString AliFemtoAnalysis::Report()
290 // Create a simple report from the analysis execution
291 cout << "AliFemtoAnalysis - constructing Report..."<<endl;
292 string temp = "-----------\nHbt Analysis Report:\n";
293 temp += "\nEvent Cuts:\n";
294 temp += fEventCut->Report();
295 temp += "\nParticle Cuts - First Particle:\n";
296 temp += fFirstParticleCut->Report();
297 temp += "\nParticle Cuts - Second Particle:\n";
298 temp += fSecondParticleCut->Report();
299 temp += "\nPair Cuts:\n";
300 temp += fPairCut->Report();
301 temp += "\nCorrelation Functions:\n";
302 AliFemtoCorrFctnIterator iter;
303 if ( fCorrFctnCollection->size()==0 ) {
304 cout << "AliFemtoAnalysis-Warning : no correlations functions in this analysis " << endl;
306 for (iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
307 temp += (*iter)->Report();
310 temp += "-------------\n";
311 AliFemtoString returnThis=temp;
314 //_________________________
315 void AliFemtoAnalysis::ProcessEvent(const AliFemtoEvent* hbtEvent) {
316 // Add event to processed events
317 fPicoEvent=0; // we will get a new pico event, if not prevent corr. fctn to access old pico event
320 EventBegin(hbtEvent);
321 // event cut and event cut monitor
322 bool tmpPassEvent = fEventCut->Pass(hbtEvent);
323 fEventCut->FillCutMonitor(hbtEvent, tmpPassEvent);
325 cout << "AliFemtoAnalysis::ProcessEvent() - Event has passed cut - build picoEvent from " <<
326 hbtEvent->TrackCollection()->size() << " tracks in TrackCollection" << endl;
327 // OK, analysis likes the event-- build a pico event from it, using tracks the analysis likes...
328 fPicoEvent = new AliFemtoPicoEvent; // this is what we will make pairs from and put in Mixing Buffer
329 // no memory leak. we will delete picoevents when they come out of the mixing buffer
330 FillHbtParticleCollection(fFirstParticleCut,(AliFemtoEvent*)hbtEvent,fPicoEvent->FirstParticleCollection());
331 if ( !(AnalyzeIdenticalParticles()) )
332 FillHbtParticleCollection(fSecondParticleCut,(AliFemtoEvent*)hbtEvent,fPicoEvent->SecondParticleCollection());
333 cout <<"AliFemtoAnalysis::ProcessEvent - #particles in First, Second Collections: " <<
334 fPicoEvent->FirstParticleCollection()->size() << " " <<
335 fPicoEvent->SecondParticleCollection()->size() << endl;
337 // mal - implement a switch which allows only using events with ParticleCollections containing a minimum
338 // number of entries (jun2002)
339 if ((fPicoEvent->FirstParticleCollection()->size() >= fMinSizePartCollection )
340 && ( AnalyzeIdenticalParticles() || (fPicoEvent->SecondParticleCollection()->size() >= fMinSizePartCollection ))) {
343 //------------------------------------------------------------------------------
344 // Temporary comment:
345 // This whole section rewritten so that all pairs are built using the
346 // same code... easier to read and manage, and MakePairs() can be called by
347 // derived classes. Also, the requirement of a full mixing buffer before
348 // mixing is removed.
349 // Dan Magestro, 11/2002
351 //------ Make real pairs. If identical, make pairs for one collection ------//
353 if (AnalyzeIdenticalParticles()) {
354 MakePairs("real", fPicoEvent->FirstParticleCollection() );
357 MakePairs("real", fPicoEvent->FirstParticleCollection(),
358 fPicoEvent->SecondParticleCollection() );
360 cout << "AliFemtoAnalysis::ProcessEvent() - reals done ";
362 //---- Make pairs for mixed events, looping over events in mixingBuffer ----//
364 AliFemtoPicoEvent* storedEvent;
365 AliFemtoPicoEventIterator fPicoEventIter;
366 for (fPicoEventIter=MixingBuffer()->begin();fPicoEventIter!=MixingBuffer()->end();fPicoEventIter++){
367 storedEvent = *fPicoEventIter;
368 if (AnalyzeIdenticalParticles()) {
369 MakePairs("mixed",fPicoEvent->FirstParticleCollection(),
370 storedEvent->FirstParticleCollection() );
373 MakePairs("mixed",fPicoEvent->FirstParticleCollection(),
374 storedEvent->SecondParticleCollection() );
376 MakePairs("mixed",storedEvent->FirstParticleCollection(),
377 fPicoEvent->SecondParticleCollection() );
380 cout << " - mixed done " << endl;
382 //--------- If mixing buffer is full, delete oldest event ---------//
384 if ( MixingBufferFull() ) {
385 delete MixingBuffer()->back();
386 MixingBuffer()->pop_back();
389 //-------- Add current event (fPicoEvent) to mixing buffer --------//
391 MixingBuffer()->push_front(fPicoEvent);
394 // Temporary comment: End of rewritten section... Dan Magestro, 11/2002
395 //------------------------------------------------------------------------------
398 } // if ParticleCollections are big enough (mal jun2002)
402 } // if currentEvent is accepted by currentAnalysis
403 EventEnd(hbtEvent); // cleanup for EbyE
404 //cout << "AliFemtoAnalysis::ProcessEvent() - return to caller ... " << endl;
406 //_________________________
407 void AliFemtoAnalysis::MakePairs(const char* typeIn, AliFemtoParticleCollection *partCollection1,
408 AliFemtoParticleCollection *partCollection2){
409 // Build pairs, check pair cuts, and call CFs' AddRealPair() or
410 // AddMixedPair() methods. If no second particle collection is
411 // specfied, make pairs within first particle collection.
413 string type = typeIn;
415 AliFemtoPair* tPair = new AliFemtoPair;
417 AliFemtoCorrFctnIterator tCorrFctnIter;
419 AliFemtoParticleIterator tPartIter1, tPartIter2;
421 AliFemtoParticleIterator tStartOuterLoop = partCollection1->begin(); // always
422 AliFemtoParticleIterator tEndOuterLoop = partCollection1->end(); // will be one less if identical
423 AliFemtoParticleIterator tStartInnerLoop;
424 AliFemtoParticleIterator tEndInnerLoop;
425 if (partCollection2) { // Two collections:
426 tStartInnerLoop = partCollection2->begin(); // Full inner & outer loops
427 tEndInnerLoop = partCollection2->end(); //
429 else { // One collection:
430 tEndOuterLoop--; // Outer loop goes to next-to-last particle
431 tEndInnerLoop = partCollection1->end() ; // Inner loop goes to last particle
433 for (tPartIter1=tStartOuterLoop;tPartIter1!=tEndOuterLoop;tPartIter1++) {
434 if (!partCollection2){
435 tStartInnerLoop = tPartIter1;
438 tPair->SetTrack1(*tPartIter1);
439 for (tPartIter2 = tStartInnerLoop; tPartIter2!=tEndInnerLoop;tPartIter2++) {
440 tPair->SetTrack2(*tPartIter2);
442 // The following lines have to be uncommented if you want pairCutMonitors
443 // they are not in for speed reasons
444 // bool tmpPassPair = fPairCut->Pass(tPair);
445 // fPairCut->FillCutMonitor(tPair, tmpPassPair);
446 // if ( tmpPassPair )
448 //---- If pair passes cut, loop over CF's and add pair to real/mixed ----//
450 if (fPairCut->Pass(tPair)){
451 for (tCorrFctnIter=fCorrFctnCollection->begin();
452 tCorrFctnIter!=fCorrFctnCollection->end();tCorrFctnIter++){
453 AliFemtoCorrFctn* tCorrFctn = *tCorrFctnIter;
455 tCorrFctn->AddRealPair(tPair);
456 else if(type == "mixed")
457 tCorrFctn->AddMixedPair(tPair);
459 cout << "Problem with pair type, type = " << type.c_str() << endl;
463 } // loop over second particle
465 } // loop over first particle
470 //_________________________
471 void AliFemtoAnalysis::EventBegin(const AliFemtoEvent* ev){
472 // Perform initialization operations at the beginning of the event processing
473 //cout << " AliFemtoAnalysis::EventBegin(const AliFemtoEvent* ev) " << endl;
474 fFirstParticleCut->EventBegin(ev);
475 fSecondParticleCut->EventBegin(ev);
476 fPairCut->EventBegin(ev);
477 for (AliFemtoCorrFctnIterator iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
478 (*iter)->EventBegin(ev);
481 //_________________________
482 void AliFemtoAnalysis::EventEnd(const AliFemtoEvent* ev){
483 // Fiinsh operations at the end of event processing
484 fFirstParticleCut->EventEnd(ev);
485 fSecondParticleCut->EventEnd(ev);
486 fPairCut->EventEnd(ev);
487 for (AliFemtoCorrFctnIterator iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
488 (*iter)->EventEnd(ev);
491 //_________________________
492 void AliFemtoAnalysis::Finish(){
493 // Perform finishing operations after all events are processed
494 AliFemtoCorrFctnIterator iter;
495 for (iter=fCorrFctnCollection->begin(); iter!=fCorrFctnCollection->end();iter++){
499 //_________________________
500 void AliFemtoAnalysis::AddEventProcessed() {
501 // Increase count of processed events
504 //_________________________
505 TList* AliFemtoAnalysis::ListSettings()
507 TList *tListSettings = new TList();
509 TList *p1Cut = fFirstParticleCut->ListSettings();
511 TListIter nextp1(p1Cut);
512 while (TObject *obj = nextp1.Next()) {
513 TString cuts(obj->GetName());
514 cuts.Prepend("AliFemtoAnalysis.");
515 tListSettings->Add(new TObjString(cuts.Data()));
518 if (fSecondParticleCut != fFirstParticleCut) {
519 TList *p2Cut = fSecondParticleCut->ListSettings();
522 while (TObject *obj = nextp2()) {
523 TString cuts(obj->GetName());
524 cuts.Prepend("AliFemtoAnalysis.");
525 tListSettings->Add(new TObjString(cuts.Data()));
529 TList *pairCut = fPairCut->ListSettings();
531 TIter nextpair(pairCut);
532 while (TObject *obj = nextpair()) {
533 TString cuts(obj->GetName());
534 cuts.Prepend("AliFemtoAnalysis.");
535 tListSettings->Add(new TObjString(cuts.Data()));
538 return tListSettings;