EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
e_narrowResonanceCrossSection.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file e_narrowResonanceCrossSection.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 //#define _makeGammaPQ2_
33 
34 #include <iostream>
35 #include <iomanip>
36 #include <fstream>
37 #include <cmath>
38 
39 #include "starlightconstants.h"
41 
42 using namespace std;
43 using namespace starlightConstants;
44 
45 //______________________________________________________________________________
47  :photonNucleusCrossSection(inputParametersInstance, bbsystem)
48 {
49  _Ep = inputParametersInstance.protonEnergy();
50  //this is in target frame
51  _electronEnergy = inputParametersInstance.electronEnergy();
52  //_target_beamLorentz = inputParametersInstance.targetBeamLorentzGamma();
53  _target_beamLorentz = inputParametersInstance.beamLorentzGamma();
54  _boost = std::acosh(inputParametersInstance.electronBeamLorentzGamma())
55  -std::acosh(inputParametersInstance.targetBeamLorentzGamma());
56  _boost = _boost/2;
57  // Photon energy limits in the two important frames
58  _targetMaxPhotonEnergy=inputParametersInstance.targetMaxPhotonEnergy();
59  _targetMinPhotonEnergy=inputParametersInstance.targetMinPhotonEnergy();
60  _cmsMaxPhotonEnergy=inputParametersInstance.cmsMaxPhotonEnergy();
61  _cmsMinPhotonEnergy=inputParametersInstance.cmsMinPhotonEnergy();
62  //
63  _VMnumEgamma = inputParametersInstance.nmbEnergyBins();
64  _useFixedRange = inputParametersInstance.fixedQ2Range();
65  _gammaMinQ2 = inputParametersInstance.minGammaQ2();
66  _gammaMaxQ2 = inputParametersInstance.maxGammaQ2();
67  _targetRadii = inputParametersInstance.targetRadius();
68  _backwardsProduction = inputParametersInstance.backwardsProduction();
69 }
70 
71 
72 //______________________________________________________________________________
74 { }
75 
76 
77 //______________________________________________________________________________
78 void
79 e_narrowResonanceCrossSection::crossSectionCalculation(const double) // _bwnormsave (unused)
80 {
81  // This subroutine calculates the vector meson cross section assuming
82  // a narrow resonance. For reference, see STAR Note 386.
83 
84  double dEgamma, minEgamma;
85  double ega[3] = {0};
86  double int_r,dR;
87  double int_r2, dR2;
88  int iEgamma, nEgamma,beam;
89 
90  //Integration is done with exponential steps, in target frame
91  //nEgamma = _VMnumEgamma;
92  nEgamma = 1000;
93  dEgamma = std::log(_targetMaxPhotonEnergy/_targetMinPhotonEnergy)/nEgamma;
94  minEgamma = std::log(_targetMinPhotonEnergy);
95 
96  cout<<" Using Narrow Resonance ..."<<endl;
97 
98  //
99  printf(" gamma+nucleon threshold (CMS): %e GeV \n", _cmsMinPhotonEnergy);
100 
101  int A_1 = getbbs().electronBeam().A();
102  int A_2 = getbbs().targetBeam().A();
103 
104  if( A_2 == 0 && A_1 >= 1 ){
105  // pA, first beam is the nucleus and is in this case the target
106  beam = 1;
107  } else if( A_1 ==0 && A_2 >= 1){
108  // photon energy in Target frame
109  beam = 2;
110  } else {
111  // photon energy in Target frame
112  beam = 2;
113  }
114 
115  int_r=0.;
116  int_r2= 0;
117  // Do this first for the case when the first beam is the photon emitter
118  // The variable beam (=1,2) defines which nucleus is the target
119  // Target beam ==2 so repidity is negative. Can generalize later
120  // These might be useful in a future iteration
121  int nQ2 = 1000;
122  printf(" gamma+nucleon threshold (Target): %e GeV \n", _targetMinPhotonEnergy);
123  for(iEgamma = 0 ; iEgamma < nEgamma; ++iEgamma){ // Integral over photon energy
124  // Target frame energies
125  ega[0] = exp(minEgamma + iEgamma*dEgamma );
126  ega[1] = exp(minEgamma + (iEgamma+1)*dEgamma );
127  ega[2] = 0.5*(ega[0]+ega[1]);
128 
129  // Integral over Q2
130  double dndE[3] = {0}; // Effective photon flux
131  double full_int[3] = {0}; // Full e+X --> e+X+V.M. cross section
132  //
133  for( int iEgaInt = 0 ; iEgaInt < 3; ++iEgaInt){ // Loop over the energies for the three points to integrate over Q2
134 
135  /*
136  if ( _backwardsProduction)
137  {
138  if (_ip->productionMode() != 2 || _ip->prodParticleId() != 223 || _ip->beam1A() == 1 || _ip->beam2A() != 1)
139  {
140  std::cout << "Backward production is implemented for ";
141  std::cout << "PROD_MODE = 2, PROD_PID = 223, ";
142  std::cout << "BEAM_1_A != 1, and BEAM_2_A == 1. ";
143  std::cout << "Terminating program." << std::endl;
144  throw 0;
145  }
146  }
147  */
148  //These are the physical limits
149  double Q2_min = std::pow(starlightConstants::mel*ega[iEgaInt],2.0)/(_electronEnergy*(_electronEnergy-ega[iEgaInt]));
150  double Q2_max = 4.*_electronEnergy*(_electronEnergy-ega[iEgaInt]);
151  if(_useFixedRange == true){
152  if( Q2_min < _gammaMinQ2 )
153  Q2_min = _gammaMinQ2;
154  if( Q2_max > _gammaMaxQ2 )
155  Q2_max = _gammaMaxQ2;
156  }
157  double lnQ2ratio = std::log(Q2_max/Q2_min)/nQ2;
158  double lnQ2_min = std::log(Q2_min);
159  //
160 
161  for( int iQ2 = 0 ; iQ2 < nQ2; ++iQ2){ // Integral over photon virtuality
162  //
163  double q2_1 = exp( lnQ2_min + iQ2*lnQ2ratio);
164  double q2_2 = exp( lnQ2_min + (iQ2+1)*lnQ2ratio);
165  double q2_12 = (q2_2+q2_1)/2.;
166  // Integrating the effective photon flux
167  dndE[iEgaInt] +=(q2_2-q2_1)*( getcsgA_Q2_dep(q2_1)*photonFlux(ega[iEgaInt],q2_1)
168  +getcsgA_Q2_dep(q2_2)*photonFlux(ega[iEgaInt],q2_2)
169  +4.*getcsgA_Q2_dep(q2_12)*photonFlux(ega[iEgaInt],q2_12) );
170  // Integrating cross section
171  full_int[iEgaInt] += (q2_2-q2_1)*( g(ega[iEgaInt],q2_1)*getcsgA(ega[iEgaInt],q2_1,beam)
172  + g(ega[iEgaInt],q2_2)*getcsgA(ega[iEgaInt],q2_2,beam)
173  + 4.*g(ega[iEgaInt],q2_12)*getcsgA(ega[iEgaInt],q2_12,beam) );
174  }
175 
176  // Finish the Q2 integration for the three end-points (Siumpsons rule)
177  dndE[iEgaInt] = dndE[iEgaInt]/6.;
178  full_int[iEgaInt] = full_int[iEgaInt]/6.;
179  }
180  // Finishing cross-section integral
181  dR = full_int[0];
182  dR += full_int[1];
183  dR += 4.*full_int[2];
184  dR = dR*(ega[1]-ega[0])/6.;
185 
186  // Finishing integral over the effective photon flux
187  dR2 = dndE[0];
188  dR2 += dndE[1];
189  dR2 += 4.*dndE[2];
190  dR2 = dR2*(ega[1]-ega[0])/6.;
191  //
192  int_r = int_r+dR;
193  int_r2 = int_r2 + dR2;
194  }
195  cout<<endl;
196  if(_useFixedRange == true){
197  cout<<" Using fixed Q2 range "<<_gammaMinQ2 << " < Q2 < "<<_gammaMaxQ2<<endl;
198  }
199 
200  if(_backwardsProduction){cout<<"********************** WARNING ***********************"<<endl;
201  cout<<"The total cross section for backward production"<<endl;
202  cout<<"should only be trusted for the omega. The exact omega"<<endl;
203  cout<<"behavior is implemented for the rho. Other mesons use"<<endl;
204  cout<<"the forward cross section dependence"<<endl;}
205  printCrossSection(" Total cross section: ",int_r);
206  if(_backwardsProduction)cout<<"******************************************************"<<endl;
207 
208  //printCrossSection(" gamma+X --> VM+X ", int_r/int_r2); // commented out for the mean time, not necesary in current implementation
209  //
210  //cout<<endl;
211  setPhotonNucleusSigma(0.01*int_r);
212  #ifdef _makeGammaPQ2_
214  #endif
215 }
216 
217 
218 //______________________________________________________________________________
219 void
221 {
222  // This subroutine calculates the Q2 dependence of
223  // gamma+X -> VM + X cross section for a narrow resonance
224 
225  /*int const nQ2bins = 19;
226  double const q2Edge[nQ2bins+1] = { 0.1,1.,2.,3., 4.,5.,
227  6.,7.,8.,9.,10.,
228  11.,12.,13.,14.,15.,
229  20.,30.,40.,50.};
230  */
231  int const nQ2bins = 38;
232  double const q2Edge[nQ2bins+1] = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09,
233  0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
234  1, 2, 3, 4, 5, 6, 7, 8, 9,
235  10, 20, 30, 40, 50, 60, 70, 80, 90,
236  100, 200 };
237  //
238  double full_x_section[nQ2bins] = {0};
239  double effective_flux[nQ2bins] = {0};
240  //
241  ofstream gamma_flux,total_xsec;
242  //
243  gamma_flux.open("estarlight_gamma_flux.csv");
244  total_xsec.open("estarlight_total_xsec.csv");
245  //
246  double dEgamma, minEgamma;
247  double ega[3] = {0};
248  double dR;
249  double dR2;
250  int iEgamma, nEgamma,beam;
251 
252  //Integration is done with exponential steps, in target frame
253  //nEgamma = _VMnumEgamma;
254  nEgamma = 1000;
255  dEgamma = std::log(_targetMaxPhotonEnergy/_targetMinPhotonEnergy)/nEgamma;
256  minEgamma = std::log(_targetMinPhotonEnergy);
257 
258  //cout<<" Using Narrow Resonance ..."<<endl;
259 
260  //printf(" gamma+nucleon threshold (CMS): %e GeV \n", _cmsMinPhotonEnergy);
261 
262  int A_1 = getbbs().electronBeam().A();
263  int A_2 = getbbs().targetBeam().A();
264 
265  if( A_2 == 0 && A_1 >= 1 ){
266  // pA, first beam is the nucleus and is in this case the target
267  beam = 1;
268  } else if( A_1 ==0 && A_2 >= 1){
269  // photon energy in Target frame
270  beam = 2;
271  } else {
272  // photon energy in Target frame
273  beam = 2;
274  }
275  // Do this first for the case when the first beam is the photon emitter
276  // The variable beam (=1,2) defines which nucleus is the target
277  // Target beam ==2 so repidity is negative. Can generalize later
278  int nQ2 = 500;
279  //printf(" gamma+nucleon threshold (Target): %e GeV \n", _targetMinPhotonEnergy);
280  for( int iQ2Bin = 0 ; iQ2Bin < nQ2bins; ++iQ2Bin){
281  for(iEgamma = 0 ; iEgamma < nEgamma; ++iEgamma){ // Integral over photon energy
282  // Target frame energies
283  ega[0] = exp(minEgamma + iEgamma*dEgamma );
284  ega[1] = exp(minEgamma + (iEgamma+1)*dEgamma );
285  ega[2] = 0.5*(ega[0]+ega[1]);
286  //
287  //
288  // Integral over Q2
289  double dndE[3] = {0}; // Effective photon flux
290  double full_int[3] = {0}; // Full e+X --> e+X+V.M. cross section
291  //
292  for( int iEgaInt = 0 ; iEgaInt < 3; ++iEgaInt){ // Loop over the energies for the three points to integrate over Q2
293  //
294  double Q2_min = q2Edge[iQ2Bin];
295  double Q2_max = q2Edge[iQ2Bin+1];
296  double lnQ2ratio = std::log(Q2_max/Q2_min)/nQ2;
297  double lnQ2_min = std::log(Q2_min);
298  for( int iQ2 = 0 ; iQ2 < nQ2; ++iQ2){ // Integral over photon virtuality
299  //
300  double q2_1 = exp( lnQ2_min + iQ2*lnQ2ratio);
301  double q2_2 = exp( lnQ2_min + (iQ2+1)*lnQ2ratio);
302  double q2_12 = (q2_2+q2_1)/2.;
303  // Integrating the photon flux
304  dndE[iEgaInt] +=(q2_2-q2_1)*( photonFlux(ega[iEgaInt],q2_1)
305  +photonFlux(ega[iEgaInt],q2_2)
306  +4.*photonFlux(ega[iEgaInt],q2_12) );
307 
308  full_int[iEgaInt] += (q2_2-q2_1)*( g(ega[iEgaInt],q2_1)*getcsgA(ega[iEgaInt],q2_1,beam)
309  + g(ega[iEgaInt],q2_2)*getcsgA(ega[iEgaInt],q2_2,beam)
310  + 4.*g(ega[iEgaInt],q2_12)*getcsgA(ega[iEgaInt],q2_12,beam) );
311  }
312  // Finish the Q2 integration for the three end-points (Siumpsons rule)
313  dndE[iEgaInt] = dndE[iEgaInt]/6.;
314  full_int[iEgaInt] = full_int[iEgaInt]/6.;
315  }
316  // Finishing cross-section integral
317  dR = full_int[0];
318  dR += full_int[1];
319  dR += 4.*full_int[2];
320  dR = dR*(ega[1]-ega[0])/6.;
321 
322  // Finishing integral over the effective photon flux
323  dR2 = dndE[0];
324  dR2 += dndE[1];
325  dR2 += 4.*dndE[2];
326  dR2 = dR2*(ega[1]-ega[0])/6.;
327  //
328  full_x_section[iQ2Bin] += dR;
329  effective_flux[iQ2Bin] += dR2;
330  }
331  //cout<<gamma_x_section[iQ2Bin]/effective_flux[iQ2Bin]*1E7<<endl;
332  gamma_flux<<q2Edge[iQ2Bin]<<","<<q2Edge[iQ2Bin+1]<<","<<effective_flux[iQ2Bin]<<endl;
333  total_xsec<<q2Edge[iQ2Bin]<<","<<q2Edge[iQ2Bin+1]<<","<<full_x_section[iQ2Bin]<<endl; //No need to remove bin width
334  }
335  //
336  //
337  gamma_flux.close();
338  total_xsec.close();
339 }
340 
341 void e_narrowResonanceCrossSection::printCrossSection(const string name, const double x_section)
342 {
343  if (0.01*x_section > 1.){
344  cout<< name.c_str() <<0.01*x_section<<" barn."<<endl;
345  } else if (10.*x_section > 1.){
346  cout<< name.c_str() <<10.*x_section<<" mb."<<endl;
347  } else if (10000.*x_section > 1.){
348  cout<< name.c_str() <<10000.*x_section<<" microb."<<endl;
349  } else if (10000000.*x_section > 1.){
350  cout<< name.c_str() <<10000000.*x_section<<" nanob."<<endl;
351  } else if (1.E10*x_section > 1.){
352  cout<< name.c_str() <<1.E10*x_section<<" picob."<<endl;
353  } else {
354  cout<< name.c_str() <<1.E13*x_section<<" femtob."<<endl;
355  }
356  //cout<<endl;
357 }