301 lines
6.8 KiB
C
301 lines
6.8 KiB
C
|
#ifndef knockout_h
|
||
|
#define knockout_h
|
||
|
|
||
|
|
||
|
//=======================================================
|
||
|
//#######################################################
|
||
|
// Class for Knockout Reaction
|
||
|
// A(a,12)B, A = B + b, a->1, b->2
|
||
|
// incident particle is A
|
||
|
// the calculation: 1) go to A's rest frame
|
||
|
// 2) calculate the b = A - B
|
||
|
// 3) go to CM frame
|
||
|
//=======================================================
|
||
|
class Knockout{
|
||
|
public:
|
||
|
Knockout();
|
||
|
~Knockout();
|
||
|
|
||
|
void SetA(int A, int Z){
|
||
|
Isotope temp(A,Z);
|
||
|
mA = temp.Mass;
|
||
|
AA = A;
|
||
|
ZA = Z;
|
||
|
nameA = temp.Name;
|
||
|
}
|
||
|
|
||
|
void SetExA(double Ex){
|
||
|
this->ExA = Ex;
|
||
|
}
|
||
|
|
||
|
void Seta(int A, int Z){
|
||
|
Isotope temp(A,Z);
|
||
|
ma = temp.Mass;
|
||
|
Aa = A;
|
||
|
Za = Z;
|
||
|
m1 = ma;
|
||
|
A1 = A;
|
||
|
Z1 = Z;
|
||
|
namea = temp.Name;
|
||
|
name1 = temp.Name;
|
||
|
}
|
||
|
|
||
|
void Set2(int A, int Z){
|
||
|
Isotope temp(A,Z);
|
||
|
m2 = temp.Mass;
|
||
|
A2 = A;
|
||
|
Z2 = Z;
|
||
|
name2 = temp.Name;
|
||
|
|
||
|
AB = AA + Aa - A1 - A2;
|
||
|
ZB = ZA + Za - Z1 - Z2;
|
||
|
Isotope temp2(AB,ZB);
|
||
|
mB0 = temp2.Mass;
|
||
|
nameB = temp2.Name;
|
||
|
|
||
|
}
|
||
|
|
||
|
void SetBSpk(double S, double kb, double thetab, double phib){
|
||
|
this->S = S;
|
||
|
AB = AA + Aa - A1 - A2;
|
||
|
ZB = ZA + Za - Z1 - Z2;
|
||
|
Isotope temp(AB,ZB);
|
||
|
mB0 = temp.Mass;
|
||
|
nameB = temp.Name;
|
||
|
this->kb = kb;
|
||
|
this->thetab = thetab;
|
||
|
this->phib = phib;
|
||
|
|
||
|
mB = mA + ExA - m2 + S;
|
||
|
|
||
|
ExB = mB - mB0;
|
||
|
|
||
|
if( ExB < 0 && !isOverRideExNegative ){
|
||
|
printf(" seperation energy is too small. \n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void OverRideExNegative(bool YN){
|
||
|
isOverRideExNegative = YN;
|
||
|
}
|
||
|
|
||
|
TString GetReactionName(){
|
||
|
TString rName;
|
||
|
|
||
|
TString normInv;
|
||
|
if( isNormalKinematics ){
|
||
|
normInv = "Normal Kinematics";
|
||
|
}else{
|
||
|
normInv = "Inverse Kinematics";
|
||
|
}
|
||
|
|
||
|
rName.Form("%s(%s,%s%s)%s, %s", nameA.c_str(), namea.c_str(), name1.c_str(), name2.c_str(), nameB.c_str(), normInv.Data());
|
||
|
|
||
|
return rName;
|
||
|
}
|
||
|
|
||
|
void SetIncidentEnergyAngle(double KEA, double theta, double phi){
|
||
|
this->KEA = KEA;
|
||
|
this->thetaIN = theta;
|
||
|
this->phiIN = phi;
|
||
|
}
|
||
|
|
||
|
void CalIncidentChannel(bool isNormalKinematics);
|
||
|
void CalReactionConstant(bool isNormalKinematics);
|
||
|
void Event(double thetaCM, double phCM);
|
||
|
|
||
|
double GetMass_A(){return mA;}
|
||
|
double GetMass_a(){return ma;}
|
||
|
double GetMass_b(){return mb;}
|
||
|
double GetMass_B(){return mB;}
|
||
|
double GetMass_Bgs(){return mB0;}
|
||
|
double GetMass_1(){return m1;}
|
||
|
double GetMass_2(){return m2;}
|
||
|
|
||
|
TLorentzVector GetPA(){return PA;}
|
||
|
TLorentzVector GetPa(){return Pa;}
|
||
|
TLorentzVector GetPb(){return Pb;}
|
||
|
TLorentzVector GetPB(){return PB;}
|
||
|
TLorentzVector GetP1(){return P1;}
|
||
|
TLorentzVector GetP2(){return P2;}
|
||
|
|
||
|
double GetMomentumbNN(){return p;}
|
||
|
double GetReactionBeta(){return beta;}
|
||
|
double GetReactionGamma(){return gamma;}
|
||
|
double GetNNTotalEnergy(){return Etot;}
|
||
|
|
||
|
double GetNNTotalKE() {return Etot - mb - ma;}
|
||
|
double GetQValue() {return mA + ExA - m2 - mB;}
|
||
|
double GetMaxExB() {return Etot - mb - mB0;}
|
||
|
|
||
|
private:
|
||
|
int AA, Aa, A1, A2, AB;
|
||
|
int ZA, Za, Z1, Z2, ZB;
|
||
|
double mA, ma, m1, m2, mB, mB0, mb;
|
||
|
string nameA, namea, name1, name2, nameB;
|
||
|
|
||
|
double S; // separation energy
|
||
|
double kb; // momentum of b
|
||
|
double thetab, phib;// direction of b
|
||
|
|
||
|
TLorentzVector PA, Pa, P1, P2, PB, Pb; // lab
|
||
|
|
||
|
double KEA, thetaIN, phiIN;
|
||
|
double T;
|
||
|
|
||
|
double k, beta, gamma, Etot, p; // reaction constant, in NN frame
|
||
|
double ExA, ExB;
|
||
|
|
||
|
bool isNormalKinematics;
|
||
|
bool isOverRideExNegative;
|
||
|
|
||
|
};
|
||
|
|
||
|
Knockout::Knockout(){
|
||
|
TLorentzVector temp(0,0,0,0);
|
||
|
|
||
|
PA = temp;
|
||
|
Pa = temp;
|
||
|
P1 = temp;
|
||
|
P2 = temp;
|
||
|
PB = temp;
|
||
|
Pb = temp;
|
||
|
|
||
|
SetA(12,6);
|
||
|
Seta(1,1);
|
||
|
Set2(1,1);
|
||
|
|
||
|
SetBSpk(1000, 0, 0, 0);
|
||
|
SetIncidentEnergyAngle(10, 0, 0);
|
||
|
|
||
|
ExA = 0;
|
||
|
|
||
|
isNormalKinematics = false;
|
||
|
isOverRideExNegative = false;
|
||
|
}
|
||
|
|
||
|
Knockout::~Knockout(){
|
||
|
|
||
|
}
|
||
|
|
||
|
void Knockout::CalIncidentChannel(bool isNormalKinematics){
|
||
|
if( ExB < 0 && !isOverRideExNegative) return;
|
||
|
|
||
|
this->isNormalKinematics = isNormalKinematics;
|
||
|
|
||
|
if(!isNormalKinematics){
|
||
|
//===== construct Lab frame 4-momentum
|
||
|
this->T = KEA * AA;
|
||
|
double kA = TMath::Sqrt(TMath::Power(mA + ExA + T, 2) - (mA + ExA) * (mA + ExA));
|
||
|
PA.SetXYZM(0, 0, kA, mA + ExA);
|
||
|
PA.RotateY(thetaIN);
|
||
|
PA.RotateZ(phiIN);
|
||
|
|
||
|
Pa.SetXYZM(0,0,0,ma);
|
||
|
|
||
|
}else{
|
||
|
//===== construct 4-momentum
|
||
|
this->T = KEA * Aa;
|
||
|
double ka = TMath::Sqrt(TMath::Power(ma + T, 2) - (ma) * (ma));
|
||
|
Pa.SetXYZM(0, 0, ka, ma);
|
||
|
Pa.RotateY(thetaIN);
|
||
|
Pa.RotateZ(phiIN);
|
||
|
|
||
|
PA.SetXYZM(0, 0, 0, mA + ExA);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void Knockout::CalReactionConstant(bool isNormalKinematics){
|
||
|
if( ExB < 0 && !isOverRideExNegative) return;
|
||
|
|
||
|
this->isNormalKinematics = isNormalKinematics;
|
||
|
|
||
|
CalIncidentChannel(isNormalKinematics);
|
||
|
|
||
|
if(!isNormalKinematics){
|
||
|
|
||
|
//===== change to A's rest frame
|
||
|
TVector3 bA = PA.BoostVector();
|
||
|
PA.Boost(-bA);
|
||
|
|
||
|
//===== constructe bounded nucleus b
|
||
|
PB.SetXYZM(0, 0, -kb, mB);
|
||
|
PB.RotateY(thetab);
|
||
|
PB.RotateZ(phib);
|
||
|
|
||
|
Pb = PA - PB;
|
||
|
mb = Pb.M();
|
||
|
|
||
|
//===== change to Lab frame
|
||
|
Pb.Boost(bA);
|
||
|
PA.Boost(bA);
|
||
|
PB.Boost(bA);
|
||
|
|
||
|
}else{
|
||
|
|
||
|
//===== constructe bounded nucleus b
|
||
|
PB.SetXYZM(0, 0, -kb, mB);
|
||
|
PB.RotateY(thetab);
|
||
|
PB.RotateZ(phib);
|
||
|
|
||
|
Pb = PA - PB;
|
||
|
mb = Pb.M();
|
||
|
|
||
|
}
|
||
|
|
||
|
//====== reaction constant
|
||
|
k = (Pa+Pb).P();
|
||
|
double E = (Pa+Pb).E();
|
||
|
beta = (Pa+Pb).Beta();
|
||
|
gamma = 1 / TMath::Sqrt(1- beta * beta);
|
||
|
Etot = TMath::Sqrt(TMath::Power(E,2) - k * k);
|
||
|
p = TMath::Sqrt( (Etot*Etot - TMath::Power(m1 + m2,2)) * (Etot*Etot - TMath::Power(m1 - m2 ,2)) ) / 2 / Etot;
|
||
|
|
||
|
//if( TMath::IsNaN(p) ){
|
||
|
// printf(" Mc: %f, m1+m2: %f, kb:%f, thetab:%f, phib:%f\n", Etot, m1+m2, kb, thetab, phib);
|
||
|
//}
|
||
|
|
||
|
}
|
||
|
|
||
|
void Knockout::Event(double thetaCM, double phiCM){
|
||
|
if( ExB < 0 && !isOverRideExNegative ) return;
|
||
|
|
||
|
//===== construct Pcm
|
||
|
TLorentzVector Pc = Pb + Pa;
|
||
|
TVector3 bc = Pc.BoostVector();
|
||
|
|
||
|
TLorentzVector Pac = Pa;
|
||
|
Pac.Boost(-bc);
|
||
|
TVector3 va = Pac.Vect();
|
||
|
|
||
|
TLorentzVector Pbc = Pb;
|
||
|
Pbc.Boost(-bc);
|
||
|
TVector3 vb = Pbc.Vect();
|
||
|
|
||
|
//--- from P1
|
||
|
TVector3 v1 = va;
|
||
|
v1.SetMag(p);
|
||
|
|
||
|
TVector3 u1 = va.Orthogonal();
|
||
|
v1.Rotate(thetaCM, u1);
|
||
|
v1.Rotate(phiCM + TMath::PiOver2(), va); // somehow, the calculation turn the vector 90 degree.
|
||
|
|
||
|
TLorentzVector P1c;
|
||
|
P1c.SetVectM(v1, m1);
|
||
|
|
||
|
//--- from P2
|
||
|
TLorentzVector P2c;
|
||
|
P2c.SetVectM(-v1, m2);
|
||
|
|
||
|
//---- to Lab Frame
|
||
|
P1 = P1c;
|
||
|
P1.Boost(bc);
|
||
|
P2 = P2c;
|
||
|
P2.Boost(bc);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#endif
|