/////////////////////////////////////////////////////////////////////
//
//
//                                  Author:  I. Froehlich
/////////////////////////////////////////////////////////////////////


using namespace std;
#include <sstream>
#include <iostream>
#include <iomanip>

#include "PEEDirectDecay.h"


ClassImp(PEEDirectDecay)

PEEDirectDecay::PEEDirectDecay()  {
};

PEEDirectDecay::PEEDirectDecay(const Char_t *id, const Char_t *de, Int_t key) : PChannelModel(id, de, key) {
    if (is_channel < 0)
	Warning("PEEDirectDecay", "The model (%s) should be bound to CHANNELS only", de);

    //set all needed parameters in advance

    Int_t tid[11];
    tid[0] = 10; 
    makeStaticData()->GetDecayModeByKey(key, tid); // retrieve current mode info
    parent_id = makeStaticData()->GetDecayParentByKey(key);
    
    if (tid[0] != 2) 
	Warning("PEEDirectDecay", "(%s) Only 2 body decay",de);

    if (makeStaticData()->IsParticle(parent_id, "rho0"))       
	cv = 3.079e-6;   
    else if (makeStaticData()->IsParticle(parent_id, "w"))     
	cv = 0.287e-6;
    else if (makeStaticData()->IsParticle(parent_id, "phi"))   
	cv = 1.450e-6;
    else if (makeStaticData()->IsParticle(parent_id, "J/Psi")) 
	cv = 1.560e-4;
    // eta-> ee: no vector meson 
    else {
	Warning("PEEDirectDecay", "(%s) Undetermined direct decay", de);
    }

    //ee or mumu?
    if (makeStaticData()->IsParticle(tid[1], "e+") ||
	makeStaticData()->IsParticle(tid[2], "e+")) 
	mlep = makeStaticData()->GetParticleMass("e-");
    else if (makeStaticData()->IsParticle(tid[1], "mu+")||
	     makeStaticData()->IsParticle(tid[2], "mu+")) 
	mlep = makeStaticData()->GetParticleMass("mu-");

    else Warning("PEEDirectDecay", "(%s) No dilepton/dimuon",de);

    use_pi_cutoff   = 0;
    use_hadronic_ps = 0;
};

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

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

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

    //getting leptons
    e1 = GetParticle("daughter");
    e2 = GetParticle("daughter");
    return kTRUE;
}

int PEEDirectDecay::GetDepth(int i) {
    makeStaticData()->SetDecayEmin(is_channel, 2*mlep);
    if (i) return -1; //no Hdepth
    return 0;
}

Bool_t PEEDirectDecay::SampleMass(void) {
    //Mass-sampling wrapper
    e1->SetM(mlep);
    e2->SetM(mlep);
    return kTRUE;
};

Bool_t PEEDirectDecay::SampleMass(Double_t *mass, Int_t *) {
    //Set to fixed decay products here
    mass[1] = mlep;
    mass[2] = mlep;
    return kTRUE;
};

#if 1
Bool_t PEEDirectDecay::GetWidth(Double_t mass, Double_t *width, Int_t) {

    if (makeStaticData()->GetPWidx(is_channel)==-1) {
	*width = makeStaticData()->GetDecayPartialWidth(is_channel);
	return kFALSE;
    }

    if (!makeStaticData()->GetPWidx(is_channel) || width_init == 0) { // Enter below only on the first call
#ifdef INGO_DEBUG
	Info("GetWidth", "Creating mesh in %s", makeStaticData()->GetDecayName(is_channel));
#endif
	width_init++;
	makeDynamicData()->GetParticleDepth(parent_id); // if 1st call will initialize flags

	mmin = makeStaticData()->GetDecayEmin(is_channel);  // mass threshold for the decay
	
	mmax = PData::UMass(parent_id);                // mass ceiling
	Double_t dm = (mmax-mmin)/(maxmesh-3.);          // mass increment
    
	mesh = new PMesh(maxmesh-2, "mesh");
	for (int i=0; i<maxmesh-2; ++i) {
	    Double_t mm = mmin+i*dm;   // current invariant mass of the parent resonance
	    Double_t temp0 = 0.;

	    //--------------------
	    double me = 2.*mlep*mlep;

	    double m2 = mm*mm, m3 = m2*mm, mem = me/m2;
	    double wid = 0;
	    if ((1.-2.*mem) > 0)
		wid = cv*sqrt(1.-2.*mem)*(1.+mem)/m3;
	    
	    //pipi cutoff
	    
	    double pi2phase = 1;

	    if ((use_pi_cutoff == 1)) 
		pi2phase = PKinematics::pcms(mm, makeStaticData()->GetParticleMass("pi+"),
					     makeStaticData()->GetParticleMass("pi-"));	  
	    
	    pi2phase = mm > 2*makeStaticData()->GetParticleMass("pi+") ? pi2phase : 0;

	    if ((wid>0) && (use_pi_cutoff)) {
		temp0 = wid*pow(pi2phase,3./2.) ;
	    } else if ((wid>0) && (use_hadronic_ps)) {
		Double_t pole_width = 
		    makeDynamicData()->GetParticleTotalWidthSum(makeStaticData()->GetParticleMass(parent_id),
								parent_id, 1);
		Double_t mass_width = 
		    makeDynamicData()->GetParticleTotalWidthSum(mm, parent_id, 1);
		
		temp0 = wid*(mass_width/pole_width);
	    } else if (wid>0) {
		temp0 = wid;
	    } else 
		temp0 = 0;
	    
	    //--------------------

	    mesh->SetNode(i, temp0); 
	}

	mesh->SetMin(mmin);                 // store mass threshold
	mesh->SetMax(mmax);                 // store mass ceiling
	makeStaticData()->SetPWidx(is_channel, 1);  //Enable channel
    } //END first call

    if (mesh)  {
	*width = mesh->GetLinearIP(mass);
	return kTRUE;
    }
    return kFALSE;
}
#endif

Double_t PEEDirectDecay::GetWeight(Double_t *, Int_t *) {
    Warning("GetWeight", "not implemented");
    return 0;
}

Double_t PEEDirectDecay::Eval(Double_t x, Double_t, Double_t, Double_t) const {
    Double_t res;
    Double_t mass = x;

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