a8fbdb358ea9df23cb72f2d9efe91b80441f5be0
[u/mrichter/AliRoot.git] / EVGEN / AliOmegaDalitz.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16
17 /* $Id$ */
18
19
20 #include "AliOmegaDalitz.h"
21 #include <TMath.h>
22 #include <AliLog.h>
23 #include <TH1.h>
24 #include <TPDGCode.h>
25 #include <TRandom.h>
26 #include <TParticle.h>
27 #include <TDatabasePDG.h>
28 #include <TLorentzVector.h>
29 #include <TClonesArray.h>
30
31 ClassImp(AliOmegaDalitz)
32
33
34 //-----------------------------------------------------------------------------
35 //
36 // Generate lepton-pair mass distributions for Dalitz decays according
37 // to the Kroll-Wada parametrization: N. Kroll, W. Wada: Phys. Rev 98(1955)1355
38 //
39 // For the electromagnetic form factor the parameterization from
40 // Lepton-G is used: L.G. Landsberg et al.: Phys. Rep. 128(1985)301
41 //
42 //-----------------------------------------------------------------------------
43 //
44 // Adaption for AliRoot
45 //
46 // R. Averbeck
47 // A. Morsch
48 //
49 AliOmegaDalitz::AliOmegaDalitz():
50         AliDecayer(),
51         fEPMass(0),
52         fMPMass(0)
53 {
54     // Constructor
55 }
56
57 void AliOmegaDalitz::Init()
58 {
59   // Initialisation
60   Int_t    idecay, ibin, nbins = 1000;
61   Double_t min, max, binwidth;
62   Double_t pmass, lmass, omass, emass, mmass;
63   Double_t epsilon, delta, mLL, q, kwHelp, krollWada, formFactor, weight;
64
65   // Get the particle masses
66   // electron
67   emass = (TDatabasePDG::Instance()->GetParticle(kElectron))->Mass();
68   // muon
69   mmass = (TDatabasePDG::Instance()->GetParticle(kMuonPlus))->Mass();
70   // omega
71   pmass = (TDatabasePDG::Instance()->GetParticle(223))      ->Mass();
72   // pi0
73   omass = (TDatabasePDG::Instance()->GetParticle(kPi0))     ->Mass();
74
75   for ( idecay = 1; idecay<=2; idecay++ )
76   {
77     if ( idecay == 1 ) 
78       lmass = emass;
79     else
80       lmass = mmass;
81
82     min = 2.0 * lmass;
83     max = pmass - omass;
84     binwidth = (max - min) / (Double_t)nbins;
85     if ( idecay == 1 ) 
86       fEPMass = new TH1F("fEPMass", "Dalitz electron pair", nbins, min, max);
87     else
88       fMPMass = new TH1F("fMPMass", "Dalitz muon pair", nbins, min, max);
89
90     epsilon = (lmass / pmass) * (lmass / pmass);
91     delta   = (omass / pmass) * (omass / pmass);
92
93     for ( ibin = 1; ibin <= nbins; ibin++ )
94     {
95       mLL = min + (Double_t)(ibin - 1) * binwidth + binwidth / 2.0;
96       q    = (mLL / pmass) * (mLL / pmass);
97       if ( q <= 4.0 * epsilon )
98       {
99         AliFatal("Error in calculating Dalitz mass histogram binning!");
100       } 
101
102       kwHelp = (1.0 + q /  (1.0 - delta)) * (1.0 + q / (1.0 - delta))
103               - 4.0 * q / ((1.0 - delta) * (1.0 - delta));    
104       if ( kwHelp <= 0.0 )
105       {
106         AliFatal("Error in calculating Dalitz mass histogram binning!");
107         if ( idecay == 1 ) 
108           fEPMass = 0;
109         else
110           fMPMass = 0;
111       } 
112       krollWada = (2.0 / mLL) * TMath::Exp(1.5 * TMath::Log(kwHelp))
113                               * TMath::Sqrt(1.0 - 4.0 * epsilon / q)   
114                               * (1.0 + 2.0 * epsilon / q);
115       formFactor = 
116         (TMath::Power(TMath::Power(0.6519,2),2)) 
117         / (TMath::Power(TMath::Power(0.6519,2)-TMath::Power(mLL, 2), 2) 
118            + TMath::Power(0.04198, 2)*TMath::Power(0.6519, 2));
119       weight = krollWada * formFactor;   
120       if ( idecay == 1 ) 
121         fEPMass->AddBinContent(ibin, weight);
122       else
123         fMPMass->AddBinContent(ibin, weight);
124     }
125   }
126 }
127
128
129 void AliOmegaDalitz::Decay(Int_t idlepton, TLorentzVector* pparent)
130 {
131 //-----------------------------------------------------------------------------
132 //
133 //  Generate Omega Dalitz decay
134 //
135 //-----------------------------------------------------------------------------
136
137   Double_t pmass, lmass, omass, lpmass;
138   Double_t e1, p1, e3, p3;
139   Double_t betaSquare, lambda;
140   Double_t costheta, sintheta, cosphi, sinphi, phi;
141   
142   // Get the particle masses
143   // lepton
144   lmass = (TDatabasePDG::Instance()->GetParticle(idlepton))->Mass();
145   // omega
146   pmass = pparent->M();
147   // pi0
148   omass = (TDatabasePDG::Instance()->GetParticle(kPi0))     ->Mass();
149
150   // Sample the lepton pair mass from a histogram
151   for( ;; ) 
152   {
153     if ( idlepton == kElectron )
154       lpmass = fEPMass->GetRandom();
155     else
156       lpmass = fMPMass->GetRandom();
157     if ( pmass - omass > lpmass && lpmass / 2. > lmass ) break;
158   }
159   
160   // lepton pair kinematics in virtual photon rest frame
161   e1 = lpmass / 2.;
162   p1 = TMath::Sqrt((e1 + lmass) * (e1 - lmass));
163   betaSquare = 1.0 - 4.0 * (lmass * lmass) / (lpmass * lpmass);
164   lambda      = betaSquare / (2.0 - betaSquare);
165   costheta = (2.0 * gRandom->Rndm()) - 1.;
166   sintheta = TMath::Sqrt((1. + costheta) * (1. - costheta));
167   phi      = 2.0 * TMath::ACos(-1.) * gRandom->Rndm();
168   sinphi   = TMath::Sin(phi);
169   cosphi   = TMath::Cos(phi);
170   // momentum vectors of leptons in virtual photon rest frame
171   Double_t pProd1[3] = {p1 * sintheta * cosphi, 
172                        p1 * sintheta * sinphi, 
173                        p1 * costheta};
174   Double_t pProd2[3] = {-1.0 * p1 * sintheta * cosphi, 
175                        -1.0 * p1 * sintheta * sinphi, 
176                        -1.0 * p1 * costheta};
177   
178   // pizero kinematics in omega rest frame
179   e3       = (pmass * pmass + omass * omass - lpmass * lpmass)/(2. * pmass);
180   p3       = TMath::Sqrt((e3 + omass)  * (e3 - omass));
181   costheta = (2.0 * gRandom->Rndm()) - 1.;
182   sintheta = TMath::Sqrt((1. + costheta) * (1. - costheta));
183   phi      = 2.0 * TMath::ACos(-1.) * gRandom->Rndm();
184   sinphi   = TMath::Sin(phi);
185   cosphi   = TMath::Cos(phi);       
186   // pizero 4-vector in omega rest frame
187   fProducts[2].SetPx(p3 * sintheta * cosphi);
188   fProducts[2].SetPy(p3 * sintheta * sinphi);
189   fProducts[2].SetPz(p3 * costheta);
190   fProducts[2].SetE(e3);
191
192   // lepton 4-vectors in properly rotated virtual photon rest frame
193   Double_t pRot1[3] = {0.};
194   Rot(pProd1, pRot1, costheta, -sintheta, -cosphi, -sinphi);
195   Double_t pRot2[3] = {0.};
196   Rot(pProd2, pRot2, costheta, -sintheta, -cosphi, -sinphi); 
197   fProducts[0].SetPx(pRot1[0]);
198   fProducts[0].SetPy(pRot1[1]);
199   fProducts[0].SetPz(pRot1[2]);
200   fProducts[0].SetE(e1);
201   fProducts[1].SetPx(pRot2[0]);
202   fProducts[1].SetPy(pRot2[1]);
203   fProducts[1].SetPz(pRot2[2]);
204   fProducts[1].SetE(e1);
205
206   // boost the dilepton into the omega's rest frame 
207   Double_t eLPparent = TMath::Sqrt(p3 * p3 + lpmass * lpmass);
208   TVector3 boostPair( -1.0 * fProducts[2].Px() / eLPparent, 
209                       -1.0 * fProducts[2].Py() / eLPparent,
210                       -1.0 * fProducts[2].Pz() / eLPparent);
211   fProducts[0].Boost(boostPair);
212   fProducts[1].Boost(boostPair);
213
214   // boost all decay products into the lab frame 
215   TVector3 boostLab( pparent->Px() / pparent->E(), 
216                      pparent->Py() / pparent->E(),
217                      pparent->Pz() / pparent->E());
218   fProducts[0].Boost(boostLab);
219   fProducts[1].Boost(boostLab);
220   fProducts[2].Boost(boostLab);
221   
222   return;
223
224 }
225
226 Int_t AliOmegaDalitz::ImportParticles(TClonesArray *particles)
227 {
228     // Import TParticles in array particles
229     // l+ l- pi0
230     
231     TClonesArray &clonesParticles = *particles;
232
233     Int_t pdg   [3] = {kElectron, -kElectron, kPi0};
234     if ( fProducts[1].M() > 0.001 ) 
235     {  
236       pdg[0] =  kMuonPlus;
237       pdg[1] = -kMuonPlus;
238     }
239     Int_t parent[3] = {0, 0, -1};
240     Int_t d1    [3] = {-1, -1, 1};
241     Int_t d2    [3] = {-1, -1, 2};
242     for (Int_t i = 2; i > -1; i--) {
243         Double_t px = fProducts[i].Px();
244         Double_t py = fProducts[i].Py();
245         Double_t pz = fProducts[i].Pz();
246         Double_t e  = fProducts[i].E();
247         //
248         new(clonesParticles[2 - i]) TParticle(pdg[i], 1, parent[i], -1, d1[i], d2[i], px, py, pz, e, 0., 0., 0., 0.);
249     }
250     return (3);
251 }
252
253
254 void AliOmegaDalitz::
255 Rot(Double_t pin[3], Double_t pout[3], Double_t costheta, Double_t sintheta,
256     Double_t cosphi, Double_t sinphi)
257 {
258   pout[0] = pin[0]*costheta*cosphi-pin[1]*sinphi+pin[2]*sintheta*cosphi;
259   pout[1] = pin[0]*costheta*sinphi+pin[1]*cosphi+pin[2]*sintheta*sinphi;
260   pout[2] = -1.0  * pin[0] * sintheta + pin[2] * costheta;
261   return;
262 }
263
264 void AliOmegaDalitz::Decay(TClonesArray* array)
265 {
266   //
267   // Replace all omega dalitz decays with the correct matrix element decays
268   //
269   printf("-->Correcting Dalitz \n");
270   Int_t nt = array->GetEntriesFast();
271   TParticle* dp[3];
272   for (Int_t i = 0; i < nt; i++) {
273     TParticle* part = (TParticle*) (array->At(i));
274     if (part->GetPdgCode() != 223)                     continue;
275     
276     Int_t fd = part->GetFirstDaughter() - 1;
277     Int_t ld = part->GetLastDaughter()  - 1;
278
279     if (fd < 0)                                        continue;
280     if ((ld - fd) != 2)                                continue;
281
282     for (Int_t j = 0; j < 3; j++) dp[j] = (TParticle*) (array->At(fd+j));
283     if ((dp[0]->GetPdgCode() != kPi0) ||
284         ((TMath::Abs(dp[1]->GetPdgCode()) != kElectron) &&
285          (TMath::Abs(dp[1]->GetPdgCode()) != kMuonPlus))) continue;
286     TLorentzVector omega(part->Px(), part->Py(), part->Pz(), part->Energy());
287     if ( TMath::Abs(dp[1]->GetPdgCode()) == kElectron ) 
288       Decay(kElectron, &omega);
289     else
290       Decay(kMuonPlus, &omega);
291     for (Int_t j = 0; j < 3; j++) dp[j]->SetMomentum(fProducts[2-j]);
292     printf("original %13.3f %13.3f %13.3f %13.3f \n", 
293            part->Px(), part->Py(), part->Pz(), part->Energy());
294     printf("new       %13.3f %13.3f %13.3f %13.3f \n", 
295            dp[0]->Px()+dp[1]->Px()+dp[2]->Px(), 
296            dp[0]->Py()+dp[1]->Py()+dp[2]->Py(), 
297            dp[0]->Pz()+dp[1]->Pz()+dp[2]->Pz(), 
298            dp[0]->Energy()+dp[1]->Energy()+dp[2]->Energy());
299
300
301   }
302 }
303 AliOmegaDalitz& AliOmegaDalitz::operator=(const  AliOmegaDalitz& rhs)
304 {
305 // Assignment operator
306     rhs.Copy(*this);
307     return *this;
308 }
309
310 void AliOmegaDalitz::Copy(TObject&) const
311 {
312     //
313     // Copy 
314     //
315     Fatal("Copy","Not implemented!\n");
316 }
317
318 AliOmegaDalitz::AliOmegaDalitz(const AliOmegaDalitz &dalitz)
319   : AliDecayer(),
320     fEPMass(0),
321     fMPMass(0)
322 {
323   // Copy constructor
324   dalitz.Copy(*this);
325 }