laura is hosted by Hepforge, IPPP Durham

Ticket #7: CalcMultiPhaseSpace.C

File CalcMultiPhaseSpace.C, 8.2 KB (added by John Back, 10 years ago)

ROOT macro used to calculate and parameterise the 4pi phase space integral

Line 
1// Calculate the multibody phase space integral (4pi or "rho,rho")
2// for the K-matrix
3
4double mPi = 0.13957018;
5double mPiSq = mPi*mPi;
6double mPiSq4 = 4.0*mPiSq;
7double mPiSq16 = 16.0*mPiSq;
8double mPi2 = 2.0*mPi;
9double mPi4 = 4.0*mPi;
10double pi = acos(-1.0);
11double piSq = pi*pi;
12
13TCanvas* theCanvas = new TCanvas("theCanvas", "", 800, 600);
14
15void CalcMultiPhaseSpace() {
16
17    // Here, s is the invariant mass-squared of the whole system
18    // while s1 and s2 are the invariant mass-squared of the two di-pion
19    // parts
20    // Width Gamma(s) = rho_1^3, where rho_1  = sqrt(1.0 - 4*m_pi^2/s)
21    // For a given s, s1 can vary between (2m_pi)^2 and s, while s2 varies
22    // between (2m_pi)^2 and sqrt(s1) - sqrt(s), since m_0 >= m_1 + m_2
23    // and s = m_0^2, s1 = m_1^2, s2 = m_2^2
24
25    // Find the phase space multi-integral for s between ~0 and 1
26    double ds = 1e-3;
27    double sMin = 0.0; //mPiSq16;
28    double sMax = 1.0 + 2.0*ds;
29    int N0 = int((sMax - sMin)/ds);
30    cout<<"N0 = "<<N0<<endl;
31
32    // The nominal pole mass of the rho meson
33    double M = 0.775;
34    double MSq = M*M;
35
36    // Do the double integral
37    int i, j, k;
38
39    double ds1 = 1e-3;
40    double ds2 = 1e-3;
41
42    double s1Min = mPiSq4; // (2*m_pi)^2
43    double s2Min = mPiSq4;
44
45    // Create a graph for the values
46    theCanvas->Clear();
47    gROOT->SetStyle("Plain");
48    gStyle->SetOptStat(0);
49    theCanvas->UseCurrentStyle();
50
51    TGraph* graph = new TGraph(N0);
52
53    for (i = 0; i < N0; i++) {
54
55        if (i%100 == 0) {cout<<"i = "<<N0 - i <<endl;}
56
57        double s = sMin + ds*i;
58        double integral(0.0);
59
60        if (s < 0.0) {continue;}
61 
62        // sqrt(s1) will vary between 2*mpi and sqrt(s) - 2*mpi.
63        // The 2*mpi factor is due to the minimum mass needed for s2.
64        double roots_2mpi = sqrt(s) - mPi2;
65        double s1Max = roots_2mpi*roots_2mpi;
66        //cout<<"s1Min = "<<s1Min<<", s1Max = "<<s1Max<<endl;
67
68        int N1 = int((s1Max - s1Min)/ds1);
69        //cout<<"N1 = "<<N1<<endl;
70
71        for (j = 0; j < N1; j++) {
72
73            double s1 = s1Min + ds1*j;
74            double gamma1 = getGamma(s1);
75
76            double Ms1 = MSq - s1;
77            double denom1 = Ms1*Ms1 + MSq*gamma1*gamma1;
78
79            // Find the maximum s2 value given s and s1
80            double s2Max(s2Min);
81
82            if (fabs(s) > 1e-10 && fabs(s1) > 1e-10) {
83                s2Max = sqrt(s) - sqrt(s1);
84                s2Max *= s2Max;
85            }
86
87            int N2 = int((s2Max - s2Min)/ds2);
88
89            for (k = 0; k < N2; k++) {
90               
91                double s2 = s2Min + ds2*k;
92                double gamma2 = getGamma(s2);
93
94                double Ms2 = MSq - s2;
95                double denom2 = Ms2*Ms2 + MSq*gamma2*gamma2;
96
97                double denom = s*denom1*denom2;
98               
99                if (fabs(denom) > 1e-10) {
100
101                    double sTerm = s + s1 - s2;
102                    double sqrtTerm = sTerm*sTerm - 4.0*s*s1;
103                   
104                    double num(0.0);
105                   
106                    if (sqrtTerm > 0.0) {
107                        num = gamma1*gamma2*sqrt(sqrtTerm);
108                    }
109
110                    integral += num*ds1*ds2*MSq/(denom*piSq);
111
112
113                } // denom is not zero
114
115            } // k
116
117        } // j
118       
119        cout<<"For i = "<<i<<", s = "<<s<<", integral = "<<integral<<endl;
120        graph->SetPoint(i, s, integral);
121
122    } // i
123
124    // Calculate the phase space factor at s = 1
125    double rho1 = sqrt(1.0 - mPiSq16);
126    // Find the same factor from the graph
127    int pointNo = int((1.0 - sMin)/ds);
128    cout<<"pointNo = "<<pointNo<<endl;
129
130    double sGraph(0.0), rhoGraph(0.0);
131    graph->GetPoint(pointNo, sGraph, rhoGraph);
132
133    // Find the scaling factor rho0
134    double rho0 = rho1/rhoGraph;
135
136    cout<<"For sGraph = "<<sGraph<<", rhoGraph = "
137        <<rhoGraph<<"; rho0 = "<<rho0<<endl;
138
139    // Rescale the graph points
140    for (i = 0; i < N0; i++) {
141
142        double x(0.0);
143        double y(0.0);
144        graph->GetPoint(i, x, y);
145        y *= rho0;
146        graph->SetPoint(i, x, y);
147
148    }
149
150    // Plot the curves
151
152    theCanvas->cd();
153
154    TH2F* nullH = new TH2F("nullH", "", 2, 0.0, 2.0, 2, 0.0, 1.1);
155    nullH->SetXTitle("s (GeV^{2}/c^{4})");
156    nullH->Draw();
157
158    graph->SetMarkerStyle(24);
159    graph->Draw("p");
160
161    // Fit the function to this distribution
162    TF1* fun = new TF1("fun", polFunction, 0.0, 2.0, 7);
163    fun->SetLineColor(kRed);
164    fun->SetParameters(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0);
165
166    graph->Fit("fun");
167
168    // Overlay "old" function
169    TF1* oldFun = new TF1("oldFun", rhoFun, 0.0, 1.0, 1);
170    oldFun->SetParameter(0, 1.0);
171    oldFun->SetLineColor(kBlue);
172    oldFun->Draw("same");
173
174    // Add the continuation from s = 1
175    TF1* endFun = new TF1("endFun", endTerm, 1.0, 2.0, 1);
176    endFun->SetParameter(0, 1.0);
177    endFun->SetLineColor(kGreen);
178    endFun->Draw("same");
179 
180    // Add the continuation from s = 1
181    TF1* endFun2 = new TF1("endFun2", endTerm2, 1.0, 2.0, 1);
182    endFun2->SetParameter(0, 1.0);
183    endFun2->SetLineColor(kOrange+7);
184    endFun2->Draw("same");
185   
186    // Text labels
187    TLatex* latex = new TLatex();
188    latex->SetTextSize(0.03);
189
190    latex->SetTextColor(kBlue);
191    latex->DrawText(1.2, 0.6, "Old Laura++ implementation");
192    latex->SetTextColor(kBlack);
193    latex->DrawText(1.2, 0.5, "New integral calculation");
194    latex->SetTextColor(kRed);
195    latex->DrawText(1.2, 0.4, "New parameterisation");
196
197    latex->SetTextColor(kGreen);
198    latex->DrawText(1.2, 0.3, "Sqrt continuation for s > 1");
199
200    latex->SetTextColor(kOrange+7);
201    latex->DrawText(1.2, 0.2, "Non-sqrt continuation for s > 1");
202
203    theCanvas->Print("Laura_rho4pi.png");
204
205}
206
207double expFunction(double* x, double* par) {
208
209    double s = x[0];
210    double c0 = par[0];
211    double c1 = par[1];
212    double c2 = par[2];
213    double c3 = par[3];
214    double c4 = par[4];
215   
216    double expTerm = (c0*s + c1)*s + c2;
217
218    double rho(0.0);
219
220    if (fabs(expTerm) < 30.0) {
221
222        rho = c3*exp(expTerm) + c4;
223
224    }
225
226    return rho;
227
228}
229
230double polFunction(double* x, double* par) {
231
232    double s = x[0];
233    double c0 = par[0];
234    double c1 = par[1];
235    double c2 = par[2];
236    double c3 = par[3];
237    double c4 = par[4];
238    double c5 = par[5];
239    double c6 = par[6];
240
241    double rho(0.0);
242
243    if (s < 1.0) {
244
245        //rho = (((((c0*s + c1)*s + c2)*s + c3)*s + c4)*s + c5)*s + c6;
246        rho = ((c0*s + c1)*s + c2)*s + c3;
247        rho = ((rho*s + c4)*s + c5)*s + c6;
248
249    } else {
250
251        double ratio(0.0);
252        if (fabs(s) > 1e-10) {
253            ratio = mPiSq16/s;
254        }
255       
256        if (ratio > 0.0 && ratio < 1.0) {
257            rho = sqrt(1.0 - ratio);
258        }
259
260    }
261
262    return rho;
263
264}
265
266double endTerm(double* x, double* par) {
267
268    double s = x[0];
269    double c0 = par[0];
270
271    double ratio(0.0);
272    if (fabs(s) > 1e-10) {
273        ratio = mPiSq16/s;
274    }
275
276    double result(0.0);
277    if (ratio > 0.0 && ratio < 1.0) {
278        result = sqrt(1.0 - ratio);
279    }
280
281    return result;
282
283
284}
285
286double endTerm2(double* x, double* par) {
287
288    double s = x[0];
289    double c0 = par[0];
290
291    double ratio(0.0);
292    if (fabs(s) > 1e-10) {
293        ratio = mPiSq16/s;
294    }
295
296    double result(0.0);
297    if (ratio > 0.0 && ratio < 1.0) {
298        result = 1.0 - ratio;
299    }
300
301    return result;
302
303
304}
305
306double getGamma(double s) {
307
308    // The gamma0 factor is the "width" of the 4pi state.
309    // The PDG tables give 300 MeV as a typical 4pi width, which
310    // is ~75% of the total width, with large uncertainties
311    double gamma0 = 0.3; // 0.3 GeV
312    double rho1 = getRho1(s);
313    double gamma = gamma0*rho1*rho1*rho1;
314    return gamma;
315
316}
317
318double getRho1(double s) {
319
320    double rho(0.0);
321   
322    double term(0.0);
323    if (fabs(s) > 1e-10) {
324        term = 1.0 - (mPiSq4/s);
325    }
326
327    if (fabs(term) > 1e-10) {
328        rho = sqrt(term);
329    }
330
331    return rho;
332
333}
334
335
336double old_rhoFun(double* x, double* par) {
337
338  double rho(0.0);
339  double s = x[0];
340  double A = par[0];
341 
342  if (s <= 1.0) {
343    double term1 = (((11.3153*s - 21.8845)*s + 16.8358)*s - 6.39017)*s + 1.2274;
344    term1 += 0.00370909/(s*s);
345    term1 -= 0.111203/s;
346    double term2 = 0.82965;
347    rho = term1*term2;
348  } else {
349    rho = sqrt(1.0 - (0.311677/s));
350  }
351
352  rho *= A;
353  return rho;
354
355}
356
357Double_t rhoFun(Double_t*x, Double_t* par) {
358
359    double mSqAB = x[0];
360    double A = par[1];
361    double mPi = 0.139570;
362 
363    if (mSqAB > 1.0) {
364        return rho( 4.0 * mPi, mSqAB );
365    }
366 
367    double m4AB = std::pow( mSqAB, 2 );
368    double m6AB = std::pow( mSqAB, 3 );
369    double m8AB = std::pow( mSqAB, 4 );
370   
371    double term = 0.0;
372    term += 0.00370909 / m4AB;
373    term -= 0.111203   / mSqAB;
374    term += 1.2274;
375    term -= 6.39017    * mSqAB;
376    term += 16.8358    * m4AB;
377    term -= 21.8845    * m6AB;
378    term += 11.3153    * m8AB;
379   
380    return rho( 4.0 * mPi, 1.0 ) * term;
381
382}
383
384double rho(double mCh, double mSqAB) {
385
386    double rhoSq = 1.0 - std::pow(mCh, 2)/mSqAB;
387 
388    return std::sqrt(rhoSq);
389
390}
391