/////////////////////////////////////////////////////////////////////
//
// Decay Model in 1 unstable and N stable hadrons
// The unstable hadron is which has the largest width
// All other masses are set to the fixed value
//
//                                  Author:  I. Froehlich
/////////////////////////////////////////////////////////////////////


using namespace std;
#include <sstream>
#include <iostream>
#include <iomanip>
#include <math.h>

#include "PHadronDecayM1N.h"


ClassImp(PHadronDecayM1N)

PHadronDecayM1N::PHadronDecayM1N() {
};

PHadronDecayM1N::PHadronDecayM1N(const Char_t *id, const Char_t *de, Int_t key) :
    PChannelModel(id, de, key) {
    if (is_channel < 0)
	Warning("PHadronDecayM1N", "The model (%s) should be bound to CHANNELS only",de);
  
    //Get particles
    Int_t tid[11];
    tid[0] = 10; 
    makeStaticData()->GetDecayModeByKey(primary_key, tid); // retrieve current mode info

    //Parent ALWAYS important (also for the inherited classes)
    parent_id   = makeStaticData()->GetDecayParentByKey(primary_key);
    parent_mass = makeStaticData()->GetParticleMass(parent_id);

    parent = NULL;
    daughter_pos   = 0;
    unstable_pos   = -1;
    unstable_width = 0;
    for (int i=0; i<M1N_MAX_DAUGHTERS; i++) {
	daughters[i] = NULL;
    }
    for (int i=0; i<tid[0]; i++) {
	daughter_masses[i] = makeStaticData()->GetParticleMass(tid[i+1]);
	daughter_id[i]     = tid[i+1];
	daughter_didx[i]   = -1;
	if (makeStaticData()->GetParticleTotalWidth(tid[i+1]) > unstable_width) {
	    //define M1 as the most unstable one
	    unstable_pos   = i;
	    unstable_id    = tid[i+1];
	    unstable_width = makeStaticData()->GetParticleTotalWidth(tid[i+1]);
	}
    }
    mesh  = NULL;
    event = new TGenPhaseSpace();
    
    maxmesh = 300;
    //We scan the complete phase space 
    old_parent_mass = 0;

    mesh = new PMesh(maxmesh-2,"mesh");
};

PDistribution *PHadronDecayM1N::Clone(const char *) const {
    return new PHadronDecayM1N((const PHadronDecayM1N &)* this);
};

void PHadronDecayM1N::UpdateMesh(void) {
    
    Double_t mmin = PData::LMass(unstable_id);
    Double_t mmax = PData::UMass(unstable_id);
    Double_t dm   = (mmax-mmin)/(maxmesh-3.);          // mass increment
    for (int i=0; i<maxmesh-2; ++i) {
	Double_t mm = mmin+i*dm;                     // current invariant mass
	
	daughter_masses[unstable_pos] = mm;
	event->SetDecay(*(TLorentzVector*)parent,daughter_pos, daughter_masses);
	Double_t phase_space  = 1./event->GetWtMax();
	Double_t model_weight = unstable_model->GetWeight(mm,&unstable_didx);
	
	mesh->SetNode(i, phase_space*model_weight); 
    }
    mesh->SetMin(mmin);                 // store mass threshold
    mesh->SetMax(mmax);                 // store mass ceiling
    SetDynamicRange(mmin, mmax);

    if (!fIntegral.empty()) {
	fIntegral.clear();
	fAlpha.clear();
	fBeta.clear();
	fGamma.clear();
    }
}

Bool_t PHadronDecayM1N::Init(void) {
    //Init function called once for each PChannel

    unstable_particle = NULL;

    //looking for parent. This is mandatory
    parent = GetParticle("parent");
    if (!parent) {
	Warning("Init", "Parent not found");
	return kFALSE;
    }

    daughter_pos = 0; //clear stuff because the Attach function makes a clone
    
    //Now get all daughters
    for (int i=0; i<M1N_MAX_DAUGHTERS; i++) {
	daughters[i] = GetParticle("daughter");
	if (daughters[i]) {
	    if (daughters[i]->ID() == unstable_id) {
		unstable_particle = daughters[i];
	    }
	    daughter_pos++;
	}
    }

    if (!unstable_particle) {
	Warning("Init", "Unstable particle not found");
	return kFALSE;
    }

    return kTRUE;
}

Bool_t PHadronDecayM1N::Prepare(void) {
    //Things which might change during the eventloop
    
    unstable_didx = unstable_particle->GetDecayModeIndex(1);
    return kTRUE;
}
 
