-
adrien-matta authoredadrien-matta authored
NPReaction.cxx 22.73 KiB
/*****************************************************************************
* Copyright (C) 2009-2013 this file is part of the NPTool Project *
* *
* For the licensing terms see $NPTOOL/Licence/NPTool_Licence *
* For the list of contributors see $NPTOOL/Licence/Contributors *
*****************************************************************************/
/*****************************************************************************
* *
* Original Author : Adrien MATTA contact address: matta@ipno.in2p3.fr *
* *
* Creation Date : March 2009 *
* Last update : January 2011 *
*---------------------------------------------------------------------------*
* Decription: *
* This class deal with Two Body transfert Reaction *
* Physical parameter (Nuclei mass) are loaded from the nubtab03.asc file *
* (2003 nuclear table of isotopes mass). *
* *
* KineRelativistic: Used in NPSimulation *
* A relativistic calculation is made to compute Light and Heavy nuclei *
* angle given the Theta CM angle. *
* *
* ReconstructRelativistic: Used in NPAnalysis *
* A relativistic calculation is made to compute Excitation energy given the*
* light angle and energy in Lab frame. *
* *
*---------------------------------------------------------------------------*
* Comment: *
* + 20/01/2011: Add support for excitation energy for light ejectile *
* (N. de Sereville) *
* Based on previous work by N.de Sereville *
* *
*****************************************************************************/
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <sstream>
#include <cmath>
#include <vector>
#include "NPReaction.h"
#include "NPOptionManager.h"
#include "NPFunction.h"
// Use CLHEP System of unit and Physical Constant
#include "NPGlobalSystemOfUnits.h"
#include "NPPhysicalConstants.h"
#ifdef NP_SYSTEM_OF_UNITS_H
using namespace NPUNITS;
#endif
// ROOT
#include"TF1.h"
ClassImp(Reaction)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Reaction::Reaction(){
//------------- Default Constructor -------------
// Need to be done before initializePrecomputeVariable
fKineLine3 = 0 ;
fKineLine4 = 0 ;
fLineBrho3 = 0 ;
fTheta3VsTheta4 = 0;
fAngleLine = 0;
//
fNuclei1 = new Beam();
fNuclei2 = new Nucleus();
fNuclei3 = new Nucleus();
fNuclei4 = new Nucleus();
fBeamEnergy = 0;
fThetaCM = 0;
fExcitation3 = 0;
fExcitation4 = 0;
fQValue = 0;
fVerboseLevel = NPOptionManager::getInstance()->GetVerboseLevel();
initializePrecomputeVariable();
// do that to avoid warning from multiple Hist with same name... int offset = 0;
int offset = 0;
while(gDirectory->FindObjectAny(Form("EnergyHist_%i",offset))!=0)
++offset;
fCrossSectionHist = new TH1F(Form("EnergyHist_%i",offset),"Reaction_CS",1,0,180);
fExcitationEnergyHist = NULL;
fshoot3=true;
fshoot4=true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// This constructor aim to provide a fast way to instantiate a reaction without input file
// The string should be of the form "A(b,c)D@E" with E the ernegy of the beam in MeV
Reaction::Reaction(string reaction){
// Instantiate the parameter to default
// Analyse the reaction and extract revelant information
string A,b,c,D,E;
unsigned int i=0;
for(; i < reaction.length() ; i++){
if(reaction.compare(i,1,"(")!=0) A.push_back(reaction[i]);
else break;
}
i++;
for(; i < reaction.length() ; i++){
if(reaction.compare(i,1,",")!=0) b.push_back(reaction[i]);
else break;
}
i++;
for(; i < reaction.length() ; i++){
if(reaction.compare(i,1,")")!=0) c.push_back(reaction[i]);
else break;
}
i++;
for(; i < reaction.length() ; i++){
if(reaction.compare(i,1,"@")!=0) D.push_back(reaction[i]);
else break;
}
i++;
for(; i < reaction.length() ; i++){
E.push_back(reaction[i]);
}
fKineLine3 = 0 ;
fKineLine4 = 0 ;
fLineBrho3 = 0;
fTheta3VsTheta4 = 0;
fAngleLine = 0;
fNuclei1 = new Beam(A);
fNuclei2 = new Nucleus(b);
fNuclei3 = new Nucleus(c);
fNuclei4 = new Nucleus(D);
fBeamEnergy = atof(E.c_str());
fThetaCM = 0;
fExcitation3 = 0;
fExcitation4 = 0;
fQValue = 0;
fVerboseLevel = NPOptionManager::getInstance()->GetVerboseLevel();
initializePrecomputeVariable();
// do that to avoid warning from multiple Hist with same name... int offset = 0;
int offset = 0;
while(gDirectory->FindObjectAny(Form("EnergyHist_%i",offset))!=0)
++offset;
fCrossSectionHist = new TH1F(Form("EnergyHist_%i",offset),"Reaction_CS",1,0,180);
fCrossSectionHist = NULL;
fshoot3=true;
fshoot4=true;
initializePrecomputeVariable();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Reaction::~Reaction(){
//------------- Default Destructor ------------
if(fNuclei1)
delete fNuclei1;
if(fNuclei2)
delete fNuclei2;
if(fNuclei3)
delete fNuclei3;
if(fNuclei4)
delete fNuclei4;
// if(fCrossSectionHist)
// delete fCrossSectionHist;
// if(fExcitationEnergyHist)
// delete fExcitationEnergyHist;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
bool Reaction::CheckKinematic(){
double theta = fThetaCM;
if (m1 > m2) theta = M_PI - fThetaCM;
fEnergyImpulsionCM_3 = TLorentzVector(pCM_3*sin(theta),0,pCM_3*cos(theta),ECM_3);
fEnergyImpulsionCM_4 = fTotalEnergyImpulsionCM - fEnergyImpulsionCM_3;
fEnergyImpulsionLab_3 = fEnergyImpulsionCM_3;
fEnergyImpulsionLab_3.Boost(0,0,BetaCM);
fEnergyImpulsionLab_4 = fEnergyImpulsionCM_4;
fEnergyImpulsionLab_4.Boost(0,0,BetaCM);
if ( fabs(fTotalEnergyImpulsionLab.E() - (fEnergyImpulsionLab_3.E()+fEnergyImpulsionLab_4.E()))> 1e-6){
cout << "Problem with energy conservation" << endl;
return false;
}
else{
//cout << "Kinematic OK" << endl;
return true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
double Reaction::ShootRandomThetaCM(){
double theta;
SetThetaCM( theta=fCrossSectionHist->GetRandom()*deg );
return theta;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Reaction::ShootRandomExcitationEnergy(){
if(fExcitationEnergyHist){
SetExcitation4(fExcitationEnergyHist->GetRandom());
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Reaction::KineRelativistic(double &ThetaLab3, double &KineticEnergyLab3,
double &ThetaLab4, double &KineticEnergyLab4){
// 2-body relativistic kinematics: direct + inverse
// EnergieLab3,4 : lab energy in MeV of the 2 ejectiles
// ThetaLab3,4 : angles in rad
// case of inverse kinematics
double theta = fThetaCM;
if (m1 > m2) theta = M_PI - fThetaCM;
fEnergyImpulsionCM_3 = TLorentzVector(pCM_3*sin(theta),0,pCM_3*cos(theta),ECM_3);
fEnergyImpulsionCM_4 = fTotalEnergyImpulsionCM - fEnergyImpulsionCM_3;
fEnergyImpulsionLab_3 = fEnergyImpulsionCM_3;
fEnergyImpulsionLab_3.Boost(0,0,BetaCM);
fEnergyImpulsionLab_4 = fEnergyImpulsionCM_4;
fEnergyImpulsionLab_4.Boost(0,0,BetaCM);
// Angle in the lab frame
ThetaLab3 = fEnergyImpulsionLab_3.Angle(fEnergyImpulsionLab_1.Vect());
if (ThetaLab3 < 0) ThetaLab3 += M_PI;
ThetaLab4 = fEnergyImpulsionLab_4.Angle(fEnergyImpulsionLab_1.Vect());
if (fabs(ThetaLab3) < 1e-6) ThetaLab3 = 0;
ThetaLab4 = fabs(ThetaLab4);
if (fabs(ThetaLab4) < 1e-6) ThetaLab4 = 0;
// Kinetic Energy in the lab frame
KineticEnergyLab3 = fEnergyImpulsionLab_3.E() - m3;
KineticEnergyLab4 = fEnergyImpulsionLab_4.E() - m4;
// test for total energy conversion
if (fabs(fTotalEnergyImpulsionLab.E() - (fEnergyImpulsionLab_3.E()+fEnergyImpulsionLab_4.E())) > 1e-6)
cout << "Problem for energy conservation" << endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
double Reaction::ReconstructRelativistic(double EnergyLab, double ThetaLab){
// EnergyLab in MeV
// ThetaLab in rad
double E3 = m3 + EnergyLab;
double p_Lab_3 = sqrt(E3*E3 - m3*m3);
fEnergyImpulsionLab_3 = TLorentzVector(p_Lab_3*sin(ThetaLab),0,p_Lab_3*cos(ThetaLab),E3);
fEnergyImpulsionLab_4 = fTotalEnergyImpulsionLab - fEnergyImpulsionLab_3;
double Eex = fEnergyImpulsionLab_4.Mag() - fNuclei4->Mass();
return Eex;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//Return ThetaCM
double Reaction::EnergyLabToThetaCM(double EnergyLab, double ThetaLab){
double E3 = m3 + EnergyLab;
double p_Lab_3 = sqrt(E3*E3 - m3*m3);
fEnergyImpulsionLab_3 = TLorentzVector(p_Lab_3*sin(ThetaLab),0,p_Lab_3*cos(ThetaLab),E3);
fEnergyImpulsionCM_3 = fEnergyImpulsionLab_3;
fEnergyImpulsionCM_3.Boost(0,0,-BetaCM);
double ThetaCM = M_PI - fEnergyImpulsionCM_1.Angle(fEnergyImpulsionCM_3.Vect());
return(ThetaCM);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Reaction::Print() const{
// Print informations concerning the reaction
cout << "Reaction : " << fNuclei2->GetName() << "(" << fNuclei1->GetName()
<< "," << fNuclei3->GetName() << ")" << fNuclei4->GetName() << " @ "
<< fBeamEnergy << " MeV"
<< endl ;
cout << "Exc Nuclei 3 = " << fExcitation3 << " MeV" << endl;
cout << "Exc Nuclei 4 = " << fExcitation4 << " MeV" << endl;
cout << "Qgg = " << fQValue << " MeV" << endl;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void Reaction::ReadConfigurationFile(string Path){
////////General Reading needs////////
string LineBuffer;
string DataBuffer;
////////Reaction Setting needs///////
string Beam, Target, Heavy, Light, CrossSectionPath ;
double CSHalfOpenAngleMin = 0, CSHalfOpenAngleMax = 0;
bool ReadingStatus = false ;
bool check_Beam = false ;
bool check_Target = false ;
bool check_Light = false ;
bool check_Heavy = false ;
bool check_ExcitationEnergy3 = false ;
bool check_ExcitationEnergy4 = false ;
bool check_ExcitationEnergyDistribution = false;
bool check_CrossSectionPath = false ;
bool check_shoot3 = false ;
bool check_shoot4 = false;
//////////////////////////////////////////////////////////////////////////////////////////
ifstream ReactionFile;
string GlobalPath = getenv("NPTOOL");
string StandardPath = GlobalPath + "/Inputs/EventGenerator/" + Path;
ReactionFile.open(StandardPath.c_str());
if (ReactionFile.is_open()) {cout << "Reading Reaction File " << Path << endl ;}
// In case the file is not found in the standard path, the programm try to interpret the file name as an absolute or relative file path.
else{
ReactionFile.open( Path.c_str() );
if(ReactionFile.is_open()) { if(fVerboseLevel==1) cout << "Reading Reaction File " << Path << endl;}
else {cout << "Reaction File " << Path << " not found" << endl;exit(1);}
}
while (!ReactionFile.eof()) {
//Pick-up next line
getline(ReactionFile, LineBuffer);
if (LineBuffer.compare(0, 15, "TwoBodyReaction") == 0) { ReadingStatus = true ;}
while(ReadingStatus){
ReactionFile >> DataBuffer;
//Search for comment Symbol %
if (LineBuffer.compare(0, 1, "%") == 0) {/* Do Nothing */;}
else if (DataBuffer=="Beam=") {
check_Beam = true ;
ReactionFile >> DataBuffer;
// Pick up the beam energy from the Beam event generator
fNuclei1->SetVerboseLevel(0);
fNuclei1->ReadConfigurationFile(Path);
fBeamEnergy= fNuclei1->GetEnergy();
if(fVerboseLevel==1) cout << "Beam " << fNuclei1->GetName() << " @ " << fBeamEnergy << " MeV" << endl;
}
else if (DataBuffer=="Target=") {
check_Target = true ;
ReactionFile >> DataBuffer;
fNuclei2 = new Nucleus(DataBuffer);
if(fVerboseLevel==1) cout << "Target " << fNuclei2->GetName() << endl;
}
else if (DataBuffer=="Light=" || DataBuffer=="Nuclei3=") {
check_Light = true ;
ReactionFile >> DataBuffer;
fNuclei3 = new Nucleus(DataBuffer);
if(fVerboseLevel==1) cout << "Light " << fNuclei3->GetName() << endl;
}
else if (DataBuffer== "Heavy="|| DataBuffer=="Nuclei4=") {
check_Heavy = true ;
ReactionFile >> DataBuffer;
fNuclei4 = new Nucleus(DataBuffer);
if(fVerboseLevel==1) cout << "Heavy " << fNuclei4->GetName() << endl;
}
else if (DataBuffer=="ExcitationEnergy3=" || DataBuffer=="ExcitationEnergyLight=") {
check_ExcitationEnergy3 = true ;
ReactionFile >> DataBuffer;
fExcitation3 = atof(DataBuffer.c_str()) * MeV;
if(fVerboseLevel==1) cout << "Excitation Energy Nuclei 3: " << fExcitation3 / MeV << " MeV" << endl;
}
else if (DataBuffer=="ExcitationEnergy4=" || DataBuffer=="ExcitationEnergyHeavy=") {
check_ExcitationEnergy4 = true ;
ReactionFile >> DataBuffer;
fExcitation4 = atof(DataBuffer.c_str()) * MeV;
if(fVerboseLevel==1) cout << "Excitation Energy Nuclei 4: " << fExcitation4 / MeV << " MeV" << endl;
}
else if (DataBuffer=="ExcitationEnergyDistribution="){
check_ExcitationEnergyDistribution = true;
string FileName,HistName;
ReactionFile >> FileName >> HistName;
if(fVerboseLevel==1) cout << "Reading Excitation Energy Distribution file: " << FileName << endl;
fExcitationEnergyHist = Read1DProfile(FileName, HistName );
fExcitation4 = 0 ;
}
else if (DataBuffer== "CrossSectionPath=") {
check_CrossSectionPath = true ;
string FileName,HistName;
ReactionFile >> FileName >> HistName;
if(fVerboseLevel==1) cout << "Reading Cross Section file: " << FileName << endl;
TH1F* CStemp = Read1DProfile(FileName, HistName );
// multiply CStemp by sin(theta)
TF1* fsin = new TF1("sin",Form("1/(sin(x*%f/180.))",M_PI),0,180);
CStemp->Divide(fsin,1);
SetCrossSectionHist(CStemp);
delete fsin;
}
else if (DataBuffer.compare(0, 17, "HalfOpenAngleMin=") == 0) {
ReactionFile >> DataBuffer;
CSHalfOpenAngleMin = atof(DataBuffer.c_str()) * deg;
if(fVerboseLevel==1) cout << "HalfOpenAngleMin " << CSHalfOpenAngleMin / deg << " degree" << endl;
}
else if (DataBuffer.compare(0, 17, "HalfOpenAngleMax=") == 0) {
ReactionFile >> DataBuffer;
CSHalfOpenAngleMax = atof(DataBuffer.c_str()) * deg;
if(fVerboseLevel==1) cout << "HalfOpenAngleMax " << CSHalfOpenAngleMax / deg << " degree" << endl;
}
else if (DataBuffer== "Shoot3=" || DataBuffer== "ShootLight=") {
check_shoot3 = true ;
ReactionFile >> DataBuffer;
if(atoi(DataBuffer.c_str()) == 0 )
fshoot3 = false;
if(fVerboseLevel==1 && fshoot3) cout << "Shoot 3 : Yes " << endl;
else if (fVerboseLevel==1 ) cout << "Shoot 3 : No " << endl;
}
else if (DataBuffer== "Shoot4=" || DataBuffer== "ShootHeavy=") {
check_shoot4 = true ;
ReactionFile >> DataBuffer;
if(atoi(DataBuffer.c_str()) == 0 )
fshoot4 = false;
if(fVerboseLevel==1 && fshoot4) cout << "Shoot 4 : Yes " << endl;
else if (fVerboseLevel==1 ) cout << "Shoot 4 : No " << endl;
}
///////////////////////////////////////////////////
// If no Transfert Token and no comment, toggle out
else
{/*Ignore Token used by G4*/}
///////////////////////////////////////////////////
// If all Token found toggle out
if (check_Beam && check_Target && check_Light && check_Heavy && check_ExcitationEnergy3
&& (check_ExcitationEnergy4 || check_ExcitationEnergyDistribution ) && check_CrossSectionPath && check_shoot4 && check_shoot3)
ReadingStatus = false;
}
}
// Modifiy the CS to shoot only within ]HalfOpenAngleMin,HalfOpenAngleMax[
SetCSAngle(CSHalfOpenAngleMin,CSHalfOpenAngleMax);
ReactionFile.close();
initializePrecomputeVariable();
}
////////////////////////////////////////////////////////////////////////////////////////////
void Reaction::initializePrecomputeVariable(){
m1 = fNuclei1->Mass();
m2 = fNuclei2->Mass();
m3 = fNuclei3->Mass() + fExcitation3;
m4 = fNuclei4->Mass() + fExcitation4;
s = m1*m1 + m2*m2 + 2*m2*(fBeamEnergy + m1);
fTotalEnergyImpulsionCM = TLorentzVector(0,0,0,sqrt(s));
ECM_1 = (s + m1*m1 - m2*m2)/(2*sqrt(s));
ECM_2 = (s + m2*m2 - m1*m1)/(2*sqrt(s));
ECM_3 = (s + m3*m3 - m4*m4)/(2*sqrt(s));
ECM_4 = (s + m4*m4 - m3*m3)/(2*sqrt(s));
pCM_1 = sqrt(ECM_1*ECM_1 - m1*m1);
pCM_2 = sqrt(ECM_2*ECM_2 - m2*m2);
pCM_3 = sqrt(ECM_3*ECM_3 - m3*m3);
pCM_4 = sqrt(ECM_4*ECM_4 - m4*m4);
fImpulsionLab_1 = TVector3(0,0,sqrt(fBeamEnergy*fBeamEnergy + 2*fBeamEnergy*m1));
fImpulsionLab_2 = TVector3(0,0,0);
fEnergyImpulsionLab_1 = TLorentzVector(fImpulsionLab_1,m1+fBeamEnergy);
fEnergyImpulsionLab_2 = TLorentzVector(fImpulsionLab_2,m2);
fTotalEnergyImpulsionLab = fEnergyImpulsionLab_1 + fEnergyImpulsionLab_2;
BetaCM = fTotalEnergyImpulsionLab.Beta();
fEnergyImpulsionCM_1 = fEnergyImpulsionLab_1;
fEnergyImpulsionCM_1.Boost(0,0,-BetaCM);
fEnergyImpulsionCM_2 = fEnergyImpulsionLab_2;
fEnergyImpulsionCM_2.Boost(0,0,-BetaCM);
}
////////////////////////////////////////////////////////////////////////////////////////////
void Reaction::SetNuclei3(double EnergyLab, double ThetaLab){
double p3 = sqrt(pow(EnergyLab,2) + 2*m3*EnergyLab);
fEnergyImpulsionLab_3 = TLorentzVector(p3*sin(ThetaLab),0,p3*cos(ThetaLab),EnergyLab+m3);
fEnergyImpulsionLab_4 = fTotalEnergyImpulsionLab - fEnergyImpulsionLab_3;
fNuclei3->SetEnergyImpulsion(fEnergyImpulsionLab_3);
fNuclei4->SetEnergyImpulsion(fEnergyImpulsionLab_4);
fThetaCM = EnergyLabToThetaCM(EnergyLab, ThetaLab);
fExcitation4 = ReconstructRelativistic(EnergyLab, ThetaLab);
}
////////////////////////////////////////////////////////////////////////////////////////////
TGraph* Reaction::GetKinematicLine3(double AngleStep_CM){
vector<double> vx;
vector<double> vy;
double theta3,E3,theta4,E4;
for (double angle=0 ; angle < 360 ; angle+=AngleStep_CM){
SetThetaCM(angle*deg);
KineRelativistic(theta3, E3, theta4, E4);
fNuclei3->SetKineticEnergy(E3);
vx.push_back(theta3/deg);
vy.push_back(E3);
}
fKineLine3 = new TGraph(vx.size(),&vx[0],&vy[0]);
return(fKineLine3);
}
////////////////////////////////////////////////////////////////////////////////////////////
TGraph* Reaction::GetKinematicLine4(double AngleStep_CM){
vector<double> vx;
vector<double> vy;
double theta3,E3,theta4,E4;
for (double angle=0 ; angle < 360 ; angle+=AngleStep_CM){
SetThetaCM(angle*deg);
KineRelativistic(theta3, E3, theta4, E4);
fNuclei4->SetKineticEnergy(E4);
vx.push_back(theta3/deg);
vy.push_back(E4);
}
fKineLine4= new TGraph(vx.size(),&vx[0],&vy[0]);
return(fKineLine4);
}
////////////////////////////////////////////////////////////////////////////////////////////
TGraph* Reaction::GetTheta3VsTheta4(double AngleStep_CM)
{
vector<double> vx;
vector<double> vy;
double theta3,E3,theta4,E4;
for (double angle=0 ; angle < 360 ; angle+=AngleStep_CM){
SetThetaCM(angle*deg);
KineRelativistic(theta3, E3, theta4, E4);
vx.push_back(theta3/deg);
vy.push_back(theta4/deg);
}
fTheta3VsTheta4= new TGraph(vx.size(),&vx[0],&vy[0]);
return(fTheta3VsTheta4);
}
////////////////////////////////////////////////////////////////////////////////////////////
TGraph* Reaction::GetBrhoLine3(double AngleStep_CM){
vector<double> vx;
vector<double> vy;
double theta3,E3,theta4,E4;
double Brho;
for (double angle=0 ; angle < 360 ; angle+=AngleStep_CM){
SetThetaCM(angle*deg);
KineRelativistic(theta3, E3, theta4, E4);
fNuclei3->SetKineticEnergy(E3);
Brho = fNuclei3->GetBrho();
vx.push_back(theta3/deg);
vy.push_back(Brho);
}
fLineBrho3= new TGraph(vx.size(),&vx[0],&vy[0]);
return(fLineBrho3);
}
////////////////////////////////////////////////////////////////////////////////////////////
TGraph* Reaction::GetThetaLabVersusThetaCM(double AngleStep_CM){
vector<double> vx;
vector<double> vy;
double theta3,E3,theta4,E4;
for (double angle=0 ; angle < 360 ; angle+=AngleStep_CM){
SetThetaCM(angle*deg);
KineRelativistic(theta3, E3, theta4, E4);
vx.push_back(fThetaCM/deg);
vy.push_back(theta3/deg);
}
fAngleLine= new TGraph(vx.size(),&vx[0],&vy[0]);
return(fAngleLine);
}
////////////////////////////////////////////////////////////////////////////////////////////
void Reaction::PrintKinematic(){
int size = 360;
double theta3,E3,theta4,E4,Brho3,Brho4;
cout << endl;
cout << "*********************** Print Kinematic ***********************" << endl;
cout << "ThetaCM" << " " << "ThetaLab" << " " << "EnergyLab3" << " " << "Brho3" << " " << "EnergyLab4" << " " << "Brho4" << endl;
for (int i = 0; i < size; ++i){
SetThetaCM(((double)i)/2*deg);
KineRelativistic(theta3, E3, theta4, E4);
fNuclei3->SetKineticEnergy(E3);
Brho3 = fNuclei3->GetBrho();
fNuclei4->SetKineticEnergy(E4);
Brho4 = fNuclei4->GetBrho();
cout << (double)i/2 << " " << theta3/deg << " " << E3 << " " << Brho3 << " " << E4 << " " << Brho4 << endl;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
void Reaction::SetCSAngle(double CSHalfOpenAngleMin,double CSHalfOpenAngleMax){
for (int i = 0 ; i< fCrossSectionHist->GetNbinsX(); i++)
if( fCrossSectionHist->GetBinCenter(i) > CSHalfOpenAngleMax && fCrossSectionHist->GetBinCenter(i) < CSHalfOpenAngleMin)
fCrossSectionHist->SetBinContent(i,0);
}