StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StParityAnalysis.cxx
1 #include "StHbtMaker/Infrastructure/StParityAnalysis.h"
2 #include "StHbtMaker/Infrastructure/StHbtParticleCollection.hh"
3 #include "StHbtMaker/Base/StHbtTrackCut.h"
4 #include "StHbtMaker/Base/StHbtV0Cut.h"
5 
6 #ifdef __ROOT__
7 ClassImp(StParityAnalysis)
8 #endif
9 
10 StHbtEventCut* copyTheCut(StHbtEventCut*);
12 StHbtPairCut* copyTheCut(StHbtPairCut*);
13 StHbtCorrFctn* copyTheCorrFctn(StHbtCorrFctn*);
14 
15 // this little function used to apply ParticleCuts (TrackCuts or V0Cuts) and fill ParticleCollections of picoEvent
16 // it is called from StParityAnalysis::ProcessEvent()
17 void FillHbtParticleCollection2(StHbtParticleCut* partCut,
18  StHbtEvent* hbtEvent,
19  StHbtParticleCollection* partCollection)
20 {
21  switch (partCut->Type()) {
22  case hbtTrack: // cut is cutting on Tracks
23  {
24  StHbtTrackCut* pCut = (StHbtTrackCut*) partCut;
25  StHbtTrack* pParticle;
26  StHbtTrackIterator pIter;
27  StHbtTrackIterator startLoop = hbtEvent->TrackCollection()->begin();
28  StHbtTrackIterator endLoop = hbtEvent->TrackCollection()->end();
29  for (pIter=startLoop;pIter!=endLoop;pIter++){
30  pParticle = *pIter;
31  bool tmpPassParticle = pCut->Pass(pParticle);
32  pCut->FillCutMonitor(pParticle, tmpPassParticle);
33  if (tmpPassParticle){
34  StHbtParticle* particle = new StHbtParticle(pParticle,pCut->Mass());
35  partCollection->push_back(particle);
36  }
37  }
38  break;
39  }
40  case hbtV0: // cut is cutting on V0s
41  {
42  StHbtV0Cut* pCut = (StHbtV0Cut*) partCut;
43  StHbtV0* pParticle;
44  StHbtV0Iterator pIter;
45  StHbtV0Iterator startLoop = hbtEvent->V0Collection()->begin();
46  StHbtV0Iterator endLoop = hbtEvent->V0Collection()->end();
47  // this following "for" loop is identical to the one above, but because of scoping, I can's see how to avoid repitition...
48  for (pIter=startLoop;pIter!=endLoop;pIter++){
49  pParticle = *pIter;
50  bool tmpPassV0 = pCut->Pass(pParticle);
51  pCut->FillCutMonitor(pParticle,tmpPassV0);
52  if (tmpPassV0){
53  StHbtParticle* particle = new StHbtParticle(pParticle,partCut->Mass());
54  partCollection->push_back(particle);
55  }
56  }
57  break;
58  }
59  default:
60  cout << "FillHbtParticleCollection2 function (in StParityAnalysis.cxx) - undefined Particle Cut type!!! \n";
61  }
62 }
63 //____________________________
64 StParityAnalysis::StParityAnalysis(){
65  mEventCut = 0;
66  mFirstParticleCut = 0;
67  mSecondParticleCut = 0;
68  mPairCut = 0;
69  mCorrFctnCollection= 0;
70  mCorrFctnCollection = new StHbtCorrFctnCollection;
71  mNeventsProcessed = 0;
72 }
73 //____________________________
74 
75 StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) : StHbtBaseAnalysis() {
76  //StParityAnalysis();
77  mEventCut = 0;
78  mFirstParticleCut = 0;
79  mSecondParticleCut = 0;
80  mPairCut = 0;
81  mCorrFctnCollection= 0;
82  mCorrFctnCollection = new StHbtCorrFctnCollection;
83  mNeventsProcessed = 0;
84 
85  // find the right event cut
86  mEventCut = a.mEventCut->Clone();
87  // find the right first particle cut
88  mFirstParticleCut = a.mFirstParticleCut->Clone();
89  // find the right second particle cut
90  if (a.mFirstParticleCut==a.mSecondParticleCut!=0)
91  SetSecondParticleCut(mSecondParticleCut); // identical particle hbt
92  else
93  mSecondParticleCut = a.mSecondParticleCut->Clone();
94 
95  mPairCut = a.mPairCut->Clone();
96 
97  if ( mEventCut ) {
98  SetEventCut(mEventCut); // this will set the myAnalysis pointer inside the cut
99  cout << " StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) - event cut set " << endl;
100  }
101  if ( mFirstParticleCut ) {
102  SetFirstParticleCut(mFirstParticleCut); // this will set the myAnalysis pointer inside the cut
103  cout << " StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) - first particle cut set " << endl;
104  }
105  if ( mSecondParticleCut ) {
106  SetSecondParticleCut(mSecondParticleCut); // this will set the myAnalysis pointer inside the cut
107  cout << " StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) - second particle cut set " << endl;
108  } if ( mPairCut ) {
109  SetPairCut(mPairCut); // this will set the myAnalysis pointer inside the cut
110  cout << " StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) - pair cut set " << endl;
111  }
112 
113  StHbtCorrFctnIterator iter;
114  for (iter=a.mCorrFctnCollection->begin(); iter!=a.mCorrFctnCollection->end();iter++){
115  cout << " StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) - looking for correlation functions " << endl;
116  StHbtCorrFctn* fctn = (*iter)->Clone();
117  if (fctn) AddCorrFctn(fctn);
118  else cout << " StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) - correlation function not found " << endl;
119  }
120 
121  mNumEventsToMix = a.mNumEventsToMix;
122 
123  cout << " StParityAnalysis::StParityAnalysis(const StParityAnalysis& a) - analysis copied " << endl;
124 }
125 
126 //____________________________
127 StParityAnalysis::~StParityAnalysis(){
128  //delete mControlSwitch ;
129  delete mEventCut ;
130  delete mFirstParticleCut ;
131  delete mSecondParticleCut ;
132  delete mPairCut ;
133  // now delete every CorrFunction in the Collection, and then the Collection itself
134  StHbtCorrFctnIterator iter;
135  for (iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
136  delete *iter;
137  }
138  delete mCorrFctnCollection;
139 }
140 //______________________
141 StHbtCorrFctn* StParityAnalysis::CorrFctn(int n){ // return pointer to n-th correlation function
142  if ( n<0 || n > (int)mCorrFctnCollection->size() )
143  return NULL;
144  StHbtCorrFctnIterator iter=mCorrFctnCollection->begin();
145  for (int i=0; i<n ;i++){
146  iter++;
147  }
148  return *iter;
149 }
150 //____________________________
151 StHbtString StParityAnalysis::Report()
152 {
153  cout << "StParityAnalysis - constructing Report..."<<endl;
154  string temp = "-----------\nHbt Analysis Report:\n";
155  temp += "\nEvent Cuts:\n";
156  temp += mEventCut->Report();
157  temp += "\nParticle Cuts - First Particle:\n";
158  temp += mFirstParticleCut->Report();
159  temp += "\nParticle Cuts - Second Particle:\n";
160  temp += mSecondParticleCut->Report();
161  temp += "\nPair Cuts:\n";
162  temp += mPairCut->Report();
163  temp += "\nCorrelation Functions:\n";
164  StHbtCorrFctnIterator iter;
165  if ( mCorrFctnCollection->size()==0 ) {
166  cout << "StParityAnalysis-Warning : no correlations functions in this analysis " << endl;
167  }
168  for (iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
169  temp += (*iter)->Report();
170  temp += "\n";
171  }
172  temp += "-------------\n";
173  StHbtString returnThis=temp;
174  return returnThis;
175 }
176 //_________________________
178 
179  // Add event to processed events
180  AddEventProcessed();
181 
182  ParityBuff PlusSame;
183  ParityBuff MinusSame;
184  ParityBuff PlusMixed;
185  ParityBuff MinusMixed;
186  #define BUFFERSIZ 50
187  static ParityBuff PlusBuffer[BUFFERSIZ];
188  static ParityBuff MinusBuffer[BUFFERSIZ];
189  static long nEvent = 0;
190  StHbtParticle *pParticle;
191 
192  EventBegin(hbtEvent);
193  // event cut and event cut monitor
194  bool tmpPassEvent = mEventCut->Pass(hbtEvent);
195  mEventCut->FillCutMonitor(hbtEvent, tmpPassEvent);
196  if (tmpPassEvent) {
197  cout << "StParityAnalysis::ProcessEvent() - Event has passed cut - build picoEvent from " <<
198  hbtEvent->TrackCollection()->size() << " tracks in TrackCollection" << endl;
199  // OK, analysis likes the event-- build a pico event from it, using tracks the analysis likes...
200  StHbtPicoEvent* picoEvent = new StHbtPicoEvent; // this is what we will make pairs from and put in Mixing Buffer
201  FillHbtParticleCollection2(mFirstParticleCut,(StHbtEvent*)hbtEvent,picoEvent->FirstParticleCollection());
202  FillHbtParticleCollection2(mSecondParticleCut,(StHbtEvent*)hbtEvent,picoEvent->SecondParticleCollection());
203  cout <<"StParityAnalysis::ProcessEvent - #particles in First, Second Collections: " <<
204  picoEvent->FirstParticleCollection()->size() << " " <<
205  picoEvent->SecondParticleCollection()->size() << endl;
206 
207  // OK, pico event is built
208  // Now copy it into the Parity Mixing Buffer...
209 
210  StHbtParticleIterator PartIter1;
211  StHbtParticleIterator PartIter2;
212  StHbtParticleIterator StartOuterLoop = picoEvent->FirstParticleCollection()->begin();
213  StHbtParticleIterator EndOuterLoop = picoEvent->FirstParticleCollection()->end();
214  StHbtParticleIterator StartInnerLoop;
215  StHbtParticleIterator EndInnerLoop;
216  StartInnerLoop = picoEvent->SecondParticleCollection()->begin(); // inner loop starts at first particle in Second collection
217  EndInnerLoop = picoEvent->SecondParticleCollection()->end() ; // inner loop goes to last particle in Second collection
218 
219  // Begin Parity ************************************************************
220 
221  int evtMod = (nEvent%BUFFERSIZ);
222  nEvent++;
223  int bufferIndex = evtMod; // if we haven't filled the buffer yet, we continue filling it
224  if (nEvent >= BUFFERSIZ ) { // if it is full, we just keep filling and destroying the
225  bufferIndex = (BUFFERSIZ - 1); // final event in the buffer (after mixing it, of course)
226  }
227 
228  //COPY JUST 4-VECTORS FROM PICO-EVENT INTO MIXING BUFFER
229 
230  PlusBuffer[bufferIndex].clear();
231 
232  for (PartIter1=StartOuterLoop;PartIter1!=EndOuterLoop;PartIter1++){
233  pParticle = *PartIter1;
234  PlusBuffer[bufferIndex].push_back(pParticle->FourMomentum() ) ;
235  }
236  int newPlusSize = PlusBuffer[bufferIndex].size();
237  if (newPlusSize == 0){cout << " 0 tracks copied to buffer for particle 1!!!"<< endl ;}
238 
239  MinusBuffer[bufferIndex].clear();
240 
241  for (PartIter2 = StartInnerLoop; PartIter2!=EndInnerLoop;PartIter2++){
242  pParticle = *PartIter2;
243  MinusBuffer[bufferIndex].push_back(pParticle->FourMomentum() ) ;
244  }
245  int newMinusSize = MinusBuffer[bufferIndex].size();
246  if (newMinusSize == 0){cout << " 0 tracks copied to buffer for particle 2!!!"<< endl ;}
247 
248  // DONE COPYING PICO-EVENT
249 
250  // CALCULATE the RXN PLANE here-in future we may can just use Flow Maker (?)
251 
252  StHbtThreeVector RxnPlaneVec;
253  {for (int iii = 0;iii<newPlusSize;iii++){
254  if (PlusBuffer[bufferIndex][iii].z() > 0 ) RxnPlaneVec += PlusBuffer[bufferIndex][iii].vect();
255  if (PlusBuffer[bufferIndex][iii].z() < 0 ) RxnPlaneVec -= PlusBuffer[bufferIndex][iii].vect();
256  }}
257  {for (int iii = 0;iii<newMinusSize;iii++){
258  if (MinusBuffer[bufferIndex][iii].z() > 0 ) RxnPlaneVec += MinusBuffer[bufferIndex][iii].vect();
259  if (MinusBuffer[bufferIndex][iii].z() < 0 ) RxnPlaneVec -= MinusBuffer[bufferIndex][iii].vect();
260  }}
261  RxnPlaneVec.setZ(0);
262  double phi_rxn_plane = acos(RxnPlaneVec.x()/RxnPlaneVec.mag());
263  if (RxnPlaneVec.y() < 0) phi_rxn_plane = -phi_rxn_plane;
264 
265  // now rotate rxn plane to be at x-axis
266  //this could be combined with some other loop but for now we'll leave it here for simplicity
267  StHbtThreeVector tempVct; // unfortunately for now need to use this to satisfy
268  // compiler (to avoid rotating const vector)
269  {for (int iii = 0;iii<newPlusSize;iii++){
270  // PlusBuffer[bufferIndex][iii].vect().rotateZ(-phi_rxn_plane);
271  tempVct = PlusBuffer[bufferIndex][iii].vect();
272  tempVct.rotateZ(-phi_rxn_plane);
273  (PlusBuffer[bufferIndex][iii]).setX(tempVct.x());
274  (PlusBuffer[bufferIndex][iii]).setY(tempVct.y());
275 
276  }}
277  {for (int iii = 0;iii<newMinusSize;iii++){
278  // MinusBuffer[bufferIndex][iii].vect().rotateZ(-phi_rxn_plane);
279  tempVct = MinusBuffer[bufferIndex][iii].vect();
280  tempVct.rotateZ(-phi_rxn_plane);
281  (MinusBuffer[bufferIndex][iii]).setX(tempVct.x());
282  (MinusBuffer[bufferIndex][iii]).setY(tempVct.y());
283 
284  }}
285  // DONE w/ RXN PLANE calculation
286 
287  // now RANDOMIZE the BUFFERS (should in the future rotate the rxn plane here as well)
288 
289  {for (int iii = 0;iii<2;iii++){ // do 2 shuffles
290  for (int iii = 0;iii<newPlusSize;iii++){
291  int switchto = (rand() % newPlusSize);
292  StHbtLorentzVector tempVec = PlusBuffer[bufferIndex][iii];
293  PlusBuffer[bufferIndex][iii] = PlusBuffer[bufferIndex][switchto];
294  PlusBuffer[bufferIndex][switchto] = tempVec;
295  }
296  }}
297 
298  {for (int iii = 0;iii<2;iii++){ // do 2 shuffles
299  for (int iii = 0;iii<newMinusSize;iii++){
300  int switchto = (rand() % newMinusSize);
301  StHbtLorentzVector tempVec = MinusBuffer[bufferIndex][iii];
302  MinusBuffer[bufferIndex][iii] = MinusBuffer[bufferIndex][switchto];
303  MinusBuffer[bufferIndex][switchto] = tempVec;
304  }
305  }}
306  // END OF RANDOMIZING TRACK ORDER
307 
308  // COPY latest EVENT to PlusSame and MinusSame vectors
309  PlusSame.clear();
310  MinusSame.clear();
311  {for (int jjj = 0; jjj < newPlusSize; jjj++){
312  PlusSame.push_back(PlusBuffer[bufferIndex][jjj]);
313  }}
314  {for (int jjj = 0; jjj < newMinusSize; jjj++){
315  MinusSame.push_back(MinusBuffer[bufferIndex][jjj]);
316  }}
317  // END of COPYing latest event
318 
319  // NOW BUILD A MIXED EVENT in the PlusMixed and MinusMixed vectors;
320 
321  if (nEvent >= BUFFERSIZ ) { // to ensure multiplicity dist is same for SAME and MIXED, don't go
322  // any further unless buffer is full
323  PlusMixed.clear();
324  MinusMixed.clear();
325 
326  if (nEvent >= BUFFERSIZ ) {
327  StHbtLorentzVector vTemp;
328  int mixedenum;
329  int mixedtnum;
330 
331  // take the newest buffered event and mix it with other events
332  {for (int jjj = 0; jjj < newPlusSize; jjj++){
333  mixedenum = (rand() % BUFFERSIZ);
334  mixedtnum = (rand() % PlusBuffer[mixedenum].size());
335  vTemp = PlusBuffer[mixedenum][mixedtnum];
336  PlusBuffer[mixedenum][mixedtnum] = PlusBuffer[bufferIndex][jjj];
337  PlusBuffer[bufferIndex][jjj] = vTemp;
338  }}
339  {for (int jjj = 0; jjj < newMinusSize; jjj++){
340  mixedenum = (rand() % BUFFERSIZ);
341  mixedtnum = (rand() % MinusBuffer[mixedenum].size());
342  vTemp = MinusBuffer[mixedenum][mixedtnum];
343  MinusBuffer[mixedenum][mixedtnum] = MinusBuffer[bufferIndex][jjj];
344  MinusBuffer[bufferIndex][jjj] = vTemp;
345  }}
346  // now that the newest buffer is randomized, copy it to mixed event
347 
348  {for (int jjj = 0; jjj < newPlusSize; jjj++){
349  PlusMixed.push_back(PlusBuffer[bufferIndex][jjj]);
350  }}
351  {for (int jjj = 0; jjj < newMinusSize; jjj++){
352  MinusMixed.push_back(MinusBuffer[bufferIndex][jjj]);
353  }}
354  }
355  // END OF BUILDING MIXED EVENT
356 
357  // NOW 'PAIR' CUTS
358 
359  mPairCut->ParityPairCuts(&PlusSame, &MinusSame);
360  if (nEvent >= BUFFERSIZ ) {
361  mPairCut->ParityPairCuts(&PlusMixed, &MinusMixed);
362  }
363 
364  // now force the final multiplicities to be the same by removing tracks from SAME or MIXED event
365  //( whichever has more)...
366 
367  if (nEvent >= BUFFERSIZ ) {
368  int eraseMe;
369  while (PlusMixed.size() > PlusSame.size()){
370  eraseMe = (rand() % PlusMixed.size());
371  PlusMixed.erase(PlusMixed.begin()+eraseMe);
372  }
373  while (MinusMixed.size() > MinusSame.size() ){
374  eraseMe = (rand() % MinusMixed.size());
375  MinusMixed.erase(MinusMixed.begin()+eraseMe);
376  }
377  while (PlusSame.size() > PlusMixed.size()){
378  eraseMe = (rand() % PlusSame.size());
379  PlusSame.erase(PlusSame.begin()+eraseMe);
380  }
381  while (MinusSame.size() > MinusMixed.size() ){
382  eraseMe = (rand() % MinusSame.size());
383  MinusSame.erase(MinusSame.begin()+eraseMe);
384  }
385  }
386  cout << " sizes:plussame minussame plusmixed minusmixed" << PlusSame.size()<< ","
387  <<MinusSame.size()<< ","
388  <<PlusMixed.size()<< ","
389  <<MinusMixed.size()<< endl ;
390 
391  // NOW WE HAVE the FINAL 'SAME' and 'MIXED' EVENTS, let's DO PARITY CALCULATIONS
392  // loop through the correlation functions
393 
394  StHbtCorrFctnIterator CorrFctnIter;
395  for (CorrFctnIter=mCorrFctnCollection->begin();CorrFctnIter!=mCorrFctnCollection->end();CorrFctnIter++){
396  StHbtCorrFctn* CorrFctn = *CorrFctnIter;
397  CorrFctn->ParityCompute(&PlusSame, &MinusSame, SAME );
398  if (nEvent >= BUFFERSIZ ) {
399  CorrFctn->ParityCompute(&PlusMixed, &MinusMixed, MIXED );
400  }
401 
402  }
403 
404  }
405  // END of PARITY CALCULATIONS
406 
407  delete picoEvent ;
408 
409  } // if currentEvent is accepted by currentAnalysis
410  EventEnd(hbtEvent); // cleanup for EbyE
411  cout << "StParityAnalysis::ProcessEvent() - return to caller ... " << endl;
412 }
413 //_________________________
414 void StParityAnalysis::EventBegin(const StHbtEvent* ev){
415  mFirstParticleCut->EventBegin(ev);
416  mSecondParticleCut->EventBegin(ev);
417  // mPairCut->EventBegin(ev);
418  for (StHbtCorrFctnIterator iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
419  (*iter)->EventBegin(ev);
420  }
421 }
422 //_________________________
423 void StParityAnalysis::EventEnd(const StHbtEvent* ev){
424  mFirstParticleCut->EventEnd(ev);
425  mSecondParticleCut->EventEnd(ev);
426  // mPairCut->EventEnd(ev);
427  for (StHbtCorrFctnIterator iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
428  (*iter)->EventEnd(ev);
429  }
430 }
431 //_________________________
432 void StParityAnalysis::Finish(){
433  StHbtCorrFctnIterator iter;
434  for (iter=mCorrFctnCollection->begin(); iter!=mCorrFctnCollection->end();iter++){
435  (*iter)->Finish();
436  }
437 }
438 //_________________________
439 void StParityAnalysis::AddEventProcessed() {
440  mNeventsProcessed++;
441 }
virtual void ProcessEvent(const StHbtEvent *)
returns reports of all cuts applied and correlation functions being done