Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rapidity_profile.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file rapidity_profile.h
1 // TRENTO: Reduced Thickness Event-by-event Nuclear Topology
2 // Copyright 2015 Jonah E. Bernhard, J. Scott Moreland
3 // TRENTO3D: Three-dimensional extension of TRENTO by Weiyao Ke
4 // MIT License
5 
6 #ifndef ETA_H
7 #define ETA_H
8 
9 #include <cmath>
10 #include <vector>
11 #include <gsl/gsl_fft_complex.h>
12 
15 #define REAL(z,i) ((z)[2*(i)])
16 #define IMAG(z,i) ((z)[2*(i)+1])
17 
18 double const sqrt2 = std::sqrt(2);
19 constexpr double TINY = 1e-12;
20 constexpr int relative_skew_switch = 1;
21 constexpr int absolute_skew_switch = 2;
27 double inline mean_function(double ta, double tb, double exp_ybeam){
28  if (ta < TINY && tb < TINY) return 0.;
29  return 0.5 * std::log((ta*exp_ybeam + tb/exp_ybeam) / std::max(ta/exp_ybeam + tb*exp_ybeam, TINY));
30 }
31 
34 double inline std_function(double ta, double tb){
35  (void)ta;
36  (void)tb;
37  return 1.;
38 }
39 
41 
42 double inline skew_function(double ta, double tb, int type_switch){
43  if (type_switch == relative_skew_switch)
44  return (ta - tb)/std::max(ta + tb, TINY);
45  else if(type_switch == absolute_skew_switch)
46  return ta-tb;
47  else return 0.;
48 }
49 
52 class fast_eta2y {
53 private:
54  double etamax_;
55  double deta_;
56  std::size_t neta_;
57  std::vector<double> y_;
58  std::vector<double> dydeta_;
59 public:
60  fast_eta2y(double J, double etamax, double deta)
61  : etamax_(etamax),
62  deta_(deta),
63  neta_(std::ceil(2.*etamax_/(deta_+1e-15))+1),
64  y_(neta_, 0.),
65  dydeta_(neta_, 0.) {
66 
67  for (std::size_t ieta = 0; ieta < neta_; ++ieta) {
68  double eta = -etamax_ + ieta*deta_;
69  double Jsh = J*std::sinh(eta);
70  double sq = std::sqrt(1. + Jsh*Jsh);
71  y_[ieta] = std::log(sq + Jsh);
72  dydeta_[ieta] = J*std::cosh(eta)/sq;
73  }
74  }
75 
76  double rapidity(double eta){
77  double steps = (eta + etamax_)/deta_;
78  double xi = std::fmod(steps, 1.);
79  std::size_t index = std::floor(steps);
80  return y_[index]*(1. - xi) + y_[index+1]*xi;
81  }
82 
83  double Jacobian(double eta){
84  double steps = (eta + etamax_)/deta_;
85  double xi = std::fmod(steps, 1.);
86  std::size_t index = std::floor(steps);
87  return dydeta_[index]*(1. - xi) + dydeta_[index+1]*xi;
88  }
89 
90 };
91 
92 
104 private:
105  size_t const N;
106  double * data, * dsdy;
107  double eta_max;
108  double deta;
109  double center;
110 
111 public:
112  cumulant_generating(): N(256), data(new double[2*N]), dsdy(new double[2*N]){};
113 
116  void calculate_dsdy(double mean, double std, double skew){
117  double k1, k2, k3, amp, arg;
118  // adaptive eta_max = 3.33*std;
119  center = mean;
120  eta_max = std*3.33;
121  deta = 2.*eta_max/(N-1.);
122  double fftmean = eta_max/std;
123  for(size_t i=0;i<N;i++){
124  k1 = M_PI*(i-N/2.0)/eta_max*std;
125  k2 = k1*k1;
126  k3 = k2*k1;
127 
128  amp = std::exp(-k2/2.0);
129  arg = fftmean*k1+skew/6.0*k3*amp;
130 
131  REAL(data,i) = amp*std::cos(arg);
132  IMAG(data,i) = amp*std::sin(arg);
133  }
134  gsl_fft_complex_radix2_forward(data, 1, N);
135 
136  for(size_t i=0;i<N;i++){
137  dsdy[i] = REAL(data,i)*(2.0*static_cast<double>(i%2 == 0)-1.0);
138  }
139  }
140 
144  double interp_dsdy(double y){
145  y = y-center+deta/2.;
146  if (y < -eta_max || y >= eta_max) return 0.0;
147  double xy = (y+eta_max)/deta;
148  size_t iy = std::floor(xy);
149  double ry = xy-iy;
150  return dsdy[iy]*(1.-ry) + dsdy[iy+1]*ry;
151  }
152 };
153 #endif