/////////////////////////////////////////////////////////////////////
//
//  N + N --> N + Delta, Ref 1
//
//                                  Author: Kagarlis  
//                                  Reimplemented I. Froehlich
/////////////////////////////////////////////////////////////////////


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

#include "PDeltaAngularDistribution.h"

ClassImp(PDeltaAngularDistribution)

PDeltaAngularDistribution::PDeltaAngularDistribution() {
};

PDeltaAngularDistribution::PDeltaAngularDistribution(const Char_t *id, const Char_t *de) :
    PAngularDistribution(id, de) {

    beam     = NULL;
    target   = NULL;
    use_term = 1+2+4; //By default all terms
};

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

Bool_t PDeltaAngularDistribution::IsNotRejected(void) {
    
    if (!direct_sampling_done) {
	Fatal("IsNotRejected", "Sampling not finished");
    }

    return kTRUE;
};

Bool_t PDeltaAngularDistribution::Init(void) {
    if (!PAngularDistribution:: Init()) return kFALSE;

    //In addition we need the beam and target
    //done already in PAngularDistribution

    if (!beam || !target) {
	Warning("Init", "beam or target not found");
	return kFALSE;
    }

    return kTRUE;
};

Bool_t PDeltaAngularDistribution::Prepare(void) {
    getNN_DeltaN_param();
    return kTRUE;
};

void PDeltaAngularDistribution::getNN_DeltaN_param() {
    // parameters of the Delta cm production angle in N+N->N+Delta
    // Ref. 1

    const double L1 = 0.3969, L2 = 0.36;     // NN & NDelta coupling constant^2
    const double fs_pi = 2.202, 
	mpi = makeStaticData()->GetParticleMass("pi0"), g_pi=0.6, 
	fmg = g_pi*fs_pi/mpi, 
	mp  = makeStaticData()->GetParticleMass("p"), 
	mp2 = mp*mp, 
	mp4 = mp2*mp2;
    double I2 = (beam->Vect4())*(target->Vect4());// product of Lorentz vectors

//  if(pdNNN>0) I2 /= 2.;                 // for p+d and d+p, half I2
// Commented out, since treated explicetly

    I2 = I2*I2-mp4;                         // kinematical factor for cross section
    if (I2 <= 0.) {
	anisotropy = 0;
	return;
    }
    anisotropy = 1;
    // factors for N + N --> N + Delta cross section
    lambda2 = ((beam->Vect()).Mag()<3.)?L1:L2;
    prefac  = fmg*fmg/(4.*64.*TMath::Pi()*I2);
};

double PDeltaAngularDistribution::ds_dt(double cos_th_cm) {
    // ds/dt(cos_th_cm) in the cm for N+N->N+Delta. With the mass of Delta
    // sampled independently in PData, the simulated events are distributed
    // as ds/dOmega (normalized). (see Ref. 1)

    const double mpi = makeStaticData()->GetParticleMass("pi0"), 
	mpi2 = mpi*mpi, 
	mp   = makeStaticData()->GetParticleMass("p"),
	mp2  = mp*mp, 
	mp4  = mp2*mp2, 
	mdelta = makeStaticData()->GetParticleMass("D0");

    double m  = mres, 
	md2   = m*m, 
	md4   = md2*md2, 
	mdmn  = m-mp, 
	mdn   = m+mp,
	mdmnm = mdmn*mdn, 
	mdn2  = mdn*mdn, 
	mdn4  = mdn2*mdn2, 
	mdmn2 = mdmn*mdmn,
	pf    = prefac/md2;

    // Mandelstam invariant t and u:
    double t = parent->InvariantT(mp,m,-cos_th_cm), // cos_th_cm sign inversed, Tingting Liu, 2010-04-13
	u = parent->InvariantT(m,mp,cos_th_cm),  // cos_th_cm sign inversed, Tingting Liu, 2010-04-13
	tu = t*u, 
	tpu = t+u;

    // Form factors for t and u channels
    double f_t = (lambda2-mpi2)/(lambda2-t);       // form factor F(t) eq. (4)
    f_t *= f_t/(t-mpi2);
    double f_u = (lambda2-mpi2)/(lambda2-u);       // same for u channel F(u)
    f_u *= f_u/(u-mpi2);

    // Off-shell corrections of Eq. (17) of Ref 1,
    // but for Moniz Delta-width parametrization see Z. Phys. A356 (1997) 421
    double qt = (PKinematics::pcmt(mdelta,t)+.09)/(PKinematics::pcmt(m,t)+.09),
	qu = (PKinematics::pcmt(mdelta,u)+.09)/(PKinematics::pcmt(m,u)+.09);
    f_t *= qt*qt;                                // Eqs. (17)
    f_u *= qu*qu;
  
    // the matrix elements for N+N->N+Delta, Eqs. (7-8) in Ref 1
    double M_t2 = pf/3. * f_t * f_t * t * (t-mdmn2) * (t-mdn2) * (t-mdn2); // t-channel
    double M_u2 = pf/3. * f_u * f_u * u * (u-mdmn2) * (u-mdn2) * (u-mdn2); // u-channel
    double M_tu = pf/2. * f_t * f_u *
	( (tu + mdmnm * tpu - md4 + mp4) * (tu + mp * mdn * mdmnm)
	  - (tu - mdn2 * tpu + mdn4) * (tu - mp * mdmn * mdmnm)/3. ); // exchange term
    // fixed according to S. Teis Ph.D.  (Giessen 1996) 
    double M2 = 0;
    if (use_term & 0x1) {M2+=M_t2;primary->SetValue(T_MATRIX ,M_t2);}
    if (use_term & 0x2) {M2+=M_tu;primary->SetValue(TU_MATRIX ,M_tu);}
    if (use_term & 0x4) {M2+=M_u2;primary->SetValue(U_MATRIX ,M_u2);}
  
    return M2;
};

double PDeltaAngularDistribution::SamplePolarAngle(double r) {

    double f=-1, tf=-1, r2, c0=-1, r1=r, a=-1, b=-1, area=-1, x1, delta;
    //int fl=0 ;

    if (!anisotropy) return 2*r-1;

    mres = primary->M();

    // test-function parameters for resonances
    a = 1.01*ds_dt(0.);                 // constant
    b = 1.2*(1.01*ds_dt(.995) - a);     // slope  (ds_dt(0) droops, use 0.995)
    area = b*(2. + b/a)/a;              // area x b/a^2
  
 again:
  
    //fl=1;
    x1 = (1-2*(r1>.5))*a/b;
    delta = sqrt(1+area*fabs(1-2*r1));
    c0 = x1*(1-delta);
    f  = ds_dt(c0);
    tf = a+b*fabs(c0);
//  printf("********a=%f b=%f: c0=%f tf=%f f=%f\n",a,b,c0,tf,f);
    r2 = PUtils::sampleFlat();
    if (r2 > f/tf) {                        // reject
	r1 = PUtils::sampleFlat();
	goto again;
    }
    if (tf < f) {                           // diagnostics
//	Warning("SamplePolarAngle","algorithm failed %d",fl);
//	Warning("SamplePolarAngle","a=%f b=%f: c0=%f tf=%f f=%f mres=%f mpar=%f",a,b,c0,tf,f,mres,parent->M());
	r1 = PUtils::sampleFlat();
	goto again;
    }
    return c0;                            // accept
};

void PDeltaAngularDistribution::Print(const Option_t *) const {
    PAngularDistribution::Print();
};


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