ROOTPWA
NParticleEvent.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------
2 // Description:
3 // Implementation of class NParticleEvent
4 // see NParticleEvent.h for details
5 //
6 // Environment:
7 // Software developed for the COMPASS experiment at CERN.
8 //
9 // Author List:
10 // Sebastian Neubert TUM (original author)
11 //
12 //
13 //-----------------------------------------------------------
14 
15 // This Class' Header ------------------
16 #include "NParticleEvent.h"
17 
18 // C/C++ Headers ----------------------
19 #include "TVector3.h"
20 #include <iomanip>
21 #include <iostream>
22 
23 using namespace std;
24 
25 // Collaborating Class Headers --------
26 #include "FSParticle.h"
27 
28 // Class Member definitions -----------
29 NParticleEvent::NParticleEvent(TClonesArray* fs_momenta,
30  std::vector<int>* fs_charges,
31  TLorentzVector* beam,
32  int* beam_charge,
33  TVector3* vertex)
34  : _fsmomenta(fs_momenta), _fs_charges(fs_charges),
35  _beam(beam),_pbeam(*beam),_qbeam(beam_charge),_vertex(vertex)
36 {}
37 
38 
39 
40 void
42  // clear
43  if(doBuild)_NPStates.clear();
44  if(doBuild)_fsparticles.clear();
45 
46  // build FSParticles
47  unsigned int nfs=_fsmomenta->GetEntries();
48  if(doBuild)_fsparticles.resize(nfs);
49  for(unsigned int ifs=0;ifs<nfs;++ifs){
50  _fsparticles[ifs]=(FSParticle(*(TLorentzVector*)_fsmomenta->At(ifs),
51  *_vertex,
52  _fs_charges->at(ifs)));
53 
54  }
55  _pbeam=*_beam;
56  if(doBuild)build();
57 }
58 
59 
60 TLorentzVector
62  TLorentzVector result;
63  unsigned int npart=_fsparticles.size();
64  for(unsigned int i=0;i<npart;++i){
65  result+=_fsparticles[i].p();
66  }
67  return result;
68 }
69 
70 
71 double
73  TLorentzVector beam=*_beam;
74  TLorentzVector p=this->p();
75  // recalibrate beam -- assumes exclusivity!
76  TVector3 dir=beam.Vect();
77  double const mpi=beam.M();// 0.13957; not always a pion!
78  double k=sqrt(p.E()*p.E()-mpi*mpi)/dir.Mag();
79  dir*=k;
80  beam.SetVectM(dir,mpi);
81  return -(beam-p).M2();
82 }
83 
84 
85 
86 TLorentzVector
87 NParticleEvent::getHelicityFrame(TLorentzVector pMother, TLorentzVector pX, TLorentzVector p1){
88 
89  TLorentzVector tempX=pX;
90  TLorentzVector p2=pX-p1;
91 
92  // cerr << "Going to Helicityframe ------------- " << endl;
93  // pMother.Vect().Print();
94  // pX.Vect().Print();
95  // p1.Vect().Print();
96  // p2.Vect().Print();
97 
98  // rotate event into production plane of X
99  // get normal vector
100  TVector3 y(0,1,0);
101  TVector3 N=pMother.Vect().Cross(tempX.Vect());
102  TVector3 rot=N.Cross(y);
103  TRotation t;
104  double a=N.Angle(y);
105  t.Rotate(a,rot);
106  //t.SetXEulerAngles(N.Phi(),N.Theta()-TMath::Pi()*0.5,-TMath::Pi()*0.5);
107  TLorentzRotation T(t);
108  TLorentzRotation L1(T);
109  tempX*=T;
110  p1*=T;
111  p2*=T;
112  // cerr << "After rotation into xz-plane" << endl;
113  // tempX.Vect().Print();
114  // p1.Vect().Print();
115  // p2.Vect().Print();
116 
117  // put X along z-axis
118  TVector3 Xdir=tempX.Vect();
119  //std::cout<<"beamDir before rotation:";beamdir.Print();
120  a=Xdir.Angle(TVector3(0,0,1));
121  //std::cout<<"angle="<<a<<std::endl;
122  TRotation t2;
123  t2.Rotate(-a,TVector3(0,1,0));
124  T=TLorentzRotation(t2);
125  tempX*=T;
126  p1*=T;
127  p2*=T;
128 
129  // cerr << "After rotation to z-axis" << endl;
130  // tempX.Vect().Print();
131  // p1.Vect().Print();
132  // p2.Vect().Print();
133 
134 
135  // boost to X rest frame
136  TVector3 boost=-tempX.BoostVector();
137  TLorentzRotation b;
138  b.Boost(boost);
139  tempX*=b;
140  //tempX.Vect().Print();
141  p1*=b;
142  p2*=b;
143 
144  // cerr << "After Boost:" << endl;
145  // tempX.Vect().Print();
146  // p1.Vect().Print();
147  // p2.Vect().Print();
148 
149  return p1;
150 }
151 
152 
153 void
155  TLorentzVector tempX=p();
156  // rotate event into scattering plane
157  // get normal vector
158  TVector3 y(0,1,0);
159  TVector3 N=_pbeam.Vect().Cross(tempX.Vect());
160  TVector3 rot=N.Cross(y);
161  TRotation t;
162  double a=N.Angle(y);
163  t.Rotate(a,rot);
164  //t.SetXEulerAngles(N.Phi(),N.Theta()-TMath::Pi()*0.5,-TMath::Pi()*0.5);
165  TLorentzRotation T(t);
166  TLorentzRotation L1(T);
167  tempX*=T;
168  //tempX.Vect().Print();
169  _pbeam.Transform(T);
170  //_beamPi.p().Vect().Print();
171 
172  // boost to X rest frame
173  TVector3 boost=-tempX.BoostVector();
174  TLorentzRotation b;
175  b.Boost(boost);
176  tempX*=b;
177  //tempX.Vect().Print();
178  _pbeam.Transform(b);
179 
180  // put beam along z-axis
181  TVector3 beamdir=_pbeam.Vect();
182  //std::cout<<"beamDir before rotation:";beamdir.Print();
183  a=beamdir.Angle(TVector3(0,0,1));
184  //std::cout<<"angle="<<a<<std::endl;
185  TRotation t2;
186  t2.Rotate(a,TVector3(0,1,0));
187  T=TLorentzRotation(t2);
188  _pbeam.Transform(T);
189 
190  //cerr << "******* Beam in GJ frame: **********" << endl;
191  //_pbeam.Vect().Print();
192 
193  // transform pions
194  unsigned int npart=_fsparticles.size();
195  for(unsigned int i=0; i<npart; ++i){
196  getParticle(i).Transform(L1);
197  getParticle(i).Transform(b);
198  getParticle(i).Transform(T);
199  }
200 
201  // check basic things:
202  //TLorentzVector p2=p();
203  //std::cout<<"In GJ-Frame: P=("<<p2.Px()
204  // <<","<<p2.Py()<<","<<p2.Pz()<<","<<p2.E()<<std::endl;
205  //std::cout<<"In GJ-Frame: Ptemp=("<<tempX.Px()
206  // <<","<<tempX.Py()<<","<<tempX.Pz()<<","<<tempX.E()<<std::endl;
207  //std::cout<<"Beam direction:";
208  //_beamPi.p().Vect().Print();
209 
210  // we need to rebuild if the event was build before...
211 
212 }
213 
214 
215 
216 unsigned int
218  // clear previous builds
219  _NPStates.clear();
220  // build n-particle state
221  unsigned int n=_fsparticles.size();
222  //std::cout<<n<<" pions in event"<<std::endl;
223  for(unsigned int np=1;np<=n;++np){// np = number of particles in (sub)state
224  // select np particless
225  int* permu=new int[np];
226  NParticleEvent::permute(n,np,permu);
227  delete[] permu;
228  } // end loop npi
229  return _NPStates.size();
230 }
231 
232 
233 // Recursive method to find all permutations of final state particles
234 void
235 NParticleEvent::permute(int n, int k, int* permu, int x, int i){
236  // computes all (k out of n) combinations of pions
237  // start values: x=-1 i=1;
238  if(i>k)return;
239  for(int y=x+1;y<n-k+i;++y){
240  permu[i-1]=y;
241  NParticleEvent::permute(n,k,permu,y,i+1);
242  if(i==k){
243  NParticleState s;
244  s.setBeam(_pbeam);
245  // add particles to state
246  bool ok=true;
247  for(int j=0;j<k;++j){
248  //std::cout<<"x["<<j<<"]="<<permu[j]<<" ";
249  FSParticle* part=&(_fsparticles.at(permu[j]));
250  if(!s.addParticle(part)){// returns false if pion cannot
251  //be added because doubel counting
252  ok=false;
253  break;
254  }
255  } // end loop over particles;
256  if(ok)_NPStates.push_back(s);
257  } // end if(i==k)
258  } // end loop over remaining states
259 }
260 
261 void
263  // number of particles
264  out<<nParticles()+1<<std::endl;
265  int geantId=9;
266  // beam:
267  TLorentzVector p=*_beam;
268  int q=*_qbeam>0 ? +1 : -1;
269  out << geantId <<" "
270  <<q<<" "<< std::setprecision(9)
271  <<p.X()<<" " // px
272  <<p.Y()<<" " // py
273  <<p.Z()<<" " // pz
274  <<p.E()<<std::endl; // E
275 
276  // pions:
277  for(unsigned int i=0;i<nParticles();++i){
279  p=pi.p();
280  q=pi.q()>0 ? +1 : -1;
281  geantId= q>0 ? 8 : 9;
282  out << geantId <<" "
283  <<q<<" "
284  <<p.X()<<" " // px
285  <<p.Y()<<" " // py
286  <<p.Z()<<" " // pz
287  <<p.E()<<std::endl; // E
288  }
289 }