using namespace std;
#include <sstream>
#include <iostream>
#include <iomanip>
#include "PHadronModel.h"
ClassImp(PHadronModel)
PHadronModel::PHadronModel() {
};
PHadronModel::PHadronModel(const Char_t *id, const Char_t *de, Int_t key) :
PChannelModel(id, de, key) {
if (is_pid < 0)
Warning("PHadronModel", "The model (%s) should be bound to PARTICLES only", de);
global_weight_scaling = 1.;
};
PDistribution *PHadronModel::Clone(const char *) const {
return new PHadronModel((const PHadronModel &)* this);
};
Bool_t PHadronModel::GetWidth(Double_t mass, Double_t *width, Int_t didx) {
if (didx >= 0) {
*width = makeDynamicData()->GetDecayPartialWidth(mass, didx);
return kTRUE;
}
int twidx = makeStaticData()->GetTWidx(is_pid);
double g0 = makeStaticData()->GetParticleTotalWidth(is_pid);
if (!width_init)
makeDynamicData()->GetParticleDepth(is_pid);
if (twidx==-1 || g0 < (*unstable_width) || mass==0. ||
makeStaticData()->GetParticleNChannels(is_pid)==0) {
*width = g0;
return kTRUE;
}
double dm;
int j, didx2;
double mm, g_tmp;
Bool_t self_consistency_loop = kTRUE;
Bool_t next_self_consistency_loop = kFALSE;
if (!width_init) {
width_init++;
global_weight_scaling = makeDynamicData()->GetParticleScalingFactor(is_pid);
mmin = PData::LMass(is_pid);
mmax = PData::UMass(is_pid);
dm = (mmax-mmin)/(maxmesh-3.);
Info("GetWidth", "Width 1st call for %s, mass range %f GeV to %f GeV",
description, mmin, mmax);
while (self_consistency_loop) {
Int_t listkey = -1;
Int_t tid[11];
while (makeDataBase()->MakeListIterator(primary_key, "pnmodes", "link", &listkey)) {
tid[0] = 10;
makeStaticData()->GetDecayModeByKey(listkey, tid);
didx2 = makeStaticData()->GetDecayIdxByKey(listkey);
if (makeStaticData()->GetPWidx(didx2) != -1 ) {
makeDynamicData()->GetDecayPartialWidth(mass, didx2);
}
}
if (mesh) delete mesh;
mesh = new PMesh(maxmesh-2, "mesh");
for (j=0; j<maxmesh-2; ++j) {
g_tmp = 0.;
mm = mmin+j*dm;
while (makeDataBase()->MakeListIterator(primary_key, "pnmodes", "link", &listkey)) {
didx2 = makeStaticData()->GetDecayIdxByKey(listkey);
g_tmp += makeDynamicData()->GetDecayPartialWidth(mm,didx2);
}
mesh->SetNode(j, g_tmp);
}
mesh->SetMin(mmin);
mesh->SetMax(mmax);
Double_t global_weight = 0;
for (j=0; j<maxmesh-2; ++j) {
mm = mmin+j*dm;
global_weight += dm*makeDynamicData()->GetParticleTotalWeight(mm, is_pid);
}
if (global_weight)
makeDynamicData()->SetParticleScalingFactor(is_pid, 1/(global_weight));
global_weight_scaling = makeDynamicData()->GetParticleScalingFactor(is_pid);
listkey = -1;
self_consistency_loop = kFALSE;
while (makeDataBase()->MakeListIterator(primary_key, "pnmodes", "link", &listkey)) {
didx2 = makeStaticData()->GetDecayIdxByKey(listkey);
Double_t partial_weight = 0.;
global_weight = 0.;
int brflag = makeStaticData()->GetDecayBRFlag(didx2);
if (brflag) {
for (j=0; j<maxmesh-2; ++j) {
mm = mmin+j*dm;
if (makeDynamicData()->GetParticleTotalWidth(mm,is_pid) > 0)
partial_weight += dm*(makeDynamicData()->GetDecayPartialWidth(mm,didx2)*
makeDynamicData()->GetParticleTotalWeight(mm,is_pid)*
makeStaticData()->GetParticleTotalWidth(is_pid)/
makeDynamicData()->GetParticleTotalWidth(mm,is_pid));
global_weight += dm*makeDynamicData()->GetParticleTotalWeight(mm,is_pid);
}
} else {
mm = makeStaticData()->GetParticleMass(is_pid);
partial_weight = (makeDynamicData()->GetDecayPartialWidth(mm,didx2)*
makeDynamicData()->GetParticleTotalWeight(mm,is_pid)*
makeStaticData()->GetParticleTotalWidth(is_pid)/
makeDynamicData()->GetParticleTotalWidth(mm,is_pid));
global_weight = makeDynamicData()->GetParticleTotalWeight(mm,is_pid);
}
Double_t calculated_br = 0;
Double_t tot_sc = 1.;
tot_sc = makeDynamicData()->GetParticleTotalWidth(makeStaticData()->GetParticleMass(is_pid),is_pid)/
makeStaticData()->GetParticleTotalWidth(is_pid);
if (global_weight)
calculated_br = tot_sc*partial_weight/global_weight;
if ((calculated_br/makeStaticData()->GetDecayPartialWidth(didx2) > 1.001)
|| (calculated_br/makeStaticData()->GetDecayPartialWidth(didx2) < 0.999)) {
if (!makeDynamicData()->CheckSCAbort(didx2)) {
Warning("GetWidth", "Self consistency calculation failed for decay: %s (%i)",
makeStaticData()->GetDecayName(didx2), didx2);
Warning("GetWidth", "Calculated Width: %f, Static Width: %f",
calculated_br,
makeStaticData()->GetDecayPartialWidth(didx2));
next_self_consistency_loop = kTRUE;
} else {
if (calculated_br > 0) {
self_consistency_loop = kTRUE;
makeDynamicData()->SetDecaySCFactor(didx2,
makeStaticData()->GetDecayPartialWidth(didx2)/
calculated_br);
}
}
}
}
if (next_self_consistency_loop)
self_consistency_loop = kFALSE;
}
}
*width = mesh->GetLinearIP(mass);
return kTRUE;
}