int PHadronDecayM1N::GetDepth(int i) {
    //check if we have models
    //This also initializes the sub-models

    Int_t a1=0;
    unstable_model = makeDynamicData()->GetParticleModel(unstable_id);
    if (unstable_model) a1 = unstable_model->GetDepth(i);

    //makeStaticData()->SetDecayEmin(is_channel, all_masses);
    return a1; 
}

void PHadronDecayM1N::SubPrint(Int_t) const {
    //Print sub-models
    
    if (unstable_model) {
	cout << " ";
	cout << unstable_model->GetDescription();
    }
}


Double_t PHadronDecayM1N::EvalPar(const Double_t *x, const Double_t *) {
    return Eval(x[0]);
}

Double_t PHadronDecayM1N::Eval(Double_t x, Double_t, Double_t, Double_t) const {
    if (mesh)  {
	return mesh->GetLinearIP(x);
    }
    return 0.;
}

Bool_t PHadronDecayM1N::SampleMass(void) {
    //Mass-sampling wrapper

    parent_mass = parent->M();

    if (fabs( parent_mass - old_parent_mass) > M1N_PARENT_GRID) {
	old_parent_mass = parent_mass;
	UpdateMesh();
    }

    Double_t new_mass = this->GetRandom();

    unstable_particle->SetM(new_mass);

    return kTRUE;
};

