613{
614
615
616
617
618 if (
json_.has_key(
"energy_pdf_max") ) {
619 bool ok;
620 const marley::JSON& max_spec =
json_.at(
"energy_pdf_max" );
621 double user_max = max_spec.to_double( ok );
622 if ( !ok ) handle_json_error( "energy_pdf_max", max_spec );
623 else {
624 gen.set_default_E_pdf_max( user_max );
625 MARLEY_LOG( DEBUG, "init.config.source" ) << "User-specified"
626 " energy_pdf_max = " << user_max;
627 }
628 }
629
630
631
632 if ( !
json_.has_key(
"source") )
return;
633 const marley::JSON& source_spec =
json_.at(
"source" );
634
635
636
638 MARLEY_LOG( INFO, "init.config.source" ) << "Null source specification detected. Skipping"
639 << " neutrino source configuration.";
640 return;
641 }
642
643
644 if ( !source_spec.has_key("type") ) {
645 throw marley::Error( "Missing \"type\" key in neutrino source"
646 " specification." );
647 return;
648 }
649
650
651 bool ok;
652 std::string type = source_spec.at( "type" ).to_string( ok );
653 if ( !ok ) handle_json_error( "source.type", source_spec.at("type") );
654
655
656 if ( !source_spec.has_key("neutrino") ) {
657 throw marley::Error( "Missing \"neutrino\" key in neutrino source"
658 " specification." );
659 return;
660 }
661
662 std::string nu = source_spec.at( "neutrino" ).to_string( ok );
663 if ( !ok ) handle_json_error( "source.neutrino", source_spec.at("neutrino") );
664
665
666 int pdg = neutrino_pdg( nu );
667
668 std::unique_ptr< marley::NeutrinoSource > source;
669
670 if ( type == "mono" || type == "monoenergetic" ) {
671 double energy = source_get_double( "energy", source_spec, "monoenergetic" );
672 source_check_positive( energy, "energy", "monoenergetic" );
673 source = std::make_unique< marley::MonoNeutrinoSource >( pdg, energy );
674 MARLEY_LOG( INFO, "init.config.source" ) << "Created monoenergetic "
675 << marley_utils::get_particle_symbol( pdg ) << " source with"
676 << " neutrino energy = " << energy << " MeV";
677 }
678 else if ( type == "dar" || type == "decay-at-rest" ) {
679 source = std::make_unique< marley::DecayAtRestNeutrinoSource >( pdg );
680 MARLEY_LOG( INFO, "init.config.source" ) << "Created muon decay-at-rest "
681 << marley_utils::get_particle_symbol( pdg ) << " source";
682 }
683 else if ( type == "fd" || type == "fermi-dirac" || type == "fermi_dirac" ) {
684 double Emin = source_get_double( "Emin", source_spec, "Fermi-Dirac" );
685 double Emax = source_get_double( "Emax", source_spec, "Fermi-Dirac" );
686 double temp = source_get_double( "temperature", source_spec,
687 "Fermi-Dirac" );
688
689 double eta = 0.;
690 if ( source_spec.has_key("eta") ) {
691 eta = source_get_double( "eta", source_spec, "Fermi-Dirac" );
692 }
693
694 source_check_nonnegative( Emin, "Emin", "Fermi-Dirac" );
695 source_check_positive( temp, "temperature", "Fermi-Dirac" );
696
697 if ( Emax <= Emin ) throw marley::Error( "Emax <= Emin for a Fermi-Dirac"
698 " neutrino source" );
699
700 source = std::make_unique< marley::FermiDiracNeutrinoSource >( pdg, Emin,
701 Emax, temp, eta );
702 MARLEY_LOG( INFO, "init.config.source" ) << "Created Fermi-Dirac "
703 << marley_utils::get_particle_symbol( pdg ) << " source with parameters";
704 MARLEY_LOG( INFO, "init.config.source" ) << " Emin = " << Emin << " MeV";
705 MARLEY_LOG( INFO, "init.config.source" ) << " Emax = " << Emax << " MeV";
706 MARLEY_LOG( INFO, "init.config.source" ) << " temperature = " << temp << " MeV";
707 MARLEY_LOG( INFO, "init.config.source" ) << " eta = " << eta;
708 }
709 else if ( type == "bf" || type == "beta" || type == "beta-fit" ) {
710 double Emin = source_get_double( "Emin", source_spec, "beta-fit" );
711 double Emax = source_get_double( "Emax", source_spec, "beta-fit" );
712 double Emean = source_get_double( "Emean", source_spec, "beta-fit" );
713
714 double beta = 4.5;
715 if ( source_spec.has_key("beta") ) {
716 beta = source_get_double( "beta", source_spec, "beta-fit" );
717 }
718
719 source_check_nonnegative( Emin, "Emin", "beta-fit" );
720 source_check_positive( Emean, "Emean", "beta-fit" );
721
722 if ( Emax <= Emin ) throw marley::Error( "Emax <= Emin for a beta-fit"
723 " neutrino source" );
724
725 source = std::make_unique< marley::BetaFitNeutrinoSource >( pdg, Emin,
726 Emax, Emean, beta );
727 MARLEY_LOG( INFO, "init.config.source" ) << "Created beta-fit "
728 << marley_utils::get_particle_symbol( pdg ) << " source with parameters";
729 MARLEY_LOG( INFO, "init.config.source" ) << " Emin = " << Emin << " MeV";
730 MARLEY_LOG( INFO, "init.config.source" ) << " Emax = " << Emax << " MeV";
731 MARLEY_LOG( INFO, "init.config.source" ) << " average energy = " << Emean << " MeV";
732 MARLEY_LOG( INFO, "init.config.source" ) << " beta = " << beta;
733 }
734 else if ( type == "af" || type == "alpha" || type == "alpha-fit" ) {
735 double Emin = source_get_double( "Emin", source_spec, "alpha-fit" );
736 double Emax = source_get_double( "Emax", source_spec, "alpha-fit" );
737 double Emean = source_get_double( "Emean", source_spec, "alpha-fit" );
738
739 double alpha = 2.;
740 if ( source_spec.has_key("alpha") ) {
741 alpha = source_get_double( "alpha", source_spec, "alpha-fit" );
742 }
743
744 source_check_nonnegative( Emin, "Emin", "alpha-fit" );
745 source_check_positive( Emean, "Emean", "alpha-fit" );
746
747 if ( Emax <= Emin ) throw marley::Error( "Emax <= Emin for an alpha-fit"
748 " neutrino source" );
749
750 source = std::make_unique< marley::AlphaFitNeutrinoSource >( pdg, Emin,
751 Emax, Emean, alpha );
752 MARLEY_LOG( INFO, "init.config.source" ) << "Created alpha-fit "
753 << marley_utils::get_particle_symbol( pdg ) << " source with parameters";
754 MARLEY_LOG( INFO, "init.config.source" ) << " Emin = " << Emin << " MeV";
755 MARLEY_LOG( INFO, "init.config.source" ) << " Emax = " << Emax << " MeV";
756 MARLEY_LOG( INFO, "init.config.source" ) << " average energy = " << Emean << " MeV";
757 MARLEY_LOG( INFO, "init.config.source" ) << " alpha = " << alpha;
758 }
759 else if ( type == "hist" || type == "histogram" ) {
760
761 std::vector< double > Es = get_vector( "E_bin_lefts", source_spec,
762 "histogram" );
763 std::vector< double > weights = get_vector( "weights", source_spec,
764 "histogram" );
765
766 if ( Es.size() != weights.size() ) throw marley::Error( "The sizes of the"
767 " arrays of energy bin left edges and weights given for a histogram"
768 " neutrino source are unequal." );
769
770 double Emax = source_get_double( "Emax", source_spec, "histogram" );
771 source_check_positive( Emax, "Emax", "histogram" );
772
773
774 Es.push_back( Emax );
775
776
777
778 weights.push_back( 0. );
779
780
781
782 int jmax = Es.size() - 1;
783 for ( int j = 0; j < jmax; ++j ) {
784
785 double width = Es.at( j + 1 ) - Es.at( j );
786 if ( width <= 0 ) throw marley::Error( "Invalid bin width"
787 + std::to_string(width) + " encountered when creating a histogram"
788 " neutrino source" );
789
790 weights.at( j ) /= width;
791 }
792
793
794 source = std::make_unique< marley::GridNeutrinoSource >( Es, weights, pdg,
795 InterpMethod::Constant );
796 MARLEY_LOG( INFO, "init.config.source" ) << "Created histogram "
797 << marley_utils::get_particle_symbol( pdg ) << " source";
798 }
799 else if ( type == "grid" ) {
800 std::vector< double > energies = get_vector( "energies", source_spec,
801 "grid" );
802 std::vector< double > PDs = get_vector( "prob_densities", source_spec,
803 "grid" );
804 std::string rule =
source_get(
"rule", source_spec,
"grid",
"linlin" );
805
806 InterpMethod method = get_interpolation_method( rule );
807
808 source = std::make_unique< marley::GridNeutrinoSource >( energies, PDs,
809 pdg, method );
810 MARLEY_LOG( INFO, "init.config.source" ) << "Created grid "
811 << marley_utils::get_particle_symbol( pdg ) << " source";
812 }
814 throw marley::Error( "Unrecognized MARLEY neutrino source type '"
815 + type + "'" );
816 }
817
818
819
820
821 if ( source_spec.has_key("weight_flux") ) {
822 bool ok = false;
823 bool should_we_weight = source_spec.at( "weight_flux" ).to_bool( ok );
824 if ( !ok ) handle_json_error( "source.weight_flux",
825 source_spec.at("weight_flux") );
827 MARLEY_LOG( DEBUG, "init.config.source" ) << "weight_flux = "
828 << ( should_we_weight ? "true" : "false" );
829 }
830
831
833
834}
void set_source(std::unique_ptr< marley::NeutrinoSource > source)
Take ownership of a new NeutrinoSource, replacing any existing source owned by this Generator.
void set_weight_flux(bool should_we_weight)
Sets the value of the weight_flux flag.
std::string source_get(const char *name, const marley::JSON &source_spec, const char *description, const char *default_str) const
Helper function for loading strings from the JSON configuration.
bool process_extra_source_types(const std::string &type, const marley::JSON &source_spec, int pdg_code, std::unique_ptr< marley::NeutrinoSource > &source) const
Helper function used to define ROOT-based neutrino source types @detail This function is a no-op when...
bool is_null() const
Functions for getting primitives from the JSON object.