diff --git a/Processes/HadronicElasticModel/HadronicElasticModel.h b/Processes/HadronicElasticModel/HadronicElasticModel.h index 0e7dc954d6cfb2a657a6daae44c57372d0487a76..cf5437f614235cd5b01898fe305c256026576eb2 100644 --- a/Processes/HadronicElasticModel/HadronicElasticModel.h +++ b/Processes/HadronicElasticModel/HadronicElasticModel.h @@ -13,6 +13,7 @@ #include <corsika/environment/Environment.h> #include <corsika/environment/NuclearComposition.h> +#include <corsika/geometry/FourVector.h> #include <corsika/particles/ParticleProperties.h> #include <corsika/process/InteractionProcess.h> #include <corsika/random/ExponentialDistribution.h> @@ -156,16 +157,22 @@ namespace corsika::process::HadronicElasticModel { std::uniform_real_distribution phiDist(0., 2 * M_PI); - utl::COMBoost const boost(projectileEnergy, projectileMomentum, targetMass); - auto const [eProjectileCoM, pProjectileCoM] = - boost.toCoM(projectileEnergy, projectileMomentum); - auto const [eTargetCoM, pTargetCoM] = boost.toCoM( + geometry::FourVector const projectileLab(projectileEnergy, projectileMomentum); + geometry::FourVector const targetLab( targetMass, geometry::Vector<units::si::hepmomentum_d>( projectileMomentum.GetCoordinateSystem(), {0_eV, 0_eV, 0_eV})); + utl::COMBoost const boost(projectileLab, targetMass); - auto const pProjectileCoMSqNorm = pProjectileCoM.squaredNorm(); + auto const projectileCoM = boost.toCoM(projectileLab); + auto const targetCoM = boost.toCoM(targetLab); + + auto const pProjectileCoMSqNorm = + projectileCoM.GetSpaceLikeComponents().squaredNorm(); auto const pProjectileCoMNorm = sqrt(pProjectileCoMSqNorm); + auto const eProjectileCoM = projectileCoM.GetTimeLikeComponent(); + auto const eTargetCoM = targetCoM.GetTimeLikeComponent(); + auto const sqrtS = eProjectileCoM + eTargetCoM; auto const s = units::si::detail::static_pow<2>(sqrtS); @@ -192,21 +199,23 @@ namespace corsika::process::HadronicElasticModel { << " GeV² (max./GeV² = " << 4 * invGeVsq * projectileMomentumSquaredNorm << ')' << std::endl; - auto const theta = - 2 * - asin(sqrt(absT / (4 * pProjectileCoMSqNorm))); // would work for in any frame + auto const theta = 2 * asin(sqrt(absT / (4 * pProjectileCoMSqNorm))); auto const phi = phiDist(fRNG); - geometry::QuantityVector<units::si::hepmomentum_d> const scatteredMomentum{ - pProjectileCoMNorm * sin(theta) * cos(phi), - pProjectileCoMNorm * sin(theta) * sin(phi), pProjectileCoMNorm * cos(theta)}; - - auto const [eProjectileScatteredLab, pProjectileScatteredLab] = - boost.fromCoM(eProjectileCoM, scatteredMomentum); - - p.SetMomentum(pProjectileScatteredLab); - p.SetEnergy(eProjectileScatteredLab); // alternatively recalculate energy from - // momentum and mass + auto const projectileScatteredLab = boost.fromCoM( + geometry::FourVector<HEPEnergyType, geometry::Vector<hepmomentum_d>>( + eProjectileCoM, + geometry::Vector<hepmomentum_d>(projectileMomentum.GetCoordinateSystem(), + {pProjectileCoMNorm * sin(theta) * cos(phi), + pProjectileCoMNorm * sin(theta) * sin(phi), + pProjectileCoMNorm * cos(theta)}))); + + p.SetMomentum(projectileScatteredLab.GetSpaceLikeComponents()); + p.SetEnergy( + sqrt(projectileScatteredLab.GetSpaceLikeComponents().squaredNorm() + + units::si::detail::static_pow<2>(corsika::particles::GetMass( + p.GetPID())))); // Don't use energy from boost. It can be smaller than + // the momentum due to limited numerical accuracy. return process::EProcessReturn::eOk; }