diff --git a/Framework/Units/PhysicalUnits.h b/Framework/Units/PhysicalUnits.h index 8bc7842a62360a4cedb51b5b6a0ce38a64e063c9..5a2a7b2402daa59c89409db78bba66914e890376 100644 --- a/Framework/Units/PhysicalUnits.h +++ b/Framework/Units/PhysicalUnits.h @@ -114,11 +114,36 @@ namespace corsika::units::si { static_pow<p>(corsika::units::constants::hBar) * static_pow<q>(corsika::units::constants::c); } + + template <typename DimFrom> + auto constexpr ConversionFactorSIToHEP() { + static_assert(DimFrom::dim4 == 0 && DimFrom::dim5 == 0 && DimFrom::dim6 == 0 && + DimFrom::dim7 == 0 && DimFrom::dim8 == 0, + "must be pure L, M, T type"); + + int constexpr l = DimFrom::dim1; // SI length dim. + int constexpr m = DimFrom::dim2; // SI mass dim. + int constexpr t = DimFrom::dim3; // SI time dim. + + int constexpr p = -m; + int constexpr q = m + t; + int constexpr e = m - t - l; + + using namespace detail; + return static_pow<e>(corsika::units::constants::hBarC) * + static_pow<p>(corsika::units::constants::hBar) * + static_pow<q>(corsika::units::constants::c); + } template <typename DimTo, typename DimFrom> auto constexpr ConvertHEPToSI(quantity<DimFrom> q) { return ConversionFactorHEPToSI<DimFrom, DimTo>() * q; } + + template <typename DimFrom> + auto constexpr ConvertSIToHEP(quantity<DimFrom> q) { + return ConversionFactorSIToHEP<DimFrom>() * q; + } } // end namespace corsika::units::si /** diff --git a/Framework/Units/testUnits.cc b/Framework/Units/testUnits.cc index 77274459c0ccf2dc19b4068a15d2bb5c2e66ce62..b715cc498e404cde1d3771aa2dde8edc0f5dc683 100644 --- a/Framework/Units/testUnits.cc +++ b/Framework/Units/testUnits.cc @@ -140,4 +140,19 @@ TEST_CASE("PhysicalUnits", "[Units]") { REQUIRE((protonMassSI / 1.672'621'898e-27_kg) == Approx(1)); REQUIRE((protonMassSI / (1.007'276 * corsika::units::constants::u)) == Approx(1)); } + + SECTION("SI/HEP conversion") { + REQUIRE(ConvertSIToHEP(units::constants::c) == Approx(1)); + REQUIRE(ConvertSIToHEP(units::constants::hBar) == Approx(1)); + + { + auto const invLength = 1 / 197.326978_fm; // should be convertible to HEPEnergy + HEPEnergyType const energy = ConvertSIToHEP(invLength); + REQUIRE(energy / 1_MeV == Approx(1)); + } + + REQUIRE(ConvertSIToHEP(6.5823e-25_s) * 1_GeV == Approx(1).epsilon(1e-4)); + + REQUIRE(ConvertSIToHEP(3.8938e-32 * meter * meter) * 1_GeV * 1_GeV == Approx(1).epsilon(1e-4)); + } }