using namespace std;
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cmath>
#include "PDefines.h"
const char *Message[14] = {
"PChannel: operation successful",
"PChannel: invalid pids",
"PChannel: reconstruct failed, increase beam energy",
"PChannel: decay failed, system invariant mass is zero",
"PChannel: decay failed, insufficient energy",
"PChannel: genbod failed, fewer than two decay products",
"PChannel: genbod failed",
"PChannel: baryon_cos algorithm failed",
"PChannel: mflag must be 0 or 1",
"PChannel: aflag must be 0 or 1",
"PChannel: bflag must be 0 or 1",
"PChannel: reconstruct failed for deuteron Fermi sampling",
"PChannel: invalid decay-mode index in the constructor",
"PChannel: inconsistent particle array with decay-mode index"};
#include "PChannel.h"
#include "PDynamicData.h"
#include "PUtils.h"
#include "PFileInput.h"
#include "PFireball.h"
#include "PDiLepton.h"
#include "PKinematics.h"
double PChannel::globalWeight = 1.;
PChannel::PChannel(PParticle **particles, int nt, int, int, int) {
makeStdData()->fillDataBase();
init_done = kFALSE;
e_cm = 0;
int i, k = -1;
status = (!particles);
n = nt;
if (!status) {
ipid.Set(n+1);
for (i=0; i<=n; ++i) {
k = particles[i]->ID();
if (!k) {
status = 1;
ipid.~TArrayI();
break;
}
ipid[i] = k;
}
}
if (status) {
printf("%s:", Message[status]);
for(i=0; i<=n; i++) printf(" %d", particles[i]->ID());
printf("\n");
return;
}
ptcls = particles;
ptcls_extern = -1;
IsReaction();
particles[0]->SetDecayModeIndex(makeStaticData()->GetDecayIdxByKey(decay_key));
w = particles[0]->W();
ecm = particles[0]->M();
DMIndex=makeStaticData()->GetDecayIdx(ipid.GetArray(),n);
}
PChannel::PChannel(int idx, PParticle **particles, int, int, int) {
makeStdData()->fillDataBase();
init_done = kFALSE;
e_cm = 0;
Int_t key = makeDataBase()->GetEntryInt("didx", idx);
Int_t ia[11];
ia[0] = 10;
if (key < 0) {
printf("%s\n", Message[12]);
return;
} else
makeStaticData()->GetDecayMode(idx,ia);
DMIndex = idx;
n = ia[0];
ipid.Set(n+1);
if (!particles) {
ptcls = new PParticle*[n+1];
for(int i=0; i<=n; i++) ptcls[i] = 0;
ptcls_extern = 0;
} else {
ptcls = particles;
ptcls_extern = -1;
}
int i;
for (i=0; i<=n; ++i) {
if (particles)
ipid[i] = particles[i]->ID();
else {
if (!i)
ipid[0] = makeStaticData()->GetDecayParent(idx);
else
ipid[i] = ia[i+1];
ptcls[i] = new PParticle(ipid[i]);
}
}
if (particles) {
ia[0] = ipid[0];
PUtils::isort(ia, n+1);
TArrayI test(ipid);
PUtils::isort(test.GetArray(), n+1);
int hit = 0;
for (i=0; i<=n; ++i)
hit += (test[i]==ia[i]);
if (hit != n) {
printf("%s\n", Message[13]);
ipid.~TArrayI();
return;
}
}
IsReaction();
ptcls[0]->SetDecayModeIndex(makeStaticData()->GetDecayIdxByKey(decay_key));
w = ptcls[0]->W();
ecm = ptcls[0]->M();
}
PChannel::PChannel(int idx, PParticle &parent, int, int, int) {
makeStdData()->fillDataBase();
init_done = kFALSE;
e_cm = 0;
Int_t key = makeDataBase()->GetEntryInt("didx", idx);
Int_t ia[11];
ia[0] = 10;
if (key < 0) {
printf("%s\n", Message[12]);
return;
} else
makeStaticData()->GetDecayMode(idx,ia);
DMIndex = idx;
n = ia[0];
ipid.Set(n+1);
ptcls = new PParticle*[n+1];
ptcls[0] = &parent;
ptcls_extern = 1;
ipid[0] = parent.ID();
if (ipid[0] != makeStaticData()->GetDecayParent(idx)) {
printf("%s\n", Message[13]);
ipid.~TArrayI();
delete [] ptcls;
return;
}
int i;
for (i=1; i<=n; ++i) {
ipid[i] = ia[i];
ptcls[i] = new PParticle(ipid[i]);
}
IsReaction();
ptcls[0]->SetDecayModeIndex(makeStaticData()->GetDecayIdxByKey(decay_key));
w = ptcls[0]->W();
ecm = ptcls[0]->M();
}
void PChannel::IsReaction() {
event_impact_param = (makeStaticData()->GetBatchValue("_event_impact_param"));
event_plane = (makeStaticData()->GetBatchValue("_event_plane"));
weight_version = makeStaticData()->GetBatchValue("_system_weight_version");
makeDynamicData()->PushPChannel((TObject *) this);
parent = ptcls[0];
orig_parent = ptcls[0];
int k = GetParentSize();
thSrc = 0;
tcSrc = 0;
dlSrc = 0;
sourceid = 0;
fEnablePattern = 0;
thermal_disable_didx = 0;
num_not_finalized = 0;
distribution_position = 0;
print_tentative = kTRUE;
quasi_pchannel = NULL;
weight_sum = 0;
tid = bid = 0;
bulkdecay_pos = 0;
pro_bulkdecay_pos = 0;
current_projector = NULL;
events = makeStaticData()->GetBatchValue("_system_total_event_number");
k = GetParentSize();
parent->SetSourceId(parent->ID());
parent->SetParentId(0);
for (int i=1; i<=n; i++) {
ptcls[i]->SetValue(CHANNEL_POS, (double)i);
}
emin = 0.;
if (k == 1) {
if (parent->IsFireball())
thSrc = 1;
else if (parent->IsFileInput())
tcSrc = 1;
else if (parent->IsDilepton())
dlSrc = 1;
else {
IdChannel();
decay_key = makeStaticData()->GetDecayKey(ipid.GetArray(), n);
CheckDecayKey();
return;
}
}
parent->SetParentIndex(-2);
parent->SetIndex(-1);
tid = ipid[0]/1000;
bid = ipid[0]%1000;
IdChannel();
decay_key = makeStaticData()->GetDecayKey(ipid.GetArray(), n);
if ((decay_key < 0) && (ipid[0]>999)) {
decay_key = makeStaticData()->AddDecay(ipid.GetArray(), n);
}
if (!thSrc && !tcSrc) CheckDecayKey();
for (int i=1; i<=n; ++i) {
emin += PData::LMass(ptcls[i]->ID());
}
}
void PChannel::CheckDecayKey(void) const {
if (decay_key < 0) {
Error("Initialization", "No database entry for:");
cout << " ";
PrintReaction(0);
Error("Initialization", "Bye...");
exit(1);
}
}
void PChannel::IdChannel() {
int i, nucleon_pid;
spectator = NULL;
participant = NULL;
quasi_composite = NULL;
quasi_pchannel = NULL;
int has_spec = 0;
for (i=1; i<=n; ++i) {
if (ptcls[n]->IsSpectator() != -1)
has_spec=1;
}
if (!has_spec) return;
has_spec = ptcls[n]->IsSpectator();
if (has_spec == 0) {
if ((bid != makeStaticData()->GetParticleID("d")) &&
(tid != makeStaticData()->GetParticleID("d")))
return;
if (!ptcls[n]->IsNucleon()) return;
}
for (i=1; i<=n; ++i) {
if (!has_spec) {
if (ptcls[i]->ID() == makeStaticData()->GetParticleID("d"))
return;
}
if (ptcls[i]->ID()>1000) return;
}
if (bid == makeStaticData()->GetParticleID("d"))
nucleon_pid = tid;
else
nucleon_pid = bid;
spectator = ptcls[n];
if (spectator->ID() == makeStaticData()->GetParticleID("p"))
participant = new PParticle("n");
else if (spectator->ID() == makeStaticData()->GetParticleID("n"))
participant = new PParticle("p");
else {
for (i=1; i<=(n-1); ++i) {
if (ptcls[i]->IsSpectator() == 1)
participant = new PParticle(ptcls[i]);
}
Int_t a_pos = -1;
for (i=1; i<=(n-1); ++i) {
if (ptcls[i]->IsSpectator() == 3)
participant = new PParticle(ptcls[i]);
if (ptcls[i]->IsSpectator() == 2)
a_pos = i;
}
if (a_pos != 1) {
Error("IdChannel","Quasi-reaction must come at first");
} else if ((a_pos == 1) && (participant)) {
for (i=1; i<=(n-3); ++i) {
ptcls[i] = ptcls[i+2];
ipid[i] = ipid[i+2];
}
n -= 2;
}
if (!participant) {
Warning("IdChannel", "No valid spectator found");
return;
}
}
PParticle dummy(nucleon_pid);
if (nucleon_pid == tid) {
quasi_composite = new PParticle(*participant + dummy);
} else {
quasi_composite = new PParticle(dummy + *participant);
}
PParticle **cc1 = new PParticle*[3];
cc1[0] = parent;
cc1[1] = quasi_composite;
cc1[2] = spectator;
quasi_pchannel = new PChannel(cc1,2);
Info("IdChannel", "(%s) Quasi-free production", PRINT_AUTO_ALLOC);
n--;
parent = quasi_composite;
orig_parent = quasi_composite;
ptcls[0] = quasi_composite;
ipid[0] = quasi_composite->ID();
}
void PChannel::ThermalSampling() {
double px, py, pz, Energy;
float b = 0., phi = 0.;
int i, nTherm = n;
PFireball *pFire =
(ptcls[0]->IsFireball()) ? (PFireball *)ptcls[0] : NULL;
if (pFire->IsRandomB()) {
if (*event_impact_param == 0.) {
b = pFire->sampleB() + 0.001;
phi = 2.*TMath::Pi()*PUtils::sampleFlat();
} else {
b = *event_impact_param;
phi = *event_plane;
}
nTherm = pFire->sampleNProd(b);
if (nTherm > n) nTherm = n;
} else if (pFire->IsRandomN()) {
nTherm = pFire->sampleNProd();
if (*event_plane == 0.)
phi = 2.*TMath::Pi()*PUtils::sampleFlat();
else
phi = *event_plane;
if (nTherm > n)
nTherm = n;
}
*event_impact_param = b;
*event_plane = phi;
for(i=1; i<=nTherm; i++) {
int didx = ptcls[i]->GetDecayModeIndex(1);
redo_thermal:
if (nTherm == 1) {
pFire->samplePartCM(px, py, pz, Energy,didx);
} else {
if (thermal_disable_didx)
pFire->samplePartCM(px, py, pz, Energy, -1);
else if ((i>1) && didx != ptcls[i-1]->GetDecayModeIndex(1)) {
thermal_disable_didx = 1;
Warning("ThermalSampling","Different decays, disable partial decay sampling");
} else {
pFire->samplePartCM(px, py, pz, Energy, didx);
}
}
ptcls[i]->SetPxPyPzE(px, py, pz, Energy);
if (ptcls[i]->M() < PData::LMass(ptcls[i]->ID()) || ptcls[i]->M() > PData::UMass(ptcls[i]->ID())) goto redo_thermal;
ptcls[i]->SetW(w*(pFire->mtScale(ptcls[i]->M())));
if (sourceid)
ptcls[i]->SetSourceId(sourceid);
else
ptcls[i]->SetSourceId(pFire->ID());
ptcls[i]->SetParentId(pFire->ID());
ptcls[i]->SetActive();
}
for(i=nTherm+1; i<=n; i++) {
ptcls[i]->SetInActive();
}
TVector3 Beta = pFire->BoostVector();
if (Beta.Mag() > 0.) {
for(i=1; i<=nTherm; ++i) {
ptcls[i]->Boost(Beta);
}
}
}
void PChannel::MakeDilepton() {
double px, py, pz, Energy;
PDiLepton * pDL =
(ptcls[0]->IsDilepton()) ? (PDiLepton *)ptcls[0] : NULL;
pDL->samplePartCM(px, py, pz, Energy);
ptcls[1]->SetPxPyPzE(px, py, pz, Energy);
ptcls[1]->SetW(w);
ptcls[1]->SetSourceId(pDL->ID());
ptcls[1]->SetParentId(pDL->ID());
ptcls[1]->SetActive();
TVector3 Beta=pDL->BoostVector();
if (Beta.Mag()>0.) ptcls[1]->Boost(Beta);
}
Int_t PChannel:: ReadFileInput() {
Double_t px, py, pz, Energy, vx, vy, vz, vt;
Float_t b = 0., phi = 0.;
Int_t id, idSrc, idPar, indPar = -2, ret;
Int_t i, nFile = 0, nMax;
PFileInput *pFile =
(ptcls[0]->IsFileInput()) ? (PFileInput*)ptcls[0] : NULL;
nMax = nFile = pFile->readEventHeader(b);
if (nFile == -1) {
printf("**** EOF reached on file input ****\n");
for(i=1; i<=n; i++)
ptcls[i]->SetInActive();
return 8;
}
if (nMax > n) nMax = n;
if (*event_impact_param == 0.) {
phi = 2.*TMath::Pi()*PUtils::sampleFlat();
}
else {
b = *event_impact_param;
phi = *event_plane;
}
*event_impact_param = b;
*event_plane = phi;
for(i=1; i<=nFile; i++) {
ret = pFile->readParticle(px,py,pz,Energy,vx,vy,vz,vt,id,idSrc,idPar,indPar,w);
if (ret == -1) break;
if (i > n) continue;
ptcls[i]->SetID(id);
ptcls[i]->SetPxPyPzE(px, py, pz, Energy);
ptcls[i]->ResetE();
ptcls[i]->SetW(w);
ptcls[i]->SetSourceId(idSrc);
ptcls[i]->SetParentId(idPar);
ptcls[i]->SetParentIndex(indPar);
ptcls[i]->SetActive();
ptcls[i]->SetVertex(vx,vy,vz,vt);
}
if (ret == -1) return 8;
for(i=nMax+1; i<=n; i++)
ptcls[i]->SetInActive();
TVector3 Beta = pFile->BoostVector();
if (Beta.Mag() > 0.)
for(i=1; i<=nMax; ++i)
ptcls[i]->Boost(Beta);
return 0;
}
int PChannel::CheckSiblings(PParticle *p, PDistribution *dist, int flag) {
if (p == NULL) {
return -1;
}
if (p->GetParent())
if ((p->GetParent()->ID() > 500) && (p->GetParent()->ID() <1000)) return -1;
if (p->ID() >= 1000) return -1;
PParticle *currentSibling = p->GetSibling();
Int_t counter = 0;
Int_t ret = -1;
while (currentSibling != p) {
if (currentSibling == NULL) return ret;
if (ret == 0) {
ret = -1;
}
if (dist->SetParticle(currentSibling, currentSibling->ID(), flag | PARTICLE_LIST_SIBLING) == 0) {
ret = 0;
}
currentSibling = currentSibling->GetSibling();
counter++;
if (counter == 8) {
Warning("CheckSiblings", "Sibling chain seems to be corrupted");
Print();
return -1;
}
}
if (ret == -1) dist->ResetRelatives(flag | PARTICLE_LIST_SIBLING);
return ret;
}
Bool_t PChannel::Reset() {
for (int j=0; j<distribution_position; j++) {
dist[j]->ResetRelatives();
dist[j]->SetEnable(1);
}
grandparent = NULL;
grandgrandparent = NULL;
init_done = kFALSE;
return kTRUE;
}
Bool_t PChannel::SetDaughters() {
if (thSrc || tcSrc) return kTRUE;
parent->ResetDaughters();
if (parent->IsActive() == kTRUE) {
for (Int_t k=1; k<=n; k++) {
parent->SetDaughter(ptcls[k]);
}
}
return kTRUE;
}
Bool_t PChannel::Init() {
int has_printed = 0;
if (orig_parent != ptcls[0]) {
parent = ptcls[0];
*orig_parent = *(ptcls[0]);
}
grandparent = parent->GetParent();
grandgrandparent = NULL;
if (grandparent)
grandgrandparent = grandparent->GetParent();
Double_t set_mode_index = 0;
for (int j=0; j<distribution_position; j++) {
if (dist[j]->GetVersionFlag() & VERSION_INVERT_WEIGHTING) {
set_mode_index++;
} else if ((dist[j]->GetVersionFlag() & VERSION_WEIGHTING)
&& (dist[j]->GetVersionFlag() & VERSION_GENERATOR_MC)
) {
set_mode_index++;
} else if (dist[j]->GetVersionFlag() & VERSION_FORCE_NO_PARTIAL_WIDTH)
set_mode_index = set_mode_index + 2;
}
if (set_mode_index < 2)
ptcls[0]->SetDecayModeIndex(makeStaticData()->GetDecayIdxByKey(decay_key));
else {
ptcls[0]->SetDecayModeIndex(-1);
}
if (parent->IsActive() == kTRUE) {
parent->SetDaughterIndex(ptcls[1]->GetIndex());
Int_t parId, parInd;
for (Int_t k=1; k<=n; k++) {
ptcls[k]->SetActive();
if (sourceid)
ptcls[k]->SetSourceId(sourceid);
else
ptcls[k]->SetSourceId(parent->GetSourceId());
parId = parent->ID();
parInd = parent->GetIndex();
if ((parId==50 || parId==51) && grandparent!=NULL) {
parId += 1000*(grandparent->ID());
parInd = grandparent->GetIndex();
}
ptcls[k]->SetParentId(parId);
ptcls[k]->SetParentIndex(parInd);
ptcls[k]->SetDaughterIndex(-1);
if (k != n) {
ptcls[k]->SetSiblingIndex(ptcls[k+1]->GetIndex());
ptcls[k]->SetSibling(ptcls[k+1]);
} else {
ptcls[k]->SetSiblingIndex(ptcls[1]->GetIndex());
ptcls[k]->SetSibling(ptcls[1]);
}
}
}
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == -1) && dist[j]->GetEnable()){
if (has_printed == 0 && print_tentative) {
has_printed = 1;
cout << "checking tentative distributions for ";
if (grandparent) {
if (grandparent->ID() < 1000)
printf("%s --> ",makeStaticData()->GetParticleName(grandparent->ID()));
}
PrintReaction();
cout << endl;
}
if (print_tentative)
printf(" [checking] %s\n",
dist[j]->GetDescription());
if (grandparent) {
if (grandparent->ID() < 1000)
dist[j]->SetParticle(grandparent, grandparent->ID(), PARTICLE_LIST_GRANDPARENT);
else
dist[j]->SetParticle(grandparent, DISTRIBUTION_QUASI_PID, PARTICLE_LIST_GRANDPARENT);
}
if (grandgrandparent) {
if (grandgrandparent->ID() < 1000)
dist[j]->SetParticle(grandgrandparent, grandgrandparent->ID(), PARTICLE_LIST_GRANDGRANDPARENT);
else
dist[j]->SetParticle(grandgrandparent, DISTRIBUTION_QUASI_PID, PARTICLE_LIST_GRANDGRANDPARENT);
}
#if 1
if (parent->ID() >= 1000) {
if (parent->GetScattering(0)) {
dist[j]->SetParticle(parent->GetScattering(0), parent->GetScattering(0)->ID(), PARTICLE_LIST_GRANDPARENT);
dist[j]->SetParticle(parent->GetScattering(1), parent->GetScattering(1)->ID(), PARTICLE_LIST_GRANDPARENT);
}
} else if (grandparent) {
if (grandparent->ID() >= 1000) {
if (grandparent->GetScattering(0)) {
dist[j]->SetParticle(grandparent->GetScattering(0), grandparent->GetScattering(0)->ID(), PARTICLE_LIST_GRANDGRANDPARENT);
dist[j]->SetParticle(grandparent->GetScattering(1), grandparent->GetScattering(1)->ID(), PARTICLE_LIST_GRANDGRANDPARENT);
}
}
}
#endif
CheckSiblings(parent, dist[j], PARTICLE_LIST_PARENT);
if (grandparent) {
CheckSiblings(grandparent, dist[j], PARTICLE_LIST_GRANDPARENT);
if (grandgrandparent)
CheckSiblings(grandgrandparent, dist[j], PARTICLE_LIST_GRANDGRANDPARENT);
}
for (Int_t k=1; k<=n; k++) {
int kk = 0;
while (ptcls[k]->GetDaughter(kk) != NULL) {
dist[j]->SetParticle(ptcls[k]->GetDaughter(kk),
ptcls[k]->GetDaughter(kk)->ID(),
PARTICLE_LIST_GRANDDAUGHTER);
kk++;
}
}
if (dist[j]->GetStatus() == -1) {
if (print_tentative) printf(" [removed] %s\n",dist[j]->GetDescription());
dist[j]->SetEnable(0);
}
else {
if (dist[j]->Init() == kTRUE) {
if (print_tentative) printf(" [enabled] %s\n",dist[j]->GetDescription()); }
else {
printf(" [error] %s:%s\n",dist[j]->GetDescription(),dist[j]->GetIdentifier());
dist[j]->SetEnable(0);
}
}
}
}
Int_t num_mass_sampling = 0;
if (parent->ID() > PLUTO_COMPOSITE) {
for (int j=0; j<distribution_position; j++) {
if (dist[j]->GetVersionFlag() & VERSION_MASS_SAMPLING) {
if (num_mass_sampling)
dist[j]->SetEnable(0);
num_mass_sampling++;
}
}
}
init_done = kTRUE;
print_tentative = kFALSE;
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
dist[j]->GetDepth();
}
}
return kTRUE;
}
int PChannel::Decay() {
TVector3 vCreation, vDecay;
Double_t tCreation, tDecay;
if (!init_done) Init();
if (parent->IsActive() == kFALSE) {
for (Int_t k=1; k<=n; k++)
ptcls[k]->SetInActive();
return STATUS_OK;
}
else {
for (Int_t k=1; k<=n; k++) {
if (ptcls[k]->ID() > 0)
ptcls[k]->SetM(makeStaticData()->GetParticleMass(ptcls[k]->ID()));
ptcls[k]->SetActive();
}
vCreation = parent->GetVertex();
tCreation = parent->T();
tDecay = tCreation + parent->Gamma() * parent->GetProperTime();
vDecay = vCreation + parent->Gamma() * parent->GetProperTime()
* parent->BoostVector();
for (Int_t k=1; k<=n; k++) {
ptcls[k]->SetProperTime();
ptcls[k]->SetVertex(vDecay,tDecay);
}
}
int decay_done[n+1];
int real_size = n+1;
for (int i=0; i<=n; i++) {
decay_done[i] = 0;
}
for (int bu=0; bu<pro_bulkdecay_pos; bu++) {
pro_bulk[bu]->Modify(ptcls, decay_done, &real_size, n+1);
}
w = parent->W();
int i, nProd = n;
status = 0;
num_not_finalized = 0;
if (thSrc) {
ThermalSampling();
decay_done[0] = 1;
for (int bu=0; bu<bulkdecay_pos; bu++)
bulk[bu]->Modify(ptcls, decay_done, &real_size, n+1);
return status;
}
if (tcSrc) {
status = ReadFileInput();
return status;
}
if (dlSrc) {
MakeDilepton();
return status;
}
ecm = parent->M();
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
dist[j]->Prepare();
}
}
if (ecm < emin) {
return status = 4;
}
Int_t do_flag = 1,
distr_status = 0;
while (do_flag) {
status = Genbod(nProd);
distr_status = 0;
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()) {
if (dist[j]->IsNotRejected() == kFALSE) {
distr_status++;
if (dist[j]->CheckAbort()) {
do_flag = 1000000;
}
}
}
}
if (distr_status) {
do_flag++;
if (do_flag > 10) {
status = 10;
do_flag = 0;
}
} else {
do_flag = 0;
}
}
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
if (!dist[j]->Finalize()) {
if (num_not_finalized < MAX_NUM_NOT_FINALIZED) {
distribution_not_finalized[num_not_finalized] = dist[j];
num_not_finalized++;
} else {
Error("Decay","MAX_NUM_NOT_FINALIZED reached");
}
}
}
}
if (status) return status;
Double_t new_weight = ptcls[0]->W();
Double_t hidden_generator_weight = ptcls[0]->GenW();
Double_t inv_generator_weight = ptcls[0]->InvGenW();
Double_t dynamic_range = 1.;
if (*weight_version) {
#if 1
Double_t generator_weight = hidden_generator_weight;
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
dist_weight[j] = dist[j]->GetWeight();
if ((dist[j]->GetVersionFlag()) & VERSION_INVERT_WEIGHTING) {
generator_weight *= dist_weight[j];
dynamic_range *= dist[j]->GetDynamicRange();
}
}
}
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
if (((dist[j]->GetVersionFlag()) & VERSION_INVERT_WEIGHTING) ||
((dist[j]->GetVersionFlag()) & VERSION_WEIGHTING)) {
Double_t local_weight = dist_weight[j];
if ((dist[j]->GetVersionFlag()) & VERSION_GENERATOR_MC) {
local_weight *= dynamic_range;
dynamic_range = 1.;
}
if (dist[j]->GetExpectedWeightMean() > 0) {
if ((dist[j]->GetVersionFlag()) & VERSION_INVERT_WEIGHTING) {
local_weight = (1./local_weight);
dist[j]->IncrementWeightSum(local_weight);
} else {
dist[j]->IncrementWeightSum(local_weight, 1./generator_weight);
}
local_weight *= (dist[j]->GetExpectedWeightMean()/dist[j]->CalcWeightMean());
}
new_weight *= local_weight;
dist_weight_sum[j] += local_weight;
dist_counter[j]++;
} else {
if (dist[j]->GetExpectedWeightMean() > 0) {
new_weight *= dist[j]->GetExpectedWeightMean();
dist_weight_sum[j] += dist[j]->GetExpectedWeightMean();
dist_counter[j]++;
Double_t local_weight = dist_weight[j];
Double_t inv_local_weight = 0.;
if (local_weight > 0.)
inv_local_weight = (1./local_weight);
dist[j]->IncrementWeightSum(inv_local_weight);
}
}
}
}
if (new_weight <= 0.)
return status = 2;
weight_sum += new_weight;
#endif
}
TVector3 beta = parent->BoostVector();
if (beta.Mag() > 0.)
for (i=1; i<=nProd; ++i)
ptcls[i]->Boost(beta);
for (i=1; i<=nProd; ++i) {
ptcls[i]->SetParent(parent);
ptcls[i]->SetW(new_weight);
ptcls[i]->SetGenW(hidden_generator_weight);
ptcls[i]->SetInvGenW(inv_generator_weight);
}
#if 0
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
}
}
#endif
decay_done[0] = 1;
for (int bu=0; bu<bulkdecay_pos; bu++)
bulk[bu]->Modify(ptcls, decay_done, &real_size, n+1);
return status;
}
int PChannel::Genbod(int nProd) {
int i;
double conserve_e = 0.,
em[nProd];
Bool_t PDistribution_sampleMass = kFALSE;
int PDistribution_sampleMomentum = 0,
PDistribution_sampleModels = 0;
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()) {
if ((dist[j]->GetVersionFlag()) & VERSION_SAMPLING)
if (dist[j]->SampleMass()) {
PDistribution_sampleMass = kTRUE;
for (i=0; i<nProd; ++i) {
em[i] = ptcls[i+1]->M();
}
}
}
}
conserve_e = ptcls[0]->M();
if (PDistribution_sampleMass == kFALSE) {
Warning("Genbod","No mass sampling model(s) found in %s",
makeStaticData()->GetDecayNameByKey(decay_key));
return status = 6;
} else {
for (i=0; i<nProd; ++i)
conserve_e -= em[i];
}
if ((conserve_e < -1.e-8) && (nProd>1) ) {
return status = 5;
}
conserve_e = ptcls[0]->M();
Int_t last_sampling_model = 0;
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
if ((dist[j]->GetVersionFlag()) & VERSION_SAMPLING) {
PDistribution_sampleModels++;
if (dist[j]->SampleMomentum()) {
if (!PDistribution_sampleMomentum) last_sampling_model = j;
PDistribution_sampleMomentum++;
}
}
if (PDistribution_sampleMomentum > 1) {
Warning("Genbod", "More than one momentum sampling model found in %s",
makeStaticData()->GetDecayNameByKey(decay_key));
Warning("Genbod","Model 1: [%s]", dist[last_sampling_model]->GetIdentifier());
Warning("Genbod","Model 2: [%s]", dist[j]->GetIdentifier());
return status=6;
}
}
}
if (PDistribution_sampleModels == 0) {
Warning("Genbod","No momentum sampling model found in %s",
makeStaticData()->GetDecayNameByKey(decay_key));
return status = 6;
}
for (int j=0; j<distribution_position; j++) {
if ((dist[j]->GetStatus() == 0) && dist[j]->GetEnable()){
if ((dist[j]->GetVersionFlag()) & VERSION_SAMPLING)
dist[j]->SampleAngle();
}
}
for (i=0; i<nProd; ++i)
conserve_e -= ptcls[i+1]->E();
if (fabs(conserve_e) > 1.e-8) {
return status = 7;
}
else return status=STATUS_OK;
}
int PChannel::SetDistribution(PDistribution *distribution) {
if (distribution->GetEnable() == 0) return -1;
if (distribution_position == MAX_DISTRIBUTIONS) {
Warning("SetDistribution","MAX_DISTRIBUTIONS reached");
return -1;
}
Int_t check = 0;
PParticle *p0 = ptcls[0];
distribution->Reset();
check = distribution->SetParticle(p0, p0->ID(), PARTICLE_LIST_PARENT);
if (check<0 && (p0->ID() > 1000))
check = distribution->SetParticle(p0, DISTRIBUTION_QUASI_PID, PARTICLE_LIST_PARENT);
for (int i=0;i<n;i++) {
check += distribution->SetParticle(ptcls[i+1], ptcls[i+1]->ID(), PARTICLE_LIST_DAUGHTER);
}
check += distribution->CheckDaughters();
if (!strcmp(distribution->GetName(), "_testmodel"))
cout << "Check number in PChannel::SetDistribution: " << check << endl;
if (check < 0) {
if (distribution->debug_flag)
distribution->Print();
distribution->Reset();
return -1;
}
distribution = (PDistribution*) distribution->Clone();
if (distribution->GetStatus() == 0) {
if (distribution->Init() == kFALSE) {
printf(" [error] %s:%s\n",distribution->GetDescription(),distribution->GetIdentifier());
distribution->SetEnable(0);
} else {
distribution->GetDepth();
dist[distribution_position] = distribution;
distribution_position++;
}
} else {
if (init_done) {
Reset();
Init();
if (distribution->GetStatus() == 0) {
if (distribution->Init() == kFALSE) {
printf(" [error] %s:%s\n",distribution->GetDescription(),distribution->GetIdentifier());
distribution->SetEnable(0);
} else {
distribution->GetDepth();
dist[distribution_position] = distribution;
distribution_position++;
}
}
} else {
dist[distribution_position] = distribution;
distribution_position++;
}
}
return 0;
}
void PChannel::GetMessage() { printf(" %s\n",Message[status]); }
char const *PChannel::GetName(void) const {
if (!thSrc && !tcSrc && !dlSrc) {
if (decay_key < 0 ) {
Warning("GetName", "No decay key found");
exit(1);
}
return makeStaticData()->GetDecayNameByKey(decay_key);
}
if (thSrc)
return " Fireball";
else if (tcSrc)
return " File Input";
else if (dlSrc)
return " Dilepton source";
return "<unknown>";
}
void PChannel::PrintReport() const {
PrintReaction();
cout << "Weighting report" << endl;
for (int j=0;j<distribution_position;j++) {
printf(" [%s] %s\n",dist[j]->GetIdentifier(),dist[j]->GetDescription());
if (dist[j]->GetExpectedWeightMean() > 0) {
cout << "Expected mean: " << dist[j]->GetExpectedWeightMean() << " Reached: "
<< dist_weight_sum[j]/dist_counter[j] << endl;
cout << "Calc mean: " << dist[j]->CalcWeightMean() << endl;
} else {
cout << "Mean: " << dist_weight_sum[j]/dist_counter[j] << endl;
}
}
}
void PChannel::PrintReaction(Int_t check_key) const {
if (check_key) {
if (!thSrc && !tcSrc && !dlSrc) {
if (decay_key < 0 ) {
Warning("PrintReaction", "No decay key found");
exit(1);
}
cout << makeStaticData()->GetDecayNameByKey(decay_key) << endl;
return;
}
}
int j;
if (thSrc)
printf("Fireball");
else if (tcSrc)
printf("File Input");
else if (dlSrc)
printf("Dilepton source");
else
printf("%s", makeStaticData()->GetParticleName(ipid[0]));
printf(" --> %s", makeStaticData()->GetParticleName(ipid[1]));
for (j=2; j<=n; ++j)
printf(" + %s",makeStaticData()->GetParticleName(ipid[j]));
cout << endl;
}
void PChannel::PrintNew() {
Long_t nPattern = 0;
for (int j=0; j<distribution_position; j++)
if (dist[j]->GetEnable() != 0) {
nPattern += ((j<64) ? 1<<(j+1) : 0);
}
if (nPattern & (~fEnablePattern)) {
fEnablePattern |= nPattern;
Print();
}
}
void PChannel::Print(const Option_t *delme) const {
int j;
if (quasi_pchannel)
quasi_pchannel->Print();
PrintReaction();
printf(" Interaction model(s):\n");
for (j=0;j<distribution_position;j++) {
if (dist[j]->GetEnable() != 0) {
if (dist[j]->GetStatus() == 0) {
dist[j]->GetDepth();
if (dist[j]->Path())
printf(" [%s] %s {/%s}",dist[j]->GetIdentifier(),dist[j]->GetDescription(),dist[j]->Path());
else
printf(" [%s] %s",dist[j]->GetIdentifier(),dist[j]->GetDescription());
dist[j]->SubPrint(0);
cout << endl;
} else
printf(" [%s,tentative] %s\n",dist[j]->GetIdentifier(),dist[j]->GetDescription());
if (delme != NULL && strcmp(delme,"debug") == 0) {
dist[j]->Print();
}
}
}
if (thSrc) ((PFireball * )parent)->Print(" ");
if (bulkdecay_pos || pro_bulkdecay_pos) {
printf(" Bulk Classes:\n");
if (pro_bulkdecay_pos) {
printf(" Prologue: ");
for (j=0;j<pro_bulkdecay_pos;j++)
cout << "<" << pro_bulk[j]->ClassName() << "> ";
cout << endl;
}
if (bulkdecay_pos) {
printf(" Epilogue: ");
for (j=0;j<bulkdecay_pos;j++)
cout << "<" << bulk[j]->ClassName() << "> ";
cout << endl;
}
}
}
Bool_t PChannel::AddBulk(PBulkInterface *mybulk) {
if (bulkdecay_pos == MAX_BULKDECAY ) {
Error("AddBulk","MAX_BULKDECAY reached");
return kFALSE;
}
if (bulkdecay_pos && (bulk[bulkdecay_pos-1]->GetPriority() > mybulk->GetPriority())) {
bulk[bulkdecay_pos] = bulk[bulkdecay_pos-1];
bulk[bulkdecay_pos-1] = mybulk;
bulkdecay_pos++;
} else
bulk[bulkdecay_pos++]=mybulk;
return kTRUE;
}
Bool_t PChannel::AddPrologueBulk(PBulkInterface * mybulk) {
if (pro_bulkdecay_pos == MAX_BULKDECAY ) {
Error("AddPrologueBulk","MAX_BULKDECAY reached");
return kFALSE;
}
if (pro_bulkdecay_pos && (pro_bulk[pro_bulkdecay_pos-1]->GetPriority() > mybulk->GetPriority())) {
pro_bulk[pro_bulkdecay_pos] = pro_bulk[pro_bulkdecay_pos-1];
pro_bulk[pro_bulkdecay_pos-1] = mybulk;
pro_bulkdecay_pos++;
} else
pro_bulk[pro_bulkdecay_pos++]=mybulk;
return kTRUE;
}
ClassImp(PChannel)