1 ///////////////////////////////////////////////////////////////////////////
5 // This file is part of starlight.
7 // starlight is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
12 // starlight is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with starlight. If not, see <http://www.gnu.org/licenses/>.
20 ///////////////////////////////////////////////////////////////////////////
22 // File and Version Information:
23 // $Rev:: $: revision of last commit
24 // $Author:: $: author of last commit
25 // $Date:: $: date of last commit
31 ///////////////////////////////////////////////////////////////////////////
39 #include "starlightconstants.h"
40 #include "gammagammasingle.h"
41 #include "starlightconfig.h"
46 //______________________________________________________________________________
47 Gammagammasingle::Gammagammasingle(beamBeamSystem& bbsystem)
48 : eventChannel(bbsystem)
58 //Storing inputparameters into protected members for use
59 _GGsingInputnumw=inputParametersInstance.nmbWBins();
60 _GGsingInputnumy=inputParametersInstance.nmbRapidityBins();
61 _GGsingInputpidtest=inputParametersInstance.prodParticleType();
62 _GGsingInputGamma_em=inputParametersInstance.beamLorentzGamma();
63 cout<<"SINGLE MESON pid test: "<<_GGsingInputpidtest<<endl;
64 //reading in luminosity tables
66 //Now calculating crosssection
71 //______________________________________________________________________________
72 Gammagammasingle::~Gammagammasingle()
76 //______________________________________________________________________________
77 void Gammagammasingle::singleCrossSection()
79 //This function carries out a delta function cross-section calculation. For reference, see STAR Note 243, Eq. 8
80 //Multiply all _Farray[] by _f_max
81 double _sigmaSum=0.,remainw=0.;//_remainwd=0.;
82 int ivalw =0;//_ivalwd;
83 //calculate the differential cross section and place in the sigma table
85 for(int i=0;i<_GGsingInputnumw;i++){
86 for(int j=0;j<_GGsingInputnumy;j++){
87 // Eq. 1 of starnote 347
88 _sigmax[i][j]=(getSpin()*2.+1.)*4*starlightConstants::pi*starlightConstants::pi*getWidth()/
89 (getMass()*getMass()*getMass())*_f_max*_Farray[i][j]*starlightConstants::hbarc*starlightConstants::hbarc/100.;
92 //find the index, i,for the value of w just less than the mass because we want to use the value from the sigma table that has w=mass
94 for(int i=0;i<_GGsingInputnumw;i++){
95 if(getMass()>_Warray[i]) ivalw=i;
98 remainw = (getMass()-_Warray[ivalw])/(_Warray[ivalw+1]-_Warray[ivalw+1]-_Warray[ivalw]);
101 //if we are interested rho pairs at threshold, the just set sigma to 100nb
102 switch(_GGsingInputpidtest){
103 case starlightConstants::ZOVERZ03:
105 for(int j=0;j<_GGsingInputnumy-1;j++){
106 _sigmaSum = _sigmaSum +(_Yarray[j+1]-_Yarray[j])*
107 100.0E-9*(.1/getMass())*((1.-remainw)*_f_max*
108 (_Farray[ivalw][j]+_Farray[ivalw][j])/2.+remainw*_f_max*
109 (_Farray[ivalw+1][j]+_Farray[ivalw+1][j+1])/2.);
113 //Sum to find the total cross-section
115 for(int j =0;j<_GGsingInputnumy-1;j++){
116 _sigmaSum = _sigmaSum+
117 (_Yarray[j+1]-_Yarray[j])*((1.-remainw)*
118 (_sigmax[ivalw][j]+_sigmax[ivalw][j+1])/2.+remainw*
119 (_sigmax[ivalw+1][j]+_sigmax[ivalw+1][j+1])/2.);
122 if(_sigmaSum > 0.1) cout <<"The total cross-section is: "<<_sigmaSum<<" barns."<<endl;
123 else if(_sigmaSum > 0.0001)cout <<"The total cross-section is: "<<_sigmaSum*1000<<" mb."<<endl;
124 else cout <<"The total cross-section is: "<<_sigmaSum*1000000<<" ub."<<endl;
131 //______________________________________________________________________________
132 void Gammagammasingle::pickw(double &w)
134 //This function picks a w for the 2-photon calculation.
135 double sgf=0.,signorm=0.,x=0.,remainarea=0.,remainw=0.,a=0.,b=0.,c=0.;
140 _sigofw = new double[starlightLimits::MAXWBINS];
141 sgfint = new double[starlightLimits::MAXYBINS];
149 //deal with the case where sigma is an array
150 //_sigofw is simga integrated over y using a linear interpolation
151 //sigint is the integral of sgfint, normalized
153 //integrate sigma down to a function of just w
154 for(int i=0;i<_GGsingInputnumw;i++){
156 for(int j=0;j<_GGsingInputnumy-1;j++){
157 _sigofw[i] = _sigofw[i]+(_Yarray[j+1]-_Yarray[j])*(_sigmax[i][j+1]+_sigmax[i][j])/2.;
160 //calculate the unnormalized sgfint array
162 for(int i=0;i<_GGsingInputnumw-1;i++){
163 sgf=(_sigofw[i+1]+_sigofw[i])*(_Warray[i+1]-_Warray[i])/2.;
164 sgfint[i+1]=sgfint[i]+sgf;
166 //normalize sgfint array
167 signorm=sgfint[_GGsingInputnumw-1];
169 for(int i=0;i<_GGsingInputnumw;i++){
170 sgfint[i]=sgfint[i]/signorm;
172 //pick a random number
173 x = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
174 //compare x and sgfint to find the ivalue which is just less than the random number x
175 for(int i=0;i<_GGsingInputnumw;i++){
176 if(x > sgfint[i]) ivalw=i;
178 //remainder above ivalw
179 remainarea = x - sgfint[ivalw];
181 //figure out what point corresponds to the excess area in remainarea
182 c = -remainarea*signorm/(_Warray[ivalw+1]-_Warray[ivalw]);
184 a = (_sigofw[ivalw+1]-_sigofw[ivalw])/2.;
189 remainw = (-b+sqrt(b*b-4.*a*c))/(2.*a);
193 //calculate the w value
194 w = _Warray[ivalw]+(_Warray[ivalw+1]-_Warray[ivalw])*remainw;
202 //______________________________________________________________________________
203 void Gammagammasingle::picky(double &y)
207 sigofy = new double[starlightLimits::MAXYBINS];
208 sgfint = new double[starlightLimits::MAXYBINS];
210 double remainw =0.,remainarea=0.,remainy=0.,a=0.,b=0.,c=0.,sgf=0.,signorm=0.,x=0.;
215 //average over two colums to get y array
216 for(int j=0;j<_GGsingInputnumy;j++){
217 sigofy[j]=_sigmax[ivalw][j]+(_sigmax[ivalw+1][j]-_sigmax[ivalw][j])*remainw;
219 //calculate the unnormalized sgfint
222 for(int j=0;j<_GGsingInputnumy-1;j++){
223 sgf = (sigofy[j+1]+sigofy[j])/2.;
224 sgfint[j+1]=sgfint[j]+sgf*(_Yarray[j+1]-_Yarray[j]);
227 //normalize the sgfint array
228 signorm = sgfint[_GGsingInputnumy-1];
230 for(int j=0;j<_GGsingInputnumy;j++){
231 sgfint[j]=sgfint[j]/signorm;
233 //pick a random number
234 x = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
235 //compare x and sgfint to find the ivalue which is just less then the random number x
236 for(int i=0;i<_GGsingInputnumy;i++){
240 //remainder above ivaly
241 remainarea = x - sgfint[ivaly];
242 //figure what point corresponds to the leftover area in remainarea
243 c = -remainarea*signorm/(_Yarray[ivaly+1]-_Yarray[ivaly]);
245 a = (sigofy[ivaly+1]-sigofy[ivaly])/2.;
250 remainy = (-b + sqrt(b*b-4.*a*c))/(2.*a);
252 //calculate the y value
253 y = _Yarray[ivaly]+(_Yarray[ivaly+1]-_Yarray[ivaly])*remainy;
259 //______________________________________________________________________________
260 void Gammagammasingle::parentMomentum(double w,double y,double &E,double &px,double &py,double &pz)
262 //this function calculates px,py,pz,and E given w and y
263 double anglepp1=0.,anglepp2=0.,pp1=0.,pp2=0.,E1=0.,E2=0.,signpx=0.,pt=0.;
265 //E1 and E2 are for the 2 photons in the CM frame
269 //calculate px and py
270 //to get x and y components-- phi is random between 0 and 2*pi
271 anglepp1 = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
272 anglepp2 = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
276 px = pp1*cos(2.*starlightConstants::pi*anglepp1)+pp2*cos(2.*starlightConstants::pi*anglepp2);
277 py = pp1*sin(2.*starlightConstants::pi*anglepp1)+pp2*sin(2.*starlightConstants::pi*anglepp2);
278 //Compute vector sum Pt=Pt1+Pt2 to find pt for the produced particle
279 pt = sqrt(px*px+py*py);
280 //W is the mass of the produced particle (not necessarily on-mass-shell).Now compute its energy and pz
281 E = sqrt(w*w+pt*pt)*cosh(y);
282 pz= sqrt(w*w+pt*pt)*sinh(y);
283 signpx = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
284 //pick the z direction
290 //______________________________________________________________________________
291 double Gammagammasingle::pp(double E)
293 // will probably have to pass in beambeamsys? that way we can do beam1.formFactor(t) or beam2..., careful with the way sergey did it for asymmetry
294 // returns on random draw from pp(E) distribution
296 double ereds =0.,Cm=0.,Coef=0.,x=0.,pp=0.,test=0.,u=0.;
297 double singleformfactorCm=0.,singleformfactorpp1=0.,singleformfactorpp2=0.;
300 ereds = (E/_GGsingInputGamma_em)*(E/_GGsingInputGamma_em);
301 Cm = sqrt(3.)*E/_GGsingInputGamma_em;
302 //the amplitude of the p_t spectrum at the maximum
303 singleformfactorCm=_bbs.beam1().formFactor(Cm*Cm+ereds);
304 //Doing this once and then storing it as a double, which we square later...SYMMETRY?using beam1 for now.
305 Coef = 3.0*(singleformfactorCm*singleformfactorCm*Cm*Cm*Cm)/((2.*(starlightConstants::pi)*(ereds+Cm*Cm))*(2.*(starlightConstants::pi)*(ereds+Cm*Cm)));
307 //pick a test value pp, and find the amplitude there
308 x = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
309 pp = x*5.*starlightConstants::hbarc/_bbs.beam1().nuclearRadius(); //Will use nucleus #1, there should be two for symmetry//nextline
310 singleformfactorpp1=_bbs.beam1().formFactor(pp*pp+ereds);
311 test = (singleformfactorpp1*singleformfactorpp1)*pp*pp*pp/((2.*starlightConstants::pi*(ereds+pp*pp))*(2.*starlightConstants::pi*(ereds+pp*pp)));
314 u = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
319 x =randyInstance.Rndom();//random()/(RAND_MAX+1.0);
320 pp = 5*starlightConstants::hbarc/_bbs.beam1().nuclearRadius()*x;
321 singleformfactorpp2=_bbs.beam1().formFactor(pp*pp+ereds);//Symmetry
322 test = (singleformfactorpp2*singleformfactorpp2)*pp*pp*pp/(2.*starlightConstants::pi*(ereds+pp*pp)*2.*starlightConstants::pi*(ereds+pp*pp));
329 //______________________________________________________________________________
330 void Gammagammasingle::twoBodyDecay(starlightConstants::particleTypeEnum &ipid,double /*E*/,double W,double px0,double py0,double pz0,double &px1,double &py1,double &pz1,double &px2,double &py2,double &pz2,int &iFbadevent)
332 // This routine decays a particle into two particles of mass mdec,
333 // taking spin into account
335 double mdec=0.,E1=0.,E2=0.;
336 double pmag,ytest=0.;
337 double phi,theta,xtest,dndtheta,Ecm;
338 double betax,betay,betaz;
340 // set the mass of the daughter particles
341 switch(_GGsingInputpidtest){
342 case starlightConstants::ZOVERZ03:
343 case starlightConstants::F2:
344 mdec = starlightConstants::pionChargedMass;
346 case starlightConstants::F2PRIME:
347 // decays 50% to K+/K-, 50% to K_0's
348 ytest = randyInstance.Rndom();
350 mdec = starlightConstants::kaonChargedMass;
357 cout<<"No default mass selected for single photon-photon particle, expect errant results"<<endl;
360 //Calculating the momentum's magnitude
361 //add switch for rho pairs at threshold and everything else.
362 switch(_GGsingInputpidtest){
363 case starlightConstants::ZOVERZ03: //the rho pairs produced at threshold
364 pmag = sqrt(getMass()*getMass()/4. - mdec*mdec);
368 cout<<" ERROR: W="<<W<<endl;
372 pmag = sqrt(W*W/4. - mdec*mdec);
374 // pick an orientation, based on the spin
375 // phi has a flat distribution in 2*pi
376 phi = randyInstance.Rndom()*2.*starlightConstants::pi; //(random()/(RAND_MAX+1.0))* 2.*starlightConstants::pi;
378 // find theta, the angle between one of the outgoing particles and
379 // the beamline, in the frame of the two photons
380 //this will depend on spin, F2,F2' and z/z03 all have spin 2, all other photonphoton-single mesons are handled by jetset
381 //Applies to spin2 mesons.
383 theta = starlightConstants::pi*randyInstance.Rndom();
384 xtest = randyInstance.Rndom();
385 dndtheta = sin(theta)*sin(theta)*sin(theta)*sin(theta)*sin(theta);
389 // compute unboosted momenta
390 px1 = sin(theta)*cos(phi)*pmag;
391 py1 = sin(theta)*sin(phi)*pmag;
392 pz1 = cos(theta)*pmag;
397 //Changed mass to W 11/9/2000 SRK
398 Ecm = sqrt(W*W+px0*px0+py0*py0+pz0*pz0);
399 E1 = sqrt(mdec*mdec+px1*px1+py1*py1+pz1*pz1);
400 E2 = sqrt(mdec*mdec+px2*px2+py2*py2+pz2*pz2);
402 // Lorentz transform into the lab frame
403 // betax,betay,betaz are the boost of the complete system
408 transform (betax,betay,betaz,E1,px1,py1,pz1,iFbadevent);
409 transform (betax,betay,betaz,E2,px2,py2,pz2,iFbadevent);
415 // change particle id from that of parent to that of daughters
417 switch(_GGsingInputpidtest){
418 //These decay into a pi+ pi- pair
419 case starlightConstants::ZOVERZ03:
420 case starlightConstants::F2:
421 ipid=starlightConstants::PION;
423 case starlightConstants::F2PRIME:
426 //Decays 50/50 into k+ k- or k_s k_l
427 ipid=starlightConstants::KAONCHARGE;
431 ipid=starlightConstants::KAONNEUTRAL;
435 cout<<"Rethink the daughter particles"<<endl;
440 //______________________________________________________________________________
441 starlightConstants::event Gammagammasingle::produceEvent(int &/*ievent*/)
443 // Not in use anymore, default event struct returned
444 return starlightConstants::event();
448 //______________________________________________________________________________
449 // fix it ... lost functionality
450 //starlightConstants::event Gammagammasingle::produceEvent(int &ievent)
451 upcEvent Gammagammasingle::produceEvent()
453 // cout << "NOT IMPLEMENTED!" << endl;
455 // return upcEvent();
457 // returns the vector with the decay particles inside.
458 // onedecayparticle single;
459 starlightConstants::event single;
460 double comenergy = 0.;
461 double rapidity = 0.;
463 double parentmomx=0.,parentmomy=0.,parentmomz=0.;
465 //this function decays particles and writes events to a file
466 //zeroing out the event structure
467 single._numberOfTracks=0;
468 for(int i=0;i<4;i++){
472 single._fsParticle[i]=starlightConstants::UNKNOWN;
478 parentMomentum(comenergy,rapidity,parentE,parentmomx,parentmomy,parentmomz);
481 if(_GGsingInputpidtest != starlightConstants::F2 && _GGsingInputpidtest != starlightConstants::F2PRIME)
484 starlightParticle particle(parentmomx,parentmomy,parentmomz, parentE, getMass(),_GGsingInputpidtest , 0);
486 _pyDecayer.addParticle(particle);
488 return _pyDecayer.execute();
495 starlightConstants::particleTypeEnum ipid = starlightConstants::UNKNOWN;
496 double px2=0.,px1=0.,py2=0.,py1=0.,pz2=0.,pz1=0.;
497 double px3=0.,px4=0.,py3=0.,py4=0.,pz3=0.,pz4=0.;
498 // double theta=0.,phi=0.;//angles from jetset
499 double xtest=0.,ztest=0.;
500 switch(_GGsingInputpidtest){
501 case starlightConstants::ZOVERZ03:
502 //Decays into two pairs.
503 parentmomx=parentmomx/2.;
504 parentmomy=parentmomy/2.;
505 parentmomz=parentmomz/2.;
507 twoBodyDecay(ipid,parentE,comenergy,parentmomx,parentmomy,parentmomz,px1,py1,pz1,px2,py2,pz2,iFbadevent);
509 twoBodyDecay(ipid,parentE,comenergy,parentmomx,parentmomy,parentmomz,px3,py3,pz3,px4,py4,pz4,iFbadevent);
510 //Now add them to vectors to be written out later.
512 single._numberOfTracks=4;//number of tracks per event
514 xtest = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
515 ztest = randyInstance.Rndom();
516 //Assigning charges randomly.
518 single._charge[0]=1;//q1=1;
519 single._charge[1]=-1;//q2=-1;
522 single._charge[0]=1;//q1=-1;
523 single._charge[1]=-1;//q2=1;
526 single._charge[2]=1;//q3=1;
527 single._charge[3]=-1;//q4=-1;
530 single._charge[2]=-1;//q3=-1;
531 single._charge[3]=1;//q4=1;
537 single._fsParticle[0]=ipid;
542 single._fsParticle[1]=ipid;
547 single._fsParticle[2]=ipid;
552 single._fsParticle[3]=ipid;
558 case starlightConstants::F2:
559 case starlightConstants::F2PRIME:
560 twoBodyDecay(ipid,parentE,comenergy,parentmomx,parentmomy,parentmomz,px1,py1,pz1,px2,py2,pz2,iFbadevent);
562 single._numberOfTracks=2;
564 xtest = randyInstance.Rndom();//random()/(RAND_MAX+1.0);
566 single._charge[0]=1;//q1=1;
567 single._charge[1]=-1;//q2=-1;
570 single._charge[0]=-1;//q1=-1;
571 single._charge[1]=1;//q2=1;
577 single._fsParticle[0]=ipid*single._charge[0];
582 single._fsParticle[1]=ipid*single._charge[1];
590 return upcEvent(single);
594 //______________________________________________________________________________
595 void Gammagammasingle::thephi(double W,double px,double py,double pz,double E,double &theta,double &phi)
597 // This subroutine calculates angles for channels decayed by jetset.
598 // subroutine thephi(W,px,py,pz,E,theta,phi)
599 E = sqrt (W*W+px*px+py*py+pz*pz);
601 theta = acos(pz/sqrt(px*px+py*py+pz*pz));
602 phi = acos(px/sqrt(px*px+py*py));
604 if ((px == 0) && (py == 0))
607 phi = 2*starlightConstants::pi - phi;
611 //______________________________________________________________________________
612 double Gammagammasingle::getMass()
614 using namespace starlightConstants;
615 double singlemass=0.;
616 switch(_GGsingInputpidtest){
617 case starlightConstants::ETA:
620 case starlightConstants::ETAPRIME:
621 singlemass=etaPrimeMass;
623 case starlightConstants::ETAC:
626 case starlightConstants::F0:
629 case starlightConstants::F2:
632 case starlightConstants::A2:
635 case starlightConstants::F2PRIME:
636 singlemass=f2PrimeMass;
638 case starlightConstants::ZOVERZ03:
642 cout<<"Not a recognized single particle, Gammagammasingle::getmass(), mass = 0."<<endl;
648 //______________________________________________________________________________
649 double Gammagammasingle::getWidth()
651 double singlewidth=0.;
652 switch(_GGsingInputpidtest){
653 case starlightConstants::ETA:
656 case starlightConstants::ETAPRIME:
659 case starlightConstants::ETAC:
662 case starlightConstants::F0:
665 case starlightConstants::F2:
668 case starlightConstants::A2:
671 case starlightConstants::F2PRIME:
674 case starlightConstants::ZOVERZ03:
678 cout<<"Not a recognized single particle, Gammagammasingle::getwidth(), width = 0."<<endl;
684 //______________________________________________________________________________
685 double Gammagammasingle::getSpin()
687 double singlespin=0.5;
688 switch(_GGsingInputpidtest){
689 case starlightConstants::ETA:
692 case starlightConstants::ETAPRIME:
695 case starlightConstants::ETAC:
698 case starlightConstants::F0:
701 case starlightConstants::F2:
704 case starlightConstants::A2:
707 case starlightConstants::F2PRIME:
710 case starlightConstants::ZOVERZ03:
714 cout<<"Not a recognized single particle, Gammagammasingle::getspin(), spin = 0."<<endl;