ClassImp(PHadronDecayM1N)
 PHadronDecayM1N.cc:1
 PHadronDecayM1N.cc:2
 PHadronDecayM1N.cc:3
 PHadronDecayM1N.cc:4
 PHadronDecayM1N.cc:5
 PHadronDecayM1N.cc:6
 PHadronDecayM1N.cc:7
 PHadronDecayM1N.cc:8
 PHadronDecayM1N.cc:9
 PHadronDecayM1N.cc:10
 PHadronDecayM1N.cc:11
 PHadronDecayM1N.cc:12
 PHadronDecayM1N.cc:13
 PHadronDecayM1N.cc:14
 PHadronDecayM1N.cc:15
 PHadronDecayM1N.cc:16
 PHadronDecayM1N.cc:17
 PHadronDecayM1N.cc:18
 PHadronDecayM1N.cc:19
 PHadronDecayM1N.cc:20
 PHadronDecayM1N.cc:21
 PHadronDecayM1N.cc:22
 PHadronDecayM1N.cc:23
 PHadronDecayM1N.cc:24
 PHadronDecayM1N.cc:25
 PHadronDecayM1N.cc:26
 PHadronDecayM1N.cc:27
 PHadronDecayM1N.cc:28
 PHadronDecayM1N.cc:29
 PHadronDecayM1N.cc:30
 PHadronDecayM1N.cc:31
 PHadronDecayM1N.cc:32
 PHadronDecayM1N.cc:33
 PHadronDecayM1N.cc:34
 PHadronDecayM1N.cc:35
 PHadronDecayM1N.cc:36
 PHadronDecayM1N.cc:37
 PHadronDecayM1N.cc:38
 PHadronDecayM1N.cc:39
 PHadronDecayM1N.cc:40
 PHadronDecayM1N.cc:41
 PHadronDecayM1N.cc:42
 PHadronDecayM1N.cc:43
 PHadronDecayM1N.cc:44
 PHadronDecayM1N.cc:45
 PHadronDecayM1N.cc:46
 PHadronDecayM1N.cc:47
 PHadronDecayM1N.cc:48
 PHadronDecayM1N.cc:49
 PHadronDecayM1N.cc:50
 PHadronDecayM1N.cc:51
 PHadronDecayM1N.cc:52
 PHadronDecayM1N.cc:53
 PHadronDecayM1N.cc:54
 PHadronDecayM1N.cc:55
 PHadronDecayM1N.cc:56
 PHadronDecayM1N.cc:57
 PHadronDecayM1N.cc:58
 PHadronDecayM1N.cc:59
 PHadronDecayM1N.cc:60
 PHadronDecayM1N.cc:61
 PHadronDecayM1N.cc:62
 PHadronDecayM1N.cc:63
 PHadronDecayM1N.cc:64
 PHadronDecayM1N.cc:65
 PHadronDecayM1N.cc:66
 PHadronDecayM1N.cc:67
 PHadronDecayM1N.cc:68
 PHadronDecayM1N.cc:69
 PHadronDecayM1N.cc:70
 PHadronDecayM1N.cc:71
 PHadronDecayM1N.cc:72
 PHadronDecayM1N.cc:73
 PHadronDecayM1N.cc:74
 PHadronDecayM1N.cc:75
 PHadronDecayM1N.cc:76
 PHadronDecayM1N.cc:77
 PHadronDecayM1N.cc:78
 PHadronDecayM1N.cc:79
 PHadronDecayM1N.cc:80
 PHadronDecayM1N.cc:81
 PHadronDecayM1N.cc:82
 PHadronDecayM1N.cc:83
 PHadronDecayM1N.cc:84
 PHadronDecayM1N.cc:85
 PHadronDecayM1N.cc:86
 PHadronDecayM1N.cc:87
 PHadronDecayM1N.cc:88
 PHadronDecayM1N.cc:89
 PHadronDecayM1N.cc:90
 PHadronDecayM1N.cc:91
 PHadronDecayM1N.cc:92
 PHadronDecayM1N.cc:93
 PHadronDecayM1N.cc:94
 PHadronDecayM1N.cc:95
 PHadronDecayM1N.cc:96
 PHadronDecayM1N.cc:97
 PHadronDecayM1N.cc:98
 PHadronDecayM1N.cc:99
 PHadronDecayM1N.cc:100
 PHadronDecayM1N.cc:101
 PHadronDecayM1N.cc:102
 PHadronDecayM1N.cc:103
 PHadronDecayM1N.cc:104
 PHadronDecayM1N.cc:105
 PHadronDecayM1N.cc:106
 PHadronDecayM1N.cc:107
 PHadronDecayM1N.cc:108
 PHadronDecayM1N.cc:109
 PHadronDecayM1N.cc:110
 PHadronDecayM1N.cc:111
 PHadronDecayM1N.cc:112
 PHadronDecayM1N.cc:113
 PHadronDecayM1N.cc:114
 PHadronDecayM1N.cc:115
 PHadronDecayM1N.cc:116
 PHadronDecayM1N.cc:117
 PHadronDecayM1N.cc:118
 PHadronDecayM1N.cc:119
 PHadronDecayM1N.cc:120
 PHadronDecayM1N.cc:121
 PHadronDecayM1N.cc:122
 PHadronDecayM1N.cc:123
 PHadronDecayM1N.cc:124
 PHadronDecayM1N.cc:125
 PHadronDecayM1N.cc:126
 PHadronDecayM1N.cc:127
 PHadronDecayM1N.cc:128
 PHadronDecayM1N.cc:129
 PHadronDecayM1N.cc:130
 PHadronDecayM1N.cc:131
 PHadronDecayM1N.cc:132
 PHadronDecayM1N.cc:133
 PHadronDecayM1N.cc:134
 PHadronDecayM1N.cc:135
 PHadronDecayM1N.cc:136
 PHadronDecayM1N.cc:137
 PHadronDecayM1N.cc:138
 PHadronDecayM1N.cc:139
 PHadronDecayM1N.cc:140
 PHadronDecayM1N.cc:141
 PHadronDecayM1N.cc:142
 PHadronDecayM1N.cc:143
 PHadronDecayM1N.cc:144
 PHadronDecayM1N.cc:145
 PHadronDecayM1N.cc:146
 PHadronDecayM1N.cc:147
 PHadronDecayM1N.cc:148
 PHadronDecayM1N.cc:149
 PHadronDecayM1N.cc:150
 PHadronDecayM1N.cc:151
 PHadronDecayM1N.cc:152
 PHadronDecayM1N.cc:153
 PHadronDecayM1N.cc:154
 PHadronDecayM1N.cc:155
 PHadronDecayM1N.cc:156
 PHadronDecayM1N.cc:157
 PHadronDecayM1N.cc:158
 PHadronDecayM1N.cc:159
 PHadronDecayM1N.cc:160
 PHadronDecayM1N.cc:161
 PHadronDecayM1N.cc:162
 PHadronDecayM1N.cc:163
 PHadronDecayM1N.cc:164
 PHadronDecayM1N.cc:165
 PHadronDecayM1N.cc:166
 PHadronDecayM1N.cc:167
 PHadronDecayM1N.cc:168
 PHadronDecayM1N.cc:169
 PHadronDecayM1N.cc:170
 PHadronDecayM1N.cc:171
 PHadronDecayM1N.cc:172
 PHadronDecayM1N.cc:173
 PHadronDecayM1N.cc:174
 PHadronDecayM1N.cc:175
 PHadronDecayM1N.cc:176
 PHadronDecayM1N.cc:177
 PHadronDecayM1N.cc:178
 PHadronDecayM1N.cc:179
 PHadronDecayM1N.cc:180
 PHadronDecayM1N.cc:181
 PHadronDecayM1N.cc:182
 PHadronDecayM1N.cc:183
 PHadronDecayM1N.cc:184
 PHadronDecayM1N.cc:185
 PHadronDecayM1N.cc:186
 PHadronDecayM1N.cc:187
 PHadronDecayM1N.cc:188