/////////////////////////////////////////////////////////////////////
//
// Beam smearing models: Angular semaring is possible as well 
// as momentum smearing using TF1 objects. 
// Particles needed: beam and target (as grandparent), parent
// The particle from(beam, target) 
// with higher momentum is defined as the real beam
//
//                                  Author: I. Froehlich
//                                  Written: 18.7.2007
//                                  Revised: 
/////////////////////////////////////////////////////////////////////


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

#include "PBeamSmearing.h"

ClassImp(PBeamSmearing)

PBeamSmearing::PBeamSmearing() {
};

PBeamSmearing::~PBeamSmearing() {
    if (mybeam)   delete (mybeam);
    if (mytarget) delete (mytarget);
};

PBeamSmearing::PBeamSmearing(const Char_t *id, const Char_t *de) :
    PDistribution(id, de) {
    beam     = NULL;
    mybeam   = NULL;
    target   = NULL;
    mytarget = NULL;
    parent   = NULL;
    mom_smearing = NULL;
    ang_smearing = NULL;
    mom_function = NULL;
    mom_smearing_histo = NULL;
    mom_function_histo = NULL;
    thetaBeam = 0.;
    phiBeam   = 0.;
    sigmaBeam = 0.;
};

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


Bool_t PBeamSmearing::Init(void) {
    //Read beam, target and parent

    beam   = GetParticle("beam");
    target = GetParticle("target");
    parent = GetParticle("parent");

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

    if (!mybeam)
	mybeam = new PParticle(beam);
    else
	*mybeam = *beam;
    if (!mytarget)
	mytarget= new PParticle(target);
    else
	*mytarget = target;

    if (!parent){
	Error("Init", "Parent not found");
	return kFALSE;
    }

    if (!mom_smearing && !ang_smearing && !mom_function) {
	Warning("Init", "No smearing model found");
    }

    return kTRUE;
}

Bool_t PBeamSmearing::Prepare(void) {
    //We use the prepare function for smearing since it might affect
    //the mass and momentum sampling done in the next steps

    Double_t angle = 0;
    if (ang_smearing) 
	angle = ang_smearing->GetRandom() *TMath::Pi() / 180.;

    Double_t mom = 1.;
    if (mom_smearing) 
	mom = mom_smearing->GetRandom();
    if (mom_smearing_histo) 
	mom *= mom_smearing->GetRandom();

    //restore saved particles
    *beam   = *mybeam;
    *target = *mytarget;

    //Apply first the new function smearing
    //because the following step includes tilting
    if (beam->P() > target->P()) {
	Double_t mymom = beam->Rho();
	if (mom_function) 
	    mymom = mom_function->GetRandom();
	if (mom_function_histo) 
	    mymom = mom_function_histo->GetRandom();
	beam->SetMom(mymom*mom);
	beam->RotateX(angle);
	beam->RotateZ(PUtils::sampleFlat()*2*TMath::Pi());
    } else {
	Double_t mymom = target->Rho();
	if (mom_function) 
	    mymom = mom_function->GetRandom();
	if (mom_function_histo) 
	    mymom = mom_function_histo->GetRandom();
	target->SetMom(mymom*mom);
	target->RotateX(angle);
	target->RotateZ(PUtils::sampleFlat()*2*TMath::Pi());
    }

    //The following lines have been copied from the "old" PReaction.cc
    if (thetaBeam>0. || sigmaBeam>0.) {    // we have a skewed and/or smeared beam axis
	Double_t thB = 0.;
	Double_t phB = 0.;
	if (sigmaBeam > 0.) {   // gaussian smearing of beam axis
	    //  thB = TMath::Abs(PUtils::sampleGaus(0.,sigmaBeam));
	    //  phB = 6.283185308*PUtils::sampleFlat();
	    Double_t thx = PUtils::sampleGaus(0., sigmaBeam);   
	    // this gives better results
	    Double_t thy = PUtils::sampleGaus(0., sigmaBeam);
	    thB = sqrt(thx*thx+thy*thy);
	    phB = TMath::ACos(thx/thB);
	    if (thy < 0.) phB = 6.283185308-phB;
	}
	TVector3 beamAxis(TMath::Sin(thB)*TMath::Cos(phB),
			  TMath::Sin(thB)*TMath::Sin(phB),
			  TMath::Cos(thB));
	if (thetaBeam > 0.) {   // skewing of beam axis (i.e. average beam is off z axis)
	    TVector3 skew(TMath::Sin(thetaBeam)*TMath::Cos(phiBeam),
			  TMath::Sin(thetaBeam)*TMath::Sin(phiBeam),
			  TMath::Cos(thetaBeam));
	    beamAxis.RotateUz(skew);
	}
	
	if (beam->P() > target->P()) {
	    beam->RotateUz(beamAxis);

	} else {
	    target->RotateUz(beamAxis);
	}
    }
    
    parent->Reconstruct();

    return kTRUE;
}

void PBeamSmearing::SetReaction(const char *reaction) {
    char *array[2];
    Int_t array_s = 2; //max products
    PUtils::Tokenize(reaction, "+", array, &array_s);
    Add("q", "parent");
    Add(array[0], "grandparent", "beam");
    Add(array[1], "grandparent", "target");
    NoDaughters();
}

void PBeamSmearing::Print(const Option_t *) const{
    PDistribution::Print();
}


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