#include "MuDecayChannel.hh" #include "musrMuonium.hh" #include "G4AntiNeutrinoMu.hh" #include "G4DecayProducts.hh" #include "G4NeutrinoE.hh" #include "G4Positron.hh" #include "Randomize.hh" #include #include #include #include #include namespace { constexpr int numberOfDecays = 50000; constexpr double expectedMeanScaledEnergy = 0.7; constexpr double meanEnergyTolerance = 0.008; constexpr double isotropyTolerance = 0.015; constexpr double energyConservationTolerance = 1.e-9; } // namespace int main() { G4Positron::PositronDefinition(); G4NeutrinoE::NeutrinoEDefinition(); G4AntiNeutrinoMu::AntiNeutrinoMuDefinition(); const auto* muonium = musrMuonium::Definition(); MuDecayChannel decay("Mu",1.); G4Random::setTheSeed(314159265); const double endpoint = muonium->GetPDGMass()/2.; const std::array expectedDaughters = { "e+", "nu_e", "anti_nu_mu" }; double scaledEnergySum = 0.; G4ThreeVector directionSum; for (int event=0; event products(decay.DecayIt(muonium->GetPDGMass())); if (!products || products->entries()!=3) { std::cerr<<"decay "<entries(); ++daughter) { const auto* particle = (*products)[daughter]; if (!particle) { std::cerr<<"decay "<GetParticleDefinition()->GetParticleName(); if (actualName!=expectedDaughters[daughter]) { std::cerr<<"decay "<GetKineticEnergy()) || particle->GetKineticEnergy()<0.) { std::cerr<<"decay "<GetKineticEnergy()<<'\n'; return 1; } } double daughterEnergy = 0.; for (int daughter=0; daughterentries(); ++daughter) { daughterEnergy += (*products)[daughter]->GetTotalEnergy(); } if (std::abs(daughterEnergy-muonium->GetPDGMass())> energyConservationTolerance) { std::cerr<<"decay "<GetPDGMass()<<'\n'; return 1; } const auto* positron = (*products)[0]; const double scaledEnergy = positron->GetTotalEnergy()/endpoint; if (scaledEnergy<0. || scaledEnergy>1.) { std::cerr<<"decay "<GetMomentumDirection(); } const double meanScaledEnergy = scaledEnergySum/numberOfDecays; if (std::abs(meanScaledEnergy-expectedMeanScaledEnergy)> meanEnergyTolerance) { std::cerr<<"Michel spectrum mean: expected " <isotropyTolerance || std::abs(meanDirection.y())>isotropyTolerance || std::abs(meanDirection.z())>isotropyTolerance) { std::cerr<<"decay directions are not isotropic: mean direction " <