/* Flow analysis through the generating-function zeros method. */ /* The input is a file 'events.dat' following the structure of the file generated by 'generator.cc', i.e.: - first, the number of events; - then, for each event, the (detected) multiplicity, and for each particle the transverse momentum (in MeV) and the azimuth (in radians). */ /* The program then reconstructs integrated elliptic flow (V2) and then differential elliptic (v2) and "hexadecupolar" (v4) flows. */ /* The results are stored in the output file 'zeros.txt' */ /* Throughout the program, references are made to the papers: [A]: R.S.Bhalerao, N.Borghini, J.-Y.Ollitrault, Nucl. Phys. A 727 (2003) 373 [nucl-th/0310016]; [B]: N.Borghini, R.S.Bhalerao, J.-Y.Ollitrault, J. Phys. G 30 (2004) S1213 [nucl-th/0402053]. */ #include #include #include #include #include "Bessel.h" #include "distributions.h" /* */ #define Pi (2.*acos(0.)) #define sqr(x) ((x)*(x)) #define rootJ0 2.4048256 /* First zero of the modified Bessel function J0 */ #define J1rootJ0 0.519147 /* J1(rootJ0) */ #define J2rootJ0 0.431755 /* J2(rootJ0) */ /* PARAMETERS USED IN THE RECONSTRUCTION */ /* kr*kt is the number of points at which one computes the generating function kt possible values for the angle kr possible values for the radius */ #define kt 5 #define kr 80 #define vmax 0.101 /* maximal possible integrated flow value */ #define vstep 0.001 #define vmin 0.021 /* minimal possible integrated flow value: check that vmin + kr*vstep = vmax!! */ #define Nbins 60 /* number of bins for differential flow. Check that it is consistent with the number in distributions.cc! */ /* */ FILE *input,*data,*output,*plotVint,*plotvdiff; main() { /* main() */ /* Variable declaration */ const complex i(0,1); long neve; /* Number of events */ long rmult; /* Detected multiplicity in an event */ double rpmult[Nbins]; /* Detected multiplicity per bin */ double rmultmean; /* Average detected multiplicity */ float phi, pT; /* particle azimuth and transverse momentum */ int binpT; double arg[kt]; /* theta values */ double RZ[kr]; /* tabulation points for each theta value */ /* Generating functions evaluated at the tabulation points: - g2[k1][k2] is the generating function g in the harmonic 2, for theta=arg[k1], evaluated at RZ[k2]; - G2[][] is its average over events; - modG2sq is the squared modulus of the averaged G2. */ complex g2[kt][kr], G2[kt][kr]; double modG2sq[kt][kr]; double w2[Nbins]; /* weights */ /* Event flow vectors, useful for the computation of statistical errors: - Q2 is the (weighted) flow vector in each event in harmonic n=2; - Q2mean is its average over events; - modQ2sqmean is the average over event of the squared modulus |Q2|^2. */ complex Q2, Q2mean; double modQ2sqmean; /* r02[] are the values of RZ which minimize the functions mod2Gsq[kt][kr]; these are the r0^theta of Refs.[A,B]. */ double r02[kt]; /* Values of the generating function g2 at the minimum of the average G2 */ complex g2r0[kt]; complex dlng2_dz[kt], dG2_dz[kt]; complex dlng2_dw2[kt][Nbins], dG2_dw2[kt][Nbins]; complex basenum42[kt][Nbins], num42[kt][Nbins]; /* V2[] are the reconstructed integrated flow values for each angle arg[k1], i.e. the various V2^theta{infty} in the notations of Refs.[A,B]; V2mean is their average value, denoted by V2{infty} in the Refs. vd22[][], vd42[][] are the differential flows for each angle, in a given bin; vd22mean[], vd42mean[] are their average values. */ double V2[kt], V2mean; double vd22[kt][Nbins], vd22mean[Nbins], vd42[kt][Nbins], vd42mean[Nbins]; double vd22av, vd42av; double chi2, err2[kt], err2mean; double err22[kt][Nbins], err22mean[Nbins], err42[kt][Nbins], err42mean[Nbins]; /* For simulations only: parameters of the event generation */ double Vmax, Vstep; int k; double temp; struct timeval Time; int debut, fin; /* Initializations */ gettimeofday (&Time, 0); debut=Time.tv_sec; data=fopen("inputdata.dat","r"); fscanf(data, "%i %i\n", &k, &rmult); fclose(data); Vmax=vmax*rmult; Vstep=vstep*rmult; for(int k1=0; k1=%G\n", rmultmean); fprintf(output," mean detected particle multiplicity =%G\n\n", rmultmean); fprintf(output," Minimum measurable flow v=%.3g\n\n", rootJ0/sqrt(2.*rmultmean*log(0.5*neve))); /* v = j_{01}/Sqrt(2M ln(Neve/2)), cf. Ref.[A], Eq.(80) */ /* RECONSTRUCTION OF INTEGRATED FLOW */ V2mean=0.; for(int k1=0; k1modG2sq[k1][k+1]) k++; /* Interpolate the value of V2[k1], see footnote 3 in Ref.[A], and derive the corresponding position of the first zero of G2 */ V2[k1]=Vmax-Vstep*(k+(modG2sq[k1][k-1]-modG2sq[k1][k+1])/2./ (modG2sq[k1][k-1]-2.*modG2sq[k1][k]+modG2sq[k1][k+1])); r02[k1]=rootJ0/V2[k1]; V2mean+=V2[k1]; /* Average V2 */ } /* End of the loop over theta angles */ V2mean/=((float) kt); /* Average V2 */ /* Compute the resolution parameters chi, using Eqs.(59),(62) of Ref.[A] */ chi2=V2mean/ sqrt(modQ2sqmean-sqr(real(Q2mean)/neve)-sqr(imag(Q2mean)/neve)-sqr(V2mean)); plotVint=fopen("plots_Vint.grf","w"); for(int k1=0; k1=%.3g +/- %.3g", V2mean/rmultmean, err2mean/rmultmean); /* */ /* RECONSTRUCTION OF DIFFERENTIAL FLOW FROM THE GENERATING FUNCTION */ /* */ /* Initializations */ for(int bin=0; bin_psi in Ref.[B]. */ dlng2_dw2[k1][binpT]+=(cos(2.*phi-arg[k1])/(1.+i*r02[k1]*temp)); basenum42[k1][binpT]+=(cos(4.*phi-2.*arg[k1])/(1.+i*r02[k1]*temp)); } /* End of the loop over theta angles */ } /* End of the loop over particles */ for(int k1=0; k10) { /* compute the average (over pT) v2 and v4 */ vd22av+=rpmult[bin]*vd22mean[bin]; vd42av+=rpmult[bin]*vd42mean[bin]; } fprintf(output," . bin %i: average detected multiplicity =%G\n", bin, rpmult[bin]); fprintf(output," v2=%.3g +/- %.3g,", vd22mean[bin], err22mean[bin]); fprintf(output," v4=%.3g +/- %.3g\n", vd42mean[bin], err42mean[bin]); fprintf(plotvdiff, "%i %.4g %.4g %.4g %.4g %.4g\n", bin, rpmult[bin], vd22mean[bin], err22mean[bin], vd42mean[bin], err42mean[bin]); } vd22av/=rmultmean; vd42av/=rmultmean; fprintf(output, "=%.3g, =%.3g\n", vd22av, vd42av); gettimeofday (&Time, 0); fin=Time.tv_sec; printf("All events read, elapsed time=%d s\n",fin-debut); fprintf(output,"\nEnd of the analysis, elapsed time=%d s\n",fin-debut); fclose(output); fclose(plotvdiff); } /* main() */