/////////////////////////////////////////////////////////////////////
//
// Decay Model of Hadron -> Hadron(stable) + Hadron(stable)
// Such a case is e.g. the Delta->N+pi
//
//                                  Author:  I. Froehlich
/////////////////////////////////////////////////////////////////////


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

#include "PHadronDecay.h"


ClassImp(PHadronDecay)

PHadronDecay::PHadronDecay()  {
};

PHadronDecay::PHadronDecay(const Char_t *id, const Char_t *de, Int_t key) :
    PChannelModel(id, de, key) {

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

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

    if (tid[0] != 2) 
	Warning("PHadronDecay", "(%s):  Only 2 body decay", de);

    mass1 = makeStaticData()->GetParticleMass(tid[1]);
    mass2 = makeStaticData()->GetParticleMass(tid[2]);
    id1   = tid[1];
    id2   = tid[2];

    //Auto-set kinematic factors (for HadronWidth)
    //These values might be overwritten in inherited classes
    if (makeStaticData()->IsParticleMeson(parent_id) ||
	PData::IsDelta(parent_id)) {
	use_fixed_delta = 1;
	fixed_delta     = 0.09;
    } else 
	use_fixed_delta = 0;

    angular_l = (makeStaticData()->IsParticleMeson(parent_id)) ? 
	makeStaticData()->GetParticleSpin(parent_id)/2 : 
	PData::LPW(parent_id, id1, id2);

    if (!makeStaticData()->IsParticleMeson(parent_id)) 
	cutoff_l = 1;
    else 
	cutoff_l = 0; //cutoff=pow(cutoff,l+1); in HadronWidth

    if (makeStaticData()->IsParticleMeson(parent_id)) 
	use_m0_over_m = 1;
    else 
	use_m0_over_m = 0;

    if ((makeStaticData()->GetParticleID("D++") == parent_id) ||
	(makeStaticData()->GetParticleID("D+") == parent_id) ||
	(makeStaticData()->GetParticleID("D0") == parent_id) ||
	(makeStaticData()->GetParticleID("D-") == parent_id))
	use_m0_over_m = 1;
    
    cutoff_version = 0;

    version_flag |= VERSION_MASS_SAMPLING;  //Only one mass sampling in the PChannel

    w0=makeStaticData()->GetDecayBR(is_channel); //Weight used for mormalization
};

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

Bool_t PHadronDecay::Init(void) {
    //Init function called once for each PChannel
    return kTRUE;
};

Double_t PHadronDecay::EvalPar(const Double_t *x, const Double_t *) {
    return Eval(x[0]);
};
 
