using namespace std;
#include <sstream>
#include <iostream>
#include <iomanip>
#include "PHadronDecayM3.h"
ClassImp(PHadronDecayM3)
PHadronDecayM3::PHadronDecayM3() {
};
PHadronDecayM3::PHadronDecayM3(const Char_t *id, const Char_t *de, Int_t key) :
PChannelModel(id, de, key) {
if (is_channel < 0)
Warning("PHadronDecayM3", "The model (%s) should be bound to CHANNELS only", de);
Int_t tid[11];
tid[0] = 10;
makeStaticData()->GetDecayModeByKey(primary_key, tid);
parent_id = makeStaticData()->GetDecayParentByKey(primary_key);
parent_mass = makeStaticData()->GetParticleMass(parent_id);
if (tid[0] != 3)
Warning("PHadronDecayM3", "(%s): Only 3 body decay", de);
mass1 = makeStaticData()->GetParticleMass(tid[1]);
mass2 = makeStaticData()->GetParticleMass(tid[2]);
mass3 = makeStaticData()->GetParticleMass(tid[3]);
id1 = tid[1];
id2 = tid[2];
id3 = tid[3];
didx1 = -1;
didx2 = -1;
didx3 = -1;
};
PDistribution *PHadronDecayM3::Clone(const char *) const {
return new PHadronDecayM3((const PHadronDecayM3 &)* this);
};
Bool_t PHadronDecayM3::Init(void) {
parent = GetParticle("parent");
if (!parent) {
Warning("Init", "Parent not found");
return kFALSE;
}
daughter1 = GetParticle(makeStaticData()->GetParticleName(id1));
daughter2 = GetParticle(makeStaticData()->GetParticleName(id2));
daughter3 = GetParticle(makeStaticData()->GetParticleName(id3));
return kTRUE;
}
Bool_t PHadronDecayM3::Prepare(void) {
didx1 = daughter1->GetDecayModeIndex(1);
didx2 = daughter2->GetDecayModeIndex(1);
didx3 = daughter3->GetDecayModeIndex(1);
return kTRUE;
}
Double_t PHadronDecayM3::Eval(Double_t x, Double_t, Double_t, Double_t) const {
Double_t res;
Double_t mass[4];
mass[0] = x;
mass[1] = mass1;
mass[2] = mass2;
mass[3] = mass3;
if (draw_option == 0) {
return ((PChannelModel*)this)->GetWeight(mass);
} else if (draw_option == 1) {
((PChannelModel*)this)->GetWidth(x, &res);
return res;
} else if (draw_option == 2) {
((PChannelModel*)this)->GetBR(x, &res);
return res;
}
return 0;
}
int PHadronDecayM3::GetDepth(int i) {
Int_t a1=0, a2=0, a3=0;
model1 = makeDynamicData()->GetParticleModel(id1);
model2 = makeDynamicData()->GetParticleModel(id2);
model3 = makeDynamicData()->GetParticleModel(id3);
if (model1) a1 = model1->GetDepth(i);
if (model2) a2 = model2->GetDepth(i);
if (model3) a3 = model3->GetDepth(i);
makeStaticData()->SetDecayEmin(is_channel, mass1+mass2+mass3);
return TMath::Max(a1+1, TMath::Max(a2+1,a3+1));
}
void PHadronDecayM3::SubPrint(Int_t) const {
if (model1) {
cout << " ";
cout << model1->GetDescription();
}
if (model2) {
cout << " ";
cout << model2->GetDescription();
}
if (model3) {
cout << " ";
cout << model3->GetDescription();
}
}
Bool_t PHadronDecayM3::SampleMass(void) {
Double_t mass[4];
Int_t didx[4];
didx[1] = didx1;
didx[2] = didx2;
didx[3] = didx3;
mass[0] = parent->M();
Bool_t ret = SampleMass(mass,didx);
daughter1->SetM(mass[1]);
daughter2->SetM(mass[2]);
daughter3->SetM(mass[3]);
return ret;
};
Bool_t PHadronDecayM3::SampleMass(Double_t *mass, Int_t *didx) {
int didx_local1 = -1;
int didx_local2 = -1;
int didx_local3 = -1;
if (didx) didx_local1 = didx[1];
if (didx) didx_local2 = didx[2];
if (didx) didx_local3 = didx[3];
int counter = 0;
Double_t old_max = 0.;
PChannelModel *unstable = NULL;
mass[1] = mass1;
mass[2] = mass2;
mass[3] = mass3;
#if 0
if (model1 && !model2 && !model3) {
unstable = model1;
old_max=model1->GetMax();
model1->SetMax(mass[0] - mass[2] - mass[3] );
model1->ClearIntegral();
} else if (!model1 && model2 && !model3) {
unstable = model2;
old_max=model2->GetMax();
model2->SetMax(mass[0] - mass[1] - mass[3] );
model2->ClearIntegral();
} else if (!model1 && !model2 && model3) {
unstable = model3;
old_max=model3->GetMax();
model3->SetMax(mass[0] - mass[1] - mass[2] );
model3->ClearIntegral();
}
#endif
repeat1:
counter++;
if (model1) model1->SampleMass(&mass[1], &didx_local1);
if (model2) model2->SampleMass(&mass[2], &didx_local2);
if (model3) model3->SampleMass(&mass[3], &didx_local3);
if ((mass[0] < (mass[1] + mass[2] + mass[3])) && (counter <1000)) {
goto repeat1;
} else if (counter >= 1000){
Warning("SampleMass", "Sampling aborted, resonance mass distribution too large?");
if (unstable) unstable->SetMax(old_max);
return kFALSE;
}
double m12min2 = (mass[1]+mass[2])*(mass[1]+mass[2]);
double m12max2 = (mass[0]-mass[3])*(mass[0]-mass[3]);
double m23min2 = (mass[2]+mass[3])*(mass[2]+mass[3]);
double m23max2 = (mass[0]-mass[1])*(mass[0]-mass[1]);
double phaseSpace = (m12max2-m12min2)*(m23max2-m23min2);
m12min2 = pow(PData::LMass(id1)+PData::LMass(id2), 2);
m12max2 = pow(mass[0]-PData::LMass(id3),2);
m23min2 = pow(PData::LMass(id2)+PData::LMass(id3), 2);
m23max2 = pow(mass[0]-PData::LMass(id1),2);
double phaseSpaceMax = (m12max2-m12min2)*(m23max2-m23min2);
if (((phaseSpace/phaseSpaceMax) <PUtils::sampleFlat()) && (counter <1000) ) {
goto repeat1;
} else if (counter >= 1000) {
Warning("SampleMass", "Sampling aborted, resonance mass too large?");
if (unstable) unstable->SetMax(old_max);
return kFALSE;
}
if (unstable) unstable->SetMax(old_max);
return kTRUE;
};
Bool_t PHadronDecayM3::GetWidth(Double_t mass, Double_t *width, Int_t) {
double q_value = mass-(mass1+mass2+mass3);
double q_value_pole = parent_mass-(mass1+mass2+mass3);
*width = (q_value/q_value_pole)*(q_value/q_value_pole);
return kTRUE;
}
Double_t PHadronDecayM3::GetWeight(void) {
Double_t mass[4];
mass[0] = parent->M();
mass[1] = daughter1->M();
mass[2] = daughter2->M();
mass[3] = daughter3->M();
Int_t didx[4];
didx[1] = didx1;
didx[2] = didx2;
didx[3] = didx3;
double m12min2 = (mass[1]+mass[2])*(mass[1]+mass[2]);
double m12max2 = (mass[0]-mass[3])*(mass[0]-mass[3]);
double m23min2 = (mass[2]+mass[3])*(mass[2]+mass[3]);
double m23max2 = (mass[0]-mass[1])*(mass[0]-mass[1]);
double phaseSpace = (m12max2-m12min2)*(m23max2-m23min2);
m12min2 = pow(PData::LMass(id1)+PData::LMass(id2), 2);
m12max2 = pow(mass[0]-PData::LMass(id3), 2);
m23min2 = pow(PData::LMass(id2)+PData::LMass(id3), 2);
m23max2 = pow(mass[0]-PData::LMass(id1), 2);
double phaseSpaceMax = (m12max2-m12min2)*(m23max2-m23min2);
return GetWeight(mass,didx)*(phaseSpace/phaseSpaceMax);
}
Double_t PHadronDecayM3::GetWeight(Double_t *mass, Int_t *didx) {
int didx_local1 = -1;
int didx_local2 = -1;
int didx_local3 = -1;
if (didx) didx_local1 = didx[1];
if (didx) didx_local2 = didx[2];
if (didx) didx_local3 = didx[3];
Double_t weight = 1.;
if (model1) weight*=model1->GetWeight(&mass[1], &didx_local1);
if (model2) weight*=model2->GetWeight(&mass[2], &didx_local2);
if (model3) weight*=model3->GetWeight(&mass[3], &didx_local3);
return weight;
}
ClassImp(PHadronDecayM3)