EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gammaaluminosity.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file gammaaluminosity.cpp
1 
2 //
3 // Copyright 2010
4 //
5 // This file is part of starlight.
6 //
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.
11 //
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.
16 //
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/>.
19 //
21 //
22 // File and Version Information:
23 // $Rev:: 264 $: revision of last commit
24 // $Author:: jseger $: author of last commit
25 // $Date:: 2016-06-06 21:05:12 +0100 #$: date of last commit
26 //
27 // Description:
28 //
29 //
30 //
32 
33 
34 #include <iostream>
35 #include <fstream>
36 #include <cmath>
37 
38 #include "inputParameters.h"
39 #include "beambeamsystem.h"
40 #include "beam.h"
41 #include "starlightconstants.h"
42 #include "nucleus.h"
43 #include "bessel.h"
44 #include "gammaaluminosity.h"
45 
46 
47 using namespace std;
48 using namespace starlightConstants;
49 
50 
51 //______________________________________________________________________________
53  : photonNucleusCrossSection(inputParametersInstance, bbsystem)
54  ,_ptBinWidthInterference(inputParametersInstance.ptBinWidthInterference())
55  ,_interferenceStrength(inputParametersInstance.interferenceStrength())
56  ,_protonEnergy(inputParametersInstance.protonEnergy())
57  ,_beamLorentzGamma(inputParametersInstance.beamLorentzGamma())
58  ,_baseFileName(inputParametersInstance.baseFileName())
59  ,_maxW(inputParametersInstance.maxW())
60  ,_minW(inputParametersInstance.minW())
61  ,_nmbWBins(inputParametersInstance.nmbWBins())
62  ,_maxRapidity(inputParametersInstance.maxRapidity())
63  ,_nmbRapidityBins(inputParametersInstance.nmbRapidityBins())
64  ,_productionMode(inputParametersInstance.productionMode())
65  ,_beamBreakupMode(inputParametersInstance.beamBreakupMode())
66  ,_interferenceEnabled(inputParametersInstance.interferenceEnabled())
67  ,_maxPtInterference(inputParametersInstance.maxPtInterference())
68  ,_nmbPtBinsInterference(inputParametersInstance.nmbPtBinsInterference())
69 {
70  cout <<"Creating Luminosity Tables."<<endl;
72  cout <<"Luminosity Tables created."<<endl;
73 }
74 
75 
76 //______________________________________________________________________________
78 { }
79 
80 
81 //______________________________________________________________________________
83 {
84  double W,dW,dY;
85  double Egamma,Y;
86  double testint,dndWdY;
87  double csgA;
88  double C;
89  int beam;
90 
91  std::string wyFileName;
92  wyFileName = _baseFileName +".txt";
93 
94  ofstream wylumfile;
95  wylumfile.precision(15);
96 
97  double bwnorm,Eth;
98 
99  dW = (_wMax-_wMin)/_nWbins;
100  dY = (_yMax-(-1.0)*_yMax)/_nYbins;
101 
102  // Write the values of W used in the calculation to slight.txt.
103  wylumfile.open(wyFileName.c_str());
104  wylumfile << getbbs().targetBeam().Z() <<endl;
105  wylumfile << getbbs().targetBeam().A() <<endl;
106  wylumfile << _beamLorentzGamma <<endl;
107  wylumfile << _maxW <<endl;
108  wylumfile << _minW <<endl;
109  wylumfile << _nmbWBins <<endl;
110  wylumfile << _maxRapidity <<endl;
111  wylumfile << _nmbRapidityBins <<endl;
112  wylumfile << _productionMode <<endl;
113  wylumfile << _beamBreakupMode <<endl;
114  wylumfile << _interferenceEnabled <<endl;
115  wylumfile << _interferenceStrength <<endl;
116  wylumfile << starlightConstants::deuteronSlopePar <<endl;
117  wylumfile << _maxPtInterference <<endl;
118  wylumfile << _nmbPtBinsInterference <<endl;
119 
120  // Normalize the Breit-Wigner Distribution and write values of W to slight.txt
121  testint=0.0;
122  //Grabbing default value for C in the breit-wigner calculation
123  C=getDefaultC();
124  for(unsigned int i = 0; i <= _nWbins - 1; ++i) {
125  W = _wMin + double(i)*dW + 0.5*dW;
126  testint = testint + breitWigner(W,C)*dW;
127  wylumfile << W << endl;
128  }
129  bwnorm = 1./testint;
130 
131  // Write the values of Y used in the calculation to slight.txt.
132  for(unsigned int i = 0; i <= _nYbins - 1; ++i) {
133  Y = -1.0*_yMax + double(i)*dY + 0.5*dY;
134  wylumfile << Y << endl;
135  }
136 
138 
139  int A_1 = 0;
140  int A_2 = getbbs().targetBeam().A();
141 
142  // Do this first for the case when the first beam is the photon emitter
143  // Treat pA separately with defined beams
144  // The variable beam (=1,2) defines which nucleus is the target
145  for(unsigned int i = 0; i <= _nWbins - 1; ++i) {
146 
147  W = _wMin + double(i)*dW + 0.5*dW;
148 
149  for(unsigned int j = 0; j <= _nYbins - 1; ++j) {
150 
151  Y = -1.0*_yMax + double(j)*dY + 0.5*dY;
152 
153  if( A_2 == 1 && A_1 != 1 ){
154  // pA, first beam is the nucleus and is in this case the target
155  Egamma = 0.5*W*exp(-Y);
156  beam = 1;
157  } else if( A_1 ==1 && A_2 != 1){
158  // pA, second beam is the nucleus and is in this case the target
159  Egamma = 0.5*W*exp(Y);
160  beam = 2;
161  } else {
162  Egamma = 0.5*W*exp(Y);
163  beam = 2;
164  }
165 
166  dndWdY = 0.;
167 
168  if( Egamma > Eth && Egamma < maxPhotonEnergy() ){
169 
170  csgA=getcsgA(Egamma,W,beam);
171  dndWdY = Egamma*photonFlux(Egamma,beam)*csgA*breitWigner(W,bwnorm);
172 
173  }
174 
175  wylumfile << dndWdY << endl;
176 
177  }
178  }
179 
180  // Repeat the loop for the case when the second beam is the photon emitter.
181  // Don't repeat for pA
182  if( !( (A_2 == 1 && A_1 != 1) || (A_1 == 1 && A_2 != 1) ) ){
183 
184  for(unsigned int i = 0; i <= _nWbins - 1; ++i) {
185 
186  W = _wMin + double(i)*dW + 0.5*dW;
187 
188  for(unsigned int j = 0; j <= _nYbins - 1; ++j) {
189 
190  Y = -1.0*_yMax + double(j)*dY + 0.5*dY;
191 
192  beam = 1;
193  Egamma = 0.5*W*exp(-Y);
194 
195  dndWdY = 0.;
196 
197  if( Egamma > Eth && Egamma < maxPhotonEnergy() ){
198 
199  csgA=getcsgA(Egamma,W,beam);
200  dndWdY = Egamma*photonFlux(Egamma,beam)*csgA*breitWigner(W,bwnorm);
201 
202  }
203 
204  wylumfile << dndWdY << endl;
205 
206  }
207  }
208  }
209 
210  wylumfile << bwnorm << endl;
211  wylumfile.close();
212 
213  if(_interferenceEnabled==1)
214  pttablegen();
215 
216 }
217 
218 
219 //______________________________________________________________________________
221 {
222  // Calculates the pt spectra for VM production with interference
223  // Follows S. Klein and J. Nystrand, Phys. Rev Lett. 84, 2330 (2000).
224  // Written by S. Klein, 8/2002
225 
226  // fill in table pttable in one call
227  // Integrate over all y (using the same y values as in table yarray
228  // note that the cross section goes from ymin (<0) to ymax (>0), in numy points
229  // here, we go from 0 to ymax in (numy/2)+1 points
230  // numy must be even.
231 
232  // At each y, calculate the photon energies Egamma1 and Egamma2
233  // and the two photon-A cross sections
234 
235  // loop over each p_t entry in the table.
236 
237  // Then, loop over b and phi (the angle between the VM \vec{p_t} and \vec{b}
238  // and calculate the cross section at each step.
239  // Put the results in pttable
240 
241  std::string wyFileName;
242  wyFileName = _baseFileName +".txt";
243 
244  ofstream wylumfile;
245  wylumfile.precision(15);
246 
247  wylumfile.open(wyFileName.c_str(),ios::app);
248 
249  double param1pt[500],param2pt[500];
250  double *ptparam1=param1pt;
251  double *ptparam2=param2pt;
252  double dY=0.,Yp=0.,Egamma1=0.,Egamma2=0.,Wgp=0.,cs=0.,cvma=0.,Av=0.,tmin=0.,tmax=0.,ax=0.,bx=0.;
253  double csgA=0.,t=0.,sig_ga_1=0.,sig_ga_2=0.,bmax=0.,bmin=0.,db=0.,pt=0.,sum1=0.,b=0.,A1=0.,A2=0.;
254  double sumg=0.,theta=0.,amp_i_2=0.,sumint=0.;
255  int NGAUSS=0,NBIN=0;
256 
257  double xg[16]={.0483076656877383162E0,.144471961582796493E0,
258  .239287362252137075E0, .331868602282127650E0,
259  .421351276130635345E0, .506899908932229390E0,
260  .587715757240762329E0, .663044266930215201E0,
261  .732182118740289680E0, .794483795967942407E0,
262  .849367613732569970E0, .896321155766052124E0,
263  .934906075937739689E0, .964762255587506430E0,
264  .985611511545268335E0, .997263861849481564E0};
265  double ag[16]={.0965400885147278006E0, .0956387200792748594E0,
266  .0938443990808045654E0, .0911738786957638847E0,
267  .0876520930044038111E0, .0833119242269467552E0,
268  .0781938957870703065E0, .0723457941088485062E0,
269  .0658222227763618468E0, .0586840934785355471E0,
270  .0509980592623761762E0, .0428358980222266807E0,
271  .0342738629130214331E0, .0253920653092620595E0,
272  .0162743947309056706E0, .00701861000947009660E0};
273 
274  NGAUSS=16;
275 
276  //Setting input calls to variables/less calls this way.
277  double Ymax=_yMax;
278  int numy = _nYbins;
279  double Ep = _protonEnergy;
280  int ibreakup = _beamBreakupMode;
281  double NPT = _nmbPtBinsInterference;
282  double gamma_em = _beamLorentzGamma;
283  double mass = getChannelMass();
284  int beam;
285 
286  // loop over y from 0 (not -ymax) to yma
287  // changed this to go from -ymax to ymax to aid asymmetric collisions
288 
289  dY=(2.*Ymax)/numy;
290  for(int jy=1;jy<=numy;jy++){
291  Yp=-Ymax+((double(jy)-0.5)*dY);
292 
293  // Find the photon energies. Yp >= 0, so Egamma2 is smaller (no longer true if we integrate over all Y)
294  // Use the vector meson mass for W here - neglect the width
295 
296  Egamma1 = 0.5*mass*exp(Yp);
297  Egamma2 = 0.5*mass*exp(-Yp);
298 
299  // Find the sigma(gammaA) for the two directions
300  // Photonuclear Cross Section 1
301  // Gamma-proton CM energy
302  beam=2;
303 
304  Wgp=sqrt(2.*Egamma1*(Ep+sqrt(Ep*Ep-starlightConstants::protonMass*
305  starlightConstants::protonMass))+starlightConstants::protonMass*starlightConstants::protonMass);
306 
307  // Calculate V.M.+proton cross section
308 
312  // Calculate V.M.+nucleus cross section
313  cvma=sigma_A(cs,beam);
314 
315  // Calculate Av = dsigma/dt(t=0) Note Units: fm**2/Gev**2
316 
319 
320  tmin = ((mass*mass)/(4.*Egamma1*gamma_em)*(mass*mass)/(4.*Egamma1*gamma_em));
321  tmax = tmin + 0.25;
322  ax = 0.5*(tmax-tmin);
323  bx = 0.5*(tmax+tmin);
324  csgA = 0.;
325 
326  for(int k=0;k<NGAUSS;k++){
327  t = sqrt(ax*xg[k]+bx);
328  csgA = csgA + ag[k]*getbbs().targetBeam().formFactor(t)*getbbs().targetBeam().formFactor(t);
329  t = sqrt(ax*(-xg[k])+bx);
330  csgA = csgA + ag[k]*getbbs().targetBeam().formFactor(t)*getbbs().targetBeam().formFactor(t);
331  }
332 
333  csgA = 0.5*(tmax-tmin)*csgA;
334  csgA = Av*csgA;
335  sig_ga_1 = csgA;
336 
337  // Photonuclear Cross Section 2
338  beam=1;
339 
340  Wgp=sqrt(2.*Egamma2*(Ep+sqrt(Ep*Ep-starlightConstants::protonMass*
341  starlightConstants::protonMass))+starlightConstants::protonMass*starlightConstants::protonMass);
342 
345 
346  cvma=sigma_A(cs,beam);
347 
350 
351  tmin = (((mass*mass)/(4.*Egamma2*gamma_em))*((mass*mass)/(4.*Egamma2*gamma_em)));
352  tmax = tmin + 0.25;
353  ax = 0.5*(tmax-tmin);
354  bx = 0.5*(tmax+tmin);
355  csgA = 0.;
356 
357  for(int k=0;k<NGAUSS;k++){
358  t = sqrt(ax*xg[k]+bx);
359  csgA = csgA + ag[k]*getbbs().electronBeam().formFactor(t)*getbbs().electronBeam().formFactor(t);
360  t = sqrt(ax*(-xg[k])+bx);
361  csgA = csgA + ag[k]*getbbs().electronBeam().formFactor(t)*getbbs().electronBeam().formFactor(t);
362  }
363 
364  csgA = 0.5*(tmax-tmin)*csgA;
365  csgA = Av*csgA;
366  sig_ga_2 = csgA;
367 
368  // Set up pttables - they find the reduction in sigma(pt)
369  // due to the nuclear form factors.
370  // Use the vector meson mass for W here - neglect width in
371  // interference calculation
372 
373  ptparam1=vmsigmapt(mass,Egamma1,ptparam1, 2);
374  ptparam2=vmsigmapt(mass,Egamma2,ptparam2, 1);
375 
377  // if we allow for nuclear breakup, use a slightly smaller bmin
378  if (ibreakup != 1)
379  bmin=0.95*bmin;
380 
381  // set bmax according to the smaller photon energy, following flux.f
382  if (Egamma1 >=Egamma2) {
383  bmax=bmin+6.*starlightConstants::hbarc*gamma_em/Egamma2;
384  }
385  else {
386  bmax=bmin+6.*starlightConstants::hbarc*gamma_em/Egamma1;
387  }
388  // set number of bins to a reasonable number to start
389  NBIN = 2000;
390  db = (bmax-bmin)/float(NBIN);
391  // loop over pt
392  for(int i=1;i<=NPT;i++){
393 
394  pt = (float(i)-0.5)*_ptBinWidthInterference;
395  sum1=0.0;
396  // loop over b
397  for(int j=1;j<=NBIN;j++){
398 
399  b = bmin + (float(j)-0.5)*db;
400  A1 = Egamma1*getbbs().electronBeam().photonDensity(Egamma1,b)*sig_ga_1*ptparam1[i];
401  A2 = Egamma2*getbbs().targetBeam().photonDensity(Egamma2,b)*sig_ga_2*ptparam2[i];
402  sumg=0.0;
403 
404  // do this as a Gaussian integral, from 0 to pi
405  for(int k=0;k<NGAUSS;k++){
406 
408  // allow for a linear sum of interfering and non-interfering amplitudes
409  amp_i_2 = A1 + A2 - 2.*_interferenceStrength
410  *sqrt(A1*A2)*cos(pt*b*cos(theta)/starlightConstants::hbarc);
411  sumg = sumg+ag[k]*amp_i_2;
412  }
413  // this is dn/dpt^2
414  // The factor of 2 is because the theta integral is only from 0 to pi
415  sumint=2.*sumg*b*db;
416  if (ibreakup > 1)
417  sumint=sumint*getbbs().probabilityOfBreakup(b);
418  sum1 = sum1 + sumint;
419 
420  }
421  // normalization is done in readDiffLum.f
422  // This is d^2sigma/dpt^2; convert to dsigma/dpt
423 
424 
425  wylumfile << sum1*pt*_ptBinWidthInterference <<endl;
426  // end of pt loop
427  }
428  // end of y loop
429  }
430  wylumfile.close();
431 }
432 
433 
434 //______________________________________________________________________________
435 double *photonNucleusLuminosity::vmsigmapt(double W, double Egamma, double *SIGMAPT, int beam)
436 {
437  //
438  // This subroutine calculates the effect of the nuclear form factor
439  // on the pt spectrum, for use in interference calculations
440  // For an interaction with mass W and photon energy Egamma,
441  // it calculates the cross section suppression SIGMAPT(PT)
442  // as a function of pt.
443  // The input pt values come from pttable.inc
444 
445 
446  double pxmax=0.,pymax=0.,dx=0.,Epom=0.,pt=0.,px0=0.,py0=0.,sum=0.,sumy=0.;
447  double py=0.,px=0.,pt1=0.,pt2=0.,f1=0.,f2=0.,q1=0.,q2=0.,norm=0.;
448  int NGAUSS =0,Nxbin=0;
449  double xg[16]={.0483076656877383162e0,.144471961582796493e0,
450  .239287362252137075e0, .331868602282127650e0,
451  .421351276130635345e0, .506899908932229390e0,
452  .587715757240762329e0, .663044266930215201e0,
453  .732182118740289680e0, .794483795967942407e0,
454  .849367613732569970e0, .896321155766052124e0,
455  .934906075937739689e0, .964762255587506430e0,
456  .985611511545268335e0, .997263861849481564e0};
457  double ag[16]={.0965400885147278006e0, .0956387200792748594e0,
458  .0938443990808045654e0, .0911738786957638847e0,
459  .0876520930044038111e0, .0833119242269467552e0,
460  .0781938957870703065e0, .0723457941088485062e0,
461  .0658222227763618468e0, .0586840934785355471e0,
462  .0509980592623761762e0, .0428358980222266807e0,
463  .0342738629130214331e0, .0253920653092620595e0,
464  .0162743947309056706e0, .00701861000947009660e0};
465  NGAUSS=16;
466 
467  // >> Initialize
468  if (beam == 1) {
471  }
472  else {
475  }
476 
477  Nxbin = 500;
478 
479  dx = 2.*pxmax/double(Nxbin);
480  Epom = W*W/(4.*Egamma);
481 
482  // >> Loop over total Pt to find distribution
483 
484  for(int k=1;k<=_nmbPtBinsInterference;k++){
485 
486  pt=_ptBinWidthInterference*(double(k)-0.5);
487 
488  px0 = pt;
489  py0 = 0.0;
490 
491  // For each total Pt, integrate over Pt1, , the photon pt
492  // The pt of the Pomeron is the difference
493  // pt1 is
494  sum=0.;
495  for(int i=1;i<=Nxbin;i++){
496 
497  px = -pxmax + (double(i)-0.5)*dx;
498  sumy=0.0;
499  for(int j=0;j<NGAUSS;j++){
500 
501  py = 0.5*pymax*xg[j]+0.5*pymax;
502  // photon pt
503  pt1 = sqrt( px*px + py*py );
504  // pomeron pt
505  pt2 = sqrt( (px-px0)*(px-px0) + (py-py0)*(py-py0) );
506  q1 = sqrt( ((Egamma/_beamLorentzGamma)*(Egamma/_beamLorentzGamma)) + pt1*pt1 );
507  q2 = sqrt( ((Epom/_beamLorentzGamma)*(Epom/_beamLorentzGamma)) + pt2*pt2 );
508 
509  // photon form factor
510  // add in phase space factor?
511  if (beam ==2) {
512  f1 = (getbbs().electronBeam().formFactor(q1*q1)*getbbs().electronBeam().formFactor(q1*q1)*pt1*pt1)/(q1*q1*q1*q1);
513 
514  // Pomeron form factor
515  f2 = getbbs().targetBeam().formFactor(q2*q2)*getbbs().targetBeam().formFactor(q2*q2);
516  }
517  else {
518  f1 = (getbbs().targetBeam().formFactor(q1*q1)*getbbs().targetBeam().formFactor(q1*q1)*pt1*pt1)/(q1*q1*q1*q1);
519 
520  // Pomeron form factor
522  }
523  sumy= sumy + ag[j]*f1*f2;
524 
525  // now consider other half of py phase space - why is this split?
526  py = 0.5*pymax*(-xg[j])+0.5*pymax;
527  pt1 = sqrt( px*px + py*py );
528  pt2 = sqrt( (px-px0)*(px-px0) + (py-py0)*(py-py0) );
529  q1 = sqrt( ((Egamma/_beamLorentzGamma)*Egamma/_beamLorentzGamma) + pt1*pt1 );
530  q2 = sqrt( ((Epom/_beamLorentzGamma)*(Epom/_beamLorentzGamma)) + pt2*pt2 );
531  // add in phase space factor?
532  if (beam ==2) {
533  f1 = (getbbs().electronBeam().formFactor(q1*q1)*getbbs().electronBeam().formFactor(q1*q1)*pt1*pt1)/(q1*q1*q1*q1);
534 
535  // Pomeron form factor
536  f2 = getbbs().targetBeam().formFactor(q2*q2)*getbbs().targetBeam().formFactor(q2*q2);
537  }
538  else {
539  f1 = (getbbs().targetBeam().formFactor(q1*q1)*getbbs().targetBeam().formFactor(q1*q1)*pt1*pt1)/(q1*q1*q1*q1);
540 
541  // Pomeron form factor
542  f2 = getbbs().electronBeam().formFactor(q2*q2)*getbbs().electronBeam().formFactor(q2*q2);
543  }
544 
545  sumy= sumy + ag[j]*f1*f2;
546 
547  }
548  // >> This is to normalize the gaussian integration
549  sumy = 0.5*pymax*sumy;
550  // >> The 2 is to account for py: 0 -- pymax
551  sum = sum + 2.*sumy*dx;
552  }
553 
554  if(k==1) norm=1./sum;
555  SIGMAPT[k]=sum*norm;
556  }
557  return (SIGMAPT);
558 }
559