Double_t PHadronDecay::Eval(Double_t x, Double_t, Double_t, Double_t) const {
    Double_t res;
    Double_t mass[3];
    mass[0] = x; 
    mass[1] = mass1;
    mass[2] = mass2;

    if (draw_option == 0) {
	return ((PChannelModel*)this)->GetWeight(mass);
	//return res;
    } 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 PHadronDecay::GetDepth(int) {
    
    makeStaticData()->SetDecayEmin(is_channel, mass1+mass2);
    return 0; //2 stable products -> depth is 0
};

Bool_t PHadronDecay::SampleMass(void) {
    //Mass-sampling wrapper
    return kTRUE;
};

Bool_t PHadronDecay::SampleMass(Double_t *mass, Int_t *) {
    //Not much to do here...
    //Since we have 2 stable products, for completeness
    //we reset the masses to the nominal value
    mass[1] = mass1;
    mass[2] = mass2;
    return kTRUE;
};


// Bool_t PHadronDecay::GetBR(Double_t mass, Double_t *br, Double_t totalwidth) {
//     //Calculates the mass-dependent br
//     //the totalwidth may be set by the user, otherwise we use the static one
//     //We take the 2body-ps into account

   
//     if (!GetWidth(mass,&width)) return kFALSE;
//     *br = width/totalwidth;

//     double sc_pole=

//     return kTRUE; 
	
// }


Bool_t PHadronDecay::GetWidth(Double_t mass, Double_t *width, Int_t) {

    if (makeStaticData()->GetPWidx(is_channel) == -1) {
	*width = parent_g0;
	return kFALSE;
    }
    *width = w0*HadronWidth(mass, mass1, mass2);
    return kTRUE;
}



// Comment (IF): This function was used in Width1, but it seems to be useless
// in the case of 2 stable products
// It just makes checks which are repeated in HWidth (now: HadronWidth)

// double PHadronDecay::HW(const double & ecm, const int & id, const int & ia=0, const int & ib=0) {
//     // for stable products

//     const double mproton=makeStaticData()->GetParticleMass("p"), 
// 	m2pi0=2.*makeStaticData()->GetParticleMass("pi0");
//     double m0=makeStaticData()->GetParticleMass(id), ma, mb, ms;
    
//     if (!(ia+ib)) {             // flag identifying N + 2-pion s-wave production
//       ma=mproton;               // in this case treat as two-body decay: 
//       mb=m2pi0;                 // 1st product is N, 2nd quasi-product is di-pion
//     } else {                    // two-hadron decay
//       ma=makeStaticData()->GetParticleMass(ia);  // 1st hadron mass
//       mb=makeStaticData()->GetParticleMass(ib);  // 2nd hadron mass
//     }
//     ms=ma+mb;                   // sum of product masses

//     return (ecm<ms||m0<ms) ? 0. : HWidth(id,ia,ib,ecm,ma,mb);
//   }


double PHadronDecay::HadronWidth(const double &m, const double &ma, const double &mb) {
    // Kinematic width (+ phase space + cutoff) for decays of type hadron -> hadron + hadron
    // Arguments: masses (GeV/c**2)
    // See Ref 10 Eqs. (15-17).
    //
    // Uses data members:
    // * parent_mass
    // * parent_g0
    
    double m0 = parent_mass, 
	ms = ma+mb, 
	md = m0-ms;
    //    if (m<=ms||md<=0.) return 0.;        // kinematically inaccessible
    if (m <= ms) return 0.;

    double qr2 = PKinematics::pcms2(m0, ma, mb),
	q2 = PKinematics::pcms2(m, ma, mb);
    if (qr2 == 0) //Below threshold production
	qr2 = 1;   
    double q = sqrt(q2/qr2);

    if (!id1) 
	return parent_g0*q*m0/m;  // ia=ib=0 is two pions coupled to s-wave

    double delta2 = (use_fixed_delta) ? fixed_delta : md*md+0.25*parent_g0*parent_g0;
    double cutoff = (qr2 + delta2)/(q2 + delta2);

    if (angular_l) {
	q = pow(q,2*angular_l+1);
	if (cutoff_l) 
	    cutoff = pow(cutoff, angular_l+1);
    }

    if (cutoff_version == 1) {
	if (angular_l)
	    cutoff = (1.2)/(1+0.2*pow(q,2*angular_l));
	else
	    cutoff = (1.2)/(1+0);
    } else if (cutoff_version == 2) {
	cutoff = 1;
	cout << "no cutoff " << is_channel << endl;
	cout << "mass " << m << " res: " << q << endl;
    }

    q *= parent_g0*cutoff;

    return (use_m0_over_m) ? q*pow((m0/m),use_m0_over_m) : q;
}

ClassImp(PHadronDecay)
 PHadronDecay.cc:1
 PHadronDecay.cc:2
 PHadronDecay.cc:3
 PHadronDecay.cc:4
 PHadronDecay.cc:5
 PHadronDecay.cc:6
 PHadronDecay.cc:7
 PHadronDecay.cc:8
 PHadronDecay.cc:9
 PHadronDecay.cc:10
 PHadronDecay.cc:11
 PHadronDecay.cc:12
 PHadronDecay.cc:13
 PHadronDecay.cc:14
 PHadronDecay.cc:15
 PHadronDecay.cc:16
 PHadronDecay.cc:17
 PHadronDecay.cc:18
 PHadronDecay.cc:19
 PHadronDecay.cc:20
 PHadronDecay.cc:21
 PHadronDecay.cc:22
 PHadronDecay.cc:23
 PHadronDecay.cc:24
 PHadronDecay.cc:25
 PHadronDecay.cc:26
 PHadronDecay.cc:27
 PHadronDecay.cc:28
 PHadronDecay.cc:29
 PHadronDecay.cc:30
 PHadronDecay.cc:31
 PHadronDecay.cc:32
 PHadronDecay.cc:33
 PHadronDecay.cc:34
 PHadronDecay.cc:35
 PHadronDecay.cc:36
 PHadronDecay.cc:37
 PHadronDecay.cc:38
 PHadronDecay.cc:39
 PHadronDecay.cc:40
 PHadronDecay.cc:41
 PHadronDecay.cc:42
 PHadronDecay.cc:43
 PHadronDecay.cc:44
 PHadronDecay.cc:45
 PHadronDecay.cc:46
 PHadronDecay.cc:47
 PHadronDecay.cc:48
 PHadronDecay.cc:49
 PHadronDecay.cc:50
 PHadronDecay.cc:51
 PHadronDecay.cc:52
 PHadronDecay.cc:53
 PHadronDecay.cc:54
 PHadronDecay.cc:55
 PHadronDecay.cc:56
 PHadronDecay.cc:57
 PHadronDecay.cc:58
 PHadronDecay.cc:59
 PHadronDecay.cc:60
 PHadronDecay.cc:61
 PHadronDecay.cc:62
 PHadronDecay.cc:63
 PHadronDecay.cc:64
 PHadronDecay.cc:65
 PHadronDecay.cc:66
 PHadronDecay.cc:67
 PHadronDecay.cc:68
 PHadronDecay.cc:69
 PHadronDecay.cc:70
 PHadronDecay.cc:71
 PHadronDecay.cc:72
 PHadronDecay.cc:73
 PHadronDecay.cc:74
 PHadronDecay.cc:75
 PHadronDecay.cc:76
 PHadronDecay.cc:77
 PHadronDecay.cc:78
 PHadronDecay.cc:79
 PHadronDecay.cc:80
 PHadronDecay.cc:81
 PHadronDecay.cc:82
 PHadronDecay.cc:83
 PHadronDecay.cc:84
 PHadronDecay.cc:85
 PHadronDecay.cc:86
 PHadronDecay.cc:87
 PHadronDecay.cc:88
 PHadronDecay.cc:89
 PHadronDecay.cc:90
 PHadronDecay.cc:91
 PHadronDecay.cc:92
 PHadronDecay.cc:93
 PHadronDecay.cc:94
 PHadronDecay.cc:95
 PHadronDecay.cc:96
 PHadronDecay.cc:97
 PHadronDecay.cc:98
 PHadronDecay.cc:99
 PHadronDecay.cc:100
 PHadronDecay.cc:101
 PHadronDecay.cc:102
 PHadronDecay.cc:103
 PHadronDecay.cc:104
 PHadronDecay.cc:105
 PHadronDecay.cc:106
 PHadronDecay.cc:107
 PHadronDecay.cc:108
 PHadronDecay.cc:109
 PHadronDecay.cc:110
 PHadronDecay.cc:111
 PHadronDecay.cc:112
 PHadronDecay.cc:113
 PHadronDecay.cc:114
 PHadronDecay.cc:115
 PHadronDecay.cc:116
 PHadronDecay.cc:117
 PHadronDecay.cc:118
 PHadronDecay.cc:119
 PHadronDecay.cc:120
 PHadronDecay.cc:121
 PHadronDecay.cc:122
 PHadronDecay.cc:123
 PHadronDecay.cc:124
 PHadronDecay.cc:125
 PHadronDecay.cc:126
 PHadronDecay.cc:127
 PHadronDecay.cc:128
 PHadronDecay.cc:129
 PHadronDecay.cc:130
 PHadronDecay.cc:131
 PHadronDecay.cc:132
 PHadronDecay.cc:133
 PHadronDecay.cc:134
 PHadronDecay.cc:135
 PHadronDecay.cc:136
 PHadronDecay.cc:137
 PHadronDecay.cc:138
 PHadronDecay.cc:139
 PHadronDecay.cc:140
 PHadronDecay.cc:141
 PHadronDecay.cc:142
 PHadronDecay.cc:143
 PHadronDecay.cc:144
 PHadronDecay.cc:145
 PHadronDecay.cc:146
 PHadronDecay.cc:147
 PHadronDecay.cc:148
 PHadronDecay.cc:149
 PHadronDecay.cc:150
 PHadronDecay.cc:151
 PHadronDecay.cc:152
 PHadronDecay.cc:153
 PHadronDecay.cc:154
 PHadronDecay.cc:155
 PHadronDecay.cc:156
 PHadronDecay.cc:157
 PHadronDecay.cc:158
 PHadronDecay.cc:159
 PHadronDecay.cc:160
 PHadronDecay.cc:161
 PHadronDecay.cc:162
 PHadronDecay.cc:163
 PHadronDecay.cc:164
 PHadronDecay.cc:165
 PHadronDecay.cc:166
 PHadronDecay.cc:167
 PHadronDecay.cc:168
 PHadronDecay.cc:169
 PHadronDecay.cc:170
 PHadronDecay.cc:171
 PHadronDecay.cc:172
 PHadronDecay.cc:173
 PHadronDecay.cc:174
 PHadronDecay.cc:175
 PHadronDecay.cc:176
 PHadronDecay.cc:177
 PHadronDecay.cc:178
 PHadronDecay.cc:179
 PHadronDecay.cc:180
 PHadronDecay.cc:181
 PHadronDecay.cc:182
 PHadronDecay.cc:183
 PHadronDecay.cc:184
 PHadronDecay.cc:185
 PHadronDecay.cc:186
 PHadronDecay.cc:187
 PHadronDecay.cc:188
 PHadronDecay.cc:189
 PHadronDecay.cc:190
 PHadronDecay.cc:191
 PHadronDecay.cc:192
 PHadronDecay.cc:193
 PHadronDecay.cc:194
 PHadronDecay.cc:195
 PHadronDecay.cc:196
 PHadronDecay.cc:197
 PHadronDecay.cc:198
 PHadronDecay.cc:199
 PHadronDecay.cc:200
 PHadronDecay.cc:201
 PHadronDecay.cc:202
 PHadronDecay.cc:203
 PHadronDecay.cc:204
 PHadronDecay.cc:205
 PHadronDecay.cc:206
 PHadronDecay.cc:207
 PHadronDecay.cc:208
 PHadronDecay.cc:209
 PHadronDecay.cc:210
 PHadronDecay.cc:211
 PHadronDecay.cc:212
 PHadronDecay.cc:213
 PHadronDecay.cc:214
 PHadronDecay.cc:215
 PHadronDecay.cc:216
 PHadronDecay.cc:217
 PHadronDecay.cc:218
 PHadronDecay.cc:219
 PHadronDecay.cc:220
 PHadronDecay.cc:221
 PHadronDecay.cc:222
 PHadronDecay.cc:223
 PHadronDecay.cc:224
 PHadronDecay.cc:225
 PHadronDecay.cc:226
 PHadronDecay.cc:227
 PHadronDecay.cc:228
 PHadronDecay.cc:229
 PHadronDecay.cc:230
 PHadronDecay.cc:231
 PHadronDecay.cc:232
 PHadronDecay.cc:233
 PHadronDecay.cc:234
 PHadronDecay.cc:235
 PHadronDecay.cc:236
 PHadronDecay.cc:237
 PHadronDecay.cc:238