StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StHbtSplitEvalAnalysis.cxx
1 /***************************************************************************
2  *
3  * $Id: StHbtSplitEvalAnalysis.cxx,v 1.2 2001/11/05 14:11:19 lisa Exp $
4  *
5  * Author: Mike Lisa, Ohio State, lisa@mps.ohio-state.edu
6  ***************************************************************************
7  *
8  * Description: part of STAR HBT Framework: StHbtMaker package
9  * This is the Class for Analysis objects. Each of the simultaneous
10  * Analyses running should have one of these instantiated. They link
11  * into the Manager in an Analysis Collection.
12  *
13  ***************************************************************************
14  *
15  * $Log: StHbtSplitEvalAnalysis.cxx,v $
16  * Revision 1.2 2001/11/05 14:11:19 lisa
17  * small modifications to Splitting Analysis class and macro
18  *
19  * Revision 1.1 2000/08/15 22:18:47 lisa
20  * Add a special HbtAnalysis class that estimates amount of splitting and add a macro to use it
21  *
22  * Revision 1.12 2000/07/16 22:23:17 laue
23  * I forgot that we moved memberfunctions out of StHbtBaseAnalysis.
24  * So my previous check-ins didn't compile with the library.
25  * Now they do.
26  *
27  * Revision 1.11 2000/07/16 21:38:22 laue
28  * StHbtCoulomb.cxx StHbtSectoredAnalysis.cxx : updated for standalone version
29  * StHbtV0.cc StHbtV0.hh : some cast to prevent compiling warnings
30  * StHbtParticle.cc StHbtParticle.hh : pointers mTrack,mV0 initialized to 0
31  * StHbtIOBinary.cc : some printouts in #ifdef STHBTDEBUG
32  * StHbtEvent.cc : B-Field set to 0.25Tesla, we have to think about a better
33  * solution
34  *
35  * Revision 1.10 2000/07/06 18:45:51 laue
36  * Copy constructor fixed. It couldn't handle identicle particles.
37  *
38  * Revision 1.9 2000/04/13 20:20:22 laue
39  * Event mixing corrected. Now the first collection of the current event is
40  * mixed with the second collection from the mixing buffer _AND_ vice verse
41  *
42  * Revision 1.8 2000/03/23 23:00:01 laue
43  * StHbtSplitEvalAnalysis copy constructor now uses Clone() function of cuts
44  * StHbtTypes now has StHbtTF1 for fitting purposes
45  *
46  * Revision 1.7 2000/03/17 17:23:05 laue
47  * Roberts new three particle correlations implemented.
48  *
49  * Revision 1.6 2000/03/16 02:07:04 laue
50  * Copy constructor added to StHbtSplitEvalAnalysis (only known cuts, corrfctn).
51  *
52  * StHbtBinaryReader can now derive filename from StIOMaker and read a list
53  * of files.
54  *
55  * StHbtManager now holds a collection of StHbtEventWriters (multiple writes
56  * possible now)
57  *
58  * Revision 1.5 2000/02/13 17:17:12 laue
59  * Calls to the EventBegin() and EventEnd() functions implemented
60  * The actual analysis is moved from StHbtManager to StHbtSplitEvalAnalysis
61  *
62  * Revision 1.4 2000/01/25 17:35:16 laue
63  * I. In order to run the stand alone version of the StHbtMaker the following
64  * changes have been done:
65  * a) all ClassDefs and ClassImps have been put into #ifdef __ROOT__ statements
66  * b) unnecessary includes of StMaker.h have been removed
67  * c) the subdirectory StHbtMaker/doc/Make has been created including everything
68  * needed for the stand alone version
69  *
70  * II. To reduce the amount of compiler warning
71  * a) some variables have been type casted
72  * b) some destructors have been declared as virtual
73  *
74  * Revision 1.3 1999/10/04 15:38:53 lisa
75  * include Franks new accessor methods StHbtSplitEvalAnalysis::CorrFctn and StHbtManager::Analysis as well as McEvent example macro
76  *
77  * Revision 1.2 1999/07/06 22:33:22 lisa
78  * Adjusted all to work in pro and new - dev itself is broken
79  *
80  * Revision 1.1.1.1 1999/06/29 16:02:57 lisa
81  * Installation of StHbtMaker
82  *
83  **************************************************************************/
84 
85 #include "StHbtMaker/Infrastructure/StHbtSplitEvalAnalysis.h"
86 #include "StHbtMaker/Infrastructure/StHbtParticleCollection.hh"
87 #include "StHbtMaker/Base/StHbtTrackCut.h"
88 #include "StHbtMaker/Base/StHbtV0Cut.h"
89 
90 #ifdef __ROOT__
91 ClassImp(StHbtSplitEvalAnalysis)
92 #endif
93 
94 StHbtEventCut* copyTheCut(StHbtEventCut*);
96 StHbtPairCut* copyTheCut(StHbtPairCut*);
97 StHbtCorrFctn* copyTheCorrFctn(StHbtCorrFctn*);
98 
99 // this little function used to apply ParticleCuts (TrackCuts or V0Cuts) and fill ParticleCollections of picoEvent
100 // it is called from StHbtSplitEvalAnalysis::ProcessEvent()
101  void FillHbtParticleCollection(StHbtParticleCut* partCut,
102  StHbtEvent* hbtEvent,
103  StHbtParticleCollection* partCollection);
104 // {
105 // switch (partCut->Type()) {
106 // case hbtTrack: // cut is cutting on Tracks
107 // {
108 // StHbtTrackCut* pCut = (StHbtTrackCut*) partCut;
109 // StHbtTrack* pParticle;
110 // StHbtTrackIterator pIter;
111 // StHbtTrackIterator startLoop = hbtEvent->TrackCollection()->begin();
112 // StHbtTrackIterator endLoop = hbtEvent->TrackCollection()->end();
113 // for (pIter=startLoop;pIter!=endLoop;pIter++){
114 // pParticle = *pIter;
115 // bool tmpPassParticle = pCut->Pass(pParticle);
116 // pCut->FillCutMonitor(pParticle, tmpPassParticle);
117 // if (tmpPassParticle){
118 // StHbtParticle* particle = new StHbtParticle(pParticle,pCut->Mass());
119 // partCollection->push_back(particle);
120 // }
121 // }
122 // break;
123 // }
124 // case hbtV0: // cut is cutting on V0s
125 // {
126 // StHbtV0Cut* pCut = (StHbtV0Cut*) partCut;
127 // StHbtV0* pParticle;
128 // StHbtV0Iterator pIter;
129 // StHbtV0Iterator startLoop = hbtEvent->V0Collection()->begin();
130 // StHbtV0Iterator endLoop = hbtEvent->V0Collection()->end();
131 // // this following "for" loop is identical to the one above, but because of scoping, I can's see how to avoid repitition...
132 // for (pIter=startLoop;pIter!=endLoop;pIter++){
133 // pParticle = *pIter;
134 // bool tmpPassV0 = pCut->Pass(pParticle);
135 // pCut->FillCutMonitor(pParticle,tmpPassV0);
136 // if (tmpPassV0){
137 // StHbtParticle* particle = new StHbtParticle(pParticle,partCut->Mass());
138 // partCollection->push_back(particle);
139 // }
140 // }
141 // break;
142 // }
143 // default:
144 // cout << "FillHbtParticleCollection function (in StHbtSplitEvalAnalysis.cxx) - undefined Particle Cut type!!! \n";
145 // }
146 // }
147 //____________________________
148 StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(){
149  // mControlSwitch = 0;
150  mEventCut = 0;
151  mFirstParticleCut = 0;
152  mSecondParticleCut = 0;
153  mPairCut = 0;
154  mCorrFctnCollection= 0;
155  mCorrFctnCollection = new StHbtCorrFctnCollection;
156  mMixingBuffer = new StHbtPicoEventCollection;
157 
158  mQinvCut = 0.05;
159 
160  int npTbins = 20;
161  float pTbinmax = 2.0;
162  mRealSplits = new StHbt1DHisto("realSplit","realSplit",npTbins,0.0,pTbinmax);
163  mRealAll = new StHbt1DHisto("realAll","realAll",npTbins,0.0,pTbinmax);
164  mMixedSplits = new StHbt1DHisto("mixedSplit","mixedSplit",npTbins,0.0,pTbinmax);
165  mMixedAll = new StHbt1DHisto("mixedAll","mixedAll",npTbins,0.0,pTbinmax);
166 
167  mSplitFractionUpperLimit = new StHbt1DHisto("SplitFracUpperLimit","SplitFracUpperLImit",npTbins,0.0,pTbinmax);
168  mSplitFractionLowerLimit = new StHbt1DHisto("SplitFracLowerLimit","SplitFracLowerLImit",npTbins,0.0,pTbinmax);
169 
170 }
171 //____________________________
172 
173 StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) : StHbtBaseAnalysis() {
174  //StHbtSplitEvalAnalysis();
175  mEventCut = 0;
176  mFirstParticleCut = 0;
177  mSecondParticleCut = 0;
178  mPairCut = 0;
179  mCorrFctnCollection= 0;
180  mCorrFctnCollection = new StHbtCorrFctnCollection;
181  mMixingBuffer = new StHbtPicoEventCollection;
182 
183  // find the right event cut
184  mEventCut = a.mEventCut->Clone();
185  // find the right first particle cut
186  mFirstParticleCut = a.mFirstParticleCut->Clone();
187  // find the right second particle cut
188  if (a.mFirstParticleCut==a.mSecondParticleCut)
189  SetSecondParticleCut(mFirstParticleCut); // identical particle hbt
190  else
191  mSecondParticleCut = a.mSecondParticleCut->Clone();
192 
193  mPairCut = a.mPairCut->Clone();
194 
195  if ( mEventCut ) {
196  SetEventCut(mEventCut); // this will set the myAnalysis pointer inside the cut
197  cout << " StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) - event cut set " << endl;
198  }
199  if ( mFirstParticleCut ) {
200  SetFirstParticleCut(mFirstParticleCut); // this will set the myAnalysis pointer inside the cut
201  cout << " StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) - first particle cut set " << endl;
202  }
203  if ( mSecondParticleCut ) {
204  SetSecondParticleCut(mSecondParticleCut); // this will set the myAnalysis pointer inside the cut
205  cout << " StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) - second particle cut set " << endl;
206  } if ( mPairCut ) {
207  SetPairCut(mPairCut); // this will set the myAnalysis pointer inside the cut
208  cout << " StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) - pair cut set " << endl;
209  }
210 
211  StHbtCorrFctnIterator iter;
212  for (iter=a.mCorrFctnCollection->begin(); iter!=a.mCorrFctnCollection->end();iter++){
213  cout << " StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) - looking for correlation functions " << endl;
214  StHbtCorrFctn* fctn = (*iter)->Clone();
215  if (fctn) AddCorrFctn(fctn);
216  else cout << " StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) - correlation function not found " << endl;
217  }
218 
219  mNumEventsToMix = a.mNumEventsToMix;
220 
221  cout << " StHbtSplitEvalAnalysis::StHbtSplitEvalAnalysis(const StHbtSplitEvalAnalysis& a) - analysis copied " << endl;
222 
223 }
224 //____________________________
225 StHbtSplitEvalAnalysis::~StHbtSplitEvalAnalysis(){
226  //delete mControlSwitch ;
227  delete mEventCut ;
228  delete mFirstParticleCut ;
229  delete mSecondParticleCut ;
230  delete mPairCut ;
231  // now delete every CorrFunction in the Collection, and then the Collection itself
232  StHbtCorrFctnIterator iter;
233  for (iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
234  delete *iter;
235  }
236  delete mCorrFctnCollection;
237  // now delete every PicoEvent in the EventMixingBuffer and then the Buffer itself
238  StHbtPicoEventIterator piter;
239  for (piter=mMixingBuffer->begin();piter!=mMixingBuffer->end();piter++){
240  delete *piter;
241  }
242  delete mMixingBuffer;
243 }
244 //______________________
245 StHbtCorrFctn* StHbtSplitEvalAnalysis::CorrFctn(int n){ // return pointer to n-th correlation function
246  if ( n<0 || n > (int)mCorrFctnCollection->size() )
247  return NULL;
248  StHbtCorrFctnIterator iter=mCorrFctnCollection->begin();
249  for (int i=0; i<n ;i++){
250  iter++;
251  }
252  return *iter;
253 }
254 //____________________________
255 StHbtString StHbtSplitEvalAnalysis::Report()
256 {
257  cout << "StHbtSplitEvalAnalysis - constructing Report..."<<endl;
258  string temp = "-----------\nHbt Analysis Report:\n";
259  temp += "\nEvent Cuts:\n";
260  temp += mEventCut->Report();
261  temp += "\nParticle Cuts - First Particle:\n";
262  temp += mFirstParticleCut->Report();
263  temp += "\nParticle Cuts - Second Particle:\n";
264  temp += mSecondParticleCut->Report();
265  temp += "\nPair Cuts:\n";
266  temp += mPairCut->Report();
267  temp += "\nCorrelation Functions:\n";
268  StHbtCorrFctnIterator iter;
269  if ( mCorrFctnCollection->size()==0 ) {
270  cout << "StHbtSplitEvalAnalysis-Warning : no correlations functions in this analysis " << endl;
271  }
272  for (iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
273  temp += (*iter)->Report();
274  temp += "\n";
275  }
276  temp += "-------------\n";
277  StHbtString returnThis=temp;
278  return returnThis;
279 }
280 //_________________________
282  // startup for EbyE
283  EventBegin(hbtEvent);
284  // event cut and event cut monitor
285  bool tmpPassEvent = mEventCut->Pass(hbtEvent);
286  mEventCut->FillCutMonitor(hbtEvent, tmpPassEvent);
287  if (tmpPassEvent) {
288  cout << "StHbtSplitEvalAnalysis::ProcessEvent() - Event has passed cut - build picoEvent from " <<
289  hbtEvent->TrackCollection()->size() << " tracks in TrackCollection" << endl;
290  // OK, analysis likes the event-- build a pico event from it, using tracks the analysis likes...
291  StHbtPicoEvent* picoEvent = new StHbtPicoEvent; // this is what we will make pairs from and put in Mixing Buffer
292  FillHbtParticleCollection(mFirstParticleCut,(StHbtEvent*)hbtEvent,picoEvent->FirstParticleCollection());
293  if ( !(AnalyzeIdenticalParticles()) )
294  FillHbtParticleCollection(mSecondParticleCut,(StHbtEvent*)hbtEvent,picoEvent->SecondParticleCollection());
295  cout <<"StHbtSplitEvalAnalysis::ProcessEvent - #particles in First, Second Collections: " <<
296  picoEvent->FirstParticleCollection()->size() << " " <<
297  picoEvent->SecondParticleCollection()->size() << endl;
298 
299  // OK, pico event is built
300  // make real pairs...
301 
302  // Fabrice points out that we do not need to keep creating/deleting pairs all the time
303  // We only ever need ONE pair, and we can just keep changing internal pointers
304  // this should help speed things up
305  StHbtPair* ThePair = new StHbtPair;
306 
307  StHbtParticleIterator PartIter1;
308  StHbtParticleIterator PartIter2;
309  StHbtCorrFctnIterator CorrFctnIter;
310  StHbtParticleIterator StartOuterLoop = picoEvent->FirstParticleCollection()->begin(); // always
311  StHbtParticleIterator EndOuterLoop = picoEvent->FirstParticleCollection()->end(); // will be one less if identical
312  StHbtParticleIterator StartInnerLoop;
313  StHbtParticleIterator EndInnerLoop;
314  if (AnalyzeIdenticalParticles()) { // only use First collection
315  EndOuterLoop--; // outer loop goes to next-to-last particle in First collection
316  EndInnerLoop = picoEvent->FirstParticleCollection()->end() ; // inner loop goes to last particle in First collection
317  }
318  else { // nonidentical - loop over First and Second collections
319  StartInnerLoop = picoEvent->SecondParticleCollection()->begin(); // inner loop starts at first particle in Second collection
320  EndInnerLoop = picoEvent->SecondParticleCollection()->end() ; // inner loop goes to last particle in Second collection
321  }
322 
323 
324  bool isSplit;
325  double trackPT;
326 
327  /* NOTE: the reason this "special analysis" requires a StHbtAnalysis class is that
328  we make plots of TRACKS not PAIRS (so that it cannot be done with a StHbtCorrFctn class).
329  Also note that in what we do below, if there is deemed to be a tracksplit, then one
330  of the daughters fills the "split" histogram, and the other the "all" histogram.
331  This is the correct thing to do, so we don't double-count in the "all" histogram.
332  */
333 
334 
335  for (PartIter1=StartOuterLoop;PartIter1!=EndOuterLoop;PartIter1++){
336  isSplit=0;
337  if (AnalyzeIdenticalParticles()){
338  StartInnerLoop = PartIter1;
339  StartInnerLoop++;
340  }
341  ThePair->SetTrack1(*PartIter1);
342  trackPT = ThePair->track1()->FourMomentum().vect().perp();
343  for (PartIter2 = StartInnerLoop; PartIter2!=EndInnerLoop;PartIter2++){
344  ThePair->SetTrack2(*PartIter2);
345  if (fabs(ThePair->qInv()) < mQinvCut){
346  // if (fabs(ThePair->qInv()) < (0.05*trackPT)){
347  if (!(mPairCut->Pass(ThePair))){
348  isSplit=1;
349  } // if failed pair cut
350  }
351  } // loop over second particle
352  if (isSplit){
353  mRealSplits->Fill(trackPT);
354  }
355  else{
356  mRealAll->Fill(trackPT);
357  }
358  } // loop over first particle
359 
360  // ok, now make mixed pairs, if the Mixing buffer is full
361 
362  cout << "StHbtSplitEvalAnalysis::ProcessEvent() - reals done" << endl;
363  if (MixingBufferFull()){
364  cout << "Mixing Buffer is full - lets rock and roll" << endl;
365  }
366  else {
367  cout << "Mixing Buffer not full -gotta wait " << MixingBuffer()->size() << endl;
368  }
369  if (MixingBufferFull()){
370  StHbtPicoEvent* storedEvent;
371  StHbtPicoEventIterator picoEventIter;
372  for (picoEventIter=MixingBuffer()->begin();picoEventIter!=MixingBuffer()->end();picoEventIter++){
373  storedEvent = *picoEventIter;
374  if (AnalyzeIdenticalParticles()){
375  StartOuterLoop = picoEvent->FirstParticleCollection()->begin();
376  EndOuterLoop = picoEvent->FirstParticleCollection()->end();
377  StartInnerLoop = storedEvent->FirstParticleCollection()->begin();
378  EndInnerLoop = storedEvent->FirstParticleCollection()->end();
379  for (PartIter1=StartOuterLoop;PartIter1!=EndOuterLoop;PartIter1++){
380  isSplit=0;
381  ThePair->SetTrack1(*PartIter1);
382  trackPT = ThePair->track1()->FourMomentum().vect().perp();
383  for (PartIter2=StartInnerLoop;PartIter2!=EndInnerLoop;PartIter2++){
384  ThePair->SetTrack2(*PartIter2);
385  // testing... cout << "ThePair defined... going to pair cut... ";
386  if (fabs(ThePair->qInv()) < mQinvCut){
387  // if (fabs(ThePair->qInv()) < (0.05*trackPT)){
388  if (!(mPairCut->Pass(ThePair))){
389  isSplit=1;
390  } // if failed pair cut
391  }
392  } // loop over second particle
393  if (isSplit){
394  mMixedSplits->Fill(trackPT);
395  }
396  else{
397  mMixedAll->Fill(trackPT);
398  }
399  } // loop over first particle
400  } /* if identical particles */
401  else { // non identical particles
402  // mix current first collection with second collection from the mixing buffer
403  StartOuterLoop = picoEvent->FirstParticleCollection()->begin();
404  EndOuterLoop = picoEvent->FirstParticleCollection()->end();
405  StartInnerLoop = storedEvent->SecondParticleCollection()->begin();
406  EndInnerLoop = storedEvent->SecondParticleCollection()->end();
407  for (PartIter1=StartOuterLoop;PartIter1!=EndOuterLoop;PartIter1++){
408  ThePair->SetTrack1(*PartIter1);
409  for (PartIter2=StartInnerLoop;PartIter2!=EndInnerLoop;PartIter2++){
410  ThePair->SetTrack2(*PartIter2);
411  // testing... cout << "ThePair defined... going to pair cut... ";
412  if (mPairCut->Pass(ThePair)){
413  // testing... cout << " ThePair passed PairCut... ";
414  for (CorrFctnIter=mCorrFctnCollection->begin();
415  CorrFctnIter!=mCorrFctnCollection->end();CorrFctnIter++){
416  StHbtCorrFctn* CorrFctn = *CorrFctnIter;
417  CorrFctn->AddMixedPair(ThePair);
418  // testing...cout << " ThePair has been added to MixedPair method " << endl;
419  } // loop over correlation function
420  } // if passed pair cut
421  } // loop over second particle
422  } // loop over first particle
423  // mix current second collection with first collection from the mixing buffer
424  StartOuterLoop = picoEvent->SecondParticleCollection()->begin();
425  EndOuterLoop = picoEvent->SecondParticleCollection()->end();
426  StartInnerLoop = storedEvent->FirstParticleCollection()->begin();
427  EndInnerLoop = storedEvent->FirstParticleCollection()->end();
428  for (PartIter1=StartOuterLoop;PartIter1!=EndOuterLoop;PartIter1++){
429  ThePair->SetTrack1(*PartIter1);
430  for (PartIter2=StartInnerLoop;PartIter2!=EndInnerLoop;PartIter2++){
431  ThePair->SetTrack2(*PartIter2);
432  // testing... cout << "ThePair defined... going to pair cut... ";
433  if (mPairCut->Pass(ThePair)){
434  // testing... cout << " ThePair passed PairCut... ";
435  for (CorrFctnIter=mCorrFctnCollection->begin();
436  CorrFctnIter!=mCorrFctnCollection->end();CorrFctnIter++){
437  StHbtCorrFctn* CorrFctn = *CorrFctnIter;
438  CorrFctn->AddMixedPair(ThePair);
439  // testing...cout << " ThePair has been added to MixedPair method " << endl;
440  } // loop over correlation function
441  } // if passed pair cut
442  } // loop over second particle
443  } // loop over first particle
444  } // else non identical particles
445  } // loop over pico-events stored in Mixing buffer
446  // Now get rid of oldest stored pico-event in buffer.
447  // This means (1) delete the event from memory, (2) "pop" the pointer to it from the MixingBuffer
448  delete MixingBuffer()->back();
449  MixingBuffer()->pop_back();
450  } // if mixing buffer is full
451  delete ThePair;
452  MixingBuffer()->push_front(picoEvent); // store the current pico-event in buffer
453  } // if currentEvent is accepted by currentAnalysis
454  EventEnd(hbtEvent); // cleanup for EbyE
455  cout << "StHbtSplitEvalAnalysis::ProcessEvent() - return to caller ... " << endl;
456 }
457 //_________________________
458 void StHbtSplitEvalAnalysis::EventBegin(const StHbtEvent* ev){
459  mFirstParticleCut->EventBegin(ev);
460  mSecondParticleCut->EventBegin(ev);
461  mPairCut->EventBegin(ev);
462  for (StHbtCorrFctnIterator iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
463  (*iter)->EventBegin(ev);
464  }
465 }
466 //_________________________
467 void StHbtSplitEvalAnalysis::EventEnd(const StHbtEvent* ev){
468  mFirstParticleCut->EventEnd(ev);
469  mSecondParticleCut->EventEnd(ev);
470  mPairCut->EventEnd(ev);
471  for (StHbtCorrFctnIterator iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
472  (*iter)->EventEnd(ev);
473  }
474 }
475 //_________________________
476 void StHbtSplitEvalAnalysis::Finish(){
477  StHbtCorrFctnIterator iter;
478  for (iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
479  (*iter)->Finish();
480  }
481  // now divide histos etc to make splitting estimates...
482  mSplitFractionUpperLimit->Divide(mRealSplits,mRealAll);
483 
484  // mSplitFractionLowerLimit->Subtract(mRealSplits,mMixedSplits);
485  mSplitFractionLowerLimit->Add(mRealSplits,mMixedSplits,1.0,-1.0);
486  mSplitFractionLowerLimit->Divide(mRealAll);
487 }
488 
virtual void ProcessEvent(const StHbtEvent *)
returns reports of all cuts applied and correlation functions being done