]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EVGEN/AliDimuCombinator.cxx
Works with newio now.
[u/mrichter/AliRoot.git] / EVGEN / AliDimuCombinator.cxx
CommitLineData
4c039060 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
88cb7938 16/* $Id$ */
4c039060 17
675e9664 18/*
19 Class for dimuon analysis and fast dimuon simulation.
20 It provides single and dimuon iterators, cuts, weighting, kinematic
21 It uses the AliRun particle tree.
22 Comments and suggestions to
23 andreas.morsch@cern.ch
24*/
25
f87cfe57 26#include <TClonesArray.h>
d430df3f 27#include <TParticle.h>
116cbefd 28#include <TPDGCode.h>
29#include <TRandom.h>
3b467544 30#include <TTree.h>
5c3fd7ea 31
116cbefd 32#include "AliDimuCombinator.h"
33#include "AliRun.h"
5d12ce38 34#include "AliMC.h"
116cbefd 35
fe4da5cc 36//
dafbc1c5 37ClassImp(AliDimuCombinator)
3b467544 38 AliDimuCombinator::AliDimuCombinator()
f87cfe57 39{
40// Constructor
3b467544 41 fNParticle = (Int_t) (gAlice->TreeK())->GetEntries();
42 fImuon1 = 0;
43 fImuon2 = 0;
44 fMuon1 = 0;
45 fMuon2 = 0;
d430df3f 46 fImin1 = 0;
47 fImin2 = 0;
48 fImax1 = fNParticle;
49 fImax2 = fNParticle;
3b467544 50 fPtMin = 0;
51 fEtaMin = -10;
52 fEtaMax = -10;
53 fRate1 = 1.;
54 fRate2 = 1.;
f87cfe57 55}
56
57AliDimuCombinator::AliDimuCombinator(const AliDimuCombinator & combinator)
198bb1c7 58 :TObject(combinator)
f87cfe57 59{
675e9664 60// Dummy copy constructor
198bb1c7 61 combinator.Copy(*this);
f87cfe57 62}
63
64
fe4da5cc 65//
66// Iterators
67//
3b467544 68TParticle* AliDimuCombinator::Particle(Int_t i)
69{
5d12ce38 70 return gAlice->GetMCApp()->Particle(i);
3b467544 71}
72
f87cfe57 73TParticle* AliDimuCombinator::FirstMuon()
74{
75// Single muon iterator: initialisation
3b467544 76 fImuon1 = fImin1;
77 fMuon1 = Particle(fImuon1);
78 while(Type(fMuon1) != kMuonPlus && Type(fMuon1) != kMuonMinus) {
d430df3f 79 fImuon1++;
3b467544 80 if (fImuon1 >= fImax1) {fMuon1 = 0; break;}
81 fMuon1 = Particle(fImuon1);
f87cfe57 82 }
d430df3f 83 return fMuon1;
f87cfe57 84}
85
86TParticle* AliDimuCombinator::FirstMuonSelected()
87{
88// Single selected muon iterator: initialisation
3b467544 89 TParticle* muon = FirstMuon();
90 while(muon != 0 && !Selected(muon)) {muon = NextMuon();}
f87cfe57 91 return muon;
92}
93
94
95TParticle* AliDimuCombinator::NextMuon()
96{
97// Single muon iterator: increment
d430df3f 98 fImuon1++;
3b467544 99 if (fImuon1 >= fNParticle) {fMuon1 = 0; return fMuon1;}
f87cfe57 100
3b467544 101 fMuon1 = Particle(fImuon1);
102 while(Type(fMuon1) != kMuonPlus && Type(fMuon1) != kMuonMinus) {
d430df3f 103 fImuon1++;
3b467544 104 if (fImuon1 >= fImax1) {fMuon1 = 0; break;}
105 fMuon1 = Particle(fImuon1);
f87cfe57 106 }
d430df3f 107 return fMuon1;
f87cfe57 108}
fe4da5cc 109
1578254f 110TParticle* AliDimuCombinator::NextMuonSelected()
fe4da5cc 111{
f87cfe57 112// Single selected muon iterator: increment
3b467544 113 TParticle * muon = NextMuon();
114 while(muon !=0 && !Selected(muon)) {muon = NextMuon();}
f87cfe57 115 return muon;
fe4da5cc 116}
117
118
f87cfe57 119void AliDimuCombinator::FirstPartner()
120{
121// Helper for dimuon iterator: initialisation
3b467544 122 if (fImin1 == fImin2) {
123 fImuon2 = fImuon1+1;
f87cfe57 124 } else {
3b467544 125 fImuon2 = fImin2;
f87cfe57 126 }
3b467544 127 if (fImuon2 >= fImax2) {fMuon2 = 0; return;}
128 fMuon2 = Particle(fImuon2);
129 while(Type(fMuon2) != kMuonPlus && Type(fMuon2) != kMuonMinus) {
d430df3f 130 fImuon2++;
3b467544 131 if (fImuon2 >= fImax2) {fMuon2 = 0; break;}
132 fMuon2 = Particle(fImuon2);
f87cfe57 133 }
134}
fe4da5cc 135
f87cfe57 136void AliDimuCombinator::FirstPartnerSelected()
137{
138// Helper for selected dimuon iterator: initialisation
139 FirstPartner();
d430df3f 140 while(fMuon2 !=0 && !Selected(fMuon2)) {NextPartner();}
f87cfe57 141}
fe4da5cc 142
fe4da5cc 143
f87cfe57 144void AliDimuCombinator::NextPartner()
145{
146// Helper for dimuon iterator: increment
d430df3f 147 fImuon2++;
3b467544 148 if (fImuon2 >= fImax2) {fMuon2 = 0; return;}
f87cfe57 149
150
3b467544 151 fMuon2 = Particle(fImuon2);
f87cfe57 152
3b467544 153 while(Type(fMuon2) != kMuonPlus && Type(fMuon2) != kMuonMinus) {
d430df3f 154 fImuon2++;
3b467544 155 if (fImuon2 >= fImax2) {fMuon2 = 0; break;}
156 fMuon2 = Particle(fImuon2);
f87cfe57 157 }
158}
fe4da5cc 159
dafbc1c5 160void AliDimuCombinator::NextPartnerSelected()
fe4da5cc 161{
f87cfe57 162// Helper for selected dimuon iterator: increment
163 NextPartner();
d430df3f 164 while(fMuon2 !=0 && !Selected(fMuon2)) {NextPartner();}
fe4da5cc 165}
166
167
f87cfe57 168TParticle* AliDimuCombinator::Partner()
169{
170// Returns current partner for muon to form a dimuon
d430df3f 171 return fMuon2;
f87cfe57 172}
fe4da5cc 173
1578254f 174void AliDimuCombinator::FirstMuonPair(TParticle* & muon1, TParticle* & muon2)
f87cfe57 175{
176// Dimuon iterator: initialisation
177 FirstMuon();
178 FirstPartner();
3b467544 179 muon1 = fMuon1;
180 muon2 = fMuon2;
f87cfe57 181}
182
1578254f 183void AliDimuCombinator::NextMuonPair(TParticle* & muon1, TParticle* & muon2)
f87cfe57 184{
185// Dimuon iterator: increment
186 NextPartner();
187 if (!Partner()) {
188 NextMuon();
189 FirstPartner();
190 }
3b467544 191 muon1 = fMuon1;
192 muon2 = fMuon2;
f87cfe57 193}
194void AliDimuCombinator::FirstMuonPairSelected(TParticle* & muon1,
195 TParticle* & muon2)
196{
197// Selected dimuon iterator: initialisation
198 FirstMuonSelected();
199 FirstPartnerSelected();
3b467544 200 muon1 = fMuon1;
201 muon2 = fMuon2;
f87cfe57 202}
203
204void AliDimuCombinator::NextMuonPairSelected(TParticle* & muon1,
205 TParticle* & muon2)
206{
207// Selected dimuon iterator: increment
208 NextPartnerSelected();
209 if (!Partner()) {
210 NextMuonSelected();
211 FirstPartnerSelected();
212 }
3b467544 213 muon1 = fMuon1;
214 muon2 = fMuon2;
f87cfe57 215}
216
dafbc1c5 217void AliDimuCombinator::ResetRange()
fe4da5cc 218{
f87cfe57 219// Reset index ranges for single muons
3b467544 220 fImin1 = fImin2 = 0;
221 fImax1 = fImax2 = fNParticle;
fe4da5cc 222}
223
dafbc1c5 224void AliDimuCombinator::SetFirstRange(Int_t from, Int_t to)
fe4da5cc 225{
f87cfe57 226// Reset index range for first muon
3b467544 227 fImin1 = from;
228 fImax1 = to;
229 if (fImax1 > fNParticle) fImax1 = fNParticle;
fe4da5cc 230}
231
dafbc1c5 232void AliDimuCombinator::SetSecondRange(Int_t from, Int_t to)
fe4da5cc 233{
f87cfe57 234// Reset index range for second muon
3b467544 235 fImin2 = from;
236 fImax2 = to;
237 if (fImax2 > fNParticle) fImax2 = fNParticle;
fe4da5cc 238}
239//
240// Selection
241//
242
1578254f 243Bool_t AliDimuCombinator::Selected(TParticle* part)
fe4da5cc 244{
f87cfe57 245// Selection cut for single muon
fe4da5cc 246//
3b467544 247 if (part == 0) {return 0;}
fe4da5cc 248
3b467544 249 if (part->Pt() > fPtMin && part->Eta() > fEtaMin && part->Eta() < fEtaMax) {
fe4da5cc 250 return 1;
251 } else {
252 return 0;
253 }
fe4da5cc 254}
255
1578254f 256Bool_t AliDimuCombinator::Selected(TParticle* part1, TParticle* part2)
fe4da5cc 257{
f87cfe57 258// Selection cut for dimuons
259//
fe4da5cc 260 return Selected(part1)*Selected(part2);
261}
262//
263// Kinematics
264//
1578254f 265Float_t AliDimuCombinator::Mass(TParticle* part1, TParticle* part2)
fe4da5cc 266{
f87cfe57 267// Invariant mass
268//
fe4da5cc 269 Float_t px,py,pz,e;
3b467544 270 px = part1->Px()+part2->Px();
271 py = part1->Py()+part2->Py();
272 pz = part1->Pz()+part2->Pz();
273 e = part1->Energy()+part2->Energy();
274 Float_t p = px*px+py*py+pz*pz;
fe4da5cc 275 if (e*e < p) {
276 return -1;
277 } else {
278 return TMath::Sqrt(e*e-p);
279 }
280}
281
1578254f 282Float_t AliDimuCombinator::PT(TParticle* part1, TParticle* part2)
fe4da5cc 283{
f87cfe57 284// Transverse momentum of dimuons
285//
fe4da5cc 286 Float_t px,py;
3b467544 287 px = part1->Px()+part2->Px();
288 py = part1->Py()+part2->Py();
fe4da5cc 289 return TMath::Sqrt(px*px+py*py);
290}
291
1578254f 292Float_t AliDimuCombinator::Pz(TParticle* part1, TParticle* part2)
fe4da5cc 293{
f87cfe57 294// Pz of dimuon system
295//
1578254f 296 return part1->Pz()+part2->Pz();
fe4da5cc 297}
298
1578254f 299Float_t AliDimuCombinator::Y(TParticle* part1, TParticle* part2)
fe4da5cc 300{
f87cfe57 301// Rapidity of dimuon system
302//
fe4da5cc 303 Float_t pz,e;
3b467544 304 pz = part1->Pz()+part2->Pz();
305 e = part1->Energy()+part2->Energy();
fe4da5cc 306 return 0.5*TMath::Log((e+pz)/(e-pz));
307}
308// Response
309//
dafbc1c5 310void AliDimuCombinator::SmearGauss(Float_t width, Float_t & value)
fe4da5cc 311{
f87cfe57 312// Apply gaussian smearing
313//
fe4da5cc 314 value+=gRandom->Gaus(0, width);
315}
316// Weighting
317//
318
f87cfe57 319Float_t AliDimuCombinator::DecayProbability(TParticle* part)
fe4da5cc 320{
f87cfe57 321// Calculate decay probability for muons from pion and kaon decays
322//
8e697b5c 323
f87cfe57 324 Float_t d, h, theta, cTau;
1578254f 325 TParticle* parent = Parent(part);
3b467544 326 Int_t ipar = Type(parent);
327 if (ipar == kPiPlus || ipar == kPiMinus) {
f87cfe57 328 cTau=780.4;
3b467544 329 } else if (ipar == kKPlus || ipar == kKMinus) {
330 cTau = 370.9;
7d566a7d 331 } else {
3b467544 332 cTau = 0;
7d566a7d 333 }
334
335
f87cfe57 336 Float_t gammaBeta=(parent->P())/(parent->GetMass());
7d566a7d 337//
338// this part is still very ALICE muon-arm specific
339//
8e697b5c 340
341
3b467544 342 theta = parent->Theta();
343 h = 90*TMath::Tan(theta);
7d566a7d 344
345 if (h<4) {
346 d=4/TMath::Sin(theta);
fe4da5cc 347 } else {
7d566a7d 348 d=90/TMath::Cos(theta);
349 }
350
f87cfe57 351 if (cTau > 0) {
352 return 1-TMath::Exp(-d/cTau/gammaBeta);
7d566a7d 353 } else {
354 return 1;
fe4da5cc 355 }
356}
357
8e697b5c 358//Begin_Html
359/*
360<p> In the the code above :
361<P>If h is less than 4 cm, pions or kaons go in the beam pipe and can have a long way
362<BR>If h is greater than 4 cm, pions or kaons crash into the front absorber
363<P><IMG SRC="absorbeur.jpg" HEIGHT=292 WIDTH=819>
364*/
365//End_Html
366
367
1578254f 368Float_t AliDimuCombinator::Weight(TParticle* part1, TParticle* part2)
7d566a7d 369{
f87cfe57 370// Dimuon weight
371
3b467544 372 Float_t wgt = (part1->GetWeight())*(part2->GetWeight());
7d566a7d 373
374 if (Correlated(part1, part2)) {
90eb4540 375 if ( part1->GetFirstMother() == part2->GetFirstMother()) {
376 return part1->GetWeight()*fRate1;
377 } else {
378 return wgt/(Parent(part1)->GetWeight())*fRate1;
379 }
7d566a7d 380 } else {
381 return wgt*fRate1*fRate2;
382 }
383}
384
8e697b5c 385//Begin_Html
386/*
387<p>Some clarifications on the calculation of the dimuons weight :
388<P>We must keep in mind that if we force the meson decay in muons and we put
389lot of mesons (J/psi, upsilon, ...) to have a good statistic we are
390obliged to calculate different weights to correct the number
391of muons
392<BR>&nbsp;
393<P>First -->
394<BR>The particle weight is given by w=R*M*Br
395<BR>&nbsp;with&nbsp; :
396<UL>R&nbsp;&nbsp; =&nbsp; the rate by event. This number gives the number
397of produced J/psi, upsilon, pion ... in a collision.
398<BR>It corresponds of the weight 0.06 given for example in&nbsp; gener->AddGenerator(jpsi,"J/Psi",
3990.06); from the config.C macro.
400<BR>In this example R=0.06
401
402<P>M&nbsp; = the rate of the mother production. This number depend on :
403<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - the number of generated events --> fParentWeight=1./Float_t(fNpart) in AliGenPythia.cxx . This
404is a normalization to 1 of the number of generated particles.
405<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - the kinematic bias coming
406from the y and Pt cuts.&nbsp; Method&nbsp; AliGenPythia::AdjustWeights() in AliGenPythia.cxx
407<BR>(in AliGenParam.cxx this 2 things are taken into account in fParentWeight
408= fYWgt*fPtWgt*phiWgt/fNpart )
409
410<P>Br = the branching ratio in muon from the mother decay</UL>
411
412<P><BR>In this method, part->GetWeight() = M*Br
413<UL>&nbsp;</UL>
414Next -->
415<BR>The weight of the dimuon depends on the correlation between muons
416<BR>&nbsp;
417<UL>If the muons are correlated and come from a resonance (for example
418J/psi -> mu+ mu-) , the weight of the dimuon is the weight of one muon then
419<BR>w12= R*M*Br = w1* R1 (in this method this gives part1->GetWeight()*fRate1)
420
421<P>If the muons are correlated and come from a charm or a bottom pair then
422w12 = M*R*Br1*Br2 = w1*w2*R1/M1
423<BR>(in this method this gives wgt/(Parent(part1)->GetWeight())*fRate1).
424Indeed the 2 muons come from the same mother so the
425<BR>weight of a DD~ or BB~ is M*Br and they are no correlation in the decay
426(Br1*Br2)
427
428<P>If the muons are not correlated w12 = M1*M2*R1*R2*Br1*Br2 = w1*w2*R1*R2
429(in this method this gives wgt*fRate1*fRate2)
430<BR>&nbsp;</UL>
431*/
432//End_Html
433
7d566a7d 434
1578254f 435Float_t AliDimuCombinator::Weight(TParticle* part)
fe4da5cc 436{
f87cfe57 437// Single muon weight
1578254f 438 return (part->GetWeight())*(Parent(part)->GetWeight())*fRate1;
7d566a7d 439}
f87cfe57 440
1578254f 441Bool_t AliDimuCombinator::Correlated(TParticle* part1, TParticle* part2)
7d566a7d 442{
f87cfe57 443// Check if muons are correlated
444//
90eb4540 445 if ((Origin(part1) >= 0) && Origin(part1) == Origin(part2)) {
446/*
447 printf("\n origin %d %d ",
448 Type(Particle(Origin(part1))),
449 Type(Particle(Origin(part2))));
450 printf("\n parent %d %d \n \n ",
451 Type(Parent(part1)),
452 Type(Parent(part2)));
453*/
7d566a7d 454 return kTRUE;
455 } else {
456 return kFALSE;
457 }
458}
1578254f 459
460TParticle* AliDimuCombinator::Parent(TParticle* part)
7d566a7d 461{
f87cfe57 462// Return pointer to parent
463//
3b467544 464 return Particle(part->GetFirstMother());
7d566a7d 465}
466
1578254f 467Int_t AliDimuCombinator::Origin(TParticle* part)
7d566a7d 468{
f87cfe57 469// Return pointer to primary particle
470//
1578254f 471 Int_t iparent= part->GetFirstMother();
7d566a7d 472 if (iparent < 0) return iparent;
473 Int_t ip;
474 while(1) {
3b467544 475 ip = (Particle(iparent))->GetFirstMother();
7d566a7d 476 if (ip < 0) {
477 break;
478 } else {
3b467544 479 iparent = ip;
7d566a7d 480 }
481 }
482 return iparent;
fe4da5cc 483}
484
d430df3f 485Int_t AliDimuCombinator::Type(TParticle *part)
486{
487// Return particle type for
488return part->GetPdgCode();
489}
490
f87cfe57 491AliDimuCombinator& AliDimuCombinator::operator=(const AliDimuCombinator& rhs)
492{
493// Assignment operator
198bb1c7 494 rhs.Copy(*this);
f87cfe57 495 return *this;
496}
497
498
198bb1c7 499void AliDimuCombinator::Copy(AliDimuCombinator&) const
675e9664 500{
501 //
198bb1c7 502 // Copy
675e9664 503 //
504 Fatal("Copy","Not implemented!\n");
505}
f87cfe57 506
507
508
509
510