1 // AliAODDimuon: a class for AODs for the MUON Arm of the ALICE Experiment
2 // Author: P. Cortese, Universita' del Piemonte Orientale in Alessandria and
3 // INFN of Torino - Italy
5 // The class defines a dimuon pair object from two AliAODTrack objects.
6 // AliAODDimuon objects are supposed to be added to the AliAODEvent structure
7 // during analysis. They would then allow to calculate the dimuon-related
8 // kinematic variables with a minimal disk occupancy.
9 // The payload of the class has been reduced to two pointers to the two
10 // tracks with the addition of a pointer to the AliAODEventInfo. An instance of
11 // this class has also to be added to the AliAODEvent structure to provide
12 // additional information that is specific to MUON and therefore has not been
13 // included into the AOD header.
14 // Two transient data members are not stored on file as they can be recomputed
18 #include "AliAODDimuon.h"
19 #include "TLorentzVector.h"
20 #define AliAODDimuon_CXX
22 ClassImp(AliAODDimuon)
24 //______________________________________________________________________________
25 AliAODDimuon::AliAODDimuon():AliVParticle(),fEi(0),fP(0),fMProton(0.93827231)
27 // default constructor
32 //______________________________________________________________________________
33 AliAODDimuon::AliAODDimuon(const AliAODDimuon& dimu):
35 fEi(dimu.fEi),fP(0),fMProton(0.93827231)
42 //______________________________________________________________________________
43 AliAODDimuon &AliAODDimuon::operator=(const AliAODDimuon& dimu)
45 // assignment operator
56 //______________________________________________________________________________
57 AliAODDimuon::AliAODDimuon(TObject *mu0, TObject *mu1, TObject *ei):
58 fP(0),fMProton(0.93827231)
60 // Creates a dimuon pair from two tracks and the EventInfo
62 //printf("Creating dimuon from %p %p\n",mu0,mu1);
68 //______________________________________________________________________________
69 AliAODDimuon::~AliAODDimuon()
76 //______________________________________________________________________________
77 void AliAODDimuon::BookP(){
78 // Fills the dimuon momentum if not filled yet
79 static UInt_t unID[2]={0,0};
81 fP=new TLorentzVector(Px(),Py(),Pz(),E());
82 unID[0]=fMu[0].GetUniqueID();
83 unID[1]=fMu[1].GetUniqueID();
85 // For efficiency reasons
86 if((unID[0]!=fMu[0].GetUniqueID())||(unID[1]!=fMu[1].GetUniqueID())){
87 fP->SetPxPyPzE(Px(),Py(),Pz(),E());
88 unID[0]=fMu[0].GetUniqueID();
89 unID[1]=fMu[1].GetUniqueID();
93 //______________________________________________________________________________
94 Double_t AliAODDimuon::Px() const {
96 if(this->CheckPointers())return -999999999;
97 return ((AliAODTrack*)fMu[0].GetObject())->Px()+
98 ((AliAODTrack*)fMu[1].GetObject())->Px();
101 //______________________________________________________________________________
102 Double_t AliAODDimuon::Py() const {
104 if(this->CheckPointers())return -999999999;
105 return ((AliAODTrack*)fMu[0].GetObject())->Py()+
106 ((AliAODTrack*)fMu[1].GetObject())->Py();
109 //______________________________________________________________________________
110 Double_t AliAODDimuon::Pz() const {
112 if(this->CheckPointers())return -999999999;
113 return ((AliAODTrack*)fMu[0].GetObject())->Pz()+
114 ((AliAODTrack*)fMu[1].GetObject())->Pz();
117 //______________________________________________________________________________
118 Double_t AliAODDimuon::Pt() const {
120 if(this->CheckPointers())return -999999999;
123 return TMath::Sqrt(px*px+py*py);
127 //______________________________________________________________________________
128 Double_t AliAODDimuon::E() const {
130 if(this->CheckPointers())return -999999999;
131 return ((AliAODTrack*)fMu[0].GetObject())->E()+
132 ((AliAODTrack*)fMu[1].GetObject())->E();
135 //______________________________________________________________________________
136 Double_t AliAODDimuon::P() const {
137 // This is just to override the virtual function
138 printf("You should never call: Double_t AliAODDimuon::P() const\n");
142 //______________________________________________________________________________
143 Double_t AliAODDimuon::P() {
145 if(this->CheckPointers())return -999999999;
150 //______________________________________________________________________________
151 Double_t AliAODDimuon::M() const {
152 // This is just to override the virtual function
153 printf("You should never call: Double_t AliAODDimuon::M() const\n");
157 //______________________________________________________________________________
158 Double_t AliAODDimuon::M() {
159 // Dimuon invariant mass
160 if(this->CheckPointers())return -999999999;
165 //______________________________________________________________________________
166 Double_t AliAODDimuon::Mass() {
167 // Dimuon invariant mass
168 if(this->CheckPointers())return -999999999;
173 //______________________________________________________________________________
174 Double_t AliAODDimuon::Eta() const {
175 // This is just to override the virtual function
176 printf("You should never call: Double_t AliAODDimuon::Eta() const\n");
180 //______________________________________________________________________________
181 Double_t AliAODDimuon::Eta() {
182 // Dimuon pseudorapidity
183 if(this->CheckPointers())return -999999999;
188 //______________________________________________________________________________
189 Double_t AliAODDimuon::Phi() const {
190 // This is just to override the virtual function
191 printf("You should never call: Double_t AliAODDimuon::Phi() const\n");
195 //______________________________________________________________________________
196 Double_t AliAODDimuon::Phi() {
197 // Dimuon asimuthal angle
198 if(this->CheckPointers())return -999999999;
202 //______________________________________________________________________________
203 Double_t AliAODDimuon::Theta() const {
204 // This is just to override the virtual function
205 printf("You should never call: Double_t AliAODDimuon::Theta() const\n");
209 //______________________________________________________________________________
210 Double_t AliAODDimuon::Theta() {
211 // Dimuon polar angle
212 if(this->CheckPointers())return -999999999;
217 //______________________________________________________________________________
218 Double_t AliAODDimuon::Y() const {
219 // This is just to override the virtual function
220 printf("You should never call: Double_t AliAODDimuon::Y() const\n");
224 //______________________________________________________________________________
225 Double_t AliAODDimuon::Y() {
227 if(this->CheckPointers())return -999999999;
229 return fP->Rapidity();
232 //______________________________________________________________________________
233 Short_t AliAODDimuon::Charge() const {
235 if(this->CheckPointers())return -999;
236 return ((AliAODTrack*)fMu[0].GetObject())->Charge()+
237 ((AliAODTrack*)fMu[1].GetObject())->Charge();
240 //______________________________________________________________________________
241 Int_t AliAODDimuon::CheckPointers() const{
242 // Checks if the track pointers have been initialized
243 if(fMu[0]==0||fMu[1]==0){
244 printf("Dimuon not initialized\n");
247 if((fMu[0].GetObject())==0||(fMu[1].GetObject())==0){
248 printf("Can not get objects. Got: %p %p\n",fMu[0].GetObject(),fMu[1].GetObject());
254 //______________________________________________________________________________
255 void AliAODDimuon::SetMu(Int_t imu, AliAODTrack *mu){
256 // Assign a track pointer
262 //______________________________________________________________________________
263 void AliAODDimuon::SetMuons(AliAODTrack *mu0, AliAODTrack *mu1){
264 // Assign the track pointers
269 //______________________________________________________________________________
270 Double_t AliAODDimuon::XF() {
272 Double_t ebeam=((AliAODEventInfo*)fEi.GetObject())->EBeam();
274 printf("AliAODDimuon::xf: can not compute xf with EBeam=%f\n",ebeam);
277 if(this->CheckPointers())return -999999999;
280 Double_t pMax=TMath::Sqrt(ebeam*ebeam-mDimu*mDimu);
284 //______________________________________________________________________________
285 // Calculation the Collins-Soper angle (adapted from code by R. Arnaldi)
286 Double_t AliAODDimuon::CostCS(){
287 // Cosinus of the Collins-Soper polar decay angle
288 if(CheckPointers())return -999999999;
290 printf("Pointer to MuonHeader not initialized\n");
293 if(fEi.GetObject()==0){
294 printf("Can not get MuonHeader object\n");
297 Double_t ebeam=((AliAODEventInfo*)fEi.GetObject())->EBeam();
299 printf("Can not compute costCS with EBeam=%f\n",ebeam);
302 Double_t mp=fMProton;
303 Double_t pbeam=TMath::Sqrt(ebeam*ebeam-mp*mp);
304 Double_t pla10=((AliAODTrack*)fMu[0].GetObject())->Px();
305 Double_t pla11=((AliAODTrack*)fMu[0].GetObject())->Py();
306 Double_t pla12=((AliAODTrack*)fMu[0].GetObject())->Pz();
307 Double_t e1=((AliAODTrack*)fMu[0].GetObject())->E();
308 Double_t mu1Charge=((AliAODTrack*)fMu[0].GetObject())->Charge();
309 Double_t pla20=((AliAODTrack*)fMu[1].GetObject())->Px();
310 Double_t pla21=((AliAODTrack*)fMu[1].GetObject())->Py();
311 Double_t pla22=((AliAODTrack*)fMu[1].GetObject())->Pz();
312 Double_t e2=((AliAODTrack*)fMu[1].GetObject())->E();
313 Double_t mu2Charge=((AliAODTrack*)fMu[1].GetObject())->Charge();
315 // Fill the Lorentz vector for projectile and target
316 // For the moment we do not consider the crossing angle
317 // Projectile runs towards the MUON arm
318 TLorentzVector pProjLab(0.,0.,-pbeam,ebeam); // projectile
319 TLorentzVector pTargLab(0.,0., pbeam,ebeam); // target
321 // --- Get the muons parameters in the LAB frame
323 TLorentzVector pMu1Lab(pla10,pla11,pla12,e1);
324 TLorentzVector pMu2Lab(pla20,pla21,pla22,e2);
326 // --- Obtain the dimuon parameters in the LAB frame
328 TLorentzVector pDimuLab=pMu1Lab+pMu2Lab;
330 // --- Translate the dimuon parameters in the dimuon rest frame
332 TVector3 beta=(-1./pDimuLab.E())*pDimuLab.Vect();
333 TLorentzVector pMu1Dimu=pMu1Lab;
334 TLorentzVector pMu2Dimu=pMu2Lab;
335 TLorentzVector pProjDimu=pProjLab;
336 TLorentzVector pTargDimu=pTargLab;
337 pMu1Dimu.Boost(beta);
338 pMu2Dimu.Boost(beta);
339 pProjDimu.Boost(beta);
340 pTargDimu.Boost(beta);
342 // --- Determine the z axis for the CS angle
344 TVector3 zaxisCS=(((pProjDimu.Vect()).Unit())-((pTargDimu.Vect()).Unit())).Unit();
346 // --- Determine the CS angle (angle between mu+ and the z axis defined above)
350 cost = zaxisCS.Dot((pMu1Dimu.Vect()).Unit());
351 // Theta CS is not properly defined for Like-Sign muons
352 if(mu2Charge > 0 && cost<0) cost=-cost;
354 // Theta CS is not properly defined for Like-Sign muons
355 cost = zaxisCS.Dot((pMu2Dimu.Vect()).Unit());
356 if(mu2Charge < 0 && cost<0) cost=-cost;
361 //______________________________________________________________________________
362 // Calculation the Helicity polarization angle (adapted from code by R. Arnaldi)
363 Double_t AliAODDimuon::CostHe(){
364 // Cosinus of the polar decay angle in the Helicity reference frame
365 if(CheckPointers())return -999999999;
367 printf("Pointer to MuonHeader not initialized\n");
370 if(fEi.GetObject()==0){
371 printf("Can not get MuonHeader object\n");
374 Double_t ebeam=((AliAODEventInfo*)fEi.GetObject())->EBeam();
376 printf("Can not compute costCS with EBeam=%f\n",ebeam);
379 Double_t pbeam=TMath::Sqrt(ebeam*ebeam-fMProton*fMProton);
380 Double_t pla10=((AliAODTrack*)fMu[0].GetObject())->Px();
381 Double_t pla11=((AliAODTrack*)fMu[0].GetObject())->Py();
382 Double_t pla12=((AliAODTrack*)fMu[0].GetObject())->Pz();
383 Double_t e1=((AliAODTrack*)fMu[0].GetObject())->E();
384 Double_t mu1Charge=((AliAODTrack*)fMu[0].GetObject())->Charge();
385 Double_t pla20=((AliAODTrack*)fMu[1].GetObject())->Px();
386 Double_t pla21=((AliAODTrack*)fMu[1].GetObject())->Py();
387 Double_t pla22=((AliAODTrack*)fMu[1].GetObject())->Pz();
388 Double_t e2=((AliAODTrack*)fMu[1].GetObject())->E();
389 Double_t mu2Charge=((AliAODTrack*)fMu[1].GetObject())->Charge();
391 // Fill the Lorentz vector for projectile and target
392 // For the moment we consider no crossing angle
393 // Projectile runs towards the MUON arm
394 TLorentzVector pProjLab(0.,0.,-pbeam,ebeam); // projectile
395 TLorentzVector pTargLab(0.,0., pbeam,ebeam); // target
397 // --- Get the muons parameters in the LAB frame
399 TLorentzVector pMu1Lab(pla10,pla11,pla12,e1);
400 TLorentzVector pMu2Lab(pla20,pla21,pla22,e2);
402 // --- Obtain the dimuon parameters in the LAB frame
404 TLorentzVector pDimuLab=pMu1Lab+pMu2Lab;
406 // --- Translate the dimuon parameters in the dimuon rest frame
408 TVector3 beta=(-1./pDimuLab.E())*pDimuLab.Vect();
409 TLorentzVector pMu1Dimu=pMu1Lab;
410 TLorentzVector pMu2Dimu=pMu2Lab;
411 pMu1Dimu.Boost(beta);
412 pMu2Dimu.Boost(beta);
414 // --- Translate the dimuon parameters in the CM frame
416 TLorentzVector pDimuCM; //CM frame
418 beta2=(-1./(fMProton+pProjLab.E()))*pProjLab.Vect();
420 pDimuCM.Boost(beta2);
422 // --- Determine the z axis for the calculation of the polarization angle
423 // (i.e. the direction of the dimuon in the CM system)
426 zaxis=(pDimuCM.Vect()).Unit();
428 // --- Calculation of the polarization angle (Helicity)
429 // (angle between mu+ and the z axis defined above)
433 cost = zaxis.Dot((pMu1Dimu.Vect()).Unit());
434 // Theta Helicity is not properly defined for Like-Sign muons
435 if(mu2Charge > 0 && cost<0) cost=-cost;
437 cost = zaxis.Dot((pMu2Dimu.Vect()).Unit());
438 // Theta Helicity is not properly defined for Like-Sign muons
439 if(mu2Charge < 0 && cost<0) cost=-cost;
444 //______________________________________________________________________________
445 Int_t AliAODDimuon::AnyPt(){
446 // Test if the two muons match two trigger tracks
447 if(this->CheckPointers())return 0;
448 return (((AliAODTrack*)fMu[0].GetObject())->MatchTriggerAnyPt())&&
449 (((AliAODTrack*)fMu[0].GetObject())->MatchTriggerAnyPt());
452 //______________________________________________________________________________
453 Int_t AliAODDimuon::LowPt(){
454 // Test if the two muons match two trigger tracks with a "Low Pt" cut
455 if(this->CheckPointers())return 0;
456 return (((AliAODTrack*)fMu[0].GetObject())->MatchTriggerLowPt())&&
457 (((AliAODTrack*)fMu[0].GetObject())->MatchTriggerLowPt());
460 //______________________________________________________________________________
461 Int_t AliAODDimuon::HighPt(){
462 // Test if the two muons match two trigger tracks with a "High Pt" cut
463 if(this->CheckPointers())return 0;
464 return (((AliAODTrack*)fMu[0].GetObject())->MatchTriggerHighPt())&&
465 (((AliAODTrack*)fMu[0].GetObject())->MatchTriggerHighPt());
468 //______________________________________________________________________________
469 Double_t AliAODDimuon::MaxChi2Match(){
470 // Maximum matching Chi2 between track and trigger track
471 if(this->CheckPointers())return -999999999;
472 return TMath::Max((((AliAODTrack*)fMu[0].GetObject())->GetChi2MatchTrigger()),
473 (((AliAODTrack*)fMu[0].GetObject())->GetChi2MatchTrigger()));