diff --git a/src/THcSecondaryKine.cxx b/src/THcSecondaryKine.cxx new file mode 100644 index 0000000000000000000000000000000000000000..63df141272c3140b6b659aab227293dfbc225fc5 --- /dev/null +++ b/src/THcSecondaryKine.cxx @@ -0,0 +1,331 @@ +/** \class THcSecondaryKine + \ingroup Physics + +\brief Class for the Calculate kinematics of scattering of the secondary (hadron) particle. +*/ + +#include "THcPrimaryKine.h" +#include "THcSecondaryKine.h" +#include "THaTrackingModule.h" +#include "THcGlobals.h" +#include "THcParmList.h" +#include "VarDef.h" +#include "TLorentzVector.h" +#include "TVector3.h" +#include "TMath.h" +#include "TRotation.h" + +#include <cstring> +#include <cstdio> +#include <cstdlib> +#include <iostream> +using namespace std; + +ClassImp(THcSecondaryKine) + +//_____________________________________________________________________________ +THcSecondaryKine::THcSecondaryKine( const char* name, const char* description, + const char* secondary_spectro, + const char* primary_kine, + Double_t secondary_mass ) : + THaPhysicsModule(name,description), fMX(secondary_mass), + fSpectroName(secondary_spectro), fSpectro(NULL), + fPrimaryName(primary_kine), fPrimary(NULL) +{ + // Constructor + +} + +//_____________________________________________________________________________ +THcSecondaryKine::~THcSecondaryKine() +{ + // Destructor + + DefineVariables( kDelete ); +} + +//_____________________________________________________________________________ +void THcSecondaryKine::Clear( Option_t* opt ) +{ + // Clear all internal variables. + + THaPhysicsModule::Clear(opt); + fTheta_xq = fPhi_xq = fTheta_bq = fPhi_bq = fXangle = fPmiss + = fPmiss_x = fPmiss_y = fPmiss_z = fEmiss = fMrecoil = fErecoil + = fTX = fTB = fPX_cm = fTheta_x_cm = fPhi_x_cm = fTheta_b_cm + = fPhi_b_cm = fTX_cm = fTB_cm = fTtot_cm = fMandelS = fMandelT + = fMandelU = kBig; + fX.SetXYZT(kBig,kBig,kBig,kBig); + fB.SetXYZT(kBig,kBig,kBig,kBig); +} + +//_____________________________________________________________________________ +Int_t THcSecondaryKine::DefineVariables( EMode mode ) +{ + // Define/delete global variables. + + if( mode == kDefine && fIsSetup ) return kOK; + fIsSetup = ( mode == kDefine ); + + RVarDef vars[] = { + { "th_xq", "Polar angle of detected particle with q (rad)", + "fTheta_xq" }, + { "ph_xq", "Azimuth of detected particle with scattering plane (rad)", + "fPhi_xq" }, + { "th_bq", "Polar angle of recoil system with q (rad)", "fTheta_bq" }, + { "ph_bq", "Azimuth of recoil system with scattering plane (rad)", + "fPhi_bq" }, + { "xangle", "Angle of detected particle with scattered electron (rad)", + "fXangle" }, + { "pmiss", "Missing momentum magnitude (GeV), nuclear physics " + "definition (-pB)", "fPmiss" }, + { "pmiss_x", "x-component of p_miss wrt q (GeV)", "fPmiss_x" }, + { "pmiss_y", "y-component of p_miss wrt q (GeV)", "fPmiss_y" }, + { "pmiss_z", "z-component of p_miss, along q (GeV)", "fPmiss_z" }, + { "emiss", "Missing energy (GeV), nuclear physics definition " + "omega-Tx-Tb", "fEmiss" }, + { "Mrecoil", "Invariant mass of recoil system (GeV)", "fMrecoil" }, + { "Erecoil", "Total energy of recoil system (GeV)", "fErecoil" }, + { "Prec_x", "x-component of recoil system in lab (GeV/c)", "fB.X()" }, + { "Prec_y", "y-component of recoil system in lab (GeV/c)", "fB.Y()" }, + { "Prec_z", "z-component of recoil system in lab (GeV/c)", "fB.Z()" }, + { "tx", "Kinetic energy of detected particle (GeV)", "fTX" }, + { "tb", "Kinetic energy of recoil system (GeV)", "fTB" }, + { "px_cm", "Magnitude of X momentum in CM system (GeV)", "fPX_cm" }, + { "thx_cm", "Polar angle of X in CM system wrt q (rad)", "fTheta_x_cm" }, + { "phx_cm", "Azimuth of X in CM system wrt q (rad)", "fPhi_x_cm" }, + { "thb_cm", "Polar angle of recoil systm in CM wrt q (rad)", + "fTheta_b_cm" }, + { "phb_cm", "Azimuth of recoil system in CM wrt q (rad)", "fPhi_b_cm" }, + { "tx_cm", "Kinetic energy of X in CM (GeV)", "fTX_cm" }, + { "tb_cm", "Kinetic energy of B in CM (GeV)", "fTB_cm" }, + { "t_tot_cm", "Total CM kinetic energy", "fTtot_cm" }, + { "MandelS", "Mandelstam s for secondary vertex (GeV^2)", "fMandelS" }, + { "MandelT", "Mandelstam t for secondary vertex (GeV^2)", "fMandelT" }, + { "MandelU", "Mandelstam u for secondary vertex (GeV^2)", "fMandelU" }, + { 0 } + }; + return DefineVarsFromList( vars, mode ); +} + +//_____________________________________________________________________________ +THaAnalysisObject::EStatus THcSecondaryKine::Init( const TDatime& run_time ) +{ + // Initialize the module. + // Locate the kinematics module named in fPrimaryName, which describes + // the primary interaction kinematics, and save pointer to it. + + // Standard initialization. Calls this object's DefineVariables(). + + // cout << "*************&&&&&&&&&&&&&&************" << endl; + //cout << "In THcSecondaryKine::Init() " << endl; + + if( THaPhysicsModule::Init( run_time ) != kOK ) + return fStatus; + + + fSpectro = dynamic_cast<THaTrackingModule*> + ( FindModule( fSpectroName.Data(), "THaTrackingModule")); + if( fStatus ) return fStatus; + + fPrimary = dynamic_cast<THcPrimaryKine*> + ( FindModule( fPrimaryName.Data(), "THcPrimaryKine")); + return fStatus; + + + +} + +//_____________________________________________________________________________ +Int_t THcSecondaryKine::Process( const THaEvData& ) +{ + // Calculate the kinematics. + + + if( !IsOK() ) return -1; + + //Get secondary particle mass + + fMX = fHC_Spectro->GetParticleMass(); + + // Tracking information from the secondary spectrometer + THaTrackInfo* trkifo = fSpectro->GetTrackInfo(); + if( !trkifo || !trkifo->IsOK() ) return 1; + + // Require valid input data + if( !fPrimary->DataValid() ) return 2; + + // Measured momentum of secondary particle X in lab + const TVector3& pX3 = trkifo->GetPvect(); + // 4-momentum of X + fX.SetVectM( pX3, fMX ); + + // 4-momenta of the the primary interaction + const TLorentzVector* pA = fPrimary->GetA(); // Initial target + const TLorentzVector* pA1 = fPrimary->GetA1(); // Final target + const TLorentzVector* pQ = fPrimary->GetQ(); // Momentum xfer + const TLorentzVector* pP1 = fPrimary->GetP1(); // Final electron + Double_t omega = fPrimary->GetOmega(); // Energy xfer + + // 4-momentum of undetected recoil system B + fB = *pA1 - fX; + + // Angle of X with scattered primary particle + fXangle = fX.Angle( pP1->Vect()); + + // Angles of X and B wrt q-vector + // xq and bq are the 3-momentum vectors of X and B expressed in + // the coordinate system where q is the z-axis and the x-axis + // lies in the scattering plane (defined by q and e') and points + // in the direction of e', so the out-of-plane angle lies within + // -90<phi_xq<90deg if X is detected on the downstream/forward side of q. + TRotation rot_to_q; + rot_to_q.SetZAxis( pQ->Vect(), pP1->Vect()).Invert(); + TVector3 xq = fX.Vect(); + TVector3 bq = fB.Vect(); + xq *= rot_to_q; + bq *= rot_to_q; + fTheta_xq = xq.Theta(); //"theta_xq" + fPhi_xq = xq.Phi(); //"out-of-plane angle", "phi" + fTheta_bq = bq.Theta(); + fPhi_bq = bq.Phi(); + + // Missing momentum and components wrt q-vector + // The definition of p_miss as the negative of the undetected recoil + // momentum is the standard nuclear physics convention. + TVector3 p_miss = -bq; + fPmiss = p_miss.Mag(); //=fB.P() + //The missing momentum components in the q coordinate system. + //FIXME: just store p_miss in member variable + fPmiss_x = p_miss.X(); + fPmiss_y = p_miss.Y(); + fPmiss_z = p_miss.Z(); + + // Invariant mass of the recoil system, a.k.a. "missing mass". + // This invariant mass equals MB(ground state) plus any excitation energy. + fMrecoil = fB.M(); + + // Kinetic energies of X and B + fTX = fX.E() - fMX; + fTB = fB.E() - fMrecoil; + + // Standard nuclear physics definition of "missing energy": + // binding energy of X in the target (= removal energy of X). + // NB: If X is knocked out of a lower shell, the recoil system carries + // a significant excitation energy. This excitation is included in Emiss + // here, as it should, since it results from the binding of X. + fEmiss = omega - fTX - fTB; + + // In production reactions, the "missing energy" is defined + // as the total energy of the undetected recoil system. + // This is the "missing mass", Mrecoil, plus any kinetic energy. + fErecoil = fB.E(); + + // Calculate some interesting quantities in the CM system of A'. + // NB: If the target is initially at rest, the A'-vector (spatial part) + // is the same as the q-vector, so we could just reuse the q rotation + // matrix. The following is completely general, i.e. allows for a moving + // target. + + // Boost of the A' system. + // NB: ROOT's Boost() boosts particle to lab if the boost vector points + // along the particle's lab velocity, so we need the negative here to + // boost from the lab to the particle frame. + Double_t beta = pA1->P()/(pA1->E()); + TVector3 boost(0.,0.,-beta); + + // CM vectors of X and B. + // Express X and B in the frame where q is along the z-axis + // - the typical head-on collision picture. + TRotation rot_to_A1; + rot_to_A1.SetZAxis( pA1->Vect(), pP1->Vect()).Invert(); + TVector3 x_cm_vect = fX.Vect(); + x_cm_vect *= rot_to_A1; + TLorentzVector x_cm(x_cm_vect,fX.E()); + x_cm.Boost(boost); + TLorentzVector b_cm(-x_cm.Vect(), pA1->E()-x_cm.E()); + fPX_cm = x_cm.P(); + // pB_cm, by construction, is the same as pX_cm. + + // CM angles of X and B in the A' frame + fTheta_x_cm = x_cm.Theta(); + fPhi_x_cm = x_cm.Phi(); + fTheta_b_cm = b_cm.Theta(); + fPhi_b_cm = b_cm.Phi(); + + // CM kinetic energies of X and B and total kinetic energy + fTX_cm = x_cm.E() - fMX; + fTB_cm = b_cm.E() - fMrecoil; + fTtot_cm = fTX_cm + fTB_cm; + + // Mandelstam variables for the secondary vertex. + // These variables are defined for the reaction gA->XB, + // where g is the virtual photon (with momentum q), and A, X, and B + // are as before. + + fMandelS = (*pQ+*pA).M2(); + fMandelT = (*pQ-fX).M2(); + fMandelU = (*pQ-fB).M2(); + + fDataValid = true; + return 0; +} + +//_____________________________________________________________________________ +Int_t THcSecondaryKine::ReadDatabase( const TDatime& date ) +{ + cout << "*************&&&&&&&&&&&&&&************" << endl; + cout << "In THcSecondaryKine::ReadDatabase() " << endl; + cout << "particleMASS: " << fMX << endl; +// Query the run database for any parameters of the module that were not + // set by the constructor. This module has only one parameter, + // the mass of the detected secondary particle X. + // + // First searches for "<prefix>.MX", then, if not found, for "MX". + // If still not found, use proton mass. + /* + Int_t err = THaPhysicsModule::ReadRunDatabase( date ); + if( err ) return err; + + FILE* f = OpenRunDBFile( date ); + if( !f ) return kFileError; + + if ( fMX <= 0.0 ) { + TString name(fPrefix), tag("MX"); name += tag; + Int_t st = LoadDBvalue( f, date, name.Data(), fMX ); + if( st ) + LoadDBvalue( f, date, tag.Data(), fMX ); + if( fMX <= 0.0 ) fMX = 0.938; + } + fclose(f); + return 0; + */ + //fMX = 0.938; +} + +//_____________________________________________________________________________ +void THcSecondaryKine::SetMX( Double_t m ) +{ + if( !IsInit()) + fMX = m; + else + PrintInitError("SetMX()"); +} + +//_____________________________________________________________________________ +void THcSecondaryKine::SetSpectrometer( const char* name ) +{ + if( !IsInit()) + fSpectroName = name; + else + PrintInitError("SetSpectrometer()"); +} + +//_____________________________________________________________________________ +void THcSecondaryKine::SetPrimary( const char* name ) +{ + if( !IsInit()) + fPrimaryName = name; + else + PrintInitError("SetPrimary()"); +} diff --git a/src/THcSecondaryKine.h b/src/THcSecondaryKine.h new file mode 100644 index 0000000000000000000000000000000000000000..4b44c5aca5c00216faf7216991d5c24fedd3a329 --- /dev/null +++ b/src/THcSecondaryKine.h @@ -0,0 +1,119 @@ +#ifndef ROOT_THcSecondaryKine +#define ROOT_THcSecondaryKine + +////////////////////////////////////////////////////////////////////////// +// +// THcSecondaryKine +// +////////////////////////////////////////////////////////////////////////// + +#include "THaPhysicsModule.h" +#include "THcHallCSpectrometer.h" +#include "TLorentzVector.h" +#include "TString.h" + +class THaTrackingModule; +typedef TLorentzVector FourVect; + +class THcSecondaryKine : public THaPhysicsModule { + +public: + THcSecondaryKine( const char* name, const char* description, + const char* secondary_spectro = "", + const char* primary_kine = "", + Double_t secondary_mass = 0.0 /* GeV */ ); + virtual ~THcSecondaryKine(); + + virtual void Clear( Option_t* opt="" ); + + Double_t GetTheta_xq() const { return fTheta_xq; } + Double_t GetPhi_xq() const { return fPhi_xq; } + Double_t GetTheta_bq() const { return fTheta_bq; } + Double_t GetPhi_bq() const { return fPhi_bq; } + Double_t GetXangle() const { return fXangle; } + Double_t GetPmiss() const { return fPmiss; } + Double_t GetPmiss_x() const { return fPmiss_x; } + Double_t GetPmiss_y() const { return fPmiss_y; } + Double_t GetPmiss_z() const { return fPmiss_z; } + Double_t GetEmiss() const { return fEmiss; } + Double_t GetMrecoil() const { return fMrecoil; } + Double_t GetErecoil() const { return fErecoil; } + Double_t GetPrecoil_x() const { return fB.X(); } + Double_t GetPrecoil_y() const { return fB.Y(); } + Double_t GetPrecoil_z() const { return fB.Z(); } + Double_t GetTX() const { return fTX; } + Double_t GetTB() const { return fTB; } + Double_t GetPX_cm() const { return fPX_cm; } + Double_t GetTheta_x_cm() const { return fTheta_x_cm; } + Double_t GetPhi_x_cm() const { return fPhi_x_cm; } + Double_t GetTheta_b_cm() const { return fTheta_b_cm; } + Double_t GetPhi_b_cm() const { return fPhi_b_cm; } + Double_t GetTX_cm() const { return fTX_cm; } + Double_t GetTB_cm() const { return fTB_cm; } + Double_t GetTtot_cm() const { return fTtot_cm; } + Double_t GetMandelS() const { return fMandelS; } + Double_t GetMandelT() const { return fMandelT; } + Double_t GetMandelU() const { return fMandelU; } + + Double_t GetMX() const { return fMX; } + + const TLorentzVector* GetPX() const { return &fX; } + const TLorentzVector* GetPB() const { return &fB; } + + virtual EStatus Init( const TDatime& run_time ); + virtual Int_t Process( const THaEvData& ); + + void SetSpectrometer( const char* name ); + void SetPrimary( const char* name ); + void SetMX( Double_t m ); + + THcPrimaryKine* GetPrimary() const { return fPrimary; } + + protected: + + // Event data + Double_t fTheta_xq; // Polar angle of detected particle with q (rad) + Double_t fPhi_xq; // Azimuth of detected particle with scattering plane (rad) + Double_t fTheta_bq; // Polar angle of recoil system with q (rad) + Double_t fPhi_bq; // Azimuth of recoil system with scattering plane (rad) + Double_t fXangle; // Angle of detected particle with scattered electron (rad) + Double_t fPmiss; // Missing momentum magnitude (GeV), nuclear physics definition (-pB) + Double_t fPmiss_x; // x-component of p_miss wrt q (GeV) + Double_t fPmiss_y; // y-component of p_miss wrt q (GeV) + Double_t fPmiss_z; // z-component of p_miss, along q (GeV) + Double_t fEmiss; // Missing energy (GeV), nuclear physics definition omega-Tx-Tb + Double_t fMrecoil; // Invariant mass of recoil system (GeV) + Double_t fErecoil; // Total energy of recoil system (GeV) + Double_t fTX; // Kinetic energy of detected particle (GeV) + Double_t fTB; // Kinetic energy of recoil system (GeV) + Double_t fPX_cm; // Magnitude of X momentum in CM system (GeV) + Double_t fTheta_x_cm; // Polar angle of X in CM system wrt q (rad) + Double_t fPhi_x_cm; // Azimuth of X in CM system wrt q (rad) + Double_t fTheta_b_cm; // Polar angle of recoil systm in CM wrt q (rad) + Double_t fPhi_b_cm; // Azimuth of recoil system in CM wrt q (rad) + Double_t fTX_cm; // Kinetic energy of X in CM (GeV) + Double_t fTB_cm; // Kinetic energy of B in CM (GeV) + Double_t fTtot_cm; // Total CM kinetic energy + Double_t fMandelS; // Mandelstam s for secondary vertex (GeV^2) + Double_t fMandelT; // Mandelstam t for secondary vertex (GeV^2) + Double_t fMandelU; // Mandelstam u for secondary vertex (GeV^2) + + TLorentzVector fX; // Detected secondary particle 4-momentum (GeV) + TLorentzVector fB; // Recoil system 4-momentum (GeV) + + // Parameters + Double_t fMX; // Mass of secondary particle (GeV) + + TString fSpectroName; // Name of spectrometer for secondary particle + THaTrackingModule* fSpectro; // Pointer to spectrometer object + THcHallCSpectrometer* fHC_Spectro; + TString fPrimaryName; // Name of module for primary interaction kinematics + THcPrimaryKine* fPrimary; // Pointer to primary kinematics module + + virtual Int_t DefineVariables( EMode mode = kDefine ); + virtual Int_t ReadDatabase( const TDatime& date ); + + ClassDef(THcSecondaryKine,0) //Secondary particle kinematics module +}; + +#endif