#include "Reconstructor.h" #include "MassLookup.h" #include namespace SabreRecon { constexpr double Reconstructor::s_phiDet[5]; //C++11 weirdness with static constexpr Reconstructor::Reconstructor() { } Reconstructor::Reconstructor(const Target& target, double spsTheta, double spsB, const std::vector& spsCal) { Init(target, spsTheta, spsB, spsCal); } Reconstructor::~Reconstructor() {} void Reconstructor::Init(const Target& target, double spsTheta, double spsB, const std::vector& spsCal) { m_target = target; m_focalPlane.Init({spsB, spsTheta, spsCal}); for(int i=0; i<5; i++) m_sabreArray.emplace_back(SabreDetector::Parameters(s_phiDet[i], s_tiltAngle, s_zOffset, false, i)); } TLorentzVector Reconstructor::GetSabre4Vector(const SabrePair& pair, double mass) { TVector3 coords; TLorentzVector result; double p, E; if(pair.detID == 4) coords = m_sabreArray[4].GetHitCoordinates(15-pair.local_ring, pair.local_wedge); else coords = m_sabreArray[pair.detID].GetHitCoordinates(pair.local_ring, pair.local_wedge); p = std::sqrt(pair.ringE*(pair.ringE + 2.0*mass)); E = pair.ringE + mass; result.SetPxPyPzE(p*std::sin(coords.Theta())*std::cos(coords.Phi()), p*std::sin(coords.Theta())*std::sin(coords.Phi()), p*std::cos(coords.Theta()), E); return result; } TLorentzVector Reconstructor::GetSabre4VectorEloss(const SabrePair& pair, double mass, const NucID& id) { TVector3 coords; TLorentzVector result; double p, E, rxnKE; if(pair.detID == 4) coords = m_sabreArray[4].GetHitCoordinates(15-pair.local_ring, pair.local_wedge); else coords = m_sabreArray[pair.detID].GetHitCoordinates(pair.local_ring, pair.local_wedge); rxnKE = pair.ringE + m_target.GetReverseEnergyLossFractionalDepth(id.Z, id.A, pair.ringE, coords.Theta(), 0.5); p = std::sqrt(pair.ringE*(pair.ringE + 2.0*mass)); E = pair.ringE + mass; result.SetPxPyPzE(p*std::sin(coords.Theta())*std::cos(coords.Phi()), p*std::sin(coords.Theta())*std::sin(coords.Phi()), p*std::cos(coords.Theta()), E); return result; } TLorentzVector Reconstructor::GetFP4VectorEloss(double xavg, double mass, const NucID& id) { TLorentzVector result; double p = m_focalPlane.GetP(xavg, id.Z); double theta = m_focalPlane.GetFPTheta(); double KE = std::sqrt(p*p + mass*mass) - mass; double rxnKE = KE + m_target.GetReverseEnergyLossFractionalDepth(id.Z, id.A, KE, theta, 0.5); double rxnP = sqrt(rxnKE*(rxnKE + 2.0*mass)); double rxnE = rxnKE + mass; result.SetPxPyPzE(rxnP*std::sin(theta), 0.0, rxnP*std::cos(theta), rxnE); return result; } TLorentzVector Reconstructor::GetProj4VectorEloss(double beamKE, double mass, const NucID& id) { TLorentzVector result; double rxnKE = beamKE + m_target.GetReverseEnergyLossFractionalDepth(id.Z, id.A, beamKE, 0.0, 0.5); result.SetPxPyPzE(0.0,0.0,std::sqrt(rxnKE*(rxnKE+2.0*mass)),rxnKE+mass); return result; } ReconResult Reconstructor::RunThreeParticleExcitation(const SabrePair& p1, const SabrePair& p2, const SabrePair& p3, const std::vector& nuclei) { ReconResult result; NucID parent; parent.Z = nuclei[0].Z + nuclei[1].Z + nuclei[2].Z; parent.A = nuclei[0].A + nuclei[1].A + nuclei[2].A; if(parent.Z > parent.A || parent.A <= 0 || parent.Z < 0) { std::cerr<<"Invalid parent nucleus at Reconstructor::RunThreeParticleExcitation with Z: "<& nuclei) { ReconResult result; NucID parent; parent.Z = nuclei[0].Z + nuclei[1].Z; parent.A = nuclei[0].A + nuclei[1].A; if(parent.Z > parent.A || parent.A <= 0 || parent.Z < 0) { std::cerr<<"Invalid parent nucleus at Reconstructor::RunTwoParticleExcitation with Z: "<& nuclei) { ReconResult result; NucID resid; resid.Z = nuclei[0].Z + nuclei[1].Z - nuclei[2].Z; resid.A = nuclei[0].A + nuclei[1].A - nuclei[2].A; if(resid.Z > resid.A || resid.A <= 0 || resid.Z < 0) { std::cerr<<"Invalid reisdual nucleus at Reconstructor::RunFPResidExcitation with Z: "<& nuclei) { ReconResult result; NucID resid; resid.Z = nuclei[0].Z + nuclei[1].Z - nuclei[2].Z; resid.A = nuclei[0].A + nuclei[1].A - nuclei[2].A; if(resid.Z > resid.A || resid.A <= 0 || resid.Z < 0) { std::cerr<<"Invalid reisdual nucleus at Reconstructor::RunFPResidExcitation with Z: "<& nuclei) { ReconResult result; NucID decayFrag; decayFrag.Z = nuclei[0].Z + nuclei[1].Z - nuclei[2].Z - nuclei[3].Z; decayFrag.A = nuclei[0].A + nuclei[1].A - nuclei[2].A - nuclei[3].A; if(decayFrag.Z > decayFrag.A || decayFrag.A <= 0 || decayFrag.Z < 0) { std::cerr<<"Invalid reisdual nucleus at Reconstructor::RunSabreExcitation with Z: "<& nuclei) { ReconResult result; NucID decayFrag; decayFrag.Z = nuclei[0].Z + nuclei[1].Z - nuclei[2].Z - nuclei[3].Z; decayFrag.A = nuclei[0].A + nuclei[1].A - nuclei[2].A - nuclei[3].A; if(decayFrag.Z > decayFrag.A || decayFrag.A <= 0 || decayFrag.Z < 0) { std::cerr<<"Invalid reisdual nucleus at Reconstructor::RunSabreExcitation with Z: "<