diff --git a/README.md b/README.md index e27d9417c3..e0dedcbb94 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # The GENIE Event Generator -
@@ -8,14 +7,14 @@

- The GENIE Generator is a leading simulation tool used by nearly all modern neutrino experiments. - It features a modular framework with state-of-the-art physics for neutrino and charged-lepton interactions, - and several BSM channels. It incorporates results from GENIE’s global data analysis and includes multiple tuned models. - GENIE supports all neutrino types, targets, and energy scales from MeV to PeV, + The GENIE Generator is a leading simulation tool used by nearly all modern neutrino experiments. + It features a modular framework with state-of-the-art physics for neutrino and charged-lepton interactions, + and several BSM channels. It incorporates results from GENIE’s global data analysis and includes multiple tuned models. + GENIE supports all neutrino types, targets, and energy scales from MeV to PeV, and provides tools for flux handling, geometry, event generation, and reweighting.

- For more information, visit + For more information, visit http://genie-mc.org | https://genie-mc.github.io.

@@ -27,7 +26,7 @@ Luis Alvarez-Ruso (*IFIC*), Costas Andreopoulos (*Liverpool*), Adi Ashkenazi (*Tel Aviv*), Joshua Barrow (*Minnesota*), Steve Dytman (*Pittsburgh*), Hugh Gallagher (*Tufts*), Alfonso Andres Garcia Soto (*IFIC*), Steven Gardiner (*Fermilab*), Matan Goldenberg (*Tel Aviv*), Robert Hatcher (*Fermilab*), Or Hen (*MIT*), Igor Kakorin (*JINR*), Konstantin Kuzmin (*ITEP and JINR*), Liang Liu (*Fermilab*), Xianguo Lu (*Warwick*), Anselmo Meregaglia (*Bordeaux, CNRS/IN2P3*), Vadim Naumov (*JINR*), Afroditi Papadopoulou (*Argonne*), Gabriel Perdue (*Fermilab*), Komninos-John Plows (*Oxford*), Marco Roda (*Liverpool*), Alon Sportes (*Tel Aviv*), Júlia Tena Vidal (*Tel Aviv*), Jeremy Wolcott (*Tufts*), Qiyu Yan (*UCAS and Warwick*) -**Past authors:** Christopher Barry (*Liverpool*), Steve Dennis (*Liverpool*), Walter Giele (*Fermilab*), Timothy Hobbs (*Fermilab*), Libo Jiang (*Pittsburgh*), Rhiannon Jones (*Liverpool*), Weijun Li (*Oxford*), Donna Naples (*Pittsburgh*), Beth Slater (*Liverpool*), Noah Steinberg (*Fermilab*), Vladyslav Syrotenko (*Tufts*), Julia Yarba (*Fermilab*) +**Past authors:** Christopher Barry (*Liverpool*), Steve Dennis (*Liverpool*), Walter Giele (*Fermilab*), Timothy Hobbs (*Fermilab*), Libo Jiang (*Pittsburgh*), Rhiannon Jones (*Liverpool*), Weijun Li (*Oxford*), Donna Naples (*Pittsburgh*), Beth Slater (*Liverpool*), Noah Steinberg (*Fermilab*), Vladyslav Syrotenko (*Tufts*), Julia Yarba (*Fermilab*) For more details on the GENIE collaboration please visit [this page](https://genie-mc.github.io/collaboration.html). @@ -54,7 +53,7 @@ DOIs for recent releases of the GENIE Event Generator are listed below: ## Physics & User manual -For installation and usage information, as well as information on the GENIE framework, event generator modules and tuning, +For installation and usage information, as well as information on the GENIE framework, event generator modules and tuning, see the [latest version of the GENIE Physics & User Manual](https://www.overleaf.com/read/rqmbqzzvsvmb#5ab475), originally published as arXiv:1510.05494. ## Public releases and physics tunes @@ -63,7 +62,7 @@ For a list of public releases and a summary information, see [this page](https:/ A list of model configurations and tunes supported in each release is maintained [here](https://genie-mc.github.io/tunes.html). Details on the naming conventions for releases, model configurations and tunes can be found [here](https://genie-mc.github.io/naming_conventions.html). -[Recent publications and talks](https://genie-mc.github.io/pub.html) +[Recent publications and talks](https://genie-mc.github.io/pub.html) by GENIE authors highlight key modeling advances and results from our global analysis of scattering data. ## Contribution guidelines diff --git a/config/CommonParam.xml b/config/CommonParam.xml index 2d24e8e061..2134a0b17c 100644 --- a/config/CommonParam.xml +++ b/config/CommonParam.xml @@ -276,18 +276,21 @@ Or changing the name of this parameter set ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Set the coupling of dark matter to nucleons --> - 0.1 + + 1.0 1.0 - 1.0 + -1.0 1.0 + 1.0 - 1.0 + -1.0 1.0 - 1.0 + -1.0 1.0 - 1.0 + -1.0 1.0 - 1.0 + -1.0 + 1.0 1.0 1.441 diff --git a/config/DMRESHadronicSystemGenerator.xml b/config/DMRESHadronicSystemGenerator.xml new file mode 100644 index 0000000000..05c1dfffea --- /dev/null +++ b/config/DMRESHadronicSystemGenerator.xml @@ -0,0 +1,22 @@ + + + + + + + + genie::UnstableParticleDecayer/BeforeHadronTransport + + + + diff --git a/config/DMRESInteractionListGenerator.xml b/config/DMRESInteractionListGenerator.xml new file mode 100644 index 0000000000..77f20ea85f --- /dev/null +++ b/config/DMRESInteractionListGenerator.xml @@ -0,0 +1,24 @@ + + + + + + + + Resonances + + + + true + + + diff --git a/config/DMRESKinematicsGenerator.xml b/config/DMRESKinematicsGenerator.xml new file mode 100644 index 0000000000..23676f1f1e --- /dev/null +++ b/config/DMRESKinematicsGenerator.xml @@ -0,0 +1,35 @@ + + + + + + + + NonResBackground + + + + + + 1.400 + 0.500 + + + + 1.400 + + + diff --git a/config/DMRESOutgoingDarkGenerator.xml b/config/DMRESOutgoingDarkGenerator.xml new file mode 100644 index 0000000000..549e3c7a23 --- /dev/null +++ b/config/DMRESOutgoingDarkGenerator.xml @@ -0,0 +1,19 @@ + + + + + + + + Lepton + + + + diff --git a/config/DMRESPXSec.xml b/config/DMRESPXSec.xml new file mode 100644 index 0000000000..767076139a --- /dev/null +++ b/config/DMRESPXSec.xml @@ -0,0 +1,64 @@ + + + + + + + + WeakInt,NonResBackground,CKM,FermiGas,BoostedDarkMatter + + genie::DMRESXSecFast/Default + + 0 + 1.000 + 1.05 + 0.76338 + 1.120 + 0.840 + + + + WeakInt,NonResBackground,CKM,FermiGas,BoostedDarkMatter + + genie::DMRESXSecFast/Default + + 2 + 1.000 + 1.05 + 0.76338 + 1.120 + 0.840 + + + + diff --git a/config/DMRESXSec.xml b/config/DMRESXSec.xml new file mode 100644 index 0000000000..0bf5b2961e --- /dev/null +++ b/config/DMRESXSec.xml @@ -0,0 +1,19 @@ + + + + + + + + + Resonances + 500 + adaptive + 1000000000 + 1e-9 + + false + + diff --git a/config/DMRESXSecFast.xml b/config/DMRESXSecFast.xml new file mode 100644 index 0000000000..10ea7583f7 --- /dev/null +++ b/config/DMRESXSecFast.xml @@ -0,0 +1,19 @@ + + + + + + + + + Resonances + 500 + adaptive + 1000000000 + 1e-9 + + false + + diff --git a/config/EventGenerator.xml b/config/EventGenerator.xml index 9187896319..1b77db6b18 100644 --- a/config/EventGenerator.xml +++ b/config/EventGenerator.xml @@ -114,6 +114,37 @@ XSecModel alg Yes Cross section model used at the thread genie::DMDISInteractionListGenerator/DM-Default + @@ -847,7 +894,7 @@ XSecModel alg Yes Cross section model used at the thread - + 4 @@ -858,7 +905,7 @@ XSecModel alg Yes Cross section model used at the thread genie::DummyHNLInteractionListGenerator/Default - + 3 @@ -868,5 +915,5 @@ XSecModel alg Yes Cross section model used at the thread genie::NormInteractionListGenerator/Default genie::NormXSec/Default - + diff --git a/config/EventGeneratorListAssembler.xml b/config/EventGeneratorListAssembler.xml index 8f98d98d40..b2e6e78495 100644 --- a/config/EventGeneratorListAssembler.xml +++ b/config/EventGeneratorListAssembler.xml @@ -7,31 +7,31 @@ .......................................................................................................................... NOTE: -The GENIE authors would like to caution users against using anything but a comprehensive +The GENIE authors would like to caution users against using anything but a comprehensive GENIE mode (`Default' setting below) for physics studies. No detector measures generator-level reaction modes like CCQE or NCRES. -Detectors measure final states / topologies like {1mu-,0pi}, {1mu-,1pi+}, {0mu-, 1pi0}, +Detectors measure final states / topologies like {1mu-,0pi}, {1mu-,1pi+}, {0mu-, 1pi0}, {1 track, 1 shower}, {1 mu-like ring} etc depending on granularity, thresholds and PID capabilities. No final state / topology is a proxy for any particular reaction mode. Intranuclear re-scattering in particular causes significant migration between states (see Table 8.1 in the Physics and User manual). -The Default configuration depends on the tune and it is defined in TuneGeneratorList.xml, +The Default configuration depends on the tune and it is defined in TuneGeneratorList.xml, which is defined in each Tune subdirectory. Examples: - {1mu-,0pi} is mostly numuCCQE, but can also be caused by numu resonance production followed by pion absorption. - numuCCQE gives mostly {1mu-,0pi} but occasionaly can give {1mu-,1pi} if the recoil nucleon re-interacts. -- NC1pi0 final states can be caused by all a) NC elastic followed by nucleon rescattering, +- NC1pi0 final states can be caused by all a) NC elastic followed by nucleon rescattering, b) NC resonance neutrino-production, c) NC non-resonance background, d) low-W NC DIS e) NC coherent scattering. Each source contributes differently in the pion momentum distribution. -We also recommend that you treat the generator-level reaction modes largely as as an internal degree of freedom. +We also recommend that you treat the generator-level reaction modes largely as as an internal degree of freedom. Consequently, try to define your selection efficiencies and purities in terms of observable final states _only_. For example, if you define as `numuCCQE-like' := {1mu-,0pi} then define your selection efficiency as: efficiency = (`numuCCQE-like' events passing cuts) / (all true {1mu-,0pi} events) -and not as: +and not as: efficiency = (`numuCCQE-like' events passing cuts) / (all true numuCCQE events) .......................................................................................................................... @@ -47,44 +47,44 @@ Generator-%d alg No --> - + 1 genie::EventGenerator/AM-NUGAMMA - + 1 genie::EventGenerator/CEvNS - + 2 genie::EventGenerator/DFR-CC genie::EventGenerator/DFR-NC - + 1 genie::EventGenerator/DFR-CC - + 1 genie::EventGenerator/DFR-NC - + 2 genie::EventGenerator/QEL-CC-CHARM genie::EventGenerator/DIS-CC-CHARM - + 1 genie::EventGenerator/DIS-CC-CHARM - + 1 genie::EventGenerator/QEL-CC-CHARM @@ -103,48 +103,48 @@ Generator-%d alg No 1 genie::EventGenerator/IBD - - + + 2 genie::EventGenerator/IMD genie::EventGenerator/IMD-ANH - + 1 genie::EventGenerator/NUE-EL - + 3 genie::EventGenerator/NUE-EL genie::EventGenerator/IMD genie::EventGenerator/IMD-ANH - + 2 genie::EventGenerator/QEL-CC genie::EventGenerator/QEL-NC - + 1 genie::EventGenerator/QEL-CC - + 1 genie::EventGenerator/QEL-NC - + 1 genie::EventGenerator/MEC-CC - + 1 genie::EventGenerator/MEC-NC @@ -156,13 +156,13 @@ Generator-%d alg No - + 2 genie::EventGenerator/MEC-CC genie::EventGenerator/QEL-CC - + 2 genie::EventGenerator/MEC-NC genie::EventGenerator/QEL-NC @@ -174,55 +174,55 @@ Generator-%d alg No genie::EventGenerator/QEL-EM - + 2 genie::EventGenerator/RES-CC genie::EventGenerator/RES-NC - + 1 genie::EventGenerator/RES-CC - + 1 genie::EventGenerator/RES-NC - + 2 genie::EventGenerator/COH-CC-PION genie::EventGenerator/COH-NC-PION - + 1 genie::EventGenerator/COH-CC-PION - + 1 genie::EventGenerator/COH-NC-PION - + 2 genie::EventGenerator/DIS-CC genie::EventGenerator/DIS-NC - + 1 genie::EventGenerator/DIS-CC - + 1 genie::EventGenerator/DIS-NC - + 6 genie::EventGenerator/QEL-NC genie::EventGenerator/RES-NC @@ -232,7 +232,7 @@ Generator-%d alg No genie::EventGenerator/DFR-NC - + 9 genie::EventGenerator/QEL-CC genie::EventGenerator/RES-CC @@ -245,7 +245,7 @@ Generator-%d alg No genie::EventGenerator/QEL-CC-LAMBDA - + 5 genie::EventGenerator/QEL-CC genie::EventGenerator/RES-CC @@ -266,26 +266,26 @@ Generator-%d alg No genie::EventGenerator/NUE-EL - - + 1 genie::EventGenerator/QEL-EM - + 1 genie::EventGenerator/MEC-EM - + 1 genie::EventGenerator/RES-EM - + 1 genie::EventGenerator/DIS-EM @@ -293,7 +293,7 @@ Generator-%d alg No - + 4 genie::EventGenerator/QEL-EM genie::EventGenerator/RES-EM @@ -301,11 +301,11 @@ Generator-%d alg No genie::EventGenerator/MEC-EM - - + 2 genie::EventGenerator/RES-CC genie::EventGenerator/DIS-CC @@ -313,7 +313,7 @@ Generator-%d alg No - + 9 genie::EventGenerator/QEL-CC @@ -323,8 +323,8 @@ Generator-%d alg No genie::EventGenerator/IMD-ANH genie::EventGenerator/QEL-CC-LAMBDA genie::EventGenerator/DIS-CC-SINGLEK - genie::EventGenerator/QEL-CC-CHARM - genie::EventGenerator/DIS-CC-CHARM + genie::EventGenerator/QEL-CC-CHARM + genie::EventGenerator/DIS-CC-CHARM @@ -379,7 +379,7 @@ Generator-%d alg No genie::EventGenerator/QEL-CC-LAMBDA genie::EventGenerator/DIS-CC-SINGLEK genie::EventGenerator/MEC-CC - genie::EventGenerator/MEC-NC + genie::EventGenerator/MEC-NC genie::EventGenerator/QEL-CC-CHARM genie::EventGenerator/DIS-CC-CHARM @@ -397,6 +397,11 @@ Generator-%d alg No genie::EventGenerator/DMDIS + + 1 + genie::EventGenerator/DMRES + + 1 genie::EventGenerator/DME @@ -409,10 +414,11 @@ Generator-%d alg No - 3 + 4 genie::EventGenerator/DMEL genie::EventGenerator/DMDIS genie::EventGenerator/DME + genie::EventGenerator/DMRES @@ -420,10 +426,16 @@ Generator-%d alg No genie::EventGenerator/COHDNu + + 3 + genie::EventGenerator/DMEL + genie::EventGenerator/DMDIS + genie::EventGenerator/DME + - + 13 genie::EventGenerator/HEDIS-CC genie::EventGenerator/HEDIS-NC @@ -440,7 +452,7 @@ Generator-%d alg No genie::EventGenerator/PhotonCOH - + 11 genie::EventGenerator/GLRES-Mu genie::EventGenerator/GLRES-Tau @@ -455,7 +467,7 @@ Generator-%d alg No genie::EventGenerator/PhotonCOH - + 6 genie::EventGenerator/HEDIS-CC genie::EventGenerator/HEDIS-NC @@ -465,7 +477,7 @@ Generator-%d alg No genie::EventGenerator/GLRES-Had - + 5 genie::EventGenerator/HEDIS-CC genie::EventGenerator/GLRES-Mu @@ -474,23 +486,23 @@ Generator-%d alg No genie::EventGenerator/GLRES-Had - + 2 genie::EventGenerator/HEDIS-CC genie::EventGenerator/HEDIS-NC - + 1 genie::EventGenerator/HEDIS-CC - + 1 genie::EventGenerator/HEDIS-NC - + 4 genie::EventGenerator/GLRES-Mu genie::EventGenerator/GLRES-Tau @@ -498,43 +510,43 @@ Generator-%d alg No genie::EventGenerator/GLRES-Had - + 1 genie::EventGenerator/GLRES-Mu - + 1 genie::EventGenerator/GLRES-Tau - + 1 genie::EventGenerator/GLRES-Ele - + 1 genie::EventGenerator/GLRES-Had - + 2 genie::EventGenerator/HENuEl-CC genie::EventGenerator/HENuEl-NC - + 1 genie::EventGenerator/HENuEl-CC - + 1 genie::EventGenerator/HENuEl-NC - + 4 genie::EventGenerator/PhotonRES-Mu genie::EventGenerator/PhotonRES-Tau @@ -542,41 +554,40 @@ Generator-%d alg No genie::EventGenerator/PhotonRES-Had - + 1 genie::EventGenerator/PhotonRES-Mu - + 1 genie::EventGenerator/PhotonRES-Tau - + 1 genie::EventGenerator/PhotonRES-Ele - + 1 genie::EventGenerator/PhotonRES-Had - + 1 genie::EventGenerator/PhotonCOH - + 1 genie::EventGenerator/NORM - - + + 2 genie::EventGenerator/QEL-CC genie::EventGenerator/NORM - diff --git a/config/GDM18_00a/ModelConfiguration.xml b/config/GDM18_00a/ModelConfiguration.xml index e562596913..3b37566680 100644 --- a/config/GDM18_00a/ModelConfiguration.xml +++ b/config/GDM18_00a/ModelConfiguration.xml @@ -4,7 +4,7 @@ - + - - - - + - + genie::ReinSehgalRESPXSec/NoPauliBlock genie::ReinSehgalRESPXSec/NoPauliBlock - genie::ReinSehgalRESPXSec/Default - + genie::ReinSehgalRESPXSec/EM-NoPauliBlock + genie::KNOTunedQPMDISPXSec/Default genie::KNOTunedQPMDISPXSec/Default genie::KNOTunedQPMDISPXSec/Default - genie::ReinSehgalCOHPiPXSec/Default genie::ReinSehgalCOHPiPXSec/Default @@ -138,6 +138,8 @@ University of Liverpool genie::AhrensDMELPXSec/Velocity0 genie::QPMDMDISPXSec/Velocity0 genie::DMElectronPXSec/Velocity0 + genie::DMRESPXSec/Velocity0 + diff --git a/config/GDM18_00a/TuneGeneratorList.xml b/config/GDM18_00a/TuneGeneratorList.xml index 60161680c5..b7b9946f45 100644 --- a/config/GDM18_00a/TuneGeneratorList.xml +++ b/config/GDM18_00a/TuneGeneratorList.xml @@ -9,10 +9,10 @@ This xml files contains the default configuration for the tune .......................................................................................................................... NOTE: -The GENIE authors would like to caution users against using anything but a comprehensive +The GENIE authors would like to caution users against using anything but a comprehensive GENIE mode (`Default' setting below) for physics studies. No detector measures generator-level reaction modes like CCQE or NCRES. -Detectors measure final states / topologies like {1mu-,0pi}, {1mu-,1pi+}, {0mu-, 1pi0}, +Detectors measure final states / topologies like {1mu-,0pi}, {1mu-,1pi+}, {0mu-, 1pi0}, {1 track, 1 shower}, {1 mu-like ring} etc depending on granularity, thresholds and PID capabilities. No final state / topology is a proxy for any particular reaction mode. Intranuclear re-scattering in particular causes significant migration between states @@ -21,16 +21,16 @@ Intranuclear re-scattering in particular causes significant migration between st Examples: - {1mu-,0pi} is mostly numuCCQE, but can also be caused by numu resonance production followed by pion absorption. - numuCCQE gives mostly {1mu-,0pi} but occasionaly can give {1mu-,1pi} if the recoil nucleon re-interacts. -- NC1pi0 final states can be caused by all a) NC elastic followed by nucleon rescattering, +- NC1pi0 final states can be caused by all a) NC elastic followed by nucleon rescattering, b) NC resonance neutrino-production, c) NC non-resonance background, d) low-W NC DIS e) NC coherent scattering. Each source contributes differently in the pion momentum distribution. -We also recommend that you treat the generator-level reaction modes largely as as an internal degree of freedom. +We also recommend that you treat the generator-level reaction modes largely as as an internal degree of freedom. Consequently, try to define your selection efficiencies and purities in terms of observable final states _only_. For example, if you define as `numuCCQE-like' := {1mu-,0pi} then define your selection efficiency as: efficiency = (`numuCCQE-like' events passing cuts) / (all true {1mu-,0pi} events) -and not as: +and not as: efficiency = (`numuCCQE-like' events passing cuts) / (all true numuCCQE events) .......................................................................................................................... @@ -46,12 +46,42 @@ Generator-%d alg No --> - + + 4 + genie::EventGenerator/DMEL + genie::EventGenerator/DMDIS + genie::EventGenerator/DME + genie::EventGenerator/DMRES + + + 3 genie::EventGenerator/DMEL - genie::EventGenerator/DMDIS - genie::EventGenerator/DME + genie::EventGenerator/DMDIS + genie::EventGenerator/DME + + + + 18 + genie::EventGenerator/QEL-CC + genie::EventGenerator/QEL-NC + genie::EventGenerator/RES-CC + genie::EventGenerator/RES-NC + genie::EventGenerator/DIS-CC + genie::EventGenerator/DIS-NC + genie::EventGenerator/COH-CC-PION + genie::EventGenerator/COH-NC-PION + genie::EventGenerator/DIS-CC-CHARM + genie::EventGenerator/QEL-CC-CHARM + genie::EventGenerator/NUE-EL + genie::EventGenerator/IMD + genie::EventGenerator/IMD-ANH + genie::EventGenerator/DFR-CC + genie::EventGenerator/DFR-NC + genie::EventGenerator/QEL-CC-LAMBDA + genie::EventGenerator/MEC-CC + genie::EventGenerator/MEC-NC - + diff --git a/config/GDM18_00b/ModelConfiguration.xml b/config/GDM18_00b/ModelConfiguration.xml index 3d7c2ff72e..0dee032efe 100644 --- a/config/GDM18_00b/ModelConfiguration.xml +++ b/config/GDM18_00b/ModelConfiguration.xml @@ -4,7 +4,7 @@ - + - - - - + - + genie::ReinSehgalRESPXSec/NoPauliBlock genie::ReinSehgalRESPXSec/NoPauliBlock genie::ReinSehgalRESPXSec/Default - + genie::KNOTunedQPMDISPXSec/Default genie::KNOTunedQPMDISPXSec/Default genie::KNOTunedQPMDISPXSec/Default - genie::ReinSehgalCOHPiPXSec/Default genie::ReinSehgalCOHPiPXSec/Default @@ -138,6 +138,8 @@ University of Liverpool genie::AhrensDMELPXSec/Velocity2 genie::QPMDMDISPXSec/Velocity2 genie::DMElectronPXSec/Velocity2 + genie::DMRESPXSec/Velocity2 + diff --git a/config/GDM18_00b/TuneGeneratorList.xml b/config/GDM18_00b/TuneGeneratorList.xml index 60161680c5..3805e309ab 100644 --- a/config/GDM18_00b/TuneGeneratorList.xml +++ b/config/GDM18_00b/TuneGeneratorList.xml @@ -9,10 +9,10 @@ This xml files contains the default configuration for the tune .......................................................................................................................... NOTE: -The GENIE authors would like to caution users against using anything but a comprehensive +The GENIE authors would like to caution users against using anything but a comprehensive GENIE mode (`Default' setting below) for physics studies. No detector measures generator-level reaction modes like CCQE or NCRES. -Detectors measure final states / topologies like {1mu-,0pi}, {1mu-,1pi+}, {0mu-, 1pi0}, +Detectors measure final states / topologies like {1mu-,0pi}, {1mu-,1pi+}, {0mu-, 1pi0}, {1 track, 1 shower}, {1 mu-like ring} etc depending on granularity, thresholds and PID capabilities. No final state / topology is a proxy for any particular reaction mode. Intranuclear re-scattering in particular causes significant migration between states @@ -21,16 +21,16 @@ Intranuclear re-scattering in particular causes significant migration between st Examples: - {1mu-,0pi} is mostly numuCCQE, but can also be caused by numu resonance production followed by pion absorption. - numuCCQE gives mostly {1mu-,0pi} but occasionaly can give {1mu-,1pi} if the recoil nucleon re-interacts. -- NC1pi0 final states can be caused by all a) NC elastic followed by nucleon rescattering, +- NC1pi0 final states can be caused by all a) NC elastic followed by nucleon rescattering, b) NC resonance neutrino-production, c) NC non-resonance background, d) low-W NC DIS e) NC coherent scattering. Each source contributes differently in the pion momentum distribution. -We also recommend that you treat the generator-level reaction modes largely as as an internal degree of freedom. +We also recommend that you treat the generator-level reaction modes largely as as an internal degree of freedom. Consequently, try to define your selection efficiencies and purities in terms of observable final states _only_. For example, if you define as `numuCCQE-like' := {1mu-,0pi} then define your selection efficiency as: efficiency = (`numuCCQE-like' events passing cuts) / (all true {1mu-,0pi} events) -and not as: +and not as: efficiency = (`numuCCQE-like' events passing cuts) / (all true numuCCQE events) .......................................................................................................................... @@ -46,12 +46,41 @@ Generator-%d alg No --> - + + 4 + genie::EventGenerator/DMEL + genie::EventGenerator/DMDIS + genie::EventGenerator/DME + genie::EventGenerator/DMRES + + + 3 genie::EventGenerator/DMEL - genie::EventGenerator/DMDIS - genie::EventGenerator/DME + genie::EventGenerator/DMDIS + genie::EventGenerator/DME - + + 18 + genie::EventGenerator/QEL-CC + genie::EventGenerator/QEL-NC + genie::EventGenerator/RES-CC + genie::EventGenerator/RES-NC + genie::EventGenerator/DIS-CC + genie::EventGenerator/DIS-NC + genie::EventGenerator/COH-CC-PION + genie::EventGenerator/COH-NC-PION + genie::EventGenerator/DIS-CC-CHARM + genie::EventGenerator/QEL-CC-CHARM + genie::EventGenerator/NUE-EL + genie::EventGenerator/IMD + genie::EventGenerator/IMD-ANH + genie::EventGenerator/DFR-CC + genie::EventGenerator/DFR-NC + genie::EventGenerator/QEL-CC-LAMBDA + genie::EventGenerator/MEC-CC + genie::EventGenerator/MEC-NC + + diff --git a/config/HAIntranuke2025.xml b/config/HAIntranuke2025.xml new file mode 100644 index 0000000000..9db9957e63 --- /dev/null +++ b/config/HAIntranuke2025.xml @@ -0,0 +1,80 @@ + + + + + + + + + NUCL + + genie::NuclearModelMap/Default + + + 0.00 + 0.05 + 1.0 + 1.0 + 1.0 + 0.041 + 1.0 + 0.0 + 0.250 + + true + true + true + + + + 0.0 + 0.0 + + + + + + + + diff --git a/config/HNIntranuke2025.xml b/config/HNIntranuke2025.xml new file mode 100644 index 0000000000..bc3952e304 --- /dev/null +++ b/config/HNIntranuke2025.xml @@ -0,0 +1,81 @@ + + + + + + + + NUCL + + genie::NuclearModelMap/Default + + + true + false + true + + 0.00 + 0.05 + 1.0 + 1.0 + 1.0 + 0.075 + 1.0 + 0.250 + + true + true + + 0.0 + 0.0 + + + + + + + diff --git a/config/Messenger.xml b/config/Messenger.xml index 713a15a71f..68723e2a0d 100644 --- a/config/Messenger.xml +++ b/config/Messenger.xml @@ -86,6 +86,13 @@ NOTICE WARN NOTICE + INFO + INFO + WARN + WARN + NOTICE + NOTICE + WARN WARN NOTICE INFO @@ -121,19 +128,19 @@ NOTICE WARN WARN - WARN + WARN WARN WARN - WARN + WARN NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE NOTICE @@ -231,7 +238,7 @@ WARN WARN ERROR - FATAL + FATAL NOTICE NOTICE diff --git a/config/Messenger_inuke_verbose.xml b/config/Messenger_inuke_verbose.xml index e53bb4f358..b2c64edb4c 100644 --- a/config/Messenger_inuke_verbose.xml +++ b/config/Messenger_inuke_verbose.xml @@ -100,18 +100,18 @@ NOTICE INFO INFO - INFO + INFO INFO INFO - NOTICE + NOTICE INFO - NOTICE + NOTICE NOTICE NOTICE - NOTICE + NOTICE INFO INFO - INFO + INFO INFO INFO INFO diff --git a/config/Messenger_laconic.xml b/config/Messenger_laconic.xml index 1cfaf6590e..68ea0e1163 100644 --- a/config/Messenger_laconic.xml +++ b/config/Messenger_laconic.xml @@ -21,7 +21,7 @@ same stream is listed twice with conflicting priority then the one found last is used --> - WARN + WARN WARN WARN WARN @@ -79,6 +79,13 @@ WARN WARN WARN + INFO + INFO + WARN + WARN + NOTICE + NOTICE + WARN WARN WARN WARN @@ -115,19 +122,19 @@ WARN WARN WARN - WARN + WARN WARN WARN - WARN + WARN WARN WARN - WARN + WARN WARN WARN - WARN + WARN WARN WARN - WARN + WARN WARN WARN WARN diff --git a/config/Messenger_rambling.xml b/config/Messenger_rambling.xml index e591abc5e9..96086459dc 100644 --- a/config/Messenger_rambling.xml +++ b/config/Messenger_rambling.xml @@ -80,6 +80,13 @@ NOTICE NOTICE NOTICE + INFO + INFO + WARN + WARN + NOTICE + NOTICE + WARN NOTICE INFO INFO @@ -93,7 +100,7 @@ WARN NOTICE NOTICE - NOTICE + NOTICE INFO INFO WARN @@ -116,20 +123,20 @@ NOTICE NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE - NOTICE + NOTICE NOTICE NOTICE NOTICE diff --git a/config/Messenger_whisper.xml b/config/Messenger_whisper.xml index c8d945a861..82732e5bd5 100644 --- a/config/Messenger_whisper.xml +++ b/config/Messenger_whisper.xml @@ -80,6 +80,13 @@ NOTICE WARN NOTICE + INFO + INFO + WARN + WARN + NOTICE + NOTICE + WARN FATAL FATAL FATAL @@ -116,20 +123,20 @@ FATAL FATAL FATAL - FATAL + FATAL FATAL FATAL - FATAL + FATAL FATAL FATAL FATAL - FATAL + FATAL FATAL FATAL - FATAL + FATAL FATAL FATAL - FATAL + FATAL FATAL FATAL FATAL diff --git a/config/RSHelicityAmplModelDMn.xml b/config/RSHelicityAmplModelDMn.xml new file mode 100644 index 0000000000..49ca01898d --- /dev/null +++ b/config/RSHelicityAmplModelDMn.xml @@ -0,0 +1,18 @@ + + + + + + + + BoostedDarkMatter + + + diff --git a/config/RSHelicityAmplModelDMp.xml b/config/RSHelicityAmplModelDMp.xml new file mode 100644 index 0000000000..4ba3606acd --- /dev/null +++ b/config/RSHelicityAmplModelDMp.xml @@ -0,0 +1,18 @@ + + + + + + + + BoostedDarkMatter + + + diff --git a/config/master_config.xml b/config/master_config.xml index 8bfe6aa53f..0dabf07fe2 100644 --- a/config/master_config.xml +++ b/config/master_config.xml @@ -9,6 +9,8 @@ HAIntranuke.xml HAIntranuke2018.xml HNIntranuke2018.xml + HAIntranuke2025.xml + HNIntranuke2025.xml HINCLCascadeIntranuke.xml HG4BertCascIntranuke.xml CascadeReweight.xml @@ -25,6 +27,7 @@ QELPrimaryLeptonGenerator.xml DISPrimaryLeptonGenerator.xml RESPrimaryLeptonGenerator.xml + DMRESOutgoingDarkGenerator.xml NuEPrimaryLeptonGenerator.xml DMEOutgoingDarkGenerator.xml COHPrimaryLeptonGenerator.xml @@ -43,6 +46,7 @@ SKKinematicsGenerator.xml DMELKinematicsGenerator.xml DMDISKinematicsGenerator.xml + DMRESKinematicsGenerator.xml HELeptonKinematicsGenerator.xml HEDISKinematicsGenerator.xml IBDHadronicSystemGenerator.xml @@ -51,6 +55,7 @@ DFRHadronicSystemGenerator.xml DISHadronicSystemGenerator.xml RESHadronicSystemGenerator.xml + DMRESHadronicSystemGenerator.xml RSPPHadronicSystemGenerator.xml SKHadronicSystemGenerator.xml NuETargetRemnantGenerator.xml @@ -91,6 +96,7 @@ SKInteractionListGenerator.xml DMELInteractionListGenerator.xml DMDISInteractionListGenerator.xml + DMRESInteractionListGenerator.xml IBDInteractionListGenerator.xml CEvNSInteractionListGenerator.xml COHDNuInteractionListGenerator.xml @@ -154,6 +160,8 @@ RSHelicityAmplModelNCn.xml RSHelicityAmplModelEMp.xml RSHelicityAmplModelEMn.xml + RSHelicityAmplModelDMn.xml + RSHelicityAmplModelDMp.xml EngelFormFactor.xml @@ -170,6 +178,7 @@ AlamSimoAtharVacasSKXSec.xml IMDXSec.xml RESXSec.xml + DMRESXSec.xml MECXSec.xml NuElectronXSec.xml DMElectronXSec.xml @@ -207,6 +216,7 @@ PattonCEvNSPXSec.xml NuElectronPXSec.xml DMElectronPXSec.xml + DMRESPXSec.xml GLRESPXSec.xml HENuElPXSec.xml PhotonCOHPXSec.xml @@ -230,6 +240,7 @@ Default.xml Default.xml ReinSehgalRESXSecFast.xml + DMRESXSecFast.xml BertuzzoDNuCOHPXSec.xml HybridXSecAlgorithm.xml HEDISPXSec.xml diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/al_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/al_abs_combined.txt new file mode 100644 index 0000000000..dad34a5fb2 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/al_abs_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 5.0 0.0 +5.0 38.0 0.0 +20.0 134.0 0.0 +50.0 219.0 0.0 +85.0 252.0 40.0 +125.0 340.0 50.0 +165.0 338.0 57.0 +205.0 327.0 57.0 +245.0 218.0 47.0 +315.0 119.0 44.0 +350.0 139.353 2.59927 +400.0 88.9288 2.08718 +450.0 57.2077 1.67945 +500.0 41.1476 1.42666 +550.0 35.4119 1.32426 +600.0 36.7586 1.34902 +650.0 32.0203 1.25968 +700.0 31.0727 1.24102 +750.0 34.0653 1.29901 +800.0 31.8707 1.25675 +850.0 29.5764 1.21095 +900.0 28.1799 1.18218 +950.0 25.0876 1.11578 +1000.0 23.9404 1.0901 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/ar_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/ar_abs_combined.txt new file mode 100644 index 0000000000..9fc07be335 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/ar_abs_combined.txt @@ -0,0 +1,24 @@ +#KE XS sig +1.0 15.0 0.0 +5.0 50.0 0.0 +20.0 206.2 0.0 +50.0 304.3 0.0 +70.0 180.0 43.0 +118.0 320.0 65.0 +162.0 351.0 49.0 +239.0 283.0 28.0 +330.0 225.0 17.0 +350.0 209.294 3.62322 +400.0 139.94 2.97903 +450.0 100.79 2.53601 +500.0 74.2802 2.18161 +550.0 62.1594 1.99758 +600.0 63.1317 2.01299 +650.0 58.076 1.93147 +700.0 58.1408 1.93254 +750.0 60.7983 1.9758 +800.0 58.789 1.94318 +850.0 55.937 1.89588 +900.0 52.5017 1.83724 +950.0 46.4089 1.72816 +1000.0 45.307 1.70767 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/bi_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/bi_abs_combined.txt new file mode 100644 index 0000000000..25e7d5a97a --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/bi_abs_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 221.0 0.0 +50.0 869.0 0.0 +85.0 1659.0 655.0 +125.0 1235.0 230.0 +165.0 1585.0 280.0 +205.0 950.0 160.0 +245.0 854.0 166.0 +315.0 618.0 170.0 +350.0 919.445 13.0765 +400.0 744.963 11.8256 +450.0 639.962 10.9912 +500.0 550.379 10.2171 +550.0 498.659 9.73841 +600.0 485.973 9.61694 +650.0 459.625 9.35908 +700.0 468.212 9.44398 +750.0 427.422 9.03288 +800.0 414.931 8.90283 +850.0 398.927 8.7331 +900.0 402.245 8.76858 +950.0 386.436 8.5981 +1000.0 359.112 8.29447 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/c_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/c_abs_combined.txt new file mode 100644 index 0000000000..f293dd4546 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/c_abs_combined.txt @@ -0,0 +1,30 @@ +#KE XS sig +1.0 0.0 0.0 +4.0 5.1 0.0 +20.0 41.2 0.0 +50.0 95.5 0.0 +85.0 109.0 20.0 +125.0 166.0 26.0 +165.0 194.0 36.0 +205.0 157.0 37.0 +245.0 95.0 32.0 +315.0 64.0 27.0 +105.6 153.8 12.0 +118.1 182.1 19.2 +135.6 160.8 16.6 +160.5 161.4 15.7 +186.9 159.4 15.3 +350.0 53.4176 1.23414 +400.0 29.8023 0.925629 +450.0 17.2249 0.705242 +500.0 12.6064 0.603814 +550.0 9.03364 0.511454 +600.0 7.37796 0.462346 +650.0 7.31987 0.460527 +700.0 7.90081 0.478405 +750.0 7.34891 0.461437 +800.0 8.19128 0.487095 +850.0 8.56889 0.498164 +900.0 7.31987 0.460527 +950.0 6.39036 0.430364 +1000.0 6.18703 0.423477 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/fe_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/fe_abs_combined.txt new file mode 100644 index 0000000000..fbaff408ca --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/fe_abs_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 15.3 0.0 +20.0 218.6 0.0 +50.0 373.5 0.0 +85.0 421.0 70.0 +125.0 527.0 74.0 +165.0 577.0 87.0 +205.0 607.0 86.0 +245.0 411.0 70.0 +315.0 320.0 62.0 +350.0 287.394 4.74198 +400.0 201.168 3.98915 +450.0 154.445 3.50563 +500.0 118.105 3.07258 +550.0 104.964 2.89899 +600.0 102.287 2.86226 +650.0 95.6359 2.76878 +700.0 91.5801 2.71012 +750.0 93.608 2.73962 +800.0 91.5801 2.71012 +850.0 81.5217 2.55857 +900.0 88.3354 2.66222 +950.0 78.926 2.51791 +1000.0 74.2212 2.44243 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/he3_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/he3_abs_combined.txt new file mode 100644 index 0000000000..ef76b7f903 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/he3_abs_combined.txt @@ -0,0 +1,24 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 1.4 0.0 +20.0 11.0 0.0 +50.0 37.0 0.0 +100.0 24.7723 0.528604 +150.0 28.7723 0.568673 +200.0 23.4005 0.514072 +250.0 17.3141 0.443382 +300.0 12.1383 0.372087 +350.0 8.46107 0.311156 +400.0 3.41209 0.19803 +450.0 1.93659 0.149286 +500.0 1.16426 0.11579 +550.0 0.979824 0.106232 +600.0 0.691641 0.0892636 +650.0 0.645531 0.0862386 +700.0 0.622477 0.0846855 +750.0 0.610949 0.0838981 +800.0 0.634004 0.0854656 +850.0 0.576367 0.0814903 +900.0 0.553313 0.0798446 +950.0 0.553313 0.0798446 +1000.0 0.414984 0.0691516 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/li_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/li_abs_combined.txt new file mode 100644 index 0000000000..5948ae254c --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/li_abs_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 44.0 20.0 +125.0 114.0 26.0 +165.0 124.0 30.0 +205.0 59.0 33.0 +245.0 42.0 30.0 +315.0 0.0 0.0 +1.0 15.0 0.0 +5.0 30.0 0.0 +20.0 59.4 0.0 +50.0 75.4 0.0 +350.0 19.25 0.590374 +400.0 9.8629 0.423679 +450.0 5.98362 0.330353 +500.0 4.51973 0.287228 +550.0 3.16564 0.240471 +600.0 2.4154 0.210095 +650.0 2.59839 0.217897 +700.0 2.5069 0.214032 +750.0 2.61669 0.218662 +800.0 2.61669 0.218662 +850.0 2.67158 0.22094 +900.0 2.54349 0.215586 +950.0 1.90305 0.186512 +1000.0 1.79325 0.181057 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/n_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/n_abs_combined.txt new file mode 100644 index 0000000000..6f49c8fdc6 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/n_abs_combined.txt @@ -0,0 +1,2 @@ +#KE XS sig +239 119 10 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/nb_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/nb_abs_combined.txt new file mode 100644 index 0000000000..592a443af2 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/nb_abs_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 324.7 0.0 +50.0 540.7 0.0 +85.0 805.0 143.0 +125.0 925.0 140.0 +165.0 880.0 160.0 +205.0 685.0 100.0 +245.0 440.0 105.0 +315.0 390.0 90.0 +350.0 481.866 7.24519 +400.0 356.167 6.26476 +450.0 284.387 5.6162 +500.0 221.481 4.97031 +550.0 210.788 4.85117 +600.0 190.881 4.62053 +650.0 183.942 4.53717 +700.0 175.183 4.42956 +750.0 167.561 4.33361 +800.0 186.331 4.56605 +850.0 173.704 4.41112 +900.0 156.299 4.18755 +950.0 153.228 4.14676 +1000.0 151.294 4.12087 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip12_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip12_abs.txt new file mode 100644 index 0000000000..901406b869 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip12_abs.txt @@ -0,0 +1,42 @@ +0.0 6.455978 +25.0 40.980631 +50.0 77.028825 +75.0 113.750466 +100.0 145.201299 +125.0 164.980104 +150.0 170.135874 +175.0 163.273128 +200.0 152.262087 +225.0 133.103706 +250.0 113.241520 +275.0 97.647882 +300.0 82.054243 +325.0 66.972608 +350.0 52.658979 +375.0 44.475557 +400.0 36.292136 +425.0 30.354552 +450.0 24.416968 +475.0 19.813004 +500.0 15.209040 +525.0 12.960797 +550.0 10.712554 +575.0 9.780145 +600.0 8.847736 +625.0 8.321987 +650.0 7.796238 +675.0 7.712002 +700.0 7.627766 +725.0 7.746859 +750.0 7.865952 +775.0 7.865952 +800.0 7.865952 +825.0 7.714907 +850.0 7.563862 +875.0 7.447674 +900.0 7.331486 +925.0 7.022135 +950.0 6.712783 +975.0 6.403432 +1000.0 6.094080 +1025.0 5.784729 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip131_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip131_abs.txt new file mode 100644 index 0000000000..9d52dcf44d --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip131_abs.txt @@ -0,0 +1 @@ +239.0 676.000000 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip14_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip14_abs.txt new file mode 100644 index 0000000000..066ef7ff44 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip14_abs.txt @@ -0,0 +1 @@ +239.0 119.000000 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip209_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip209_abs.txt new file mode 100644 index 0000000000..6b6b2b75ea --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip209_abs.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 371.300719 +50.0 711.469045 +75.0 975.524439 +100.0 1148.028014 +125.0 1259.497043 +150.0 1257.686391 +175.0 1210.928625 +200.0 1096.750186 +225.0 1048.278440 +250.0 1007.289542 +275.0 930.525343 +300.0 853.761143 +325.0 793.129889 +350.0 756.698051 +375.0 727.103941 +400.0 697.509831 +425.0 684.095716 +450.0 670.681600 +475.0 627.334400 +500.0 583.987200 +525.0 555.453400 +550.0 526.919600 +575.0 509.744600 +600.0 492.569600 +625.0 480.273900 +650.0 467.978200 +675.0 459.605400 +700.0 451.232600 +725.0 442.528000 +750.0 433.823400 +775.0 428.085400 +800.0 422.347400 +825.0 414.169800 +850.0 405.992200 +875.0 399.161200 +900.0 392.330200 +925.0 386.123750 +950.0 379.917300 +975.0 373.710850 +1000.0 367.504400 +1025.0 361.297950 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip27_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip27_abs.txt new file mode 100644 index 0000000000..b153bd7b65 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip27_abs.txt @@ -0,0 +1,42 @@ +0.0 36.377668 +25.0 108.675490 +50.0 180.654250 +75.0 230.812530 +100.0 267.209154 +125.0 294.431340 +150.0 294.786753 +175.0 290.229322 +200.0 278.302625 +225.0 259.101683 +250.0 236.753342 +275.0 209.089648 +300.0 181.425955 +325.0 153.723917 +350.0 125.964359 +375.0 108.319858 +400.0 90.675357 +425.0 81.542579 +450.0 72.409800 +475.0 62.150360 +500.0 51.890920 +525.0 46.200070 +550.0 40.509220 +575.0 37.895720 +600.0 35.282220 +625.0 34.573990 +650.0 33.865760 +675.0 33.511640 +700.0 33.157520 +725.0 32.439300 +750.0 31.721080 +775.0 31.337040 +800.0 30.953000 +825.0 30.354490 +850.0 29.755980 +875.0 28.743490 +900.0 27.731000 +925.0 26.713530 +950.0 25.696060 +975.0 24.678590 +1000.0 23.661120 +1025.0 22.643650 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip3_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip3_abs.txt new file mode 100644 index 0000000000..314a622eac --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip3_abs.txt @@ -0,0 +1,42 @@ +0.0 4.671263 +25.0 11.755438 +50.0 18.303596 +75.0 21.594818 +100.0 24.886040 +125.0 25.568940 +150.0 26.251840 +175.0 23.765670 +200.0 21.279500 +225.0 19.648377 +250.0 18.017254 +275.0 15.481233 +300.0 12.945212 +325.0 10.798821 +350.0 8.652430 +375.0 7.037446 +400.0 5.422462 +425.0 4.306614 +450.0 3.190767 +475.0 2.413824 +500.0 1.636881 +525.0 1.360225 +550.0 1.083569 +575.0 0.952158 +600.0 0.820747 +625.0 0.765415 +650.0 0.710084 +675.0 0.675502 +700.0 0.640920 +725.0 0.629393 +750.0 0.617866 +775.0 0.608644 +800.0 0.599422 +825.0 0.592506 +850.0 0.585589 +875.0 0.565993 +900.0 0.546396 +925.0 0.523342 +950.0 0.500287 +975.0 0.477232 +1000.0 0.454177 +1025.0 0.431123 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip40_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip40_abs.txt new file mode 100644 index 0000000000..a8c59e6370 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip40_abs.txt @@ -0,0 +1,42 @@ +0.0 67.966712 +25.0 138.663849 +50.0 207.446495 +75.0 261.568135 +100.0 275.188919 +125.0 282.952060 +150.0 275.652690 +175.0 273.155172 +200.0 275.090134 +225.0 277.025096 +250.0 270.316393 +275.0 252.606662 +300.0 234.896932 +325.0 217.187201 +350.0 195.001164 +375.0 175.206307 +400.0 155.411450 +425.0 136.352085 +450.0 117.292720 +475.0 102.676490 +500.0 88.060260 +525.0 79.873860 +550.0 71.687460 +575.0 67.422540 +600.0 63.157620 +625.0 61.809430 +650.0 60.461240 +675.0 60.124200 +700.0 59.787160 +725.0 59.067690 +750.0 58.348220 +775.0 57.790790 +800.0 57.233360 +825.0 56.060170 +850.0 54.886980 +875.0 53.337850 +900.0 51.788720 +925.0 49.964115 +950.0 48.139510 +975.0 46.314905 +1000.0 44.490300 +1025.0 42.665695 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip56_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip56_abs.txt new file mode 100644 index 0000000000..d865195727 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip56_abs.txt @@ -0,0 +1,42 @@ +0.0 38.456145 +25.0 166.025721 +50.0 284.544858 +75.0 377.012015 +100.0 446.063524 +125.0 499.504599 +150.0 505.189225 +175.0 505.519238 +200.0 497.817333 +225.0 478.304754 +250.0 451.934987 +275.0 409.947136 +300.0 367.959286 +325.0 324.078128 +350.0 277.357010 +375.0 248.499373 +400.0 219.641735 +425.0 196.428468 +450.0 173.215200 +475.0 154.704500 +500.0 136.193800 +525.0 125.640590 +550.0 115.087380 +575.0 108.800890 +600.0 102.514400 +625.0 100.064700 +650.0 97.615000 +675.0 96.276610 +700.0 94.938220 +725.0 92.861690 +750.0 90.785160 +775.0 90.055110 +800.0 89.325060 +825.0 88.059650 +850.0 86.794240 +875.0 84.855560 +900.0 82.916880 +925.0 81.051205 +950.0 79.185530 +975.0 77.319855 +1000.0 75.454180 +1025.0 73.588505 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip7_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip7_abs.txt new file mode 100644 index 0000000000..99e1c5c8a5 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip7_abs.txt @@ -0,0 +1,42 @@ +0.0 34.019924 +25.0 44.093802 +50.0 61.108919 +75.0 75.653515 +100.0 82.104049 +125.0 83.158541 +150.0 79.059453 +175.0 75.406087 +200.0 72.421306 +225.0 63.390359 +250.0 52.669351 +275.0 41.234264 +300.0 29.799177 +325.0 20.870132 +350.0 15.700152 +375.0 11.834032 +400.0 7.967911 +425.0 8.262145 +450.0 8.556378 +475.0 6.872918 +500.0 5.189458 +525.0 4.463007 +550.0 3.736556 +575.0 3.388884 +600.0 3.041212 +625.0 2.850908 +650.0 2.660604 +675.0 2.605709 +700.0 2.550814 +725.0 2.576432 +750.0 2.602050 +775.0 2.596560 +800.0 2.591070 +825.0 2.530685 +850.0 2.470300 +875.0 2.387956 +900.0 2.305612 +925.0 2.184842 +950.0 2.064071 +975.0 1.943301 +1000.0 1.822530 +1025.0 1.701760 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip93_abs.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip93_abs.txt new file mode 100644 index 0000000000..feaeb62601 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/pip93_abs.txt @@ -0,0 +1,42 @@ +0.0 21.810276 +25.0 257.793350 +50.0 467.926967 +75.0 618.753041 +100.0 711.774221 +125.0 766.258804 +150.0 754.222052 +175.0 731.032993 +200.0 691.115474 +225.0 641.410509 +250.0 589.402241 +275.0 537.968209 +300.0 486.534177 +325.0 437.452660 +350.0 391.899915 +375.0 371.103643 +400.0 350.307371 +425.0 330.622586 +450.0 310.937800 +475.0 281.839300 +500.0 252.740800 +525.0 235.518300 +550.0 218.295800 +575.0 207.375400 +600.0 196.455000 +625.0 191.063000 +650.0 185.671000 +675.0 183.225300 +700.0 180.779600 +725.0 179.061900 +750.0 177.344200 +775.0 174.579900 +800.0 171.815600 +825.0 169.620100 +850.0 167.424600 +875.0 165.797900 +900.0 164.171200 +925.0 159.643700 +950.0 155.116200 +975.0 150.588700 +1000.0 146.061200 +1025.0 141.533700 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_abs/xe_abs_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/xe_abs_combined.txt new file mode 100644 index 0000000000..2dfd67d02f --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_abs/xe_abs_combined.txt @@ -0,0 +1,2 @@ +#KE XS sig +239 676 94 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/al_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/al_cex_combined.txt new file mode 100644 index 0000000000..3cd6a1577f --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/al_cex_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 55.0 27.0 +125.0 58.0 29.0 +165.0 72.0 36.0 +205.0 58.0 30.0 +245.0 64.0 32.0 +315.0 73.0 36.0 +1.0 0.1 0.0 +5.0 0.18 0.0 +20.0 3.8 0.0 +50.0 24.9 0.0 +350.0 73.0184 1.89434 +400.0 73.5171 1.90071 +450.0 71.1729 1.8706 +500.0 72.9186 1.89307 +550.0 75.562 1.92656 +600.0 71.2228 1.87125 +650.0 58.1055 1.69242 +700.0 50.2251 1.57474 +750.0 48.7787 1.55212 +800.0 52.7189 1.61295 +850.0 58.8037 1.70244 +900.0 50.7238 1.58246 +950.0 49.3772 1.56152 +1000.0 40.6988 1.41892 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/ar_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/ar_cex_combined.txt new file mode 100644 index 0000000000..0b62408901 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/ar_cex_combined.txt @@ -0,0 +1,5 @@ +#KE XS sig +1 0.1 0 +5 0.54 0 +20 9.2 0 +50 48.0 0 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/bi_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/bi_cex_combined.txt new file mode 100644 index 0000000000..626ecacd57 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/bi_cex_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 141.0 70.0 +125.0 165.0 82.0 +165.0 196.0 100.0 +205.0 260.0 130.0 +245.0 276.0 140.0 +315.0 304.0 150.0 +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 19.0 0.0 +50.0 107.0 0.0 +350.0 209.222 6.35579 +400.0 242.206 6.83261 +450.0 245.133 6.87326 +500.0 259.966 7.07543 +550.0 270.505 7.21545 +600.0 268.944 7.19489 +650.0 244.548 6.86515 +700.0 216.053 6.45757 +750.0 215.272 6.44602 +800.0 228.154 6.63386 +850.0 242.986 6.84348 +900.0 222.494 6.55202 +950.0 217.029 6.47198 +1000.0 202.001 6.24631 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/c_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/c_cex_combined.txt new file mode 100644 index 0000000000..36563c9b70 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/c_cex_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 35.0 12.0 +125.0 38.0 12.0 +165.0 46.0 23.0 +205.0 45.0 23.0 +245.0 47.0 23.0 +315.0 45.0 22.0 +1.0 0.0 0.0 +4.0 0.0 0.0 +20.0 0.28 0.0 +50.0 8.5 0.0 +350.0 41.6826 1.09242 +400.0 42.7573 1.10621 +450.0 39.2426 1.06042 +500.0 38.3131 1.04795 +550.0 41.7988 1.09392 +600.0 38.1098 1.04521 +650.0 29.018 0.913493 +700.0 24.3415 0.837331 +750.0 25.3 0.853517 +800.0 25.1548 0.851085 +850.0 27.4205 0.888237 +900.0 27.13 0.883565 +950.0 22.7729 0.810124 +1000.0 18.8516 0.737583 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/fe_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/fe_cex_combined.txt new file mode 100644 index 0000000000..d2070c4ca4 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/fe_cex_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 79.0 40.0 +125.0 83.0 41.0 +165.0 103.0 50.0 +205.0 83.0 40.0 +245.0 95.0 50.0 +315.0 98.0 50.0 +1.0 0.0 0.0 +5.0 0.08 0.0 +20.0 7.2 0.0 +50.0 42.9 0.0 +350.0 113.076 3.00739 +400.0 114.211 3.02224 +450.0 117.051 3.05903 +500.0 121.674 3.11796 +550.0 123.134 3.13633 +600.0 126.784 3.18175 +650.0 107.073 2.92758 +700.0 93.6891 2.74079 +750.0 87.6054 2.65131 +800.0 99.4484 2.82276 +850.0 99.2861 2.82048 +900.0 94.1758 2.74781 +950.0 88.0921 2.65859 +1000.0 80.7105 2.54593 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/he3_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/he3_cex_combined.txt new file mode 100644 index 0000000000..309869c98e --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/he3_cex_combined.txt @@ -0,0 +1,24 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 0.0 0.0 +50.0 2.3 0.0 +70.0 2.7 0.6 +118.0 13.3 1.2 +162.0 24.1 2.0 +239.0 24.1 2.0 +330.0 15.9 1.4 +350.0 10.317 0.343312 +400.0 9.60228 0.331311 +450.0 8.219 0.306705 +500.0 7.9654 0.301969 +550.0 8.16136 0.305635 +600.0 7.66568 0.296272 +650.0 5.92506 0.26067 +700.0 4.81843 0.235184 +750.0 4.74927 0.233497 +800.0 5.54465 0.252206 +850.0 6.00575 0.26243 +900.0 5.24494 0.245327 +950.0 4.21901 0.220127 +1000.0 3.18155 0.191242 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/li_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/li_cex_combined.txt new file mode 100644 index 0000000000..84b9261b60 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/li_cex_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 0.05 0.0 +5.0 0.46 0.0 +20.0 4.1 0.0 +50.0 23.3 0.0 +85.0 31.0 15.0 +125.0 43.0 21.0 +165.0 46.0 23.0 +205.0 54.0 27.0 +245.0 50.0 25.0 +315.0 0.0 0.0 +350.0 30.6134 0.742165 +400.0 26.1852 0.687236 +450.0 23.2025 0.647447 +500.0 22.434 0.63677 +550.0 24.8128 0.669239 +600.0 22.1412 0.632652 +650.0 17.8411 0.568579 +700.0 13.7971 0.500562 +750.0 13.1932 0.489567 +800.0 15.4257 0.529044 +850.0 17.1823 0.558085 +900.0 16.798 0.551867 +950.0 13.2115 0.489904 +1000.0 11.2536 0.452391 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/nb_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/nb_cex_combined.txt new file mode 100644 index 0000000000..6ffeb83947 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/nb_cex_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 100.0 50.0 +125.0 105.0 52.0 +165.0 130.0 65.0 +205.0 130.0 65.0 +245.0 170.0 85.0 +315.0 154.0 80.0 +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 14.0 0.0 +50.0 65.0 0.0 +350.0 142.421 3.99979 +400.0 149.702 4.09941 +450.0 159.257 4.22642 +500.0 169.609 4.35961 +550.0 171.656 4.38544 +600.0 165.969 4.31327 +650.0 151.635 4.12545 +700.0 131.615 3.84689 +750.0 127.974 3.79394 +800.0 139.236 3.95537 +850.0 137.757 3.93457 +900.0 136.278 3.91365 +950.0 127.064 3.78057 +1000.0 114.21 3.5863 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/o_cex_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/o_cex_combined.txt new file mode 100644 index 0000000000..6548828ba1 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/o_cex_combined.txt @@ -0,0 +1,2 @@ +#KE XS sig +100.0 66.0 10.0 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip12_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip12_cex.txt new file mode 100644 index 0000000000..196c4e0160 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip12_cex.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 5.618014 +50.0 13.878380 +75.0 21.284997 +100.0 28.012695 +125.0 34.287779 +150.0 39.232917 +175.0 42.656506 +200.0 43.797770 +225.0 44.581468 +250.0 45.059311 +275.0 44.671297 +300.0 44.283283 +325.0 43.809655 +350.0 43.207607 +375.0 42.353184 +400.0 41.498761 +425.0 41.128820 +450.0 40.758880 +475.0 40.401600 +500.0 40.044320 +525.0 38.670390 +550.0 37.296460 +575.0 35.806350 +600.0 34.316240 +625.0 33.014930 +650.0 31.713620 +675.0 30.049220 +700.0 28.384820 +725.0 27.315890 +750.0 26.246960 +775.0 26.058160 +800.0 25.869360 +825.0 25.712500 +850.0 25.555640 +875.0 24.910800 +900.0 24.265960 +925.0 23.403260 +950.0 22.540560 +975.0 21.677860 +1000.0 20.815160 +1025.0 19.952460 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip16_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip16_cex.txt new file mode 100644 index 0000000000..ddc1756296 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip16_cex.txt @@ -0,0 +1 @@ +100.0 66.000000 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip209_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip209_cex.txt new file mode 100644 index 0000000000..bff6986e00 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip209_cex.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 38.557839 +50.0 76.325289 +75.0 108.361344 +100.0 140.562302 +125.0 172.873193 +150.0 194.577447 +175.0 214.618448 +200.0 232.164568 +225.0 241.540495 +250.0 248.027820 +275.0 251.130932 +300.0 254.234044 +325.0 256.000225 +350.0 255.761009 +375.0 254.056926 +400.0 252.352843 +425.0 248.879622 +450.0 245.406400 +475.0 251.378600 +500.0 257.350800 +525.0 257.585000 +550.0 257.819200 +575.0 254.911200 +600.0 252.003200 +625.0 247.533800 +650.0 243.064400 +675.0 238.829300 +700.0 234.594200 +725.0 231.998400 +750.0 229.402600 +775.0 227.197200 +800.0 224.991800 +825.0 225.089400 +850.0 225.187000 +875.0 223.859900 +900.0 222.532800 +925.0 218.619650 +950.0 214.706500 +975.0 210.793350 +1000.0 206.880200 +1025.0 202.967050 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip27_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip27_cex.txt new file mode 100644 index 0000000000..9bb4ad7d26 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip27_cex.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 11.354138 +50.0 24.586055 +75.0 36.248169 +100.0 45.584670 +125.0 53.370762 +150.0 58.389036 +175.0 62.221933 +200.0 64.276766 +225.0 66.120062 +250.0 67.677111 +275.0 68.300706 +300.0 68.924301 +325.0 69.749263 +350.0 70.876275 +375.0 71.807350 +400.0 72.738425 +425.0 72.988112 +450.0 73.237800 +475.0 73.058240 +500.0 72.878680 +525.0 71.337520 +550.0 69.796360 +575.0 67.701580 +600.0 65.606800 +625.0 63.192810 +650.0 60.778820 +675.0 58.494510 +700.0 56.210200 +725.0 54.968290 +750.0 53.726380 +775.0 52.988210 +800.0 52.250040 +825.0 52.165250 +850.0 52.080460 +875.0 51.272470 +900.0 50.464480 +925.0 48.791145 +950.0 47.117810 +975.0 45.444475 +1000.0 43.771140 +1025.0 42.097805 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip3_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip3_cex.txt new file mode 100644 index 0000000000..b5799ef983 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip3_cex.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 1.053474 +50.0 3.360812 +75.0 6.656912 +100.0 9.767197 +125.0 12.484986 +150.0 14.193501 +175.0 15.443794 +200.0 16.271111 +225.0 17.098428 +250.0 17.184449 +275.0 16.327001 +300.0 15.469553 +325.0 14.612106 +350.0 13.922304 +375.0 12.273089 +400.0 10.623875 +425.0 9.738441 +450.0 8.853008 +475.0 8.587876 +500.0 8.322744 +525.0 7.955022 +550.0 7.587300 +575.0 7.247243 +600.0 6.907186 +625.0 6.585573 +650.0 6.263960 +675.0 6.002289 +700.0 5.740618 +725.0 5.574625 +750.0 5.408632 +775.0 5.340620 +800.0 5.272608 +825.0 5.212666 +850.0 5.152724 +875.0 4.995952 +900.0 4.839180 +925.0 4.513533 +950.0 4.187886 +975.0 3.862239 +1000.0 3.536592 +1025.0 3.210945 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip40_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip40_cex.txt new file mode 100644 index 0000000000..276e31553f --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip40_cex.txt @@ -0,0 +1,4 @@ +1.0 0.100000 +5.0 0.540000 +20.0 9.200000 +50.0 48.000000 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip56_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip56_cex.txt new file mode 100644 index 0000000000..56a711c732 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip56_cex.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 17.793867 +50.0 37.084900 +75.0 53.829845 +100.0 67.049042 +125.0 77.917740 +150.0 84.594152 +175.0 89.476952 +200.0 91.669331 +225.0 94.846375 +250.0 97.940447 +275.0 99.717963 +300.0 101.495479 +325.0 103.895751 +350.0 107.230158 +375.0 109.857750 +400.0 112.485342 +425.0 115.157271 +450.0 117.829200 +475.0 119.200000 +500.0 120.570800 +525.0 119.857000 +550.0 119.143200 +575.0 116.807010 +600.0 114.470820 +625.0 111.063960 +650.0 107.657100 +675.0 105.288540 +700.0 102.919980 +725.0 100.170190 +750.0 97.420400 +775.0 96.130680 +800.0 94.840960 +825.0 94.281260 +850.0 93.721560 +875.0 93.032070 +900.0 92.342580 +925.0 89.909090 +950.0 87.475600 +975.0 85.042110 +1000.0 82.608620 +1025.0 80.175130 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip7_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip7_cex.txt new file mode 100644 index 0000000000..8b1809d789 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip7_cex.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 8.722758 +50.0 17.835488 +75.0 25.356245 +100.0 32.452037 +125.0 39.264520 +150.0 42.724195 +175.0 43.559340 +200.0 40.457691 +225.0 39.067836 +250.0 37.713811 +275.0 34.791308 +300.0 31.868804 +325.0 28.983016 +350.0 26.152302 +375.0 23.213785 +400.0 20.275268 +425.0 22.862424 +450.0 25.449580 +475.0 24.602360 +500.0 23.755140 +525.0 22.920730 +550.0 22.086320 +575.0 21.145780 +600.0 20.205240 +625.0 19.281160 +650.0 18.357080 +675.0 17.418370 +700.0 16.479660 +725.0 15.983770 +750.0 15.487880 +775.0 15.383570 +800.0 15.279260 +825.0 15.220700 +850.0 15.162140 +875.0 14.968180 +900.0 14.774220 +925.0 14.158470 +950.0 13.542720 +975.0 12.926970 +1000.0 12.311220 +1025.0 11.695470 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip93_cex.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip93_cex.txt new file mode 100644 index 0000000000..1d5ec9ef4c --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/pip93_cex.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 25.375815 +50.0 50.213536 +75.0 71.404103 +100.0 89.522569 +125.0 105.592970 +150.0 118.972364 +175.0 129.281366 +200.0 134.984782 +225.0 140.199272 +250.0 144.642804 +275.0 146.491421 +300.0 148.340038 +325.0 151.088750 +350.0 155.187602 +375.0 154.931222 +400.0 154.674842 +425.0 156.601921 +450.0 158.529000 +475.0 160.883800 +500.0 163.238600 +525.0 163.431900 +550.0 163.625200 +575.0 160.861000 +600.0 158.096800 +625.0 153.933300 +650.0 149.769800 +675.0 146.527800 +700.0 143.285800 +725.0 140.464600 +750.0 137.643400 +775.0 136.107700 +800.0 134.572000 +825.0 134.116900 +850.0 133.661800 +875.0 132.285400 +900.0 130.909000 +925.0 127.871750 +950.0 124.834500 +975.0 121.797250 +1000.0 118.760000 +1025.0 115.722750 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_cex/various-pip-c-cex.dat b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/various-pip-c-cex.dat new file mode 100644 index 0000000000..54aa5f1afd --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_cex/various-pip-c-cex.dat @@ -0,0 +1,8 @@ +# values from Dytman calculations using various authors +# inel: various +# elas: saunders +# abs: navon +# cex: navon, bowles +# KE (MeV) sig (mb) +0.0 5 +50.0 18 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/al_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/al_inelas_combined.txt new file mode 100644 index 0000000000..a766a054e9 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/al_inelas_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 331.0 56.0 +125.0 342.0 70.0 +165.0 321.0 72.0 +205.0 269.0 72.0 +245.0 296.0 62.0 +315.0 307.0 54.0 +1.0 0.05 0.0 +5.0 0.23 0.0 +20.0 14.8 0.0 +50.0 105.5 0.0 +350.0 218.008 3.2246 +400.0 195.314 3.05941 +450.0 180.8 2.948 +500.0 177.459 2.92164 +550.0 172.621 2.88299 +600.0 175.264 2.90418 +650.0 157.907 2.7616 +700.0 132.77 2.53885 +750.0 132.371 2.53513 +800.0 154.815 2.7353 +850.0 166.336 2.83187 +900.0 168.88 2.85269 +950.0 155.613 2.74211 +1000.0 147.034 2.66782 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/ar_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/ar_inelas_combined.txt new file mode 100644 index 0000000000..554e72b9da --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/ar_inelas_combined.txt @@ -0,0 +1,5 @@ +#KE XS sig +1 0.01 0 +5 0.38 0 +20 29.2 0 +50 156.4 0 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/bi_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/bi_inelas_combined.txt new file mode 100644 index 0000000000..b5f3cd7682 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/bi_inelas_combined.txt @@ -0,0 +1,24 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 22.9 0.0 +50.0 273.5 0.0 +125.0 1257.0 535.0 +165.0 696.0 500.0 +205.0 1060.0 440.0 +245.0 1100.0 390.0 +315.0 1028.0 380.0 +350.0 469.383 9.45549 +400.0 444.792 9.21041 +450.0 477.385 9.53374 +500.0 484.607 9.60376 +550.0 489.291 9.64887 +600.0 495.926 9.71239 +650.0 473.482 9.49566 +700.0 440.889 9.17084 +750.0 439.132 9.15298 +800.0 465.285 9.41513 +850.0 498.854 9.74026 +900.0 513.101 9.87467 +950.0 487.144 9.62822 +1000.0 457.478 9.33772 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/c_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/c_inelas_combined.txt new file mode 100644 index 0000000000..be3c23c2a3 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/c_inelas_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 0.0 0.0 +4.0 0.0 0.0 +20.0 0.3 0.0 +50.0 27.6 0.0 +85.0 143.0 26.0 +125.0 213.0 33.0 +165.0 207.0 33.0 +205.0 210.0 51.0 +245.0 224.0 30.0 +315.0 200.0 22.0 +350.0 142.999 1.98726 +400.0 115.52 1.79501 +450.0 109.449 1.74911 +500.0 99.312 1.66916 +550.0 100.474 1.67855 +600.0 96.2621 1.64422 +650.0 84.498 1.5437 +700.0 74.1863 1.44909 +750.0 75.4353 1.46091 +800.0 86.9089 1.5649 +850.0 95.1002 1.63461 +900.0 96.872 1.64924 +950.0 90.5688 1.59648 +1000.0 85.6308 1.55371 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/fe_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/fe_inelas_combined.txt new file mode 100644 index 0000000000..c35b4cddfc --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/fe_inelas_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 0.04 0.0 +20.0 21.8 0.0 +50.0 159.5 0.0 +85.0 784.0 115.0 +125.0 644.0 123.0 +165.0 474.0 130.0 +205.0 360.0 125.0 +245.0 430.0 110.0 +315.0 389.0 100.0 +350.0 313.757 4.94634 +400.0 290.315 4.76512 +450.0 277.742 4.66454 +500.0 274.254 4.63619 +550.0 274.254 4.63619 +600.0 280.418 4.68616 +650.0 250.649 4.43885 +700.0 223.718 4.20079 +750.0 223.232 4.19635 +800.0 254.218 4.46933 +850.0 264.682 4.55735 +900.0 273.118 4.62691 +950.0 258.679 4.5071 +1000.0 231.262 4.26899 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/he3_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/he3_inelas_combined.txt new file mode 100644 index 0000000000..ef82f2a7d1 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/he3_inelas_combined.txt @@ -0,0 +1,24 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 0.0 0.0 +50.0 5.0 0.0 +100.0 28.0806 0.561969 +150.0 87.7923 0.966921 +200.0 101.856 1.03459 +250.0 85.775 0.956653 +300.0 74.9047 0.898524 +350.0 67.9883 0.858778 +400.0 46.8702 0.719945 +450.0 40.1613 0.668449 +500.0 35.0431 0.625839 +550.0 32.6916 0.605111 +600.0 30.6743 0.586672 +650.0 25.8558 0.539781 +700.0 21.2103 0.489898 +750.0 23.1815 0.51171 +800.0 27.7809 0.559037 +850.0 32.242 0.601057 +900.0 32.8299 0.606352 +950.0 30.3976 0.584092 +1000.0 28.4149 0.565221 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/li_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/li_inelas_combined.txt new file mode 100644 index 0000000000..2cd2468659 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/li_inelas_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 74.0 18.0 +125.0 131.0 23.0 +165.0 191.0 26.0 +205.0 230.0 24.0 +245.0 209.0 19.0 +315.0 188.0 34.0 +1.0 0.01 0.0 +5.0 0.21 0.0 +20.0 8.7 0.0 +50.0 73.5 0.0 +350.0 105.875 1.35102 +400.0 79.196 1.17748 +450.0 68.3084 1.09694 +500.0 63.7154 1.0608 +550.0 62.8188 1.05358 +600.0 62.709 1.05269 +650.0 53.944 0.978773 +700.0 46.6429 0.911998 +750.0 48.6741 0.931113 +800.0 59.3055 1.02471 +850.0 67.1007 1.08757 +900.0 66.936 1.08629 +950.0 62.5809 1.05165 +1000.0 57.5122 1.00961 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/nb_inelas_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/nb_inelas_combined.txt new file mode 100644 index 0000000000..a5fba324c3 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/nb_inelas_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 848.0 350.0 +125.0 652.0 270.0 +165.0 552.0 280.0 +205.0 618.0 250.0 +245.0 690.0 240.0 +315.0 579.0 220.0 +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 34.0 0.0 +50.0 209.4 0.0 +350.0 345.019 6.16905 +400.0 339.559 6.12156 +450.0 338.535 6.11261 +500.0 348.659 6.20049 +550.0 348.773 6.20147 +600.0 335.577 6.08666 +650.0 316.125 5.91282 +700.0 291.554 5.68469 +750.0 282.681 5.59976 +800.0 329.662 6.03439 +850.0 334.781 6.07966 +900.0 336.146 6.09166 +950.0 314.191 5.89522 +1000.0 312.712 5.88173 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip12_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip12_inelas.txt new file mode 100644 index 0000000000..4bd7172a44 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip12_inelas.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 23.046597 +50.0 63.821634 +75.0 98.005187 +100.0 129.437854 +125.0 159.036597 +150.0 184.263724 +175.0 202.297677 +200.0 209.541868 +225.0 205.491738 +250.0 197.998749 +275.0 188.028651 +300.0 178.058553 +325.0 168.522547 +350.0 159.637679 +375.0 147.273720 +400.0 134.909761 +425.0 124.230281 +450.0 113.550800 +475.0 108.877110 +500.0 104.203420 +525.0 101.101220 +550.0 97.999020 +575.0 94.472750 +600.0 90.946480 +625.0 88.558810 +650.0 86.171140 +675.0 84.814630 +700.0 83.458120 +725.0 83.341930 +750.0 83.225740 +775.0 84.463140 +800.0 85.700540 +825.0 87.338790 +850.0 88.977040 +875.0 89.996590 +900.0 91.016140 +925.0 90.661760 +950.0 90.307380 +975.0 89.953000 +1000.0 89.598620 +1025.0 89.244240 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip209_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip209_inelas.txt new file mode 100644 index 0000000000..bf34bfb67f --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip209_inelas.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 134.524897 +50.0 303.329482 +75.0 444.482059 +100.0 585.634636 +125.0 726.787213 +150.0 836.236663 +175.0 933.630726 +200.0 1012.941707 +225.0 955.570912 +250.0 874.792090 +275.0 837.062939 +300.0 799.333788 +325.0 757.946675 +350.0 711.072616 +375.0 649.147217 +400.0 587.221818 +425.0 530.156709 +450.0 473.091600 +475.0 475.745900 +500.0 478.400200 +525.0 481.269200 +550.0 484.138200 +575.0 480.488600 +600.0 476.839000 +625.0 472.291500 +650.0 467.744000 +675.0 465.343400 +700.0 462.942800 +725.0 463.235600 +750.0 463.528400 +775.0 467.490300 +800.0 471.452200 +825.0 476.077700 +850.0 480.703200 +875.0 482.537800 +900.0 484.372400 +925.0 483.006200 +950.0 481.640000 +975.0 480.273800 +1000.0 478.907600 +1025.0 477.541400 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip27_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip27_inelas.txt new file mode 100644 index 0000000000..4bd7c705c2 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip27_inelas.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 58.659614 +50.0 135.769843 +75.0 191.513095 +100.0 235.977301 +125.0 272.922142 +150.0 297.220803 +175.0 310.864870 +200.0 308.527045 +225.0 296.918334 +250.0 283.357001 +275.0 271.256065 +300.0 259.155128 +325.0 248.710000 +350.0 240.748585 +375.0 229.141674 +400.0 217.534763 +425.0 203.187582 +450.0 188.840400 +475.0 184.566000 +500.0 180.291600 +525.0 176.550900 +550.0 172.810200 +575.0 168.007200 +600.0 163.204200 +625.0 158.695400 +650.0 154.186600 +675.0 152.406000 +700.0 150.625400 +725.0 149.732600 +750.0 148.839800 +775.0 149.937100 +800.0 151.034400 +825.0 153.318700 +850.0 155.603000 +875.0 157.069300 +900.0 158.535600 +925.0 157.221350 +950.0 155.907100 +975.0 154.592850 +1000.0 153.278600 +1025.0 151.964350 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip3_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip3_inelas.txt new file mode 100644 index 0000000000..3d923e78d6 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip3_inelas.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 4.515613 +50.0 15.394685 +75.0 28.709979 +100.0 42.025274 +125.0 51.863027 +150.0 61.700780 +175.0 68.691250 +200.0 75.681720 +225.0 79.672490 +250.0 83.663260 +275.0 79.571050 +300.0 75.478840 +325.0 69.309370 +350.0 63.139900 +375.0 58.066710 +400.0 52.993520 +425.0 48.772210 +450.0 44.550900 +475.0 40.819500 +500.0 37.088100 +525.0 34.986660 +550.0 32.885220 +575.0 30.990120 +600.0 29.095020 +625.0 27.908860 +650.0 26.722700 +675.0 26.231630 +700.0 25.740560 +725.0 25.897330 +750.0 26.054100 +775.0 26.751510 +800.0 27.448920 +825.0 28.367650 +850.0 29.286380 +875.0 29.809720 +900.0 30.333060 +925.0 30.304240 +950.0 30.275420 +975.0 30.246600 +1000.0 30.217780 +1025.0 30.188960 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip40_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip40_inelas.txt new file mode 100644 index 0000000000..bcba698b17 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip40_inelas.txt @@ -0,0 +1,4 @@ +1.0 0.010000 +5.0 0.380000 +20.0 29.200000 +50.0 156.400000 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip56_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip56_inelas.txt new file mode 100644 index 0000000000..5e9f14a8c9 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip56_inelas.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 116.724276 +50.0 274.991637 +75.0 365.851601 +100.0 432.935070 +125.0 484.167543 +150.0 518.062829 +175.0 520.341822 +200.0 475.196375 +225.0 433.009306 +250.0 396.324702 +275.0 378.691585 +300.0 361.058468 +325.0 347.990511 +350.0 341.770295 +375.0 326.208599 +400.0 310.646903 +425.0 298.355652 +450.0 286.064400 +475.0 282.730500 +500.0 279.396600 +525.0 275.430000 +550.0 271.463400 +575.0 266.061000 +600.0 260.658600 +625.0 255.556400 +650.0 250.454200 +675.0 248.450600 +700.0 246.447000 +725.0 244.873400 +750.0 243.299800 +775.0 245.546700 +800.0 247.793600 +825.0 251.289700 +850.0 254.785800 +875.0 255.588800 +900.0 256.391800 +925.0 253.796050 +950.0 251.200300 +975.0 248.604550 +1000.0 246.008800 +1025.0 243.413050 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip7_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip7_inelas.txt new file mode 100644 index 0000000000..6c4f052fb7 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip7_inelas.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 23.963741 +50.0 50.039318 +75.0 79.305496 +100.0 108.929375 +125.0 138.791721 +150.0 156.421896 +175.0 172.335734 +200.0 185.675070 +225.0 189.003721 +250.0 187.033593 +275.0 173.879032 +300.0 160.724471 +325.0 146.769901 +350.0 131.615315 +375.0 117.196448 +400.0 102.777581 +425.0 89.380151 +450.0 75.982720 +475.0 71.666120 +500.0 67.349520 +525.0 64.824320 +550.0 62.299120 +575.0 60.132570 +600.0 57.966020 +625.0 56.461890 +650.0 54.957760 +675.0 54.606430 +700.0 54.255100 +725.0 54.694270 +750.0 55.133440 +775.0 56.432640 +800.0 57.731840 +825.0 59.325640 +850.0 60.919440 +875.0 61.803250 +900.0 62.687060 +925.0 62.281740 +950.0 61.876420 +975.0 61.471100 +1000.0 61.065780 +1025.0 60.660460 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip93_inelas.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip93_inelas.txt new file mode 100644 index 0000000000..f3dcc94665 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_inelas/pip93_inelas.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 133.582085 +50.0 300.674397 +75.0 402.811661 +100.0 492.778086 +125.0 574.630618 +150.0 635.486482 +175.0 658.654275 +200.0 625.289963 +225.0 593.075359 +250.0 562.190552 +275.0 535.475224 +300.0 508.759896 +325.0 484.002102 +350.0 462.180609 +375.0 427.555621 +400.0 392.930633 +425.0 368.519817 +450.0 344.109000 +475.0 343.164800 +500.0 342.220600 +525.0 339.877200 +550.0 337.533800 +575.0 332.835700 +600.0 328.137600 +625.0 321.539800 +650.0 314.942000 +675.0 313.030900 +700.0 311.119800 +725.0 311.040200 +750.0 310.960600 +775.0 312.962700 +800.0 314.964800 +825.0 317.228500 +850.0 319.492200 +875.0 322.495300 +900.0 325.498400 +925.0 322.773900 +950.0 320.049400 +975.0 317.324900 +1000.0 314.600400 +1025.0 311.875900 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/al_pipro_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/al_pipro_combined.txt new file mode 100644 index 0000000000..f45555d112 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/al_pipro_combined.txt @@ -0,0 +1,21 @@ +#KE XS sig +50.0 1.2469 0.249348 +100.0 1.94516 0.311414 +150.0 4.03995 0.448701 +200.0 8.92779 0.666697 +250.0 11.3717 0.752251 +300.0 10.6734 0.728841 +350.0 10.5737 0.725434 +400.0 43.0429 1.45886 +450.0 59.2027 1.70814 +500.0 73.3176 1.89816 +550.0 96.5099 2.17264 +600.0 126.386 2.47868 +650.0 137.707 2.58431 +700.0 157.857 2.76118 +750.0 169.229 2.85553 +800.0 183.344 2.96788 +850.0 199.603 3.09144 +900.0 207.384 3.14855 +950.0 199.803 3.09292 +1000.0 205.439 3.13439 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/bi_pipro_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/bi_pipro_combined.txt new file mode 100644 index 0000000000..bdcefbe6a9 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/bi_pipro_combined.txt @@ -0,0 +1,21 @@ +#KE XS sig +50.0 8.78264 1.30894 +100.0 12.686 1.573 +150.0 22.8349 2.10985 +200.0 37.4726 2.70175 +250.0 52.3055 3.19078 +300.0 57.3799 3.34154 +350.0 58.3558 3.36975 +400.0 162.381 5.60609 +450.0 209.808 6.36458 +500.0 273.823 7.25894 +550.0 356.77 8.26789 +600.0 422.543 8.98232 +650.0 457.868 9.34161 +700.0 491.242 9.6676 +750.0 531.838 10.0484 +800.0 553.306 10.2434 +850.0 626.495 10.8788 +900.0 610.882 10.7468 +950.0 636.839 10.9652 +1000.0 655.575 11.1198 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/c_pipro_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/c_pipro_combined.txt new file mode 100644 index 0000000000..cb7ba7d442 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/c_pipro_combined.txt @@ -0,0 +1,21 @@ +#KE XS sig +50.0 0.580942 0.12989 +100.0 1.01665 0.171815 +150.0 2.06234 0.244668 +200.0 3.97945 0.339754 +250.0 6.15798 0.422483 +300.0 5.83846 0.411399 +350.0 5.08324 0.38392 +400.0 21.4077 0.785652 +450.0 30.3252 0.933628 +500.0 41.6826 1.09242 +550.0 55.1023 1.25308 +600.0 73.402 1.44161 +650.0 82.4356 1.52531 +700.0 88.6227 1.57978 +750.0 98.0339 1.65876 +800.0 107.068 1.73071 +850.0 112.528 1.77257 +900.0 117.612 1.81051 +950.0 115.782 1.79696 +1000.0 117.931 1.81287 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/fe_pipro_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/fe_pipro_combined.txt new file mode 100644 index 0000000000..801f8e9125 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/fe_pipro_combined.txt @@ -0,0 +1,21 @@ +#KE XS sig +50.0 4.13692 0.579137 +100.0 4.21804 0.584785 +150.0 9.00389 0.854137 +200.0 15.2498 1.11116 +250.0 19.4679 1.25514 +300.0 24.0915 1.39585 +350.0 24.0104 1.39351 +400.0 71.6255 2.39973 +450.0 95.0681 2.76065 +500.0 124.351 3.15155 +550.0 163.692 3.60696 +600.0 201.979 3.99697 +650.0 224.043 4.20375 +700.0 252.92 4.45827 +750.0 271.982 4.61762 +800.0 301.022 4.84887 +850.0 312.865 4.93959 +900.0 332.495 5.08578 +950.0 317.894 4.97753 +1000.0 333.955 5.09646 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/li_pipro_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/li_pipro_combined.txt new file mode 100644 index 0000000000..560b8472cc --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/li_pipro_combined.txt @@ -0,0 +1,21 @@ +#KE XS sig +50.0 0.109791 0.0448207 +100.0 0.274478 0.0708645 +150.0 1.00642 0.135668 +200.0 1.93964 0.188295 +250.0 2.4703 0.212466 +300.0 2.452 0.211679 +350.0 2.28731 0.204456 +400.0 12.8822 0.483803 +450.0 17.8594 0.568867 +500.0 22.6353 0.639585 +550.0 32.9922 0.769951 +600.0 43.1662 0.878205 +650.0 49.8086 0.941602 +700.0 54.7309 0.985667 +750.0 63.9167 1.06242 +800.0 68.345 1.09722 +850.0 73.5235 1.13636 +900.0 74.969 1.147 +950.0 73.5966 1.1369 +1000.0 73.2307 1.13419 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/nb_pipro_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/nb_pipro_combined.txt new file mode 100644 index 0000000000..e37e450fa2 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/nb_pipro_combined.txt @@ -0,0 +1,21 @@ +#KE XS sig +50.0 3.41265 0.622968 +100.0 5.23273 0.771346 +150.0 12.1718 1.17606 +200.0 18.7696 1.46 +250.0 24.5711 1.67004 +300.0 31.7376 1.89743 +350.0 34.4678 1.97712 +400.0 99.5356 3.35016 +450.0 135.482 3.90234 +500.0 165.4 4.30598 +550.0 213.632 4.88317 +600.0 264.025 5.41637 +650.0 302.361 5.78626 +700.0 312.94 5.88381 +750.0 338.649 6.1136 +800.0 361.968 6.31391 +850.0 394.616 6.58273 +900.0 411.566 6.71742 +950.0 405.081 6.66627 +1000.0 430.449 6.86388 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip12_pipro.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip12_pipro.txt new file mode 100644 index 0000000000..b89208417a --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip12_pipro.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 0.000000 +50.0 0.000000 +75.0 0.641941 +100.0 1.347785 +125.0 2.053629 +150.0 2.759472 +175.0 3.285224 +200.0 3.810976 +225.0 4.217635 +250.0 4.624294 +275.0 6.558830 +300.0 8.493366 +325.0 11.127941 +350.0 13.762516 +375.0 17.314978 +400.0 20.867440 +425.0 25.793824 +450.0 30.720208 +475.0 37.552084 +500.0 44.383960 +525.0 50.486750 +550.0 56.589540 +575.0 62.419290 +600.0 68.249040 +625.0 73.884170 +650.0 79.519300 +675.0 84.715870 +700.0 89.912440 +725.0 93.825040 +750.0 97.737640 +775.0 101.255280 +800.0 104.772920 +825.0 107.488850 +850.0 110.204780 +875.0 112.194490 +900.0 114.184200 +925.0 115.433200 +950.0 116.682200 +975.0 117.931200 +1000.0 119.180200 +1025.0 120.429200 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip209_pipro.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip209_pipro.txt new file mode 100644 index 0000000000..bc0a5ff667 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip209_pipro.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 0.000000 +50.0 4.449864 +75.0 10.041480 +100.0 15.633096 +125.0 21.224712 +150.0 26.816328 +175.0 31.676054 +200.0 36.535780 +225.0 41.102760 +250.0 45.669740 +275.0 59.624350 +300.0 73.578960 +325.0 90.812500 +350.0 108.046040 +375.0 130.197790 +400.0 152.349540 +425.0 182.288550 +450.0 212.227560 +475.0 248.646280 +500.0 285.065000 +525.0 314.613700 +550.0 344.162400 +575.0 372.305800 +600.0 400.449200 +625.0 426.250700 +650.0 452.052200 +675.0 471.705800 +700.0 491.359400 +725.0 511.754600 +750.0 532.149800 +775.0 547.451200 +800.0 562.752600 +825.0 577.312300 +850.0 591.872000 +875.0 604.245700 +900.0 616.619400 +925.0 627.363500 +950.0 638.107600 +975.0 648.851700 +1000.0 659.595800 +1025.0 670.339900 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip27_pipro.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip27_pipro.txt new file mode 100644 index 0000000000..e7fa2503bf --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip27_pipro.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 0.000000 +50.0 0.059854 +75.0 1.421466 +100.0 2.783077 +125.0 4.144689 +150.0 5.506300 +175.0 6.448950 +200.0 7.391600 +225.0 8.254454 +250.0 9.117308 +275.0 13.017603 +300.0 16.917898 +325.0 21.945389 +350.0 26.972880 +375.0 33.167470 +400.0 39.362060 +425.0 47.945710 +450.0 56.529360 +475.0 68.110590 +500.0 79.691820 +525.0 89.158230 +550.0 98.624640 +575.0 108.490070 +600.0 118.355500 +625.0 127.946640 +650.0 137.537780 +675.0 146.221190 +700.0 154.904600 +725.0 162.226300 +750.0 169.548000 +775.0 176.515700 +800.0 183.483400 +825.0 187.678000 +850.0 191.872600 +875.0 195.493600 +900.0 199.114600 +925.0 201.334100 +950.0 203.553600 +975.0 205.773100 +1000.0 207.992600 +1025.0 210.212100 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip3_pipro.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip3_pipro.txt new file mode 100644 index 0000000000..0d83cb0a3d --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip3_pipro.txt @@ -0,0 +1,24 @@ +## pi+ -> he3-3 +## File generated by MakeTextFiles.cxx +## KE pipro_xs +0 0 +50 0 +100 0 +150 0 +200 0 +250 0 +300 0 +350 0 +400 11.653 +450 24.1586 +500 26.1481 +550 28.9903 +600 32.2588 +650 35.8115 +700 39.6485 +750 43.2012 +800 46.0434 +850 47.8908 +900 49.1698 +950 50.1645 +1000 51.3014 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip56_pipro.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip56_pipro.txt new file mode 100644 index 0000000000..ba1dac6d46 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip56_pipro.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 0.000000 +50.0 2.076566 +75.0 4.161252 +100.0 6.245938 +125.0 8.330624 +150.0 10.415310 +175.0 12.410768 +200.0 14.406226 +225.0 16.385462 +250.0 18.364698 +275.0 24.626859 +300.0 30.889020 +325.0 38.870850 +350.0 46.852680 +375.0 57.340990 +400.0 67.829300 +425.0 81.789350 +450.0 95.749400 +475.0 113.546260 +500.0 131.343120 +525.0 146.584870 +550.0 161.826620 +575.0 177.611810 +600.0 193.397000 +625.0 208.160100 +650.0 222.923200 +675.0 236.656200 +700.0 250.389200 +725.0 261.477800 +750.0 272.566400 +775.0 283.411600 +800.0 294.256800 +825.0 300.754200 +850.0 307.251600 +875.0 313.448900 +900.0 319.646200 +925.0 323.190950 +950.0 326.735700 +975.0 330.280450 +1000.0 333.825200 +1025.0 337.369950 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip7_pipro.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip7_pipro.txt new file mode 100644 index 0000000000..b3ce0cba10 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip7_pipro.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 0.000000 +50.0 0.000000 +75.0 0.202199 +100.0 0.521508 +125.0 0.840817 +150.0 1.160126 +175.0 1.394347 +200.0 1.628568 +225.0 1.829851 +250.0 2.031134 +275.0 3.218712 +300.0 4.406290 +325.0 5.998266 +350.0 7.590242 +375.0 9.606742 +400.0 11.623242 +425.0 14.677262 +450.0 17.731282 +475.0 21.819171 +500.0 25.907060 +525.0 29.599700 +550.0 33.292340 +575.0 36.979490 +600.0 40.666640 +625.0 44.794780 +650.0 48.922920 +675.0 52.458200 +700.0 55.993480 +725.0 59.029210 +750.0 62.064940 +775.0 64.580980 +800.0 67.097020 +825.0 68.983590 +850.0 70.870160 +875.0 71.801560 +900.0 72.732960 +925.0 73.225185 +950.0 73.717410 +975.0 74.209635 +1000.0 74.701860 +1025.0 75.194085 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip93_pipro.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip93_pipro.txt new file mode 100644 index 0000000000..4bbfbb0062 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_pipro/pip93_pipro.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 0.000000 +50.0 1.660822 +75.0 4.453511 +100.0 7.246199 +125.0 10.038888 +150.0 12.831576 +175.0 15.664071 +200.0 18.496566 +225.0 21.420073 +250.0 24.343580 +275.0 33.079960 +300.0 41.816340 +325.0 53.487580 +350.0 65.158820 +375.0 79.241710 +400.0 93.324600 +425.0 111.514040 +450.0 129.703480 +475.0 152.659200 +500.0 175.614920 +525.0 195.897460 +550.0 216.180000 +575.0 233.925800 +600.0 251.671600 +625.0 268.996500 +650.0 286.321400 +675.0 301.155000 +700.0 315.988600 +725.0 329.047700 +750.0 342.106800 +775.0 353.027300 +800.0 363.947800 +825.0 373.161900 +850.0 382.376000 +875.0 391.556000 +900.0 400.736000 +925.0 408.107350 +950.0 415.478700 +975.0 422.850050 +1000.0 430.221400 +1025.0 437.592750 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/al_tot_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/al_tot_combined.txt new file mode 100644 index 0000000000..3ea6ede51e --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/al_tot_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 638.0 47.63 +125.0 740.0 56.57 +165.0 719.0 57.28 +205.0 654.0 53.91 +245.0 578.0 51.66 +315.0 499.0 47.42 +1.0 20.0 0.0 +5.0 38.4 0.0 +20.0 118.4 0.0 +50.0 350.0 0.0 +350.0 440.953 4.68966 +400.0 400.803 4.47106 +450.0 368.384 4.28643 +500.0 364.842 4.26578 +550.0 380.104 4.35409 +600.0 409.631 4.52004 +650.0 385.74 4.38625 +700.0 371.925 4.30698 +750.0 384.444 4.37887 +800.0 422.748 4.59184 +850.0 454.32 4.76021 +900.0 455.168 4.76465 +950.0 429.881 4.63041 +1000.0 417.112 4.56113 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/bi_tot_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/bi_tot_combined.txt new file mode 100644 index 0000000000..2b02806417 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/bi_tot_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 2980.0 646.22 +125.0 2660.0 488.26 +165.0 2446.0 424.26 +205.0 2270.0 431.39 +245.0 2230.0 377.36 +315.0 1950.0 368.92 +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 448.0 0.0 +50.0 1257.0 0.0 +350.0 1656.41 17.98 +400.0 1594.34 17.6399 +450.0 1572.29 17.5175 +500.0 1568.77 17.4979 +550.0 1615.23 17.7551 +600.0 1673.39 18.0719 +650.0 1635.52 17.8663 +700.0 1616.4 17.7615 +750.0 1613.66 17.7465 +800.0 1661.68 18.0086 +850.0 1767.26 18.5719 +900.0 1748.72 18.4742 +950.0 1727.45 18.3615 +1000.0 1674.17 18.0761 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/c_tot_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/c_tot_combined.txt new file mode 100644 index 0000000000..2c5894f964 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/c_tot_combined.txt @@ -0,0 +1,33 @@ +#KE XS sig +1.0 0.0 0.0 +4.0 5.1 0.0 +20.0 41.8 0.0 +50.0 131.7 0.0 +85.0 287.0 21.63 +125.0 417.0 24.17 +165.0 447.0 23.41 +205.0 412.0 21.84 +245.0 366.0 21.19 +315.0 309.0 15.65 +42.0 125.0 14.0 +45.0 135.0 15.0 +46.5 137.0 14.0 +48.0 140.0 20.0 +49.5 158.0 19.0 +50.0 152.0 14.0 +54.0 147.0 14.0 +65.0 202.0 17.0 +350.0 243.182 2.65777 +400.0 209.488 2.46678 +450.0 196.242 2.38752 +500.0 191.914 2.36105 +550.0 206.409 2.44859 +600.0 215.152 2.49991 +650.0 203.272 2.42991 +700.0 195.051 2.38027 +750.0 206.118 2.44686 +800.0 227.323 2.56964 +850.0 243.618 2.66015 +900.0 248.934 2.68901 +950.0 235.514 2.61553 +1000.0 228.601 2.57686 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/fe_tot_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/fe_tot_combined.txt new file mode 100644 index 0000000000..d30f8b9959 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/fe_tot_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 15.4 0.0 +20.0 247.7 0.0 +50.0 578.0 0.0 +85.0 1284.0 100.6 +125.0 1254.0 106.3 +165.0 1154.0 106.3 +205.0 1050.0 98.99 +245.0 936.0 98.99 +315.0 807.0 92.2 +350.0 738.238 7.73841 +400.0 677.32 7.41226 +450.0 644.305 7.22935 +500.0 638.384 7.19606 +550.0 666.044 7.3503 +600.0 711.469 7.59682 +650.0 677.401 7.4127 +700.0 661.907 7.32744 +750.0 676.427 7.40737 +800.0 746.268 7.78038 +850.0 758.355 7.84314 +900.0 788.124 7.9956 +950.0 743.591 7.76642 +1000.0 720.149 7.64301 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/he3_tot_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/he3_tot_combined.txt new file mode 100644 index 0000000000..707e091075 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/he3_tot_combined.txt @@ -0,0 +1,24 @@ +#KE XS sig +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 11.0 0.0 +50.0 16.0 0.0 +100.0 58.5128 0.821278 +150.0 127.711 1.21333 +200.0 138.766 1.26476 +250.0 115.861 1.15567 +300.0 98.1553 1.06371 +350.0 86.7663 1.00009 +400.0 64.5762 0.862782 +450.0 57.2217 0.812167 +500.0 54.2016 0.790443 +550.0 54.9509 0.795888 +600.0 58.2592 0.819496 +650.0 55.1583 0.797389 +700.0 53.948 0.788592 +750.0 59.0661 0.825152 +800.0 67.3427 0.881069 +850.0 73.3831 0.919735 +900.0 73.8211 0.922476 +950.0 69.2217 0.893276 +1000.0 65.7289 0.870448 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/li_tot_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/li_tot_combined.txt new file mode 100644 index 0000000000..4e7b7f5167 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/li_tot_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +1.0 16.0 0.0 +5.0 30.7 0.0 +20.0 72.3 0.0 +50.0 172.6 0.0 +85.0 149.0 11.7 +125.0 288.0 16.12 +165.0 361.0 16.12 +205.0 343.0 12.65 +245.0 301.0 9.49 +315.0 228.0 7.21 +350.0 158.026 1.70048 +400.0 128.126 1.53118 +450.0 115.354 1.45286 +500.0 113.304 1.4399 +550.0 123.789 1.50505 +600.0 130.432 1.5449 +650.0 124.192 1.50749 +700.0 117.678 1.46742 +750.0 128.401 1.53282 +800.0 145.693 1.63278 +850.0 160.478 1.71362 +900.0 161.247 1.71772 +950.0 151.292 1.66386 +1000.0 143.79 1.62208 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/nb_tot_combined.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/nb_tot_combined.txt new file mode 100644 index 0000000000..9df1f91454 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/nb_tot_combined.txt @@ -0,0 +1,25 @@ +#KE XS sig +85.0 1753.0 340.0 +125.0 1682.0 234.31 +165.0 1562.0 234.31 +205.0 1433.0 233.24 +245.0 1300.0 233.24 +315.0 1123.0 216.33 +1.0 0.0 0.0 +5.0 0.0 0.0 +20.0 373.2 0.0 +50.0 818.1 0.0 +350.0 1003.77 10.6857 +400.0 944.963 10.3679 +450.0 917.661 10.2171 +500.0 905.148 10.1472 +550.0 944.849 10.3673 +600.0 956.452 10.4308 +650.0 954.063 10.4177 +700.0 911.291 10.1815 +750.0 916.865 10.2126 +800.0 1017.2 10.7569 +850.0 1040.86 10.8813 +900.0 1040.29 10.8783 +950.0 999.565 10.6633 +1000.0 1008.67 10.7117 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip12_tot.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip12_tot.txt new file mode 100644 index 0000000000..555cb56f83 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip12_tot.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 69.563360 +50.0 145.294109 +75.0 228.853232 +100.0 293.829802 +125.0 346.847561 +150.0 371.192835 +175.0 387.897862 +200.0 393.142519 +225.0 380.621682 +250.0 361.922982 +275.0 336.278314 +300.0 310.633646 +325.0 287.046311 +350.0 266.544974 +375.0 249.125471 +400.0 231.705968 +425.0 220.576484 +450.0 209.447000 +475.0 206.644000 +500.0 203.841000 +525.0 203.219400 +550.0 202.597800 +575.0 202.478700 +600.0 202.359600 +625.0 203.780000 +650.0 205.200400 +675.0 207.291800 +700.0 209.383200 +725.0 212.229800 +750.0 215.076400 +775.0 219.642600 +800.0 224.208800 +825.0 228.255100 +850.0 232.301400 +875.0 234.549700 +900.0 236.798000 +925.0 236.520600 +950.0 236.243200 +975.0 235.965800 +1000.0 235.688400 +1025.0 235.411000 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip209_tot.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip209_tot.txt new file mode 100644 index 0000000000..00fca3ece6 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip209_tot.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 639.732111 +50.0 1293.489507 +75.0 1727.722614 +100.0 2058.020751 +125.0 2319.028909 +150.0 2442.885841 +175.0 2471.016636 +200.0 2355.558225 +225.0 2243.203861 +250.0 2135.346561 +275.0 2042.373467 +300.0 1949.400374 +325.0 1868.971143 +350.0 1807.357703 +375.0 1740.436797 +400.0 1673.515890 +425.0 1637.461945 +450.0 1601.408000 +475.0 1603.106000 +500.0 1604.804000 +525.0 1608.922000 +550.0 1613.040000 +575.0 1617.451000 +600.0 1621.862000 +625.0 1626.351000 +650.0 1630.840000 +675.0 1635.485000 +700.0 1640.130000 +725.0 1649.517000 +750.0 1658.904000 +775.0 1670.224000 +800.0 1681.544000 +825.0 1692.649000 +850.0 1703.754000 +875.0 1709.805000 +900.0 1715.856000 +925.0 1715.114500 +950.0 1714.373000 +975.0 1713.631500 +1000.0 1712.890000 +1025.0 1712.148500 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip27_tot.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip27_tot.txt new file mode 100644 index 0000000000..361998c4b0 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip27_tot.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 174.359686 +50.0 333.361385 +75.0 449.569756 +100.0 541.962436 +125.0 618.477989 +150.0 648.054246 +175.0 660.877649 +200.0 648.571770 +225.0 620.228526 +250.0 587.536797 +275.0 553.488497 +300.0 519.440196 +325.0 487.727622 +350.0 459.518637 +375.0 438.224777 +400.0 416.930917 +425.0 403.974059 +450.0 391.017200 +475.0 387.885000 +500.0 384.752800 +525.0 383.246500 +550.0 381.740200 +575.0 382.094300 +600.0 382.448400 +625.0 384.408600 +650.0 386.368800 +675.0 390.633200 +700.0 394.897600 +725.0 399.366500 +750.0 403.835400 +775.0 410.778200 +800.0 417.721000 +825.0 423.516600 +850.0 429.312200 +875.0 432.579000 +900.0 435.845800 +925.0 434.060250 +950.0 432.274700 +975.0 430.489150 +1000.0 428.703600 +1025.0 426.918050 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip3_tot.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip3_tot.txt new file mode 100644 index 0000000000..b125ad30a2 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip3_tot.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 11.965821 +50.0 29.880722 +75.0 48.528254 +100.0 67.175785 +125.0 79.272973 +150.0 91.370160 +175.0 99.585690 +200.0 107.801220 +225.0 110.626570 +250.0 113.451920 +275.0 107.138440 +300.0 100.824960 +325.0 92.670530 +350.0 84.516100 +375.0 78.350160 +400.0 72.184220 +425.0 67.863780 +450.0 63.543340 +475.0 60.692630 +500.0 57.841920 +525.0 56.900130 +550.0 55.958340 +575.0 55.630970 +600.0 55.303600 +625.0 55.790050 +650.0 56.276500 +675.0 57.515680 +700.0 58.754860 +725.0 60.267250 +750.0 61.779640 +775.0 63.645920 +800.0 65.512200 +825.0 67.039570 +850.0 68.566940 +875.0 69.233220 +900.0 69.899500 +925.0 69.530050 +950.0 69.160600 +975.0 68.791150 +1000.0 68.421700 +1025.0 68.052250 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip56_tot.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip56_tot.txt new file mode 100644 index 0000000000..41c5998854 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip56_tot.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 300.906858 +50.0 597.070147 +75.0 797.154939 +100.0 946.500673 +125.0 1062.020368 +150.0 1108.007638 +175.0 1115.338011 +200.0 1064.683039 +225.0 1008.029216 +250.0 951.316894 +275.0 900.369427 +300.0 849.421961 +325.0 803.029811 +350.0 763.470637 +375.0 733.610491 +400.0 703.750346 +425.0 688.304273 +450.0 672.858200 +475.0 670.181300 +500.0 667.504400 +525.0 667.512500 +550.0 667.520600 +575.0 669.280800 +600.0 671.041000 +625.0 674.845300 +650.0 678.649600 +675.0 686.672000 +700.0 694.694400 +725.0 699.383000 +750.0 704.071600 +775.0 715.143900 +800.0 726.216200 +825.0 734.384600 +850.0 742.553000 +875.0 746.925200 +900.0 751.297400 +925.0 747.947300 +950.0 744.597200 +975.0 741.247100 +1000.0 737.897000 +1025.0 734.546900 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip7_tot.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip7_tot.txt new file mode 100644 index 0000000000..a25d2c8d50 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip7_tot.txt @@ -0,0 +1,42 @@ +0.0 31.567210 +25.0 77.093580 +50.0 129.095645 +75.0 180.423470 +100.0 223.582918 +125.0 261.296781 +150.0 278.236293 +175.0 293.011199 +200.0 304.539196 +225.0 298.503431 +250.0 284.994095 +275.0 259.154243 +300.0 233.314390 +325.0 209.293791 +350.0 188.002074 +375.0 169.121417 +400.0 150.240760 +425.0 138.980280 +450.0 127.719800 +475.0 124.960400 +500.0 122.201000 +525.0 121.807600 +550.0 121.414200 +575.0 121.646600 +600.0 121.879000 +625.0 123.388700 +650.0 124.898400 +675.0 127.088800 +700.0 129.279200 +725.0 132.283800 +750.0 135.288400 +775.0 138.993900 +800.0 142.699400 +825.0 146.060800 +850.0 149.422200 +875.0 150.961100 +900.0 152.500000 +925.0 151.850400 +950.0 151.200800 +975.0 150.551200 +1000.0 149.901600 +1025.0 149.252000 diff --git a/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip93_tot.txt b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip93_tot.txt new file mode 100644 index 0000000000..6fcf39043f --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/2025/pipA_tot/pip93_tot.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 417.359266 +50.0 819.543914 +75.0 1093.709470 +100.0 1294.771322 +125.0 1447.097372 +150.0 1508.911514 +175.0 1518.968634 +200.0 1451.390218 +225.0 1377.367480 +250.0 1303.522138 +275.0 1236.830704 +300.0 1170.139269 +325.0 1110.577360 +350.0 1061.709737 +375.0 1021.927369 +400.0 982.145002 +425.0 962.711601 +450.0 943.278200 +475.0 938.546400 +500.0 933.814600 +525.0 934.724600 +550.0 935.634600 +575.0 934.997600 +600.0 934.360600 +625.0 935.532300 +650.0 936.704000 +675.0 943.939100 +700.0 951.174200 +725.0 959.615000 +750.0 968.055800 +775.0 976.678500 +800.0 985.301200 +825.0 994.128600 +850.0 1002.956000 +875.0 1012.136500 +900.0 1021.317000 +925.0 1018.399250 +950.0 1015.481500 +975.0 1012.563750 +1000.0 1009.646000 +1025.0 1006.728250 diff --git a/data/evgen/intranuke/tot_xsec/README.md b/data/evgen/intranuke/tot_xsec/README.md new file mode 100644 index 0000000000..917e7c29cc --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/README.md @@ -0,0 +1,28 @@ + +The first spline files for pion-nucleus total cross sections were made at Univ. of Pittsburgh in 2018. +Those results had issues wihch made certain cases (e.g. pi charge exchange for Ar40) give odd results +that aren't consistent with the undelying data. In addition, only CEM03 was available for the first +effort and it has proven unable to fit data. Finally, the code was still using pion-nucleus elastic +cross sections and this has been discontinued. The new effort (2025) was undertaken by +Mohamed Ismail (mis90@pitt.edu) and Steve Dytman (dytman@pitt.edu) at Univ., of Pittsburgh +to fix these and other issues. Dytman should be contacted for all questions. + +The normalizing cross sections are now total reaction cross sections instead of the total cross +sections used for the 2018 versions. Ashery (A>4) and Lehmann (A<=4) are used for 50400 MeV where there is presently no data and calculations are mostly +reliable (minimal nuclear effects). + +Splines are built at A=3, 7, 12, 27, 56, 93, and 209 for charge exchange (cex), inelastic (inel), +absorption, and pion production (pipro). Files labeled e,g. c_pip_combined_abs.txt have the +amalgam of the 3 sources of input data. Files labeled e.g. pip12_abs.txt have the +results of smoothing via ROOT. These files are all read into GENIE via INukeHadroData2025. +If probe is pi0, cross sections are modified inside HAIntranuke2025 according to results from hN. + +Only hA pionA splines have been modified. Similar updates of pA and nA splines are anticipated +in the future. + +references: +Ashery, et al., Phys Rev C 23, 2173 (1981) +Lehmann, et al., Phys Rev C 55, 2391 (1997) +SAID: downloaded from web site httphttps://gwdac.phys.gwu.edu/ 2009-2018. diff --git a/data/evgen/intranuke/tot_xsec/pipA_abs/ashery-pip-li-abs.dat b/data/evgen/intranuke/tot_xsec/pipA_abs/ashery-pip-li-abs.dat index 91cd0cafb3..0c7216e755 100644 --- a/data/evgen/intranuke/tot_xsec/pipA_abs/ashery-pip-li-abs.dat +++ b/data/evgen/intranuke/tot_xsec/pipA_abs/ashery-pip-li-abs.dat @@ -4,3 +4,4 @@ 165 124. 30. 205 59. 33. 245 42. 30. +315 0 0 diff --git a/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-ar-abs.dat b/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-ar-abs.dat new file mode 100644 index 0000000000..342a279269 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-ar-abs.dat @@ -0,0 +1,9 @@ + +#Kotlinski - LADS - Eur. Phys. J. A9. 537 (2000) +# pi+ Ar total abs cross section +#KEpi sigma (mb) uncertainty (mb) +70 180 43 +118 320 65 +162 351 49 +239 283 28 +330 225 17 diff --git a/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-n-abs.dat b/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-n-abs.dat new file mode 100644 index 0000000000..a22b144890 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-n-abs.dat @@ -0,0 +1,5 @@ + +#Kotlinski - LADS - Eur. Phys. J. A9. 537 (2000) +# pi+ N total abs cross section +#KEpi sigma (mb) uncertainty (mb) +239 119 10 diff --git a/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-xe-abs.dat b/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-xe-abs.dat new file mode 100644 index 0000000000..058ef6d12c --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_abs/kotlinski-pip-xe-abs.dat @@ -0,0 +1,5 @@ + +#Kotlinski - LADS - Eur. Phys. J. A9. 537 (2000) +# pi+ Xe total abs cross section +#KEpi sigma (mb) uncertainty (mb) +239 676 94 diff --git a/data/evgen/intranuke/tot_xsec/pipA_abs/pinzon-pip-c-abs.dat b/data/evgen/intranuke/tot_xsec/pipA_abs/pinzon-pip-c-abs.dat new file mode 100644 index 0000000000..df6375cc93 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_abs/pinzon-pip-c-abs.dat @@ -0,0 +1,7 @@ +#DUET expt - Pinzon et al. PR C95, 045203 (2019) +# pip C total absorption +105.6 153.8 12.0 +118.1 182.1 19.2 +135.6 160.8 16.6 +160.5 161.4 15.7 +186.9 159.4 15.3 diff --git a/data/evgen/intranuke/tot_xsec/pipA_cex/ashery-pip-li-cex.dat b/data/evgen/intranuke/tot_xsec/pipA_cex/ashery-pip-li-cex.dat index 4ef6923b3e..fe0046888d 100644 --- a/data/evgen/intranuke/tot_xsec/pipA_cex/ashery-pip-li-cex.dat +++ b/data/evgen/intranuke/tot_xsec/pipA_cex/ashery-pip-li-cex.dat @@ -4,3 +4,4 @@ 165 46. 23. 205 54. 27. 245 50. 25. +315 0 0 diff --git a/data/evgen/intranuke/tot_xsec/pipA_cex/ashery-pip-pim-A-cex.dat b/data/evgen/intranuke/tot_xsec/pipA_cex/ashery-pip-pim-A-cex.dat new file mode 100644 index 0000000000..4446767a5f --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_cex/ashery-pip-pim-A-cex.dat @@ -0,0 +1,12 @@ +#Ashery (LAMPF) 160 MeV +# PRC 30, 946 (1984) +probe target xs (mb) error (mb) + +pi+/- 12C 64 10 +pi+/- 16O 80 12 +pi+ Ni 158 20 +pi+ Pb 252 30 + +pi- 18O 73 15 +pi- 129Sn 127 25 +pi- Pb 113 16 diff --git a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-al-inelas.dat b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-al-inelas.dat index feae215c82..35004fcedd 100644 --- a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-al-inelas.dat +++ b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-al-inelas.dat @@ -1,5 +1,6 @@ # Data at 85 MeV omitted in favor of Aniol data # KE Inelas Sig +85 331 56 125 342. 70. 165 321. 72. 205 269. 72. diff --git a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-c-inelas.dat b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-c-inelas.dat index 15585822a1..6d1ee8d913 100644 --- a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-c-inelas.dat +++ b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-c-inelas.dat @@ -1,5 +1,6 @@ # Data at 85 MeV omitted in favor of Aniol data # KE Inelas Sig +85 143 26 125 213. 33. 165 207. 33. 205 210. 51. diff --git a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-fe-inelas.dat b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-fe-inelas.dat index 9b97b43942..06a98b19c1 100644 --- a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-fe-inelas.dat +++ b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-fe-inelas.dat @@ -1,5 +1,6 @@ # Data at 85 MeV omitted in favor of Aniol data # KE Inelas Sig +85 784 115 125 644. 123. 165 474. 130. 205 360. 125. diff --git a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-li-inelas.dat b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-li-inelas.dat index 019de68d88..b2f98c936f 100644 --- a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-li-inelas.dat +++ b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-li-inelas.dat @@ -1,5 +1,6 @@ # Data at 85 MeV omitted in favor of Aniol data # KE Inelas Sig +85 74 18 125 131. 23. 165 191. 26. 205 230. 24. diff --git a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-nb-inelas.dat b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-nb-inelas.dat index f46c1ac4d2..1e44752fda 100644 --- a/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-nb-inelas.dat +++ b/data/evgen/intranuke/tot_xsec/pipA_inelas/ashery-pip-nb-inelas.dat @@ -1,5 +1,6 @@ # Data at 85 MeV omitted in favor of Aniol data # KE Inelas Sig +85 848 350 125 652. 270. 165 552. 280. 205 618. 250. diff --git a/data/evgen/intranuke/tot_xsec/pipA_pipro/pip27_pipro.txt b/data/evgen/intranuke/tot_xsec/pipA_pipro/pip27_pipro.txt new file mode 100644 index 0000000000..e7fa2503bf --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_pipro/pip27_pipro.txt @@ -0,0 +1,42 @@ +0.0 0.000000 +25.0 0.000000 +50.0 0.059854 +75.0 1.421466 +100.0 2.783077 +125.0 4.144689 +150.0 5.506300 +175.0 6.448950 +200.0 7.391600 +225.0 8.254454 +250.0 9.117308 +275.0 13.017603 +300.0 16.917898 +325.0 21.945389 +350.0 26.972880 +375.0 33.167470 +400.0 39.362060 +425.0 47.945710 +450.0 56.529360 +475.0 68.110590 +500.0 79.691820 +525.0 89.158230 +550.0 98.624640 +575.0 108.490070 +600.0 118.355500 +625.0 127.946640 +650.0 137.537780 +675.0 146.221190 +700.0 154.904600 +725.0 162.226300 +750.0 169.548000 +775.0 176.515700 +800.0 183.483400 +825.0 187.678000 +850.0 191.872600 +875.0 195.493600 +900.0 199.114600 +925.0 201.334100 +950.0 203.553600 +975.0 205.773100 +1000.0 207.992600 +1025.0 210.212100 diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-al-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-al-reac.dat new file mode 100755 index 0000000000..31f6479df7 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-al-reac.dat @@ -0,0 +1,7 @@ +#KE (MeV) Reac (mb) Err (mb) +85 638 47.63 +125 740 56.57 +165 719 57.28 +205 654 53.91 +245 578 51.66 +315 499 47.42 diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-bi-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-bi-reac.dat new file mode 100755 index 0000000000..e2fe89a8b0 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-bi-reac.dat @@ -0,0 +1,7 @@ +#KE (MeV) Reac (mb) Err (mb) +85 2980 646.22 +125 2660 488.26 +165 2446 424.26 +205 2270 431.39 +245 2230 377.36 +315 1950 368.92 diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-c-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-c-reac.dat new file mode 100755 index 0000000000..2882e3b0bb --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-c-reac.dat @@ -0,0 +1,7 @@ +#KE (MeV) Reac (mb) Err (mb) +85 287 21.63 +125 417 24.17 +165 447 23.41 +205 412 21.84 +245 366 21.19 +315 309 15.65 diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-fe-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-fe-reac.dat new file mode 100755 index 0000000000..25a3329fba --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-fe-reac.dat @@ -0,0 +1,7 @@ +#KE (MeV) Reac (mb) Err (mb) +85 1284 100.60 +125 1254 106.30 +165 1154 106.30 +205 1050 98.99 +245 936 98.99 +315 807 92.20 diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-li-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-li-reac.dat new file mode 100755 index 0000000000..a948b84d50 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-li-reac.dat @@ -0,0 +1,7 @@ +#KE (MeV) Reac (mb) Err (mb) +85 149 11.70 +125 288 16.12 +165 361 16.12 +205 343 12.65 +245 301 9.49 +315 228 7.21 diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-nb-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-nb-reac.dat new file mode 100755 index 0000000000..2f93234329 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/ashery-pip-nb-reac.dat @@ -0,0 +1,7 @@ +#KE (MeV) Reac (mb) Err (mb) +85 1753 340.00 +125 1682 234.31 +165 1562 234.31 +205 1433 233.24 +245 1300 233.24 +315 1123 216.33 diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-ca-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-ca-reac.dat new file mode 100755 index 0000000000..d5d1eb009e --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-ca-reac.dat @@ -0,0 +1,6 @@ +#pi+ Ca total reaction xsec +#Meirav, et al. Phys Rev C36, 1066 (1987) +#Tpi (MeV) sig (mb) err (mb) + 50. 439 66 + 65. 563 43 + diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-o-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-o-reac.dat new file mode 100755 index 0000000000..f7b3c128ff --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-o-reac.dat @@ -0,0 +1,5 @@ +#pi+ O total reaction xsec +#Meirav, et al. Phys Rev C36, 1066 (1987) +#Tpi (MeV) sig (mb) err (mb) + 50. 166 19 + diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-zr-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-zr-reac.dat new file mode 100755 index 0000000000..1e3806ca71 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/meirav-pip-zr-reac.dat @@ -0,0 +1,5 @@ +#pi+ Zr total reaction xsec +#Meirav, et al. Phys Rev C36,1066(1987) +#Tpi (MeV) sig (mb) err (mb) + 50. 949 61 + diff --git a/data/evgen/intranuke/tot_xsec/pipA_tot/saunders-pip-c-reac.dat b/data/evgen/intranuke/tot_xsec/pipA_tot/saunders-pip-c-reac.dat new file mode 100755 index 0000000000..fac663c445 --- /dev/null +++ b/data/evgen/intranuke/tot_xsec/pipA_tot/saunders-pip-c-reac.dat @@ -0,0 +1,12 @@ +#Saunders et al +#source: Phys Rev C 1996 +#pip C total reaction xs +#KE (MeV) sig err +42. 125 14 +45. 135 15 +46.5 137 14 +48. 140 20 +49.5 158 19 +50.0 152 14 +54. 147 14 +65. 202 17 diff --git a/src/Apps/gAtmoEvGen.cxx b/src/Apps/gAtmoEvGen.cxx index 1872f3170e..57d74dbdfc 100644 --- a/src/Apps/gAtmoEvGen.cxx +++ b/src/Apps/gAtmoEvGen.cxx @@ -376,6 +376,7 @@ int main(int argc, char** argv) * option. */ mcj_driver->ForceSingleProbScale(); + // initialize an ntuple writer NtpWriter ntpw(kDefOptNtpFormat, gOptRunNu, gOptRanSeed); ntpw.CustomizeFilenamePrefix(gOptEvFilePrefix); diff --git a/src/Apps/gEvGenDM.cxx b/src/Apps/gEvGenDM.cxx index 6f48039bd1..9d2015cac5 100644 --- a/src/Apps/gEvGenDM.cxx +++ b/src/Apps/gEvGenDM.cxx @@ -300,14 +300,17 @@ void GenerateEventsAtFixedInitState(void) // Create init state InitialState init_state(target, dark_matter); - + +// +/* bool unitary = CheckUnitarityLimit(); if (!unitary) { LOG("gevgen_dm", pFATAL) << "Cross-section risks exceeding unitarity limit - Exiting"; exit(1); } - +*/ +// // Create/config event generation driver GEVGDriver evg_driver; diff --git a/src/Apps/gEvGenHadronNucleus.cxx b/src/Apps/gEvGenHadronNucleus.cxx index c66194bdb8..471d64f4d0 100644 --- a/src/Apps/gEvGenHadronNucleus.cxx +++ b/src/Apps/gEvGenHadronNucleus.cxx @@ -245,11 +245,11 @@ const EventRecordVisitorI * GetIntranuke(void) } else if ( gOptMode.compare("hN") == 0 ) { sname = "genie::HNIntranuke"; sconf = "Default"; - } else if ( gOptMode.compare("hA2019") == 0 ) { - sname = "genie::HAIntranuke2019"; + } else if ( gOptMode.compare("hA2025") == 0 ) { + sname = "genie::HAIntranuke2025"; sconf = "Default"; - } else if ( gOptMode.compare("hN2019") == 0 ) { - sname = "genie::HNIntranuke2019"; + } else if ( gOptMode.compare("hN2025") == 0 ) { + sname = "genie::HNIntranuke2025"; sconf = "Default"; } else if ( gOptMode.compare("hA2018") == 0 ) { sname = "genie::HAIntranuke2018"; diff --git a/src/Framework/Conventions/KinePhaseSpace.h b/src/Framework/Conventions/KinePhaseSpace.h index ef211a8964..436c9919c0 100644 --- a/src/Framework/Conventions/KinePhaseSpace.h +++ b/src/Framework/Conventions/KinePhaseSpace.h @@ -67,7 +67,7 @@ typedef enum EKinePhaseSpace { // TODO: rename this value when the correct variables are identified kPSTAfE, kPSEgTlOgfE, - kPSDMELEvGen, // Equivalent to kPSQELEvGen for Dark Matter scattering + kPSDMELEvGen, // Equivalent to kPSQELEvGen for Dark Matter scattering kPSxQ2fE, kPSlog10xlog10Q2fE, kPSEDNufE, // Used for Dark Neutrinos, two body final state diff --git a/src/Framework/EventGen/GMCJDriver.cxx b/src/Framework/EventGen/GMCJDriver.cxx index 4e9e2041d4..87d633705a 100644 --- a/src/Framework/EventGen/GMCJDriver.cxx +++ b/src/Framework/EventGen/GMCJDriver.cxx @@ -130,7 +130,7 @@ void GMCJDriver::SetXSecSplineNbins(int nbins) fXSecSplineNbins = nbins; LOG("GMCJDriver", pNOTICE) - << "Number of bins in energy used for the xsec splines: " + << "Number of bins in energy used for the xsec splines: " << fXSecSplineNbins; } //___________________________________________________________________________ @@ -147,7 +147,7 @@ void GMCJDriver::SetPmaxNbins(int nbins) fPmaxNbins = nbins; LOG("GMCJDriver", pNOTICE) - << "Number of bins in energy used for maximum int. probability: " + << "Number of bins in energy used for maximum int. probability: " << fPmaxNbins; } //___________________________________________________________________________ @@ -654,11 +654,11 @@ void GMCJDriver::BootstrapXSecSplineSummation(void) // knots with zero y values (although the GENIE Spline object handles it) double min = rE.min; double max = TMath::Min(rE.max, fEmax); - + // Because of edge issue (see GENIE docdb 297) these lines are commented out // double dE = fEmax/10.; // double max = (fEmax+dE < rE.max) ? fEmax+dE : rE.max; - + // in the logaritmic binning is important to have a narrow binning to // describe better the glashow resonance peak. evgdriver->CreateXSecSumSpline(fXSecSplineNbins,min,max,true); @@ -747,7 +747,7 @@ void GMCJDriver::ComputeProbScales(void) // get xsec sum over all modelled processes for given neutrino+target) double sxsecLow = evgdriver->XSecSumSpline()->Evaluate(EvLow); - double sxsecHigh = evgdriver->XSecSumSpline()->Evaluate(EvHigh); + double sxsecHigh = evgdriver->XSecSumSpline()->Evaluate(EvHigh); // get max{path-length x density} double plmax = fMaxPathLengths.PathLength(target_pdgc); @@ -860,11 +860,11 @@ EventRecord * GMCJDriver::GenerateEvent1Try(void) } if (fForceInteraction) { - bool pl_ok = this->ComputePathLengths(); - if(!pl_ok) { - LOG("GMCJDriver", pFATAL) << "** Cannot calculate path lenths!"; - exit(1); - } + bool pl_ok = this->ComputePathLengths(); + if(!pl_ok) { + LOG("GMCJDriver", pFATAL) << "** Cannot calculate path lenths!"; + exit(1); + } if(fCurPathLengths.AreAllZero()) { LOG("GMCJDriver", pNOTICE) << "** Rejecting current flux neutrino (misses generation volume)"; @@ -877,53 +877,53 @@ EventRecord * GMCJDriver::GenerateEvent1Try(void) } else { // Compute the interaction probabilities assuming max. path lengths - // and decide whether the neutrino would interact -- - // Many flux neutrinos should be rejected here, drastically reducing - // the number of neutrinos that I need to propagate through the - // actual detector geometry (this is skipped when using + // and decide whether the neutrino would interact -- + // Many flux neutrinos should be rejected here, drastically reducing + // the number of neutrinos that I need to propagate through the + // actual detector geometry (this is skipped when using // pre-calculated flux interaction probabilities) if(fPreSelect) { - LOG("GMCJDriver", pNOTICE) + LOG("GMCJDriver", pNOTICE) << "Computing interaction probabilities for max. path lengths"; Psum = this->ComputeInteractionProbabilities(true /* <- max PL*/); Pno = 1-Psum; LOG("GMCJDriver", pNOTICE) - << "The no-interaction probability (max. path lengths) is: " + << "The no-interaction probability (max. path lengths) is: " << 100*Pno << " %"; if(Pno<0.) { - LOG("GMCJDriver", pFATAL) + LOG("GMCJDriver", pFATAL) << "Negative no-interaction probability! (P = " << 100*Pno << " %)" << " Particle E=" << fFluxDriver->Momentum().E() << " type=" << fFluxDriver->PdgCode() << "Psum=" << Psum; gAbortingInErr=true; exit(1); } if(R>=1-Pno) { - LOG("GMCJDriver", pNOTICE) + LOG("GMCJDriver", pNOTICE) << "** Rejecting current flux neutrino"; return 0; } - } // preselect + } // preselect bool pl_ok = false; - // If possible use pre-generated flux neutrino interaction probabilities + // If possible use pre-generated flux neutrino interaction probabilities if(fFluxIntTree){ - Psum = this->PreGenFluxInteractionProbability(); - } + Psum = this->PreGenFluxInteractionProbability(); + } // Else compute them in the usual manner else { // Compute (pathLength x density x weight fraction) for all materials // in the input geometry, for the neutrino generated by the flux driver pl_ok = this->ComputePathLengths(); if(!pl_ok) { - LOG("GMCJDriver", pERROR) + LOG("GMCJDriver", pERROR) << "** Rejecting current flux neutrino (err computing path-lengths)"; return 0; } if(fCurPathLengths.AreAllZero()) { - LOG("GMCJDriver", pNOTICE) + LOG("GMCJDriver", pNOTICE) << "** Rejecting current flux neutrino (misses generation volume)"; return 0; } @@ -935,14 +935,14 @@ EventRecord * GMCJDriver::GenerateEvent1Try(void) LOG("GMCJDriver", pNOTICE) << "** Rejecting current flux neutrino (has null interaction probability)"; return 0; - } + } // Now decide whether the current neutrino interacts Pno = 1-Psum; LOG("GMCJDriver", pNOTICE) << "The actual 'no interaction' probability is: " << 100*Pno << " %"; if(Pno<0.) { - LOG("GMCJDriver", pFATAL) + LOG("GMCJDriver", pFATAL) << "Negative no interactin probability! (P = " << 100*Pno << " %)"; // print info about what caused the problem @@ -966,27 +966,27 @@ EventRecord * GMCJDriver::GenerateEvent1Try(void) exit(1); } if(R>=1-Pno) { - LOG("GMCJDriver", pNOTICE) + LOG("GMCJDriver", pNOTICE) << "** Rejecting current flux neutrino"; return 0; } // - // The flux neutrino interacts! + // The flux neutrino interacts! // - // Calculate path lengths for first time and check potential mismatch if + // Calculate path lengths for first time and check potential mismatch if // used pre-generated flux interaction probabilities if(fFluxIntTree){ - pl_ok = this->ComputePathLengths(); - if(!pl_ok) { - LOG("GMCJDriver", pFATAL) << "** Cannot calculate path lenths!"; - exit(1); - } + pl_ok = this->ComputePathLengths(); + if(!pl_ok) { + LOG("GMCJDriver", pFATAL) << "** Cannot calculate path lenths!"; + exit(1); + } double Psum_curr = this->ComputeInteractionProbabilities(false /* <- actual PL */); - bool mismatch = TMath::Abs(Psum-Psum_curr) > controls::kASmallNum; + bool mismatch = TMath::Abs(Psum-Psum_curr) > controls::kASmallNum; if(mismatch){ - LOG("GMCJDriver", pFATAL) << + LOG("GMCJDriver", pFATAL) << "** Mismatch between pre-calculated and current interaction "<< "probabilities!"; exit(1); diff --git a/src/Framework/Interaction/Interaction.cxx b/src/Framework/Interaction/Interaction.cxx index f3456f6676..55cb4bddf8 100644 --- a/src/Framework/Interaction/Interaction.cxx +++ b/src/Framework/Interaction/Interaction.cxx @@ -915,7 +915,7 @@ Interaction * Interaction::MECNC( Interaction * Interaction::MECEM(int tgt, int probe, double E) { - Interaction * interaction = + Interaction * interaction = Interaction::Create(tgt, probe, kScMEC, kIntEM); InitialState * init_state = interaction->InitStatePtr(); @@ -1093,6 +1093,31 @@ Interaction * Interaction::DMDI( return interaction; } //___________________________________________________________________________ +Interaction * Interaction::RESDM(int target, int hitnuc, int probe, double E) +{ + Interaction * interaction = + Interaction::Create(target,probe,kScDarkMatterResonant, kIntDarkMatter); + + InitialState * init_state = interaction->InitStatePtr(); + init_state->SetProbeE(E); + init_state->TgtPtr()->SetHitNucPdg(hitnuc); + + return interaction; +} +//___________________________________________________________________________ +Interaction * Interaction::RESDM( + int target, int hitnuc, int probe, const TLorentzVector & p4probe) +{ + Interaction * interaction = + Interaction::Create(target,probe,kScDarkMatterResonant, kIntDarkMatter); + + InitialState * init_state = interaction->InitStatePtr(); + init_state->SetProbeP4(p4probe); + init_state->TgtPtr()->SetHitNucPdg(hitnuc); + + return interaction; +} +//___________________________________________________________________________ Interaction * Interaction::HNL(int probe, double E, int decayed_mode) { Interaction * interaction = diff --git a/src/Framework/Interaction/Interaction.h b/src/Framework/Interaction/Interaction.h index 0336a21076..e7d46bc5a5 100644 --- a/src/Framework/Interaction/Interaction.h +++ b/src/Framework/Interaction/Interaction.h @@ -11,7 +11,7 @@ \author Costas Andreopoulos University of Liverpool - Changes required to implement the GENIE Boosted Dark Matter module + Changes required to implement the GENIE Boosted Dark Matter module were installed by Josh Berger (Univ. of Wisconsin) \created April 25, 2004 @@ -48,16 +48,16 @@ const UInt_t kISkipProcessChk = 1<<17; ///< if set, skip process validity c const UInt_t kISkipKinematicChk = 1<<16; ///< if set, skip kinematic validity checks const UInt_t kIAssumeFreeNucleon = 1<<15; ///< const UInt_t kIAssumeFreeElectron = 1<<15; ///< -const UInt_t kINoNuclearCorrection = 1<<14; ///< if set, inhibit nuclear corrections +const UInt_t kINoNuclearCorrection = 1<<14; ///< if set, inhibit nuclear corrections class Interaction; -ostream & operator << (ostream & stream, const Interaction & i); +ostream & operator << (ostream & stream, const Interaction & i); class Interaction : public TObject { public: using TObject::Print; // suppress clang 'hides overloaded virtual function [-Woverloaded-virtual]' warnings - using TObject::Copy; // + using TObject::Copy; // Interaction(); Interaction(const InitialState & init, const ProcessInfo & proc); @@ -88,7 +88,7 @@ class Interaction : public TObject { int FSPrimLeptonPdg (void) const; ///< final state primary lepton pdg int RecoilNucleonPdg (void) const; ///< recoil nucleon pdg TParticlePDG * FSPrimLepton (void) const; ///< final state primary lepton - TParticlePDG * RecoilNucleon (void) const; ///< recoil nucleon + TParticlePDG * RecoilNucleon (void) const; ///< recoil nucleon // Copy, reset, print itself and build string code void Reset (void); @@ -132,10 +132,10 @@ class Interaction : public TObject { static Interaction * DFRCC (int tgt, int nuc, int probe, double E=0); static Interaction * DFRCC (int tgt, int nuc, int probe, const TLorentzVector & p4probe); static Interaction * COHCC (int tgt, int probe, unsigned int prod_pdg, double E=0); - static Interaction * COHCC (int tgt, int probe, unsigned int prod_pdg, + static Interaction * COHCC (int tgt, int probe, unsigned int prod_pdg, const TLorentzVector & p4probe); static Interaction * COHNC (int tgt, int probe, unsigned int prod_pdg, double E=0); - static Interaction * COHNC (int tgt, int probe, unsigned int prod_pdg, + static Interaction * COHNC (int tgt, int probe, unsigned int prod_pdg, const TLorentzVector & p4probe); static Interaction * CEvNS (int tgt, int probe, double E=0); static Interaction * CEvNS (int tgt, int probe, const TLorentzVector & p4probe); @@ -164,6 +164,8 @@ class Interaction : public TObject { static Interaction * DMDI (int tgt, int nuc, int qrk, bool sea, int probe, double E=0); static Interaction * DMDI (int tgt, int nuc, int probe, const TLorentzVector & p4probe); static Interaction * DMDI (int tgt, int nuc, int qrk, bool sea, int probe, const TLorentzVector & p4probe); + static Interaction * RESDM (int tgt, int nuc, int probe, double E=0); + static Interaction * RESDM (int tgt, int nuc, int probe, const TLorentzVector & p4probe); static Interaction * HNL (int probe, double E=0, int decayed_mode=-1); private: @@ -181,7 +183,7 @@ class Interaction : public TObject { Kinematics * fKinematics; ///< kinematical variables XclsTag * fExclusiveTag; ///< Additional info for exclusive channels KPhaseSpace * fKinePhSp; ///< Kinematic phase space - + ClassDef(Interaction,2) }; diff --git a/src/Framework/Interaction/KPhaseSpace.cxx b/src/Framework/Interaction/KPhaseSpace.cxx index 989297803e..6c5592f9da 100644 --- a/src/Framework/Interaction/KPhaseSpace.cxx +++ b/src/Framework/Interaction/KPhaseSpace.cxx @@ -8,6 +8,7 @@ Changes required to implement the GENIE Boosted Dark Matter module were installed by Josh Berger (Univ. of Wisconsin) + and Zachary Orr (Colorado State Univ.) */ //____________________________________________________________________________ @@ -107,9 +108,9 @@ double KPhaseSpace::Threshold(void) const double Ethresh = (mtot*mtot - Mi*Mi - mi*mi)/2/Mi; return Ethresh; } - + if (pi.IsNorm() ) return 0; - + if (pi.IsSingleKaon()) { int kaon_pdgc = xcls.StrangeHadronPdg(); double Mi = tgt.HitNucP4Ptr()->M(); // initial nucleon mass @@ -149,6 +150,7 @@ double KPhaseSpace::Threshold(void) const pi.IsDarkMatterElastic() || pi.IsInverseBetaDecay() || pi.IsResonant() || + pi.IsDarkMatterResonant() || pi.IsDeepInelastic() || pi.IsDarkMatterDeepInelastic() || pi.IsDiffractive()) @@ -184,7 +186,7 @@ double KPhaseSpace::Threshold(void) const double smin = TMath::Power(Wmin+ml,2.); double Ethr = 0.5*(smin-Mn2)/Mn; // threshold is different for dark matter case - if(pi.IsDarkMatterElastic() || pi.IsDarkMatterDeepInelastic()) { + if(pi.IsDarkMatterElastic() || pi.IsDarkMatterDeepInelastic() || pi.IsDarkMatterResonant()) { // Correction to minimum kinematic variables Wmin = Mn; smin = TMath::Power(Wmin+ml,2); @@ -307,6 +309,7 @@ bool KPhaseSpace::IsAboveThreshold(void) const pi.IsDarkMatterElastic() || pi.IsInverseBetaDecay() || pi.IsResonant() || + pi.IsDarkMatterResonant() || pi.IsDeepInelastic() || pi.IsDarkMatterDeepInelastic() || pi.IsDiffractive() || @@ -346,7 +349,7 @@ bool KPhaseSpace::IsAllowed(void) const // RES // Check the running W vs the W limits // & the running Q2 vs Q2 limits for the given W - if(pi.IsResonant()) { + if(pi.IsResonant() || pi.IsDarkMatterResonant()) { Range1D_t Wl = this->WLim(); Range1D_t Q2l = this->Q2Lim_W(); double W = kine.W(); @@ -454,7 +457,7 @@ Range1D_t KPhaseSpace::WLim(void) const bool is_em = pi.IsEM(); bool is_qel = pi.IsQuasiElastic() || pi.IsInverseBetaDecay() || pi.IsDarkMatterElastic(); bool is_inel = pi.IsDeepInelastic() || pi.IsResonant() || pi.IsDiffractive(); - bool is_dmdis = pi.IsDarkMatterDeepInelastic(); + bool is_dmdis = pi.IsDarkMatterDeepInelastic() || pi.IsDarkMatterResonant(); if(is_qel) { double MR = fInteraction->RecoilNucleon()->Mass(); @@ -530,7 +533,7 @@ Range1D_t KPhaseSpace::Q2Lim_W(void) const bool is_inel = pi.IsDeepInelastic() || pi.IsResonant() || pi.IsDiffractive(); bool is_coh = pi.IsCoherentProduction(); bool is_dme = pi.IsDarkMatterElastic(); - bool is_dmdis = pi.IsDarkMatterDeepInelastic(); + bool is_dmdis = pi.IsDarkMatterDeepInelastic() || pi.IsDarkMatterResonant(); if(!is_qel && !is_inel && !is_coh && !is_dme && !is_dmdis) return Q2l; @@ -587,7 +590,7 @@ Range1D_t KPhaseSpace::Q2Lim(void) const bool is_coh = pi.IsCoherentProduction(); bool is_cevns = pi.IsCoherentElastic(); bool is_dme = pi.IsDarkMatterElastic(); - bool is_dmdis = pi.IsDarkMatterDeepInelastic(); + bool is_dmdis = pi.IsDarkMatterDeepInelastic() || pi.IsDarkMatterResonant(); if(!is_qel && !is_inel && !is_coh && !is_cevns && !is_dme && !is_dmdis) return Q2l; @@ -711,7 +714,7 @@ Range1D_t KPhaseSpace::XLim(void) const return xl; } //DMDIS - bool is_dmdis = pi.IsDarkMatterDeepInelastic(); + bool is_dmdis = pi.IsDarkMatterDeepInelastic() || pi.IsDarkMatterResonant(); if(is_dmdis) { const InitialState & init_state = fInteraction->InitState(); double Ev = init_state.ProbeE(kRfHitNucRest); @@ -763,7 +766,7 @@ Range1D_t KPhaseSpace::YLim(void) const return yl; } //DMDIS - bool is_dmdis = pi.IsDarkMatterDeepInelastic(); + bool is_dmdis = pi.IsDarkMatterDeepInelastic() || pi.IsDarkMatterResonant(); if(is_dmdis) { const InitialState & init_state = fInteraction->InitState(); double Ev = init_state.ProbeE(kRfHitNucRest); @@ -836,7 +839,7 @@ Range1D_t KPhaseSpace::YLim_X(void) const return yl; } //DMDIS - bool is_dmdis = pi.IsDarkMatterDeepInelastic(); + bool is_dmdis = pi.IsDarkMatterDeepInelastic() || pi.IsDarkMatterResonant(); if(is_dmdis) { const InitialState & init_state = fInteraction->InitState(); double Ev = init_state.ProbeE(kRfHitNucRest); @@ -1001,7 +1004,7 @@ double KPhaseSpace::Threshold_SPP_iso(void) const { const InitialState & init_state = fInteraction->InitState(); PDGLibrary * pdglib = PDGLibrary::Instance(); - + // imply isospin symmetry double mpi = (pdglib->Find(kPdgPiP)->Mass() + pdglib->Find(kPdgPi0)->Mass() + pdglib->Find(kPdgPiM)->Mass())/3; double M = (pdglib->Find(kPdgProton)->Mass() + pdglib->Find(kPdgNeutron)->Mass())/2; @@ -1025,7 +1028,7 @@ Range1D_t KPhaseSpace::WLim_SPP(void) const // kinematic W-limits Wl.min = Mf + mpi; Wl.max = ECM - mf; - + if ( (Wl.max - Wl.min) < (Wl.max + Wl.min)*std::numeric_limits::epsilon() ) { Wl.min = 2*Wl.max*Wl.min/(Wl.max + Wl.min); @@ -1036,7 +1039,7 @@ Range1D_t KPhaseSpace::WLim_SPP(void) const Wl.min *= 1. + std::numeric_limits::epsilon(); Wl.max *= 1. - std::numeric_limits::epsilon(); } - + return Wl; } //____________________________________________________________________________ @@ -1055,7 +1058,7 @@ Range1D_t KPhaseSpace::WLim_SPP_iso(void) const // kinematic W-limits Wl.min = M + mpi; Wl.max = ECM - mf; - + if ( (Wl.max - Wl.min) < (Wl.max + Wl.min)*std::numeric_limits::epsilon() ) { Wl.min = 2*Wl.max*Wl.min/(Wl.max + Wl.min); @@ -1066,7 +1069,7 @@ Range1D_t KPhaseSpace::WLim_SPP_iso(void) const Wl.min *= 1. + std::numeric_limits::epsilon(); Wl.max *= 1. - std::numeric_limits::epsilon(); } - + return Wl; } //____________________________________________________________________________ @@ -1093,7 +1096,7 @@ Range1D_t KPhaseSpace::Q2Lim_W_SPP (void) const // kinematic Q2-limits Q2l.min = 2*(Ei_CM*Ef_CM - Pi_CM*Pf_CM) - mi2 - mf2; Q2l.max = 2*(Ei_CM*Ef_CM + Pi_CM*Pf_CM) - mi2 - mf2; - + if ( (Q2l.max - Q2l.min) < (Q2l.max + Q2l.min)*std::numeric_limits::epsilon() ) { Q2l.min = 2*Q2l.max*Q2l.min/(Q2l.max + Q2l.min); @@ -1120,11 +1123,11 @@ Range1D_t KPhaseSpace::Q2Lim_W_SPP_iso(void) const double mi2 = mi*mi; double mf2 = mf*mf; double W = kinematics::W(fInteraction); - + double Ei = init_state.ProbeE(kRfHitNucRest); double s = M*(M + 2*Ei) + mi2; double ECM = TMath::Sqrt(s); - + double Ei_CM = (s + mi2 - M*M)/2/ECM; double Ef_CM = (s + mf2 - W*W)/2/ECM; double Pi_CM = (Ei_CM - mi)<0?0:TMath::Sqrt(Ei_CM*Ei_CM - mi2); @@ -1132,7 +1135,7 @@ Range1D_t KPhaseSpace::Q2Lim_W_SPP_iso(void) const // kinematic Q2-limits Q2l.min = 2*(Ei_CM*Ef_CM - Pi_CM*Pf_CM) - mi2 - mf2; Q2l.max = 2*(Ei_CM*Ef_CM + Pi_CM*Pf_CM) - mi2 - mf2; - + if ( (Q2l.max - Q2l.min) < (Q2l.max + Q2l.min)*std::numeric_limits::epsilon() ) { Q2l.min = 2*Q2l.max*Q2l.min/(Q2l.max + Q2l.min); @@ -1143,8 +1146,7 @@ Range1D_t KPhaseSpace::Q2Lim_W_SPP_iso(void) const Q2l.min *= 1. + std::numeric_limits::epsilon(); Q2l.max *= 1. - std::numeric_limits::epsilon(); } - + return Q2l; } //____________________________________________________________________________ - diff --git a/src/Framework/Interaction/ProcessInfo.cxx b/src/Framework/Interaction/ProcessInfo.cxx index 1456b9c383..01aba4c372 100644 --- a/src/Framework/Interaction/ProcessInfo.cxx +++ b/src/Framework/Interaction/ProcessInfo.cxx @@ -8,6 +8,7 @@ Changes required to implement the GENIE Boosted Dark Matter module were installed by Josh Berger (Univ. of Wisconsin) + and Zachary Orr (Colorado State Univ.) Changes required to implement the GENIE Dark Neutrino module were installed by Iker de Icaza (Univ. of Sussex) @@ -101,6 +102,11 @@ bool ProcessInfo::IsResonant(void) const return (fScatteringType == kScResonant); } //____________________________________________________________________________ +bool ProcessInfo::IsDarkMatterResonant(void) const +{ + return (fScatteringType == kScDarkMatterResonant); +} +//____________________________________________________________________________ bool ProcessInfo::IsCoherentProduction(void) const { return (fScatteringType == kScCoherentProduction); diff --git a/src/Framework/Interaction/ProcessInfo.h b/src/Framework/Interaction/ProcessInfo.h index cf2548089c..69d2cbfe49 100644 --- a/src/Framework/Interaction/ProcessInfo.h +++ b/src/Framework/Interaction/ProcessInfo.h @@ -13,6 +13,7 @@ Changes required to implement the GENIE Boosted Dark Matter module were installed by Josh Berger (Univ. of Wisconsin) + and Zachary Orr (Colorado State Univ.) Changes required to implement the GENIE Dark Neutrino module were installed by Iker de Icaza (Univ. of Sussex) @@ -64,6 +65,7 @@ class ProcessInfo : public TObject { bool IsDeepInelastic (void) const; bool IsDarkMatterDeepInelastic (void) const; bool IsResonant (void) const; + bool IsDarkMatterResonant (void) const; bool IsCoherentProduction (void) const; bool IsCoherentElastic (void) const; bool IsSinglePion (void) const; diff --git a/src/Framework/Interaction/ScatteringType.h b/src/Framework/Interaction/ScatteringType.h index bd4f80b231..9acfab8e73 100644 --- a/src/Framework/Interaction/ScatteringType.h +++ b/src/Framework/Interaction/ScatteringType.h @@ -34,7 +34,7 @@ namespace genie { // append to the end of the total list and set a new enum counter value. typedef enum EScatteringType { - kScUnknown = -100, + kScUnknown = -100, kScNull = 0, kScQuasiElastic, kScSingleKaon, @@ -56,7 +56,8 @@ typedef enum EScatteringType { kScDarkMatterElastic = 101, kScDarkMatterDeepInelastic, kScDarkMatterElectron, - kScNorm + kScDarkMatterResonant, + kScNorm = 110 } ScatteringType_t; class ScatteringType @@ -89,6 +90,7 @@ class ScatteringType case(kScDarkMatterElastic) : return "DMEL"; break; case(kScDarkMatterDeepInelastic) : return "DMDIS"; break; case(kScDarkMatterElectron) : return "DME"; break; + case(kScDarkMatterResonant) : return "DMRES"; break; default : return "Unknown"; break; } return "Unknown"; diff --git a/src/Physics/BoostedDarkMatter/EventGen/DMRESHadronicSystemGenerator.cxx b/src/Physics/BoostedDarkMatter/EventGen/DMRESHadronicSystemGenerator.cxx new file mode 100644 index 0000000000..8441a688a9 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/EventGen/DMRESHadronicSystemGenerator.cxx @@ -0,0 +1,236 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + Zachary W. Orr + Colorado State University + + based on code by + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory +*/ +//____________________________________________________________________________ + +// #include +// #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,6) +// #include +// #else +// #include +// #endif + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/EventGen/EVGThreadException.h" +#include "Framework/GHEP/GHepStatus.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Framework/GHEP/GHepFlags.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Interaction/SppChannel.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/ParticleData/BaryonResonance.h" +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/ParticleData/PDGLibrary.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/Utils/PrintUtils.h" +// #include "Physics/Decay/DecayModelI.h" +#include "Physics/BoostedDarkMatter/EventGen/DMRESHadronicSystemGenerator.h" + +using namespace genie; +using namespace genie::constants; + +//___________________________________________________________________________ +DMRESHadronicSystemGenerator::DMRESHadronicSystemGenerator() : +HadronicSystemGenerator("genie::DMRESHadronicSystemGenerator") +{ + +} +//___________________________________________________________________________ +DMRESHadronicSystemGenerator::DMRESHadronicSystemGenerator(string config): +HadronicSystemGenerator("genie::DMRESHadronicSystemGenerator", config) +{ + +} +//___________________________________________________________________________ +DMRESHadronicSystemGenerator::~DMRESHadronicSystemGenerator() +{ + +} +//___________________________________________________________________________ +void DMRESHadronicSystemGenerator::ProcessEventRecord(GHepRecord * evrec) const +{ +// This method generates the final state hadronic system + + // Get the right resonance PDG code so that the selected resonance + // conserves charge + int pdgc = GetResonancePdgCode(evrec); + + // Add the selected resonance + this->AddResonance(evrec,pdgc); + + // Decay the resonance (and its decay products, if they include resonances) + fResonanceDecayer->ProcessEventRecord(evrec); + + // Add the baryon resonance decay products at the event record + //this->AddResonanceDecayProducts(evrec,pdgc); + + // Handle resonance decay channels to other resonances or short-living + // partices + //LOG("RESHadronicVtx", pNOTICE) + // << "Decay any resonance in the initial resonance decay products"; + //this->PreHadronTransportDecays(evrec); +} +//___________________________________________________________________________ +int DMRESHadronicSystemGenerator::GetResonancePdgCode(GHepRecord * evrec) const +{ +// In the RES thread the resonance is specifed when selecting interaction +// This method adds it to the GHEP record. + + Interaction * interaction = evrec->Summary(); + + // Get resonance id + const XclsTag & xcls = interaction->ExclTag(); + assert(xcls.KnownResonance()); + Resonance_t res = xcls.Resonance(); + + // Get resonance charge + int q_res = this->ResonanceCharge(evrec); + + // Find resonance PDG code from resonance charge and id + int pdgc = utils::res::PdgCode(res, q_res); + + LOG("RESHadronicVtx", pNOTICE) + << "Selected event has RES with PDGC = " << pdgc << ", Q = " << q_res; + + return pdgc; +} +//___________________________________________________________________________ +void DMRESHadronicSystemGenerator::AddResonance( + GHepRecord * evrec, int pdgc) const +{ + //-- Compute RES p4 = p4(neutrino) + p4(hit nucleon) - p4(primary lepton) + TLorentzVector p4 = this->Hadronic4pLAB(evrec); + + //-- Add the resonance at the EventRecord + GHepStatus_t ist = kIStPreDecayResonantState; + int mom = evrec->HitNucleonPosition(); + + //-- Get vtx position + GHepParticle * neutrino = evrec->Probe(); + const TLorentzVector & vtx = *(neutrino->X4()); + + evrec->AddParticle(pdgc, ist, mom,-1,-1,-1, p4, vtx); +} +//___________________________________________________________________________ +// void RESHadronicSystemGenerator::AddResonanceDecayProducts( +// GHepRecord * evrec, int pdgc) const +// { +// // Decay the baryon resonance, take the decay products, boost them in the LAB +// // and add them in the GHEP record. +// // Unlike the SPP thread where the resonance decay products are determined +// // from the selected SPP channel, in the RES thread we can any of the the +// // resonance's kinematically available(the RES is not on the mass shell)decay +// // channels +// +// // find the resonance position +// int irpos = evrec->ParticlePosition(pdgc, kIStPreDecayResonantState, 0); +// assert(irpos>0); +// +// // access the GHEP entry +// GHepParticle * resonance = evrec->Particle(irpos); +// assert(resonance); +// +// // resonance location +// const TLorentzVector & x4 = *(resonance->X4()); +// +// // prepare the decayer inputs +// DecayerInputs_t dinp; +// dinp.PdgCode = pdgc; +// dinp.P4 = resonance->P4(); +// +// // do the decay +// TClonesArray * decay_products = fResonanceDecayer->Decay(dinp); +// if(!decay_products) { +// LOG("RESHadronicVtx", pWARN) << "Got an empty decay product list!"; +// LOG("RESHadronicVtx", pWARN) +// << "Quitting the current event generation thread"; +// +// evrec->EventFlags()->SetBitNumber(kHadroSysGenErr, true); +// +// genie::exceptions::EVGThreadException exception; +// exception.SetReason("Not enough phase space for hadronizer"); +// exception.SwitchOnFastForward(); +// throw exception; +// +// return; +// } +// +// // get the decay weight (if any) +// double wght = fResonanceDecayer->Weight(); +// +// // update the event weight +// evrec->SetWeight(wght * evrec->Weight()); +// +// // decide the istatus of decay products +// GHepParticle * nuc = evrec->TargetNucleus(); +// GHepStatus_t dpist = (nuc) ? kIStHadronInTheNucleus : kIStStableFinalState; +// +// // if the list is not empty, boost and copy the decay products in GHEP +// if(decay_products) { +// +// // first, mark the resonance as decayed +// resonance->SetStatus(kIStDecayedState); +// +// // loop over the daughter and add them to the event record +// TMCParticle * dpmc = 0; +// TObjArrayIter decay_iter(decay_products); +// +// while( (dpmc = (TMCParticle *) decay_iter.Next()) ) { +// +// int dppdg = dpmc->GetKF(); +// double px = dpmc->GetPx(); +// double py = dpmc->GetPy(); +// double pz = dpmc->GetPz(); +// double E = dpmc->GetEnergy(); +// TLorentzVector p4(px,py,pz,E); +// +// //-- Only add the decay products - the mother particle already exists +// if(dpmc->GetKS()==1) { +// evrec->AddParticle(dppdg,dpist,irpos,-1,-1,-1, p4, x4); +// } +// } +// +// // done, release the original list +// decay_products->Delete(); +// delete decay_products; +// }// !=0 +// } +//___________________________________________________________________________ +void DMRESHadronicSystemGenerator::Configure(const Registry & config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//___________________________________________________________________________ +void DMRESHadronicSystemGenerator::Configure(string config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//___________________________________________________________________________ +void DMRESHadronicSystemGenerator::LoadConfig(void) +{ + fResonanceDecayer = 0; + //fPreINukeDecayer = 0; + + // Get the specified decayers + fResonanceDecayer = + dynamic_cast (this->SubAlg("Decayer")); + assert(fResonanceDecayer); + // fPreINukeDecayer = + // dynamic_cast (this->SubAlg("PreTransportDecayer")); + // assert(fPreINukeDecayer); +} +//___________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/EventGen/DMRESHadronicSystemGenerator.h b/src/Physics/BoostedDarkMatter/EventGen/DMRESHadronicSystemGenerator.h new file mode 100644 index 0000000000..960a8e7188 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/EventGen/DMRESHadronicSystemGenerator.h @@ -0,0 +1,67 @@ +//____________________________________________________________________________ +/*! + +\class genie::DMRESHadronicSystemGenerator + +\brief Generates the 'final state' hadronic system in DM RES interactions. (same as v RES) + It adds the remnant nucleus (if any), the pre-selected resonance + and the resonance decay products at the GHEP record. + Unlike the SPP thread, in the RES thread the resonance is specified + at the time an interaction is selected but its decay products not + (semi-inclusive resonance reactions). The off the mass-shell baryon + resonance is decayed using a phase space generator. All kinematically + available decay channels are being used (not just 1 pi channels). + Is a concrete implementation of the EventRecordVisitorI interface. + +\author Zachary W. Orr + Colorado State University + + based on code by + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + + +\created November 23, 2004 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _DMRES_HADRONIC_SYSTEM_GENERATOR_H_ +#define _DMRES_HADRONIC_SYSTEM_GENERATOR_H_ + +#include "Physics/Common/HadronicSystemGenerator.h" + +namespace genie { + +class Decayer; + +class DMRESHadronicSystemGenerator : public HadronicSystemGenerator { + +public : + DMRESHadronicSystemGenerator(); + DMRESHadronicSystemGenerator(string config); + ~DMRESHadronicSystemGenerator(); + + // implement the EventRecordVisitorI interface + void ProcessEventRecord(GHepRecord * event_rec) const; + + // overload the Algorithm::Configure() methods to load private data + // members from configuration options + void Configure(const Registry & config); + void Configure(string config); + +private: + + void LoadConfig (void); + int GetResonancePdgCode (GHepRecord * evrec) const; + void AddResonance (GHepRecord * evrec, int pdgc) const; + // void AddResonanceDecayProducts (GHepRecord * evrec, int pdgc) const; + + const EventRecordVisitorI * fResonanceDecayer; +}; + +} // genie namespace + +#endif // _DMRES_HADRONIC_SYSTEM_GENERATOR_H_ diff --git a/src/Physics/BoostedDarkMatter/EventGen/DMRESInteractionListGenerator.cxx b/src/Physics/BoostedDarkMatter/EventGen/DMRESInteractionListGenerator.cxx new file mode 100644 index 0000000000..f71d47c700 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/EventGen/DMRESInteractionListGenerator.cxx @@ -0,0 +1,169 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + Zachary W. Orr + Colorado State University + + based on code by + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory +*/ +//____________________________________________________________________________ + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/EventGen/InteractionList.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Physics/BoostedDarkMatter/EventGen/DMRESInteractionListGenerator.h" + +using namespace genie; + +//___________________________________________________________________________ +DMRESInteractionListGenerator::DMRESInteractionListGenerator() : +InteractionListGeneratorI("genie::DMRESInteractionListGenerator") +{ + +} +//___________________________________________________________________________ +DMRESInteractionListGenerator::DMRESInteractionListGenerator(string config) : +InteractionListGeneratorI("genie::DMRESInteractionListGenerator", config) +{ + +} +//___________________________________________________________________________ +DMRESInteractionListGenerator::~DMRESInteractionListGenerator() +{ + +} +//___________________________________________________________________________ +InteractionList * DMRESInteractionListGenerator::CreateInteractionList( + const InitialState & init_state) const +{ + LOG("IntLst", pINFO) << "InitialState = " << init_state.AsString(); + + // In the thread generating interactions from the list produced here (RES), + // we simulate (for free and nuclear targets) semi-inclusive resonance + // interactions: v + N -> v(l) + R -> v(l) + X + // Specifically, the RES thread generates: + // + // CC: + // nu + p (A) -> l- R (A), for all resonances with Q=+2 + // nu + n (A) -> l- R (A), for all resonances with Q=+1 + // \bar{nu} + p (A) -> l+ R (A), for all resonances with Q= 0 + // \bar{nu} + n (A) -> l+ R (A), for all resonances with Q=-1 + // NC: + // nu + p (A) -> nu R (A), for all resonances with Q=+1 + // nu + n (A) -> nu R (A), for all resonances with Q= 0 + // \bar{nu} + p (A) -> \bar{nu} R (A), for all resonances with Q=+1 + // \bar{nu} + n (A) -> \bar{nu} R (A), for all resonances with Q= 0 + // + // and then the resonance R should be allowed to decay to get the full + // hadronic final state X. All decay channels kinematically accessible + // to the (off the mass-shell produced) resonance can be allowed. + + // specify the requested interaction type + InteractionType_t inttype; + // Only accept DM scattering here + if (fIsDM) inttype = kIntDarkMatter; + else { + LOG("IntLst", pWARN) + << "Unknown InteractionType! Returning NULL InteractionList " + << "for init-state: " << init_state.AsString(); + return 0; + } + + // create a process information object + ProcessInfo proc_info(kScDarkMatterResonant, inttype); + + // learn whether the input nuclear or free target has avail. p and n + const Target & inp_target = init_state.Tgt(); + bool hasP = (inp_target.Z() > 0); + bool hasN = (inp_target.N() > 0); + + // possible hit nucleons + const int hit_nucleon[2] = {kPdgProton, kPdgNeutron}; + + // create an interaction list + InteractionList * intlist = new InteractionList; + + // loop over all baryon resonances considered in current MC job + unsigned int nres = fResList.NResonances(); + for(unsigned int ires = 0; ires < nres; ires++) { + + //get current resonance + Resonance_t res = fResList.ResonanceId(ires); + + // loop over hit nucleons + for(int i=0; i<2; i++) { + + // proceed only if the hit nucleon exists in the current init state + if(hit_nucleon[i]==kPdgProton && !hasP) continue; + if(hit_nucleon[i]==kPdgNeutron && !hasN) continue; + + // proceed only if the current resonance conserves charge + // (the only problematic case is when the RES charge has to be +2 + // because then only Delta resonances are possible) +// bool skip_res = proc_info.IsWeakCC() && +// pdg::IsNeutrino(init_state.ProbePdg()) && +// (hit_nucleon[i]==kPdgProton) && +// (!utils::res::IsDelta(res)); +// if(skip_res) continue; + + // create an interaction + Interaction * interaction = new Interaction(init_state, proc_info); + + // add the struck nucleon + Target * target = interaction->InitStatePtr()->TgtPtr(); + target->SetHitNucPdg(hit_nucleon[i]); + + // add the baryon resonance in the exclusive tag + XclsTag * xcls = interaction->ExclTagPtr(); + xcls->SetResonance(res); + + // add the interaction at the interaction list + intlist->push_back(interaction); + + }//hit nucleons + } //resonances + + if(intlist->size() == 0) { + LOG("IntLst", pERROR) + << "Returning NULL InteractionList for init-state: " + << init_state.AsString(); + delete intlist; + return 0; + } + + return intlist; +} +//___________________________________________________________________________ +void DMRESInteractionListGenerator::Configure(const Registry & config) +{ + Algorithm::Configure(config); + this->LoadConfigData(); +} +//____________________________________________________________________________ +void DMRESInteractionListGenerator::Configure(string config) +{ + Algorithm::Configure(config); + this->LoadConfigData(); +} +//____________________________________________________________________________ +void DMRESInteractionListGenerator::LoadConfigData(void) +{ + string resonances = ""; + this->GetParam("ResonanceNameList", resonances); + SLOG("IntLst", pDEBUG) << "Resonance list: " << resonances; + + fResList.Clear(); + fResList.DecodeFromNameList(resonances); + LOG("IntLst", pDEBUG) << fResList; + + this->GetParamDef("is-DM", fIsDM, false); +} +//____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/EventGen/DMRESInteractionListGenerator.h b/src/Physics/BoostedDarkMatter/EventGen/DMRESInteractionListGenerator.h new file mode 100644 index 0000000000..558ab01cd2 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/EventGen/DMRESInteractionListGenerator.h @@ -0,0 +1,54 @@ +//____________________________________________________________________________ +/*! + +\class genie::DMRESInteractionListGenerator + +\brief Creates a list of all the interactions that can be generated by the + RES thread (generates semi-inclusive resonance reactions). + Concrete implementations of the InteractionListGeneratorI interface. + follows same procedure as RESInteractionListGenerator.h + +\author Zach Orr + Colorado State University + + +\created Jan 27, 2024 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _DMRES_INTERACTION_LIST_GENERATOR_H_ +#define _DMRES_INTERACTION_LIST_GENERATOR_H_ + +#include "Framework/ParticleData/BaryonResList.h" +#include "Framework/EventGen/InteractionListGeneratorI.h" + +namespace genie { + +class DMRESInteractionListGenerator : public InteractionListGeneratorI { + +public : + DMRESInteractionListGenerator(); + DMRESInteractionListGenerator(string config); + ~DMRESInteractionListGenerator(); + + // implement the InteractionListGeneratorI interface + InteractionList * CreateInteractionList(const InitialState & init) const; + + // overload the Algorithm::Configure() methods to load private data + // members from configuration options + void Configure(const Registry & config); + void Configure(string config); + +private: + + void LoadConfigData(void); + + bool fIsDM; + BaryonResList fResList; +}; + +} // genie namespace +#endif // _DMRES_INTERACTION_LIST_GENERATOR_H_ diff --git a/src/Physics/BoostedDarkMatter/EventGen/DMRESKinematicsGenerator.cxx b/src/Physics/BoostedDarkMatter/EventGen/DMRESKinematicsGenerator.cxx new file mode 100644 index 0000000000..bac01c3af7 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/EventGen/DMRESKinematicsGenerator.cxx @@ -0,0 +1,372 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + /author Zach Orr + Colorado State University + follows same procedure as RESKinematicsGenerator.cxx + + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory +*/ +//____________________________________________________________________________ + +#include +#include +#include + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/Conventions/Controls.h" +#include "Framework/Conventions/KineVar.h" +#include "Framework/Conventions/KinePhaseSpace.h" +#include "Framework/EventGen/EVGThreadException.h" +#include "Framework/EventGen/EventGeneratorI.h" +#include "Framework/EventGen//RunningThreadInfo.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepFlags.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/Numerical/RandomGen.h" +#include "Framework/Numerical/MathUtils.h" +#include "Framework/ParticleData/BaryonResonance.h" +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/Utils/KineUtils.h" +#include "Physics/BoostedDarkMatter/EventGen/DMRESKinematicsGenerator.h" + +using namespace genie; +using namespace genie::controls; +using namespace genie::utils; + +//___________________________________________________________________________ +DMRESKinematicsGenerator::DMRESKinematicsGenerator() : +KineGeneratorWithCache("genie::DMRESKinematicsGenerator") +{ + fEnvelope = 0; +} +//___________________________________________________________________________ +DMRESKinematicsGenerator::DMRESKinematicsGenerator(string config) : +KineGeneratorWithCache("genie::DMRESKinematicsGenerator", config) +{ + fEnvelope = 0; +} +//___________________________________________________________________________ +DMRESKinematicsGenerator::~DMRESKinematicsGenerator() +{ + if(fEnvelope) delete fEnvelope; +} +//___________________________________________________________________________ +void DMRESKinematicsGenerator::ProcessEventRecord(GHepRecord * evrec) const +{ + if(fGenerateUniformly) { + LOG("DMRESKinematics", pNOTICE) + << "Generating kinematics uniformly over the allowed phase space"; + } + + //-- Get the random number generators + RandomGen * rnd = RandomGen::Instance(); + + //-- Access cross section algorithm for running thread + RunningThreadInfo * rtinfo = RunningThreadInfo::Instance(); + const EventGeneratorI * evg = rtinfo->RunningThread(); + fXSecModel = evg->CrossSectionAlg(); + + //-- Get the interaction from the GHEP record + Interaction * interaction = evrec->Summary(); + interaction->SetBit(kISkipProcessChk); + + //-- DM process + bool is_DM = interaction->ProcInfo().IsDarkMatterResonant(); + + //-- Compute the W limits + // (the physically allowed W's, unless an external cut is imposed) + const KPhaseSpace & kps = interaction->PhaseSpace(); + Range1D_t W = kps.Limits(kKVW); + + if(W.max <=0 || W.min>=W.max) { + LOG("DMRESKinematics", pWARN) << "No available phase space"; + evrec->EventFlags()->SetBitNumber(kKineGenErr, true); + genie::exceptions::EVGThreadException exception; + exception.SetReason("No available phase space"); + exception.SwitchOnFastForward(); + throw exception; + } + + const InitialState & init_state = interaction -> InitState(); + double E = init_state.ProbeE(kRfHitNucRest); + + //-- For the subsequent kinematic selection with the rejection method: + // Calculate the max differential cross section or retrieve it from the + // cache. Throw an exception and quit the evg thread if a non-positive + // value is found. + // If the kinematics are generated uniformly over the allowed phase + // space the max xsec is irrelevant + double xsec_max = (fGenerateUniformly) ? -1 : this->MaxXSec(evrec); + + //-- Try to select a valid W, Q2 pair using the rejection method + double dW = W.max - W.min; + double xsec = -1; + + unsigned int iter = 0; + bool accept = false; + while(1) { + iter++; + if(iter > kRjMaxIterations) { + LOG("DMRESKinematics", pWARN) + << "*** Could not select a valid (W,Q^2) pair after " + << iter << " iterations"; + evrec->EventFlags()->SetBitNumber(kKineGenErr, true); + genie::exceptions::EVGThreadException exception; + exception.SetReason("Couldn't select kinematics"); + exception.SwitchOnFastForward(); + throw exception; + } + + double gW = 0; // current hadronic invariant mass + double gQ2 = 0; // current momentum transfer + double gQD2 = 0; // tranformed Q2 to take out dipole form + + if(fGenerateUniformly) + { + //-- Generate a W uniformly in the kinematically allowed range. + // For the generated W, compute the Q2 range and generate a value + // uniformly over that range + gW = W.min + dW * rnd->RndKine().Rndm(); + interaction->KinePtr()->SetW(gW); + Range1D_t Q2 = kps.Q2Lim_W(); + if(Q2.max<=0. || Q2.min>=Q2.max) continue; + gQ2 = Q2.min + (Q2.max-Q2.min) * rnd->RndKine().Rndm(); + interaction->SetBit(kISkipKinematicChk); + } + else + { + + // dm scattering + // Selecting unweighted event kinematics using an importance sampling + // method. Q2 with be transformed to QD2 to take out the dipole form. + interaction->KinePtr()->SetW(W.min); + Range1D_t Q2 = kps.Q2Lim_W(); + double Q2min = -99.; + if (is_DM) + Q2min = Q2.min + kASmallNum; + else + Q2min = 0 + kASmallNum; + double Q2max = Q2.max - kASmallNum; + + // In unweighted mode - use transform that takes out the dipole form + double QD2min = utils::kinematics::Q2toQD2(Q2max); + double QD2max = utils::kinematics::Q2toQD2(Q2min); + + gW = W.min + dW * rnd->RndKine().Rndm(); + gQD2 = QD2min + (QD2max - QD2min) * rnd->RndKine().Rndm(); + + // QD2 -> Q2 + gQ2 = utils::kinematics::QD2toQ2(gQD2); + } // uniformly over phase space? + + LOG("DMRESKinematics", pINFO) << "Trying: W = " << gW << ", Q2 = " << gQ2; + + //-- Set kinematics for current trial + interaction->KinePtr()->SetW(gW); + interaction->KinePtr()->SetQ2(gQ2); + + //-- Computing cross section for the current kinematics + xsec = fXSecModel->XSec(interaction, kPSWQD2fE); + //-- Decide whether to accept the current kinematics + if(!fGenerateUniformly) + { + // unified neutrino / electron scattering + double t = xsec_max * rnd->RndKine().Rndm(); + this->AssertXSecLimits(interaction, xsec, xsec_max); + accept = (t < xsec); + } // charged lepton or neutrino scattering? + else + { + accept = (xsec>0); + } // uniformly over phase space + + //-- If the generated kinematics are accepted, finish-up module's job + if(accept) { + LOG("DMRESKinematics", pINFO) + << "Selected: W = " << gW << ", Q2 = " << gQ2; + // reset 'trust' bits + interaction->ResetBit(kISkipProcessChk); + interaction->ResetBit(kISkipKinematicChk); + + // compute x,y for selected W,Q2 + // note: hit nucleon can be off the mass-shell + double gx=-1, gy=-1; + double M = init_state.Tgt().HitNucP4().M(); + kinematics::WQ2toXY(E,M,gW,gQ2,gx,gy); + + // set the cross section for the selected kinematics + evrec->SetDiffXSec(xsec,kPSWQ2fE); + + // for uniform kinematics, compute an event weight as + // wght = (phase space volume)*(differential xsec)/(event total xsec) + if(fGenerateUniformly) { + double vol = kinematics::PhaseSpaceVolume(interaction,kPSWQ2fE); + double totxsec = evrec->XSec(); + double wght = (vol/totxsec)*xsec; + LOG("DMRESKinematics", pNOTICE) << "Kinematics wght = "<< wght; + + // apply computed weight to the current event weight + wght *= evrec->Weight(); + LOG("DMRESKinematics", pNOTICE) << "Current event wght = " << wght; + evrec->SetWeight(wght); + } + + // lock selected kinematics & clear running values + interaction->KinePtr()->SetQ2(gQ2, true); + interaction->KinePtr()->SetW (gW, true); + interaction->KinePtr()->Setx (gx, true); + interaction->KinePtr()->Sety (gy, true); + interaction->KinePtr()->ClearRunningValues(); + + return; + } // accept + } // iterations +} +//___________________________________________________________________________ +void DMRESKinematicsGenerator::Configure(const Registry & config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//____________________________________________________________________________ +void DMRESKinematicsGenerator::Configure(string config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//____________________________________________________________________________ +void DMRESKinematicsGenerator::LoadConfig(void) +{ + // Safety factor for the maximum differential cross section + this->GetParamDef("MaxXSec-SafetyFactor", fSafetyFactor, 1.25); + + // Minimum energy for which max xsec would be cached, forcing explicit + // calculation for lower eneries + this->GetParamDef("Cache-MinEnergy", fEMin, 0.5); + + // Load Wcut used in DIS/RES join scheme + this->GetParam("Wcut", fWcut); + + // Maximum allowed fractional cross section deviation from maxim cross + // section used in rejection method + this->GetParamDef("MaxXSec-DiffTolerance", fMaxXSecDiffTolerance, 999999.); + assert(fMaxXSecDiffTolerance>=0); + + // Generate kinematics uniformly over allowed phase space and compute + // an event weight? + this->GetParamDef("UniformOverPhaseSpace", fGenerateUniformly, false); + + // Envelope employed when importance sampling is used + // (initialize with dummy range) + if(fEnvelope) delete fEnvelope; + fEnvelope = new TF2("res-envelope", + kinematics::RESImportanceSamplingEnvelope,0.01,1,0.01,1,4); + // stop ROOT from deleting this object of its own volition + gROOT->GetListOfFunctions()->Remove(fEnvelope); +} + +double DMRESKinematicsGenerator::ComputeMaxXSec( + const Interaction * interaction) const +{ +// Computes the maximum differential cross section in the requested phase +// space. This method overloads KineGeneratorWithCache::ComputeMaxXSec +// method and the value is cached at a circular cache branch for retrieval +// during subsequent event generation. +// The computed max differential cross section does not need to be the exact +// maximum. The number used in the rejection method will be scaled up by a +// safety factor. But this needs to be fast - do not use a very fine grid. + + double max_xsec = 0.; + + const InitialState & init_state = interaction -> InitState(); + double E = init_state.ProbeE(kRfHitNucRest); + bool is_em = interaction->ProcInfo().IsEM(); + double Q2Thres = is_em ? utils::kinematics::electromagnetic::kMinQ2Limit : controls::kMinQ2Limit; + + double md; + if(!interaction->ExclTag().KnownResonance()) md=1.23; + else { + Resonance_t res = interaction->ExclTag().Resonance(); + md=res::Mass(res); + } + + // ** 2-D Scan + const KPhaseSpace & kps = interaction->PhaseSpace(); + Range1D_t rW = kps.WLim(); + + int NW = 20; + double Wmin = rW.min + kASmallNum; + double Wmax = rW.max - kASmallNum; + + Wmax = TMath::Min(Wmax,fWcut); + + Wmin = TMath::Max(Wmin, md-.3); + Wmax = TMath::Min(Wmax, md+.3); + + if(Wmax-Wmin<0.05) { NW=1; Wmin=Wmax; } + + double dW = (NW>1) ? (Wmax-Wmin)/(NW-1) : 0.; + + for(int iw=0; iwKinePtr()->SetW(W); + + int NQ2 = 25; + int NQ2b = 4; + + Range1D_t rQ2 = kps.Q2Lim_W(); + if( rQ2.max < Q2Thres || rQ2.min <=0 ) continue; + if( rQ2.max-rQ2.min<0.02 ) {NQ2=5; NQ2b=3;} + + double logQ2min = TMath::Log(rQ2.min+kASmallNum); + double logQ2max = TMath::Log(rQ2.max-kASmallNum); + double dlogQ2 = (logQ2max - logQ2min) /(NQ2-1); + double xseclast = -1; + bool increasing = true; + + for(int iq2=0; iq2KinePtr()->SetQ2(Q2); + double xsec = fXSecModel->XSec(interaction, kPSWQD2fE); + LOG("DMRESKinematics", pDEBUG) + << "xsec(W= " << W << ", Q2= " << Q2 << ") = " << xsec; + max_xsec = TMath::Max(xsec, max_xsec); + increasing = xsec-xseclast>=0; + xseclast=xsec; + + // once the cross section stops increasing, I reduce the step size and + // step backwards a little bit to handle cases that the max cross section + // is grossly underestimated (very peaky distribution & large step) + if(!increasing) + { + dlogQ2/=NQ2b; + for(int iq2b=0; iq2bKinePtr()->SetQ2(Q2); + xsec = fXSecModel->XSec(interaction, kPSWQD2fE); + LOG("DMRESKinematics", pDEBUG) + << "xsec(W= " << W << ", Q2= " << Q2 << ") = " << xsec; + max_xsec = TMath::Max(xsec, max_xsec); + } + break; + } + } // Q2 + }//W + + // Apply safety factor, since value retrieved from the cache might + // correspond to a slightly different energy + // Apply larger safety factor for smaller energies. + max_xsec *= ( (El+Resonance) kinematics. + Is a concrete implementation of the EventRecordVisitorI interface. + Follows same procedure as RESKinematicsGenerator.h + +\author Zach Orr + Colorado State University + +\created November 18, 2004 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _DMRES_KINEMATICS_GENERATOR_H_ +#define _DMRES_KINEMATICS_GENERATOR_H_ + +#include "Framework/Utils/Range1.h" +#include "Physics/Common/KineGeneratorWithCache.h" + +class TF2; + +namespace genie { + +class DMRESKinematicsGenerator : public KineGeneratorWithCache { + +public : + DMRESKinematicsGenerator(); + DMRESKinematicsGenerator(string config); + ~DMRESKinematicsGenerator(); + + // implement the EventRecordVisitorI interface + void ProcessEventRecord(GHepRecord * event_rec) const; + + // overload the Algorithm::Configure() methods to load private data + // members from configuration options + void Configure(const Registry & config); + void Configure(string config); + +private: + void LoadConfig (void); + double ComputeMaxXSec (const Interaction * interaction) const; + + mutable TF2 * fEnvelope; ///< 2-D envelope used for importance sampling + double fWcut; ///< Wcut parameter in DIS/RES join scheme +}; + +} // genie namespace +#endif // _DMRES_KINEMATICS_GENERATOR_H_ diff --git a/src/Physics/BoostedDarkMatter/EventGen/DMRESOutgoingDarkGenerator.cxx b/src/Physics/BoostedDarkMatter/EventGen/DMRESOutgoingDarkGenerator.cxx new file mode 100644 index 0000000000..4b0d2bbcb9 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/EventGen/DMRESOutgoingDarkGenerator.cxx @@ -0,0 +1,51 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + + Author: Zach Orr + Colorado State University + + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory +*/ +//____________________________________________________________________________ + +#include + +#include "Physics/BoostedDarkMatter/EventGen/DMRESOutgoingDarkGenerator.h" +#include "Framework/EventGen/EVGThreadException.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Framework/GHEP/GHepFlags.h" +#include "Framework/Messenger/Messenger.h" + +using namespace genie; + +//___________________________________________________________________________ +DMRESOutgoingDarkGenerator::DMRESOutgoingDarkGenerator() : +OutgoingDarkGenerator("genie::DMRESOutgoingDarkGenerator") +{ + +} +//___________________________________________________________________________ +DMRESOutgoingDarkGenerator::DMRESOutgoingDarkGenerator(string config) : +OutgoingDarkGenerator("genie::DMRESOutgoingDarkGenerator", config) +{ + +} +//___________________________________________________________________________ +DMRESOutgoingDarkGenerator::~DMRESOutgoingDarkGenerator() +{ + +} +//___________________________________________________________________________ +void DMRESOutgoingDarkGenerator::ProcessEventRecord(GHepRecord * evrec) const +{ +// This method generates the final state primary lepton in RES events + + // no modification is required to the std implementation + OutgoingDarkGenerator::ProcessEventRecord(evrec); +} +//___________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/EventGen/DMRESOutgoingDarkGenerator.h b/src/Physics/BoostedDarkMatter/EventGen/DMRESOutgoingDarkGenerator.h new file mode 100644 index 0000000000..df482b736f --- /dev/null +++ b/src/Physics/BoostedDarkMatter/EventGen/DMRESOutgoingDarkGenerator.h @@ -0,0 +1,37 @@ +//____________________________________________________________________________ +/*! + +\class genie::DMRESPrimaryLeptonGenerator + +\brief Generates the final state primary lepton in DM RES interactions. + Is a concrete implementation of the EventRecordVisitorI interface. + +\author Zach Orr Colorado State + +\created Jan 27 2024 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _DMRES_OUTGOING_DARK_GENERATOR_H_ +#define _DMRES_OUTGOING_DARK_GENERATOR_H_ + +#include "Physics/Common/OutgoingDarkGenerator.h" + +namespace genie { + + class DMRESOutgoingDarkGenerator : public OutgoingDarkGenerator { + +public : + DMRESOutgoingDarkGenerator(); + DMRESOutgoingDarkGenerator(string config); + ~DMRESOutgoingDarkGenerator(); + + // implement the EventRecordVisitorI interface + void ProcessEventRecord(GHepRecord * event_rec) const; +}; + +} // genie namespace +#endif // _DMRES_OUTGOING_DARK_GENERATOR_H_ diff --git a/src/Physics/BoostedDarkMatter/EventGen/LinkDef.h b/src/Physics/BoostedDarkMatter/EventGen/LinkDef.h index 1a89a5ca5f..06dcfac82d 100644 --- a/src/Physics/BoostedDarkMatter/EventGen/LinkDef.h +++ b/src/Physics/BoostedDarkMatter/EventGen/LinkDef.h @@ -10,9 +10,16 @@ #pragma link C++ class genie::DMELInteractionListGenerator; #pragma link C++ class genie::DMELKinematicsGenerator; #pragma link C++ class genie::DMELOutgoingDarkGenerator; + #pragma link C++ class genie::DMDISOutgoingDarkGenerator; #pragma link C++ class genie::DMDISInteractionListGenerator; #pragma link C++ class genie::DMDISKinematicsGenerator; + +#pragma link C++ class genie::DMRESInteractionListGenerator; +#pragma link C++ class genie::DMRESKinematicsGenerator; +#pragma link C++ class genie::DMRESOutgoingDarkGenerator; +#pragma link C++ class genie::DMRESHadronicSystemGenerator; + #pragma link C++ class genie::DMEOutgoingDarkGenerator; #pragma link C++ class genie::DMEInteractionListGenerator; #pragma link C++ class genie::DMEKinematicsGenerator; diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESPXSec.cxx b/src/Physics/BoostedDarkMatter/XSection/DMRESPXSec.cxx new file mode 100644 index 0000000000..224c401e94 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESPXSec.cxx @@ -0,0 +1,514 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + Zachary W. Orr + Colorado State University + +based on code by + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory +*/ +//____________________________________________________________________________ + +#include +#include + +#include "Framework/Algorithm/AlgFactory.h" +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Conventions/RefFrame.h" +#include "Framework/Conventions/KineVar.h" +#include "Framework/Conventions/Units.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/Numerical/Spline.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/ParticleData/PDGLibrary.h" +#include "Framework/Utils/KineUtils.h" +#include "Framework/Numerical/MathUtils.h" +#include "Framework/Utils/Range1.h" +#include "Framework/Utils/BWFunc.h" +#include "Physics/BoostedDarkMatter/XSection/DMRESPXSec.h" +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.h" +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.h" +#include "Physics/XSectionIntegration/XSecIntegratorI.h" +#include "Physics/NuclearState/FermiMomentumTablePool.h" +#include "Physics/NuclearState/FermiMomentumTable.h" +#include "Physics/NuclearState/NuclearUtils.h" + +using namespace genie; +using namespace genie::constants; + +//____________________________________________________________________________ +DMRESPXSec::DMRESPXSec() : +XSecAlgorithmI("genie::DMRESPXSec") +{ + +} +//____________________________________________________________________________ +DMRESPXSec::DMRESPXSec(string config) : +XSecAlgorithmI("genie::DMRESPXSec", config) +{ + +} +//____________________________________________________________________________ +DMRESPXSec::~DMRESPXSec() +{ + +} +//____________________________________________________________________________ +double DMRESPXSec::XSec( + const Interaction * interaction, KinePhaseSpace_t kps) const +{ + if(! this -> ValidProcess (interaction) ) return 0.; + if(! this -> ValidKinematics (interaction) ) return 0.; + + const InitialState & init_state = interaction -> InitState(); + const ProcessInfo & proc_info = interaction -> ProcInfo(); + const Target & target = init_state.Tgt(); + + const Kinematics & kinematics = interaction -> Kine(); + LOG("DMRESPXSec", pDEBUG) << "Using v^" << fVelMode << " dependence"; + +//Get Kinematic Parameters: + double W = kinematics.W(); + double W2 = TMath::Power(W, 2); //W^2 + double q2 = kinematics.q2(); + +//Rejection Sampling from Kinematics: +// Under the DIS/RES joining scheme, xsec(RES)=0 for W>=Wcut + if(fUsingDisResJoin) { + if(W>=fWcut) { +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("DMRES", pDEBUG) + << "RES/DIS Join Scheme: XSec[RES, W=" << W + << " >= Wcut=" << fWcut << "] = 0"; +#endif + return 0; + } + } +//Pass: Resonance XSec + +//Probe Res Interaction: +// Get the input baryon resonance: + Resonance_t resonance = interaction->ExclTag().Resonance(); + string resname = utils::res::AsString(resonance); + bool is_delta = utils::res::IsDelta (resonance); + +// Get the dark matter, target nucleon & DM current: + int nucpdgc = target.HitNucPdg(); + int probepdgc = init_state.ProbePdg(); + bool is_dm = pdg::IsDarkMatter (probepdgc); + bool is_dmbar = pdg::IsAntiDarkMatter (probepdgc); + + + bool is_p = pdg::IsProton (nucpdgc); + bool is_n = pdg::IsNeutron (nucpdgc); + bool is_dmres = proc_info.IsDarkMatterResonant(); + + //Need break for is not DM + if(!is_dmres) { + return 0; + } + + // Get baryon resonance parameters + int IR = utils::res::ResonanceIndex (resonance); + int LR = utils::res::OrbitalAngularMom (resonance); + double MR = utils::res::Mass (resonance); + double WR = utils::res::Width (resonance); + double NR = fNormBW?utils::res::BWNorm (resonance,fN0ResMaxNWidths,fN2ResMaxNWidths,fGnResMaxNWidths):1; + + // Following NeuGEN, avoid problems with underlying unphysical + // model assumptions by restricting the allowed W phase space + // around the resonance peak + if (fNormBW) { + if (W > MR + fN0ResMaxNWidths * WR && IR==0) return 0.; + else if (W > MR + fN2ResMaxNWidths * WR && IR==2) return 0.; + else if (W > MR + fGnResMaxNWidths * WR) return 0.; + } + + //Auxillary Kinematic factors + double E = init_state.ProbeE(kRfHitNucRest); //E1 + double E2 = TMath::Power(E,2); //E1^2 + double Mnuc = target.HitNucMass(); //Nucleon mass + double Mnuc2 = TMath::Power(Mnuc, 2); //m^2 + + //Scalar Charge + double fQchiS2 = TMath::Power(fQchiS,2); //QS^2 + // L and R charges + double fQchiL = fQchiV-fQchiA; + double fQchiR = fQchiV+fQchiA; + + // Compute kinematic factors + double k = 0.5 * (W2 - Mnuc2)/Mnuc; + double v = k - 0.5 * q2/Mnuc; + double v2 = TMath::Power(v, 2); + double Q2 = v2 - q2; + double Q = TMath::Sqrt(Q2); + double Eprime = E - v; + + double U = 0.5 * (E + Eprime + Q) / E; + double V = 0.5 * (E + Eprime - Q) / E; + double U2 = TMath::Power(U, 2); + double V2 = TMath::Power(V, 2); + double UV = U*V; + + +// Masses + double mchi = init_state.GetProbeP4(kRfHitNucRest)->M(); //DM mass: mx + double mchi2 = TMath::Power(mchi, 2); // mx^2 + double mZprime2 = TMath::Power(fMedMass, 2); // mZ'^2 + double mZprime4 = TMath::Power(mZprime2, 2); //mZ'^4 +//DM charge auxillary factors + double fQchiLmR = fQchiL-fQchiR; // QL - QR + double fQchiLR = fQchiL * fQchiR; // QL*QR + double fQchiLmR2 = TMath::Power(fQchiLmR, 2); //(QL - QR)^2 + double fQchiL2 = TMath::Power(fQchiL, 2); //QL^2 + double fQchiR2 = TMath::Power(fQchiR, 2); //QR^2 +//DM mass auxillary factors + double mZ_q2 = TMath::Power(mZprime2 - q2, 2)/mZprime4; //(mZ'^2 - q^2)^2 / mZ'^4 + double mchiTerm = (mchi2 * Q2)/(E2 * q2); //mchi^2 * Q^2 / E^2 * q^2 + + //Spin average over incident DM = 0.5 + double AL = U2*fQchiL2 + V2*fQchiR2 + 2*mchiTerm*fQchiLR; + double AR = V2*fQchiL2 + U2*fQchiR2 + 2*mchiTerm*fQchiLR; + double AS = 2*UV*(fQchiL2 + fQchiR2) + mchiTerm*fQchiLmR2; + //DM term + double AZ = 0.0; + if (mZprime2 != 0.0){ + AZ = -mchiTerm*mZ_q2*fQchiLmR2; + } + + //For Scalar DM: spin average = 1 + if(fVelMode == 2){ + AL = fQchiS2 * (2*UV + 2*mchiTerm); + AR = fQchiS2 * (2*UV + 2*mchiTerm); + AS = fQchiS2 * (TMath::Power((U+V), 2)); + AZ = 0.0; +} + // Calculate the Feynman-Kislinger-Ravndall parameters + double Go = TMath::Power(1 - 0.25 * q2/Mnuc2, 0.5-IR); + double GV = Go * TMath::Power( 1./(1-q2/fMv2), 2); + double GA = Go * TMath::Power( 1./(1-q2/fMa2), 2); + if(mZprime2 == 0.){ + GA = 0; + } + + double d = TMath::Power(W+Mnuc,2.) - q2; + double d2 = W2 - Mnuc2 + q2; + double sq2omg = TMath::Sqrt(2./fOmega); + double nomg = IR * fOmega; + double mq_w = Mnuc*Q/W; + double BC = (2*W*mq_w) / (W2 - Mnuc2 + q2); + fFKRDM.Lamda = sq2omg * mq_w; + fFKRDM.Tv = GV / (3.*W*sq2omg); + fFKRDM.Rv = kSqrt2 * mq_w*(W+Mnuc)*GV / d; + fFKRDM.S = (-q2/Q2) * (3*W*Mnuc + q2 - Mnuc2) * GV / (6*Mnuc2); + fFKRDM.Ta = (2./3.) * (fZeta/sq2omg) * mq_w * GA / d; + fFKRDM.Ra = (kSqrt2/6.) * fZeta * (GA/W) * (W+Mnuc + 2*nomg*W/d ); + fFKRDM.Bs = fZeta/(3.*W*sq2omg) * (1 + (W2-Mnuc2+q2)/ d) * GA; + fFKRDM.Cs = fZeta/(6.*Q) * (W2 - Mnuc2 + nomg*(W2-Mnuc2+q2)/d) * (GA/Mnuc); + fFKRDM.Bz = ((fZeta * GA) * (W - Mnuc)) / (2 * W * mq_w * sq2omg); + fFKRDM.Cz = ((fZeta * GA)/3) * (1 + ((3*q2 + nomg) / d)); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("FKR", pDEBUG) + << "FKR params for DMRES = " << resname << " : " << fFKRDM; +#endif + + // Calculate the Rein-Sehgal Helicity Amplitudes + + const RSHelicityAmplModelDMI * hamplmod = 0; + if(is_dmres) { + if (is_p) { hamplmod = fHAmplModelDMp;} + else { hamplmod = fHAmplModelDMn;} + } + assert(hamplmod); + + const RSHelicityAmplDM & hampl = hamplmod->Compute(resonance, fFKRDM); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("DMHAmpl", pDEBUG) + << "Helicity Amplitudes for DMRES = " << resname << " : " << hampl; +#endif + + // Compute the cross section structure factors + double gZp4 = TMath::Power(fgZp, 4.0); + double XoEn = 1.0-(mchi2/E2); //1 - (mchi/E)^2 + double XoPropMass = TMath::Power(q2 - mZprime2, 2); //(q^2 - mZ'^2)^2 + double Xo = gZp4/(XoEn*XoPropMass); + double sig0 = 0.0625*(Xo/kPi)*(-q2/Q2)*(W/Mnuc); + double scLR = 0.5*W/Mnuc; + double scS = 0.5*(Mnuc/W)*(Q2/(-q2)); + double sigL = 0.0; + double sigR = 0.0; + double sigS = 0.0; + double sigZ = 0.0; + +//Including Hadron spin avg and res-rest frame transformations + sigL = scLR* (hampl.Amp2Plus3() + hampl.Amp2Plus1()); + sigR = scLR* (hampl.Amp2Minus3 () + hampl.Amp2Minus1 ()); + sigS = scS * (hampl.Amp20Plus () + hampl.Amp20Minus()); + sigZ = scS *(hampl.Ampz20Plus () + hampl.Ampz20Minus()); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("DMRES", pDEBUG) << "sig_{0} = " << sig0; + LOG("DMRES", pDEBUG) << "sig_{L} = " << sigL; + LOG("DMRES", pDEBUG) << "sig_{R} = " << sigR; + LOG("DMRES", pDEBUG) << "sig_{S} = " << sigS; + LOG("DMRES", pDEBUG) << "sig_{Z} = " << sigZ; +#endif + +//DM Cross Section Calculation: + +//XSec calc: + double xsec = 0.0; + if (is_dm) { + xsec = sig0*(AL*sigL + AR*sigR + AS*sigS + AZ*sigZ); + } + else + if (is_dmbar) { + xsec = sig0*(AL*sigR + AR*sigL + AS*sigS + AZ*sigZ); + } + xsec = TMath::Max(0.,xsec); + + +//________________________________________________________________________________________ +//X-Sec scaling by BreitWigner,Jacobian,free-nucleon,Pauli-Blocking +//________________________________________________________________________________________ + + + // Check whether the cross section is to be weighted with a + // Breit-Wigner distribution (default: true) + double bw = 1.0; + if(fWghtBW) { + bw = utils::bwfunc::BreitWignerL(W,LR,MR,WR,NR); + + } +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("DMRES", pDEBUG) + << "BreitWigner(RES=" << resname << ", W=" << W << ") = " << bw; +#endif + xsec *= bw; + + + //Apply given scaling factor + double xsec_scale = 1.; + if (is_dmres) { xsec_scale = fXSecScaleDM; } + xsec *= xsec_scale; + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("DMRES", pINFO) + << "\n d2xsec/dQ2dW" << "[" << interaction->AsString() + << "](W=" << W << ", q2=" << q2 << ", E=" << E << ") = " << xsec; +#endif + + // The algorithm computes d^2xsec/dWdQ2 + // Check whether variable tranformation is needed + if(kps!=kPSWQ2fE) { + double J = utils::kinematics::Jacobian(interaction,kPSWQ2fE,kps); + xsec *= J; + } + + // If requested return the free nucleon xsec even for input nuclear tgt + if( interaction->TestBit(kIAssumeFreeNucleon) ) return xsec; + + int Z = target.Z(); + int A = target.A(); + int N = A-Z; + + // Take into account the number of scattering centers in the target + int NNucl = (is_p) ? Z : N; + + xsec*=NNucl; // nuclear xsec (no nuclear suppression factor) + + if (fUsePauliBlocking && A!=1) + { + // Calculation of Pauli blocking according references: + // + // [1] S.L. Adler, S. Nussinov, and E.A. Paschos, "Nuclear + // charge exchange corrections to leptonic pion production + // in the (3,3) resonance region," Phys. Rev. D 9 (1974) + // 2125-2143 [Erratum Phys. Rev. D 10 (1974) 1669]. + // [2] J.Y. Yu, "Neutrino interactions and nuclear effects in + // oscillation experiments and the nonperturbative disper- + // sive sector in strong (quasi-)abelian fields," Ph. D. + // Thesis, Dortmund U., Dortmund, 2002 (unpublished). + // [3] E.A. Paschos, J.Y. Yu, and M. Sakuda, "Neutrino pro- + // duction of resonances," Phys. Rev. D 69 (2004) 014013 + // [arXiv: hep-ph/0308130]. + + double P_Fermi = 0.0; + + // Maximum value of Fermi momentum of target nucleon (GeV) + if (A<6 || !fUseRFGParametrization) + { + // Look up the Fermi momentum for this target + FermiMomentumTablePool * kftp = FermiMomentumTablePool::Instance(); + const FermiMomentumTable * kft = kftp->GetTable(fKFTable); + P_Fermi = kft->FindClosestKF(pdg::IonPdgCode(A, Z), nucpdgc); + } + else { + // Define the Fermi momentum for this target + P_Fermi = utils::nuclear::FermiMomentumForIsoscalarNucleonParametrization(target); + // Correct the Fermi momentum for the struck nucleon + if(is_p) { P_Fermi *= TMath::Power( 2.*Z/A, 1./3); } + else { P_Fermi *= TMath::Power( 2.*N/A, 1./3); } + } + + double FactorPauli_RES = 1.0; + + double k0 = 0., q = 0., q0 = 0.; + + if (P_Fermi > 0.) + { + k0 = (W2-Mnuc2-Q2)/(2*W); + k = TMath::Sqrt(k0*k0+Q2); // previous value of k is overridden + q0 = (W2-Mnuc2+kPionMass2)/(2*W); + q = TMath::Sqrt(q0*q0-kPionMass2); + } + + if (2*P_Fermi < k-q) + FactorPauli_RES = 1.0; + if (2*P_Fermi >= k+q) + FactorPauli_RES = ((3*k*k+q*q)/(2*P_Fermi)-(5*TMath::Power(k,4)+TMath::Power(q,4)+10*k*k*q*q)/(40*TMath::Power(P_Fermi,3)))/(2*k); + if (2*P_Fermi >= k-q && 2*P_Fermi <= k+q) + FactorPauli_RES = ((q+k)*(q+k)-4*P_Fermi*P_Fermi/5-TMath::Power(k-q, 3)/(2*P_Fermi)+TMath::Power(k-q, 5)/(40*TMath::Power(P_Fermi, 3)))/(4*q*k); + + xsec *= FactorPauli_RES; + } + + return xsec; +} +//________________________________________________________________________________________ +//________________________________________________________________________________________ + + +//____________________________________________________________________________ +double DMRESPXSec::Integral(const Interaction * interaction) const +{ + double xsec = fXSecIntegrator->Integrate(this,interaction); + return xsec; +} +//____________________________________________________________________________ +bool DMRESPXSec::ValidProcess(const Interaction * interaction) const +{ + if(interaction->TestBit(kISkipProcessChk)) return true; + + const InitialState & init_state = interaction->InitState(); + const ProcessInfo & proc_info = interaction->ProcInfo(); + const XclsTag & xcls = interaction->ExclTag(); + + if(!proc_info.IsDarkMatterResonant()) return false; + if(!xcls.KnownResonance()) return false; + + int hitnuc = init_state.Tgt().HitNucPdg(); + bool is_pn = (pdg::IsProton(hitnuc) || pdg::IsNeutron(hitnuc)); + + if (!is_pn) return false; + + int probe = init_state.ProbePdg(); + bool is_dmres = proc_info.IsDarkMatterResonant(); + bool is_dm = proc_info.IsDarkMatter(); + + if (!is_dm && !is_dmres) return false; + + return true; +} +//____________________________________________________________________________ +void DMRESPXSec::Configure(const Registry & config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//____________________________________________________________________________ +void DMRESPXSec::Configure(string config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//____________________________________________________________________________ +void DMRESPXSec::LoadConfig(void) +{ + // Cross section scaling factor + this->GetParam( "RES-DM-XSecScale", fXSecScaleDM ) ; + + //FKR Params + this->GetParam( "RES-Zeta", fZeta ) ; + this->GetParam( "RES-Omega", fOmega ) ; + + // velocity dependence of interaction: fermion/scalar DM + this->GetParamDef("velocity-mode", fVelMode, 0 ); + //DM mass + double ma, mv ; + this->GetParam( "RES-Ma", ma ) ; + this->GetParam( "RES-Mv", mv ) ; + fMa2 = TMath::Power(ma,2); + fMv2 = TMath::Power(mv,2); + //DM Charges + double QchiL, QchiR; + this->GetParam( "DarkLeftCharge", QchiL ) ; + this->GetParam( "DarkRightCharge", QchiR ) ; + this->GetParam( "DarkScalarCharge", fQchiS ) ; + fQchiV = 0.5*(QchiL + QchiR); + fQchiA = 0.5*(- QchiL + QchiR); + // DM Mediator + this->GetParam("ZpCoupling", fgZp ) ; + fMedMass = PDGLibrary::Instance()->Find(kPdgMediator)->Mass(); + + this->GetParamDef( "BreitWignerWeight", fWghtBW, true ) ; + this->GetParamDef( "BreitWignerNorm", fNormBW, true); + + + this->GetParam("FermiMomentumTable", fKFTable); + this->GetParam("RFG-UseParametrization", fUseRFGParametrization); + this->GetParam("UsePauliBlockingForRES", fUsePauliBlocking); + + // Load all the sub-algorithms needed + + fHAmplModelDMp = 0; + fHAmplModelDMn = 0; + + AlgFactory * algf = AlgFactory::Instance(); + + fHAmplModelDMp = dynamic_cast ( + algf->GetAlgorithm("genie::RSHelicityAmplModelDMp","Default")); //DM + p + fHAmplModelDMn = dynamic_cast ( + algf->GetAlgorithm("genie::RSHelicityAmplModelDMn","Default")); //DM + n + + assert( fHAmplModelDMp ); + assert( fHAmplModelDMn ); + + // Use algorithm within a DIS/RES join scheme. If yes get Wcut + this->GetParam( "UseDRJoinScheme", fUsingDisResJoin ) ; + fWcut = 999999; + if(fUsingDisResJoin) { + this->GetParam( "Wcut", fWcut ) ; + } + + double thw ; + this->GetParam( "WeinbergAngle", thw ) ; + fSin48w = TMath::Power( TMath::Sin(thw), 4 ); + // NeuGEN limits in the allowed resonance phase space: + // W < min{ Wmin(physical), (res mass) + x * (res width) } + // It limits the integration area around the peak and avoids the + // problem with huge xsec increase at low Q2 and high W. + // In correspondence with Hugh, Rein said that the underlying problem + // are unphysical assumptions in the model. + this->GetParamDef( "MaxNWidthForN2Res", fN2ResMaxNWidths, 2.0 ) ; + this->GetParamDef( "MaxNWidthForN0Res", fN0ResMaxNWidths, 6.0 ) ; + this->GetParamDef( "MaxNWidthForGNRes", fGnResMaxNWidths, 4.0 ) ; + +//______________________________________________________________________________________ + + + // load the differential cross section integrator + fXSecIntegrator = + dynamic_cast (this->SubAlg("XSec-Integrator")); + assert(fXSecIntegrator); +} +//____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESPXSec.h b/src/Physics/BoostedDarkMatter/XSection/DMRESPXSec.h new file mode 100644 index 0000000000..3ee8456c21 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESPXSec.h @@ -0,0 +1,107 @@ +//____________________________________________________________________________ +/*! + +\class genie::DMRESPXSec + +\brief Computes the double differential cross section for resonance + DM-production according to the Rein-Sehgal model. + + The computed cross section is the d^2 xsec/ dQ^2 dW \n + + where \n + \li \c Q^2 : momentum transfer ^ 2 + \li \c W : invariant mass of the final state hadronic system + + Is a concrete implementation of the XSecAlgorithmI interface. + +\ref D.Rein and L.M.Sehgal, Neutrino Excitation of Baryon Resonances + and Single Pion Production, Ann.Phys.133, 79 (1981) + +\author Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + + Changes made for Dark Matter - Zach Orr, Colorado State University + +\created May 05, 2004 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _DM_RES_PXSEC_H_ +#define _DM_RES_PXSEC_H_ + +#include "Framework/EventGen/XSecAlgorithmI.h" +#include "Framework/ParticleData/BaryonResonance.h" +#include "Physics/BoostedDarkMatter/XSection/FKRDM.h" + +namespace genie { + +class RSHelicityAmplModelDMI; +class Spline; +class XSecIntegratorI; + +class DMRESPXSec : public XSecAlgorithmI { + +public: + DMRESPXSec(); + DMRESPXSec(string config); + virtual ~DMRESPXSec(); + + // implement the XSecAlgorithmI interface + double XSec (const Interaction * i, KinePhaseSpace_t k) const; + double Integral (const Interaction * i) const; + bool ValidProcess (const Interaction * i) const; + + // overload the Algorithm::Configure() methods to load private data + // members from configuration options + void Configure(const Registry & config); + void Configure(string config); + +private: + + void LoadConfig (void); + + mutable FKRDM fFKRDM; + + const RSHelicityAmplModelDMI * fHAmplModelDMp; + const RSHelicityAmplModelDMI * fHAmplModelDMn; + + // configuration data + double fQchiV; ///< DM vector charge + double fQchiA; ///< DM axial charge + double fQchiS; ///< DM scalar charge + int fVelMode; ///< DM (scalar/fermion) + double fMedMass; ///< DM mediator mass + double fgZp; ///< DM mediator coupling + bool fWghtBW; ///< weight with resonance breit-wigner? + bool fNormBW; ///< normalize resonance breit-wigner to 1? + double fZeta; ///< FKR parameter Zeta + double fOmega; ///< FKR parameter Omega + double fMa2; ///< (axial mass)^2 + double fMv2; ///< (vector mass)^2 + bool fUsingDisResJoin; ///< use a DIS/RES joining scheme? + double fWcut; ///< apply DIS/RES joining scheme < Wcut + double fN2ResMaxNWidths; ///< limits allowed phase space for n=2 res + double fN0ResMaxNWidths; ///< limits allowed phase space for n=0 res + double fGnResMaxNWidths; ///< limits allowed phase space for other res + string fKFTable; ///< table of Fermi momentum (kF) constants for various nuclei + bool fUseRFGParametrization; ///< use parametrization for fermi momentum insted of table? + bool fUsePauliBlocking; ///< account for Pauli blocking? + + double fSin48w; ///< sin^4(Weingberg angle) + +// bool fUsingNuTauScaling; ///< use NeuGEN nutau xsec reduction factors? +// Spline * fNuTauRdSpl; ///< xsec reduction spline for nu_tau +// Spline * fNuTauBarRdSpl; ///< xsec reduction spline for nu_tau_bar + + double fXSecScaleDM; ///< external DM xsec scaling factor + + + const XSecIntegratorI * fXSecIntegrator; +}; + +} // genie namespace + +#endif // _DM_RES_PXSEC_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESXSec.cxx b/src/Physics/BoostedDarkMatter/XSection/DMRESXSec.cxx new file mode 100644 index 0000000000..ec6712987d --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESXSec.cxx @@ -0,0 +1,121 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + based on code of + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + + + Changes made for RES DM by Zach Orr, Colorado State University + */ + //____________________________________________________________________________ + + #include + #include + #include + + #include "Framework/Conventions/GBuild.h" + #include "Framework/Conventions/Constants.h" + #include "Framework/Conventions/Units.h" + #include "Framework/Conventions/KineVar.h" + #include "Framework/Messenger/Messenger.h" + #include "Framework/ParticleData/PDGUtils.h" + #include "Framework/Numerical/MathUtils.h" + #include "Framework/Utils/KineUtils.h" + #include "Framework/Numerical/GSLUtils.h" + #include "Physics/BoostedDarkMatter/XSection/DMRESXSec.h" + #include "Physics/XSectionIntegration/GSLXSecFunc.h" + + using namespace genie; + using namespace genie::constants; + + //____________________________________________________________________________ + DMRESXSec::DMRESXSec() : + XSecIntegratorI("genie::DMRESXSec") + { + + } + //____________________________________________________________________________ + DMRESXSec::DMRESXSec(string config) : + XSecIntegratorI("genie::DMRESXSec", config) + { + + } + //____________________________________________________________________________ + DMRESXSec::~DMRESXSec() + { + + } + //____________________________________________________________________________ + double DMRESXSec::Integrate( + const XSecAlgorithmI * model, const Interaction * in) const + { + if(! model->ValidProcess(in) ) return 0.; + + const KPhaseSpace & kps = in->PhaseSpace(); + if(!kps.IsAboveThreshold()) { + LOG("COHXSec", pDEBUG) << "*** Below energy threshold"; + return 0; + } + Range1D_t Q2l = kps.Limits(kKVQ2); + Range1D_t Wl = kps.Limits(kKVW); + + Interaction * interaction = new Interaction(*in); + interaction->SetBit(kISkipProcessChk); + //interaction->SetBit(kISkipKinematicChk); + + ROOT::Math::IBaseFunctionMultiDim * func = + new utils::gsl::d2XSec_dWdQ2_E(model, interaction); + + ROOT::Math::IntegrationMultiDim::Type ig_type = + utils::gsl::IntegrationNDimTypeFromString(fGSLIntgType); + double abstol = 1E-16; //We mostly care about relative tolerance. + + ROOT::Math::IntegratorMultiDim ig(*func, ig_type, abstol, fGSLRelTol, fGSLMaxEval); + + double kine_min[2] = { Wl.min, Q2l.min }; + double kine_max[2] = { Wl.max, Q2l.max }; + double xsec = ig.Integral(kine_min, kine_max) * (1E-38 * units::cm2); + + LOG("DMRESXSec", pERROR) << "Integrator opt / Integrator = " << ig.Options().Integrator(); + + if(xsec < 0) { + LOG("DMRESXSec", pERROR) << "Algorithm " << *model << " returns a negative cross-section (xsec = " << xsec << " 1E-38 * cm2)"; + LOG("DMRESXSec", pERROR) << "for process" << *interaction; + LOG("DMRESXSec", pERROR) << "Integrator status code = " << ig.Status(); + LOG("DMRESXSec", pERROR) << "Integrator error code = " << ig.Error(); + } + + //LOG("RESXSec", pINFO) << "XSec[RES] (Ev = " << Ev << " GeV) = " << xsec; + + delete interaction; + delete func; + return xsec; + } + //____________________________________________________________________________ + void DMRESXSec::Configure(const Registry & config) + { + Algorithm::Configure(config); + this->LoadConfig(); + } + //____________________________________________________________________________ + void DMRESXSec::Configure(string config) + { + Algorithm::Configure(config); + this->LoadConfig(); + } + //____________________________________________________________________________ + void DMRESXSec::LoadConfig(void) + { + // Get GSL integration type & relative tolerance + GetParamDef( "gsl-integration-type", fGSLIntgType, string("adaptive") ) ; + GetParamDef( "gsl-relative-tolerance", fGSLRelTol, 1E-2 ) ; + int max, min ; + GetParamDef( "gsl-max-eval", max, 500000 ) ; + GetParamDef( "gsl-min-eval", min, 5000 ) ; + fGSLMaxEval = (unsigned int) max ; + fGSLMinEval = (unsigned int) min ; + } + //____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESXSec.h b/src/Physics/BoostedDarkMatter/XSection/DMRESXSec.h new file mode 100644 index 0000000000..37360aeb33 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESXSec.h @@ -0,0 +1,48 @@ +//____________________________________________________________________________ +/*! + +\class genie::DMRESXSec + +\brief Computes the DM RES Cross Section.\n + Is a concrete implementation of the XSecIntegratorI interface.\n + +\author Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + + updated for DM RES by Zach Orr, Colorado State University + +\created May 04, 2004 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _DMRES_XSEC_H_ +#define _DMRES_XSEC_H_ + +#include "Physics/XSectionIntegration/XSecIntegratorI.h" + +namespace genie { + +class DMRESXSec : public XSecIntegratorI { + +public: + DMRESXSec(); + DMRESXSec(string param_set); + virtual ~DMRESXSec(); + + //! XSecIntegratorI interface implementation + double Integrate(const XSecAlgorithmI * model, const Interaction * i) const; + + //! Overload the Algorithm::Configure() methods to load private data + //! members from configuration options + void Configure(const Registry & config); + void Configure(string config); + +private: + void LoadConfig (void); +}; + +} // genie namespace +#endif // _DMRES_XSEC_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESXSecFast.cxx b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecFast.cxx new file mode 100644 index 0000000000..4a4e0f2061 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecFast.cxx @@ -0,0 +1,227 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2026, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + Igor Kakorin + Joint Institute for Nuclear Research + + based on code of + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + + adjusted for Dark Matter by + Zachary W. Orr + Colorado State University + */ +//____________________________________________________________________________ + +#include +#include +#include + +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Conventions/Units.h" +#include "Framework/Conventions/KineVar.h" +#include "Physics/XSectionIntegration/GSLXSecFunc.h" +#include "Framework/Conventions/Units.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Physics/BoostedDarkMatter/XSection/DMRESXSecFast.h" +#include "Framework/Utils/RunOpt.h" +#include "Framework/Numerical/MathUtils.h" +#include "Framework/Utils/KineUtils.h" +#include "Framework/Utils/Cache.h" +#include "Framework/Utils/CacheBranchFx.h" +#include "Framework/Utils/XSecSplineList.h" +#include "Framework/Numerical/GSLUtils.h" + +using namespace genie; +using namespace genie::constants; +using namespace genie::units; + +//____________________________________________________________________________ +DMRESXSecFast::DMRESXSecFast() : +DMRESXSecWithCacheFast("genie::DMRESXSecFast") +{ + +} +//____________________________________________________________________________ +DMRESXSecFast::DMRESXSecFast(string config) : +DMRESXSecWithCacheFast("genie::DMRESXSecFast", config) +{ + +} +//____________________________________________________________________________ +DMRESXSecFast::~DMRESXSecFast() +{ + +} +//____________________________________________________________________________ +double DMRESXSecFast::Integrate( + const XSecAlgorithmI * model, const Interaction * interaction) const +{ + if(! model->ValidProcess(interaction) ) return 0.; + fSingleResXSecModel = model; + + const KPhaseSpace & kps = interaction->PhaseSpace(); + if(!kps.IsAboveThreshold()) { + LOG("DMRESXSecFast", pDEBUG) << "*** Below energy threshold"; + return 0; + } + + //-- Get init state and process information + const InitialState & init_state = interaction->InitState(); + const ProcessInfo & proc_info = interaction->ProcInfo(); + const Target & target = init_state.Tgt(); + + InteractionType_t it = proc_info.InteractionTypeId(); + int nucleon_pdgc = target.HitNucPdg(); + int nu_pdgc = init_state.ProbePdg(); + + //-- Get neutrino energy in the struck nucleon rest frame + double Ev = init_state.ProbeE(kRfHitNucRest); + + //-- Get the requested resonance + Resonance_t res = interaction->ExclTag().Resonance(); + + // If the input interaction is off a nuclear target, then chek whether + // the corresponding free nucleon cross section already exists at the + // cross section spline list. + // If yes, calculate the nuclear cross section based on that value. + // + XSecSplineList * xsl = XSecSplineList::Instance(); + if(init_state.Tgt().IsNucleus() && !xsl->IsEmpty() ) { + Interaction * in = new Interaction(*interaction); + if(pdg::IsProton(nucleon_pdgc)) { + in->InitStatePtr()->TgtPtr()->SetId(kPdgTgtFreeP); + } else { + in->InitStatePtr()->TgtPtr()->SetId(kPdgTgtFreeN); + } + if(xsl->SplineExists(model,in)) { + const Spline * spl = xsl->GetSpline(model, in); + double xsec = spl->Evaluate(Ev); + SLOG("DMResTF", pNOTICE) + << "XSec[RES/" << utils::res::AsString(res)<< "/free] (Ev = " + << Ev << " GeV) = " << xsec/(1E-38 *cm2)<< " x 1E-38 cm^2"; + if(! interaction->TestBit(kIAssumeFreeNucleon) ) { + int NNucl = (pdg::IsProton(nucleon_pdgc)) ? target.Z() : target.N(); + xsec *= NNucl; + } + delete in; + return xsec; + } + delete in; + } + + // There was no corresponding free nucleon spline saved in XSecSplineList that + // could be used to speed up this calculation. + // Check whether local caching of free nucleon cross sections is allowed. + // If yes, store free nucleon cross sections at a cache branch and use those + // at any subsequent call. + // + bool bare_xsec_pre_calc = RunOpt::Instance()->BareXSecPreCalc(); + if(bare_xsec_pre_calc && !fUsePauliBlocking) { + Cache * cache = Cache::Instance(); + string key = this->CacheBranchName(res, it, nu_pdgc, nucleon_pdgc); + LOG("DMResTF", pINFO) + << "Finding cache branch with key: " << key; + CacheBranchFx * cache_branch = + dynamic_cast (cache->FindCacheBranch(key)); + if(!cache_branch) { + LOG("DMResTF", pWARN) + << "No cached RES v-production data for input neutrino" + << " (pdgc: " << nu_pdgc << ")"; + LOG("DMResTF", pWARN) + << "Wait while computing/caching RES production xsec first..."; + + this->CacheResExcitationXSec(interaction); + + LOG("DMResTF", pINFO) << "Done caching resonance xsec data"; + LOG("DMResTF", pINFO) + << "Finding newly created cache branch with key: " << key; + cache_branch = + dynamic_cast (cache->FindCacheBranch(key)); + assert(cache_branch); + } + const CacheBranchFx & cbranch = (*cache_branch); + + //-- Get cached resonance neutrinoproduction xsec + // (If E>Emax, assume xsec = xsec(Emax) - but do not evaluate the + // cross section spline at the end of its energy range-) + double rxsec = (EvTestBit(kIAssumeFreeNucleon) ) return rxsec; + + int NNucl = (pdg::IsProton(nucleon_pdgc)) ? target.Z() : target.N(); + rxsec*=NNucl; // nuclear xsec + return rxsec; + } // disable local caching + + // Just go ahead and integrate the input differential cross section for the + // specified interaction. + else { + + Range1D_t rW = Range1D_t(0.0,1.0); + Range1D_t rQ2 = Range1D_t(0.0,1.0); + + LOG("DMResTF", pINFO) + << "*** Integrating d^2 XSec/dWdQ^2 for R: " + << utils::res::AsString(res) << " at Ev = " << Ev; + LOG("DMResTF", pINFO) + << "{W} = " << rW.min << ", " << rW.max; + LOG("DMResTF", pINFO) + << "{Q^2} = " << rQ2.min << ", " << rQ2.max; + + ROOT::Math::IBaseFunctionMultiDim * func= new utils::gsl::d2XSecRESFast_dWQ2_E(model, interaction); + ROOT::Math::IntegrationMultiDim::Type ig_type = utils::gsl::IntegrationNDimTypeFromString(fGSLIntgType); + ROOT::Math::IntegratorMultiDim ig(ig_type,0,fGSLRelTol,fGSLMaxEval); + ig.SetFunction(*func); + double kine_min[2] = { rW.min, rQ2.min }; + double kine_max[2] = { rW.max, rQ2.max }; + double xsec = ig.Integral(kine_min, kine_max) * (1E-38 * units::cm2); + + delete func; + return xsec; + } + return 0; +} +//____________________________________________________________________________ +void DMRESXSecFast::Configure(const Registry & config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//____________________________________________________________________________ +void DMRESXSecFast::Configure(string config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//____________________________________________________________________________ +void DMRESXSecFast::LoadConfig(void) +{ + + // Get GSL integration type & relative tolerance + GetParamDef( "gsl-integration-type", fGSLIntgType, string("adaptive") ) ; + GetParamDef( "gsl-relative-tolerance", fGSLRelTol, 0.01 ) ; + GetParamDef( "gsl-max-eval", fGSLMaxEval, 100000 ) ; + GetParam("UsePauliBlockingForRES", fUsePauliBlocking); + // Get upper E limit on res xsec spline (=f(E)) before assuming xsec=const + GetParamDef( "ESplineMax", fEMax, 100. ) ; + fEMax = TMath::Max(fEMax, 20.); // don't accept user Emax if less than 20 GeV + + // Create the baryon resonance list specified in the config. + fResList.Clear(); + string resonances ; + GetParam( "ResonanceNameList", resonances ) ; + fResList.DecodeFromNameList(resonances); +} +//____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESXSecFast.h b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecFast.h new file mode 100644 index 0000000000..3581c03f33 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecFast.h @@ -0,0 +1,69 @@ +//____________________________________________________________________________ +/*! + +\class genie::DMRESXSecFast + +\brief Computes the cross section for an exclusive 1pi reaction through + resonance neutrinoproduction according to the Rein-Sehgal model. + + This algorithm produces in principle what you could also get from + the genie::RESXSec algorithm (RES cross section integrator) by + specifying the genie::DMRESPXSec as the differential + cross section model. However, DMRESXSecFast offers a faster + alternative. Before computing any RES cross section this algorithm + computes and caches splines for resonance neutrino-production cross + sections. This improves the speed of the GENIE spline construction + phase if splines for multiple nuclear targets are to be computed. + Also this class integrates cross sections faster, than + DMRESXSec because of integration area transformation. + + Is a concrete implementation of the XSecAlgorithmI interface.\n + +\ref D.Rein and L.M.Sehgal, Neutrino Excitation of Baryon Resonances + and Single Pion Production, Ann.Phys.133, 79 (1981) + +\author Igor Kakorin + Joint Institute for Nuclear Research + + based on code of + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + +\created March 01, 2017 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + +*/ +//____________________________________________________________________________ + +#ifndef _DM_RES_XSEC_FAST_H_ +#define _DM_RES_XSEC_FAST_H_ + +#include "Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.h" + +namespace genie { + +class DMRESXSecFast : public DMRESXSecWithCacheFast { + +public: + DMRESXSecFast(); + DMRESXSecFast(string param_set); + virtual ~DMRESXSecFast(); + + // XSecIntegratorI interface implementation + double Integrate(const XSecAlgorithmI * model, const Interaction * i) const; + + // Overload the Algorithm::Configure() methods to load private data + // members from configuration options + void Configure(const Registry & config); + void Configure(string config); + +private: + void LoadConfig(void); + + bool fUsePauliBlocking; ///< account for Pauli blocking? +}; + +} // genie namespace +#endif // _DM_RES_XSEC_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.cxx b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.cxx new file mode 100644 index 0000000000..e5e3c0f540 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.cxx @@ -0,0 +1,314 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + Igor Kakorin + Joint Institute for Nuclear Research + + based on code of + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory +*/ +//____________________________________________________________________________ + +#include +#include + +#include +#include +#include + +#include "Framework/EventGen/XSecAlgorithmI.h" +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/Conventions/Controls.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Conventions/Units.h" +#include "Framework/Conventions/KinePhaseSpace.h" +#include "Framework/Conventions/KineVar.h" +#include "Physics/XSectionIntegration/GSLXSecFunc.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.h" +#include "Framework/Numerical/MathUtils.h" +#include "Framework/Utils/KineUtils.h" +#include "Framework/Utils/Cache.h" +#include "Framework/Utils/CacheBranchFx.h" +#include "Framework/Numerical/GSLUtils.h" +#include "Framework/Utils/Range1.h" + + + + + + + +using std::ostringstream; + +using namespace genie; +using namespace genie::controls; +using namespace genie::constants; +//using namespace genie::units; + +//____________________________________________________________________________ +DMRESXSecWithCacheFast::DMRESXSecWithCacheFast() : +XSecIntegratorI() +{ + +} +//____________________________________________________________________________ +DMRESXSecWithCacheFast::DMRESXSecWithCacheFast(string nm) : +XSecIntegratorI(nm) +{ + +} +//____________________________________________________________________________ +DMRESXSecWithCacheFast::DMRESXSecWithCacheFast(string nm,string conf): +XSecIntegratorI(nm,conf) +{ + +} +//____________________________________________________________________________ +DMRESXSecWithCacheFast::~DMRESXSecWithCacheFast() +{ + +} +//____________________________________________________________________________ +void DMRESXSecWithCacheFast::CacheResExcitationXSec( + const Interaction * in) const +{ +// Cache resonance neutrino production data from free nucleons + + Cache * cache = Cache::Instance(); + + assert(fSingleResXSecModel); +// assert(fIntegrator); + + // Compute the number of spline knots - use at least 10 knots per decade + // && at least 40 knots in the full energy range + const double Emin = 0.01; + const int nknots_min = (int) (10*(TMath::Log(fEMax)-TMath::Log(Emin))); + const int nknots = TMath::Max(100, nknots_min); + double * E = new double[nknots]; // knot 'x' + + TLorentzVector p4(0,0,0,0); + //*************************************** + //Get Dark Matter mass for calculating p4 + double mchi = in->InitState().GetProbeP4(kRfHitNucRest)->M(); //DM mass: mx + //*************************************** + int nu_code = in->InitState().ProbePdg(); + int nuc_code = in->InitState().Tgt().HitNucPdg(); + int tgt_code = (nuc_code==kPdgProton) ? kPdgTgtFreeP : kPdgTgtFreeN; + + Interaction * interaction = new Interaction(*in); + interaction->InitStatePtr()->SetPdgs(tgt_code, nu_code); + interaction->InitStatePtr()->TgtPtr()->SetHitNucPdg(nuc_code); + + InteractionType_t wkcur = interaction->ProcInfo().InteractionTypeId(); + unsigned int nres = fResList.NResonances(); + for(unsigned int ires = 0; ires < nres; ires++) { + + // Get next resonance from the resonance list + Resonance_t res = fResList.ResonanceId(ires); + + interaction->ExclTagPtr()->SetResonance(res); + + // Get a unique cache branch name + string key = this->CacheBranchName(res, wkcur, nu_code, nuc_code); + + // Make sure the cache branch does not already exists + CacheBranchFx * cache_branch = + dynamic_cast (cache->FindCacheBranch(key)); + assert(!cache_branch); + + // Create the new cache branch + LOG("DMResCF", pNOTICE) + << "\n ** Creating cache branch - key = " << key; + cache_branch = new CacheBranchFx("RES Excitation XSec"); + cache->AddCacheBranch(key, cache_branch); + assert(cache_branch); + + const KPhaseSpace & kps = interaction->PhaseSpace(); + double Ethr = kps.Threshold(); + LOG("DMResCF", pNOTICE) << "E threshold = " << Ethr; + + // Distribute the knots in the energy range as is being done in the + // XSecSplineList so that the energy threshold is treated correctly + // in the spline - see comments there in. + int nkb = (Ethr>Emin) ? 5 : 0; // number of knots < threshold + int nka = nknots-nkb; // number of knots >= threshold + // knots < energy threshold + double dEb = (Ethr>Emin) ? (Ethr - Emin) / nkb : 0; + for(int i=0; i= energy threshold + double E0 = TMath::Max(Ethr,Emin); + double dEa = (TMath::Log10(fEMax) - TMath::Log10(E0)) /(nka-1); + for(int i=0; iInitStatePtr()->SetProbeP4(p4); + + if(Ev>Ethr+kASmallNum) { + // Get integration ranges + Range1D_t rW = Range1D_t(0.0,1.0); + Range1D_t rQ2 = Range1D_t(0.0,1.0); + + LOG("DMResCF", pINFO) + << "*** Integrating d^2 XSec/dWdQ^2 for R: " + << utils::res::AsString(res) << " at Ev = " << Ev; + LOG("DMResCF", pINFO) + << "{W} = " << rW.min << ", " << rW.max; + LOG("DMResCF", pINFO) + << "{Q^2} = " << rQ2.min << ", " << rQ2.max; + + if(rW.maxCreateSpline(); + }//ires + + delete [] E; + delete interaction; +} +//____________________________________________________________________________ +string DMRESXSecWithCacheFast::CacheBranchName( + Resonance_t res, InteractionType_t it, int nupdgc, int nucleonpdgc) const +{ +// Build a unique name for the cache branch + + Cache * cache = Cache::Instance(); + string res_name = utils::res::AsString(res); + string it_name = InteractionType::AsString(it); + string nc_nuc = ((nucleonpdgc==kPdgProton) ? "p" : "n"); + + ostringstream intk; + intk << "ResExcitationXSec/R:" << res_name << ";nu:" << nupdgc + << ";int:" << it_name << nc_nuc; + + string algkey = fSingleResXSecModel->Id().Key(); + string ikey = intk.str(); + string key = cache->CacheBranchKey(algkey, ikey); + + return key; +} +//____________________________________________________________________________ +// GSL wrappers +//____________________________________________________________________________ +genie::utils::gsl::d2XSecRESFast_dWQ2_E::d2XSecRESFast_dWQ2_E( + const XSecAlgorithmI * m, const Interaction * i) : +ROOT::Math::IBaseFunctionMultiDim(), +fModel(m), +fInteraction(i) +{ + kps = fInteraction->PhaseSpacePtr(); + Range1D_t Wl = kps->WLim(); + fWmin = Wl.min; + fWmax = Wl.max; + Registry fConfig = (const_cast(fModel))->GetConfig(); + bool fUsingDisResJoin = fConfig.GetBool("UseDRJoinScheme"); + double fWcut = 999999; + if(fUsingDisResJoin) + { + fWcut = fConfig.GetDouble("Wcut"); + } + fWmax=TMath::Min(fWcut, fWmax); + if (fWcutExclTag().Resonance(); + int IR = utils::res::ResonanceIndex (resonance); + double MR = utils::res::Mass (resonance); + double WR = utils::res::Width (resonance); + if (IR==0) + fWcut = MR + fN0ResMaxNWidths * WR; + else if (IR==2) + fWcut = MR + fN2ResMaxNWidths * WR; + else + fWcut = MR + fGNResMaxNWidths * WR; + fWmax=TMath::Min(fWcut, fWmax); + if (fWcutKinePtr()->SetW(W); + Range1D_t Q2l = kps->Q2Lim_W(); + if (Q2l.min<0 || Q2l.max<0) + return 0.0; + double Q2 = Q2l.min+(Q2l.max-Q2l.min)*xin[1]; + fInteraction->KinePtr()->SetQ2(Q2); + double xsec = fModel->XSec(fInteraction, kPSWQ2fE)*(fWmax-fWmin)*(Q2l.max-Q2l.min); + return xsec/(1E-38 * units::cm2); +} +ROOT::Math::IBaseFunctionMultiDim * + genie::utils::gsl::d2XSecRESFast_dWQ2_E::Clone() const +{ + return + new genie::utils::gsl::d2XSecRESFast_dWQ2_E(fModel,fInteraction); +} +//____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.h b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.h new file mode 100644 index 0000000000..23845074d5 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/DMRESXSecWithCacheFast.h @@ -0,0 +1,106 @@ +//____________________________________________________________________________ +/*! + +\class genie::DMRESXSecWithCacheFast + +\brief Class that caches resonance neutrinoproduction cross sections on free + nucleons according to the Rein-Sehgal model. This significantly speeds + the cross section calculation for multiple nuclear targets (eg at the + spline construction phase). This class integrates cross sections faster, + than DMRESXSecWithCache because of integration area transformation. + +\ref D.Rein and L.M.Sehgal, Neutrino Excitation of Baryon Resonances + and Single Pion Production, Ann.Phys.133, 79 (1981) + +\author Igor Kakorin + Joint Institute for Nuclear Research + + based on code of + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + + adjusted for Dark Matter by + Zachary W. Orr + Colorado State University + +\created March 01, 2017 + +\cpright Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _DM_RES_XSEC_WITH_CACHE_FAST_H_ +#define _DM_RES_XSEC_WITH_CACHE_FAST_H_ + +#include +#include + +#include "Physics/XSectionIntegration/XSecIntegratorI.h" +#include "Framework/ParticleData//BaryonResList.h" +#include "Framework/ParticleData/BaryonResonance.h" +#include "Framework/Utils/Range1.h" +#include "Framework/Interaction/KPhaseSpace.h" + +namespace genie { + +class DMRESXSecWithCacheFast : public XSecIntegratorI { + +protected: + DMRESXSecWithCacheFast(); + DMRESXSecWithCacheFast(string name); + DMRESXSecWithCacheFast(string name, string config); + virtual ~DMRESXSecWithCacheFast(); + + // Don't implement the XSecIntegratorI interface - leave it for the concrete + // subclasses. Just define utility methods and data + void CacheResExcitationXSec (const Interaction * interaction) const; + string CacheBranchName(Resonance_t r, InteractionType_t it, int nu, int nuc) const; + + bool fUsingDisResJoin; + double fWcut; + double fEMax; + + mutable const XSecAlgorithmI * fSingleResXSecModel; + BaryonResList fResList; +}; + + +class XSecAlgorithmI; +class Interaction; + +namespace utils { +namespace gsl { + + + +//..................................................................................... +// +// genie::utils::gsl::d2XSecRESFast_dWQ2_E +// A 2-D cross section function: d2xsec/dWdQ2 = f(W,Q2)|(fixed E) +// +class d2XSecRESFast_dWQ2_E: public ROOT::Math::IBaseFunctionMultiDim +{ +public: + d2XSecRESFast_dWQ2_E(const XSecAlgorithmI * m, const Interaction * i); + ~d2XSecRESFast_dWQ2_E(); + + // ROOT::Math::IBaseFunctionMultiDim interface + unsigned int NDim (void) const; + double DoEval (const double * xin) const; + ROOT::Math::IBaseFunctionMultiDim * Clone (void) const; + +private: + const XSecAlgorithmI * fModel; + const Interaction * fInteraction; + double fWmin; + double fWmax; + bool isfWcutLessfWmin; + KPhaseSpace * kps; +}; + +} // gsl namespace +} // utils namespace +} // genie namespace + +#endif // _DM_RES_XSEC_WITH_CACHE_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/FKRDM.cxx b/src/Physics/BoostedDarkMatter/XSection/FKRDM.cxx new file mode 100644 index 0000000000..f107cb64d0 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/FKRDM.cxx @@ -0,0 +1,70 @@ +//____________________________________________________________________________ +/* +Dark Matter model parameters calculated in the same form as +the Feynmann-Kislinger-Ravndall (FKR) baryon excitation model parameters. + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + +#include + +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Messenger/Messenger.h" +#include "Physics/BoostedDarkMatter/XSection/FKRDM.h" + +using std::endl; + +using namespace genie; +using namespace genie::constants; + +//____________________________________________________________________________ +namespace genie +{ + ostream & operator << (ostream & stream, const FKRDM & parameters) + { + parameters.Print(stream); + return stream; + } +} +//____________________________________________________________________________ +FKRDM::FKRDM() +{ + this->Reset(); +} +//____________________________________________________________________________ +FKRDM::~FKRDM() +{ + +} +//____________________________________________________________________________ +void FKRDM::Print(ostream & stream) const +{ + stream << endl; + stream << " lamda = " << Lamda << endl; + stream << " Tv = " << Tv << endl; + stream << " Rv = " << Rv << endl; + stream << " S = " << S << endl; + stream << " Ta = " << Ta << endl; + stream << " Ra = " << Ra << endl; + stream << " Bs = " << Bs << endl; + stream << " Cs = " << Cs << endl; + stream << " Bz = " << Bz << endl; + stream << " Cz = " << Cz << endl; +} +//____________________________________________________________________________ +void FKRDM::Reset(void) +{ + Lamda = 0.0; + Tv = 0.0; + Rv = 0.0; + S = 0.0; + Ta = 0.0; + Ra = 0.0; + Bs = 0.0; + Cs = 0.0; + Bz = 0.0; + Cz = 0.0; +} +//____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/FKRDM.h b/src/Physics/BoostedDarkMatter/XSection/FKRDM.h new file mode 100644 index 0000000000..7e661199b7 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/FKRDM.h @@ -0,0 +1,51 @@ +//____________________________________________________________________________ +/* +Dark Matter model parameters calculated in the same form as +the Feynmann-Kislinger-Ravndall (FKR) baryon excitation model parameters. (header) + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + +#ifndef _FKRDM_H_ +#define _FKRDM_H_ + +#include + +using std::ostream; + +namespace genie { + +class FKRDM; +ostream & operator<< (ostream & stream, const FKRDM & parameters); + +class FKRDM { + +public: + + friend ostream & operator<< (ostream & stream, const FKRDM & parameters); + + //Unchanged variables + double Lamda; + double Tv; + double Rv; + double S; + double Ta; + double Ra; + + //New variables for DM case that differ from the FKR calculation + double Bs; + double Cs; + double Bz; + double Cz; + + void Reset (void); + void Print (ostream & stream) const; + + FKRDM(); + ~FKRDM(); +}; + +} // genie namespace + +#endif // _FKRDM_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/LinkDef.h b/src/Physics/BoostedDarkMatter/XSection/LinkDef.h index 35371cf40d..48c8ba854a 100644 --- a/src/Physics/BoostedDarkMatter/XSection/LinkDef.h +++ b/src/Physics/BoostedDarkMatter/XSection/LinkDef.h @@ -14,4 +14,14 @@ #pragma link C++ class genie::DMDISXSec; #pragma link C++ class genie::DMElectronXSec; +#pragma link C++ class genie::DMRESPXSec; +#pragma link C++ class genie::DMRESXSec; +#pragma link C++ class genie::DMRESXSecFast; +#pragma link C++ class genie::DMRESXSecWithCacheFast; +#pragma link C++ class genie::FKRDM; +#pragma link C++ class genie::RSHelicityAmplModelDMn; +#pragma link C++ class genie::RSHelicityAmplModelDMp; +#pragma link C++ class genie::RSHelicityAmplModelDMI; +#pragma link C++ class genie::RSHelicityAmplDM; + #endif diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.cxx b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.cxx new file mode 100644 index 0000000000..1e208f416c --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.cxx @@ -0,0 +1,68 @@ +//____________________________________________________________________________ +/* +Dark Matter Calculations of |f|^2 terms for the cross section, based on the +procedure of FKR. + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.h" + +using namespace genie; +using std::endl; + +//____________________________________________________________________________ +namespace genie { + ostream & operator<< (ostream & stream, const RSHelicityAmplDM & hamp) + { + hamp.Print(stream); + return stream; + } +} +//____________________________________________________________________________ +RSHelicityAmplDM::RSHelicityAmplDM() +{ + this->Init(); +} +//____________________________________________________________________________ +RSHelicityAmplDM::RSHelicityAmplDM(const RSHelicityAmplDM & hamp) +{ + fMinus1 = hamp.AmpMinus1(); + fPlus1 = hamp.AmpPlus1(); + fMinus3 = hamp.AmpMinus3(); + fPlus3 = hamp.AmpPlus3(); + f0Minus = hamp.Amp0Minus(); + f0Plus = hamp.Amp0Plus(); + //New terms specific to DM + fz0Minus = hamp.Ampz0Minus(); + fz0Plus = hamp.Ampz0Plus(); +} +//____________________________________________________________________________ +void RSHelicityAmplDM::Print(ostream & stream) const +{ + stream << endl; + stream << " f(-1) = " << fMinus1 << endl; + stream << " f(+1) = " << fPlus1 << endl; + stream << " f(-3) = " << fMinus3 << endl; + stream << " f(+3) = " << fPlus3 << endl; + stream << " f(0-) = " << f0Minus << endl; + stream << " f(0+) = " << f0Plus << endl; + //New terms specific to DM + stream << " fz(0-) = " << fz0Minus << endl; + stream << " fz(0+) = " << fz0Plus << endl; +} +//____________________________________________________________________________ +void RSHelicityAmplDM::Init(void) +{ + fMinus1 = 0.0; + fPlus1 = 0.0; + fMinus3 = 0.0; + fPlus3 = 0.0; + f0Minus = 0.0; + f0Plus = 0.0; + //New terms specific to DM + fz0Minus = 0.0; + fz0Plus = 0.0; +} +//____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.h b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.h new file mode 100644 index 0000000000..6fd34b220d --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.h @@ -0,0 +1,106 @@ +//____________________________________________________________________________ +/* +Dark Matter Calculations of |f|^2 terms for the cross section, based on the +procedure of FKR. (header) + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + + + + +//____________________________________________________________________________ +/*! + +\class genie::RSHelicityAmpl + +\brief A class holding the Rein-Sehgal's helicity amplitudes. + + This class is using the \b Strategy Pattern. \n + It can accept requests to calculate itself, for a given interaction, + that it then delegates to the algorithmic object, implementing the + RSHelicityAmplModelI interface, that it finds attached to itself. + +\author Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + +\created May 03, 2004 + +\cpright Copyright (c) 2003-2020, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org +*/ +//____________________________________________________________________________ + +#ifndef _RS_HELICITY_AMPL_DM_H_ +#define _RS_HELICITY_AMPL_DM_H_ + +#include + +#include + +#include "Framework/Interaction/Interaction.h" +#include "Physics/BoostedDarkMatter/XSection/FKRDM.h" + +using std::ostream; + +namespace genie { + +class RSHelicityAmplDM; +ostream & operator<< (ostream & stream, const RSHelicityAmplDM & hamp); + +class RSHelicityAmplDM { +//Only two possibilites +friend class RSHelicityAmplModelDMp; +friend class RSHelicityAmplModelDMn; + +public: + + RSHelicityAmplDM(); + RSHelicityAmplDM(const RSHelicityAmplDM & hamp); + ~RSHelicityAmplDM() { } + + //! return helicity amplitude + double AmpMinus1 (void) const { return fMinus1; } /* f(-1) */ + double AmpPlus1 (void) const { return fPlus1; } /* f(+1) */ + double AmpMinus3 (void) const { return fMinus3; } /* f(-3) */ + double AmpPlus3 (void) const { return fPlus3; } /* f(+3) */ + double Amp0Minus (void) const { return f0Minus; } /* f(0-) */ + double Amp0Plus (void) const { return f0Plus; } /* f(0+) */ + //New terms specific to DM + double Ampz0Minus (void) const { return fz0Minus; } /* fz(0-) */ + double Ampz0Plus (void) const { return fz0Plus; } /* fz(0+) */ + + //! return |helicity amplitude|^2 + double Amp2Minus1 (void) const { return TMath::Power(fMinus1, 2.); } /* |f(-1)|^2 */ + double Amp2Plus1 (void) const { return TMath::Power(fPlus1, 2.); } /* |f(+1)|^2 */ + double Amp2Minus3 (void) const { return TMath::Power(fMinus3, 2.); } /* |f(-3)|^2 */ + double Amp2Plus3 (void) const { return TMath::Power(fPlus3, 2.); } /* |f(+3)|^2 */ + double Amp20Minus (void) const { return TMath::Power(f0Minus, 2.); } /* |f(0-)|^2 */ + double Amp20Plus (void) const { return TMath::Power(f0Plus, 2.); } /* |f(0+)|^2 */ + //New terms specific to DM + double Ampz20Minus (void) const { return TMath::Power(fz0Minus, 2.); } /* |fz(0-)|^2 */ + double Ampz20Plus (void) const { return TMath::Power(fz0Plus, 2.); } /* |fz(0+)|^2 */ + + friend ostream & operator<< (ostream & stream, const RSHelicityAmplDM & hamp); + + void Print(ostream & stream) const; + +private: + + void Init(void); + + double fMinus1; + double fPlus1; + double fMinus3; + double fPlus3; + double f0Minus; + double f0Plus; + //New terms specific to DM + double fz0Minus; + double fz0Plus; +}; + +} // genie namespace + +#endif // _RS_HELICITY_AMPL_DM_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.cxx b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.cxx new file mode 100644 index 0000000000..0e9492e125 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.cxx @@ -0,0 +1,59 @@ +//____________________________________________________________________________ +/* +RSHelicityAmplModelDMI: the interface for the Dark Matter helicity Amplitudes + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.h" //Specific to DM + +using namespace genie; + +//____________________________________________________________________________ +RSHelicityAmplModelDMI::RSHelicityAmplModelDMI() : +Algorithm() +{ + +} +//____________________________________________________________________________ +RSHelicityAmplModelDMI::RSHelicityAmplModelDMI(string name) : +Algorithm(name) +{ + +} +//____________________________________________________________________________ +RSHelicityAmplModelDMI::RSHelicityAmplModelDMI(string name, string config) : +Algorithm(name, config) +{ + +} +//____________________________________________________________________________ +RSHelicityAmplModelDMI::~RSHelicityAmplModelDMI() +{ + +} +//____________________________________________________________________________ + +//___________added for quark charges +//____________________________________________________________________________ +void RSHelicityAmplModelDMI::Configure(string config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//____________________________________________________________________________ +void RSHelicityAmplModelDMI::LoadConfig(void) +{ + + // quark couplings to mediator + double QuL, QuR, QdL, QdR; + this->GetParam( "UpLeftCharge", QuL ) ; + this->GetParam( "UpRightCharge", QuR ) ; + this->GetParam( "DownLeftCharge", QdL ) ; + this->GetParam( "DownRightCharge", QdR ) ; + fQuV = 0.5*(QuL + QuR); + fQuA = 0.5*(- QuL + QuR); + fQdV = 0.5*(QdL + QdR); + fQdA = 0.5*(- QdL + QdR); +} +//_____________ diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.h b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.h new file mode 100644 index 0000000000..c7c2c82c2d --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.h @@ -0,0 +1,50 @@ +//____________________________________________________________________________ +/* +RSHelicityAmplModelDMI: the interface for the Dark Matter helicity Amplitudes (header) + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + +#ifndef _REIN_SEHGAL_HELICITY_AMPL_MODEL_DM_I_H_ +#define _REIN_SEHGAL_HELICITY_AMPL_MODEL_DM_I_H_ + +#include "Framework/Algorithm/Algorithm.h" +#include "Framework/ParticleData/BaryonResonance.h" +#include "Physics/BoostedDarkMatter/XSection/FKRDM.h" +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.h" + +namespace genie { + +class RSHelicityAmplModelDMI : public Algorithm +{ +public: +//______________________ added for quark charges + void Configure(string config); +//______________________ + + virtual ~RSHelicityAmplModelDMI(); + + virtual const RSHelicityAmplDM & Compute(Resonance_t res, const FKRDM & fkrdm) const = 0; + + + +protected: + RSHelicityAmplModelDMI(); + RSHelicityAmplModelDMI(string name); + RSHelicityAmplModelDMI(string name, string config); + + //______________added for quark charges + void LoadConfig(void); + + double fQuV; + double fQuA; + double fQdV; + double fQdA; + //________________ + +}; + +} // namespace + +#endif // _REIN_SEHGAL_HELICITY_AMPL_MODEL_DM_I_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMn.cxx b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMn.cxx new file mode 100644 index 0000000000..f351a4c8df --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMn.cxx @@ -0,0 +1,312 @@ +//____________________________________________________________________________ +/* +Dark Matter Resonant Scattering Helicity Amplitudes for neutron Interactions + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Messenger/Messenger.h" +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMn.h" +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplDM.h" + +using namespace genie; +using namespace genie::constants; + +//____________________________________________________________________________ +RSHelicityAmplModelDMn::RSHelicityAmplModelDMn() : +RSHelicityAmplModelDMI("genie::RSHelicityAmplModelDMn") +{ + +} +//____________________________________________________________________________ +RSHelicityAmplModelDMn::RSHelicityAmplModelDMn(string config) : +RSHelicityAmplModelDMI("genie::RSHelicityAmplModelDMn", config) +{ + +} +//____________________________________________________________________________ +RSHelicityAmplModelDMn::~RSHelicityAmplModelDMn() +{ + +} +//____________________________________________________________________________ +const RSHelicityAmplDM & + RSHelicityAmplModelDMn::Compute( + Resonance_t res, const FKRDM & fkrdm) const +{ + switch(res) { + + case (kP33_1232) : + { + fAmpl.fMinus3 = kSqrt6 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = kSqrt2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus1 = kSqrt2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus3 = kSqrt6 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.f0Plus = 2.0 * kSqrt2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.f0Minus = 2.0 * kSqrt2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.fz0Plus = 2.0 * kSqrt2 * fkrdm.Cz * (fQuA - fQdA); + fAmpl.fz0Minus = 2.0 * kSqrt2 * fkrdm.Cz * (fQuA - fQdA); + + break; + } + case (kS11_1535) : + { + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQuA + 5 * fQdA) - fkrdm.Rv * (fQuV + 5 * fQdV)) + kSqrt3 * fkrdm.Ta * (fQdA - fQuA) + kSqrt3 * fkrdm.Tv * (fQuV - fQdV); + fAmpl.fPlus1 = -k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQuA + 5 * fQdA) + fkrdm.Rv * (fQuV + 5 * fQdV)) + kSqrt3 * fkrdm.Ta * (fQuA - fQdA) + kSqrt3 * fkrdm.Tv * (fQuV - fQdV); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV - fQuV) - 3 * fkrdm.Bs * (fQuA + 5 * fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQuA + 5 * fQdA)); + fAmpl.f0Minus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQuV - fQdV) - 3 * fkrdm.Bs * (fQuA + 5 * fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQuA + 5 * fQdA)); + fAmpl.fz0Plus = -k1_Sqrt6 * ((fQuA + 5 * fQdA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz)); + fAmpl.fz0Minus = -k1_Sqrt6 * ((fQuA + 5 * fQdA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz)); + + break; + } + case (kD13_1520) : + { + fAmpl.fMinus3 = k3_Sqrt2 * (fkrdm.Tv * (fQuV - fQdV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.fMinus1 = 0.5 * k1_Sqrt3 * (2.0 * fkrdm.Lamda * (fkrdm.Rv * (5 * fQdV + fQuV) - fkrdm.Ra * (5 * fQdA + fQuA)) + 3 * kSqrt2 * (fkrdm.Tv * (fQuV - fQdV) + fkrdm.Ta * (fQdA - fQuA))); + fAmpl.fPlus1 = 0.5 * k1_Sqrt3 * (-2.0 * fkrdm.Lamda * (fkrdm.Ra * fQuA + fkrdm.Rv * (5 * fQdV + fQuV)) + fQdA * (3 * kSqrt2 * fkrdm.Ta - 10 * fkrdm.Lamda * fkrdm.Ra) + 3 * kSqrt2 * fkrdm.Tv * (fQdV - fQuV) - 3 * kSqrt2 * fQuA * fkrdm.Ta); + fAmpl.fPlus3 = k3_Sqrt2 * (fkrdm.Tv * (fQdV - fQuV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.f0Plus = -fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQdV - fQuV) + fkrdm.Cs * (fQuA + 5 * fQdA)); + fAmpl.f0Minus = fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQuV - fQdV) + fkrdm.Cs * (fQuA + 5 * fQdA)); + fAmpl.fz0Plus = -fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQuA + 5 * fQdA); + fAmpl.fz0Minus = fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQuA + 5 * fQdA); + + break; + } + case (kS11_1650) : + { + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt6 * fkrdm.Lamda *(fkrdm.Rv * (2.0 * fQuV + fQdV) - fkrdm.Ra * (2.0 * fQuA + fQdA)); + fAmpl.fPlus1 = k1_Sqrt6* fkrdm.Lamda *(fkrdm.Rv * (2.0 * fQuV + fQdV) + fkrdm.Ra * (2.0 * fQuA + fQdA)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = -kSqrt2_3 * (2.0 * fQuA + fQdA) * (3 * fkrdm.Bs - fkrdm.Lamda * fkrdm.Cs); + fAmpl.f0Minus = -kSqrt2_3 * (2.0 * fQuA + fQdA) * (3 * fkrdm.Bs - fkrdm.Lamda * fkrdm.Cs); + fAmpl.fz0Plus = -kSqrt2_3 * (2.0 * fQuA + fQdA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + fAmpl.fz0Minus = -kSqrt2_3 * (2.0 * fQuA + fQdA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + + break; + } + case (kD13_1700) : + { + fAmpl.fMinus3 = (1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQuV + fQdV) - fkrdm.Ra * (2.0 * fQuA + fQdA)); + fAmpl.fMinus1 = k1_Sqrt30 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQuV + fQdV) - fkrdm.Ra * (2.0 * fQuA + fQdA)); + fAmpl.fPlus1 = -k1_Sqrt30 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQuV + fQdV) + fkrdm.Ra * (2.0 * fQuA + fQdA)); + fAmpl.fPlus3 = -(1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQuV + fQdV) + fkrdm.Ra * (2.0 * fQuA + fQdA)); + fAmpl.f0Plus = (kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQuA + fQdA); + fAmpl.f0Minus = -(kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQuA + fQdA); + fAmpl.fz0Plus = (kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQuA + fQdA); + fAmpl.fz0Minus = -(kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQuA + fQdA); + + break; + } + case (kD15_1675) : + { + fAmpl.fMinus3 = kSqrt3_5 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQuA + fQdA) - fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.fMinus1 = kSqrt3_10 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQuA + fQdA) - fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.fPlus1 = -kSqrt3_10 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQuA + fQdA) + fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.fPlus3 = -kSqrt3_5 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQuA + fQdA) + fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.f0Plus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQuA + fQdA); + fAmpl.f0Minus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQuA + fQdA); + fAmpl.fz0Plus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQuA + fQdA); + fAmpl.fz0Minus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQuA + fQdA); + + break; + } + case (kS31_1620) : + { + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)) + kSqrt3 * fkrdm.Ta * (fQuA - fQdA) + kSqrt3 * fkrdm.Tv * (fQdV - fQuV); + fAmpl.fPlus1 = k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)) + kSqrt3 * fkrdm.Ta * (fQdA - fQuA) + kSqrt3 * fkrdm.Tv * (fQdV - fQuV); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQuV - fQdV) + 3 * fkrdm.Bs * (fQuA - fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - fQuA)); + fAmpl.f0Minus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV - fQuV) + 3 * fkrdm.Bs * (fQuA - fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - fQuA)); + fAmpl.fz0Plus = -k1_Sqrt6 * (fQdA - fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + fAmpl.fz0Minus = -k1_Sqrt6 * (fQdA - fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + + break; + } + case (kD33_1700) : + { + fAmpl.fMinus3 = -k3_Sqrt2 * (fkrdm.Tv * (fQuV - fQdV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.fMinus1 = 0.5 * k1_Sqrt3 * ((fQuA - fQdA) * (2.0 * fkrdm.Lamda * fkrdm.Ra + 3 * kSqrt2 * fkrdm.Ta) + (fQdV - fQuV) * (2.0 * fkrdm.Lamda * fkrdm.Rv + 3 * kSqrt2 * fkrdm.Tv)); + fAmpl.fPlus1 = 0.5 * k1_Sqrt3 * ((fQuA - fQdA) * (2.0 * fkrdm.Lamda * fkrdm.Ra + 3 * kSqrt2 * fkrdm.Ta) - (fQdV - fQuV) * (2.0 * fkrdm.Lamda * fkrdm.Rv + 3 * kSqrt2 * fkrdm.Tv)); + fAmpl.fPlus3 = -k3_Sqrt2 * (fkrdm.Tv * (fQdV - fQuV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.f0Plus = fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQdV - fQuV) + fkrdm.Cs * (fQuA - fQdA)); + fAmpl.f0Minus = fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQdV - fQuV) + fkrdm.Cs * (fQdA - fQuA)); + fAmpl.fz0Plus = fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQuA - fQdA); + fAmpl.fz0Minus = fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQdA - fQuA); + + break; + } + case (kP11_1440) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = 0.5 * k1_Sqrt3 * L2 * (fkrdm.Ra * (fQuA - 4 * fQdA) - fkrdm.Rv * (fQuV - 4 * fQdV)); + fAmpl.fPlus1 = 0.5 * k1_Sqrt3 * L2 * (fkrdm.Ra * (fQuA - 4 * fQdA) + fkrdm.Rv * (fQuV - 4 * fQdV)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = (fkrdm.Lamda/2.0) * k1_Sqrt3 * (-3 * fkrdm.Lamda * fkrdm.S * (fQuV + 2.0 * fQdV) - 2.0 * fkrdm.Bs * (fQuA - 4 * fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQuA - 4 * fQdA)); + fAmpl.f0Minus = (fkrdm.Lamda/2.0) * k1_Sqrt3 * (-3 * fkrdm.Lamda * fkrdm.S * (fQuV + 2.0 * fQdV) + 2.0 * fkrdm.Bs * (fQuA - 4 * fQdA) + fkrdm.Lamda * fkrdm.Cs * (4 * fQdA - fQuA)); + fAmpl.fz0Plus = (fkrdm.Lamda/2.0) * k1_Sqrt3 * ((fQuA - 4 * fQdA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz)); + fAmpl.fz0Minus = -(fkrdm.Lamda/2.0) * k1_Sqrt3 * ((fQuA - 4 * fQdA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz)); + + break; + } + case (kP33_1600) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = k1_Sqrt2 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fMinus1 = k1_Sqrt6 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus1 = k1_Sqrt6 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus3 = k1_Sqrt2 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.f0Plus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs); + fAmpl.f0Minus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs); + fAmpl.fz0Plus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + fAmpl.fz0Minus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + + break; + } + case (kP13_1720) : + { + fAmpl.fMinus3 = (1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Ta * (fQuA + 2.0 * fQdA) - fkrdm.Tv * (fQuV + 2.0 * fQdV)); + fAmpl.fMinus1 = k1_Sqrt15 * (fkrdm.Lamda/2.0) * (2.0 * fkrdm.Lamda * (fkrdm.Ra * (fQuA - 4 * fQdA) - fkrdm.Rv * (fQuV - 4 * fQdV)) + 9 * kSqrt2 * (fkrdm.Tv * (fQuV + 2.0 * fQdV) - fkrdm.Ta * (fQuA + 2.0 * fQdA))); + fAmpl.fPlus1 = k1_Sqrt15 * (fkrdm.Lamda/2.0) * (9 * kSqrt2 * (fkrdm.Tv * (fQuV + 2.0 * fQdV) + fkrdm.Ta * (fQuA + 2.0 * fQdA)) - 2.0 * fkrdm.Lamda * (fkrdm.Ra * (fQuA - 4 * fQdA) + fkrdm.Rv * (fQuV - 4 * fQdV))); + fAmpl.fPlus3 = -(1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Ta * (fQuA + 2.0 * fQdA) + fkrdm.Tv * (fQuV + 2.0 * fQdV)); + fAmpl.f0Plus = fkrdm.Lamda * k1_Sqrt15 * (-3 * fkrdm.Lamda * fkrdm.S * (fQuV + 2.0 * fQdV) - 5 * fkrdm.Bs * (fQuA - 4 * fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQuA - 4 * fQdA)); + fAmpl.f0Minus = fkrdm.Lamda * k1_Sqrt15 * (3 * fkrdm.Lamda * fkrdm.S * (fQuV + 2.0 * fQdV) - 5 * fkrdm.Bs * (fQuA - 4 * fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQuA - 4 * fQdA)); + fAmpl.fz0Plus = fkrdm.Lamda * k1_Sqrt15 * ((4 * fQdA - fQuA) * (5 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz)); + fAmpl.fz0Minus = fkrdm.Lamda * k1_Sqrt15 * ((4 * fQdA - fQuA) * (5 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz)); + + break; + } + case (kF15_1680) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 3 * fkrdm.Lamda * kSqrt2_5 * (fkrdm.Tv * (fQuV + 2.0 * fQdV) - fkrdm.Ta * (fQuA + 2.0 * fQdA)); + fAmpl.fMinus1 = k1_Sqrt5 * (fkrdm.Lamda/2.0) * (kSqrt2 * fkrdm.Lamda * (fkrdm.Rv * (fQuV - 4 * fQdV) - fkrdm.Ra * (fQuA - 4 * fQdA)) + 6 * (fkrdm.Tv * (fQuV + 2.0 * fQdV) - fkrdm.Ta * (fQuA + 2.0 * fQdA))); + fAmpl.fPlus1 = k1_Sqrt5 * (fkrdm.Lamda/2.0) * (-kSqrt2 * fkrdm.Lamda * (fkrdm.Rv * (fQuV - 4 * fQdV) + fkrdm.Ra * (fQuA - 4 * fQdA)) - 6 * (fkrdm.Tv * (fQuV + 2.0 * fQdV) + fkrdm.Ta * (fQuA + 2.0 * fQdA))); + fAmpl.fPlus3 = -3 * fkrdm.Lamda * kSqrt2_5 * (fkrdm.Tv * (fQuV + 2.0 * fQdV) + fkrdm.Ta * (fQuA + 2.0 * fQdA)); + fAmpl.f0Plus = (1.0/kSqrt10) * L2 * (3 * fkrdm.S * (fQuV + 2.0 * fQdV) - fkrdm.Cs * (fQuA - 4 * fQdA)); + fAmpl.f0Minus = (1.0/kSqrt10) * L2 * (3 * fkrdm.S * (fQuV + 2.0 * fQdV) + fkrdm.Cs * (fQuA - 4 * fQdA)); + fAmpl.fz0Plus = -(1.0/kSqrt10) * L2 * fkrdm.Cz * (fQuA - 4 * fQdA); + fAmpl.fz0Minus = (1.0/kSqrt10) * L2 * fkrdm.Cz * (fQuA - 4 * fQdA); + + break; + } + case (kP31_1910) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = -k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.f0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.fz0Plus = -k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + fAmpl.fz0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + + break; + } + case (kP33_1920) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = k1_Sqrt5 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus3 = k1_Sqrt5 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.f0Plus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.f0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.fz0Plus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + fAmpl.fz0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + + break; + } + case (kF35_1905) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = -3 * L2 * (kSqrt2 * k1_Sqrt35) * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = L2 * k1_Sqrt35 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus1 = L2 * k1_Sqrt35 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus3 = -3 * L2 * (kSqrt2 * k1_Sqrt35) * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.f0Plus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cs * (fQdA - fQuA); + fAmpl.f0Minus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.fz0Plus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cz * (fQdA - fQuA); + fAmpl.fz0Minus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cz * (fQuA - fQdA); + + break; + } + case (kF37_1950) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = kSqrt2_7 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = kSqrt6_35 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus1 = kSqrt6_35 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus3 = kSqrt2_7 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.f0Plus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.f0Minus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.fz0Plus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cz * (fQuA - fQdA); + fAmpl.fz0Minus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cz * (fQuA - fQdA); + + break; + } + case (kP11_1710) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = 0.5 * k1_Sqrt6 * L2 * (fkrdm.Ra * (fQuA + 5 * fQdA) - fkrdm.Rv * (fQuV + 5 * fQdV)); + fAmpl.fPlus1 = 0.5 * k1_Sqrt6 * L2 * (fkrdm.Ra * (fQuA + 5 * fQdA) + fkrdm.Rv * (fQuV + 5 * fQdV)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = fkrdm.Lamda * 0.5 * k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV - fQuV) + (fQuA + 5 * fQdA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs)); + fAmpl.f0Minus = -fkrdm.Lamda * 0.5 * k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQuV - fQdV) + (fQuA + 5 * fQdA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs)); + fAmpl.fz0Plus = fkrdm.Lamda * 0.5 * k1_Sqrt6 * (fQuA + 5 * fQdA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + fAmpl.fz0Minus = -fkrdm.Lamda * 0.5 * k1_Sqrt6 * (fQuA + 5 * fQdA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + + break; + } + case (kF17_1970) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = (k1_Sqrt2 * k1_Sqrt7) * L2 * (fkrdm.Ra * (2.0 * fQuA + fQdA) - fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.fMinus1 = (kSqrt3_2 * k1_Sqrt35) * L2 * (fkrdm.Ra * (2.0 * fQuA + fQdA) - fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.fPlus1 = -(kSqrt3_2 * k1_Sqrt35) * L2 * (fkrdm.Ra * (2.0 * fQuA + fQdA) + fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.fPlus3 = -(k1_Sqrt2 * k1_Sqrt7) * L2 * (fkrdm.Ra * (2.0 * fQuA + fQdA) + fkrdm.Rv * (2.0 * fQuV + fQdV)); + fAmpl.f0Plus = -kSqrt6_35 * L2 * fkrdm.Cs * (2.0 * fQuA + fQdA); + fAmpl.f0Minus = -kSqrt6_35 * L2 * fkrdm.Cs * (2.0 * fQuA + fQdA); + fAmpl.fz0Plus = -kSqrt6_35 * L2 * fkrdm.Cz * (2.0 * fQuA + fQdA); + fAmpl.fz0Minus = -kSqrt6_35 * L2 * fkrdm.Cz * (2.0 * fQuA + fQdA); + + break; + } + + default: + { + LOG("DMHAmpl", pWARN) << "*** UNRECOGNIZED RESONANCE!"; + fAmpl.fMinus1 = 0.; + fAmpl.fPlus1 = 0.; + fAmpl.fMinus3 = 0.; + fAmpl.fPlus3 = 0.; + fAmpl.f0Minus = 0.; + fAmpl.f0Plus = 0.; + break; + } + + }//switch + + return fAmpl; +} +//____________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMn.h b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMn.h new file mode 100644 index 0000000000..fdd1c7f6d4 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMn.h @@ -0,0 +1,31 @@ +//____________________________________________________________________________ +/* +Dark Matter Resonant Scattering Amplitude Calculation for neutron Interactions (header) + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + + +#ifndef _HELICITY_AMPL_MODEL_DM_N_H_ +#define _HELICITY_AMPL_MODEL_DM_N_H_ + +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.h" + +namespace genie { + +class RSHelicityAmplModelDMn : public RSHelicityAmplModelDMI { + +public: + RSHelicityAmplModelDMn(); + RSHelicityAmplModelDMn(string config); + virtual ~RSHelicityAmplModelDMn(); + + const RSHelicityAmplDM & Compute(Resonance_t res, const FKRDM & fkrdm) const; + +private: + mutable RSHelicityAmplDM fAmpl; +}; + +} // genie namespace +#endif // _HELICITY_AMPL_MODEL_DM_N_H_ diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMp.cxx b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMp.cxx new file mode 100644 index 0000000000..09af5615e5 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMp.cxx @@ -0,0 +1,314 @@ +//____________________________________________________________________________ +/* +Dark Matter Resonant Scattering Helicity Amplitudes for proton Interactions + + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + +#include "Framework/ParticleData/BaryonResUtils.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Messenger/Messenger.h" +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMp.h" + +using namespace genie; +using namespace genie::constants; + +//____________________________________________________________________________ +RSHelicityAmplModelDMp::RSHelicityAmplModelDMp() : +RSHelicityAmplModelDMI("genie::RSHelicityAmplModelDMp") +{ + +} +//____________________________________________________________________________ +RSHelicityAmplModelDMp::RSHelicityAmplModelDMp(string config) : +RSHelicityAmplModelDMI("genie::RSHelicityAmplModelDMp", config) +{ + +} +//____________________________________________________________________________ +RSHelicityAmplModelDMp::~RSHelicityAmplModelDMp() +{ + +} +//____________________________________________________________________________ +const RSHelicityAmplDM & + RSHelicityAmplModelDMp::Compute( + Resonance_t res, const FKRDM & fkrdm) const +{ + switch(res) { + + + case (kP33_1232) : + { + fAmpl.fMinus3 = kSqrt6 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = kSqrt2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus1 = kSqrt2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus3 = kSqrt6 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.f0Plus = 2.0 * kSqrt2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.f0Minus = 2.0 * kSqrt2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.fz0Plus = 2.0 * kSqrt2 * fkrdm.Cz * (fQuA - fQdA); + fAmpl.fz0Minus = 2.0 * kSqrt2 * fkrdm.Cz * (fQuA - fQdA); + + break; + } + case (kS11_1535) : + { + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQdA + 5 * fQuA) - fkrdm.Rv * (fQdV + 5 * fQuV)) + kSqrt3 * fkrdm.Ta * (fQuA - fQdA) + kSqrt3 * fkrdm.Tv * (fQdV - fQuV); + fAmpl.fPlus1 = -k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQdA + 5 * fQuA) + fkrdm.Rv * (fQdV + 5 * fQuV)) + kSqrt3 * fkrdm.Ta * (fQdA - fQuA) + kSqrt3 * fkrdm.Tv * (fQdV - fQuV); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQuV - fQdV) - 3 * fkrdm.Bs * (fQdA + 5 * fQuA) + fkrdm.Lamda * fkrdm.Cs * (fQdA + 5 * fQuA)); + fAmpl.f0Minus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV - fQuV) - 3 * fkrdm.Bs * (fQdA + 5 * fQuA) + fkrdm.Lamda * fkrdm.Cs * (fQdA + 5 * fQuA)); + fAmpl.fz0Plus = -k1_Sqrt6 * ((fQdA + 5 * fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz)); + fAmpl.fz0Minus = -k1_Sqrt6 * ((fQdA + 5 * fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz)); + + break; + } + case (kD13_1520) : + { + fAmpl.fMinus3 = -k3_Sqrt2 * (fkrdm.Tv * (fQuV - fQdV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.fMinus1 = 0.5 * k1_Sqrt3 * (2.0 * fkrdm.Lamda * (fkrdm.Rv * (fQdV + 5 * fQuV) - 5 * fkrdm.Ra * fQuA) - fQdA * (2.0 * fkrdm.Lamda * fkrdm.Ra + 3 * kSqrt2 * fkrdm.Ta) + 3 * kSqrt2 * fkrdm.Tv * (fQdV - fQuV) + 3 * kSqrt2 * fQuA * fkrdm.Ta); + fAmpl.fPlus1 = 0.5 * k1_Sqrt3 * (-2.0 * fkrdm.Lamda * (fkrdm.Rv * (fQdV + 5 * fQuV) + 5 * fkrdm.Ra * fQuA) - fQdA * (2.0 * fkrdm.Lamda * fkrdm.Ra + 3 * kSqrt2 * fkrdm.Ta) + 3 * kSqrt2 * fkrdm.Tv * (fQuV - fQdV) + 3 * kSqrt2 * fQuA * fkrdm.Ta); + fAmpl.fPlus3 = -k3_Sqrt2 * (fkrdm.Tv * (fQdV - fQuV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.f0Plus = -fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQuV - fQdV) + fkrdm.Cs * (fQdA + 5 * fQuA)); + fAmpl.f0Minus = fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQdV - fQuV) + fkrdm.Cs * (fQdA + 5 * fQuA)); + fAmpl.fz0Plus = -fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQdA + 5 * fQuA); + fAmpl.fz0Minus = fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQdA + 5 * fQuA); + + break; + } + case (kS11_1650) : + { + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt6 * fkrdm.Lamda *(fkrdm.Rv * (2.0 * fQdV + fQuV) - fkrdm.Ra * (2.0 * fQdA + fQuA)); + fAmpl.fPlus1 = k1_Sqrt6* fkrdm.Lamda *(fkrdm.Rv * (2.0 * fQdV + fQuV) + fkrdm.Ra * (2.0 * fQdA + fQuA)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = -kSqrt2_3 * (2.0 * fQdA + fQuA) * (3 * fkrdm.Bs - fkrdm.Lamda * fkrdm.Cs); + fAmpl.f0Minus = -kSqrt2_3 * (2.0 * fQdA + fQuA) * (3 * fkrdm.Bs - fkrdm.Lamda * fkrdm.Cs); + fAmpl.fz0Plus = -kSqrt2_3 * (2.0 * fQdA + fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + fAmpl.fz0Minus = -kSqrt2_3 * (2.0 * fQdA + fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + + break; + } + case (kD13_1700) : + { + fAmpl.fMinus3 = (1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQdV + fQuV) - fkrdm.Ra * (2.0 * fQdA + fQuA)); + fAmpl.fMinus1 = k1_Sqrt30 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQdV + fQuV) - fkrdm.Ra * (2.0 * fQdA + fQuA)); + fAmpl.fPlus1 = -k1_Sqrt30 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQdV + fQuV) + fkrdm.Ra * (2.0 * fQdA + fQuA)); + fAmpl.fPlus3 = -(1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Rv * (2.0 * fQdV + fQuV) + fkrdm.Ra * (2.0 * fQdA + fQuA)); + fAmpl.f0Plus = (kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQdA + fQuA); + fAmpl.f0Minus = -(kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQdA + fQuA); + fAmpl.fz0Plus = (kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQdA + fQuA); + fAmpl.fz0Minus = -(kSqrt2 * k1_Sqrt15) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQdA + fQuA); + + break; + } + case (kD15_1675) : + { + fAmpl.fMinus3 = kSqrt3_5 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQdA + fQuA) - fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.fMinus1 = kSqrt3_10 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQdA + fQuA) - fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.fPlus1 = -kSqrt3_10 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQdA + fQuA) + fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.fPlus3 = -kSqrt3_5 * fkrdm.Lamda * (fkrdm.Ra * (2.0 * fQdA + fQuA) + fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.f0Plus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQdA + fQuA); + fAmpl.f0Minus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cs * (2.0 * fQdA + fQuA); + fAmpl.fz0Plus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQdA + fQuA); + fAmpl.fz0Minus = -(kSqrt3 * kSqrt2_5) * fkrdm.Lamda * fkrdm.Cz * (2.0 * fQdA + fQuA); + + break; + } + case (kS31_1620) : + { + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)) + kSqrt3 * fkrdm.Ta * (fQuA - fQdA) + kSqrt3 * fkrdm.Tv * (fQdV - fQuV); + fAmpl.fPlus1 = k1_Sqrt6 * fkrdm.Lamda * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)) + kSqrt3 * fkrdm.Ta * (fQdA - fQuA) + kSqrt3 * fkrdm.Tv * (fQdV - fQuV); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQuV - fQdV) + 3 * fkrdm.Bs * (fQuA - fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - fQuA)); + fAmpl.f0Minus = k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV - fQuV) + 3 * fkrdm.Bs * (fQuA - fQdA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - fQuA)); + fAmpl.fz0Plus = -k1_Sqrt6 * (fQdA - fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + fAmpl.fz0Minus = -k1_Sqrt6 * (fQdA - fQuA) * (3 * fkrdm.Bz - fkrdm.Lamda * fkrdm.Cz); + + break; + } + case (kD33_1700) : + { + fAmpl.fMinus3 = -k3_Sqrt2 * (fkrdm.Tv * (fQuV - fQdV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.fMinus1 = 0.5 * k1_Sqrt3 * ((fQuA - fQdA) * (2.0 * fkrdm.Lamda * fkrdm.Ra + 3 * kSqrt2 * fkrdm.Ta) + (fQdV - fQuV) * (2.0 * fkrdm.Lamda * fkrdm.Rv + 3 * kSqrt2 * fkrdm.Tv)); + fAmpl.fPlus1 = 0.5 * k1_Sqrt3 * ((fQuA - fQdA) * (2.0 * fkrdm.Lamda * fkrdm.Ra + 3 * kSqrt2 * fkrdm.Ta) - (fQdV - fQuV) * (2.0 * fkrdm.Lamda * fkrdm.Rv + 3 * kSqrt2 * fkrdm.Tv)); + fAmpl.fPlus3 = -k3_Sqrt2 * (fkrdm.Tv * (fQdV - fQuV) + fkrdm.Ta * (fQdA - fQuA)); + fAmpl.f0Plus = fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQdV - fQuV) + fkrdm.Cs * (fQuA - fQdA)); + fAmpl.f0Minus = fkrdm.Lamda * k1_Sqrt3 * (3 * fkrdm.S * (fQdV - fQuV) + fkrdm.Cs * (fQdA - fQuA)); + fAmpl.fz0Plus = fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQuA - fQdA); + fAmpl.fz0Minus = fkrdm.Lamda * fkrdm.Cz * k1_Sqrt3 * (fQdA - fQuA); + + break; + } + case (kP11_1440) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = 0.5 * k1_Sqrt3 * L2 * (fkrdm.Ra * (fQdA - 4 * fQuA) - fkrdm.Rv * (fQdV - 4 * fQuV)); + fAmpl.fPlus1 = 0.5 * k1_Sqrt3 * L2 * (fkrdm.Ra * (fQdA - 4 * fQuA) + fkrdm.Rv * (fQdV - 4 * fQuV)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = (fkrdm.Lamda/2.0) * k1_Sqrt3 * (-3 * fkrdm.Lamda * fkrdm.S * (fQdV + 2.0 * fQuV) - 2.0 * fkrdm.Bs * (fQdA - 4 * fQuA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - 4 * fQuA)); + fAmpl.f0Minus = -(fkrdm.Lamda/2.0) * k1_Sqrt3 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV + 2.0 * fQuV) - 2.0 * fkrdm.Bs * (fQdA - 4 * fQuA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - 4 * fQuA)); + fAmpl.fz0Plus = (fkrdm.Lamda/2.0) * k1_Sqrt3 * ((fQdA - 4 * fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz)); + fAmpl.fz0Minus = -(fkrdm.Lamda/2.0) * k1_Sqrt3 * ((fQdA - 4 * fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz)); + + break; + } + case (kP33_1600) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = k1_Sqrt2 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fMinus1 = k1_Sqrt6 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus1 = k1_Sqrt6 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus3 = k1_Sqrt2 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.f0Plus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs); + fAmpl.f0Minus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs); + fAmpl.fz0Plus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + fAmpl.fz0Minus = kSqrt2_3 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + + break; + } + case (kP13_1720) : + { + fAmpl.fMinus3 = (1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Ta * (fQdA + 2.0 * fQuA) - fkrdm.Tv * (fQdV + 2.0 * fQuV)); + fAmpl.fMinus1 = k1_Sqrt15 * (fkrdm.Lamda/2.0) * (2.0 * fkrdm.Lamda * (fkrdm.Ra * (fQdA - 4 * fQuA) - fkrdm.Rv * (fQdV - 4 * fQuV)) + 9 * kSqrt2 * (fkrdm.Tv * (fQdV + 2.0 * fQuV) - fkrdm.Ta * (fQdA + 2.0 * fQuA))); + fAmpl.fPlus1 = k1_Sqrt15 * (fkrdm.Lamda/2.0) * (9 * kSqrt2 * (fkrdm.Tv * (fQdV + 2.0 * fQuV) + fkrdm.Ta * (fQdA + 2.0 * fQuA)) - 2.0 * fkrdm.Lamda * (fkrdm.Ra * (fQdA - 4 * fQuA) + fkrdm.Rv * (fQdV - 4 * fQuV))); + fAmpl.fPlus3 = -(1.0/kSqrt10) * 3 * fkrdm.Lamda * (fkrdm.Ta * (fQdA + 2.0 * fQuA) + fkrdm.Tv * (fQdV + 2.0 * fQuV)); + fAmpl.f0Plus = fkrdm.Lamda * k1_Sqrt15 * (-3 * fkrdm.Lamda * fkrdm.S * (fQdV + 2.0 * fQuV) - 5 * fkrdm.Bs * (fQdA - 4 * fQuA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - 4 * fQuA)); + fAmpl.f0Minus = fkrdm.Lamda * k1_Sqrt15 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV + 2.0 * fQuV) - 5 * fkrdm.Bs * (fQdA - 4 * fQuA) + fkrdm.Lamda * fkrdm.Cs * (fQdA - 4 * fQuA)); + fAmpl.fz0Plus = fkrdm.Lamda * k1_Sqrt15 * ((fQdA - 4 * fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz)); + fAmpl.fz0Minus = fkrdm.Lamda * k1_Sqrt15 * ((fQdA - 4 * fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz)); + + break; + } + case (kF15_1680) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 3 * fkrdm.Lamda * kSqrt2_5 * (fkrdm.Tv * (fQdV + 2.0 * fQuV) - fkrdm.Ta * (fQdA + 2.0 * fQuA)); + fAmpl.fMinus1 = k1_Sqrt5 * (fkrdm.Lamda/2.0) * (kSqrt2 * fkrdm.Lamda * (fkrdm.Rv * (fQdV - 4 * fQuV) - fkrdm.Ra * (fQdA - 4 * fQuA)) + 6 * (fkrdm.Tv * (fQdV + 2.0 * fQuV) - fkrdm.Ta * (fQdA + 2.0 * fQuA))); + fAmpl.fPlus1 = k1_Sqrt5 * (fkrdm.Lamda/2.0) * (-kSqrt2 * fkrdm.Lamda * (fkrdm.Rv * (fQdV - 4 * fQuV) + fkrdm.Ra * (fQdA - 4 * fQuA)) - 6 * (fkrdm.Tv * (fQdV + 2.0 * fQuV) + fkrdm.Ta * (fQdA + 2.0 * fQuA))); + fAmpl.fPlus3 = -3 * fkrdm.Lamda * kSqrt2_5 * (fkrdm.Tv * (fQdV + 2.0 * fQuV) + fkrdm.Ta * (fQdA + 2.0 * fQuA)); + fAmpl.f0Plus = (1.0/kSqrt10) * L2 * (3 * fkrdm.S * (fQdV + 2.0 * fQuV) - fkrdm.Cs * (fQdA - 4 * fQuA)); + fAmpl.f0Minus = (1.0/kSqrt10) * L2 * (3 * fkrdm.S * (fQdV + 2.0 * fQuV) + fkrdm.Cs * (fQdA - 4 * fQuA)); + fAmpl.fz0Plus = -(1.0/kSqrt10) * L2 * fkrdm.Cz * (fQdA - 4 * fQuA); + fAmpl.fz0Minus = (1.0/kSqrt10) * L2 * fkrdm.Cz * (fQdA - 4 * fQuA); + + break; + } + case (kP31_1910) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = -k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.f0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.fz0Plus = -k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + fAmpl.fz0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + + break; + } + case (kP33_1920) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = k1_Sqrt5 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus1 = k1_Sqrt15 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus3 = k1_Sqrt5 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.f0Plus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.f0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cs - 5 * fkrdm.Bs); + fAmpl.fz0Plus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + fAmpl.fz0Minus = k1_Sqrt15 * 2.0 * fkrdm.Lamda * (fQdA - fQuA) * (fkrdm.Lamda * fkrdm.Cz - 5 * fkrdm.Bz); + + break; + } + case (kF35_1905) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = -3 * L2 * (kSqrt2 * k1_Sqrt35) * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = L2 * k1_Sqrt35 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.fPlus1 = L2 * k1_Sqrt35 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus3 = -3 * L2 * (kSqrt2 * k1_Sqrt35) * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQdV - fQuV)); + fAmpl.f0Plus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cs * (fQdA - fQuA); + fAmpl.f0Minus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.fz0Plus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cz * (fQdA - fQuA); + fAmpl.fz0Minus = 2.0 * L2 * k1_Sqrt35 * fkrdm.Cz * (fQuA - fQdA); + + break; + } + case (kF37_1950) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = kSqrt2_7 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fMinus1 = kSqrt6_35 * L2 * (fkrdm.Ra * (fQdA - fQuA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus1 = kSqrt6_35 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.fPlus3 = kSqrt2_7 * L2 * (fkrdm.Ra * (fQuA - fQdA) + fkrdm.Rv * (fQuV - fQdV)); + fAmpl.f0Plus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.f0Minus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cs * (fQuA - fQdA); + fAmpl.fz0Plus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cz * (fQuA - fQdA); + fAmpl.fz0Minus = 2.0 * kSqrt6_35 * L2 * fkrdm.Cz * (fQuA - fQdA); + + break; + } + case (kP11_1710) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = 0; + fAmpl.fMinus1 = 0.5 * k1_Sqrt6 * L2 * (fkrdm.Ra * (fQdA + 5 * fQuA) - fkrdm.Rv * (fQdV + 5 * fQuV)); + fAmpl.fPlus1 = 0.5 * k1_Sqrt6 * L2 * (fkrdm.Ra * (fQdA + 5 * fQuA) + fkrdm.Rv * (fQdV + 5 * fQuV)); + fAmpl.fPlus3 = 0; + fAmpl.f0Plus = fkrdm.Lamda * 0.5 * k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQuV - fQdV) + (fQdA + 5 * fQuA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs)); + fAmpl.f0Minus = -fkrdm.Lamda * 0.5 * k1_Sqrt6 * (3 * fkrdm.Lamda * fkrdm.S * (fQdV - fQuV) + (fQdA + 5 * fQuA) * (fkrdm.Lamda * fkrdm.Cs - 2.0 * fkrdm.Bs)); + fAmpl.fz0Plus = fkrdm.Lamda * 0.5 * k1_Sqrt6 * (fQdA + 5 * fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + fAmpl.fz0Minus = -fkrdm.Lamda * 0.5 * k1_Sqrt6 * (fQdA + 5 * fQuA) * (fkrdm.Lamda * fkrdm.Cz - 2.0 * fkrdm.Bz); + + break; + } + case (kF17_1970) : + { + double L2 = TMath::Power(fkrdm.Lamda, 2); + + fAmpl.fMinus3 = (k1_Sqrt2 * k1_Sqrt7) * L2 * (fkrdm.Ra * (2.0 * fQdA + fQuA) - fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.fMinus1 = (kSqrt3_2 * k1_Sqrt35) * L2 * (fkrdm.Ra * (2.0 * fQdA + fQuA) - fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.fPlus1 = -(kSqrt3_2 * k1_Sqrt35) * L2 * (fkrdm.Ra * (2.0 * fQdA + fQuA) + fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.fPlus3 = -(k1_Sqrt2 * k1_Sqrt7) * L2 * (fkrdm.Ra * (2.0 * fQdA + fQuA) + fkrdm.Rv * (2.0 * fQdV + fQuV)); + fAmpl.f0Plus = -kSqrt6_35 * L2 * fkrdm.Cs * (2.0 * fQdA + fQuA); + fAmpl.f0Minus = -kSqrt6_35 * L2 * fkrdm.Cs * (2.0 * fQdA + fQuA); + fAmpl.fz0Plus = -kSqrt6_35 * L2 * fkrdm.Cz * (2.0 * fQdA + fQuA); + fAmpl.fz0Minus = -kSqrt6_35 * L2 * fkrdm.Cz * (2.0 * fQdA + fQuA); + + break; + } + default: + { + LOG("DMHAmpl", pWARN) << "*** UNRECOGNIZED RESONANCE!"; + fAmpl.fMinus1 = 0.; + fAmpl.fPlus1 = 0.; + fAmpl.fMinus3 = 0.; + fAmpl.fPlus3 = 0.; + fAmpl.f0Minus = 0.; + fAmpl.f0Plus = 0.; + //New terms specific to DM + fAmpl.fz0Minus = 0.; + fAmpl.fz0Plus = 0.; + break; + } + + }//switch + + return fAmpl; + } + //___________________________________________________________________________ diff --git a/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMp.h b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMp.h new file mode 100644 index 0000000000..39127a7f91 --- /dev/null +++ b/src/Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMp.h @@ -0,0 +1,32 @@ +//____________________________________________________________________________ +/* +Dark Matter Resonant Scattering Amplitude Calculation for proton Interactions (header) + +Zachary W. Orr, Colorado State University +*/ +//____________________________________________________________________________ + + +#ifndef _HELICITY_AMPL_MODEL_DM_P_H_ +#define _HELICITY_AMPL_MODEL_DM_P_H_ + +#include "Physics/BoostedDarkMatter/XSection/RSHelicityAmplModelDMI.h" + +namespace genie { + +class RSHelicityAmplModelDMp : public RSHelicityAmplModelDMI { + +public: + RSHelicityAmplModelDMp(); + RSHelicityAmplModelDMp(string config); + virtual ~RSHelicityAmplModelDMp(); + + + const RSHelicityAmplDM & Compute(Resonance_t res, const FKRDM & fkrdm) const; + +private: + mutable RSHelicityAmplDM fAmpl; +}; + +} // genie namespace +#endif // _HELICITY_AMPL_MODEL_DM_N_H_ diff --git a/src/Physics/HadronTransport/HAIntranuke2025.cxx b/src/Physics/HadronTransport/HAIntranuke2025.cxx new file mode 100644 index 0000000000..cb5027f69f --- /dev/null +++ b/src/Physics/HadronTransport/HAIntranuke2025.cxx @@ -0,0 +1,1617 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + + Author: Steve Dytman , Pittsburgh Univ. + Aaron Meyer , Pittsburgh Univ. + Alex Bell, Pittsburgh Univ. + Hugh Gallagher , Tufts Univ. + Costas Andreopoulos , Rutherford Lab. + September 20, 2005 + + For the class documentation see the corresponding header file. + + Important revisions after version 2.0.0 : + @ sep 2025 - Mohamed Ismail, SD + new class for hA2025. no changes from the 2018 class version, major changes made in INukeHadroData2025 +for new hA pion splines Add data, use hN for high pion KE, use INCL for low energy. Use splines for channel +and total reac xs to improve accuracy. Also, smooth results to avoid discontinuities. + + +*/ +//____________________________________________________________________________ + +#include +#include +#include + +#include + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/Algorithm/AlgFactory.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Conventions/Controls.h" +#include "Framework/EventGen/EVGThreadException.h" +#include "Framework/GHEP/GHepFlags.h" +#include "Framework/GHEP/GHepStatus.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Physics/HadronTransport/INukeException.h" +#include "Physics/HadronTransport/Intranuke2025.h" +#include "Physics/HadronTransport/HAIntranuke2025.h" +#include "Physics/HadronTransport/INukeHadroData2025.h" +#include "Physics/HadronTransport/INukeUtils2025.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/Numerical/RandomGen.h" +#include "Framework/Numerical/Spline.h" +#include "Framework/ParticleData/PDGLibrary.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Framework/ParticleData/PDGCodeList.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/Utils/PrintUtils.h" +#include "Physics/NuclearState/NuclearUtils.h" +#include "Physics/NuclearState/NuclearModelI.h" +#include "Physics/NuclearState/NuclearModelMap.h" +//#include "Physics/HadronTransport/INukeOset.h" + +using std::ostringstream; + +using namespace genie; +using namespace genie::utils; +using namespace genie::utils::intranuke2025; +using namespace genie::constants; +using namespace genie::controls; + +//___________________________________________________________________________ +//___________________________________________________________________________ +// Methods specific to INTRANUKE's HA-mode +//___________________________________________________________________________ +//___________________________________________________________________________ +HAIntranuke2025::HAIntranuke2025() : +Intranuke2025("genie::HAIntranuke2025") +{ + +} +//___________________________________________________________________________ +HAIntranuke2025::HAIntranuke2025(string config) : +Intranuke2025("genie::HAIntranuke2025",config) +{ + +} +//___________________________________________________________________________ +HAIntranuke2025::~HAIntranuke2025() +{ + +} +//___________________________________________________________________________ +void HAIntranuke2025::ProcessEventRecord(GHepRecord * evrec) const +{ + LOG("HAIntranuke2025", pNOTICE) + << "************ Running hA2025 MODE INTRANUKE ************"; + GHepParticle * nuclearTarget = evrec -> TargetNucleus(); + nuclA = nuclearTarget -> A(); + + Intranuke2025::ProcessEventRecord(evrec); + + LOG("HAIntranuke2025", pINFO) << "Done with this event"; +} +//___________________________________________________________________________ +void HAIntranuke2025::SimulateHadronicFinalState( + GHepRecord* ev, GHepParticle* p) const +{ +// Simulate a hadron interaction for the input particle p in HA mode +// + // check inputs + if(!p || !ev) { + LOG("HAIntranuke2025", pERROR) << "** Null input!"; + return; + } + + // get particle code and check whether this particle can be handled + int pdgc = p->Pdg(); + bool is_gamma = (pdgc==kPdgGamma); + bool is_pion = (pdgc==kPdgPiP || pdgc==kPdgPiM || pdgc==kPdgPi0); + bool is_kaon = (pdgc==kPdgKP); // sd: only K+. need many changes for K- + bool is_baryon = (pdgc==kPdgProton || pdgc==kPdgNeutron); + bool is_handled = (is_baryon || is_pion || is_kaon || is_gamma); + if(!is_handled) { + LOG("HAIntranuke2025", pERROR) << "** Can not handle particle: " << p->Name(); + return; + } + + // select a fate for the input particle + INukeFateHA_t fate = this->HadronFateHA(p); + + // store the fate + ev->Particle(p->FirstMother())->SetRescatterCode((int)fate); + + if(fate == kIHAFtUndefined) { + LOG("HAIntranuke2025", pERROR) << "** Couldn't select a fate"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + LOG("HAIntranuke2025", pNOTICE) + << "Selected "<< p->Name() << " fate: "<< INukeHadroFates2025::AsString(fate); + + // try to generate kinematics - repeat till is done (should seldom need >2) + fNumIterations = 0; + this->SimulateHadronicFinalStateKinematics(ev,p); +} +//___________________________________________________________________________ +void HAIntranuke2025::SimulateHadronicFinalStateKinematics( + GHepRecord* ev, GHepParticle* p) const +{ + // get stored fate + INukeFateHA_t fate = (INukeFateHA_t) + ev->Particle(p->FirstMother())->RescatterCode(); + + LOG("HAIntranuke2025", pINFO) + << "Generating kinematics for " << p->Name() + << " fate: "<< INukeHadroFates2025::AsString(fate); + + // try to generate kinematics for the selected fate + + try + { + fNumIterations++; + /* if (fate == kIHAFtElas) + { + this->ElasHA(ev,p,fate); + } + else */ + if (fate == kIHAFtInelas || fate == kIHAFtCEx) + { + this->InelasticHA(ev,p,fate); + } + else if (fate == kIHAFtAbs || fate == kIHAFtPiProd) + { + this->Inelastic(ev,p,fate); + } + else if (fate == kIHAFtCmp) //(suarez edit, 17 July, 2017: cmp) + { + LOG("HAIntranuke2025", pWARN) << "Running PreEquilibrium for kIHAFtCmp"; + LOG("HAIntranuke2025", pFATAL) << "The PreEquilibrium and Compound Nucleus code are experimental, should not be used"; + utils::intranuke2025::PreEquilibrium(ev,p,fRemnA,fRemnZ,fRemnP4,fDoFermi,fFermiFac,fNuclmodel,fNucRmvE,kIMdHA); //should be kiMdHA or HN? + } + } + catch(exceptions::INukeException exception) + { + LOG("HAIntranuke2025", pNOTICE) + << exception; + if(fNumIterations <= 100) { + LOG("HAIntranuke2025", pNOTICE) + << "Failed attempt to generate kinematics for " + << p->Name() << " fate: " << INukeHadroFates2025::AsString(fate) + << " - After " << fNumIterations << " tries, still retrying..."; + this->SimulateHadronicFinalStateKinematics(ev,p); + } else { + LOG("HAIntranuke2025", pNOTICE) + << "Failed attempt to generate kinematics for " + << p->Name() << " fate: " << INukeHadroFates2025::AsString(fate) + << " after " << fNumIterations-1 + << " attempts. Trying a new fate..."; + this->SimulateHadronicFinalState(ev,p); + } + } +} +//___________________________________________________________________________ +INukeFateHA_t HAIntranuke2025::HadronFateHA(const GHepParticle * p) const +{ +// Select a hadron fate in HA mode +// + RandomGen * rnd = RandomGen::Instance(); + + // get pdgc code & kinetic energy in MeV + int pdgc = p->Pdg(); + double ke = p->KinE() / units::MeV; + + //bool isPion = (pdgc == kPdgPiP or pdgc == kPdgPi0 or pdgc == kPdgPiM); + //if (isPion and fUseOset and ke < 350.0) return this->HadronFateOset(); + + LOG("HAIntranuke2025", pINFO) + << "Selecting hA fate for " << p->Name() << " with KE = " << ke << " MeV"; + + // try to generate a hadron fate + unsigned int iter = 0; + while(iter++ < kRjMaxIterations) { + + // handle pions + // + if (pdgc==kPdgPiP || pdgc==kPdgPiM || pdgc==kPdgPi0) { + + double frac_cex = fHadroData2025->FracADep(pdgc, kIHAFtCEx, ke, nuclA); + // double frac_elas = fHadroData2025->FracADep(pdgc, kIHAFtElas, ke, nuclA); + double frac_inel = fHadroData2025->FracADep(pdgc, kIHAFtInelas, ke, nuclA); + double frac_abs = fHadroData2025->FracADep(pdgc, kIHAFtAbs, ke, nuclA); + double frac_piprod = fHadroData2025->FracADep(pdgc, kIHAFtPiProd, ke, nuclA); + LOG("HAIntranuke2025", pDEBUG) + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtCEx) << "} = " << frac_cex + // << "\n frac{" << INukeHadroFates::AsString(kIHAFtElas) << "} = " << frac_elas + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtInelas) << "} = " << frac_inel + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtAbs) << "} = " << frac_abs + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtPiProd) << "} = " << frac_piprod; + + // apply external tweaks to fractions + frac_cex *= fPionFracCExScale; + frac_inel *= fPionFracInelScale; + if (pdgc==kPdgPiP || pdgc==kPdgPiM) frac_abs *= fChPionFracAbsScale; + if (pdgc==kPdgPi0) frac_abs *= fNeutralPionFracAbsScale; + frac_piprod *= fPionFracPiProdScale; + + + // Flag to enable or disable π0/π+ ratio corrections + bool apply_pi0_ratio_correction = true; + + if (apply_pi0_ratio_correction && pdgc == kPdgPi0) { + + // Cap the kinetic energy at 1000 MeV for the correction calculation + // decision made by Steve Dytman and Hugh Gallagher (2006) as best for MINOS. Looks OK for DUNE in 1st simulations. + // This is reasonable because cross ections for KE above 1 GeV tend to be constand. + double ke_ratio = (ke > 1000.0) ? 1000.0 : ke; + + // Define correction scale factors as a function of kinetic energy (in MeV) to match reslts of hN sim. MI Nov, 2025. + double ratio_cex = 0.0008702 * ke_ratio + 1.9047; + double ratio_abs = 0.0003291 * ke_ratio + 0.82617; + double ratio_inel = -0.0003209 * ke_ratio + 0.837764; + double ratio_piprod = 0.0004402 * ke_ratio + 0.47418; + + // Apply the corrections only if kinetic energy is below 1000 MeV + + frac_cex *= ratio_cex; + frac_abs *= ratio_abs; + frac_inel *= ratio_inel; + + // Apply piprod correction only if KE is above 400 MeV + if (ke > 400.0) { + frac_piprod *= ratio_piprod; + } + + } + + + + + double frac_rescale = 1./(frac_cex + frac_inel + frac_abs + frac_piprod); + + frac_cex *= frac_rescale; + frac_inel *= frac_rescale; + frac_abs *= frac_rescale; + frac_piprod *= frac_rescale; + + + // compute total fraction (can be <1 if fates have been switched off) + double tf = frac_cex + + // frac_elas + + frac_inel + + frac_abs + + frac_piprod; + + double r = tf * rnd->RndFsi().Rndm(); +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HAIntranuke2025", pDEBUG) << "r = " << r << " (max = " << tf << ")"; +#endif + double cf=0; // current fraction + if(r < (cf += frac_cex )) return kIHAFtCEx; // cex + // if(r < (cf += frac_elas )) return kIHAFtElas; // elas + if(r < (cf += frac_inel )) return kIHAFtInelas; // inelas + if(r < (cf += frac_abs )) return kIHAFtAbs; // abs + if(r < (cf += frac_piprod )) return kIHAFtPiProd; // pi prod + + LOG("HAIntranuke2025", pWARN) + << "No selection after going through all fates! " + << "Total fraction = " << tf << " (r = " << r << ")"; + } + + // handle nucleons + else if (pdgc==kPdgProton || pdgc==kPdgNeutron) { + double frac_cex = fHadroData2025->FracAIndep(pdgc, kIHAFtCEx, ke); + //double frac_elas = fHadroData2025->FracAIndep(pdgc, kIHAFtElas, ke); + double frac_inel = fHadroData2025->FracAIndep(pdgc, kIHAFtInelas, ke); + double frac_abs = fHadroData2025->FracAIndep(pdgc, kIHAFtAbs, ke); + double frac_pipro = fHadroData2025->FracAIndep(pdgc, kIHAFtPiProd, ke); + double frac_cmp = fHadroData2025->FracAIndep(pdgc, kIHAFtCmp , ke); + + LOG("HAIntranuke2025", pINFO) + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtCEx) << "} = " << frac_cex + // << "\n frac{" << INukeHadroFates::AsString(kIHAFtElas) << "} = " << frac_elas + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtInelas) << "} = " << frac_inel + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtAbs) << "} = " << frac_abs + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtPiProd) << "} = " << frac_pipro + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtCmp) << "} = " << frac_cmp; //suarez edit, cmp + + // apply external tweaks to fractions + frac_cex *= fNucleonFracCExScale; + frac_inel *= fNucleonFracInelScale; + frac_abs *= fNucleonFracAbsScale; + frac_pipro *= fNucleonFracPiProdScale; + + double frac_rescale = 1./(frac_cex + frac_inel + frac_abs + frac_pipro); + + frac_cex *= frac_rescale; + frac_inel *= frac_rescale; + frac_abs *= frac_rescale; + frac_pipro *= frac_rescale; + + // compute total fraction (can be <1 if fates have been switched off) + double tf = frac_cex + + //frac_elas + + frac_inel + + frac_abs + + frac_pipro + + frac_cmp; //suarez edit, cmp + + double r = tf * rnd->RndFsi().Rndm(); +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HAIntranuke2025", pDEBUG) << "r = " << r << " (max = " << tf << ")"; +#endif + double cf=0; // current fraction + if(r < (cf += frac_cex )) return kIHAFtCEx; // cex + //if(r < (cf += frac_elas )) return kIHAFtElas; // elas + if(r < (cf += frac_inel )) return kIHAFtInelas; // inelas + if(r < (cf += frac_abs )) return kIHAFtAbs; // abs + if(r < (cf += frac_pipro )) return kIHAFtPiProd; // pi prod + if(r < (cf += frac_cmp )) return kIHAFtCmp; //suarez edit, cmp + + LOG("HAIntranuke2025", pWARN) + << "No selection after going through all fates! " + << "Total fraction = " << tf << " (r = " << r << ")"; + } + // handle kaons SD: only K+, remove K- in following statement + else if (pdgc==kPdgKP) { + double frac_inel = fHadroData2025->FracAIndep(pdgc, kIHAFtInelas, ke); + double frac_abs = fHadroData2025->FracAIndep(pdgc, kIHAFtAbs, ke); + + LOG("HAIntranuke2025", pDEBUG) + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtInelas) << "} = " << frac_inel + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtAbs) << "} = " << frac_abs; + // compute total fraction (can be <1 if fates have been switched off) + double tf = frac_inel + + frac_abs; + double r = tf * rnd->RndFsi().Rndm(); +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HAIntranuke2025", pDEBUG) << "r = " << r << " (max = " << tf << ")"; +#endif + double cf=0; // current fraction + if(r < (cf += frac_inel )) return kIHAFtInelas; // inelas + if(r < (cf += frac_abs )) return kIHAFtAbs; // abs + } + }//iterations + + return kIHAFtUndefined; +} +//___________________________________________________________________________ +double HAIntranuke2025::PiBounce(void) const +{ +// [adapted from neugen3 intranuke_bounce.F] +// [is a fortran stub / difficult to understand - needs to be improved] +// +// Generates theta in radians for elastic pion-nucleus scattering/ +// Lookup table is based on Fig 17 of Freedman, Miller and Henley, Nucl.Phys. +// A389, 457 (1982) +// + const int nprob = 25; + double dintor = 0.0174533; + double denom = 47979.453; + double rprob[nprob] = { + 5000., 4200., 3000., 2600., 2100., 1800., 1200., 750., 500., 230., 120., + 35., 9., 3., 11., 18., 29., 27., 20., 14., 10., 6., 2., 0.14, 0.19 }; + + double angles[nprob]; + for(int i=0; iRndFsi().Rndm(); + + double xsum = 0.; + double theta = 0.; + double binl = 0.; + double binh = 0.; + int tj = 0; + for(int i=0; i<60; i++) { + theta = i+0.5; + for(int j=0; j < nprob-1; j++) { + binl = angles[j]; + binh = angles[j+1]; + tj=j; + if(binl<=theta && binh>=theta) break; + tj=0; + }//j + int itj = tj; + double tfract = (theta-binl)/2.5; + double delp = rprob[itj+1] - rprob[itj]; + xsum += (rprob[itj] + tfract*delp)/denom; + if(xsum>r) break; + theta = 0.; + }//i + + theta *= dintor; + + LOG("HAIntranuke2025", pNOTICE) + << "Generated pi+A elastic scattering angle = " << theta << " radians"; + + return theta; +} +//___________________________________________________________________________ +double HAIntranuke2025::PnBounce(void) const +{ +// [adapted from neugen3 intranuke_pnbounce.F] +// [is a fortran stub / difficult to understand - needs to be improved] +// +// Generates theta in radians for elastic nucleon-nucleus scattering. +// Use 800 MeV p+O16 as template in same (highly simplified) spirit as pi+A +// from table in Adams et al., PRL 1979. Guess value at 0-2 deg based on Ni +// data. +// + const int nprob = 20; + double dintor = 0.0174533; + double denom = 11967.0; + double rprob[nprob] = { + 2400., 2350., 2200., 2000., 1728., 1261., 713., 312., 106., 35., + 6., 5., 10., 12., 11., 9., 6., 1., 1., 1. }; + + double angles[nprob]; + for(int i=0; iRndFsi().Rndm(); + + double xsum = 0.; + double theta = 0.; + double binl = 0.; + double binh = 0.; + int tj = 0; + for(int i=0; i< nprob; i++) { + theta = i+0.5; + for(int j=0; j < nprob-1; j++) { + binl = angles[j]; + binh = angles[j+1]; + tj=j; + if(binl<=theta && binh>=theta) break; + tj=0; + }//j + int itj = tj; + double tfract = (theta-binl)/2.5; + double delp = rprob[itj+1] - rprob[itj]; + xsum += (rprob[itj] + tfract*delp)/denom; + if(xsum>r) break; + theta = 0.; + }//i + + theta *= dintor; + + LOG("HAIntranuke2025", pNOTICE) + << "Generated N+A elastic scattering angle = " << theta << " radians"; + + return theta; +} +//___________________________________________________________________________ +void HAIntranuke2025::ElasHA(GHepRecord* ev, GHepParticle* p, + INukeFateHA_t fate ) const +{ + // scatters particle within nucleus, copy of hN code meant to run only once + // in hA mode + + LOG("HAIntranuke2025", pDEBUG) + << "ElasHA() is invoked for a : " << p->Name() + << " whose fate is : " << INukeHadroFates2025::AsString(fate); + + /* if(fate!=kIHAFtElas) + { + LOG("HAIntranuke2025", pWARN) + << "ElasHA() cannot handle fate: " << INukeHadroFates::AsString(fate); + return; + } */ + + // check remnants + if(fRemnA<0 || fRemnZ<0) // best to stop it here and not try again. + { + LOG("HAIntranuke2025", pWARN) << "Invalid Nucleus! : (A,Z) = ("<SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + + // vars for incoming particle, target, and scattered pdg codes + int pcode = p->Pdg(); + double Mp = p->Mass(); + double Mt = 0.; + if (ev->TargetNucleus()->A()==fRemnA) + { Mt = PDGLibrary::Instance()->Find(ev->TargetNucleus()->Pdg())->Mass(); } + else + { + Mt = fRemnP4.M(); + } + TLorentzVector t4PpL = *p->P4(); + TLorentzVector t4PtL = fRemnP4; + double C3CM = 0.0; + + // calculate scattering angle + if(pcode==kPdgNeutron||pcode==kPdgProton) C3CM = TMath::Cos(this->PnBounce()); + else C3CM = TMath::Cos(this->PiBounce()); + + // calculate final 4 momentum of probe + TLorentzVector t4P3L, t4P4L; + + if (!utils::intranuke2025::TwoBodyKinematics(Mp,Mt,t4PpL,t4PtL,t4P3L,t4P4L,C3CM,fRemnP4)) + { + LOG("HAIntranuke2025", pNOTICE) << "ElasHA() failed"; + exceptions::INukeException exception; + exception.SetReason("TwoBodyKinematics failed in ElasHA"); + throw exception; + } + + // Update probe particle + p->SetMomentum(t4P3L); + p->SetStatus(kIStStableFinalState); + + // Update Remnant nucleus + fRemnP4 = t4P4L; + LOG("HAIntranuke2025",pINFO) + << "C3cm = " << C3CM; + LOG("HAIntranuke2025",pINFO) + << "|p3| = " << t4P3L.Vect().Mag() << ", E3 = " << t4P3L.E() << ",Mp = " << Mp; + LOG("HAIntranuke2025",pINFO) + << "|p4| = " << fRemnP4.Vect().Mag() << ", E4 = " << fRemnP4.E() << ",Mt = " << Mt; + + ev->AddParticle(*p); + +} +//___________________________________________________________________________ +void HAIntranuke2025::InelasticHA( + GHepRecord* ev, GHepParticle* p, INukeFateHA_t fate) const +{ + // charge exch and inelastic - scatters particle within nucleus, hA version + // each are treated as quasielastic, particle scatters off single nucleon + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HAIntranuke2025", pDEBUG) + << "InelasticHA() is invoked for a : " << p->Name() + << " whose fate is : " << INukeHadroFates2025::AsString(fate); +#endif + if(ev->Probe() ) { + LOG("HAIntranuke2025", pINFO) << " probe KE = " << ev->Probe()->KinE(); + } + if(fate!=kIHAFtCEx && fate!=kIHAFtInelas) + { + LOG("HAIntranuke2025", pWARN) + << "InelasticHA() cannot handle fate: " << INukeHadroFates2025::AsString(fate); + return; + } + + // Random number generator + RandomGen * rnd = RandomGen::Instance(); + + // vars for incoming particle, target, and scattered pdg codes + int pcode = p->Pdg(); + int tcode, scode, s2code; + double ppcnt = (double) fRemnZ / (double) fRemnA; // % of protons + + // Select a hadron fate in HN mode + INukeFateHN_t h_fate; + if (fate == kIHAFtCEx) h_fate = kIHNFtCEx; + else h_fate = kIHNFtElas; + + // Select a target randomly, weighted to # + // -- Unless, of course, the fate is CEx, + // -- in which case the target may be deterministic + // Also assign scattered particle code + if(fate==kIHAFtCEx) + { + if(pcode==kPdgPiP) {tcode = kPdgNeutron; scode = kPdgPi0; s2code = kPdgProton;} + else if(pcode==kPdgPiM) {tcode = kPdgProton; scode = kPdgPi0; s2code = kPdgNeutron;} + else if(pcode==kPdgPi0) + { + // for pi0 + tcode = (rnd->RndFsi().Rndm()<=ppcnt)?(kPdgProton) :(kPdgNeutron); + scode = (tcode == kPdgProton) ?(kPdgPiP) :(kPdgPiM); + s2code = (tcode == kPdgProton) ?(kPdgNeutron):(kPdgProton); + } + else if(pcode==kPdgProton) {tcode = kPdgNeutron; scode = kPdgNeutron; s2code = kPdgProton;} + else if(pcode==kPdgNeutron){tcode = kPdgProton; scode = kPdgProton; s2code = kPdgNeutron;} + else + { LOG("HAIntranuke2025", pWARN) << "InelasticHA() cannot handle fate: " + << INukeHadroFates2025::AsString(fate) + << " for particle " << p->Name(); + return; + } + } + else + { + tcode = (rnd->RndFsi().Rndm()<=ppcnt)?(kPdgProton):(kPdgNeutron); + // if(pcode == kPdgKP) tcode = kPdgProton; + scode = pcode; + s2code = tcode; + } + + // check remnants + if ( fRemnA < 1 ) //we've blown nucleus apart, no need to retry anything - exit + { + LOG("HAIntranuke2025",pNOTICE) << "InelasticHA() stops : not enough nucleons"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + else if ( fRemnZ + (((pcode==kPdgProton)||(pcode==kPdgPiP))?1:0) - (pcode==kPdgPiM?1:0) + < ((( scode==kPdgProton)||( scode==kPdgPiP)) ?1:0) - (scode ==kPdgPiM ?1:0) + + (((s2code==kPdgProton)||(s2code==kPdgPiP)) ?1:0) - (s2code==kPdgPiM ?1:0) ) + { + LOG("HAIntranuke2025",pWARN) << "InelasticHA() failed : too few protons in nucleus"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; // another extreme case, best strategy is to exit and go to next event + } + + GHepParticle t(*p); + t.SetPdgCode(tcode); + + // set up fermi target + Target target(ev->TargetNucleus()->Pdg()); + double tM = t.Mass(); + + // handle fermi momentum + if(fDoFermi) + { + target.SetHitNucPdg(tcode); + fNuclmodel->GenerateNucleon(target); + TVector3 tP3 = fFermiFac * fNuclmodel->Momentum3(); + double tE = TMath::Sqrt(tP3.Mag2()+ tM*tM); + t.SetMomentum(TLorentzVector(tP3,tE)); + } + else + { + t.SetMomentum(0,0,0,tM); + } + + GHepParticle * cl = new GHepParticle(*p); // clone particle, to run IntBounce at proper energy + // calculate energy and momentum using invariant mass + double pM = p->Mass(); + double E_p = ((*p->P4() + *t.P4()).Mag2() - tM*tM - pM*pM)/(2.0*tM); + double P_p = TMath::Sqrt(E_p*E_p - pM*pM); + cl->SetMomentum(TLorentzVector(P_p,0,0,E_p)); + // momentum doesn't have to be in right direction, only magnitude + double C3CM = fHadroData2025->IntBounce(cl,tcode,scode,h_fate); + delete cl; + if (C3CM<-1.) // hope this doesn't occur too often - unphysical but we just pass it on + { + LOG("HAIntranuke2025", pWARN) << "unphysical angle chosen in InelasicHA - put particle outside nucleus"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + double KE1L = p->KinE(); + double KE2L = t.KinE(); + LOG("HAIntranuke2025",pINFO) + << " KE1L = " << KE1L << " " << KE1L << " KE2L = " << KE2L; + GHepParticle cl1(*p); + GHepParticle cl2(t); + bool success = utils::intranuke2025::TwoBodyCollision(ev,pcode,tcode,scode,s2code,C3CM, + &cl1,&cl2,fRemnA,fRemnZ,fRemnP4,kIMdHA); + if(success) + { + double P3L = TMath::Sqrt(cl1.Px()*cl1.Px() + cl1.Py()*cl1.Py() + cl1.Pz()*cl1.Pz()); + double P4L = TMath::Sqrt(cl2.Px()*cl2.Px() + cl2.Py()*cl2.Py() + cl2.Pz()*cl2.Pz()); + double E3L = cl1.KinE(); + double E4L = cl2.KinE(); + LOG ("HAIntranuke2025",pINFO) << "Successful quasielastic scattering or charge exchange"; + LOG("HAIntranuke",pINFO) + << "C3CM = " << C3CM << "\n P3L, E3L = " + << P3L << " " << E3L << " P4L, E4L = "<< P4L << " " << E4L ; + if(ev->Probe() ) { LOG("HAIntranuke",pINFO) + << "P4L = " << P4L << " ;E4L= " << E4L << "\n probe KE = " << ev->Probe()->KinE() << "\n"; + LOG("HAIntranuke2025", pINFO) << "Nucleus : (A,Z) = ("<Find(ipdgc); + if(!remn) + { + LOG("HAIntranuke2025", pINFO) + << "NO Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + else + { + MassRem = remn->Mass(); + LOG("HAIntranuke2025", pINFO) + << "Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + double ERemn = fRemnP4.E(); + double PRemn = TMath::Sqrt(fRemnP4.Px()*fRemnP4.Px() + fRemnP4.Py()*fRemnP4.Py() + fRemnP4.Pz()*fRemnP4.Pz()); + double MRemn = TMath::Sqrt(ERemn*ERemn - PRemn*PRemn); + LOG("HAIntranuke2025",pINFO) << "PRemn = " << PRemn << " ;ERemn= " << ERemn; + LOG("HAIntranuke2025",pINFO) << "MRemn= " << MRemn << " ;true Mass= " << MassRem << " ; excitation energy= " << (MRemn-MassRem)*1000. << " MeV"; + } + if (ev->Probe() && (E3L>ev->Probe()->KinE())) //assuming E3 is most important, definitely for pion. what about pp? + { + // LOG("HAIntranuke",pINFO) + // << "E3Lagain = " << E3L << " ;E4L= " << E4L << "\n probe KE = " << ev->Probe()->KinE() << "\n"; + exceptions::INukeException exception; + exception.SetReason("TwoBodyCollison gives KE> probe KE in hA simulation"); + throw exception; + } + ev->AddParticle(cl1); + ev->AddParticle(cl2); + + LOG("HAIntranuke2025", pDEBUG) << "Nucleus : (A,Z) = ("< Reaction approximated by exponential decay in p+n (sum) space, + // gaussian in p-n (difference) space + // -fit to hN simulations p C, Fe, Pb at 200, 800 MeV + // -get n from isospin, np-nn smaller by 2 + // Pions -> Reaction approximated with a modified gaussian in p+n space, + // normal gaussian in p-n space + // -based on fits to multiplicity distributions of hN model + // for pi+ C, Fe, Pb at 250, 500 MeV + // -fit sum and diff of nn, np to Gaussian + // -get pi0 from isospin, np-nn smaller by 2 + // -get pi- from isospin, np-nn smaller by 4 + // -add 2-body absorption to better match McKeown data + // Kaons -> no guidance, use same code as pions. + // + // Normally distributed random number generated using Box-Muller transformation + // + // Pion production reactions rescatter pions in nucleus, otherwise unchanged from + // older versions of GENIE + // + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HAIntranuke2025", pDEBUG) + << "Inelastic() is invoked for a : " << p->Name() + << " whose fate is : " << INukeHadroFates2025::AsString(fate); +#endif + + bool allow_dup = true; + PDGCodeList list(allow_dup); // list of final state particles + + // only absorption/pipro fates allowed + if (fate == kIHAFtPiProd) { + + GHepParticle s1(*p); + GHepParticle s2(*p); + GHepParticle s3(*p); + + bool success = utils::intranuke2025::PionProduction( + ev,p,&s1,&s2,&s3,fRemnA,fRemnZ,fRemnP4, fDoFermi,fFermiFac,fFermiMomentum,fNuclmodel); + + if (success){ + LOG ("HAIntranuke2025",pINFO) << " successful pion production fate"; + // set status of particles and conserve charge/baryon number + s1.SetStatus(kIStStableFinalState); //should be redundant + // if (pdg::IsPion(s2->Pdg())) s2->SetStatus(kIStHadronInTheNucleus); + s2.SetStatus(kIStStableFinalState); + // if (pdg::IsPion(s3->Pdg())) s3->SetStatus(kIStHadronInTheNucleus); + s3.SetStatus(kIStStableFinalState); + + ev->AddParticle(s1); + ev->AddParticle(s2); + ev->AddParticle(s3); + + return; + } + else { + LOG("HAIntranuke2025", pNOTICE) << "Error: could not create pion production final state"; + exceptions::INukeException exception; + exception.SetReason("PionProduction kinematics failed - retry kinematics"); + throw exception; + } + } + + else if (fate==kIHAFtAbs) +// tuned for pions - mixture of 2-body and many-body +// use same for kaons as there is no guidance + { + // Instances for reference + PDGLibrary * pLib = PDGLibrary::Instance(); + RandomGen * rnd = RandomGen::Instance(); + + double ke = p->KinE() / units::MeV; + int pdgc = p->Pdg(); + + if (fRemnA<2) + { + LOG("HAIntranuke2025", pNOTICE) << "stop propagation - could not create absorption final state: too few particles"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + if (fRemnZ<1 && (pdgc==kPdgPiM || pdgc==kPdgKM)) + { + LOG("HAIntranuke2025", pNOTICE) << "stop propagation - could not create absorption final state: Pi- or K- cannot be absorbed by only neutrons"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + if (fRemnA-fRemnZ<1 && (pdgc==kPdgPiP || pdgc==kPdgKP)) + { + LOG("HAIntranuke2025", pINFO) << "stop propagation - could not create absorption final state: Pi+ or K+ cannot be absorbed by only protons"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + + // for now, empirical split between multi-nucleon absorption and pi d -> N N + // + // added 03/21/11 - Aaron Meyer + // + if (pdg::IsPion(pdgc) && rnd->RndFsi().Rndm()<1.14*(.903-0.00189*fRemnA)*(1.35-0.00467*ke)) + { // pi d -> N N, probability determined empirically with McKeown et al (Phys Rev C24, 211 (1984)) data + // parameters have energy and angle dependence for proton prouction for pi+ and pi- + + INukeFateHN_t fate_hN=kIHNFtAbs; + int t1code,t2code,scode,s2code; + double ppcnt = (double) fRemnZ / (double) fRemnA; // % of protons + + // choose target nucleon + // -- fates weighted by values from Engels and Mosel Nuclear Physics A572 (1994) 657-681 + if (pdgc==kPdgPiP) { + double Prob_pipd_pp=2.*ppcnt*(1.-ppcnt); + double Prob_pipnn_pn=.083*(1.-ppcnt)*(1.-ppcnt); + if (rnd->RndFsi().Rndm()*(Prob_pipd_pp+Prob_pipnn_pn)RndFsi().Rndm()*(Prob_pimd_nn+Prob_pimpp_pn)RndFsi().Rndm(); + if (random_number*(Prob_pi0d_pn+Prob_pi0pp_pp+Prob_pi0nn_nn)Find(pdgc) ->Mass(); + double M2_1 = pLib->Find(t1code)->Mass(); + double M2_2 = pLib->Find(t2code)->Mass(); + //double M2 = M2_1 + M2_2; + double M3 = pLib->Find(scode) ->Mass(); + double M4 = pLib->Find(s2code)->Mass(); + + // handle fermi momentum + double E2_1L, E2_2L; + TVector3 tP2_1L, tP2_2L; + //TLorentzVector dNucl_P4; + Target target(ev->TargetNucleus()->Pdg()); + if(fDoFermi) + { + target.SetHitNucPdg(t1code); + fNuclmodel->GenerateNucleon(target); + //LOG("HAIntranuke2025", pNOTICE) << "Nuclmodel= " << fNuclmodel->ModelType(target) ; + tP2_1L=fFermiFac * fNuclmodel->Momentum3(); + E2_1L = TMath::Sqrt(tP2_1L.Mag2() + M2_1*M2_1); + + target.SetHitNucPdg(t2code); + fNuclmodel->GenerateNucleon(target); + tP2_2L=fFermiFac * fNuclmodel->Momentum3(); + E2_2L = TMath::Sqrt(tP2_2L.Mag2() + M2_2*M2_2); + + //dNucl_P4=TLorentzVector(tP2_1L+tP2_2L,E2_1L+E2_2L); + } + else + { + tP2_1L.SetXYZ(0.0, 0.0, 0.0); + E2_1L = M2_1; + + tP2_2L.SetXYZ(0.0, 0.0, 0.0); + E2_2L = M2_2; + } + TLorentzVector dNucl_P4=TLorentzVector(tP2_1L+tP2_2L,E2_1L+E2_2L); + + double E2L = E2_1L + E2_2L; + + // adjust p to reflect scattering + // get random scattering angle + double C3CM = fHadroData2025->IntBounce(p,t1code,scode,fate_hN); + if (C3CM<-1.) + { + LOG("HAIntranuke2025", pWARN) << "Inelastic() failed: IntBounce returned bad angle - try again"; + exceptions::INukeException exception; + exception.SetReason("unphysical angle for hN scattering"); + throw exception; + return; + } + + TLorentzVector t4P1L,t4P2L,t4P3L,t4P4L; + t4P1L=*p->P4(); + t4P2L=TLorentzVector(TVector3(tP2_1L+tP2_2L),E2L); + double bindE=0.050; // set to fit McKeown data, updated aug 18 + //double bindE=0.0; + if (utils::intranuke2025::TwoBodyKinematics(M3,M4,t4P1L,t4P2L,t4P3L,t4P4L,C3CM,fRemnP4,bindE)) + { + //construct remnant nucleus and its mass + + if (pdgc==kPdgPiP || pdgc==kPdgKP) fRemnZ++; + if (pdgc==kPdgPiM) fRemnZ--; //sd: remove K-, only K+ at present + if (t1code==kPdgProton) fRemnZ--; + if (t2code==kPdgProton) fRemnZ--; + fRemnA-=2; + + fRemnP4-=dNucl_P4; + + TParticlePDG * remn = 0; + double MassRem = 0.; + int ipdgc = pdg::IonPdgCode(fRemnA, fRemnZ); + remn = PDGLibrary::Instance()->Find(ipdgc); + if(!remn) + { + LOG("HAIntranuke2025", pINFO) + << "NO Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + else + { + MassRem = remn->Mass(); + LOG("HAIntranuke2025", pINFO) + << "Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + double ERemn = fRemnP4.E(); + double PRemn = TMath::Sqrt(fRemnP4.Px()*fRemnP4.Px() + fRemnP4.Py()*fRemnP4.Py() + fRemnP4.Pz()*fRemnP4.Pz()); + double MRemn = TMath::Sqrt(ERemn*ERemn - PRemn*PRemn); + LOG("HAIntranuke2025",pINFO) << "PRemn = " << PRemn << " ;ERemn= " << ERemn; + LOG("HAIntranuke2025",pINFO) << "expt MRemn= " << MRemn << " ;true Mass= " << MassRem << " ; excitation energy (>0 good)= " << (MRemn-MassRem)*1000. << " MeV"; + + // create t particles w/ appropriate momenta, code, and status + // Set target's mom to be the mom of the hadron that was cloned + GHepParticle* t1 = new GHepParticle(*p); + GHepParticle* t2 = new GHepParticle(*p); + t1->SetFirstMother(p->FirstMother()); + t1->SetLastMother(p->LastMother()); + t2->SetFirstMother(p->FirstMother()); + t2->SetLastMother(p->LastMother()); + + // adjust p to reflect scattering + t1->SetPdgCode(scode); + t1->SetMomentum(t4P3L); + + t2->SetPdgCode(s2code); + t2->SetMomentum(t4P4L); + + t1->SetStatus(kIStStableFinalState); + t2->SetStatus(kIStStableFinalState); + + ev->AddParticle(*t1); + ev->AddParticle(*t2); + delete t1; + delete t2; + + return; + } + else + { + LOG("HAIntranuke2025", pNOTICE) << "Inelastic in hA failed calling TwoBodyKineamtics"; + exceptions::INukeException exception; + exception.SetReason("Pion absorption kinematics through TwoBodyKinematics failed"); + throw exception; + + } + + } // end pi d -> N N + else // multi-nucleon + { + + // declare some parameters for double gaussian and determine values chosen + // parameters for proton and pi+, others come from isospin transformations + // work done in 2011 by Steve Dytman and Aaron Meyer. Fit Gaussians to hN pi abs simulations + // for sum and difference of n, p multiplicity. Parameters have energy, A, and Z dependence. + + double ns0=0; // mean - sum of nucleons + double nd0=0; // mean - difference of nucleons + double Sig_ns=0; // std dev - sum + double Sig_nd=0; // std dev - diff + double gam_ns=0; // exponential decay rate (for nucleons) + + if ( pdg::IsNeutronOrProton (pdgc) ) // nucleon probe + { + // antisymmetric about Z=N + if (fRemnA-fRemnZ > fRemnZ) + nd0 = 135.227 * TMath::Exp(-7.124*(fRemnA-fRemnZ)/double(fRemnA)) - 2.762; + else + nd0 = -135.227 * TMath::Exp(-7.124* fRemnZ /double(fRemnA)) + 4.914; + + Sig_nd = 2.034 + fRemnA * 0.007846; + + double c1 = 0.041 + ke * 0.0001525; + double c2 = -0.003444 - ke * 0.00002324; +//change last factor from 30 to 15 so that gam_ns always larger than 0 +//add check to be certain + double c3 = 0.064 - ke * 0.000015; + gam_ns = c1 * TMath::Exp(c2*fRemnA) + c3; + if(gam_ns<0.002) gam_ns = 0.002; + //gam_ns = 10.; + LOG("HAIntranuke2025", pINFO) << "nucleon absorption"; + LOG("HAIntranuke2025", pINFO) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd; + // LOG("HAIntranuke2025", pINFO) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns; + LOG("HAIntranuke2025", pINFO) << "--> gam_ns = " << gam_ns; + } + else if ( pdgc==kPdgPiP || pdgc==kPdgPi0 || pdgc==kPdgPiM) //pion probe + { + ns0 = .0001*(1.+ke/250.) * (fRemnA-10)*(fRemnA-10) + 3.5; + nd0 = (1.+ke/250.) - ((fRemnA/200.)*(1. + 2.*ke/250.)); + Sig_ns = (10. + 4. * ke/250.)*TMath::Power(fRemnA/250.,0.9); //(1. - TMath::Exp(-0.02*fRemnA)); + Sig_nd = 4*(1 - TMath::Exp(-0.03*ke)); + LOG("HAIntranuke2025", pINFO) << "pion absorption"; + LOG("HAIntranuke2025", pINFO) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd; + LOG("HAIntranuke2025", pINFO) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns; + } + else if (pdgc==kPdgKP) // kaon probe, only K+ at present + { + ns0 = (rnd->RndFsi().Rndm()>0.5?3:2); + nd0 = 1.; + Sig_ns = 0.1; + Sig_nd = 0.1; + LOG("HAIntranuke2025", pINFO) << "kaon absorption - set ns, nd later"; + // LOG("HAIntranuke2025", pINFO) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd; + // LOG("HAIntranuke2025", pINFO) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns; + } + else + { + LOG("HAIntranuke2025", pWARN) << "Inelastic() cannot handle absorption reaction for " << p->Name(); + } + + // account for different isospin + if (pdgc==kPdgPi0 || pdgc==kPdgNeutron) nd0-=2.; + if (pdgc==kPdgPiM) nd0-=4.; + + int iter=0; // counter + int np=0,nn=0; // # of p, # of n + bool not_done=true; + double u1 = 0, u2 = 0; + + while (not_done) + { + // infinite loop check + if (iter>=100) { + LOG("HAIntranuke2025", pNOTICE) << "Error: could not choose absorption final state"; + LOG("HAIntranuke2025", pNOTICE) << "--> mean diff distr = " << nd0 << ", stand dev = " << Sig_nd; + LOG("HAIntranuke2025", pNOTICE) << "--> mean sum distr = " << ns0 << ", Stand dev = " << Sig_ns; + LOG("HAIntranuke2025", pNOTICE) << "--> gam_ns = " << gam_ns; + LOG("HAIntranuke2025", pNOTICE) << "--> A = " << fRemnA << ", Z = " << fRemnZ << ", Energy = " << ke; + exceptions::INukeException exception; + exception.SetReason("Absorption choice of # of p,n failed"); + throw exception; + } + //here?? + + // Box-Muller transform + // Takes two uniform distribution random variables on (0,1] + // Creates two normally distributed random variables on (0,inf) + + u1 = rnd->RndFsi().Rndm(); // uniform random variable 1 + u2 = rnd->RndFsi().Rndm(); // " " 2 + if (u1==0) u1 = rnd->RndFsi().Rndm(); + if (u2==0) u2 = rnd->RndFsi().Rndm(); // Just in case + + // normally distributed random variable + double x2 = TMath::Sqrt(-2*TMath::Log(u1))*TMath::Sin(2*kPi*u2); + + double ns = 0; + + if ( pdg::IsNeutronOrProton (pdgc) ) //nucleon probe + { + // work done in 2011 by Meyer and Dytman. Make fits to hN simulation output for p and n. + ns = -TMath::Log(rnd->RndFsi().Rndm())/gam_ns; // exponential random variable + } + if ( pdg::IsKaon (pdgc) ) //charged kaon probe - either 2 or 3 nucleons to stay simple. + // No data available, use hN simulation (sd) + { + ns = (rnd->RndFsi().Rndm()<0.5?2:3); + } + else if ( pdgc==kPdgPiP || pdgc==kPdgPi0 || pdgc==kPdgPiM) //pion probe + { + // Pion fit for sum takes for xs*exp((xs-x0)^2 / 2*sig_xs0) + // Find random variable by first finding gaussian random variable + // then throwing the value against a linear P.D.F. + // + // max is the maximum value allowed for the random variable (10 std + mean) + // minimum allowed value is 0 + + double max = ns0 + Sig_ns * 10; + if(max>fRemnA) max=fRemnA; + double x1 = 0; + bool not_found = true; + int iter2 = 0; + + while (not_found) + { + // infinite loop check + if (iter2>=100) + { + LOG("HAIntranuke2025", pNOTICE) << "Error: stuck in random variable loop for ns"; + LOG("HAIntranuke2025", pNOTICE) << "--> mean of sum parent distr = " << ns0 << ", Stand dev = " << Sig_ns; + LOG("HAIntranuke2025", pNOTICE) << "--> A = " << fRemnA << ", Z = " << fRemnZ << ", Energy = " << ke; + + exceptions::INukeException exception; + exception.SetReason("Random number generator for choice of #p,n final state failed - unusual - redo kinematics"); + throw exception; + } + + // calculate exponential random variable + u1 = rnd->RndFsi().Rndm(); + u2 = rnd->RndFsi().Rndm(); + if (u1==0) u1 = rnd->RndFsi().Rndm(); + if (u2==0) u2 = rnd->RndFsi().Rndm(); + x1 = TMath::Sqrt(-2*TMath::Log(u1))*TMath::Cos(2*kPi*u2); + + ns = ns0 + Sig_ns * x1; + if ( ns>max || ns<0 ) {iter2++; continue;} + else if ( rnd->RndFsi().Rndm() > (ns/max) ) {iter2++; continue;} + else { + // accept this sum value + not_found=false; + } + } //while(not_found) + }//else pion + + double nd = nd0 + Sig_nd * x2; // difference (p-n) for both pion, nucleon probe + if (pdgc==kPdgKP) // special for KP + { if (ns==2) nd=0; + if (ns>2) nd=1; } + + np = int((ns+nd)/2.+.5); // Addition of .5 for rounding correction + nn = int((ns-nd)/2.+.5); + + LOG("HAIntranuke2025", pINFO) << "ns = "<86) // too many particles, scale down + { + double frac = 85./double(np+nn); + np = int(np*frac); + nn = int(nn*frac); + } + + if ( (np==fRemnZ +((pdg::IsProton (pdgc)||pdgc==kPdgPiP||pdgc==kPdgKP)?1:0)-(pdgc==kPdgPiM?1:0)) + &&(nn==fRemnA-fRemnZ+((pdg::IsNeutron(pdgc)||pdgc==kPdgPiM)?1:0)-(pdgc==kPdgPiP||pdgc==kPdgKP?1:0)) ) + { // leave at least one nucleon in the nucleus to prevent excess momentum + if (rnd->RndFsi().Rndm()18) + { + // code lists + PDGCodeList list0(allow_dup); + PDGCodeList list1(allow_dup); + PDGCodeList list2(allow_dup); + PDGCodeList list3(allow_dup); + PDGCodeList list4(allow_dup); + PDGCodeList* listar[5] = {&list0, &list1, &list2, &list3, &list4}; + + //set up HadronClusters + // simple for now, each (of 5) in hadron cluster has 1/5 of mom and KE + + double probM = pLib->Find(pdgc) ->Mass(); + probM -= .025; // BE correction + TVector3 pP3 = p->P4()->Vect() * (1./5.); + double probKE = p->P4()->E() -probM; + double clusKE = probKE * (1./5.); + TLorentzVector clusP4(pP3,clusKE); //no mass + LOG("HAIntranuke2025",pINFO) << "probM = " << probM << " ;clusKE= " << clusKE; + TLorentzVector X4(*p->X4()); + GHepStatus_t ist = kIStNucleonClusterTarget; + + int mom = p->FirstMother(); + + GHepParticle * p0 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4); + GHepParticle * p1 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4); + GHepParticle * p2 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4); + GHepParticle * p3 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4); + GHepParticle * p4 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4); + + // To conserve 4-momenta + // fRemnP4 -= probP4 + protP4*np_p + neutP4*(4-np_p) - *p->P4(); + fRemnP4 -= 5.*clusP4 - *p->P4(); + + for (int i=0;i<(np+nn);i++) + { + if (ipush_back(kPdgProton); + fRemnZ--; + } + else listar[i%5]->push_back(kPdgNeutron); + fRemnA--; + } + for (int i=0;i<5;i++) + { + LOG("HAIntranuke2025", pINFO) << "List" << i << " size: " << listar[i]->size(); + if (listar[i]->size() <2) + { + exceptions::INukeException exception; + exception.SetReason("too few particles for Phase Space decay - try again"); + throw exception; + } + } + + // commented out to better fit with absorption reactions + // Add the fermi energy of the nucleons to the phase space + /*if(fDoFermi) + { + GHepParticle* p_ar[5] = {cl, p1, p2, p3, p4}; + for (int i=0;i<5;i++) + { + Target target(ev->TargetNucleus()->Pdg()); + TVector3 pBuf = p_ar[i]->P4()->Vect(); + double mBuf = p_ar[i]->Mass(); + double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + TLorentzVector tSum(pBuf,eBuf); + double mSum = 0.0; + vector::const_iterator pdg_iter; + for(pdg_iter=++(listar[i]->begin());pdg_iter!=listar[i]->end();++pdg_iter) + { + target.SetHitNucPdg(*pdg_iter); + fNuclmodel->GenerateNucleon(target); + mBuf = pLib->Find(*pdg_iter)->Mass(); + mSum += mBuf; + pBuf = fFermiFac * fNuclmodel->Momentum3(); + eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + tSum += TLorentzVector(pBuf,eBuf); + fRemnP4 -= TLorentzVector(pBuf,eBuf-mBuf); + } + TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum); + p_ar[i]->SetMomentum(dP4); + } + }*/ + + bool success1 = utils::intranuke2025::PhaseSpaceDecay(ev,p0,*listar[0],fRemnP4,fNucRmvE,kIMdHA); + bool success2 = utils::intranuke2025::PhaseSpaceDecay(ev,p1,*listar[1],fRemnP4,fNucRmvE,kIMdHA); + bool success3 = utils::intranuke2025::PhaseSpaceDecay(ev,p2,*listar[2],fRemnP4,fNucRmvE,kIMdHA); + bool success4 = utils::intranuke2025::PhaseSpaceDecay(ev,p3,*listar[3],fRemnP4,fNucRmvE,kIMdHA); + bool success5 = utils::intranuke2025::PhaseSpaceDecay(ev,p4,*listar[4],fRemnP4,fNucRmvE,kIMdHA); + if(success1 && success2 && success3 && success4 && success5) + { + LOG("HAIntranuke2025", pINFO)<<"Successful many-body absorption - n>=18"; + LOG("HAIntranuke2025", pDEBUG) << "Nucleus : (A,Z) = ("<Find(ipdgc); + if(!remn) + { + LOG("HAIntranuke2025", pINFO) + << "NO Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + else + { + MassRem = remn->Mass(); + LOG("HAIntranuke2025", pINFO) + << "Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + double ERemn = fRemnP4.E(); + double PRemn = TMath::Sqrt(fRemnP4.Px()*fRemnP4.Px() + fRemnP4.Py()*fRemnP4.Py() + fRemnP4.Pz()*fRemnP4.Pz()); + double MRemn = TMath::Sqrt(ERemn*ERemn - PRemn*PRemn); + LOG("HAIntranuke2025",pINFO) << "PRemn = " << PRemn << " ;ERemn= " << ERemn; + LOG("HAIntranuke2025",pINFO) << "MRemn= " << MRemn << " ;true Mass= " << MassRem << " ; excitation energy (>0 good)= " << (MRemn-MassRem)*1000. << " MeV"; + + } + else + { + // try to recover + LOG("HAIntranuke2025", pWARN) << "PhaseSpace decay fails for HadrCluster- recovery likely incorrect - rethrow event"; + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + fRemnA+=np+nn; + fRemnZ+=np; + if ( pdgc==kPdgProton || pdgc==kPdgPiP ) fRemnZ--; + if ( pdgc==kPdgPiM ) fRemnZ++; + if ( pdg::IsNeutronOrProton (pdgc) ) fRemnA--; + /* exceptions::INukeException exception; + exception.SetReason("Phase space generation of absorption final state failed"); + throw exception; + */ + } + + // delete cl; + delete p0; + delete p1; + delete p2; + delete p3; + delete p4; + + } + else // less than 18 particles pion + { + if (pdgc==kPdgKP) list.push_back(kPdgKP); //normally conserve strangeness +// if (pdgc==kPdgKM) list.push_back(kPdgKM); + /* + TParticlePDG * remn0 = 0; + int ipdgc0 = pdg::IonPdgCode(fRemnA, fRemnZ); + remn0 = PDGLibrary::Instance()->Find(ipdgc0); + double Mass0 = remn0->Mass(); + TParticlePDG * remnt = 0; + int ipdgct = pdg::IonPdgCode(fRemnA-(nn+np), fRemnZ-np); + remnt = PDGLibrary::Instance()->Find(ipdgct); + double MassRemt = remnt->Mass(); + LOG("HAIntranuke2025",pINFO) << "Mass0 = " << Mass0 << " ;Masst= " << MassRemt << " ; diff/nucleon= "<< (Mass0-MassRemt)/(np+nn); + */ + //set up HadronCluster + + double probM = pLib->Find(pdgc) ->Mass(); + double probBE = (np+nn)*.005; // BE correction + TVector3 pP3 = p->P4()->Vect(); + double probKE = p->P4()->E() - (probM - probBE); + double clusKE = probKE; // + np*0.9383 + nn*.9396; + TLorentzVector clusP4(pP3,clusKE); //no mass is correct + LOG("HAIntranuke2025",pINFO) << "probM = " << probM << " ;clusKE= " << clusKE; + TLorentzVector X4(*p->X4()); + GHepStatus_t ist = kIStNucleonClusterTarget; + int mom = p->FirstMother(); + + GHepParticle * p0 = new GHepParticle(kPdgCompNuclCluster,ist, mom,-1,-1,-1,clusP4,X4); + + //set up remnant nucleus + fRemnP4 -= clusP4 - *p->P4(); + + for (int i=0;iTargetNucleus()->Pdg()); + TVector3 pBuf = p->P4()->Vect(); + double mBuf = p->Mass(); + double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + TLorentzVector tSum(pBuf,eBuf); + double mSum = 0.0; + vector::const_iterator pdg_iter; + for(pdg_iter=++(list.begin());pdg_iter!=list.end();++pdg_iter) + { + target.SetHitNucPdg(*pdg_iter); + fNuclmodel->GenerateNucleon(target); + mBuf = pLib->Find(*pdg_iter)->Mass(); + mSum += mBuf; + pBuf = fFermiFac * fNuclmodel->Momentum3(); + eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + tSum += TLorentzVector(pBuf,eBuf); + fRemnP4 -= TLorentzVector(pBuf,eBuf-mBuf); + } + TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum); + p->SetMomentum(dP4); + }*/ + + LOG("HAIntranuke2025", pDEBUG) + << "Remnant nucleus (A,Z) = (" << fRemnA << ", " << fRemnZ << ")"; + LOG("HAIntranuke2025", pINFO) << " list size: " << np+nn; + if (np+nn <2) + { + exceptions::INukeException exception; + exception.SetReason("too few particles for Phase Space decay - try again"); + throw exception; + } + // GHepParticle * cl = new GHepParticle(*p); + // cl->SetPdgCode(kPdgDecayNuclCluster); + //bool success1 = utils::intranuke2025::PhaseSpaceDecay(ev,p0,*listar[0],fRemnP4,fNucRmvE,kIMdHA); + bool success = utils::intranuke2025::PhaseSpaceDecay(ev,p0,list,fRemnP4,fNucRmvE,kIMdHA); + if (success) + { + LOG ("HAIntranuke2025",pINFO) << "Successful many-body absorption, n<=18"; + LOG("HAIntranuke2025", pDEBUG) << "Nucleus : (A,Z) = ("<Find(ipdgc); + if(!remn) + { + LOG("HAIntranuke2025", pINFO) + << "NO Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + else + { + MassRem = remn->Mass(); + LOG("HAIntranuke2025", pINFO) + << "Particle with [A = " << fRemnA << ", Z = " << fRemnZ + << ", pdgc = " << ipdgc << "] in PDGLibrary!"; + } + double ERemn = fRemnP4.E(); + double PRemn = TMath::Sqrt(fRemnP4.Px()*fRemnP4.Px() + fRemnP4.Py()*fRemnP4.Py() + fRemnP4.Pz()*fRemnP4.Pz()); + double MRemn = TMath::Sqrt(ERemn*ERemn - PRemn*PRemn); + LOG("HAIntranuke2025",pINFO) << "PRemn = " << PRemn << " ;ERemn= " << ERemn; + LOG("HAIntranuke2025",pINFO) << "expt MRemn= " << MRemn << " ;true Mass= " << MassRem << " ; excitation energy (>0 good)= " << (MRemn-MassRem)*1000. << " MeV"; + } + else { + // recover + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + fRemnA+=np+nn; + fRemnZ+=np; + if ( pdgc==kPdgProton || pdgc==kPdgPiP ) fRemnZ--; + if ( pdgc==kPdgPiM ) fRemnZ++; + if ( pdg::IsNeutronOrProton (pdgc) ) fRemnA--; + exceptions::INukeException exception; + exception.SetReason("Phase space generation of absorption final state failed"); + throw exception; + } + delete p0; + } + } // end multi-nucleon FS + } + else // not absorption/pipro + { + LOG("HAIntranuke2025", pWARN) + << "Inelastic() can not handle fate: " << INukeHadroFates2025::AsString(fate); + return; + } +} +//___________________________________________________________________________ +int HAIntranuke2025::HandleCompoundNucleus(GHepRecord* /*ev*/, GHepParticle* /*p*/, int /*mom*/) const +{ + + // only relevant for hN mode - not anymore. + return false; + +} +//___________________________________________________________________________ +void HAIntranuke2025::LoadConfig(void) +{ + + // load hadronic cross sections + fHadroData2025 = INukeHadroData2025::Instance(); + + // fermi momentum setup + // this is specifically set in Intranuke2025::Configure(string) + fNuclmodel = dynamic_cast( this -> SubAlg("NuclearModel") ) ; + + // other intranuke config params + GetParam( "NUCL-R0", fR0 ); // fm + GetParam( "NUCL-NR", fNR ); + + GetParam( "INUKE-NucRemovalE", fNucRmvE ); // GeV + GetParam( "INUKE-HadStep", fHadStep ) ; + GetParam( "INUKE-NucAbsFac", fNucAbsFac ) ; + GetParam( "INUKE-NucCEXFac", fNucCEXFac ) ; + GetParam( "INUKE-Energy_Pre_Eq", fEPreEq ) ; + GetParam( "INUKE-FermiFac", fFermiFac ) ; + GetParam( "INUKE-FermiMomentum", fFermiMomentum ) ; + + GetParam( "INUKE-DoCompoundNucleus", fDoCompoundNucleus ) ; + GetParam( "INUKE-DoFermi", fDoFermi ) ; + GetParam( "INUKE-XsecNNCorr", fXsecNNCorr ) ; + GetParamDef( "UseOset", fUseOset, false ) ; + GetParamDef( "AltOset", fAltOset, false ) ; + + GetParam( "HAINUKE-DelRPion", fDelRPion ) ; + GetParam( "HAINUKE-DelRNucleon", fDelRNucleon ) ; + + GetParamDef( "FSI-ChargedPion-MFPScale", fChPionMFPScale, 1.0 ) ; + GetParamDef( "FSI-NeutralPion-MFPScale", fNeutralPionMFPScale, 1.0 ) ; + GetParamDef( "FSI-Pion-FracCExScale", fPionFracCExScale, 1.0 ) ; + GetParamDef( "FSI-ChargedPion-FracAbsScale", fChPionFracAbsScale, 1.0 ) ; + GetParamDef( "FSI-NeutralPion-FracAbsScale", fNeutralPionFracAbsScale,1.0 ) ; + GetParamDef( "FSI-Pion-FracInelScale", fPionFracInelScale, 1.0 ) ; + GetParamDef( "FSI-Pion-FracPiProdScale", fPionFracPiProdScale, 1.0 ) ; + GetParamDef( "FSI-Nucleon-MFPScale", fNucleonMFPScale, 1.0 ) ; + GetParamDef( "FSI-Nucleon-FracCExScale", fNucleonFracCExScale , 1.0 ) ; + GetParamDef( "FSI-Nucleon-FracInelScale", fNucleonFracInelScale, 1.0 ) ; + GetParamDef( "FSI-Nucleon-FracAbsScale", fNucleonFracAbsScale, 1.0 ) ; + GetParamDef( "FSI-Nucleon-FracPiProdScale", fNucleonFracPiProdScale, 1.0 ) ; + + // report + LOG("HAIntranuke2025", pINFO) << "Settings for INTRANUKE mode: " << INukeMode::AsString(kIMdHA); + LOG("HAIntranuke2025", pINFO) << "R0 = " << fR0 << " fermi"; + LOG("HAIntranuke2025", pINFO) << "NR = " << fNR; + LOG("HAIntranuke2025", pINFO) << "DelRPion = " << fDelRPion; + LOG("HAIntranuke2025", pINFO) << "DelRNucleon = " << fDelRNucleon; + LOG("HAIntranuke2025", pINFO) << "HadStep = " << fHadStep << " fermi"; + LOG("HAIntranuke2025", pINFO) << "EPreEq = " << fHadStep << " fermi"; + LOG("HAIntranuke2025", pINFO) << "NucAbsFac = " << fNucAbsFac; + LOG("HAIntranuke2025", pINFO) << "NucCEXFac = " << fNucCEXFac; + LOG("HAIntranuke2025", pINFO) << "FermiFac = " << fFermiFac; + LOG("HAIntranuke2025", pINFO) << "FermiMomtm = " << fFermiMomentum; + LOG("HAIntranuke2025", pINFO) << "DoFermi? = " << ((fDoFermi)?(true):(false)); + LOG("HAIntranuke2025", pINFO) << "DoCmpndNuc? = " << ((fDoCompoundNucleus)?(true):(false)); + LOG("HAIntranuke2025", pINFO) << "XsecNNCorr? = " << ((fXsecNNCorr)?(true):(false)); +} +//___________________________________________________________________________ +/* +INukeFateHA_t HAIntranuke2025::HadronFateOset () const +{ + const double fractionAbsorption = osetUtils::currentInstance-> + getAbsorptionFraction(); + const double fractionCex = osetUtils::currentInstance->getCexFraction (); + + RandomGen *randomGenerator = RandomGen::Instance(); + const double randomNumber = randomGenerator->RndFsi().Rndm(); + + LOG("HAIntranuke2025", pINFO) + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtCEx) << "} = " << fractionCex + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtInelas) << "} = " << 1-fractionCex-fractionAbsorption + << "\n frac{" << INukeHadroFates2025::AsString(kIHAFtAbs) << "} = " << fractionAbsorption; + if (randomNumber < fractionAbsorption && fRemnA > 1) return kIHAFtAbs; + else if (randomNumber < fractionAbsorption + fractionCex) return kIHAFtCEx; + else return kIHAFtInelas; +} +*/ diff --git a/src/Physics/HadronTransport/HAIntranuke2025.h b/src/Physics/HadronTransport/HAIntranuke2025.h new file mode 100644 index 0000000000..f8a0c86811 --- /dev/null +++ b/src/Physics/HadronTransport/HAIntranuke2025.h @@ -0,0 +1,91 @@ +//____________________________________________________________________________ +/*! + +\class genie::Intranuke + +\brief The INTRANUKE intranuclear hadron transport MC. + Is a concrete implementation of the EventRecordVisitorI interface. + +\ref R.Merenyi et al., Phys.Rev.D45 (1992) + R.D.Ransome, Nucl.Phys.B 139 (2005) + + Current INTRANUKE development is led by S.Dytman and H.Gallagher. + The original INTRANUKE cascade MC was developed (in fortran) for the + NeuGEN MC by R.Edgecock, G.F.Pearce, W.A.Mann, R.Merenyi and others. + +\author Steve Dytman , Pittsburgh University + Aaron Meyer , Pittsburgh University + Alex Bell, Pittsburgh University + Hugh Gallagher , Tufts University + Costas Andreopoulos STFC, Rutherford Lab + +\created September 20, 2005 + +\cpright Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + +\created on september,2025 by Mohamed Ismail +no changes from the 2018 class version, major changes made in INukeHadroData2025 for new hA pion splines +Add data, use hN for high pion KE, use INCL for low energy. Use splines for channel and total reac xs +to improve accuracy. Also, smooth results to avoid discontinuities. +*/ +//____________________________________________________________________________ + +#ifndef _HA_INTRANUKE_2025_H_ +#define _HA_INTRANUKE_2025_H_ + +#include + +#include "Physics/NuclearState/NuclearModelI.h" +#include "Framework/Algorithm/AlgFactory.h" +#include "Framework/EventGen/EventRecordVisitorI.h" +#include "Physics/HadronTransport/INukeMode.h" +#include "Physics/HadronTransport/INukeHadroFates2025.h" +#include "Physics/HadronTransport/Intranuke2025.h" + +class TLorentzVector; +class TVector3; + +namespace genie { + +class GHepParticle; +class INukeHadroData2025; +class PDGCodeList; + +class HAIntranuke2025 : public Intranuke2025 { + +friend class IntranukeTester; + +public : + HAIntranuke2025(); + HAIntranuke2025(string config); + ~HAIntranuke2025(); + + void ProcessEventRecord(GHepRecord * event_rec) const; + + virtual string GetINukeMode() const {return "hA2025";}; + virtual string GetGenINukeMode() const {return "hA";}; + +private: + + void LoadConfig (void); + + void SimulateHadronicFinalState (GHepRecord* ev, GHepParticle* p) const; + void SimulateHadronicFinalStateKinematics (GHepRecord* ev, GHepParticle* p) const; + + INukeFateHA_t HadronFateHA (const GHepParticle* p) const; + //INukeFateHA_t HadronFateOset (void) const; + void Inelastic (GHepRecord* ev, GHepParticle* p, INukeFateHA_t fate) const; + void ElasHA (GHepRecord* ev, GHepParticle* p, INukeFateHA_t fate) const; + void InelasticHA (GHepRecord* ev, GHepParticle* p, INukeFateHA_t fate) const; + double PiBounce (void) const; + double PnBounce (void) const; + int HandleCompoundNucleus(GHepRecord* ev, GHepParticle* p, int mom) const; + + mutable int nuclA; ///< value of A for the target nucleus in hA mode + mutable unsigned int fNumIterations; +}; + +} // genie namespace + +#endif // _HA_INTRANUKE_2025_H_ diff --git a/src/Physics/HadronTransport/HNIntranuke2025.cxx b/src/Physics/HadronTransport/HNIntranuke2025.cxx new file mode 100644 index 0000000000..b00ffbcc67 --- /dev/null +++ b/src/Physics/HadronTransport/HNIntranuke2025.cxx @@ -0,0 +1,1036 @@ + +//____________________________________________________________________________ +/* + Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + + Author: Steve Dytman , Pittsburgh Univ. + Aaron Meyer , Pittsburgh Univ. + Alex Bell, Pittsburgh Univ. + Hugh Gallagher , Tufts Univ. + Costas Andreopoulos , Rutherford Lab. + September 20, 2005 + + For the class documentation see the corresponding header file. + + Important revisions after version 2.0.0 : + @ Nov 30, 2007 - SD + Changed the hadron tracking algorithm to take into account the radial + nuclear density dependence. Using the somewhat empirical approach of + increasing the nuclear radius by a const (tunable) number times the tracked + particle's de Broglie wavelength as this helps getting the hadron+nucleus + cross sections right. + @ Mar 08, 2008 - CA + Fixed code retrieving the remnant nucleus which stopped working as soon as + simulation of nuclear de-excitation started pushing photons in the target + nucleus daughter list. + @ Jun 20, 2008 - CA + Fix a mem leak: The (clone of the) GHepParticle being re-scattered was not + deleted after it was added at the GHEP event record. + @ Jul 15, 2010 - AM + The hN mode is now implemented in Intranuke. Similar to hA mode, but particles + produced by reactions are stepped through the nucleus like probe particles. + Particles react with nucleons instead of the entire nucleus, and final states + are determined after reactions are finished, not before. + @ Dec 15, 2014 - SD, Nick Geary + Update fates to include Compound Nucleus final state correctly. + @ Jan 9, 2015 - SD, NG, Tomek Golan + Added 2014 version of INTRANUKE codes (new class) for independent development. + @ Oct, 2015 - TG + Added 2015 version of INTRANUKE codes (new class) for independent development. Include Oset model for medium corrections to piA for Tpi<350 MeV. + @ May, 2015 Flor Blaszczyk + K+ are now handled. + @ July, 2016 Nicholas Suarez, Josh Kleckner, SD + fix memory leak, fix fates, improve NNCorr binning + & Mar, 2025 Nicholas Suarez, SD + add compound nucleus option to populate KE<30 MeV + @ Sep, 2025 Mohamed Ismail, SD - hN2025 is born, identical to hN2018 +*/ +//____________________________________________________________________________ + +#include +#include + +#include + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/Algorithm/AlgFactory.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Conventions/Controls.h" +#include "Framework/EventGen/EVGThreadException.h" +#include "Framework/GHEP/GHepFlags.h" +#include "Framework/GHEP/GHepStatus.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Physics/HadronTransport/Intranuke2025.h" +#include "Physics/HadronTransport/HNIntranuke2025.h" +#include "Physics/HadronTransport/INukeException.h" +#include "Physics/HadronTransport/INukeHadroData2025.h" +#include "Physics/HadronTransport/INukeUtils2025.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/Numerical/RandomGen.h" +#include "Framework/Numerical/Spline.h" +#include "Framework/ParticleData/PDGLibrary.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Framework/ParticleData/PDGCodeList.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/Utils/PrintUtils.h" +#include "Physics/NuclearState/NuclearUtils.h" +#include "Physics/HadronTransport/INukeOset.h" + +using std::ostringstream; + +using namespace genie; +using namespace genie::utils; +using namespace genie::utils::intranuke2025; +using namespace genie::constants; +using namespace genie::controls; + +//___________________________________________________________________________ +//___________________________________________________________________________ +// Methods specific to INTRANUKE's HN-mode +//___________________________________________________________________________ +//___________________________________________________________________________ +HNIntranuke2025::HNIntranuke2025() : +Intranuke2025("genie::HNIntranuke2025") +{ + +} +//___________________________________________________________________________ +HNIntranuke2025::HNIntranuke2025(string config) : +Intranuke2025("genie::HNIntranuke2025",config) +{ + +} +//___________________________________________________________________________ +HNIntranuke2025::~HNIntranuke2025() +{ + +} +//___________________________________________________________________________ +void HNIntranuke2025::ProcessEventRecord(GHepRecord * evrec) const +{ + LOG("HNIntranuke2025", pNOTICE) + << "************ Running hN2025 MODE INTRANUKE ************"; + + Intranuke2025::ProcessEventRecord(evrec); + + LOG("HNIntranuke2025", pINFO) << "Done with this event"; +} +//___________________________________________________________________________ +void HNIntranuke2025::SimulateHadronicFinalState(GHepRecord* ev, GHepParticle* p) const +{ +// Simulate a hadron interaction for the input particle p in HN mode +// + if(!p || !ev) + { + LOG("HNIntranuke2025", pERROR) << "** Null input!"; + return; + } + + // check particle id + int pdgc = p->Pdg(); + bool is_pion = (pdgc==kPdgPiP || pdgc==kPdgPiM || pdgc==kPdgPi0); + bool is_kaon = (pdgc==kPdgKP); + bool is_baryon = (pdgc==kPdgProton || pdgc==kPdgNeutron); + bool is_gamma = (pdgc==kPdgGamma); + if(!(is_pion || is_baryon || is_gamma || is_kaon)) + { + LOG("HNIntranuke2025", pERROR) << "** Cannot handle particle: " << p->Name(); + return; + } + try + { + // select a fate for the input particle + INukeFateHN_t fate = this->HadronFateHN(p); + + // store the fate + ev->Particle(p->FirstMother())->SetRescatterCode((int)fate); + + if(fate == kIHNFtUndefined) + { + LOG("HNIntranuke2025", pERROR) << "** Couldn't select a fate"; + LOG("HNIntranuke2025", pERROR) << "** Num Protons: " << fRemnZ + << ", Num Neutrons: "<<(fRemnA-fRemnZ); + LOG("HNIntranuke2025", pERROR) << "** Particle: " << "\n" << (*p); + //LOG("HNIntranuke2025", pERROR) << "** Event Record: " << "\n" << (*ev); + //p->SetStatus(kIStUndefined); + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + + LOG("HNIntranuke2025", pNOTICE) + << "Selected " << p->Name() << " fate: " << INukeHadroFates2025::AsString(fate); + + // handle the reaction + if(fate == kIHNFtCEx || fate == kIHNFtElas) + { + this->ElasHN(ev,p,fate); + } + else if(fate == kIHNFtAbs) {this-> AbsorbHN(ev,p,fate);} + else if(fate == kIHNFtInelas && pdgc != kPdgGamma) + { +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025", pDEBUG) + << "Invoking InelasticHN() for a : " << p->Name() + << " whose fate is : " << INukeHadroFates2025::AsString(fate); +#endif + + this-> InelasticHN(ev,p); + } + else if(fate == kIHNFtInelas && pdgc == kPdgGamma) {this-> GammaInelasticHN(ev,p,fate);} + else if(fate == kIHNFtCmp) LOG("HNIntranuke2025", pFATAL) << "The PreEquilibrium and Compound Nucleus code are experimental, should not be used"; +//{utils::intranuke2025::PreEquilibrium(ev,p,fRemnA,fRemnZ,fRemnP4,fDoFermi,fFermiFac,fNuclmodel,fNucRmvE,kIMdHN);} + else if(fate == kIHNFtNoInteraction) + { + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + } + catch(exceptions::INukeException exception) + { + this->SimulateHadronicFinalState(ev,p); + LOG("HNIntranuke2025", pNOTICE) + << "retry call to SimulateHadronicFinalState "; + LOG("HNIntranuke2025", pNOTICE) << exception; + + } +} +//___________________________________________________________________________ +INukeFateHN_t HNIntranuke2025::HadronFateHN(const GHepParticle * p) const +{ +// Select a hadron fate in HN mode +// + RandomGen * rnd = RandomGen::Instance(); + + // get pdgc code & kinetic energy in MeV + int pdgc = p->Pdg(); + double ke = p->KinE() / units::MeV; + + bool isPion = (pdgc == kPdgPiP or pdgc == kPdgPi0 or pdgc == kPdgPiM); + + if (isPion and fUseOset and ke < 350.0) return HadronFateOset (); + + LOG("HNIntranuke2025", pNOTICE) + << "Selecting hN fate for " << p->Name() << " with KE = " << ke << " MeV"; + + // try to generate a hadron fate + unsigned int iter = 0; + while(iter++ < kRjMaxIterations) { + + // handle pions + // + if (pdgc==kPdgPiP || pdgc==kPdgPiM || pdgc==kPdgPi0) { + + double frac_cex = this->FateWeight(pdgc, kIHNFtCEx) + * fHadroData2025->Frac(pdgc, kIHNFtCEx, ke, fRemnA, fRemnZ); + double frac_elas = this->FateWeight(pdgc, kIHNFtElas) + * fHadroData2025->Frac(pdgc, kIHNFtElas, ke, fRemnA, fRemnZ); + double frac_inel = this->FateWeight(pdgc, kIHNFtInelas) + * fHadroData2025->Frac(pdgc, kIHNFtInelas, ke, fRemnA, fRemnZ); + double frac_abs = this->FateWeight(pdgc, kIHNFtAbs) + * fHadroData2025->Frac(pdgc, kIHNFtAbs, ke, fRemnA, fRemnZ); + + frac_cex *= fNucCEXFac; // scaling factors + frac_abs *= fNucAbsFac; + frac_elas *= fNucQEFac; + if(pdgc==kPdgPi0) frac_abs*= 0.665; //isospin factor + + LOG("HNIntranuke2025", pNOTICE) + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtCEx) << "} = " << frac_cex + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtElas) << "} = " << frac_elas + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtInelas) << "} = " << frac_inel + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtAbs) << "} = " << frac_abs; + + // compute total fraction (can be <1 if fates have been switched off) + double tf = frac_cex + + frac_elas + + frac_inel + + frac_abs; + + double r = tf * rnd->RndFsi().Rndm(); +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025", pDEBUG) << "r = " << r << " (max = " << tf << ")"; +#endif + + double cf=0; // current fraction + + if(r < (cf += frac_cex )) return kIHNFtCEx; //cex + if(r < (cf += frac_elas )) return kIHNFtElas; //elas + if(r < (cf += frac_inel )) return kIHNFtInelas; //inelas + if(r < (cf += frac_abs )) return kIHNFtAbs; //abs + + LOG("HNIntranuke2025", pWARN) + << "No selection after going through all fates! " + << "Total fraction = " << tf << " (r = " << r << ")"; + //////////////////////////// + return kIHNFtUndefined; + } + + // handle nucleons + else if (pdgc==kPdgProton || pdgc==kPdgNeutron) { + + double frac_elas = this->FateWeight(pdgc, kIHNFtElas) + * fHadroData2025->Frac(pdgc, kIHNFtElas, ke, fRemnA, fRemnZ); + double frac_inel = this->FateWeight(pdgc, kIHNFtInelas) + * fHadroData2025->Frac(pdgc, kIHNFtInelas, ke, fRemnA, fRemnZ); + double frac_cmp = this->FateWeight(pdgc, kIHNFtCmp) + * fHadroData2025->Frac(pdgc, kIHNFtCmp, ke, fRemnA , fRemnZ); + + LOG("HNIntranuke2025", pINFO) + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtElas) << "} = " << frac_elas + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtInelas) << "} = " << frac_inel; + + // compute total fraction (can be <1 if fates have been switched off) + double tf = frac_elas + + frac_inel + + frac_cmp; + + double r = tf * rnd->RndFsi().Rndm(); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025", pDEBUG) << "r = " << r << " (max = " << tf << ")"; +#endif + + double cf=0; // current fraction + if(r < (cf += frac_elas )) return kIHNFtElas; // elas + if(r < (cf += frac_inel )) return kIHNFtInelas; // inelas + if(r < (cf += frac_cmp )) return kIHNFtCmp; // cmp + + LOG("HNIntranuke2025", pWARN) + << "No selection after going through all fates! " + << "Total fraction = " << tf << " (r = " << r << ")"; + ////////////////////////// + return kIHNFtUndefined; + } + + // handle gamma -- does not currently consider the elastic case + else if (pdgc==kPdgGamma) return kIHNFtInelas; + // Handle kaon -- elastic + charge exchange + else if (pdgc==kPdgKP){ + double frac_cex = this->FateWeight(pdgc, kIHNFtCEx) + * fHadroData2025->Frac(pdgc, kIHNFtCEx, ke, fRemnA, fRemnZ); + double frac_elas = this->FateWeight(pdgc, kIHNFtElas) + * fHadroData2025->Frac(pdgc, kIHNFtElas, ke, fRemnA, fRemnZ); + + // frac_cex *= fNucCEXFac; // scaling factors + // frac_elas *= fNucQEFac; // Flor - Correct scaling factors? + + LOG("HNIntranuke", pINFO) + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtCEx) << "} = " << frac_cex + << "\n frac{" << INukeHadroFates2025::AsString(kIHNFtElas) << "} = " << frac_elas; + + // compute total fraction (can be <1 if fates have been switched off) + double tf = frac_cex + + frac_elas; + + double r = tf * rnd->RndFsi().Rndm(); +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke", pDEBUG) << "r = " << r << " (max = " << tf << ")"; +#endif + + double cf=0; // current fraction + + if(r < (cf += frac_cex )) return kIHNFtCEx; //cex + if(r < (cf += frac_elas )) return kIHNFtElas; //elas + + LOG("HNIntranuke", pWARN) + << "No selection after going through all fates! " + << "Total fraction = " << tf << " (r = " << r << ")"; + //////////////////////////// + return kIHNFtUndefined; + }//End K+ + + /*else if (pdgc==kPdgKM){ + + return kIHNFtElas; + }//End K-*/ + + }//iterations + + return kIHNFtUndefined; +} + +//___________________________________________________________________________ +double HNIntranuke2025::FateWeight(int pdgc, INukeFateHN_t fate) const +{ + // turn fates off if the remnant nucleus does not have the number of p,n + // required + + int np = fRemnZ; + int nn = fRemnA - fRemnZ; + + if (np < 1 && nn < 1) + { + LOG("HNIntranuke2025", pERROR) << "** Nothing left in nucleus!!! **"; + return 0; + } + else + { + if (fate == kIHNFtCEx && pdgc==kPdgPiP ) { return (nn>=1) ? 1. : 0.; } + if (fate == kIHNFtCEx && pdgc==kPdgPiM ) { return (np>=1) ? 1. : 0.; } + if (fate == kIHNFtCEx && pdgc==kPdgKP ) { return (nn>=1) ? 1. : 0.; } //Added, changed np to nn + if (fate == kIHNFtAbs) { return ((nn>=1) && (np>=1)) ? 1. : 0.; } + if (fate == kIHNFtCmp ) { return ((pdgc==kPdgProton||pdgc==kPdgNeutron)&&fDoCompoundNucleus&&fRemnA>5) ? 1. : 0.; } + + } + return 1.; +} +//___________________________________________________________________________ +void HNIntranuke2025::AbsorbHN( + GHepRecord * ev, GHepParticle * p, INukeFateHN_t fate) const +{ + // handles pi+d->2p, pi-d->nn, pi0 d->pn absorbtion, all using pi+d values + + int pdgc = p->Pdg(); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025", pDEBUG) + << "AbsorbHN() is invoked for a : " << p->Name() + << " whose fate is : " << INukeHadroFates2025::AsString(fate); +#endif + + // check fate + if(fate!=kIHNFtAbs) + { + LOG("HNIntranuke2025", pWARN) + << "AbsorbHN() cannot handle fate: " << INukeHadroFates2025::AsString(fate); + return; + } + + // random number generator + RandomGen * rnd = RandomGen::Instance(); + + // Notes on the kinematics + // -- Simple variables are used for efficiency + // -- Variables are numbered according to particle + // -- -- #1 -> incoming particle + // -- -- #2 -> target (here, 2_1 and 2_2 for individual particles) + // -- -- #3 -> scattered incoming (Particle tracked in hA mode) + // -- -- #4 -> other scattered particle + // -- Suffix "L" is for lab frame, suffix "CM" is for center of mass frame + // -- Subscript "z" is for parallel component, "t" is for transverse + + int pcode, t1code, t2code, scode, s2code; // particles + double M1, M2_1, M2_2, M3, M4; // rest energies, in GeV + double E1L, P1L, E2L, P2L, E3L, P3L, E4L, P4L; + double P1zL, P2zL; + double beta, gm; // speed and gamma for CM frame in lab + double Et, E2CM; + double C3CM, S3CM; // cos and sin of scattering angle + double Theta1, Theta2, theta5; + double PHI3; // transverse scattering angle + double E1CM, E3CM, E4CM, P3CM; + double P3zL, P3tL, P4zL, P4tL; + double E2_1L, E2_2L; + TVector3 tP2_1L, tP2_2L, tP1L, tP2L, tPtot, P1zCM, P2zCM; + TVector3 tP3L, tP4L; + TVector3 bDir, tTrans, tbeta, tVect; + + // Library instance for reference + PDGLibrary * pLib = PDGLibrary::Instance(); + + // Handle fermi target + Target target(ev->TargetNucleus()->Pdg()); + + // Target should be a deuteron, but for now + // handling it as seperate nucleons + if(pdgc==211) // pi-plus + { + pcode = 211; + t1code = 2212; // proton + t2code = 2112; // neutron + scode = 2212; + s2code = 2212; + } + else if(pdgc==-211) // pi-minus + { + pcode = -211; + t1code = 2212; + t2code = 2112; + scode = 2112; + s2code = 2112; + } + else if(pdgc==111) // pi-zero + { + pcode = 111; + t1code = 2212; + t2code = 2112; + scode = 2212; + s2code = 2112; + } + else + { + LOG("HNIntranuke2025", pWARN) + << "AbsorbHN() cannot handle probe: " << pdgc; + return; + } + + // assign proper masses + M1 = pLib->Find(pcode) ->Mass(); + M2_1 = pLib->Find(t1code)->Mass(); + M2_2 = pLib->Find(t2code)->Mass(); + M3 = pLib->Find(scode) ->Mass(); + M4 = pLib->Find(s2code)->Mass(); + + // handle fermi momentum + if(fDoFermi) + { + target.SetHitNucPdg(t1code); + fNuclmodel->GenerateNucleon(target); + tP2_1L=fFermiFac * fNuclmodel->Momentum3(); + E2_1L = TMath::Sqrt(tP2_1L.Mag2() + M2_1*M2_1); + + target.SetHitNucPdg(t2code); + fNuclmodel->GenerateNucleon(target); + tP2_2L=fFermiFac * fNuclmodel->Momentum3(); + E2_2L = TMath::Sqrt(tP2_2L.Mag2() + M2_2*M2_2); + } + else + { + tP2_1L.SetXYZ(0.0, 0.0, 0.0); + E2_1L = M2_1; + + tP2_2L.SetXYZ(0.0, 0.0, 0.0); + E2_2L = M2_2; + } + + E2L = E2_1L + E2_2L; + + // adjust p to reflect scattering + // get random scattering angle + C3CM = fHadroData2025->IntBounce(p,t1code,scode,fate); + if (C3CM<-1.) + { + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + S3CM = TMath::Sqrt(1.0 - C3CM*C3CM); + + // Get lab energy and momenta + E1L = p->E(); + if(E1L<0.001) E1L=0.001; + P1L = TMath::Sqrt(E1L*E1L - M1*M1); + tP1L = p->P4()->Vect(); + tP2L = tP2_1L + tP2_2L; + P2L = tP2L.Mag(); + tPtot = tP1L + tP2L; + + // get unit vectors and angles needed for later + bDir = tPtot.Unit(); + Theta1 = tP1L.Angle(bDir); + Theta2 = tP2L.Angle(bDir); + + // get parallel and transverse components + P1zL = P1L*TMath::Cos(Theta1); + P2zL = P2L*TMath::Cos(Theta2); + tVect.SetXYZ(1,0,0); + if(TMath::Abs((tVect - bDir).Mag())<.01) tVect.SetXYZ(0,1,0); + theta5 = tVect.Angle(bDir); + tTrans = (tVect - TMath::Cos(theta5)*bDir).Unit(); + + // calculate beta and gamma + tbeta = tPtot * (1.0 / (E1L + E2L)); + beta = tbeta.Mag(); + gm = 1.0 / TMath::Sqrt(1.0 - beta*beta); + + // boost to CM frame to get scattered particle momenta + E1CM = gm*E1L - gm*beta*P1zL; + P1zCM = gm*P1zL*bDir - gm*tbeta*E1L; + E2CM = gm*E2L - gm*beta*P2zL; + P2zCM = gm*P2zL*bDir - gm*tbeta*E2L; + Et = E1CM + E2CM; + E3CM = (Et*Et + (M3*M3) - (M4*M4)) / (2.0*Et); + E4CM = Et - E3CM; + P3CM = TMath::Sqrt(E3CM*E3CM - M3*M3); + + // boost back to lab + P3zL = gm*beta*E3CM + gm*P3CM*C3CM; + P3tL = P3CM*S3CM; + P4zL = gm*beta*E4CM + gm*P3CM*(-C3CM); + P4tL = P3CM*(-S3CM); + + P3L = TMath::Sqrt(P3zL*P3zL + P3tL*P3tL); + P4L = TMath::Sqrt(P4zL*P4zL + P4tL*P4tL); + + // check for too small values + // may introduce error, so warn if it occurs + if(!(TMath::Finite(P3L))||P3L<.001) + { + LOG("HNIntranuke2025",pINFO) + << "Particle 3 " << M3 << " momentum small or non-finite: " << P3L + << "\n" << "--> Assigning .001 as new momentum"; + P3tL = 0; + P3zL = .001; + P3L = .001; + E3L = TMath::Sqrt(P3L*P3L + M3*M3); + } + + if(!(TMath::Finite(P4L))||P4L<.001) + { + LOG("HNIntranuke2025",pINFO) + << "Particle 4 " << M4 << " momentum small or non-finite: " << P4L + << "\n" << "--> Assigning .001 as new momentum"; + P4tL = 0; + P4zL = .001; + P4L = .001; + E4L = TMath::Sqrt(P4L*P4L + M4*M4); + } + + // pauli blocking (do not apply PB for Oset) + //if(!fUseOset && (P3L < fFermiMomentum || P4L < fFermiMomentum)) + double ke = p->KinE() / units::MeV; + if((!fUseOset || ke > 350.0 ) && (P3L < fFermiMomentum || P4L < fFermiMomentum)) + { +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025",pINFO) << "AbsorbHN failed: Pauli blocking"; +#endif + /* + p->SetStatus(kIStHadronInTheNucleus); + //disable until needed + // utils::intranuke2025::StepParticle(p,fFreeStep,fTrackingRadius); + ev->AddParticle(*p); + return; + */ + // new attempt at error handling: + LOG("HNIntranuke2025", pINFO) << "AbsorbHN failed: Pauli blocking"; + exceptions::INukeException exception; + exception.SetReason("hN absorption failed"); + throw exception; + } + + // handle remnant nucleus updates + fRemnZ--; + fRemnA -=2; + fRemnP4 -= TLorentzVector(tP2_1L,E2_1L); + fRemnP4 -= TLorentzVector(tP2_2L,E2_2L); + + // get random phi angle, distributed uniformally in 360 deg + PHI3 = 2 * kPi * rnd->RndFsi().Rndm(); + + tP3L = P3zL*bDir + P3tL*tTrans; + tP4L = P4zL*bDir + P4tL*tTrans; + + tP3L.Rotate(PHI3,bDir); // randomize transverse components + tP4L.Rotate(PHI3,bDir); + + E3L = TMath::Sqrt(P3L*P3L + M3*M3); + E4L = TMath::Sqrt(P4L*P4L + M4*M4); + + // create t particle w/ appropriate momenta, code, and status + // set target's mom to be the mom of the hadron that was cloned + GHepParticle * t = new GHepParticle(*p); + t->SetFirstMother(p->FirstMother()); + t->SetLastMother(p->LastMother()); + + TLorentzVector t4P4L(tP4L,E4L); + t->SetPdgCode(s2code); + t->SetMomentum(t4P4L); + t->SetStatus(kIStHadronInTheNucleus); + + // adjust p to reflect scattering + TLorentzVector t4P3L(tP3L,E3L); + p->SetPdgCode(scode); + p->SetMomentum(t4P3L); + p->SetStatus(kIStHadronInTheNucleus); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025", pDEBUG) + << "|p3| = " << (P3L) << ", E3 = " << (E3L); + LOG("HNIntranuke2025", pDEBUG) + << "|p4| = " << (P4L) << ", E4 = " << (E4L); +#endif + + ev->AddParticle(*p); + ev->AddParticle(*t); + + delete t; // delete particle clone +} +//___________________________________________________________________________ +void HNIntranuke2025::ElasHN( + GHepRecord * ev, GHepParticle * p, INukeFateHN_t fate) const +{ + // scatters particle within nucleus + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025", pDEBUG) + << "ElasHN() is invoked for a : " << p->Name() + << " whose fate is : " << INukeHadroFates2025::AsString(fate); +#endif + + if(fate!=kIHNFtCEx && fate!=kIHNFtElas) + { + LOG("HNIntranuke2025", pWARN) + << "ElasHN() cannot handle fate: " << INukeHadroFates2025::AsString(fate); + return; + } + + // Random number generator + RandomGen * rnd = RandomGen::Instance(); + + // vars for incoming particle, target, and scattered pdg codes + int pcode = p->Pdg(); + int tcode, scode, s2code; + double ppcnt = (double) fRemnZ / (double) fRemnA; // % of protons + + // Select a target randomly, weighted to # + // -- Unless, of course, the fate is CEx, + // -- in which case the target may be deterministic + // Also assign scattered particle code + if(fate==kIHNFtCEx) + { + if(pcode==kPdgPiP) {tcode = kPdgNeutron; scode = kPdgPi0; s2code = kPdgProton;} + else if(pcode==kPdgPiM) {tcode = kPdgProton; scode = kPdgPi0; s2code = kPdgNeutron;} + else if(pcode==kPdgKP) {tcode = kPdgNeutron; scode = kPdgK0; s2code = kPdgProton;} + else + { + // for pi0 + tcode = (rnd->RndFsi().Rndm()<=ppcnt)?(kPdgProton) :(kPdgNeutron); + scode = (tcode == kPdgProton) ?(kPdgPiP) :(kPdgPiM); + s2code = (tcode == kPdgProton) ?(kPdgNeutron):(kPdgProton); + } + } + else + { + tcode = (rnd->RndFsi().Rndm()<=ppcnt)?(kPdgProton):(kPdgNeutron); + scode = pcode; + s2code = tcode; + } + + // get random scattering angle + double C3CM = fHadroData2025->IntBounce(p,tcode,scode,fate); + if (C3CM<-1.) + { + p->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + return; + } + + // create scattered particle + GHepParticle * t = new GHepParticle(*p); + t->SetPdgCode(tcode); + double Mt = t->Mass(); + //t->SetMomentum(TLorentzVector(0,0,0,Mt)); + t->SetRemovalEnergy(0); + // handle fermi momentum + if(fDoFermi) + { + // Handle fermi target + Target target(ev->TargetNucleus()->Pdg()); + //LOG("HAIntranuke2025", pNOTICE) << "Nuclmodel= " << fNuclmodel->ModelType(target) ; + target.SetHitNucPdg(tcode); + fNuclmodel->GenerateNucleon(target); + TVector3 tP3L = fFermiFac * fNuclmodel->Momentum3(); + double tE = TMath::Sqrt(tP3L.Mag2() + Mt*Mt); + t->SetMomentum(TLorentzVector(tP3L,tE)); + } + else + { + t->SetMomentum(TLorentzVector(0,0,0,Mt)); + } + + bool pass = utils::intranuke2025::TwoBodyCollision(ev,pcode,tcode,scode,s2code,C3CM, + p,t,fRemnA,fRemnZ,fRemnP4,kIMdHN); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025",pDEBUG) + << "|p3| = " << P3L << ", E3 = " << E3L; + LOG("HNIntranuke2025",pDEBUG) + << "|p4| = " << P4L << ", E4 = " << E4L; +#endif + + if (pass==true) + { + ev->AddParticle(*p); + ev->AddParticle(*t); + } else + { + delete t; //fixes memory leak + LOG("HNIntranuke2025", pINFO) << "Elastic in hN failed calling TwoBodyCollision"; + exceptions::INukeException exception; + exception.SetReason("hN scattering kinematics through TwoBodyCollision failed"); + throw exception; + } + + delete t; + +} +//___________________________________________________________________________ +void HNIntranuke2025::InelasticHN(GHepRecord* ev, GHepParticle* p) const +{ + // Aaron Meyer (Jan 2010) + // Updated version of InelasticHN + + GHepParticle s1(*p); + GHepParticle s2(*p); + GHepParticle s3(*p); + s2.SetRemovalEnergy(0); + s3.SetRemovalEnergy(0); + + + + if (utils::intranuke2025::PionProduction(ev,p,&s1,&s2,&s3,fRemnA,fRemnZ,fRemnP4,fDoFermi,fFermiFac,fFermiMomentum,fNuclmodel)) + { + // set status of particles and return + + s1.SetStatus(kIStHadronInTheNucleus); + s2.SetStatus(kIStHadronInTheNucleus); + s3.SetStatus(kIStHadronInTheNucleus); + + ev->AddParticle(s1); + ev->AddParticle(s2); + ev->AddParticle(s3); + } + else + { + LOG("HNIntranuke2025", pNOTICE) << "Error: could not create pion production final state"; + exceptions::INukeException exception; + exception.SetReason("PionProduction in hN failed"); + throw exception; + } + return; + +} +//___________________________________________________________________________ +void HNIntranuke2025::GammaInelasticHN(GHepRecord* ev, GHepParticle* p, INukeFateHN_t fate) const +{ + // This function handles pion photoproduction reactions + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025", pDEBUG) + << "GammaInelasticHN() is invoked for a : " << p->Name() + << " whose fate is : " << INukeHadroFates2025::AsString(fate); +#endif + + if(fate!=kIHNFtInelas && p->Pdg()!=kPdgGamma) + { + LOG("HNIntranuke2025", pWARN) + << "GammaInelasticHN() cannot handle fate: " << INukeHadroFates2025::AsString(fate); + return; + } + + // random number generator + RandomGen * rnd = RandomGen::Instance(); + + // vars for incoming particle, target, and scattered reaction products + double ppcnt = (double) fRemnZ / (double) fRemnA; // % of protons + int pcode = p->Pdg(); + int tcode = (rnd->RndFsi().Rndm()<=ppcnt)?(kPdgProton):(kPdgNeutron); + int scode, s2code; + double ke = p->KinE() / units::MeV; + + LOG("HNIntranuke2025", pNOTICE) + << "Particle code: " << pcode << ", target: " << tcode; + + + if (rnd->RndFsi().Rndm() * (fHadroData2025 -> XSecGamp_fs() -> Evaluate(ke) + + fHadroData2025 -> XSecGamn_fs() -> Evaluate(ke) ) + <= fHadroData2025 -> XSecGamp_fs() -> Evaluate(ke) ) { scode = kPdgProton; } + else { scode = kPdgNeutron; } + + //scode=fHadroData2025->AngleAndProduct(p,tcode,C3CM,fate); + //double C3CM = 0.0; // cos of scattering angle + double C3CM = fHadroData2025->IntBounce(p,tcode,scode,fate); + + if ((tcode == kPdgProton ) && (scode==kPdgProton )) {s2code=kPdgPi0;} + else if ((tcode == kPdgProton ) && (scode==kPdgNeutron)) {s2code=kPdgPiP;} + else if ((tcode == kPdgNeutron) && (scode==kPdgProton )) {s2code=kPdgPiM;} + else if ((tcode == kPdgNeutron) && (scode==kPdgNeutron)) {s2code=kPdgPi0;} + else { + LOG("HNIntranuke2025", pERROR) + << "Error: could not determine particle final states"; + ev->AddParticle(*p); + return; + } + + LOG("HNIntranuke2025", pNOTICE) + << "GammaInelastic fate: " << INukeHadroFates2025::AsString(fate); + LOG("HNIntranuke2025", pNOTICE) + << " final state: " << scode << " and " << s2code; + LOG("HNIntranuke2025", pNOTICE) + << " scattering angle: " << C3CM; + + GHepParticle * t = new GHepParticle(*p); + t->SetPdgCode(tcode); + double Mt = t->Mass(); + + // handle fermi momentum + if(fDoFermi) + { + // Handle fermi target + Target target(ev->TargetNucleus()->Pdg()); + + target.SetHitNucPdg(tcode); + fNuclmodel->GenerateNucleon(target); + TVector3 tP3L = fFermiFac * fNuclmodel->Momentum3(); + double tE = TMath::Sqrt(tP3L.Mag2() + Mt*Mt); + t->SetMomentum(TLorentzVector(tP3L,tE)); + } + else + { + t->SetMomentum(TLorentzVector(0,0,0,Mt)); + } + + bool pass = utils::intranuke2025::TwoBodyCollision(ev,pcode,tcode,scode,s2code,C3CM, + p,t,fRemnA,fRemnZ,fRemnP4,kIMdHN); + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("HNIntranuke2025",pDEBUG) + << "|p3| = " << P3L << ", E3 = " << E3L; + LOG("HNIntranuke2025",pDEBUG) + << "|p4| = " << P4L << ", E4 = " << E4L; +#endif + + if (pass==true) + { + //p->SetStatus(kIStStableFinalState); + //t->SetStatus(kIStStableFinalState); + ev->AddParticle(*p); + ev->AddParticle(*t); + } else + { + ev->AddParticle(*p); + } + + delete t; + +} +//___________________________________________________________________________ +int HNIntranuke2025::HandleCompoundNucleus(GHepRecord* ev, GHepParticle* p, int mom) const +{ + + // handle compound nucleus option + // -- Call the PreEquilibrium function + if( fDoCompoundNucleus && IsInNucleus(p) && pdg::IsNeutronOrProton(p->Pdg())) + { // random number generator + //unused var - quiet compiler warning//RandomGen * rnd = RandomGen::Instance(); + + if((p->KinE() < fEPreEq) ) + { + if(fRemnA>4) //this needs to be matched to what is in PreEq and Eq + { + GHepParticle * sp = new GHepParticle(*p); + sp->SetFirstMother(mom); + // this was PreEquilibrium - now just used for hN + //same arguement lists for PreEq and Eq + utils::intranuke2025::Equilibrium(ev,sp,fRemnA,fRemnZ,fRemnP4, + fDoFermi,fFermiFac,fNuclmodel,fNucRmvE,kIMdHN); + + delete sp; + return 2; + } + else + { + // nothing left to interact with! + LOG("HNIntranuke2025", pNOTICE) + << "*** Nothing left to interact with, escaping."; + GHepParticle * sp = new GHepParticle(*p); + sp->SetFirstMother(mom); + sp->SetStatus(kIStStableFinalState); + ev->AddParticle(*sp); + delete sp; + return 1; + } + } + } + return 0; +} +//___________________________________________________________________________ +bool HNIntranuke2025::HandleCompoundNucleusHN(GHepRecord* ev, GHepParticle* p) const +{ + return (this->HandleCompoundNucleus(ev,p,p->FirstMother())==2); +} +//___________________________________________________________________________ + +void HNIntranuke2025::LoadConfig(void) +{ + // load hadronic cross sections + fHadroData2025 = INukeHadroData2025::Instance(); + + // fermi momentum setup + // this is specifically set in Intranuke2025::Configure(string) + fNuclmodel = dynamic_cast( this -> SubAlg("NuclearModel") ) ; + + // other intranuke config params + GetParam( "NUCL-R0", fR0 ); // fm + GetParam( "NUCL-NR", fNR ); + + GetParam( "INUKE-NucRemovalE", fNucRmvE ); // GeV + GetParam( "INUKE-HadStep", fHadStep ) ; + GetParam( "INUKE-NucAbsFac", fNucAbsFac ) ; + GetParam( "INUKE-NucQEFac", fNucQEFac ) ; + GetParam( "INUKE-NucCEXFac", fNucCEXFac ) ; + GetParam( "INUKE-Energy_Pre_Eq", fEPreEq ) ; + GetParam( "INUKE-FermiFac", fFermiFac ) ; + GetParam( "INUKE-FermiMomentum", fFermiMomentum ) ; + + GetParam( "INUKE-DoCompoundNucleus", fDoCompoundNucleus ) ; + GetParam( "INUKE-DoFermi", fDoFermi ) ; + GetParam( "INUKE-XsecNNCorr", fXsecNNCorr ) ; + GetParamDef( "AltOset", fAltOset, false ) ; + + GetParam( "HNINUKE-UseOset", fUseOset ) ; + GetParam( "HNINUKE-DelRPion", fDelRPion ) ; + GetParam( "HNINUKE-DelRNucleon", fDelRNucleon ) ; + + GetParamDef( "FSI-ChargedPion-MFPScale", fChPionMFPScale, 1.0 ) ; + GetParamDef( "FSI-NeutralPion-MFPScale", fNeutralPionMFPScale, 1.0 ) ; + GetParamDef( "FSI-Nucleon-MFPScale", fNucleonMFPScale, 1.0 ) ; + + // report + LOG("HNIntranuke2025", pINFO) << "Settings for Intranuke2025 mode: " << INukeMode::AsString(kIMdHN); + LOG("HNIntranuke2025", pWARN) << "R0 = " << fR0 << " fermi"; + LOG("HNIntranuke2025", pWARN) << "NR = " << fNR; + LOG("HNIntranuke2025", pWARN) << "DelRPion = " << fDelRPion; + LOG("HNIntranuke2025", pWARN) << "DelRNucleon = " << fDelRNucleon; + LOG("HNIntranuke2025", pWARN) << "HadStep = " << fHadStep << " fermi"; + LOG("HNIntranuke2025", pWARN) << "NucAbsFac = " << fNucAbsFac; + LOG("HNIntranuke2025", pWARN) << "NucQEFac = " << fNucQEFac; + LOG("HNIntranuke2025", pWARN) << "NucCEXFac = " << fNucCEXFac; + LOG("HNIntranuke2025", pWARN) << "EPreEq = " << fEPreEq; + LOG("HNIntranuke2025", pWARN) << "FermiFac = " << fFermiFac; + LOG("HNIntranuke2025", pWARN) << "FermiMomtm = " << fFermiMomentum; + LOG("HNIntranuke2025", pWARN) << "DoFermi? = " << ((fDoFermi)?(true):(false)); + LOG("HNIntranuke2025", pWARN) << "DoCmpndNuc? = " << ((fDoCompoundNucleus)?(true):(false)); + LOG("HNIntranuke2025", pWARN) << "useOset = " << fUseOset; + LOG("HNIntranuke2025", pWARN) << "altOset = " << fAltOset; + LOG("HNIntranuke2025", pWARN) << "XsecNNCorr? = " << ((fXsecNNCorr)?(true):(false)); + LOG("HNIntranuke2025", pWARN) << "FSI-ChargedPion-MFPScale = " << fChPionMFPScale; + LOG("HNIntranuke2025", pWARN) << "FSI-NeutralPion-MFPScale = " << fNeutralPionMFPScale; +} +//___________________________________________________________________________ + +INukeFateHN_t HNIntranuke2025::HadronFateOset () const +{ + //LOG("HNIntranuke2025", pWARN) << "IN HadronFateOset"; + + //LOG("HNIntranuke2025", pWARN) << "{ frac abs = " << osetUtils::currentInstance->getAbsorptionFraction(); + //LOG("HNIntranuke2025", pWARN) << " frac cex = " << osetUtils::currentInstance->getCexFraction() << " }"; + + double fractionAbsorption = osetUtils::currentInstance->getAbsorptionFraction(); + double fractionCex = osetUtils::currentInstance->getCexFraction (); + double fractionElas = 1 - (fractionAbsorption + fractionCex); + + fractionCex *= fNucCEXFac; // scaling factors + fractionAbsorption *= fNucAbsFac; + fractionElas *= fNucQEFac; + + double totalFrac = fractionCex + fractionAbsorption + fractionElas; + + RandomGen *randomGenerator = RandomGen::Instance(); + const double randomNumber = randomGenerator->RndFsi().Rndm() * totalFrac; + + LOG("HNIntranuke2025", pNOTICE) << "{ frac abs = " << fractionAbsorption; + LOG("HNIntranuke2025", pNOTICE) << " frac cex = " << fractionCex; + LOG("HNIntranuke2025", pNOTICE) << " frac elas = " << fractionElas << " }"; + + if (randomNumber < fractionAbsorption && fRemnA > 1) return kIHNFtAbs; + else if (randomNumber < fractionAbsorption + fractionCex) return kIHNFtCEx; + else return kIHNFtElas; +} diff --git a/src/Physics/HadronTransport/HNIntranuke2025.h b/src/Physics/HadronTransport/HNIntranuke2025.h new file mode 100644 index 0000000000..c629b90746 --- /dev/null +++ b/src/Physics/HadronTransport/HNIntranuke2025.h @@ -0,0 +1,91 @@ +//____________________________________________________________________________ +/*! + +\class genie::Intranuke + +\brief The INTRANUKE intranuclear hadron transport MC. + Is a concrete implementation of the EventRecordVisitorI interface. + +\ref R.Merenyi et al., Phys.Rev.D45 (1992) + R.D.Ransome, Nucl.Phys.B 139 (2005) + + Current INTRANUKE development is led by S.Dytman and H.Gallagher. + The original INTRANUKE cascade MC was developed (in fortran) for the + NeuGEN MC by R.Edgecock, G.F.Pearce, W.A.Mann, R.Merenyi and others. + +\author Steve Dytman , Pittsburgh University + Aaron Meyer , Pittsburgh University + Alex Bell, Pittsburgh University + Hugh Gallagher , Tufts University + Costas Andreopoulos STFC, Rutherford Lab + +\created September 20, 2005 + +\cpright Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + +*/ +//____________________________________________________________________________ + +#ifndef _HN_INTRANUKE_2025_H_ +#define _HN_INTRANUKE_2025_H_ + +#include + +#include "Physics/NuclearState/NuclearModelI.h" +#include "Framework/Algorithm/AlgFactory.h" +#include "Framework/EventGen/EventRecordVisitorI.h" +#include "Physics/HadronTransport/INukeMode.h" +#include "Physics/HadronTransport/INukeHadroFates.h" +#include "Physics/HadronTransport/Intranuke2025.h" + +class TLorentzVector; +class TVector3; + +namespace genie { + +class GHepParticle; +class INukeHadroData; +class PDGCodeList; + +class HNIntranuke2025 : public Intranuke2025 { + +friend class IntranukeTester; + +public : + HNIntranuke2025(); + HNIntranuke2025(string config); + ~HNIntranuke2025(); + + void ProcessEventRecord(GHepRecord * event_rec) const; + + virtual string GetINukeMode() const {return "hN2025";}; + virtual string GetGenINukeMode() const {return "hN";}; + +private: + + void LoadConfig (void); + + // methods specific to intranuke HN-mode + void SimulateHadronicFinalState (GHepRecord* ev, GHepParticle* p) const; + INukeFateHN_t HadronFateHN (const GHepParticle* p) const; + INukeFateHN_t HadronFateOset () const; + double FateWeight (int pdgc, INukeFateHN_t fate) const; + void ElasHN (GHepRecord* ev, GHepParticle* p, INukeFateHN_t fate) const; + void AbsorbHN (GHepRecord* ev, GHepParticle* p, INukeFateHN_t fate) const; + void InelasticHN (GHepRecord* ev, GHepParticle* p) const; + void GammaInelasticHN (GHepRecord* ev, GHepParticle* p, INukeFateHN_t fate) const; + bool HandleCompoundNucleusHN (GHepRecord* ev, GHepParticle* p) const; + int HandleCompoundNucleus(GHepRecord* ev, GHepParticle* p, int mom) const; + + mutable int nuclA; ///< value of A for the target nucleus in hA mode + + // data members specific to intranuke HN-mode + double fNucQEFac; + +}; + +} // genie namespace + +#endif // _HN_INTRANUKE_ALT_H_ + diff --git a/src/Physics/HadronTransport/INukeHadroData2025.cxx b/src/Physics/HadronTransport/INukeHadroData2025.cxx new file mode 100644 index 0000000000..2ad7a4c760 --- /dev/null +++ b/src/Physics/HadronTransport/INukeHadroData2025.cxx @@ -0,0 +1,1692 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2024, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + + Costas Andreopoulos , Rutherford Lab. + Steve Dytman , Pittsburgh Univ. + Aaron Meyer , Pittsburgh Univ. + Alex Bell, Pittsburgh Univ. + February 01, 2007 + + For the class documentation see the corresponding header file. + + Important revisions after version 2.0.0 : + @ Dec 06, 2008 - CA + Tweak dtor so as not to clutter the output if GENIE exits in err so as to + spot the fatal mesg immediately. + @ Jul 15, 2010 - AM + MeanFreePath now distinguishes between protons and neutrons. To account for + this, additional splines were added for each nucleon. Absorption fates + condensed into a single fate, splines updated accordingly. Added gamma and kaon + splines.Outdated splines were removed. Function IntBounce implemented to calculate + a CM scattering angle for given probe, target, product, and fate. AngleAndProduct + similar to IntBounce, but also determines the target nucleon. + @ May 01, 2012 - CA + Pick data from $GENIE/data/evgen/intranuke/ + @ Jan 9, 2015 - SD, Nick Geary, Tomek Golan + Added 2014 version of INTRANUKE codes for independent development. + @ Oct, 2015 - TG + Added 2015 version of INTRANUKE codes for independent development. + Include Oset data files. + @ Apr, 2016 - Flor Blasczyk + Added K+ cex data files + + @ Sep, 2025 - Mohamed Ismail, SD + added total cross sections TGraph2d for hA2025 model + corresponding data. +no changes for the 2018 class version, major changes made in INukeHadroData2025 +for new hA pion splines Add data, use hN for high pion KE, use INCL for low energy. +Use splines for channel and total reac xs to improve accuracy. Also, smooth results to +avoid discontinuities. + +*/ +//____________________________________________________________________________ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "Framework/Conventions/Constants.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Physics/HadronTransport/INukeHadroData2025.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/Numerical/RandomGen.h" +#include "Framework/Numerical/Spline.h" +#include "Framework/ParticleData/PDGCodes.h" + +using std::ostringstream; +using std::ios; + +using namespace genie; +using namespace genie::constants; + +//____________________________________________________________________________ +INukeHadroData2025 * INukeHadroData2025::fInstance = 0; +//____________________________________________________________________________ +double INukeHadroData2025::fMinKinEnergy = 1.0; // MeV +double INukeHadroData2025::fMaxKinEnergyHA = 999.0; // MeV +double INukeHadroData2025::fMaxKinEnergyHN = 1799.0; // MeV +//____________________________________________________________________________ +INukeHadroData2025::INukeHadroData2025() +{ + this->LoadCrossSections(); + fInstance = 0; +} +//____________________________________________________________________________ +INukeHadroData2025::~INukeHadroData2025() +{ + + // pi+n/p hA x-section splines + delete fXSecPipn_Tot; + delete fXSecPipn_CEx; + delete fXSecPipn_Elas; + delete fXSecPipn_Reac; + delete fXSecPipp_Tot; + delete fXSecPipp_CEx; + delete fXSecPipp_Elas; + delete fXSecPipp_Reac; + delete fXSecPipd_Abs; + + delete fXSecPp_Cmp; //added to fix memory leak; no noticeable effect, but good convention. + delete fXSecPn_Cmp; + delete fXSecNn_Cmp; + delete fXSecPp_Tot; + delete fXSecPp_Elas; + delete fXSecPp_Reac; + delete fXSecPn_Tot; + delete fXSecPn_Elas; + delete fXSecPn_Reac; + delete fXSecNn_Tot; + delete fXSecNn_Elas; + delete fXSecNn_Reac; + + // pi0n/p hA x-section splines + delete fXSecPi0n_Tot; + delete fXSecPi0n_CEx; + delete fXSecPi0n_Elas; + delete fXSecPi0n_Reac; + delete fXSecPi0p_Tot; + delete fXSecPi0p_CEx; + delete fXSecPi0p_Elas; + delete fXSecPi0p_Reac; + delete fXSecPi0d_Abs; + + // K+N x-section splines + delete fXSecKpn_Elas; + delete fXSecKpp_Elas; + delete fXSecKpn_CEx; + delete fXSecKpN_Abs; + delete fXSecKpN_Tot; + + // gamma x-section splines (inelastic only) + delete fXSecGamp_fs; + delete fXSecGamn_fs; + delete fXSecGamN_Tot; + + // N+A x-section splines + delete fFracPA_Tot; + // delete fFracPA_Elas; + delete fFracPA_Inel; + delete fFracPA_CEx; + delete fFracPA_Abs; + delete fFracPA_PiPro; + delete fFracNA_Tot; + // delete fFracNA_Elas; + delete fFracNA_Inel; + delete fFracNA_CEx; + delete fFracNA_Abs; + delete fFracNA_PiPro; + + delete fFracPA_Cmp; // cmp - add support later + delete fFracNA_Cmp; + + // hN data + delete fhN2dXSecPP_Elas; + delete fhN2dXSecNP_Elas; + delete fhN2dXSecPipN_Elas; + delete fhN2dXSecPi0N_Elas; + delete fhN2dXSecPimN_Elas; + delete fhN2dXSecKpN_Elas; + delete fhN2dXSecKpP_Elas; + delete fhN2dXSecPiN_CEx; + delete fhN2dXSecPiN_Abs; + delete fhN2dXSecGamPi0P_Inelas; + delete fhN2dXSecGamPi0N_Inelas; + delete fhN2dXSecGamPipN_Inelas; + delete fhN2dXSecGamPimP_Inelas; + delete fhN2dXSecKpN_CEx; + + // for hA2025 + delete TPipA_Tot; + delete TPipA_Abs; + delete TPipA_CEx; + delete TPipA_Inelas; + delete TPipA_PiPro; + + + // K+A x-section fraction splines + delete fFracKA_Tot; + delete fFracKA_Elas; + delete fFracKA_CEx; + delete fFracKA_Inel; + delete fFracKA_Abs; + +} +//____________________________________________________________________________ +INukeHadroData2025 * INukeHadroData2025::Instance() +{ + if(fInstance == 0) { + LOG("INukeData", pINFO) << "INukeHadroData2025 late initialization"; + static INukeHadroData2025::Cleaner cleaner; + cleaner.DummyMethodAndSilentCompiler(); + fInstance = new INukeHadroData2025; + } + return fInstance; +} +//____________________________________________________________________________ +void INukeHadroData2025::LoadCrossSections(void) +{ +// Loads hadronic x-section data + + //-- Get the top-level directory with input hadron cross-section data + // (search for $GINUKEHADRONDATA or use default location) + string data_dir = (gSystem->Getenv("GINUKEHADRONDATA")) ? + string(gSystem->Getenv("GINUKEHADRONDATA")) : + string(gSystem->Getenv("GENIE")) + string("/data/evgen/intranuke"); + + LOG("INukeData", pINFO) + << "Loading INTRANUKE hadron data from: " << data_dir; + + //-- Build filenames + + string datafile_NN = data_dir + "/tot_xsec/intranuke-xsections-NN2014.dat"; + string datafile_pipN = data_dir + "/tot_xsec/intranuke-xsections-pi+N.dat"; + string datafile_pi0N = data_dir + "/tot_xsec/intranuke-xsections-pi0N.dat"; + string datafile_NA = data_dir + "/tot_xsec/intranuke-fractions-NA2016.dat"; + string datafile_KA = data_dir + "/tot_xsec/intranuke-fractions-KA.dat"; + string datafile_gamN = data_dir + "/tot_xsec/intranuke-xsections-gamN.dat"; + string datafile_kN = data_dir + "/tot_xsec/intranuke-xsections-kaonN2018.dat"; + + //-- Make sure that all data files are available + + assert( ! gSystem->AccessPathName(datafile_NN. c_str()) ); + assert( ! gSystem->AccessPathName(datafile_pipN.c_str()) ); + assert( ! gSystem->AccessPathName(datafile_pi0N.c_str()) ); + assert( ! gSystem->AccessPathName(datafile_NA. c_str()) ); + assert( ! gSystem->AccessPathName(datafile_KA. c_str()) ); + assert( ! gSystem->AccessPathName(datafile_gamN.c_str()) ); + assert( ! gSystem->AccessPathName(datafile_kN. c_str()) ); + + LOG("INukeData", pINFO) << "Found all necessary data files..."; + + //-- Load data files + + TTree data_NN; + TTree data_pipN; + TTree data_pi0N; + TTree data_NA; + TTree data_KA; + TTree data_gamN; + TTree data_kN; + + data_NN.ReadFile(datafile_NN.c_str(),"ke/D:pp_tot/D:pp_elas/D:pp_reac/D:pn_tot/D:pn_elas/D:pn_reac/D:nn_tot/D:nn_elas/D:nn_reac/D:pp_cmp/D:pn_cmp/D:nn_cmp/D"); + data_pipN.ReadFile(datafile_pipN.c_str(), + "ke/D:pipn_tot/D:pipn_cex/D:pipn_elas/D:pipn_reac/D:pipp_tot/D:pipp_cex/D:pipp_elas/D:pipp_reac/D:pipd_abs"); + data_pi0N.ReadFile(datafile_pi0N.c_str(), + "ke/D:pi0n_tot/D:pi0n_cex/D:pi0n_elas/D:pi0n_reac/D:pi0p_tot/D:pi0p_cex/D:pi0p_elas/D:pi0p_reac/D:pi0d_abs"); + //data_NA.ReadFile(datafile_NA.c_str(), + //"ke/D:pA_tot/D:pA_elas/D:pA_inel/D:pA_cex/D:pA_abs/D:pA_pipro/D"); // add support for cmp here (?) + data_NA.ReadFile(datafile_NA.c_str(), + "ke/D:pA_tot/D:pA_inel/D:pA_cex/D:pA_abs/D:pA_pipro/D:pA_cmp/D"); // add support for cmp here (?) + data_gamN.ReadFile(datafile_gamN.c_str(), + "ke/D:pi0p_tot/D:pipn_tot/D:pimp_tot/D:pi0n_tot/D:gamp_fs/D:gamn_fs/D:gamN_tot/D"); + data_kN.ReadFile(datafile_kN.c_str(), + "ke/D:kpp_elas/D:kpn_elas/D:kpn_cex/D:kp_abs/D:kpN_tot/D"); + data_KA.ReadFile(datafile_KA.c_str(), + "ke/D:KA_tot/D:KA_elas/D:KA_inel/D:KA_abs/D"); + + LOG("INukeData", pDEBUG) << "Number of data rows in NN : " << data_NN.GetEntries(); + LOG("INukeData", pDEBUG) << "Number of data rows in pipN : " << data_pipN.GetEntries(); + LOG("INukeData", pDEBUG) << "Number of data rows in pi0N : " << data_pi0N.GetEntries(); + LOG("INukeData", pDEBUG) << "Number of data rows in NA : " << data_NA.GetEntries(); + LOG("INukeData", pDEBUG) << "Number of data rows in KA : " << data_KA.GetEntries(); + LOG("INukeData", pDEBUG) << "Number of data rows in gamN : " << data_gamN.GetEntries(); + LOG("INukeData", pDEBUG) << "Number of data rows in kN : " << data_kN.GetEntries(); + + LOG("INukeData", pINFO) << "Done loading all x-section files..."; + + //-- Build x-section splines + + // p/n+p/n hA x-section splines + fXSecPp_Tot = new Spline(&data_NN, "ke:pp_tot"); + fXSecPp_Elas = new Spline(&data_NN, "ke:pp_elas"); + fXSecPp_Reac = new Spline(&data_NN, "ke:pp_reac"); + fXSecPn_Tot = new Spline(&data_NN, "ke:pn_tot"); + fXSecPn_Elas = new Spline(&data_NN, "ke:pn_elas"); + fXSecPn_Reac = new Spline(&data_NN, "ke:pn_reac"); + fXSecNn_Tot = new Spline(&data_NN, "ke:nn_tot"); + fXSecNn_Elas = new Spline(&data_NN, "ke:nn_elas"); + fXSecNn_Reac = new Spline(&data_NN, "ke:nn_reac"); + fXSecPp_Cmp = new Spline(&data_NN, "ke:pp_cmp"); //for compound nucleus fate + fXSecPn_Cmp = new Spline(&data_NN, "ke:pn_cmp"); + fXSecNn_Cmp = new Spline(&data_NN, "ke:nn_cmp"); + + // pi+n/p hA x-section splines + fXSecPipn_Tot = new Spline(&data_pipN, "ke:pipn_tot"); + fXSecPipn_CEx = new Spline(&data_pipN, "ke:pipn_cex"); + fXSecPipn_Elas = new Spline(&data_pipN, "ke:pipn_elas"); + fXSecPipn_Reac = new Spline(&data_pipN, "ke:pipn_reac"); + fXSecPipp_Tot = new Spline(&data_pipN, "ke:pipp_tot"); + fXSecPipp_CEx = new Spline(&data_pipN, "ke:pipp_cex"); + fXSecPipp_Elas = new Spline(&data_pipN, "ke:pipp_elas"); + fXSecPipp_Reac = new Spline(&data_pipN, "ke:pipp_reac"); + fXSecPipd_Abs = new Spline(&data_pipN, "ke:pipd_abs"); + + // pi0n/p hA x-section splines + fXSecPi0n_Tot = new Spline(&data_pi0N, "ke:pi0n_tot"); + fXSecPi0n_CEx = new Spline(&data_pi0N, "ke:pi0n_cex"); + fXSecPi0n_Elas = new Spline(&data_pi0N, "ke:pi0n_elas"); + fXSecPi0n_Reac = new Spline(&data_pi0N, "ke:pi0n_reac"); + fXSecPi0p_Tot = new Spline(&data_pi0N, "ke:pi0p_tot"); + fXSecPi0p_CEx = new Spline(&data_pi0N, "ke:pi0p_cex"); + fXSecPi0p_Elas = new Spline(&data_pi0N, "ke:pi0p_elas"); + fXSecPi0p_Reac = new Spline(&data_pi0N, "ke:pi0p_reac"); + fXSecPi0d_Abs = new Spline(&data_pi0N, "ke:pi0d_abs"); + + // K+N x-section splines + fXSecKpn_Elas = new Spline(&data_kN, "ke:kpn_elas"); + fXSecKpp_Elas = new Spline(&data_kN, "ke:kpp_elas"); + fXSecKpn_CEx = new Spline(&data_kN, "ke:kpn_cex"); + fXSecKpN_Abs = 0; // new Spline(&data_kN, "ke:kp_abs"); why not used? + fXSecKpN_Tot = new Spline(&data_kN, "ke:kpN_tot"); + + // gamma x-section splines + fXSecGamp_fs = new Spline(&data_gamN, "ke:gamp_fs"); + fXSecGamn_fs = new Spline(&data_gamN, "ke:gamn_fs"); + fXSecGamN_Tot = new Spline(&data_gamN, "ke:gamN_tot"); + + // N+A x-section fraction splines + fFracPA_Tot = new Spline(&data_NA, "ke:pA_tot"); + // fFracPA_Elas = new Spline(&data_NA, "ke:pA_elas"); + fFracPA_Inel = new Spline(&data_NA, "ke:pA_inel"); + fFracPA_CEx = new Spline(&data_NA, "ke:pA_cex"); + fFracPA_Abs = new Spline(&data_NA, "ke:pA_abs"); + fFracPA_PiPro = new Spline(&data_NA, "ke:pA_pipro"); + fFracNA_Tot = new Spline(&data_NA, "ke:pA_tot"); // assuming nA same as pA + // fFracNA_Elas = new Spline(&data_NA, "ke:pA_elas"); + fFracNA_Inel = new Spline(&data_NA, "ke:pA_inel"); + fFracNA_CEx = new Spline(&data_NA, "ke:pA_cex"); + fFracNA_Abs = new Spline(&data_NA, "ke:pA_abs"); + fFracNA_PiPro = new Spline(&data_NA, "ke:pA_pipro"); + + fFracPA_Cmp = new Spline(&data_NA, "ke:pA_cmp"); //cmp - add support later + fFracNA_Cmp = new Spline(&data_NA, "ke:pA_cmp"); + + // K+A x-section fraction splines + fFracKA_Tot = new Spline(&data_KA, "ke:KA_tot"); + fFracKA_Elas = new Spline(&data_KA, "ke:KA_elas"); + fFracKA_CEx = 0; // new Spline(&data_KA, "ke:KA_cex"); //Added, but needs to be computed + fFracKA_Inel = new Spline(&data_KA, "ke:KA_inel"); + fFracKA_Abs = new Spline(&data_KA, "ke:KA_abs"); + // + // hN stuff + // + + + // kIHNFtElas + // pp, nn --> read from pp/pp%.txt + // pn, np --> read from pp/pn%.txt + // pi+ N --> read from pip/pip%.txt + // pi0 N --> read from pip/pip%.txt + // pi- N --> read from pim/pim%.txt + // K+ N --> read from kpn/kpn%.txt + // K+ P --> read from kpp/kpp%.txt + // kIHNFtCEx + // pi+, pi0, pi- --> read from pie/pie%.txt (using pip+n->pi0+p data) + // kIHNFtAbs + // pi+, pi0, pi- --> read from pid2p/pid2p%.txt (using pip+D->2p data) + // kIHNFtInelas + // gamma p -> p pi0 --> read from gampi0p/%-pi0p.txt + // gamma p -> n pi+ --> read from gampi+n/%-pi+n.txt + // gamma n -> n pi0 --> read from gampi0n/%-pi0n.txt + // gamma n -> p pi- --> read from gampi-p/%-pi-p.txt + + + // kIHNFtElas, pp&nn : + { + const int hN_ppelas_nfiles = 20; + const int hN_ppelas_points_per_file = 21; + const int hN_ppelas_npoints = hN_ppelas_points_per_file * hN_ppelas_nfiles; + + double hN_ppelas_energies[hN_ppelas_nfiles] = { + 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, + 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000 + }; + + double hN_ppelas_costh [hN_ppelas_points_per_file]; + double hN_ppelas_xsec [hN_ppelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_ppelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_ppelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/pp/pp" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_ppelas_points_per_file, + ipoint, hN_ppelas_costh, hN_ppelas_xsec,2); + }//loop over files + + fhN2dXSecPP_Elas = new BLI2DNonUnifGrid(hN_ppelas_nfiles,hN_ppelas_points_per_file, + hN_ppelas_energies,hN_ppelas_costh,hN_ppelas_xsec); + } + + // kIHNFtElas, pn&np : + { + const int hN_npelas_nfiles = 20; + const int hN_npelas_points_per_file = 21; + const int hN_npelas_npoints = hN_npelas_points_per_file * hN_npelas_nfiles; + + double hN_npelas_energies[hN_npelas_nfiles] = { + 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, + 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000 + }; + + double hN_npelas_costh [hN_npelas_points_per_file]; + double hN_npelas_xsec [hN_npelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_npelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_npelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/pn/pn" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_npelas_points_per_file, + ipoint, hN_npelas_costh, hN_npelas_xsec,2); + }//loop over files + + fhN2dXSecNP_Elas = new BLI2DNonUnifGrid(hN_npelas_nfiles,hN_npelas_points_per_file, + hN_npelas_energies,hN_npelas_costh,hN_npelas_xsec); + } + + // kIHNFtElas, pipN : + { + const int hN_pipNelas_nfiles = 60; + const int hN_pipNelas_points_per_file = 21; + const int hN_pipNelas_npoints = hN_pipNelas_points_per_file * hN_pipNelas_nfiles; + + double hN_pipNelas_energies[hN_pipNelas_nfiles] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, + 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, + 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, + 300, 340, 380, 420, 460, 500, 540, 580, 620, 660, + 700, 740, 780, 820, 860, 900, 940, 980, + 1020, 1060, 1100, 1140, 1180, 1220, 1260, + 1300, 1340, 1380, 1420, 1460, 1500 + }; + + double hN_pipNelas_costh [hN_pipNelas_points_per_file]; + double hN_pipNelas_xsec [hN_pipNelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_pipNelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_pipNelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/pip/pip" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_pipNelas_points_per_file, + ipoint, hN_pipNelas_costh, hN_pipNelas_xsec,2); + }//loop over files + + fhN2dXSecPipN_Elas = new BLI2DNonUnifGrid(hN_pipNelas_nfiles,hN_pipNelas_points_per_file, + hN_pipNelas_energies,hN_pipNelas_costh,hN_pipNelas_xsec); + } + + // kIHNFtElas, pi0N : + { + const int hN_pi0Nelas_nfiles = 60; + const int hN_pi0Nelas_points_per_file = 21; + const int hN_pi0Nelas_npoints = hN_pi0Nelas_points_per_file * hN_pi0Nelas_nfiles; + + double hN_pi0Nelas_energies[hN_pi0Nelas_nfiles] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, + 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, + 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, + 300, 340, 380, 420, 460, 500, 540, 580, 620, 660, + 700, 740, 780, 820, 860, 900, 940, 980, + 1020, 1060, 1100, 1140, 1180, 1220, 1260, + 1300, 1340, 1380, 1420, 1460, 1500 + }; + + double hN_pi0Nelas_costh [hN_pi0Nelas_points_per_file]; + double hN_pi0Nelas_xsec [hN_pi0Nelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_pi0Nelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_pi0Nelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/pip/pip" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_pi0Nelas_points_per_file, + ipoint, hN_pi0Nelas_costh, hN_pi0Nelas_xsec,2); + }//loop over files + + fhN2dXSecPi0N_Elas = new BLI2DNonUnifGrid(hN_pi0Nelas_nfiles,hN_pi0Nelas_points_per_file, + hN_pi0Nelas_energies,hN_pi0Nelas_costh,hN_pi0Nelas_xsec); + } + + // kIHNFtElas, pimN : + { + const int hN_pimNelas_nfiles = 60; + const int hN_pimNelas_points_per_file = 21; + const int hN_pimNelas_npoints = hN_pimNelas_points_per_file * hN_pimNelas_nfiles; + + double hN_pimNelas_energies[hN_pimNelas_nfiles] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, + 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, + 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, + 300, 340, 380, 420, 460, 500, 540, 580, 620, 660, + 700, 740, 780, 820, 860, 900, 940, 980, + 1020, 1060, 1100, 1140, 1180, 1220, 1260, + 1300, 1340, 1380, 1420, 1460, 1500 + }; + + double hN_pimNelas_costh [hN_pimNelas_points_per_file]; + double hN_pimNelas_xsec [hN_pimNelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_pimNelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_pimNelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/pim/pim" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_pimNelas_points_per_file, + ipoint, hN_pimNelas_costh, hN_pimNelas_xsec,2); + }//loop over files + + fhN2dXSecPimN_Elas = new BLI2DNonUnifGrid(hN_pimNelas_nfiles,hN_pimNelas_points_per_file, + hN_pimNelas_energies,hN_pimNelas_costh,hN_pimNelas_xsec); + } + + // kIHNFtElas, kpn : + { + const int hN_kpNelas_nfiles = 18; + const int hN_kpNelas_points_per_file = 37; + const int hN_kpNelas_npoints = hN_kpNelas_points_per_file * hN_kpNelas_nfiles; + + double hN_kpNelas_energies[hN_kpNelas_nfiles] = { + 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, + 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800 + }; + + double hN_kpNelas_costh [hN_kpNelas_points_per_file]; + double hN_kpNelas_xsec [hN_kpNelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_kpNelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_kpNelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/kpn/kpn" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_kpNelas_points_per_file, + ipoint, hN_kpNelas_costh, hN_kpNelas_xsec,2); + }//loop over files + + fhN2dXSecKpN_Elas = new BLI2DNonUnifGrid(hN_kpNelas_nfiles,hN_kpNelas_points_per_file, + hN_kpNelas_energies,hN_kpNelas_costh,hN_kpNelas_xsec); + } + // kIHNFtCEx, kpn : + { + const int hN_kpNcex_nfiles = 18; + const int hN_kpNcex_points_per_file = 37; + const int hN_kpNcex_npoints = hN_kpNcex_points_per_file * hN_kpNcex_nfiles; + + double hN_kpNcex_energies[hN_kpNcex_nfiles] = { + 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, + 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800 + }; + + double hN_kpNcex_costh [hN_kpNcex_points_per_file]; + double hN_kpNcex_xsec [hN_kpNcex_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_kpNcex_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_kpNcex_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/kpncex/kpcex" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_kpNcex_points_per_file, + ipoint, hN_kpNcex_costh, hN_kpNcex_xsec,2); + }//loop over files + + /*double hN_kpNcex_costh_cond [hN_kpNcex_points_per_file]; + for (int ient = 0; ient < hN_kpNcex_points_per_file; ient++) { + hN_kpNcex_costh_cond[ient] = hN_kpNcex_costh[ient]; + }*/ + + fhN2dXSecKpN_CEx = new BLI2DNonUnifGrid(hN_kpNcex_nfiles,hN_kpNcex_points_per_file, + hN_kpNcex_energies,hN_kpNcex_costh,hN_kpNcex_xsec); + } +//---------------------------------------------------------------------------------------- + + + // kIHNFtElas, kpp : + { + const int hN_kpPelas_nfiles = 18; + const int hN_kpPelas_points_per_file = 37; + const int hN_kpPelas_npoints = hN_kpPelas_points_per_file * hN_kpPelas_nfiles; + + double hN_kpPelas_energies[hN_kpPelas_nfiles] = { + 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, + 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800 + }; + + double hN_kpPelas_costh [hN_kpPelas_points_per_file]; + double hN_kpPelas_xsec [hN_kpPelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_kpPelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_kpPelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/kpp/kpp" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_kpPelas_points_per_file, + ipoint, hN_kpPelas_costh, hN_kpPelas_xsec,2); + }//loop over files + + fhN2dXSecKpP_Elas = new BLI2DNonUnifGrid(hN_kpPelas_nfiles,hN_kpPelas_points_per_file, + hN_kpPelas_energies,hN_kpPelas_costh,hN_kpPelas_xsec); + } + + // kIHNFtCEx, (pi+, pi0, pi-) N + { + const int hN_piNcex_nfiles = 60; + const int hN_piNcex_points_per_file = 21; + const int hN_piNcex_npoints = hN_piNcex_points_per_file * hN_piNcex_nfiles; + + double hN_piNcex_energies[hN_piNcex_nfiles] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, + 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, + 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, + 300, 340, 380, 420, 460, 500, 540, 580, 620, 660, + 700, 740, 780, 820, 860, 900, 940, 980, + 1020, 1060, 1100, 1140, 1180, 1220, 1260, + 1300, 1340, 1380, 1420, 1460, 1500 + }; + + double hN_piNcex_costh [hN_piNcex_points_per_file]; + double hN_piNcex_xsec [hN_piNcex_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_piNcex_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_piNcex_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/pie/pie" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_piNcex_points_per_file, + ipoint, hN_piNcex_costh, hN_piNcex_xsec,2); + }//loop over files + + fhN2dXSecPiN_CEx = new BLI2DNonUnifGrid(hN_piNcex_nfiles,hN_piNcex_points_per_file, + hN_piNcex_energies,hN_piNcex_costh,hN_piNcex_xsec); + } + + // kIHNFtAbs, (pi+, pi0, pi-) N + { + const int hN_piNabs_nfiles = 19; + const int hN_piNabs_points_per_file = 21; + const int hN_piNabs_npoints = hN_piNabs_points_per_file * hN_piNabs_nfiles; + + double hN_piNabs_energies[hN_piNabs_nfiles] = { + 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, + 300, 325, 350, 375, 400, 425, 450, 475, 500 + }; + + double hN_piNabs_costh [hN_piNabs_points_per_file]; + double hN_piNabs_xsec [hN_piNabs_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_piNabs_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_piNabs_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/pid2p/pid2p" << ke << ".txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_piNabs_points_per_file, + ipoint, hN_piNabs_costh, hN_piNabs_xsec,2); + }//loop over files + + fhN2dXSecPiN_Abs = new BLI2DNonUnifGrid(hN_piNabs_nfiles,hN_piNabs_points_per_file, + hN_piNabs_energies,hN_piNabs_costh,hN_piNabs_xsec); + } + + // kIHNFtInelas, gamma p -> p pi0 + { + const int hN_gampi0pInelas_nfiles = 29; + const int hN_gampi0pInelas_points_per_file = 37; + const int hN_gampi0pInelas_npoints = hN_gampi0pInelas_points_per_file * hN_gampi0pInelas_nfiles; + + double hN_gampi0pInelas_energies[hN_gampi0pInelas_nfiles] = { + 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, + 360, 380, 400, 450, 500, 550, 600, 650, 700, 750, + 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200 + }; + + double hN_gampi0pInelas_costh [hN_gampi0pInelas_points_per_file]; + double hN_gampi0pInelas_xsec [hN_gampi0pInelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_gampi0pInelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_gampi0pInelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/gampi0p/" << ke << "-pi0p.txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_gampi0pInelas_points_per_file, + ipoint, hN_gampi0pInelas_costh, hN_gampi0pInelas_xsec,3); + }//loop over files + + fhN2dXSecGamPi0P_Inelas = new BLI2DNonUnifGrid(hN_gampi0pInelas_nfiles,hN_gampi0pInelas_points_per_file, + hN_gampi0pInelas_energies,hN_gampi0pInelas_costh,hN_gampi0pInelas_xsec); + } + + // kIHNFtInelas, gamma n -> n pi0 + { + const int hN_gampi0nInelas_nfiles = 29; + const int hN_gampi0nInelas_points_per_file = 37; + const int hN_gampi0nInelas_npoints = hN_gampi0nInelas_points_per_file * hN_gampi0nInelas_nfiles; + + double hN_gampi0nInelas_energies[hN_gampi0nInelas_nfiles] = { + 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, + 360, 380, 400, 450, 500, 550, 600, 650, 700, 750, + 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200 + }; + + double hN_gampi0nInelas_costh [hN_gampi0nInelas_points_per_file]; + double hN_gampi0nInelas_xsec [hN_gampi0nInelas_npoints]; + int ipoint=0; + + for(int ifile = 0; ifile < hN_gampi0nInelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_gampi0nInelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/gampi0n/" << ke << "-pi0n.txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_gampi0nInelas_points_per_file, + ipoint, hN_gampi0nInelas_costh, hN_gampi0nInelas_xsec,3); + }//loop over files + + fhN2dXSecGamPi0N_Inelas = new BLI2DNonUnifGrid(hN_gampi0nInelas_nfiles,hN_gampi0nInelas_points_per_file, + hN_gampi0nInelas_energies,hN_gampi0nInelas_costh,hN_gampi0nInelas_xsec); + } + + // kIHNFtInelas, gamma p -> n pi+ + { + const int hN_gampipnInelas_nfiles = 29; + const int hN_gampipnInelas_points_per_file = 37; + const int hN_gampipnInelas_npoints = hN_gampipnInelas_points_per_file * hN_gampipnInelas_nfiles; + + double hN_gampipnInelas_energies[hN_gampipnInelas_nfiles] = { + 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, + 360, 380, 400, 450, 500, 550, 600, 650, 700, 750, + 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200 + }; + + double hN_gampipnInelas_costh [hN_gampipnInelas_points_per_file]; + double hN_gampipnInelas_xsec [hN_gampipnInelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_gampipnInelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_gampipnInelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/gampi+n/" << ke << "-pi+n.txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_gampipnInelas_points_per_file, + ipoint, hN_gampipnInelas_costh, hN_gampipnInelas_xsec,3); + }//loop over files + + fhN2dXSecGamPipN_Inelas = new BLI2DNonUnifGrid(hN_gampipnInelas_nfiles,hN_gampipnInelas_points_per_file, + hN_gampipnInelas_energies,hN_gampipnInelas_costh,hN_gampipnInelas_xsec); + } + + // kIHNFtInelas, gamma n -> p pi- + { + const int hN_gampimpInelas_nfiles = 29; + const int hN_gampimpInelas_points_per_file = 37; + const int hN_gampimpInelas_npoints = hN_gampimpInelas_points_per_file * hN_gampimpInelas_nfiles; + + double hN_gampimpInelas_energies[hN_gampimpInelas_nfiles] = { + 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, + 360, 380, 400, 450, 500, 550, 600, 650, 700, 750, + 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200 + }; + + double hN_gampimpInelas_costh [hN_gampimpInelas_points_per_file]; + double hN_gampimpInelas_xsec [hN_gampimpInelas_npoints]; + + int ipoint=0; + + for(int ifile = 0; ifile < hN_gampimpInelas_nfiles; ifile++) { + // build filename + ostringstream hN_datafile; + double ke = hN_gampimpInelas_energies[ifile]; + hN_datafile << data_dir << "/diff_ang/gampi-p/" << ke << "-pi-p.txt"; + // read data + ReadhNFile( + hN_datafile.str(), ke, hN_gampimpInelas_points_per_file, + ipoint, hN_gampimpInelas_costh, hN_gampimpInelas_xsec,3); + }//loop over files + + fhN2dXSecGamPimP_Inelas = new BLI2DNonUnifGrid(hN_gampimpInelas_nfiles,hN_gampimpInelas_points_per_file, + hN_gampimpInelas_energies,hN_gampimpInelas_costh,hN_gampimpInelas_xsec); + } + + + + + TFile TGraphs_file; + bool saveTGraphsToFile = false; //true; + + if (saveTGraphsToFile) { + string filename = "TGraphs.root"; + LOG("INukeHadroData2025", pNOTICE) << "Saving INTRANUKE hadron x-section data to ROOT file: " << filename; + TGraphs_file.Open(filename.c_str(), "RECREATE"); + } + + + // kIHNFtTot, pip + A PipA_Tot used for hA2025 - this is total reaction cross section - sd + { + const int pipATot_nfiles = 7; + const int pipATot_nuclei[pipATot_nfiles] = {12,27 ,3,56, 93,209,7}; + const int pipATot_npoints = 294; + + TPipA_Tot = new TGraph2D(pipATot_npoints); + TPipA_Tot->SetNameTitle("TPipA_Tot","TPipA_Tot"); + TPipA_Tot->SetDirectory(0); + + int ipoint=0; + double x, y; + + for(int ifile=0; ifile < pipATot_nfiles; ifile++) { + ostringstream ADep_datafile; + int nucleus = pipATot_nuclei[ifile]; + ADep_datafile << data_dir << "/tot_xsec/2025/pipA_tot/pip" << nucleus << "_tot.txt"; + TGraph * buff = new TGraph(ADep_datafile.str().c_str()); + buff->SetNameTitle("buff","buff"); + for(int i=0; i < buff->GetN(); i++) { + buff -> GetPoint(i,x,y); + if (y > 0) { + TPipA_Tot->SetPoint(ipoint, (double)nucleus, x, log(y)); + ipoint++; + } + + } + delete buff; + } + + if (saveTGraphsToFile) { + TPipA_Tot -> Write("TPipA_Tot"); // TPipA_Tot will be _key_ name + } + } + + + // kIHNFtAbs, pip + A PipA_Abs_frac + + // kIHNFtCEx, pip + A PipA_CEx total pi+ charge exchange cross section - used in hA2025 - sd + { + + + const int pipACEx_nfiles = 7; + const int pipACEx_nuclei[pipACEx_nfiles] = {3, 27 , 12 , 56 , 93 , 209 , 7}; + const int pipACEx_npoints = 294; + + TPipA_CEx = new TGraph2D(pipACEx_npoints); + TPipA_CEx->SetNameTitle("TPipA_CEx","TPipA_CEx"); + TPipA_CEx->SetDirectory(0); + + int ipoint=0; + double x, y; + + for(int ifile=0; ifile < pipACEx_nfiles; ifile++) { + ostringstream ADep_datafile; + int nucleus = pipACEx_nuclei[ifile]; + ADep_datafile << data_dir << "/tot_xsec/2025/pipA_cex/pip" << nucleus << "_cex.txt"; + TGraph * buff = new TGraph(ADep_datafile.str().c_str()); + buff->SetNameTitle("buff","buff"); + for(int i=0; i < buff->GetN(); i++) { + buff -> GetPoint(i,x,y); + if(y>0){ + TPipA_CEx -> SetPoint(ipoint,(double)nucleus,x,log(y)); + ipoint++; + } + } + delete buff; + } + + if (saveTGraphsToFile) { + TPipA_CEx -> Write("TPipA_CEx"); + } + + + } + + // kIHNFtAbs, pip + A PipA_Abs used in hA2025 - sd + { + + const int pipAAbs_nfiles = 7; + const int pipAAbs_nuclei[pipAAbs_nfiles] = {3, 27 , 12 , 56 , 93 , 209 , 7}; + const int pipAAbs_npoints = 294; + + TPipA_Abs = new TGraph2D(pipAAbs_npoints); + TPipA_Abs->SetNameTitle("TPipA_Abs","TPipA_Abs"); + TPipA_Abs->SetDirectory(0); + + int ipoint=0; + double x, y; + + for(int ifile=0; ifile < pipAAbs_nfiles; ifile++) { + ostringstream ADep_datafile; + int nucleus = pipAAbs_nuclei[ifile]; + ADep_datafile << data_dir << "/tot_xsec/2025/pipA_abs/pip" << nucleus << "_abs.txt"; + TGraph * buff = new TGraph(ADep_datafile.str().c_str()); + buff->SetNameTitle("buff","buff"); + for(int i=0; i < buff->GetN(); i++) { + buff -> GetPoint(i,x,y); + if(y>0){ + TPipA_Abs -> SetPoint(ipoint,(double)nucleus,x,log(y)); + ipoint++; + } + } + delete buff; + } + + if (saveTGraphsToFile) { + TPipA_Abs -> Write("TPipA_Abs"); + } + + } + + // kIHNFtInelas, pip + A PipA_Inelas used in hA2025 - sd + { + + const int pipAInelas_nfiles = 7; + const int pipAInelas_nuclei[pipAInelas_nfiles] = {3, 27 , 12 , 56 , 93 , 209 , 7}; + const int pipAInelas_npoints = 294; + + TPipA_Inelas = new TGraph2D(pipAInelas_npoints); + TPipA_Inelas->SetNameTitle("TPipA_Inelas","TPipA_Inelas"); + TPipA_Inelas->SetDirectory(0); + + int ipoint=0; + double x, y; + + for(int ifile=0; ifile < pipAInelas_nfiles; ifile++) { + ostringstream ADep_datafile; + int nucleus = pipAInelas_nuclei[ifile]; + ADep_datafile << data_dir << "/tot_xsec/2025/pipA_inelas/pip" << nucleus << "_inelas.txt"; + TGraph * buff = new TGraph(ADep_datafile.str().c_str()); + buff->SetNameTitle("buff","buff"); + for(int i=0; i < buff->GetN(); i++) { + buff -> GetPoint(i,x,y); + if(y>0){ + TPipA_Inelas -> SetPoint(ipoint,(double)nucleus,x,log(y)); + ipoint++; + } + } + delete buff; + } + + if (saveTGraphsToFile) { + TPipA_Inelas -> Write("TPipA_Inelas"); + } + } + + // kIHNFtPiPro, pip + A PipA_pipro used in hA2025 - sd + { + + const int pipApipro_nfiles = 6; + const int pipApipro_nuclei[pipApipro_nfiles] = { 27 , 12 , 56 , 93 , 209 , 7}; + const int pipAInelas_npoints = 252; + + TPipA_PiPro = new TGraph2D(pipAInelas_npoints); + TPipA_PiPro->SetNameTitle("TPipA_PiPro","TPipA_PiPro"); + TPipA_PiPro->SetDirectory(0); + + int ipoint=0; + double x, y; + + for(int ifile=0; ifile < pipApipro_nfiles; ifile++) { + ostringstream ADep_datafile; + int nucleus = pipApipro_nuclei[ifile]; + ADep_datafile << data_dir << "/tot_xsec/2025/pipA_pipro/pip" << nucleus << "_pipro.txt"; + TGraph * buff = new TGraph(ADep_datafile.str().c_str()); + buff->SetNameTitle("buff","buff"); + for(int i=0; i < buff->GetN(); i++) { + buff -> GetPoint(i,x,y); + if(y>0){ + TPipA_PiPro -> SetPoint(ipoint,(double)nucleus,x,log(y)); + ipoint++; + } + } + delete buff; + } + + if (saveTGraphsToFile) { + TPipA_PiPro -> Write("TPipA_PiPro"); + } + } + + TGraphs_file.Close(); + + LOG("INukeData", pINFO) << "Done building x-section splines..."; + +} + +//____________________________________________________________________________ +void INukeHadroData2025::ReadhNFile( + string filename, double ke, int npoints, int & curr_point, + double * costh_array, double * xsec_array, int cols) +{ + // open + std::ifstream hN_stream(filename.c_str(), ios::in); + if(!hN_stream.good()) { + LOG("INukeData", pERROR) + << "Error reading INTRANUKE/hN data from: " << filename; + return; + } + + if(cols<2) { + LOG("INukeData", pERROR) + << "Error reading INTRANUKE/hN data from: " << filename; + LOG("INukeData", pERROR) + << "Too few columns: " << cols; + return; + } + + LOG("INukeData", pINFO) + << "Reading INTRANUKE/hN data from: " << filename; + + // skip initial comments + char cbuf[501]; + hN_stream.getline(cbuf,400); + hN_stream.getline(cbuf,400); + hN_stream.getline(cbuf,400); + + // read + double angle = 0; + double xsec = 0; + double trash = 0; + + for(int ip = 0; ip < npoints; ip++) { + hN_stream >> angle >> xsec; + + for(int ic = 0; ic < (cols-2); ic++) { + hN_stream >> trash; + } + + LOG("INukeData", pDEBUG) + << "Adding data point: (KE = " << ke << " MeV, angle = " + << angle << ", sigma = " << xsec << " mbarn)"; + costh_array[ip] = TMath::Cos(angle*kPi/180.); + xsec_array [curr_point] = xsec; + curr_point++; + } +} +//____________________________________________________________________________ +double INukeHadroData2025::XSec( + int hpdgc, int tgtpdgc, int nppdgc, INukeFateHN_t fate, double ke, double costh) const +{ +// inputs +// fate : h+N fate code +// hpdgc : h PDG code +// tgtpdgc : N PDG code +// nppdgc : product N PDG code +// ke : kinetic energy (MeV) +// costh : cos(scattering angle) +// returns +// xsec : mbarn + + double ke_eval = ke; + double costh_eval = costh; + + costh_eval = TMath::Min(costh, 1.); + costh_eval = TMath::Max(costh_eval, -1.); + + if(fate==kIHNFtElas) { + + if( (hpdgc==kPdgProton && tgtpdgc==kPdgProton) || + (hpdgc==kPdgNeutron && tgtpdgc==kPdgNeutron) ) + { + ke_eval = TMath::Min(ke_eval, 999.); + ke_eval = TMath::Max(ke_eval, 50.); + return fhN2dXSecPP_Elas->Evaluate(ke_eval, costh_eval); + } + else + if( (hpdgc==kPdgProton && tgtpdgc==kPdgNeutron) || + (hpdgc==kPdgNeutron && tgtpdgc==kPdgProton) ) + { + ke_eval = TMath::Min(ke_eval, 999.); + ke_eval = TMath::Max(ke_eval, 50.); + return fhN2dXSecNP_Elas->Evaluate(ke_eval, costh_eval); + } + else + if(hpdgc==kPdgPiP) + { + ke_eval = TMath::Min(ke_eval, 1499.); + ke_eval = TMath::Max(ke_eval, 10.); + return fhN2dXSecPipN_Elas->Evaluate(ke_eval, costh_eval); + } + else + if(hpdgc==kPdgPi0) + { + ke_eval = TMath::Min(ke_eval, 1499.); + ke_eval = TMath::Max(ke_eval, 10.); + return fhN2dXSecPi0N_Elas->Evaluate(ke_eval, costh_eval); + } + else + if(hpdgc==kPdgPiM) + { + ke_eval = TMath::Min(ke_eval, 1499.); + ke_eval = TMath::Max(ke_eval, 10.); + return fhN2dXSecPimN_Elas->Evaluate(ke_eval, costh_eval); + } + else + if(hpdgc==kPdgKP && tgtpdgc==kPdgNeutron) + { + ke_eval = TMath::Min(ke_eval, 1799.); + ke_eval = TMath::Max(ke_eval, 100.); + return fhN2dXSecKpN_Elas->Evaluate(ke_eval, costh_eval); + } + else + if(hpdgc==kPdgKP && tgtpdgc==kPdgProton) + { + ke_eval = TMath::Min(ke_eval, 1799.); + ke_eval = TMath::Max(ke_eval, 100.); + return fhN2dXSecKpP_Elas->Evaluate(ke_eval, costh_eval); + } + } + + else if(fate == kIHNFtCEx) { + if( (hpdgc==kPdgPiP || hpdgc==kPdgPi0 || hpdgc==kPdgPiM) && + (tgtpdgc==kPdgProton || tgtpdgc==kPdgNeutron) ) + { + ke_eval = TMath::Min(ke_eval, 1499.); + ke_eval = TMath::Max(ke_eval, 10.); + return fhN2dXSecPiN_CEx->Evaluate(ke_eval, costh_eval); + } + else if( (hpdgc == kPdgProton && tgtpdgc == kPdgProton) || + (hpdgc == kPdgNeutron && tgtpdgc == kPdgNeutron) ) + { + ke_eval = TMath::Min(ke_eval, 999.); + ke_eval = TMath::Max(ke_eval, 50.); + return fhN2dXSecPP_Elas->Evaluate(ke_eval, costh_eval); + } + else if( (hpdgc == kPdgProton && tgtpdgc == kPdgNeutron) || + (hpdgc == kPdgNeutron && tgtpdgc == kPdgProton) ) + { + ke_eval = TMath::Min(ke_eval, 999.); + ke_eval = TMath::Max(ke_eval, 50.); + return fhN2dXSecNP_Elas->Evaluate(ke_eval, costh_eval); + } + else if(hpdgc == kPdgKP && tgtpdgc == kPdgNeutron) { + ke_eval = TMath::Min(ke_eval, 1799.); + ke_eval = TMath::Max(ke_eval, 100.); + return fhN2dXSecKpN_CEx->Evaluate(ke_eval, costh_eval); + } + } + + else if(fate == kIHNFtAbs) { + if( (hpdgc==kPdgPiP || hpdgc==kPdgPi0 || hpdgc==kPdgPiM) && + (tgtpdgc==kPdgProton || tgtpdgc==kPdgNeutron) ) + { + ke_eval = TMath::Min(ke_eval, 499.); + ke_eval = TMath::Max(ke_eval, 50.); + return fhN2dXSecPiN_Abs->Evaluate(ke_eval, costh_eval); + } + if(hpdgc==kPdgKP) return 1.; //isotropic since no data ??? + } + + else if(fate == kIHNFtInelas) { + if( hpdgc==kPdgGamma && tgtpdgc==kPdgProton &&nppdgc==kPdgProton ) + { + ke_eval = TMath::Min(ke_eval, 1199.); + ke_eval = TMath::Max(ke_eval, 160.); + return fhN2dXSecGamPi0P_Inelas->Evaluate(ke_eval, costh_eval); + } + else + if( hpdgc==kPdgGamma && tgtpdgc==kPdgProton && nppdgc==kPdgNeutron ) + { + ke_eval = TMath::Min(ke_eval, 1199.); + ke_eval = TMath::Max(ke_eval, 160.); + return fhN2dXSecGamPipN_Inelas->Evaluate(ke_eval, costh_eval); + } + else + if( hpdgc==kPdgGamma && tgtpdgc==kPdgNeutron && nppdgc==kPdgProton ) + { + ke_eval = TMath::Min(ke_eval, 1199.); + ke_eval = TMath::Max(ke_eval, 160.); + return fhN2dXSecGamPimP_Inelas->Evaluate(ke_eval, costh_eval); + } + else + if( hpdgc==kPdgGamma && tgtpdgc==kPdgNeutron && nppdgc==kPdgNeutron ) + { + ke_eval = TMath::Min(ke_eval, 1199.); + ke_eval = TMath::Max(ke_eval, 160.); + return fhN2dXSecGamPi0N_Inelas->Evaluate(ke_eval, costh_eval); + } + } + + return 0; +} +//____________________________________________________________________________ +double INukeHadroData2025::FracADep(int hpdgc, INukeFateHA_t fate, double ke, int targA) const +{ + // return the x-section fraction for the input fate for the particle with the input pdg + // code and the target with the input mass number at the input kinetic energy + + ke = TMath::Max(fMinKinEnergy, ke); // ke >= 1 MeV + ke = TMath::Min(fMaxKinEnergyHA, ke); // ke <= 999 MeV + + targA = TMath::Min(208, targA); // A <= 208 + + LOG("INukeData", pDEBUG) << "Querying hA cross section at ke = " << ke << " and target " << targA; + + // Handle pions (currently the same cross sections are used for pi+, pi-, and pi0) + if ( hpdgc == kPdgPiP || hpdgc == kPdgPiM || hpdgc == kPdgPi0 ) { + // get log fate cross sections + double log_cex_xs = TPipA_CEx->Interpolate(targA, ke); + double log_inelas_xs = TPipA_Inelas->Interpolate(targA, ke); + double log_abs_xs = TPipA_Abs->Interpolate(targA, ke); + double log_pipro_xs = TPipA_PiPro->Interpolate(targA, ke); + double log_tot_xs = TPipA_Tot->Interpolate(targA, ke); + + + // get cross sections + double cex_xs = exp(log_cex_xs); + double inelas_xs = exp(log_inelas_xs); + double abs_xs = exp(log_abs_xs); + double pipro_xs = exp(log_pipro_xs); + double tot_xs = exp(log_tot_xs); + + // construct ratios + + double frac_cex = cex_xs / tot_xs ; + double frac_inelas = inelas_xs / tot_xs ; + double frac_abs = abs_xs / tot_xs ; + double frac_pipro = pipro_xs / tot_xs ; + + + + // Protect against unitarity violation due to interpolation problems + // by renormalizing all available fate fractions to unity. + double total = frac_cex + frac_inelas + frac_abs + frac_pipro; // + frac_elas + + if ( fate == kIHAFtCEx ) return frac_cex / total; + else if ( fate == kIHAFtInelas ) return frac_inelas / total; + else if ( fate == kIHAFtAbs ) return frac_abs / total; + else if ( fate == kIHAFtPiProd ) return frac_pipro / total; + else { + std::string sign("+"); + if ( hpdgc == kPdgPiM ) sign = "-"; + else if ( hpdgc == kPdgPi0 ) sign = "0"; + LOG("INukeData", pWARN) << "Pi" << sign << "'s don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0.; + } + } + + LOG("INukeData", pWARN) << "Can't handle particles with pdg code = " << hpdgc; + return 0.; +} +//____________________________________________________________________________ +double INukeHadroData2025::FracAIndep(int hpdgc, INukeFateHA_t fate, double ke) const +{ + // return the x-section fraction for the input fate for the particle with the input pdg + // code at the input kinetic energy + ke = TMath::Max(fMinKinEnergy, ke); + ke = TMath::Min(fMaxKinEnergyHA, ke); + + LOG("INukeData", pDEBUG) << "Querying hA cross section at ke = " << ke; + + // TODO: reduce code duplication here + if (hpdgc == kPdgProton) { + // handle protons + double frac_cex = fFracPA_CEx->Evaluate(ke); + double frac_inelas = fFracPA_Inel->Evaluate(ke); + double frac_abs = fFracPA_Abs->Evaluate(ke); + double frac_pipro = fFracPA_PiPro->Evaluate(ke); + double frac_comp = fFracPA_Cmp->Evaluate(ke); + + // Protect against unitarity violation due to interpolation problems + // by renormalizing all available fate fractions to unity. + double total = frac_cex + frac_inelas + frac_abs + frac_pipro + frac_comp; // + frac_elas + + if ( fate == kIHAFtCEx ) return frac_cex / total; + //else if ( fate == kIHAFtElas ) return frac_elas / total; + else if ( fate == kIHAFtInelas ) return frac_inelas / total; + else if ( fate == kIHAFtAbs ) return frac_abs / total; + else if ( fate == kIHAFtPiProd ) return frac_pipro / total; + else if ( fate == kIHAFtCmp ) return frac_comp / total; // cmp - add support for this later + else { + LOG("INukeData", pWARN) + << "Protons don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + } + else if (hpdgc == kPdgNeutron) { + // handle neutrons + double frac_cex = fFracNA_CEx->Evaluate(ke); + double frac_inelas = fFracNA_Inel->Evaluate(ke); + double frac_abs = fFracNA_Abs->Evaluate(ke); + double frac_pipro = fFracNA_PiPro->Evaluate(ke); + double frac_comp = fFracNA_Cmp->Evaluate(ke); + + // Protect against unitarity violation due to interpolation problems + // by renormalizing all available fate fractions to unity. + double total = frac_cex + frac_inelas + frac_abs + frac_pipro + frac_comp; // + frac_elas + + if ( fate == kIHAFtCEx ) return frac_cex / total; + //else if ( fate == kIHAFtElas ) return frac_elas / total; + else if ( fate == kIHAFtInelas ) return frac_inelas / total; + else if ( fate == kIHAFtAbs ) return frac_abs / total; + else if ( fate == kIHAFtPiProd ) return frac_pipro / total; + else if ( fate == kIHAFtCmp ) return frac_comp / total; // cmp - add support for this later + else { + LOG("INukeData", pWARN) + << "Neutrons don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + } + else if (hpdgc == kPdgKP) { + // handle K+ + double frac_inelas = fFracKA_Inel->Evaluate(ke); + //double frac_elas = fFracKA_Elas->Evaluate(ke); + double frac_abs = fFracKA_Abs->Evaluate(ke); + + // Protect against unitarity violation due to interpolation problems + // by renormalizing all available fate fractions to unity. + double total = frac_inelas + frac_abs; // + frac_elas + + if ( fate == kIHAFtInelas ) return frac_inelas / total; + else if ( fate == kIHAFtAbs ) return frac_abs / total; + else { + LOG("INukeData", pWARN) + << "K+'s don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0.; + } + } + LOG("INukeData", pWARN) << "Can't handle particles with pdg code = " << hpdgc; + return 0.; +} +//____________________________________________________________________________ +double INukeHadroData2025::XSec(int hpdgc, INukeFateHN_t fate, double ke, int targA, int targZ) const +{ +// return the x-section for the input fate for the particle with the input pdg +// code at the input kinetic energy +// + ke = TMath::Max(fMinKinEnergy, ke); + ke = TMath::Min(fMaxKinEnergyHN, ke); + + LOG("INukeData", pDEBUG) << "Querying hN cross section at ke = " << ke; + + double xsec=0; + + if (hpdgc == kPdgPiP) { + /* handle pi+ */ + if (fate == kIHNFtCEx ) {xsec = TMath::Max(0., fXSecPipp_CEx -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPipn_CEx -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtElas ) {xsec = TMath::Max(0., fXSecPipp_Elas -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPipn_Elas -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtInelas) {xsec = TMath::Max(0., fXSecPipp_Reac -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPipn_Reac -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtAbs ) {xsec = TMath::Max(0., fXSecPipd_Abs -> Evaluate(ke)) * targA; + return xsec;} + else { + LOG("INukeData", pWARN) + << "Pi+'s don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + + } else if (hpdgc == kPdgPiM) { + /* handle pi- */ + if (fate == kIHNFtCEx ) {xsec = TMath::Max(0., fXSecPipn_CEx -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPipp_CEx -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtElas ) {xsec = TMath::Max(0., fXSecPipn_Elas -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPipp_Elas -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtInelas) {xsec = TMath::Max(0., fXSecPipn_Reac -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPipp_Reac -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtAbs ) {xsec = TMath::Max(0., fXSecPipd_Abs -> Evaluate(ke)) * targA; + return xsec;} + else { + LOG("INukeData", pWARN) + << "Pi-'s don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + + } else if (hpdgc == kPdgPi0) { + /* handle pi0 */ + if (fate == kIHNFtCEx ) {xsec = TMath::Max(0., fXSecPi0p_CEx -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPi0n_CEx -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtElas ) {xsec = TMath::Max(0., fXSecPi0p_Elas -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPi0n_Elas -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtInelas) {xsec = TMath::Max(0., fXSecPi0p_Reac -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPi0n_Reac -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtAbs ) {xsec = TMath::Max(0., fXSecPi0d_Abs -> Evaluate(ke)) * targA; + return xsec;} + else { + LOG("INukeData", pWARN) + << "Pi0's don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + + } else if (hpdgc == kPdgProton) { + /* handle protons */ + if (fate == kIHNFtElas ) {xsec = TMath::Max(0., fXSecPp_Elas -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPn_Elas -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtInelas) {xsec = TMath::Max(0., fXSecPp_Reac -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPn_Reac -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtCmp) {xsec = TMath::Max(0., fXSecPp_Cmp -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPn_Cmp -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else { + LOG("INukeData", pWARN) + << "Protons don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + + } else if (hpdgc == kPdgNeutron) { + /* handle protons */ + if (fate == kIHNFtElas ) {xsec = TMath::Max(0., fXSecPn_Elas -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecNn_Elas -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtInelas) {xsec = TMath::Max(0., fXSecPn_Reac -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecNn_Reac -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtCmp) {xsec = TMath::Max(0., fXSecPp_Cmp -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecPn_Cmp -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else { + LOG("INukeData", pWARN) + << "Neutrons don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + //Adding here kaons, why elastic only on protons? hA or hN? No _Reac for kaons... + } else if (hpdgc == kPdgKP) { + /* handle K+ */ + if (fate == kIHNFtCEx ) {xsec = TMath::Max(0., fXSecKpn_CEx -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecKpn_CEx -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else if (fate == kIHNFtElas ) {xsec = TMath::Max(0., fXSecKpn_Elas -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecKpn_Elas -> Evaluate(ke)) * (targA-targZ); + return xsec;} + /*else if (fate == kIHNFtAbs ) {xsec = TMath::Max(0., fXSecKpd_Abs -> Evaluate(ke)) * targA; + return xsec;}*/ + else { + LOG("INukeData", pWARN) + << "K+'s don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + } + //------------------------------------------------ + /* } else if (hpdgc == kPdgGamma) { + / * handle gamma * / + if (fate == kIHNFtInelas) {xsec = TMath::Max(0., fXSecGamp_fs -> Evaluate(ke)) * targZ; + xsec+= TMath::Max(0., fXSecGamn_fs -> Evaluate(ke)) * (targA-targZ); + return xsec;} + else { + LOG("INukeData", pWARN) + << "Gamma's don't have this fate: " << INukeHadroFates2025::AsString(fate); + return 0; + }*/ + } + LOG("INukeData", pWARN) + << "Can't handle particles with pdg code = " << hpdgc; + + return 0; +} + +double INukeHadroData2025::Frac(int hpdgc, INukeFateHN_t fate, double ke, int targA, int targZ) const +{ +// return the x-section fraction for the input fate for the particle with the +// input pdg code at the input kinetic energy + + ke = TMath::Max(fMinKinEnergy, ke); + ke = TMath::Min(fMaxKinEnergyHN, ke); + + // get x-section + double xsec = this->XSec(hpdgc,fate,ke,targA,targZ); + + // get max x-section + double xsec_tot = 0; + if (hpdgc == kPdgPiP ){xsec_tot = TMath::Max(0., fXSecPipp_Tot -> Evaluate(ke)) * targZ; + xsec_tot+= TMath::Max(0., fXSecPipn_Tot -> Evaluate(ke)) * (targA-targZ);} + else if (hpdgc == kPdgPiM ){xsec_tot = TMath::Max(0., fXSecPipn_Tot -> Evaluate(ke)) * targZ; + xsec_tot+= TMath::Max(0., fXSecPipp_Tot -> Evaluate(ke)) * (targA-targZ);} + else if (hpdgc == kPdgPi0 ){xsec_tot = TMath::Max(0., fXSecPi0p_Tot -> Evaluate(ke)) * targZ; + xsec_tot+= TMath::Max(0., fXSecPi0n_Tot -> Evaluate(ke)) * (targA-targZ);} + else if (hpdgc == kPdgProton ){xsec_tot = TMath::Max(0., fXSecPp_Tot -> Evaluate(ke)) * targZ; + xsec_tot+= TMath::Max(0., fXSecPn_Tot -> Evaluate(ke)) * (targA-targZ);} + else if (hpdgc == kPdgNeutron){xsec_tot = TMath::Max(0., fXSecPn_Tot -> Evaluate(ke)) * targZ; + xsec_tot+= TMath::Max(0., fXSecNn_Tot -> Evaluate(ke)) * (targA-targZ);} + else if (hpdgc == kPdgGamma ) xsec_tot = TMath::Max(0., fXSecGamN_Tot -> Evaluate(ke)); + else if (hpdgc == kPdgKP ) xsec_tot = TMath::Max(0., fXSecKpN_Tot -> Evaluate(ke)); + + // compute fraction + double frac = (xsec_tot>0) ? xsec/xsec_tot : 0.; + return frac; +} +//____________________________________________________________________________ +double INukeHadroData2025::IntBounce(const GHepParticle* p, int target, int scode, INukeFateHN_t fate) +{ + // This method returns a random cos(ang) according to a distribution + // based upon the particle and fate. The sampling uses the + // Accept/Reject method, whereby a distribution is bounded above by + // an envelope, or in this case, a number of envelopes, which can be + // easily sampled (here, we use uniform distributions). + // To get a random value, first the envelope is sampled to + // obtain an x-coordinate (cos(ang)), and then another random value + // is obtained uniformally in the range [0,h(j,0)], where h(j,0) + // is the height of the j-th envelope. If the point is beneath the + // distribution, the x-coordinate is accepted, otherwise, we try + // again. + + RandomGen * rnd = RandomGen::Instance(); + + // numEnv is the number of envelopes in the total envelope, + // that is, the number of seperate simple uniform distributions + // that will be fit against the distribution in question in the + // Accept/Reject process of sampling + int numEnv = 4; + int numPoints = 1000; // The number of points to be evaluated + // for the purpose of finding the max + // value of the distribution + assert((numPoints%numEnv)==0); // numPoints/numEnv has to be an integer + double sr = 2.0 / numEnv; // Subrange, i.e., range of an envelope + double cstep = 2.0 / (numPoints); // Magnitude of the step between eval. points + + double ke = (p->E() - p->Mass()) * 1000.0; // ke in MeV + if (TMath::Abs((int)ke-ke)<.01) ke+=.3; // make sure ke isn't an integer, + // otherwise sometimes gives weird results + // due to ROOT's Interpolate() function + double avg = 0.0; // average value in envelop + + // Matrices to hold data; buff holds the distribution + // data per envelope from which the max value is + // obtained. That value is then recorded in dist, where + // the integral of the envelope to that point is + // also recorded + + double * buff = new double[numPoints/numEnv + 1]; + double ** dist = new double*[numEnv]; + for(int ih=0;ihXSec(p->Pdg(),target,scode,fate,ke,lbound+j*cstep); + avg += buff[j]; + } + + totxsec+=avg; + avg/= (double(numPoints)/double(numEnv)); + dist[i][0] = TMath::MaxElement(numPoints/numEnv+1,buff); + dist[i][1] = avg; + dist[i][2] = dist[i][1] + ((i==0)?0.0:dist[i-1][2]); + avg=0.0; + } + + + delete [] buff; + + int iter=1; // keep track of iterations + int env=0; // envelope index + double rval = 0.0; // random value + double val = 0.0; // angle value + + // Get a random point, see if its in the distribution, and if not + // then try again. + + rval = rnd->RndFsi().Rndm()*dist[numEnv-1][2]; + + env=0; + // Check which envelope it's in, to + // get proper height + while(envRndFsi().Rndm()*sr; + val += sr*env-1; + rval = rnd->RndFsi().Rndm()*dist[env][0]; + + // Test to see if point is in distribution, if it is, stop and return + if(rval < this->XSec(p->Pdg(),target,scode,fate,ke,val)) break; + + // Possibly an extremely long loop, don't want to + // hold up the program + if(iter==1000) + { + int NUM_POINTS=2000; + int pvalues=0; + double points[200]={0}; + for(int k=0;kXSec(p->Pdg(),target,scode,fate,ke,-1+(2.0/NUM_POINTS)*k); + if(points[int(k/10)]>0) pvalues++; + } + if(pvalues<(.05*NUM_POINTS)) + { + // if it reaches here, one more test...if momenta of particle is + // extremely low, just give it an angle from a uniform distribution + if(p->P4()->P()<.005) // 5 MeV + { + val = 2*rnd->RndFsi().Rndm()-1; + break; + } + else + { + LOG("Intranuke", pWARN) << "Hung-up in IntBounce method - Exiting"; + LOG("Intranuke", pWARN) << (*p); + LOG("Intranuke", pWARN) << "Target: " << target << ", Scode: " << scode << ", fate: " << INukeHadroFates2025::AsString(fate); + for(int ie=0;ie<200;ie+=10) { + LOG("Intranuke", pWARN) << points[ie+0] << ", " << points[ie+1] << ", " << points[ie+2] << ", " + << points[ie+3] << ", " << points[ie+4] << ", " << points[ie+5] << ", " << points[ie+6] << ", " + << points[ie+7] << ", " << points[ie+8] << ", " << points[ie+9]; + } + for(int ih=0;ih, Rutherford Lab. + Steve Dytman , Pittsburgh Univ. + Aaron Meyer , Pittsburgh Univ. + Mohamed Ismail , Pittsburgh Univ. + +\created September 01, 2025 + +\cpright Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + @ september,2025 Mohamed Ismail , SD +Data sources for hA splines updated. + - replace Mashnik CEM03 at Tpi>400 MeV with hN calculations + - replace estimates at Tpi<60 MeV with INCL calculatiosn + - fix errors in CEX (too large at low energies, too low and highenergies + - use total reaction cross sections as denominator in xs fractiopns instead of total cross section + For hA2025, we rely now on total cross sections TGraph2d not the fractions TGraph2d. + +*/ +//____________________________________________________________________________ + +#ifndef _INTRANUKE_HADRON_CROSS_SECTIONS_2025_H_ +#define _INTRANUKE_HADRON_CROSS_SECTIONS_2025_H_ + +#include "Physics/HadronTransport/INukeHadroFates2025.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Framework/Numerical/BLI2D.h" + +class TGraph2D; + +namespace genie { + +class Spline; + +class INukeHadroData2025 +{ +public: + static INukeHadroData2025 * Instance (void); + +// Note that, unlike most the rest of GENIE where everything is expressed +// in natural units, all x-section splines included here are evaluated in +// kinetic energies given in MeV and return the x-section value in mbarns + + double XSec (int hpdgc, int tgt, int nprod, INukeFateHN_t rxnType, double ke, double costh) const; + double XSec (int hpdgc, INukeFateHN_t fate, double ke, int targA, int targZ) const; + double FracADep (int hpdgc, INukeFateHA_t fate, double ke, int targA) const; + double FracAIndep (int hpdgc, INukeFateHA_t fate, double ke) const; + double Frac (int hpdgc, INukeFateHN_t fate, double ke, int targA=0, int targZ=0) const; + double IntBounce (const GHepParticle* p, int target, int s1, INukeFateHN_t fate); + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // hN mode hadron x-section splines + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + const Spline * XSecPipn_Tot (void) const { return fXSecPipn_Tot; } + const Spline * XSecPipn_CEx (void) const { return fXSecPipn_CEx; } + const Spline * XSecPipn_Elas (void) const { return fXSecPipn_Elas; } + const Spline * XSecPipn_Reac (void) const { return fXSecPipn_Reac; } + const Spline * XSecPipp_Tot (void) const { return fXSecPipp_Tot; } + const Spline * XSecPipp_CEx (void) const { return fXSecPipp_CEx; } + const Spline * XSecPipp_Elas (void) const { return fXSecPipp_Elas; } + const Spline * XSecPipp_Reac (void) const { return fXSecPipp_Reac; } + const Spline * XSecPipp_Abs (void) const { return fXSecPipd_Abs; } + const Spline * XSecPi0n_Tot (void) const { return fXSecPi0n_Tot; } + const Spline * XSecPi0n_CEx (void) const { return fXSecPi0n_CEx; } + const Spline * XSecPi0n_Elas (void) const { return fXSecPi0n_Elas; } + const Spline * XSecPi0n_Reac (void) const { return fXSecPi0n_Reac; } + const Spline * XSecPi0p_Tot (void) const { return fXSecPi0p_Tot; } + const Spline * XSecPi0p_CEx (void) const { return fXSecPi0p_CEx; } + const Spline * XSecPi0p_Elas (void) const { return fXSecPi0p_Elas; } + const Spline * XSecPi0p_Reac (void) const { return fXSecPi0p_Reac; } + const Spline * XSecPi0p_Abs (void) const { return fXSecPi0d_Abs; } + const Spline * XSecPp_Tot (void) const { return fXSecPp_Tot; } + const Spline * XSecPp_Elas (void) const { return fXSecPp_Elas; } + const Spline * XSecPp_Reac (void) const { return fXSecPp_Reac; } + const Spline * XSecPn_Tot (void) const { return fXSecPn_Tot; } + const Spline * XSecPn_Elas (void) const { return fXSecPn_Elas; } + const Spline * XSecPn_Reac (void) const { return fXSecPn_Reac; } + const Spline * XSecNn_Tot (void) const { return fXSecNn_Tot; } + const Spline * XSecNn_Elas (void) const { return fXSecNn_Elas; } + const Spline * XSecNn_Reac (void) const { return fXSecNn_Reac; } + const Spline * XSecKpn_Elas (void) const { return fXSecKpn_Elas; } + const Spline * XSecKpn_CEx (void) const { return fXSecKpn_CEx; } + const Spline * XSecKpp_Elas (void) const { return fXSecKpp_Elas; } + const Spline * XSecKpN_Abs (void) const { return fXSecKpN_Abs; } //not implemented + const Spline * XSecKpN_Tot (void) const { return fXSecKpN_Tot; } + const Spline * XSecGamp_fs (void) const { return fXSecGamp_fs; } + const Spline * XSecGamn_fs (void) const { return fXSecGamn_fs; } + const Spline * XSecGamN_Tot (void) const { return fXSecGamN_Tot; } + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // hA mode hadron x-section splines + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + const Spline * FracPA_Tot (void) const { return fFracPA_Tot; } + const Spline * FracPA_Elas (void) const { return fFracPA_Elas; } + const Spline * FracPA_Inel (void) const { return fFracPA_Inel; } + const Spline * FracPA_CEx (void) const { return fFracPA_CEx; } + const Spline * FracPA_Abs (void) const { return fFracPA_Abs; } + const Spline * FracPA_PiPro (void) const { return fFracPA_PiPro; } + const Spline * FracNA_Tot (void) const { return fFracNA_Tot; } + const Spline * FracNA_Elas (void) const { return fFracNA_Elas; } + const Spline * FracNA_Inel (void) const { return fFracNA_Inel; } + const Spline * FracNA_CEx (void) const { return fFracNA_CEx; } + const Spline * FracNA_Abs (void) const { return fFracNA_Abs; } + const Spline * FracNA_PiPro (void) const { return fFracNA_PiPro; } + const Spline * FracKA_Tot (void) const { return fFracKA_Tot; } + const Spline * FracKA_Elas (void) const { return fFracKA_Elas; } + const Spline * FracKA_Inel (void) const { return fFracKA_Inel; } + const Spline * FracKA_CEx (void) const { return fFracKA_CEx; } + const Spline * FracKA_Abs (void) const { return fFracKA_Abs; } + + const Spline * FracPA_Cmp (void) const { return fFracPA_Cmp; } + const Spline * FracNA_Cmp (void) const { return fFracNA_Cmp; } //suarez + + + const BLI2DNonUnifGrid * hN2dXSecPP_Elas (void) const { return fhN2dXSecPP_Elas; } + const BLI2DNonUnifGrid * hN2dXSecNP_Elas (void) const { return fhN2dXSecNP_Elas; } + const BLI2DNonUnifGrid * hN2dXSecPipN_Elas (void) const { return fhN2dXSecPipN_Elas; } + const BLI2DNonUnifGrid * hN2dXSecPi0N_Elas (void) const { return fhN2dXSecPi0N_Elas; } + const BLI2DNonUnifGrid * hN2dXSecPimN_Elas (void) const { return fhN2dXSecPimN_Elas; } + const BLI2DNonUnifGrid * hN2dXSecKpN_Elas (void) const { return fhN2dXSecKpN_Elas; } + const BLI2DNonUnifGrid * hN2dXSecKpP_Elas (void) const { return fhN2dXSecKpP_Elas; } + const BLI2DNonUnifGrid * hN2dXSecPiN_CEx (void) const { return fhN2dXSecPiN_CEx; } + const BLI2DNonUnifGrid * hN2dXSecPiN_Abs (void) const { return fhN2dXSecPiN_Abs; } + const BLI2DNonUnifGrid * hN2dXSecGamPi0P_Inelas (void) const { return fhN2dXSecGamPi0P_Inelas; } + const BLI2DNonUnifGrid * hN2dXSecGamPi0N_Inelas (void) const { return fhN2dXSecGamPi0N_Inelas; } + const BLI2DNonUnifGrid * hN2dXSecGamPipN_Inelas (void) const { return fhN2dXSecGamPipN_Inelas; } + const BLI2DNonUnifGrid * hN2dXSecGamPimP_Inelas (void) const { return fhN2dXSecGamPimP_Inelas; } + + static double fMinKinEnergy; ///< + static double fMaxKinEnergyHA; ///< + static double fMaxKinEnergyHN; ///< + +private: + INukeHadroData2025(); + INukeHadroData2025(const INukeHadroData2025 & shx); + ~INukeHadroData2025(); + + void LoadCrossSections(void); + + void ReadhNFile( + string filename, double ke, int npoints, int & curr_point, + /*double * ke_array,*/ double * costh_array, double * xsec_array, int cols); + + static INukeHadroData2025 * fInstance; + + Spline * fXSecPipn_Tot; ///< pi+n hN x-section splines + Spline * fXSecPipn_CEx; ///< + Spline * fXSecPipn_Elas; ///< + Spline * fXSecPipn_Reac; ///< + Spline * fXSecPipp_Tot; ///< pi+p hN x-section splines + Spline * fXSecPipp_CEx; ///< + Spline * fXSecPipp_Elas; ///< + Spline * fXSecPipp_Reac; ///< + Spline * fXSecPipd_Abs; ///< + Spline * fXSecPi0n_Tot; ///< pi0n hN x-section splines + Spline * fXSecPi0n_CEx; ///< + Spline * fXSecPi0n_Elas; ///< + Spline * fXSecPi0n_Reac; ///< + Spline * fXSecPi0p_Tot; ///< pi0p hN x-section splines + Spline * fXSecPi0p_CEx; ///< + Spline * fXSecPi0p_Elas; ///< + Spline * fXSecPi0p_Reac; ///< + Spline * fXSecPi0d_Abs; ///< + Spline * fXSecPp_Tot; ///< p/nN x-section splines + Spline * fXSecPp_Elas; ///< + Spline * fXSecPp_Reac; ///< + Spline * fXSecPn_Tot; ///< + Spline * fXSecPn_Elas; ///< + Spline * fXSecPn_Reac; ///< + Spline * fXSecNn_Tot; ///< + Spline * fXSecNn_Elas; ///< + Spline * fXSecNn_Reac; ///< + Spline * fXSecKpn_Elas; ///< K+N x-section splines + Spline * fXSecKpp_Elas; ///< + Spline * fXSecKpn_CEx; ///< + Spline * fXSecKpN_Abs; ///< + Spline * fXSecKpN_Tot; ///< + Spline * fFracPA_Tot; ///< N+A x-section splines + Spline * fFracPA_Elas; ///< + Spline * fFracPA_Inel; ///< + Spline * fFracPA_CEx; ///< + Spline * fFracPA_Abs; ///< + Spline * fFracPA_PiPro; ///< + Spline * fFracNA_Tot; ///< + Spline * fFracNA_Elas; ///< + Spline * fFracNA_Inel; ///< + Spline * fFracNA_CEx; ///< + Spline * fFracNA_Abs; ///< + Spline * fFracNA_PiPro; ///< + Spline * fFracKA_Tot; ///< K+A x-section splines + Spline * fFracKA_Elas; ///< + Spline * fFracKA_CEx; ///< + Spline * fFracKA_Inel; ///< + Spline * fFracKA_Abs; ///< + Spline * fXSecGamp_fs; ///< gamma A x-section splines + Spline * fXSecGamn_fs; ///< + Spline * fXSecGamN_Tot; ///< + Spline * fXSecPp_Cmp; ///< NN cmp (compound nucleus) fate + Spline * fXSecPn_Cmp; + Spline * fXSecNn_Cmp; + Spline * fFracPA_Cmp; + Spline * fFracNA_Cmp; + + // TGraph2D * TPipA_Tot; + TGraph2D * TfracPipA_CEx; +// TGraph2D * TfracPipA_Elas; + TGraph2D * TfracPipA_Inelas; + TGraph2D * TfracPipA_Abs; + TGraph2D * TfracPipA_PiPro; + + TGraph2D * TPipA_Tot; + TGraph2D * TPipA_CEx; + TGraph2D * TPipA_Inelas; + TGraph2D * TPipA_Abs; + TGraph2D * TPipA_PiPro; + + BLI2DNonUnifGrid * fhN2dXSecPP_Elas; + BLI2DNonUnifGrid * fhN2dXSecNP_Elas; + BLI2DNonUnifGrid * fhN2dXSecPipN_Elas; + BLI2DNonUnifGrid * fhN2dXSecPi0N_Elas; + BLI2DNonUnifGrid * fhN2dXSecPimN_Elas; + BLI2DNonUnifGrid * fhN2dXSecKpN_Elas; + BLI2DNonUnifGrid * fhN2dXSecKpP_Elas; + BLI2DNonUnifGrid * fhN2dXSecKpN_CEx; + BLI2DNonUnifGrid * fhN2dXSecKpN_Abs; + BLI2DNonUnifGrid * fhN2dXSecPiN_CEx; + BLI2DNonUnifGrid * fhN2dXSecPiN_Abs; + BLI2DNonUnifGrid * fhN2dXSecGamPi0P_Inelas; + BLI2DNonUnifGrid * fhN2dXSecGamPi0N_Inelas; + BLI2DNonUnifGrid * fhN2dXSecGamPipN_Inelas; + BLI2DNonUnifGrid * fhN2dXSecGamPimP_Inelas; + + //-- Sinleton cleaner + struct Cleaner { + void DummyMethodAndSilentCompiler() { } + ~Cleaner() { + if (INukeHadroData2025::fInstance !=0) { + delete INukeHadroData2025::fInstance; + INukeHadroData2025::fInstance = 0; + } + } + }; + friend struct Cleaner; +}; + +} // genie namespace +#endif //_INTRANUKE_HADRON_CROSS_SECTIONS_2015_H_ + + diff --git a/src/Physics/HadronTransport/INukeHadroFates2025.h b/src/Physics/HadronTransport/INukeHadroFates2025.h new file mode 100644 index 0000000000..1e1470f34d --- /dev/null +++ b/src/Physics/HadronTransport/INukeHadroFates2025.h @@ -0,0 +1,126 @@ +//____________________________________________________________________________ +/*! + +\class genie::INukeHadroFates + +\brief An enumeration of possible hadron "fates" taken into account by the + INTRANUKE hadron transport MC. + +\author Steve Dytman , Pittsburgh Univ. + Hugh Gallagher , Tufts Univ. + Costas Andreopoulos , Rutherford Lab. + +\created September 22, 2025 + +\cpright Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + @ Sept, 2025 Copied by Mohamed Ismail , no changes + + +*/ +//____________________________________________________________________________ + +#ifndef _INTRANUKE_FATES_H_ +#define _INTRANUKE_FATES_H_ + +#include + +using std::string; + +namespace genie { + +// Fates in INTRANUKE's HN mode +// +typedef enum EINukeFateHN_t { + + kIHNFtUndefined = 0, + kIHNFtNoInteraction, + kIHNFtCEx, // cex + kIHNFtElas, // elas + kIHNFtInelas, // inelas + kIHNFtAbs, // abs + kIHNFtCmp //cmp + +} INukeFateHN_t; + +// Fates in INTRANUKE's HA mode +// +typedef enum EINukeFateHA_t { + + kIHAFtUndefined = 0, + kIHAFtNoInteraction, // no interaction + kIHAFtCEx, // cex + // kIHAFtElas, // elas + kIHAFtInelas, // inelas + kIHAFtAbs, // abs + kIHAFtKo, // knock out + kIHAFtCmp, // compound nucleus + kIHAFtPiProd, // pi production + kIHAFtInclPip, // pi production : inclusive pi+ + kIHAFtInclPim, // pi production : inclusive pi- + kIHAFtInclPi0, // pi production : inclusive pi0 + kIHAFtDCEx // dcex + +} INukeFateHA_t; + +class INukeHadroFates2025 { + +public: + //__________________________________________________________________________ + static string AsString(INukeFateHN_t fate) { + switch (fate) { + case kIHNFtUndefined : return "** Undefined HN-mode fate **"; break; + case kIHNFtCEx : return "HN-mode / cex"; break; + case kIHNFtElas : return "HN-mode / elas"; break; + case kIHNFtInelas : return "HN-mode / inelas"; break; + case kIHNFtAbs : return "HN-mode / abs"; break; + case kIHNFtCmp : return "HN-mode / compound"; break; + case kIHNFtNoInteraction : return "HN-mode / no interaction"; break; + default : break; + } + return "** Undefined HN-mode fate **"; + } + //__________________________________________________________________________ + static string AsString(INukeFateHA_t fate) { + switch (fate) { + case kIHAFtUndefined : return "** Undefined HA-mode fate **"; break; + case kIHAFtNoInteraction : return "HA-mode / no interaction"; break; + case kIHAFtCEx : return "HA-mode / cex"; break; + // case kIHAFtElas : return "HA-mode / elas"; break; + case kIHAFtInelas : return "HA-mode / inelas"; break; + case kIHAFtAbs : return "HA-mode / abs"; break; + case kIHAFtKo : return "HA-mode / knock-out"; break; + case kIHAFtCmp : return "HA-mode / compound"; break; + case kIHAFtPiProd : return "HA-mode / pi-production" ; break; + case kIHAFtInclPip : return "HA-mode / pi-prod incl pi+"; break; + case kIHAFtInclPim : return "HA-mode / pi-prod incl pi-"; break; + case kIHAFtInclPi0 : return "HA-mode / pi-prod incl pi0"; break; + case kIHAFtDCEx : return "HA-mode / dcex"; break; + default : break; + } + return "** Undefined HA-mode fate **"; + } + //__________________________________________________________________________ + static string AsSimpleString(INukeFateHA_t fate) { + switch (fate) { + case kIHAFtUndefined : return "undefined"; break; + case kIHAFtNoInteraction : return "no interaction"; break; + case kIHAFtCEx : return "cex"; break; + // case kIHAFtElas : return "elas"; break; + case kIHAFtInelas : return "inelas"; break; + case kIHAFtAbs : return "abs"; break; + case kIHAFtKo : return "knock out"; break; + case kIHAFtCmp : return "compound"; break; + case kIHAFtPiProd : return "pi prod"; break; + case kIHAFtDCEx : return "dcex"; break; + default : break; + } + return "undefined"; + } + //__________________________________________________________________________ + +}; + +} // genie +#endif // _INTRANUKE_FATES_H_ diff --git a/src/Physics/HadronTransport/INukeUtils2018.h b/src/Physics/HadronTransport/INukeUtils2018.h index e527492ab4..dbbb00c5eb 100644 --- a/src/Physics/HadronTransport/INukeUtils2018.h +++ b/src/Physics/HadronTransport/INukeUtils2018.h @@ -3,7 +3,11 @@ \namespace genie::intranuke -\brief INTRANUKE utilities +\brief INTRANUKE utilities: + mean free path methods used to determine where hadron interactions happen + 2-body scattering and pion production kinematics. + Phase space 'decay' of pseudostates, e.g. multinucleon, used in pion absorption and nucleon knowckout + Reweighting methods \author Jim Dobson Imperial College London diff --git a/src/Physics/HadronTransport/INukeUtils2025.cxx b/src/Physics/HadronTransport/INukeUtils2025.cxx new file mode 100644 index 0000000000..b1951bbbf8 --- /dev/null +++ b/src/Physics/HadronTransport/INukeUtils2025.cxx @@ -0,0 +1,1936 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2023, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + + Author: Jim Dobson + Imperial College London + + Costas Andreopoulos + University of Liverpool & STFC Rutherford Appleton Laboratory + + Aaron Meyer + Pittsburgh University + + For documentation see the corresponding header file. + + Important revisions after version 2.0.0 : + @ Sep, 2025 - SD, MI + Copied from 2018 version, no changes +*/ +//____________________________________________________________________________ + +#include +#include +#include + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Conventions/Controls.h" +#include "Framework/Conventions/Units.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/EventGen/EVGThreadException.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Physics/HadronTransport/Intranuke2025.h" +#include "Physics/HadronTransport/INukeException.h" +#include "Physics/HadronTransport/INukeUtils2025.h" +#include "Physics/HadronTransport/INukeHadroData2025.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/Numerical/RandomGen.h" +#include "Framework/Numerical/Spline.h" +#include "Framework/ParticleData/PDGLibrary.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Framework/ParticleData/PDGCodeList.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/Registry/Registry.h" +#include "Physics/NuclearState/NuclearUtils.h" +#include "Framework/Utils/PrintUtils.h" +#include "Physics/HadronTransport/INukeOset.h" +#include "Physics/HadronTransport/INukeOsetTable.h" +#include "Physics/HadronTransport/INukeOsetFormula.h" +#include "TComplex.h" + +using std::ostringstream; +using namespace genie; +using namespace genie::utils; +using namespace genie::constants; +using namespace genie::controls; + +//____________________________________________________________________________ +double genie::utils::intranuke2025::MeanFreePath( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, + double A, double Z, double nRpi, double nRnuc, const bool useOset, + const bool altOset, const bool xsecNNCorr, string INukeMode) +{ +// Calculate the mean free path (in fm) for a pions and nucleons in a nucleus +// +// Inputs +// pdgc : Hadron PDG code +// x4 : Hadron 4-position in the nucleus coordinate system (units: fm) +// p4 : Hadron 4-momentum (units: GeV) +// A : Nucleus atomic mass number +// nRpi : Controls the pion ring size in terms of de-Broglie wavelengths +// nRnuc: Controls the nuclepn ring size in terms of de-Broglie wavelengths +// + bool is_pion = pdgc == kPdgPiP || pdgc == kPdgPi0 || pdgc == kPdgPiM; + bool is_nucleon = pdgc == kPdgProton || pdgc == kPdgNeutron; + bool is_kaon = pdgc == kPdgKP; + bool is_gamma = pdgc == kPdgGamma; + + if(!is_pion && !is_nucleon && !is_kaon && !is_gamma) return 0.; + + // before getting the nuclear density at the current position + // check whether the nucleus has to become larger by const times the + // de Broglie wavelength -- that is somewhat empirical, but this + // is what is needed to get piA total cross sections right. + // The ring size is different for light nuclei (using gaus density) / + // heavy nuclei (using woods-saxon density). + // The ring size is different for pions / nucleons. + // + double momentum = p4.Vect().Mag(); // hadron momentum in GeV + double ring = (momentum>0) ? 1.240/momentum : 0; // de-Broglie wavelength + + if(A<=20) { ring /= 2.; } + + /* + if (is_pion ) { ring *= nRpi; } + else if (is_nucleon ) { ring *= nRnuc; } + else if (is_gamma || is_kaon || useOset) { ring = 0.; } + */ + if(INukeMode=="hN2025") + { + if (is_pion ) { ring *= nRpi; } + else if (is_nucleon ) { ring *= nRnuc; } + else if (is_gamma || is_kaon || useOset) { ring = 0.;} + } + else + { + if (is_pion || is_kaon ) { ring *= nRpi; } + else if (is_nucleon ) { ring *= nRnuc; } + else if (is_gamma ) { ring = 0.; } + } + + // get the nuclear density at the current position + double rnow = x4.Vect().Mag(); + double rho = A * utils::nuclear::Density(rnow,(int) A,ring); + + // the hadron+nucleon cross section will be evaluated within the range + // of the input spline and assumed to be const outside that range + // + double ke = (p4.Energy() - p4.M()) / units::MeV; // kinetic energy in MeV + ke = TMath::Max(INukeHadroData2025::fMinKinEnergy, ke); + ke = TMath::Min(INukeHadroData2025::fMaxKinEnergyHN, ke); + + // get total xsection for the incident hadron at its current + // kinetic energy + double sigtot = 0; + double ppcnt = (double) Z/ (double) A; // % of protons remaining + INukeHadroData2025 * fHadroData2025 = INukeHadroData2025::Instance(); + + if (is_pion and (INukeMode == "hN2025") and useOset and ke < 350.0) + sigtot = sigmaTotalOset (ke, rho, pdgc, ppcnt, altOset); + else if (pdgc == kPdgPiP) + { sigtot = fHadroData2025 -> XSecPipp_Tot() -> Evaluate(ke)*ppcnt; + sigtot+= fHadroData2025 -> XSecPipn_Tot() -> Evaluate(ke)*(1-ppcnt);} + else if (pdgc == kPdgPi0) + { sigtot = fHadroData2025 -> XSecPi0p_Tot() -> Evaluate(ke)*ppcnt; + sigtot+= fHadroData2025 -> XSecPi0n_Tot() -> Evaluate(ke)*(1-ppcnt);} + else if (pdgc == kPdgPiM) + { sigtot = fHadroData2025 -> XSecPipn_Tot() -> Evaluate(ke)*ppcnt; + sigtot+= fHadroData2025 -> XSecPipp_Tot() -> Evaluate(ke)*(1-ppcnt);} + else if (pdgc == kPdgProton) + { + sigtot = fHadroData2025 -> XSecPp_Tot() -> Evaluate(ke)*ppcnt; + //sigtot+= fHadroData2025 -> XSecPn_Tot() -> Evaluate(ke)*(1-ppcnt); + + PDGLibrary * pLib = PDGLibrary::Instance(); + double hc = 197.327; + double R0 = 1.25 * TMath::Power(A,1./3.) + 2.0 * 0.65; // should all be in units of fm + double Mp = pLib->Find(2212)->Mass(); + double M = pLib->Find(pdgc)->Mass(); + //double E = (p4.Energy() - Mp) * 1000.; // Convert GeV to MeV. + double E = ke; + if (Z*hc/137./x4.Vect().Mag() > E) // Coulomb correction (Cohen, Concepts of Nuclear Physics, pg. 259-260) + { + double z = 1.0; // charge for single proton + double Bc = z*Z*hc/137./R0; + double x = E/Bc; + double f = TMath::ACos(TMath::Power(x,0.5)) - TMath::Power(x*(1-x),0.5); + double B = 0.63*z*Z*TMath::Power((M/Mp)/E,0.5); + double Pc = TMath::Exp(-B*f); + sigtot *= Pc; + } + sigtot+= fHadroData2025 -> XSecPn_Tot() -> Evaluate(ke)*(1-ppcnt); + + double E0 = TMath::Power(A,0.2)*12.; + if (INukeMode=="hN2025"){if(ke mfp = " << lamda << " fm."; +*/ + return lamda; +} +//____________________________________________________________________________ +double genie::utils::intranuke2025::MeanFreePath_Delta( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, double A) +{ +// +// **test** +// + +// Calculate the mean free path (in fm) for Delta's in a nucleus +// +// Inputs +// pdgc : Hadron PDG code +// x4 : Hadron 4-position in the nucleus coordinate system (units: fm) +// p4 : Hadron 4-momentum (units: GeV) +// A : Nucleus atomic mass number +// + bool is_deltapp = (pdgc==kPdgP33m1232_DeltaPP); + if(!is_deltapp) return 0.; + + // get the nuclear density at the current position + double rnow = x4.Vect().Mag(); + double rho = A * utils::nuclear::Density(rnow,(int) A); + + // the Delta+N->N+N cross section will be evaluated within the range + // of the input spline and assumed to be const outside that range + double ke = (p4.Energy() - p4.M()) / units::MeV; // kinetic energy in MeV + ke = TMath::Max(1500., ke); + ke = TMath::Min( 0., ke); + + // get the Delta+N->N+N cross section + double sig = 0; + if (ke< 500) sig=20; + else if (ke<1000) sig=40; + else sig=30; + + // value is in mb -> convert to fm^2 + sig *= (units::mb / units::fm2); + + // compute the mean free path + double lamda = 1. / (rho * sig); + + // exits if lamda is InF (if cross section is 0) + if( ! TMath::Finite(lamda) ) { + return -1; + } + + return lamda; +} +//____________________________________________________________________________ +double genie::utils::intranuke2025::ProbSurvival( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, double A, double /*Z*/, + double mfp_scale_factor, const Intranuke2025& fsi_model ) +{ +// Calculate the survival probability for a hadron inside a nucleus +// +// Inputs +// pdgc : Hadron PDG code +// x4 : Hadron 4-position in the nucleus coordinate system (units: fm) +// p4 : Hadron 4-momentum (units: GeV) +// A : Target nucleus atomic mass number +// mfp_scale_factor: Tweaks the mean free path (mfp -> mfp*scale). Def: 1.0 + + double prob = 1.0; + + // Get extra parameters from the FSI model that we need to compute the + // mean free path + + // nRpi: Controls the pion ring size in terms of de-Broglie wavelengths + double nRpi = fsi_model.GetDelRPion(); + + // nRnuc: Controls the nuclepn ring size in terms of de-Broglie wavelengths + double nRnuc = fsi_model.GetDelRNucleon(); + + // NR: How far away to track the hadron, in terms of the corresponding + // nuclear radius. Def: 3 + double NR = fsi_model.GetNR(); + + // R0: R0 in R=R0*A^1/3 (units:fm). Def. 1.4 + double R0 = fsi_model.GetR0(); + + // step: Step size (fm) to use when tracking hadrons + double step = fsi_model.GetHadStep(); + + // Boolean model configuration options + bool useOset = fsi_model.GetUseOset(); + bool altOset = fsi_model.GetAltOset(); + bool xsecNNCorr = fsi_model.GetXsecNNCorr(); + + // Intranuke mode setting ("HA2025", etc.) + std::string inuke_mode = fsi_model.GetINukeMode(); + + // Maximum radius to use in the stepping loop. Note that Intranuke2025 uses + // the *target* mass number to choose this radius, not the value for the + // pre- or post-FSI remnant. + double R = NR * R0 * TMath::Power(A, 1./3.); + + TVector3 dr3 = p4.Vect().Unit(); // unit vector along its direction + TLorentzVector dr4(dr3,0); + + int remnA = fsi_model.GetRemnA(); + int remnZ = fsi_model.GetRemnZ(); + + LOG("INukeUtils", pDEBUG) + << "Calculating survival probability for hadron with PDG code = " << pdgc + << " and momentum = " << p4.P() << " GeV"; + LOG("INukeUtils", pDEBUG) + << "mfp scale = " << mfp_scale_factor + << ", nRpi = " << nRpi << ", nRnuc = " << nRnuc << ", NR = " << NR + << ", R0 = " << R0 << " fm"; + + TLorentzVector x4_curr(x4); // current position + + while(1) { + double rnow = x4_curr.Vect().Mag(); + if (rnow > (R+step)) break; + + x4_curr += (step*dr4); + rnow = x4_curr.Vect().Mag(); + + double mfp = genie::utils::intranuke2025::MeanFreePath( pdgc, x4_curr, p4, + remnA, remnZ, nRpi, nRnuc, useOset, altOset, xsecNNCorr, inuke_mode ); + double mfp_twk = mfp * mfp_scale_factor; + + double dprob = (mfp_twk>0) ? TMath::Exp(-step/mfp_twk) : 0.; + prob*=dprob; +/* + LOG("INukeUtils", pDEBUG) + << "+ step size = " << step << " fm, |r| = " << rnow << " fm, " + << "mfp = " << mfp_twk << "fm (nominal mfp = " << mfp << " fm): " + << "dPsurv = " << dprob << ", current Psurv = " << prob; +*/ + } + + LOG("INukeUtils", pDEBUG) << "Psurv = " << prob; + + return prob; +} +//____________________________________________________________________________ +double genie::utils::intranuke2025::Dist2Exit( + const TLorentzVector & x4, const TLorentzVector & p4, + double A, double NR, double R0) +{ +// Calculate distance within a nucleus (units: fm) before we stop tracking +// the hadron. +// See previous functions for a description of inputs. +// + double R = NR * R0 * TMath::Power(A, 1./3.); + double step = 0.05; // fermi + + TVector3 dr3 = p4.Vect().Unit(); // unit vector along its direction + TLorentzVector dr4(dr3,0); + + TLorentzVector x4_curr(x4); // current position + + double d=0; + while(1) { + double rnow = x4_curr.Vect().Mag(); + x4_curr += (step*dr4); + d+=step; + rnow = x4_curr.Vect().Mag(); + if (rnow > R) break; + } + return d; +} +//____________________________________________________________________________ +double genie::utils::intranuke2025::Dist2ExitMFP( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, + double A, double Z, double NR, double R0) +{ +// Calculate distance within a nucleus (expressed in terms of 'mean free +// paths') before we stop tracking the hadron. +// See previous functions for a description of inputs. +// + +// distance before exiting in mean free path lengths +// + double R = NR * R0 * TMath::Power(A, 1./3.); + double step = 0.05; // fermi + + TVector3 dr3 = p4.Vect().Unit(); // unit vector along its direction + TLorentzVector dr4(dr3,0); + + TLorentzVector x4_curr(x4); // current position + + double d=0; + double d_mfp=0; + while(1) { + double rnow = x4_curr.Vect().Mag(); + x4_curr += (step*dr4); + d+=step; + rnow = x4_curr.Vect().Mag(); + + double lambda = genie::utils::intranuke2025::MeanFreePath(pdgc,x4_curr,p4,A,Z); + d_mfp += (step/lambda); + + if (rnow > R) break; + } + return d_mfp; +} +//____________________________________________________________________________ +void genie::utils::intranuke2025::StepParticle( + GHepParticle * p, double step, double nuclear_radius) +{ +// Steps a particle starting from its current position (in fm) and moving +// along the direction of its current momentum by the input step (in fm). +// The particle is stepped in a straight line. +// If a nuclear radius is set then the following check is performed: +// If the step is too large and takes the the particle far away from the +// nucleus then its position is scaled back so that the escaped particles are +// always within a ~1fm from the "outer nucleus surface" + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("INukeUtils", pDEBUG) + << "Stepping particle [" << p->Name() << "] by dr = " << step << " fm"; +#endif + + // Step particle + TVector3 dr = p->P4()->Vect().Unit(); // unit vector along its direction + dr.SetMag(step); // spatial step size + double dt = 0; // temporal step: + TLorentzVector dx4(dr,dt); // 4-vector step + TLorentzVector x4new = *(p->X4()) + dx4; // new position + + if(nuclear_radius > 0.) { + // Check position against nuclear boundary. If the particle was stepped + // too far away outside the nuclear boundary bring it back to within + // 1fm from that boundary + double epsilon = 1; // fm + double r = x4new.Vect().Mag(); // fm + double rmax = nuclear_radius+epsilon; + if(r > rmax) { + LOG("INukeUtils", pINFO) + << "Particle was stepped too far away (r = " << r << " fm)"; + LOG("INukeUtils", pINFO) + << "Placing it " << epsilon + << " fm outside the nucleus (r' = " << rmax << " fm)"; + double scale = rmax/r; + x4new *= scale; + }//r>rmax + }//nucl radius set + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("INukeUtils", pDEBUG) + << "\n Init direction = " << print::Vec3AsString(&dr) + << "\n Init position (in fm,nsec) = " << print::X4AsString(p->X4()) + << "\n Fin position (in fm,nsec) = " << print::X4AsString(&x4new); +#endif + + p->SetPosition(x4new); +} + + +//___________________________________________________________________________ +// Method to handle compound nucleus considerations, preequilibrium +// and equilibrium +// Alex Bell -- 6/17/2008 +void genie::utils::intranuke2025::PreEquilibrium( + GHepRecord * ev, GHepParticle * p, + int &RemnA, int &RemnZ, TLorentzVector &RemnP4, + bool /* DoFermi */, double /* FermiFac */, + const NuclearModelI* /* Nuclmodel */, double NucRmvE, EINukeMode mode) +{ + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("INukeUtils", pDEBUG) + << "PreEquilibrium() is invoked for a : " << p->Name() + << " whose kinetic energy is : " << p->KinE(); +#endif + + // Random number generator + RandomGen * rnd = RandomGen::Instance(); + //unused PDGLibrary * pLib = PDGLibrary::Instance(); + + bool allow_dup = true; + PDGCodeList list(allow_dup); // list of final state particles + + double ppcnt = (double) RemnZ / (double) RemnA; // % of protons left + + // figure out the final state conditions + + if(p->Pdg()==kPdgProton) list.push_back(kPdgProton); + else if(p->Pdg()==kPdgNeutron) list.push_back(kPdgNeutron); + + for(int i=0;i<3;i++) + { + if(rnd->RndFsi().Rndm()TargetNucleus()->Pdg()); + TVector3 pBuf = p->P4()->Vect(); + double mBuf = p->Mass(); + double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + TLorentzVector tSum(pBuf,eBuf); + double mSum = 0.0; + vector::const_iterator pdg_iter; + for(pdg_iter=++(list.begin());pdg_iter!=list.end();++pdg_iter) + { + target.SetHitNucPdg(*pdg_iter); + Nuclmodel->GenerateNucleon(target); + mBuf = pLib->Find(*pdg_iter)->Mass(); + mSum += mBuf; + pBuf = FermiFac * Nuclmodel->Momentum3(); + eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + tSum += TLorentzVector(pBuf,eBuf); + RemnP4 -= TLorentzVector(pBuf,eBuf-mBuf); + } + TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum); + p->SetMomentum(dP4); + } + */ + // do the phase space decay & save all f/s particles to the event record + bool success = genie::utils::intranuke2025::PhaseSpaceDecay(ev,p,list,RemnP4,NucRmvE,mode); + if(success) LOG("INukeUtils2025",pINFO) << "Successful phase space decay for pre-equilibrium nucleus FSI event"; + else + { + exceptions::INukeException exception; + exception.SetReason("Phase space generation of pre-equilibrium nucleus final state failed, details above"); + throw exception; + } + + int p_loc = 0; + while(p_locGetEntries()) + { + GHepParticle * p_ref = ev->Particle(p_loc); + if(!p->ComparePdgCodes(p_ref)) p_loc++; + else + { + if(!p->CompareStatusCodes(p_ref)) p_loc++; + else + { + if(!p->CompareMomentum(p_ref)) p_loc++; + else break; + } + } + } + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("INukeUtils", pDEBUG) + << "Particle at: " << p_loc; +#endif + + // find the appropriate daughter + vector * descendants = ev->GetStableDescendants(p_loc); + + int loc = p_loc + 1; + int f_loc = p_loc + 1; + double energy = ev->Particle(loc)->E(); + +/* // (1) least energetic + double min_en = energy; + + for(unsigned int j=0;jsize();j++) + { + loc = (*descendants)[j]; + energy = ev->Particle(loc)->E(); + if(energysize();j++) + { + loc = (*descendants)[j]; + energy = ev->Particle(loc)->E(); + if(energy>max_en) + { + f_loc = loc; + max_en = energy; + } + } + + // (3) 1st particle + // ...just use the defaulted f_loc + + delete descendants; + + // change particle status for decaying particle - take out as test + //ev->Particle(f_loc)->SetStatus(kIStIntermediateState); + // decay a clone particle + GHepParticle * t = new GHepParticle(*(ev->Particle(f_loc))); + t->SetFirstMother(f_loc); + //next statement was in Alex Bell's original code - PreEq, then Equilibrium using particle with highest energy. Note it gets IST=kIStIntermediateState. + //genie::utils::intranuke2025::Equilibrium(ev,t,RemnA,RemnZ,RemnP4,DoFermi,FermiFac,Nuclmodel,NucRmvE,mode); + + delete t; +} +//___________________________________________________________________________ +// Method to handle Equilibrium reaction +// Alex Bell -- 6/17/2008 +void genie::utils::intranuke2025::Equilibrium( + GHepRecord * ev, GHepParticle * p, + int &RemnA, int &RemnZ, TLorentzVector &RemnP4, + bool /* DoFermi */, double /* FermiFac */, + const NuclearModelI* /* Nuclmodel */, double NucRmvE, EINukeMode mode) +{ + +#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__ + LOG("INukeUtils", pDEBUG) + << "Equilibrium() is invoked for a : " << p->Name() + << " whose kinetic energy is : " << p->KinE(); +#endif + + // Random number generator + RandomGen * rnd = RandomGen::Instance(); + //usused PDGLibrary * pLib = PDGLibrary::Instance(); + + bool allow_dup = true; + PDGCodeList list(allow_dup); // list of final state particles + + // % of protons left + double ppcnt = (double) RemnZ / (double) RemnA; + + // figure out the final state conditions + + if(p->Pdg()==kPdgProton) list.push_back(kPdgProton); + else if(p->Pdg()==kPdgNeutron) list.push_back(kPdgNeutron); + + //add additonal particles to stack + for(int i=0;i<4;i++) + { + if(rnd->RndFsi().Rndm()TargetNucleus()->Pdg()); + TVector3 pBuf = p->P4()->Vect(); + double mBuf = p->Mass(); + double eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + TLorentzVector tSum(pBuf,eBuf); + double mSum = 0.0; + vector::const_iterator pdg_iter; + for(pdg_iter=++(list.begin());pdg_iter!=list.end();++pdg_iter) + { + target.SetHitNucPdg(*pdg_iter); + Nuclmodel->GenerateNucleon(target); + mBuf = pLib->Find(*pdg_iter)->Mass(); + mSum += mBuf; + pBuf = FermiFac * Nuclmodel->Momentum3(); + eBuf = TMath::Sqrt(pBuf.Mag2() + mBuf*mBuf); + tSum += TLorentzVector(pBuf,eBuf); + RemnP4 -= TLorentzVector(pBuf,eBuf-mBuf); + } + TLorentzVector dP4 = tSum + TLorentzVector(TVector3(0,0,0),-mSum); + p->SetMomentum(dP4); + } + */ + // do the phase space decay & save all f/s particles to the record + bool success = genie::utils::intranuke2025::PhaseSpaceDecay(ev,p,list,RemnP4,NucRmvE,mode); + if (success) LOG("INukeUtils",pINFO) << "successful equilibrium interaction"; + else + { + exceptions::INukeException exception; + exception.SetReason("Phase space generation of compound nucleus final state failed, details above"); + throw exception; + } + +} + + +//___________________________________________________________________________ +bool genie::utils::intranuke2025::TwoBodyCollision( + GHepRecord* ev, int pcode, int tcode, int scode, int s2code, double C3CM, + GHepParticle* p, GHepParticle* t, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, EINukeMode mode) +{ + // Aaron Meyer (10/29/09) + // Adapted from kinematics in other function calls + // + // C3CM is the cosine of the scattering angle, calculated before calling + // p and t are the output particles, must be allocated before calling + // pcode,tcode,scode,s2code are initial and final particle PDG codes in scattering + // return value used for error checking + + // Kinematic variables + + double M1, /* M2, */ M3, M4; // rest energies, in GeV + double E3L, P3L, E4L, P4L; + TVector3 tP1L, tPtot, tbeta, tbetadir, tTrans, tVect; + TVector3 tP1zCM, tP2zCM, tP3L, tP4L; + + // Library instance for reference + PDGLibrary * pLib = PDGLibrary::Instance(); + + // random number generator + //RandomGen * rnd = RandomGen::Instance(); + + // handle fermi target + Target target(ev->TargetNucleus()->Pdg()); + + // get mass for particles + M1 = pLib->Find(pcode)->Mass(); + // usused // M2 = pLib->Find(tcode)->Mass(); + M3 = pLib->Find(scode)->Mass(); + M4 = pLib->Find(s2code)->Mass(); + + // get lab energy and momenta and assign to 4 vectors + TLorentzVector t4P1L = *p->P4(); + TLorentzVector t4P2L = *t->P4(); + + // binding energy + double bindE = 0.025; // empirical choice, might need to be improved + //double bindE = 0.0; + + LOG("TwoBodyCollision",pNOTICE) << "M1 = " << t4P1L.M() << " , M2 = " << t4P2L.M(); + LOG("TwoBodyCollision",pNOTICE) << "E1 = " << t4P1L.E() << " , E2 = " << t4P2L.E(); + + if ( (p->Energy()-p->Mass()) < bindE ){bindE = 0.;} // if the probe's energy is less than the binding energy, set the binding energy to 0. + + // don't use BE unless kinetic energy >> BE. + if((pcode==2112||pcode==2212)&&(t4P1L.E()-M1)<.1) bindE = 0.0; + if((pcode==211||pcode==-211||pcode==111)&&(t4P1L.E()-M1)<.08) bindE = 0.0; + if((pcode==321)&&(t4P1L.E()-M1)<.1) bindE = 0.0; + + // carry out scattering + TLorentzVector t4P3L, t4P4L; + if (!TwoBodyKinematics(M3,M4,t4P1L,t4P2L,t4P3L,t4P4L,C3CM,RemnP4,bindE)) + { + P3L = t4P3L.Vect().Mag(); + P4L = t4P4L.Vect().Mag(); + E3L = t4P3L.E(); + E4L = t4P4L.E(); + + LOG("TwoBodyCollision",pNOTICE) + << "TwoBodyKinematics fails: C3CM, P3 = " << C3CM << " " + << P3L << " " << E3L << "\n" << " P4 = " + << P4L << " " << E4L ; + return false; //covers all possiblities for now + } + + // error checking + P3L = t4P3L.Vect().Mag(); + P4L = t4P4L.Vect().Mag(); + E3L = t4P3L.E(); + E4L = t4P4L.E(); + LOG("INukeUtils",pINFO) + << "C3CM, P3 = " << C3CM << " " + << P3L << " " << E3L << "\n" << " P4 = " + << P4L << " " << E4L ; + + // handle very low momentum particles + if(!(TMath::Finite(P3L)) || P3L<.001) + { + LOG("INukeUtils",pINFO) + << "Particle 3 momentum small or non-finite: " << P3L + << "\n" << "--> Assigning .001 as new momentum"; + P3L = .001; + E3L = TMath::Sqrt(P3L*P3L + M3*M3); + } + if(!(TMath::Finite(P4L)) || P4L<.001) + { + LOG("INukeUtils",pINFO) + << "Particle 4 momentum small or non-finite: " << P4L + << "\n" << "--> Assigning .001 as new momentum"; + P4L = .001; + E4L = TMath::Sqrt(P4L*P4L + M4*M4); + } + + // if this is going to be on in the future, remember to not apply PB for Oset + /*// pauli blocking turn off for now to better match data + // if(P3LSetStatus(kIStHadronInTheNucleus); + RemnP4 -= TLorentzVector(0,0,0,bindE); + return false; + }*/ + + // update remnant nucleus + RemnP4 -= t4P2L; + LOG("INukeUtils",pINFO) + << "t4P2L= " << t4P2L.E() << " " << t4P2L.Z() + << " RemnP4= " << RemnP4.E() << " " << RemnP4.Z() ; + if (tcode==kPdgProton) {RemnZ--;RemnA--;} + else if(tcode==kPdgNeutron) RemnA--; + + // create t particle w/ appropriate momenta, code, and status + // Set target's mom to be the mom of the hadron that was cloned + t->SetFirstMother(p->FirstMother()); + t->SetLastMother(p->LastMother()); + + // adjust p to reflect scattering + p->SetPdgCode(scode); + p->SetMomentum(t4P3L); + + t->SetPdgCode(s2code); + t->SetMomentum(t4P4L); + + if (mode==kIMdHN) + { + p->SetStatus(kIStHadronInTheNucleus); + t->SetStatus(kIStHadronInTheNucleus); + } + else + { + p->SetStatus(kIStStableFinalState); + t->SetStatus(kIStStableFinalState); + } + LOG("INukeUtils",pINFO) << "Successful 2 body collision"; + return true; + +} +//___________________________________________________________________________ +bool genie::utils::intranuke2025::TwoBodyKinematics( + double M3, double M4, TLorentzVector t4P1L, TLorentzVector t4P2L, + TLorentzVector &t4P3L, TLorentzVector &t4P4L, double C3CM, TLorentzVector &RemnP4, double bindE) +{ + // Aaron Meyer (05/17/10) + // Adapted from kinematics in other function calls + // + // Outgoing particle masses M3,M4 + // Scatters particles according to normal two body collisions + // + // bindE is the binding energy (GeV) of a particle removed from the nucleus (default 0) + // For nonzero binding energy, remove the binding energy from the total energy, + // then put both of the particles back on mass shell by shifting momentum/energy + // of target + // Momentum only shifted in the direction parallel to the probe's motion + // + // Rotates final transverse component of momentum by a random angle from 0->2pi + // Return value for error checking + // Gives outgoing 4-momenta of particles 3 and 4 (t4P3L, t4P4L respectively) + // + // All 4-momenta should be on mass shell + + double E1L, E2L, P1L, P2L, E3L, P3L; + double beta, gm; // speed and gamma for CM frame in Lab + double S3CM; // sin of scattering angle + double PHI3; + double E1CM, E2CM, E3CM, P3CM;//, E4CM, P4CM; + double P3zL, P3tL;//, P4zL, P4tL; + double Et; + double theta1, theta2, theta5, P1zL, P2zL, P1tL, P2tL; + TVector3 tbeta, tbetadir, tTrans, tVect; + TVector3 tP1zCM, tP2zCM, vP3L; + TLorentzVector t4P1buf, t4P2buf, t4Ptot; + + // Library instance for reference + //PDGLibrary * pLib = PDGLibrary::Instance(); + + // random number generator + RandomGen * rnd = RandomGen::Instance(); + + // error checking + if (C3CM < -1. || C3CM > 1.) return false; + + // calculate sine from scattering angle + S3CM = TMath::Sqrt(1.0 - C3CM*C3CM); + + // fill buffers + t4P1buf = t4P1L; + t4P2buf = t4P2L; + + // get lab energy and momenta + E1L = t4P1buf.E(); + P1L = t4P1buf.P(); + E2L = t4P2buf.E(); + P2L = t4P2buf.P(); + t4Ptot = t4P1buf + t4P2buf; + + LOG("INukeUtils",pINFO) <<"M1 "< Assigning .001 as new momentum"; + P3tL = 0; + P3zL = .001; + P3L = .001; + E3L = TMath::Sqrt(P3L*P3L + M3*M3); + } + + // get random phi angle, distributed uniformally in 360 deg + PHI3 = 2 * kPi * rnd->RndFsi().Rndm(); + + vP3L = P3zL*tbetadir + P3tL*tTrans; + vP3L.Rotate(PHI3,tbetadir); + + t4P3L.SetVect(vP3L); + t4P3L.SetE(E3L); + + t4P4L = t4P1buf + t4P2buf - t4P3L; + t4P4L-= TLorentzVector(0,0,0,bindE); + /*LOG("INukeUtils",pINFO) <<"GENIE:"; + LOG("INukeUtils",pINFO) <<"E4L "<Find(p->Pdg())->Mass(); + M2 = pLib->Find(tcode)->Mass(); + M3 = pLib->Find(s1->Pdg())->Mass(); + M4 = pLib->Find(s2->Pdg())->Mass(); + M5 = pLib->Find(s3->Pdg())->Mass(); + + // set up fermi target + Target target(ev->TargetNucleus()->Pdg()); + + // handle fermi momentum + if(DoFermi) + { + target.SetHitNucPdg(tcode); + Nuclmodel->GenerateNucleon(target); + tP2L = FermiFac * Nuclmodel->Momentum3(); + P2L = tP2L.Mag(); + E2L = TMath::Sqrt(tP2L.Mag2() + M2*M2); + } + else + { + tP2L.SetXYZ(0.0, 0.0, 0.0); + P2L = 0; + E2L = M2; + } + + // first sequence, handle 4th and 5th products as composite + E1L = p->E(); + + P1L = TMath::Sqrt(E1L*E1L - M1*M1); + tP1L = p->P4()->Vect(); + tPtot = tP1L + tP2L; + + tbeta = tPtot * (1.0 / (E1L + E2L)); + tbetadir = tbeta.Unit(); + beta = tbeta.Mag(); + gm = 1.0 / TMath::Sqrt(1.0 - beta*beta); + + theta1 = tP1L.Angle(tbeta); + theta2 = tP2L.Angle(tbeta); + P1zL = P1L*TMath::Cos(theta1); + P2zL = P2L*TMath::Cos(theta2); + tVect.SetXYZ(1,0,0); + if(TMath::Abs((tVect - tbetadir).Mag())<.01) tVect.SetXYZ(0,1,0); + theta5 = tVect.Angle(tbetadir); + tTrans = (tVect - TMath::Cos(theta5)*tbetadir).Unit(); + + E1CM = gm*E1L - gm*beta*P1zL; + tP1zCM = gm*P1zL*tbetadir - gm*tbeta*E1L; + E2CM = gm*E2L - gm*beta*P2zL; + tP2zCM = gm*P2zL*tbetadir - gm*tbeta*E2L; + Et = E1CM + E2CM; + M = (rnd->RndFsi().Rndm()*(Et - M3 - M4 - M5)) + (M4 + M5); + E3CM = (Et*Et + M3*M3 - M*M)/(2*Et); + EiCM = Et - E3CM; + if(E3CM*E3CM - M3*M3<0) + { + LOG("INukeUtils",pNOTICE) + << "PionProduction P3 has non-real momentum - retry kinematics"; + LOG("INukeUtils",pNOTICE) << "Energy, masses of 3 fs particales:" + << E3CM << " " << M3 << " " << " " << M4 << " " << M5; + exceptions::INukeException exception; + exception.SetReason("PionProduction particle 3 has non-real momentum"); + throw exception; + return false; + } + P3CM = TMath::Sqrt(E3CM*E3CM - M3*M3); + + theta3 = kPi * rnd->RndFsi().Rndm(); + theta4 = kPi * rnd->RndFsi().Rndm(); + phi3 = 2*kPi * rnd->RndFsi().Rndm(); + phi4 = 2*kPi * rnd->RndFsi().Rndm(); + + P3zL = gm*beta*E3CM + gm*P3CM*TMath::Cos(theta3); + P3tL = P3CM*TMath::Sin(theta3); + PizL = gm*beta*EiCM - gm*P3CM*TMath::Cos(theta3); + PitL = -P3CM*TMath::Sin(theta3); + + P3L = TMath::Sqrt(P3zL*P3zL + P3tL*P3tL); + PiL = TMath::Sqrt(PizL*PizL + PitL*PitL); + E3L = TMath::Sqrt(P3L*P3L + M3*M3); + EiL = TMath::Sqrt(PiL*PiL + M*M); + + // handle very low momentum particles + if(!(TMath::Finite(P3L)) || P3L < .001) + { + LOG("INukeUtils",pINFO) + << "Particle 3 " << M3 << " momentum small or non-finite: " << P3L + << "\n" << "--> Assigning .001 as new momentum"; + P3tL = 0; + P3zL = .001; + P3L = .001; + E3L = TMath::Sqrt(P3L*P3L + M3*M3); + } + + tP3L = P3zL*tbetadir + P3tL*tTrans; + tPiL = PizL*tbetadir + PitL*tTrans; + tP3L.Rotate(phi3,tbetadir); + tPiL.Rotate(phi3,tbetadir); + + // second sequence, handle formally composite particles 4 and 5 + tbeta2 = tPiL * (1.0 / EiL); + tbetadir2 = tbeta2.Unit(); + beta2 = tbeta2.Mag(); + gm2 = 1.0 / TMath::Sqrt(1.0 - beta2*beta2); + + E4CM2 = (M*M + M4*M4 - M5*M5) / (2*M); + E5CM2 = M - E4CM2; + P4CM2 = TMath::Sqrt(E4CM2*E4CM2 - M4*M4); + + tVect.SetXYZ(1,0,0); + if(TMath::Abs((tVect - tbetadir2).Mag())<.01) tVect.SetXYZ(0,1,0); + theta5 = tVect.Angle(tbetadir2); + tTrans2 = (tVect - TMath::Cos(theta5)*tbetadir2).Unit(); + + P4zL = gm2*beta2*E4CM2 + gm2*P4CM2*TMath::Cos(theta4); + P4tL = P4CM2*TMath::Sin(theta4); + P5zL = gm2*beta2*E5CM2 - gm2*P4CM2*TMath::Cos(theta4); + P5tL = - P4tL; + + P4L = TMath::Sqrt(P4zL*P4zL + P4tL*P4tL); + P5L = TMath::Sqrt(P5zL*P5zL + P5tL*P5tL); + E4L = TMath::Sqrt(P4L*P4L + M4*M4); + E5L = TMath::Sqrt(P5L*P5L + M5*M5); + + // handle very low momentum particles + if(!(TMath::Finite(P4L)) || P4L < .001) + { + LOG("INukeUtils",pINFO) + << "Particle 4 " << M4 << " momentum small or non-finite: " << P4L + << "\n" << "--> Assigning .001 as new momentum"; + P4tL = 0; + P4zL = .001; + P4L = .001; + E4L = TMath::Sqrt(P4L*P4L + M4*M4); + } + if(!(TMath::Finite(P5L)) || P5L < .001) + { + LOG("INukeUtils",pINFO) + << "Particle 5 " << M5 << " momentum small or non-finite: " << P5L + << "\n" << "--> Assigning .001 as new momentum"; + P5tL = 0; + P5zL = .001; + P5L = .001; + E5L = TMath::Sqrt(P5L*P5L + M5*M5); + } + + tP4L = P4zL*tbetadir2 + P4tL*tTrans2; + tP5L = P5zL*tbetadir2 + P5tL*tTrans2; + tP4L.Rotate(phi4,tbetadir2); + tP5L.Rotate(phi4,tbetadir2); + + // pauli blocking + if(P3L < FermiMomentum || ( pdg::IsNeutronOrProton(s2->Pdg()) && P4L < FermiMomentum ) ) + { + LOG("INukeUtils",pNOTICE) + << "PionProduction fails because of Pauli blocking - retry kinematics"; + exceptions::INukeException exception; + exception.SetReason("PionProduction final state not determined"); + throw exception; + return false; + } + + // create scattered particles w/ appropriate momenta, code, and status + // Set moms to be the moms of the hadron that was cloned + s1->SetFirstMother(p->FirstMother()); + s2->SetFirstMother(p->FirstMother()); + s3->SetFirstMother(p->FirstMother()); + s1->SetLastMother(p->LastMother()); + s2->SetLastMother(p->LastMother()); + s3->SetLastMother(p->LastMother()); + + TLorentzVector(tP3L,E3L); + TLorentzVector(tP4L,E4L); + TLorentzVector(tP5L,E5L); + + s1->SetMomentum(TLorentzVector(tP3L,E3L)); + s2->SetMomentum(TLorentzVector(tP4L,E4L)); + s3->SetMomentum(TLorentzVector(tP5L,E5L)); + int mode = kIMdHA; + LOG ("INukeUtils",pDEBUG) << "in Pi Prod, mode = " << mode; + if (mode==kIMdHN) + { + s1->SetStatus(kIStHadronInTheNucleus); + s2->SetStatus(kIStHadronInTheNucleus); + s3->SetStatus(kIStHadronInTheNucleus); + } + else + { + s1->SetStatus(kIStStableFinalState); + s2->SetStatus(kIStStableFinalState); + s3->SetStatus(kIStStableFinalState); + } + return true; +} +//___________________________________________________________________________ +bool genie::utils::intranuke2025::PionProduction( + GHepRecord* ev, GHepParticle* p, GHepParticle* s1, GHepParticle* s2, GHepParticle* s3, int &RemnA, int &RemnZ, + TLorentzVector &RemnP4, bool DoFermi, double FermiFac, double FermiMomentum, const NuclearModelI* Nuclmodel) +{ + // Aaron Meyer (7/15/2010) + // + // Handles pion production reactions in both hA and hN mode + // Calculates fundamental cross sections from fit functions + // Uses isospin relations to determine the rest of cross sections + // + // p is the probe particle + // s1, s2, and s3 are the particles produced in the reaction + // must set the status and add particles to the event record after returning from this method + // return value for error checking + + + // random number generator + RandomGen * rnd = RandomGen::Instance(); + + // library reference + PDGLibrary * pLib = PDGLibrary::Instance(); + + bool ptarg = false; + int pcode = p->Pdg(); + + int p1code = p->Pdg(); + // Randomly determine target and 1st product baryons + int p3code = 0, p4code = 0, p5code = 0; + + // + // Uses a fit curve log(sigma) = a - b/(T_pi - c) for pions + // Fit parameters determined by Roman Tacik (4/3/09) + // pi- & p cross sections are assumed to be the same as pi+ & n + // + // Fit curve for nucleons: + // sigma = a*(1+b*e^(-c*(eta-d)^2))*(1-e^(-(f*eta)^g))*(1-e^(-h/eta^2)) + // 7 parameters (a,b,c,d,f,g,h) + // eta is maximum kinematically allowed momentum of the pion, normalized by the mass + // Uses isotopic spin decomposition of total cross sections + // + + if ((p1code==kPdgPi0)||(p1code==kPdgPiP)||(p1code==kPdgPiM)) { + + double kine = 1000*p->KinE(); + + // Determine cross sections + + // pion + // pi- & p + // -> pi0 & pi0 & n + // a = 8.82; b = 573.2; c = 107.3; + double xsec2pi0n = TMath::Max(0.,TMath::Exp(8.82 - (573.2/(kine-107.3)))); + // -> pi- & pi+ & n + // a = 11.06; b = 985.9; c = 88.2; + double xsecpippimn = TMath::Max(0.,TMath::Exp(11.06 - (985.9/(kine-88.2)))); + // -> pi- & pi0 & p + // a = 9.58; b = 1229.4; c = 60.5; + double xsecpimpi0p = TMath::Max(0.,TMath::Exp(9.58 - (1229.4/(kine-60.5)))); + double totpimp = xsec2pi0n + xsecpippimn + xsecpimpi0p; + + + // pi+ & p + // -> pi+ & pi+ & n + // a = 5.64; b = 222.6; c = 150.0; + double xsec2pipn = TMath::Max(0.,TMath::Exp(5.64 - (222.6/(kine-150.)))); + // -> pi+ & pi0 & p + // a = 7.95; b = 852.6; c = 77.8; + double xsecpippi0p = TMath::Max(0.,TMath::Exp(7.95 - (852.6/(kine-77.8)))); + double totpipp = xsec2pipn + xsecpippi0p; + + if (totpimp<=0 && totpipp<=0) { + LOG("INukeUtils",pNOTICE) << "InelasticHN called below threshold energy"; + p->SetStatus(kIStHadronInTheNucleus); + ev->AddParticle(*p); + return false; + } + + double xsecp, xsecn; + switch (p1code) { + case kPdgPi0: xsecp = 0.5 * (totpimp + totpipp); xsecn = xsecp; break; + case kPdgPiP: xsecp = totpipp; xsecn = totpimp; break; + case kPdgPiM: xsecp = totpimp; xsecn = totpipp; break; + default: + LOG("INukeUtils",pWARN) << "InelasticHN cannot handle probe: " + << PDGLibrary::Instance()->Find(p1code)->GetName(); + exceptions::INukeException exception; + exception.SetReason("PionProduction final state not determined"); + throw exception; + return false; + break; + } + + // Normalize cross sections by Z or A-Z + + xsecp *= RemnZ; + xsecn *= RemnA-RemnZ; + + // determine target + + double rand = rnd->RndFsi().Rndm() * (xsecp + xsecn); + if (rand < xsecp) // proton target + { rand /= RemnZ; ptarg = true;} + else // neutron target + { rand -= xsecp; rand /= RemnA-RemnZ; ptarg = false;} + + + // determine final state + + if (((ptarg==true)&&(p1code==kPdgPiP)) + || ((ptarg==false)&&(p1code==kPdgPiM))) + { + if (rand < xsec2pipn) // pi+ & pi+ & n final state + { + p3code = (ptarg ? kPdgNeutron : kPdgProton); + p4code = p1code; + p5code = p1code; + } + else { // pi+ & pi0 & p final state + p3code = (ptarg ? kPdgProton : kPdgNeutron); + p4code = p1code; + p5code = kPdgPi0; + } + } + else if (((ptarg==false)&&(p1code==kPdgPiP)) + || ((ptarg==true)&&(p1code==kPdgPiM))) + { + if (rand < xsec2pi0n) // pi0 & pi0 & n final state + { + p3code = (ptarg ? kPdgNeutron : kPdgProton); + p4code = kPdgPi0; + p5code = p4code; + } + else if (rand < (xsec2pi0n + xsecpippimn)) // pi+ & pi- & n final state + { + p3code = (ptarg ? kPdgNeutron : kPdgProton); + p4code = p1code; + p5code = ((p1code==kPdgPiP) ? kPdgPiM : kPdgPiP); + } + else // pi0 & pi- & p final state + { + p3code = (ptarg ? kPdgProton : kPdgNeutron); + p4code = p1code; + p5code = kPdgPi0; + } + } + else if (p1code==kPdgPi0) + { + rand = rnd->RndFsi().Rndm(); + if (rand < 191./270.) //unknown source, likely data in narrow energy range - sd + { // pi+ & pi- & p final state + p3code = (ptarg ? kPdgProton : kPdgNeutron); + p4code = kPdgPiP; + p5code = kPdgPiM; + } + else if (rand < 7./135.) //unknown source, likely data in narrow energy range - sd + { // pi0 & pi0 & p final state + p3code = (ptarg ? kPdgProton : kPdgNeutron); + p4code = kPdgPi0; + p5code = kPdgPi0; + } + else + { // pi+ & pi0 & n final state + p3code = (ptarg ? kPdgNeutron : kPdgProton); + p4code = (ptarg ? kPdgPiP : kPdgPiM); + p5code = kPdgPi0; + } + } + else // unhandled + { + LOG("INukeUtils",pNOTICE) << "Pi production final state unable to be determined, picode, ptarg = " <Find(p1code)->GetName() << " " << PDGLibrary::Instance()->Find(ptarg)->GetName(); + exceptions::INukeException exception; + exception.SetReason("PionProduction final state not determined"); + throw exception; + return false; + } + + } else if(p1code==kPdgProton||p1code==kPdgNeutron) //nucleon probes + { + + double tote = p->Energy(); + double pMass = pLib->Find(2212)->Mass(); + double nMass = pLib->Find(2112)->Mass(); + double etapp2ppPi0 = + utils::intranuke2025::CalculateEta(pMass,tote,pMass,pMass+pMass,pLib->Find(111)->Mass()); + double etapp2pnPip = + utils::intranuke2025::CalculateEta(pLib->Find(p1code)->Mass(),tote,((p1code==kPdgProton)?pMass:nMass), + pMass+nMass,pLib->Find(211)->Mass()); + double etapn2nnPip = + utils::intranuke2025::CalculateEta(pMass,tote,nMass,nMass+nMass,pLib->Find(211)->Mass()); + double etapn2ppPim = + utils::intranuke2025::CalculateEta(pMass,tote,nMass,pMass+pMass,pLib->Find(211)->Mass()); + + if ((etapp2ppPi0<=0.)&&(etapp2pnPip<=0.)&&(etapn2nnPip<=0.)&&(etapn2ppPim<=0.)) { // below threshold + LOG("INukeUtils",pNOTICE) << "PionProduction() called below threshold energy"; + exceptions::INukeException exception; + exception.SetReason("PionProduction final state not possible - below threshold"); + throw exception; + return false; + } + + // calculate cross sections + double xsecppPi0=0,xsecpnPiP=0,xsecnnPiP=0,xsecppPiM=0; + if (etapp2ppPi0>0){ + xsecppPi0 = 4511*(1-.91*TMath::Exp(-TMath::Power((etapp2ppPi0-.705),2))); + xsecppPi0 *= (1-TMath::Exp(-TMath::Power((.556*etapp2ppPi0),3.5))); + xsecppPi0 *= (1-TMath::Exp(-56.897/(etapp2ppPi0*etapp2ppPi0))); + xsecppPi0 = TMath::Max(0.,xsecppPi0);} + + if (etapp2pnPip>0){ + xsecpnPiP = 18840*(1-.808*TMath::Exp(-TMath::Power((etapp2pnPip-.371),2))); + xsecpnPiP *= (1-TMath::Exp(-TMath::Power((.568*etapp2pnPip),3.2))); + xsecpnPiP *= (1-TMath::Exp(-39.818/(etapp2pnPip*etapp2pnPip))); + xsecpnPiP = TMath::Max(0.,xsecpnPiP);} + + if (etapn2nnPip>0){ + xsecnnPiP = 7670*(1-.479*TMath::Exp(-TMath::Power((etapn2nnPip-.947),2))); + xsecnnPiP *= (1-TMath::Exp(-TMath::Power((.35*etapn2nnPip),3.2))); + xsecnnPiP *= (1-TMath::Exp(-71.53/(etapn2nnPip*etapn2nnPip))); + xsecnnPiP = TMath::Max(0.,xsecnnPiP);} + + if (etapn2ppPim>0){ + xsecppPiM = 7670*(1-.479*TMath::Exp(-TMath::Power((etapn2ppPim-.947),2))); + xsecppPiM *= (1-TMath::Exp(-TMath::Power((.35*etapn2ppPim),3.2))); + xsecppPiM *= (1-TMath::Exp(-71.53/(etapn2ppPim*etapn2ppPim))); + xsecppPiM = TMath::Max(0.,xsecppPiM);} + + // double sigma11 = xsecppPi0; + double sigma10 = TMath::Max(0.,xsecpnPiP - xsecppPi0); // Fundamental cross sections + double sigma01 = TMath::Max(0.,xsecppPiM + xsecnnPiP - xsecppPi0); + + double xsecpnPi0 = .5*(sigma10 + sigma01); + xsecpnPi0 = TMath::Max(xsecpnPi0,0.); + + LOG("INukeUtils",pDEBUG) << '\n' << "Cross section values: "<<'\n' + << xsecppPi0 << " PP pi0" <<'\n' + << xsecpnPiP << " PN pi+" <<'\n' + << xsecnnPiP << " NN pi+" <<'\n' + << xsecpnPi0 << " PN pi0"; + + double xsecp=0,xsecn=0; + switch (p1code) { + case kPdgProton: xsecp=xsecppPi0+xsecpnPiP; xsecn=xsecppPiM+xsecnnPiP+xsecpnPi0; break; + case kPdgNeutron: xsecp=xsecppPiM+xsecnnPiP+xsecpnPi0; xsecn=xsecppPi0+xsecpnPiP; break; + default: + LOG("INukeUtils",pWARN) << "InelasticHN cannot handle probe: " + << PDGLibrary::Instance()->Find(p1code)->GetName(); + return false; + break; + } + + // Normalize cross sections by Z or (A-Z) + + xsecp *= RemnZ; + xsecn *= RemnA-RemnZ; + + // determine target + + double rand = rnd->RndFsi().Rndm() * (xsecp + xsecn); + if (rand < xsecp) // proton target + { rand /= RemnZ; ptarg = true;} + else // neutron target + { rand -= xsecp; rand /= RemnA-RemnZ; ptarg = false;} + + if(p1code==kPdgProton) // Cross sections not explicitly given are calculated from isospin relations + { + if(ptarg) + { + if (randSetPdgCode(p3code); + s2->SetPdgCode(p4code); + s3->SetPdgCode(p5code); + + if(genie::utils::intranuke2025::ThreeBodyKinematics( + ev,p,(ptarg?kPdgProton:kPdgNeutron),s1,s2,s3,DoFermi,FermiFac,FermiMomentum,Nuclmodel)) + { + // okay, handle remnants and return true + // assumes first particle is always the nucleon, + // second can be either nucleon or pion + // last always pion + if (pcode==kPdgProton || pcode==kPdgPiP) RemnZ++; + if (pcode==kPdgPiM) RemnZ--; + if (pdg::IsPion(pcode)) RemnA--; + if (pdg::IsProton(p3code)) RemnZ--; + if (pdg::IsNeutronOrProton(p4code)) RemnA--; + if (p4code==kPdgPiP || p4code==kPdgProton) RemnZ--; + if (p4code==kPdgPiM) RemnZ++; + if (p5code==kPdgPiP) RemnZ--; + if (p5code==kPdgPiM) RemnZ++; + + LOG("INukeUtils",pDEBUG) << "Remnant (A,Z) = (" <P4() + *s2->P4() + *s3->P4() - *p->P4(); + return true; + } + else { + exceptions::INukeException exception; + exception.SetReason("PionProduction final state not determined"); + throw exception; + return false; + } +} +//___________________________________________________________________________ +double genie::utils::intranuke2025::CalculateEta(double Minc, double nrg, double Mtarg, + double Mtwopart, double Mpi) +{ + //Aaron Meyer (1/20/2010) + + //Used to calculate the maximum kinematically allowed CM frame pion momentum + // ke in MeV, eta normalized by pion mass + // approximated by taking two ejected nucleons to be one particle of the same mass + //For pion cross sections, in utils::intranuke2025::PionProduction + + //LOG("INukeUtils",pDEBUG) << "Input values: "< 1); + + LOG("INukeUtils",pINFO) << "probe mass: M = " << p->Mass(); + + // Get the decay product masses & names + + ostringstream state_sstream; + state_sstream << "( "; + vector::const_iterator pdg_iter; + int i = 0; + double * mass = new double[pdgv.size()]; + double mass_sum = 0; + for(pdg_iter = pdgv.begin(); pdg_iter != pdgv.end(); ++pdg_iter) { + int pdgc = *pdg_iter; + double m = PDGLibrary::Instance()->Find(pdgc)->Mass(); + string nm = PDGLibrary::Instance()->Find(pdgc)->GetName(); + mass[i++] = m; + mass_sum += m; + state_sstream << nm << " "; + } + state_sstream << ")"; + + TLorentzVector * pd = p->GetP4(); // incident particle 4p + + bool is_nuc = pdg::IsNeutronOrProton(p->Pdg()); + bool is_kaon = p->Pdg()==kPdgKP || p->Pdg()==kPdgKM; + // not used // bool is_pion = p->Pdg()==kPdgPiP || p->Pdg()==kPdgPi0 || p->Pdg()==kPdgPiM; + // update available energy -> init (mass + kinetic) + sum of f/s masses + // for pion only. Probe mass not available for nucleon, kaon + double availE = pd->Energy() + mass_sum; + if(is_nuc||is_kaon) availE -= p->Mass(); + pd->SetE(availE); + + LOG("INukeUtils",pNOTICE) + << "size, mass_sum, availE, pd mass, energy = " << pdgv.size() << " " + << mass_sum << " " << availE << " " << p->Mass() << " " << p->Energy() ; + + // compute the 4p transfer to the hadronic blob + double dE = mass_sum; + if(is_nuc||is_kaon) dE -= p->Mass(); + TLorentzVector premnsub(0,0,0,dE); + RemnP4 -= premnsub; + + LOG("INukeUtils", pINFO) + << "Final state = " << state_sstream.str() << " has N = " << pdgv.size() + << " particles / total mass = " << mass_sum; + LOG("INukeUtils", pINFO) + << "Composite system p4 = " << utils::print::P4AsString(pd); + + // Set the decay + TGenPhaseSpace GenPhaseSpace; + bool permitted = GenPhaseSpace.SetDecay(*pd, pdgv.size(), mass); + if(!permitted) { + LOG("INukeUtils", pERROR) + << " *** Phase space decay is not permitted \n" + << " Total particle mass = " << mass_sum << "\n" + << " Decaying system p4 = " << utils::print::P4AsString(pd); + + // clean-up and return + RemnP4 += premnsub; + delete [] mass; + delete pd; + return false; + } + + // The decay is permitted - add the incident particle at the event record + // and mark is as 'Nucleon Cluster Target' (used to be confusing 'Decayed State') + p->SetStatus(kIStNucleonClusterTarget); //kIStDecayedState); + p->SetPdgCode(kPdgCompNuclCluster); + ev->AddParticle(*p); + // Get the maximum weight + double wmax = -1; + for(int k=0; k<200; k++) { + double w = GenPhaseSpace.Generate(); + wmax = TMath::Max(wmax,w); + } + assert(wmax>0); + + LOG("INukeUtils", pINFO) + << "Max phase space gen. weight @ current hadronic interaction: " << wmax; + + // Generate an unweighted decay + + RandomGen * rnd = RandomGen::Instance(); + wmax *= 1.2; + + bool accept_decay=false; + unsigned int itry=0; + + while(!accept_decay) + { + itry++; + + if(itry>kMaxUnweightDecayIterations) { + // report, clean-up and return + LOG("INukeUtils", pNOTICE) + << "Couldn't generate an unweighted phase space decay after " + << itry << " attempts"; + delete [] mass; + delete pd; + return false; + } + + double w = GenPhaseSpace.Generate(); + double gw = wmax * rnd->RndFsi().Rndm(); + + if(w > wmax) { + LOG("INukeUtils", pNOTICE) + << "Decay weight = " << w << " > max decay weight = " << wmax; + } + + LOG("INukeUtils", pNOTICE) << "Decay weight = " << w << " / R = " << gw; + accept_decay = (gw<=w); + } + + // Insert final state products into the event record + // - the particles are added as daughters of the decayed state + // - the particles are marked as final stable state (in hA mode) + i=0; + int mom = ev->ParticlePosition(p); + LOG("INukeUtils", pNOTICE) << "mother index = " << mom; + GHepStatus_t ist = kIStStableFinalState; + GHepStatus_t ist_pi = kIStHadronInTheNucleus; + + TLorentzVector * v4 = p->GetX4(); + + double checkpx = p->Px(); + double checkpy = p->Py(); + double checkpz = p->Pz(); + double checkE = p->E(); + + //LOG("INukeUtils", PNOTICE) + + for(pdg_iter = pdgv.begin(); pdg_iter != pdgv.end(); ++pdg_iter) { + + //-- current PDG code + int pdgc = *pdg_iter; + bool isnuc = pdg::IsNeutronOrProton(pdgc); + + //-- get the 4-momentum of the i-th final state particle + TLorentzVector * p4fin = GenPhaseSpace.GetDecay(i++); + + //-- intranuke no longer throws "bindinos" but adds all the energy + // not going at a simulated f/s particle at a "hadronic blob" + // representing the remnant system: do the binding energy subtraction + // here & update the remnant hadronic system 4p + double M = PDGLibrary::Instance()->Find(pdgc)->Mass(); + double En = p4fin->Energy(); + + double KE = En-M; + + //double KE = En; + //if(is_pion) KE -= M; + + double dE_leftover = TMath::Min(NucRmvE, KE); + KE -= dE_leftover; + En = KE+M; + double pmag_old = p4fin->P(); + double pmag_new = TMath::Sqrt(TMath::Max(0.,En*En-M*M)); + double scale = pmag_new / pmag_old; + double pxn = scale * p4fin->Px(); + double pyn = scale * p4fin->Py(); + double pzn = scale * p4fin->Pz(); + + TLorentzVector p4n(pxn,pyn,pzn,En); + // LOG("INukeUtils", pNOTICE) << "Px = " << pxn << " Py = " << pyn + // << " Pz = " << pzn << " E = " << KE; + checkpx -= pxn; + checkpy -= pyn; + checkpz -= pzn; + checkE -= KE; + + if (mode==kIMdHA && + (pdgc==kPdgPiP || pdgc==kPdgPi0 || pdgc==kPdgPiM) ) + { + if (p4n.Vect().Mag()>=0.001) + { + GHepParticle new_particle(pdgc, ist_pi, mom,-1,-1,-1, p4n, *v4); + ev->AddParticle(new_particle); + } + else + { + // Momentum too small, assign a non-zero momentum to the particle + // Conserve momentum with the remnant nucleus + + LOG("INukeUtils", pINFO)<<"Momentum too small; assigning 0.001 as new momentum"; + + double phi = 2*kPi*rnd->RndFsi().Rndm(); + double omega = 2*rnd->RndFsi().Rndm(); + // throw number against solid angle for uniform distribution + + double E4n = TMath::Sqrt(0.001*0.001+M*M); + p4n.SetPxPyPzE(0.001,0,0,E4n); + p4n.Rotate(TMath::ACos(1-omega),TVector3(0,0,1)); + p4n.Rotate(phi,TVector3(1,0,0)); + + RemnP4 -= (p4n - TLorentzVector(0,0,0,M)); + + GHepParticle new_particle(pdgc, ist, mom,-1,-1,-1, p4n, *v4); + ev->AddParticle(new_particle); + } + } + else + { + GHepParticle new_particle(pdgc, ist, mom,-1,-1,-1, p4n, *v4); + + if(isnuc) new_particle.SetRemovalEnergy(0.); + ev->AddParticle(new_particle); + } + + double dpx = (1-scale)*p4fin->Px(); + double dpy = (1-scale)*p4fin->Py(); + double dpz = (1-scale)*p4fin->Pz(); + TLorentzVector premnadd(dpx,dpy,dpz,dE_leftover); + RemnP4 += premnadd; + } + //LOG("INukeUtils", pNOTICE) << "TEST: " << p->Mass(); + LOG("INukeUtils", pNOTICE) << "check conservation: Px = " << checkpx << " Py = " << checkpy + << " Pz = " << checkpz << " E = " << checkE; + + // Clean-up + delete [] mass; + delete pd; + delete v4; + + return true; +} + +double genie::utils::intranuke2025::sigmaTotalOset ( + const double &pionKineticEnergy, + const double &density, + const int &pionPDG, + const double &protonFraction, + const bool &isTableChosen + ) +{ + // ------ OsetCrossSection init (only first time function is called) ------ // + static INukeOset *iNukeOset = NULL; + + if (iNukeOset == NULL) + { + if (isTableChosen) + { + // set directory with data on first call + static const std::string dataDir = (gSystem->Getenv("GINUKEHADRONDATA")) ? + string(gSystem->Getenv("GINUKEHADRONDATA")) : + string(gSystem->Getenv("GENIE")) + + string("/") + + string("/data/evgen/intranuke/"); + // set file with Oset table on first call + static const std::string dataFile = dataDir + "tot_xsec/" + "intranuke-xsection-pi+N-Oset.dat"; + // initialize OsetCrossSection on first call + iNukeOset = new INukeOsetTable (dataFile.c_str()); + } + else iNukeOset = new INukeOsetFormula(); + } + // ------ OsetCrossSection init (only first time function is called) ------ // + + // set up Oset class (assign pion Tk, nuclear density etc) + iNukeOset->setupOset (density, pionKineticEnergy, pionPDG, protonFraction); + + return iNukeOset->getTotalCrossSection(); + +} diff --git a/src/Physics/HadronTransport/INukeUtils2025.h b/src/Physics/HadronTransport/INukeUtils2025.h new file mode 100644 index 0000000000..514b58d0bf --- /dev/null +++ b/src/Physics/HadronTransport/INukeUtils2025.h @@ -0,0 +1,127 @@ +//____________________________________________________________________________ +/*! + +\namespace genie::intranuke + +\brief INTRANUKE utilities: + mean free path methods used to determine where hadron interactions happen + 2-body scattering and pion production kinematics. + Phase space 'decay' of pseudostates, e.g. multinucleon, used in pion absorption and nucleon knowckout + Reweighting methods + +\author Jim Dobson + Imperial College London + + Costas Andreopoulos + University of Liverpool + + Aaron Meyer + Pittsburgh University + +\created Mar 03, 2009 + +\cpright Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + +*/ +//____________________________________________________________________________ + +#ifndef _INTRANUKE_UTILS_2025_H_ +#define _INTRANUKE_UTILS_2025_H_ + +#include + +#include "Physics/NuclearState/NuclearModelI.h" +#include "Physics/HadronTransport/INukeHadroFates2025.h" +#include "Physics/HadronTransport/INukeMode.h" +#include "Physics/HadronTransport/INukeNucleonCorr.h" + +class TLorentzVector; + +namespace genie { + +class GHepRecord; +class GHepParticle; +class Intranuke2025; +class PDGCodeList; + +namespace utils { +namespace intranuke2025 +{ + //! Hadron survival probability + double ProbSurvival( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, double A, + double Z, double mfp_scale_factor, const Intranuke2025& fsi_model ); + + //! Mean free path (pions, nucleons) + double MeanFreePath( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, double A, + double Z, double nRpi=0.5, double nRnuc=1.0, const bool useOset = false, const bool altOset = false, const bool xsecNNCorr = false, string INukeMode = "XX2025"); + + //! Mean free path (Delta++ **test**) + double MeanFreePath_Delta( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, double A ); + + //! Distance to exit + double Dist2Exit( + const TLorentzVector & x4, const TLorentzVector & p4, + double A, double NR=3, double R0=1.4); + + //! Distance to exit + double Dist2ExitMFP( + int pdgc, const TLorentzVector & x4, const TLorentzVector & p4, + double A, double Z, double NR=3, double R0=1.4); + + //! Step particle + void StepParticle( + GHepParticle * p, double step, double nuclear_radius=-1.); + + + //! Intranuke utility functions + + bool TwoBodyCollision( + GHepRecord* ev, int pcode, int tcode, int scode, int s2code, double C3CM, GHepParticle* p, + GHepParticle* t, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, EINukeMode mode=kIMdHA); + + bool TwoBodyKinematics( + double M3, double M4, TLorentzVector tP1L, TLorentzVector tP2L, + TLorentzVector &tP3L, TLorentzVector &tP4L, double C3CM, TLorentzVector &RemnP4, double bindE=0); + + bool ThreeBodyKinematics( + GHepRecord* ev, GHepParticle* p, int tcode, GHepParticle* s1, GHepParticle* s2, GHepParticle* s3, + bool DoFermi=false, double FermiFac=0, double FermiMomentum=0, const NuclearModelI* Nuclmodel=(const NuclearModelI*)0); + + bool PionProduction( + GHepRecord* ev, GHepParticle* p, GHepParticle* s1, GHepParticle* s2, GHepParticle* s3, int &RemnA, int &RemnZ, + TLorentzVector &RemnP4,bool DoFermi, double FermiFac, double FermiMomentum, const NuclearModelI* Nuclmodel); + + double CalculateEta( + double Minc, double ke, double Mtarg, double Mtwopart, double Mpi); + + void Equilibrium( + GHepRecord* ev, GHepParticle* p, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, + double FermiFac, const NuclearModelI* Nuclmodel, double NucRmvE, EINukeMode mode=kIMdHN); + + void PreEquilibrium( + GHepRecord* ev, GHepParticle* p, int &RemnA, int &RemnZ, TLorentzVector &RemnP4, bool DoFermi, + double FermiFac, const NuclearModelI* Nuclmodel, double NucRmvE, EINukeMode mode=kIMdHN); + + + //! general phase space decay method + bool PhaseSpaceDecay ( + GHepRecord* ev, GHepParticle* p, const PDGCodeList & pdgv, TLorentzVector &RemnP4, + double NucRmvE, EINukeMode mode=kIMdHA); + + // calculate pion-nucleon total cross section based on Oset model + // use only for pion with kinetic energy up to 350 MeV + double sigmaTotalOset (const double &pionKineticEnergy, const double &density, + const int &pionPDG, const double &protonFraction, + const bool &isTableChosen = true + ); + +} // intranuke namespace +} // utils namespace +} // genie namespace + + +#endif // _INTRANUKE_UTILS_2025_H_ diff --git a/src/Physics/HadronTransport/Intranuke2025.cxx b/src/Physics/HadronTransport/Intranuke2025.cxx new file mode 100644 index 0000000000..c071352da9 --- /dev/null +++ b/src/Physics/HadronTransport/Intranuke2025.cxx @@ -0,0 +1,407 @@ +//____________________________________________________________________________ +/* + Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + + Author: Steve Dytman , Pittsburgh Univ. + Aaron Meyer , Pittsburgh Univ. + Alex Bell, Pittsburgh Univ. + Hugh Gallagher , Tufts Univ. + Costas Andreopoulos , Rutherford Lab. + September 20, 2005 + + For the class documentation see the corresponding header file. + + Important revisions after version 2.0.0 : + @ Oct, 2025 - SD, MI establish hA2025 and hN2025, start with identical code of 2018 versions. + +*/ +//____________________________________________________________________________ + +#include +#include + +#include + +#include "Framework/Algorithm/AlgConfigPool.h" +#include "Framework/Algorithm/AlgFactory.h" +#include "Framework/Conventions/GBuild.h" +#include "Framework/Conventions/Constants.h" +#include "Framework/Conventions/Controls.h" +#include "Framework/GHEP/GHepStatus.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Physics/HadronTransport/Intranuke2025.h" +#include "Physics/HadronTransport/INukeHadroData2025.h" +#include "Physics/HadronTransport/INukeHadroFates.h" +#include "Physics/HadronTransport/INukeMode.h" +#include "Physics/HadronTransport/INukeUtils2025.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Messenger/Messenger.h" +#include "Framework/Numerical/RandomGen.h" +#include "Framework/Numerical/Spline.h" +#include "Framework/ParticleData/PDGLibrary.h" +#include "Framework/ParticleData/PDGCodes.h" +#include "Framework/ParticleData/PDGCodeList.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/Utils/PrintUtils.h" +#include "Physics/NuclearState/NuclearUtils.h" + +using std::ostringstream; + +using namespace genie; +using namespace genie::utils; +using namespace genie::constants; +using namespace genie::controls; + +//___________________________________________________________________________ +Intranuke2025::Intranuke2025() : +EventRecordVisitorI() +{ + +} +//___________________________________________________________________________ +Intranuke2025::Intranuke2025(string name) : +EventRecordVisitorI(name) +{ + +} +//___________________________________________________________________________ +Intranuke2025::Intranuke2025(string name, string config) : +EventRecordVisitorI(name, config) +{ + +} +//___________________________________________________________________________ +Intranuke2025::~Intranuke2025() +{ + +} +//___________________________________________________________________________ +void Intranuke2025::ProcessEventRecord(GHepRecord * evrec) const +{ + // Do not continue if there is no nuclear target + GHepParticle * nucltgt = evrec->TargetNucleus(); + if (!nucltgt) { + LOG("Intranuke2025", pINFO) << "No nuclear target found - INTRANUKE exits"; + return; + } + + // Decide tracking radius for the current nucleus (few * R0 * A^1/3) + this->SetTrackingRadius(nucltgt); + + // Understand what the event generation mode is (hadron/photon-nucleus, + // lepton-nucleus, nucleon decay) from the input event. + // The determined mode has an effect on INTRANUKE behaviour (how to lookup + // the residual nucleus, whether to set an intranuclear vtx etc) but it + // does not affect the INTRANUKE physics. + fGMode = evrec->EventGenerationMode(); + + // For lepton-nucleus scattering and for nucleon decay intranuclear vtx + // position (in the target nucleus coord system) is set elsewhere. + // This method only takes effect in hadron/photon-nucleus interactions. + // In this special mode, an interaction vertex is set at the periphery + // of the target nucleus. +// This is the only exception to the general case of setting vertex according to nuclear density presently anticipated. + if(fGMode == kGMdHadronNucleus || + fGMode == kGMdPhotonNucleus) + { + this->GenerateVertex(evrec); + } + + // Now transport all hadrons outside the tracking radius. + // Stepping part is common for both HA and HN. + // Once it has been estabished that an interaction takes place then + // HA and HN specific code takes over in order to simulate the final state. + this->TransportHadrons(evrec); +} +//___________________________________________________________________________ +void Intranuke2025::GenerateVertex(GHepRecord * evrec) const +{ +// Sets a vertex in the nucleus periphery +// Called onlt in hadron/photon-nucleus interactions. + + GHepParticle * nucltgt = evrec->TargetNucleus(); + assert(nucltgt); + + RandomGen * rnd = RandomGen::Instance(); + TVector3 vtx(999999.,999999.,999999.); + + // *** For h+A events (test mode): + // Assume a hadron beam with uniform intensity across an area, + // so we need to choose events uniformly within that area. + double x=999999., y=999999., epsilon = 0.001; + double R2 = TMath::Power(fTrackingRadius,2.); + double rp2 = TMath::Power(x,2.) + TMath::Power(y,2.); + while(rp2 > R2-epsilon) { + x = (fTrackingRadius-epsilon) * rnd->RndFsi().Rndm(); + y = -fTrackingRadius + 2*fTrackingRadius * rnd->RndFsi().Rndm(); + y -= ((y>0) ? epsilon : -epsilon); + rp2 = TMath::Power(x,2.) + TMath::Power(y,2.); + } + vtx.SetXYZ(x,y, -1.*TMath::Sqrt(TMath::Max(0.,R2-rp2)) + epsilon); + + // get the actual unit vector along the incoming hadron direction + TVector3 direction = evrec->Probe()->P4()->Vect().Unit(); + + // rotate the vtx position + vtx.RotateUz(direction); + + LOG("Intranuke2025", pNOTICE) + << "Generated vtx @ R = " << vtx.Mag() << " fm / " + << print::Vec3AsString(&vtx); + + TObjArrayIter piter(evrec); + GHepParticle * p = 0; + while( (p = (GHepParticle *) piter.Next()) ) + { + if(pdg::IsPseudoParticle(p->Pdg())) continue; + if(pdg::IsIon (p->Pdg())) continue; + + p->SetPosition(vtx.x(), vtx.y(), vtx.z(), 0.); + } +} +//___________________________________________________________________________ +void Intranuke2025::SetTrackingRadius(const GHepParticle * p) const +{ + assert(p && pdg::IsIon(p->Pdg())); + double A = p->A(); + fTrackingRadius = fR0 * TMath::Power(A, 1./3.); + + // multiply that by some input factor so that hadrons are tracked + // beyond the nuclear 'boundary' since the nuclear density distribution + // is not zero there + fTrackingRadius *= fNR; + + LOG("Intranuke2025", pNOTICE) + << "Setting tracking radius to R = " << fTrackingRadius; +} +//___________________________________________________________________________ +bool Intranuke2025::NeedsRescattering(const GHepParticle * p) const +{ +// checks whether the particle should be rescattered + + assert(p); + + if(fGMode == kGMdHadronNucleus || + fGMode == kGMdPhotonNucleus) { + // hadron/photon-nucleus scattering propagate the incoming particle + return ( + (p->Status() == kIStInitialState || p->Status() == kIStHadronInTheNucleus) + && !pdg::IsIon(p->Pdg())); + } + else { + // attempt to rescatter anything marked as 'hadron in the nucleus' + return (p->Status() == kIStHadronInTheNucleus); + } +} +//___________________________________________________________________________ +bool Intranuke2025::CanRescatter(const GHepParticle * p) const +{ +// checks whether a particle that needs to be rescattered, can in fact be +// rescattered by this cascade MC + + assert(p); + return ( p->Pdg() == kPdgPiP || + p->Pdg() == kPdgPiM || + p->Pdg() == kPdgPi0 || + p->Pdg() == kPdgProton || + p->Pdg() == kPdgNeutron || + // p->Pdg() == kPdgGamma || + p->Pdg() == kPdgKP //|| + // p->Pdg() == kPdgKM + ); +} +//___________________________________________________________________________ +bool Intranuke2025::IsInNucleus(const GHepParticle * p) const +{ +// check whether the input particle is still within the nucleus +// + return (p->X4()->Vect().Mag() < fTrackingRadius + fHadStep); +} +//___________________________________________________________________________ +void Intranuke2025::TransportHadrons(GHepRecord * evrec) const +{ +// transport all hadrons outside the nucleus + + int inucl = -1; + fRemnA = -1; + fRemnZ = -1; + + // Get 'nuclear environment' at the beginning of hadron transport + // and keep track of the remnant nucleus A,Z + + if(fGMode == kGMdHadronNucleus || + fGMode == kGMdPhotonNucleus) + { + inucl = evrec->TargetNucleusPosition(); + } + else if(fGMode == kGMdLeptonNucleus || + fGMode == kGMdDarkMatterNucleus || + fGMode == kGMdNucleonDecay) { + inucl = evrec->RemnantNucleusPosition(); + } + + LOG("Intranuke2025", pNOTICE) + << "Propagating hadrons within nucleus found in position = " << inucl; + GHepParticle * nucl = evrec->Particle(inucl); + if(!nucl) { + LOG("Intranuke2025", pERROR) + << "No nucleus found in position = " << inucl; + LOG("Intranuke2025", pERROR) + << *evrec; + return; + } + + fRemnA = nucl->A(); + fRemnZ = nucl->Z(); + + LOG("Intranuke2025", pNOTICE) + << "Nucleus (A,Z) = (" << fRemnA << ", " << fRemnZ << ")"; + + const TLorentzVector & p4nucl = *(nucl->P4()); + fRemnP4 = p4nucl; + + // Loop over GHEP and run intranuclear rescattering on handled particles + TObjArrayIter piter(evrec); + GHepParticle * p = 0; + int icurr = -1; + + while( (p = (GHepParticle *) piter.Next()) ) + { + icurr++; + + // Check whether the particle needs rescattering, otherwise skip it + if( ! this->NeedsRescattering(p) ) continue; + + LOG("Intranuke2025", pNOTICE) + << " >> Stepping a " << p->Name() + << " with kinetic E = " << p->KinE() << " GeV"; + + // Rescatter a clone, not the original particle + GHepParticle * sp = new GHepParticle(*p); + + // Set clone's mom to be the hadron that was cloned + sp->SetFirstMother(icurr); + + // Check whether the particle can be rescattered + if(!this->CanRescatter(sp)) { + + // if I can't rescatter it, I will just take it out of the nucleus + LOG("Intranuke2025", pNOTICE) + << "... Current version can't rescatter a " << sp->Name(); + sp->SetFirstMother(icurr); + sp->SetStatus(kIStStableFinalState); + evrec->AddParticle(*sp); + delete sp; + continue; // <-- skip to next GHEP entry + } + + // Start stepping particle out of the nucleus + bool has_interacted = false; + while ( this-> IsInNucleus(sp) ) + { + // advance the hadron by a step + utils::intranuke2025::StepParticle(sp, fHadStep); + + // check whether it interacts + double d = this->GenerateStep(evrec,sp); + has_interacted = (d0) { + // the particle interacts - simulate the hadronic interaction + LOG("Intranuke2025", pNOTICE) + << "Particle has interacted at location: " + << sp->X4()->Vect().Mag() << " / nucl rad= " << fTrackingRadius; + this->SimulateHadronicFinalState(evrec,sp); + } else if(has_interacted && fRemnA<=0) { + // nothing left to interact with! + LOG("Intranuke2025", pNOTICE) + << "*** Nothing left to interact with, escaping."; + sp->SetStatus(kIStStableFinalState); + evrec->AddParticle(*sp); + evrec->Particle(sp->FirstMother())->SetRescatterCode(1); + } else { + // the exits the nucleus without interacting - Done with it! + LOG("Intranuke2025", pNOTICE) + << "*** Hadron escaped the nucleus! Done with it."; + sp->SetStatus(kIStStableFinalState); + evrec->AddParticle(*sp); + evrec->Particle(sp->FirstMother())->SetRescatterCode(1); + } + delete sp; + + // Current snapshot + //LOG("Intranuke2025", pINFO) << "Current event record snapshot: " << *evrec; + + }// GHEP entries + + // Add remnant nucleus - that 'hadronic blob' has all the remaining hadronic + // 4p not put explicitly into the simulated particles + TLorentzVector v4(0.,0.,0.,0.); + GHepParticle remnant_nucleus( + kPdgHadronicBlob, kIStFinalStateNuclearRemnant, inucl,-1,-1,-1, fRemnP4, v4); + evrec->AddParticle(remnant_nucleus); + // Mark the initial remnant nucleus as an intermediate state + // Don't do that in the hadron/photon-nucleus scatterig mode since the initial + // remnant nucleus and the target nucleus coincide. + if(fGMode != kGMdHadronNucleus && + fGMode != kGMdPhotonNucleus) { + evrec->Particle(inucl)->SetStatus(kIStIntermediateState); + } +} +//___________________________________________________________________________ +double Intranuke2025::GenerateStep(GHepRecord* /*evrec*/, GHepParticle* p) const //Added ev to get tgt argument// +{ +// Generate a step (in fermis) for particle p in the input event. +// Computes the mean free path L and generate an 'interaction' distance d +// from an exp(-d/L) distribution + + int pdgc = p->Pdg(); + + double scale = 1.; + if (pdgc==kPdgPiP || pdgc==kPdgPiM) { + scale = fChPionMFPScale; + } + if (pdgc==kPdgPi0) { + scale = fNeutralPionMFPScale; + } + else if (pdgc==kPdgProton || pdgc==kPdgNeutron) { + scale = fNucleonMFPScale; + } + + RandomGen * rnd = RandomGen::Instance(); + + string fINukeMode = this->GetINukeMode(); + string fINukeModeGen = this->GetGenINukeMode(); + + double L = utils::intranuke2025::MeanFreePath(p->Pdg(), *p->X4(), *p->P4(), fRemnA, + fRemnZ, fDelRPion, fDelRNucleon, fUseOset, fAltOset, fXsecNNCorr, fINukeMode); + + LOG("Intranuke2025", pDEBUG) << "mode= " << fINukeModeGen; + L *= scale; + + double d = -1.*L * TMath::Log(rnd->RndFsi().Rndm()); + + /* LOG("Intranuke2025", pDEBUG) + << "mode= " << fINukeMode << "; Mean free path = " << L << " fm / " + << "Generated path length = " << d << " fm"; + */ + return d; +} +//___________________________________________________________________________ +void Intranuke2025::Configure(const Registry & config) +{ + Algorithm::Configure(config); + this->LoadConfig(); +} +//___________________________________________________________________________ +void Intranuke2025::Configure(string param_set) +{ + Algorithm::Configure(param_set); + this->LoadConfig(); +} +//___________________________________________________________________________ diff --git a/src/Physics/HadronTransport/Intranuke2025.h b/src/Physics/HadronTransport/Intranuke2025.h new file mode 100644 index 0000000000..65a79d1522 --- /dev/null +++ b/src/Physics/HadronTransport/Intranuke2025.h @@ -0,0 +1,162 @@ +//____________________________________________________________________________ +/*! + +\class genie::Intranuke + +\brief The INTRANUKE intranuclear hadron transport MC. + Is a concrete implementation of the EventRecordVisitorI interface. + +\ref R.Merenyi et al., Phys.Rev.D45 (1992) + R.D.Ransome, Nucl.Phys.B 139 (2005) + + Current INTRANUKE development is led by S.Dytman and H.Gallagher. + The original INTRANUKE cascade MC was developed (in fortran) for the + NeuGEN MC by R.Edgecock, G.F.Pearce, W.A.Mann, R.Merenyi and others. + Vast changes since then at Univ. of Pittsburgh and elsewhere + +\author Steve Dytman , Pittsburgh University + Aaron Meyer , Pittsburgh University + Mohamed Ismail , Pittsburgh University + Hugh Gallagher , Tufts University + Costas Andreopoulos STFC, Rutherford Lab + +\created September 20, 2025 + +\cpright Copyright (c) 2003-2025, The GENIE Collaboration + For the full text of the license visit http://copyright.genie-mc.org + + Sepr 2025: MI, SD: copied from Intranuke2018.h with no modifications except labels +*/ +//____________________________________________________________________________ + +#ifndef _INTRANUKE_2025_H_ +#define _INTRANUKE_2025_H_ + +#include + +#include "Physics/NuclearState/NuclearModelI.h" + +#include "Framework/Algorithm/AlgFactory.h" +#include "Framework/EventGen/EventRecordVisitorI.h" +#include "Framework/Conventions/GMode.h" +#include "Physics/HadronTransport/INukeMode.h" +#include "Physics/HadronTransport/INukeHadroFates2025.h" + +class TLorentzVector; +class TVector3; + +namespace genie { + +class GHepParticle; +class INukeHadroData2025; +class PDGCodeList; +class HNIntranuke2025; +class HAIntranuke2025; + +class Intranuke2025 : public EventRecordVisitorI { + +friend class IntranukeTester; + +public : + Intranuke2025(); + Intranuke2025(string name); + Intranuke2025(string name, string config); + ~Intranuke2025(); + + // implement the EventRecordVisitorI interface + virtual void ProcessEventRecord(GHepRecord * event_rec) const; + + // override the Algorithm::Configure methods to load configuration + // data to protected data members + virtual void Configure (const Registry & config); + virtual void Configure (string param_set); + + virtual string GetINukeMode() const {return "XX2025";}; + virtual string GetGenINukeMode() const {return "XX";}; + + // Setters used in reweighting + inline void SetRemnA( int A ) { fRemnA = A; } + inline void SetRemnZ( int Z ) { fRemnZ = Z; } + + inline double GetRemnA() const { return fRemnA; } + inline double GetRemnZ() const { return fRemnZ; } + + inline double GetR0() const { return fR0; } + inline double GetNR() const { return fNR; } + + inline double GetDelRPion() const { return fDelRPion; } + inline double GetDelRNucleon() const { return fDelRNucleon; } + + inline double GetNucRmvE() const { return fNucRmvE; } + inline double GetHadStep() const { return fHadStep; } + + inline bool GetUseOset() const { return fUseOset; } + inline bool GetAltOset() const { return fAltOset; } + inline bool GetXsecNNCorr() const { return fXsecNNCorr; } + +protected: + + // methods for loading configuration + virtual void LoadConfig (void)=0; + + // general methods for the cascade mc structure + void TransportHadrons (GHepRecord * ev) const; + void GenerateVertex (GHepRecord * ev) const; + bool NeedsRescattering (const GHepParticle* p) const; + bool CanRescatter (const GHepParticle* p) const; + bool IsInNucleus (const GHepParticle* p) const; + void SetTrackingRadius (const GHepParticle* p) const; + double GenerateStep (GHepRecord* ev, GHepParticle* p) const; + + // virtual functions for individual modes + virtual void SimulateHadronicFinalState(GHepRecord* ev, GHepParticle* p) const = 0; + virtual int HandleCompoundNucleus(GHepRecord* ev, GHepParticle* p, int mom) const = 0; + + // utility objects & params + mutable double fTrackingRadius;///< tracking radius for the nucleus in the current event + mutable TGenPhaseSpace fGenPhaseSpace; ///< a phase space generator + INukeHadroData2025 * fHadroData2025; ///< a collection of h+N,h+A data & calculations + AlgFactory * fAlgf; ///< algorithm factory instance + const NuclearModelI * fNuclmodel; ///< nuclear model used to generate fermi momentum + mutable int fRemnA; ///< remnant nucleus A + mutable int fRemnZ; ///< remnant nucleus Z + mutable TLorentzVector fRemnP4; ///< P4 of remnant system + mutable GEvGenMode_t fGMode; ///< event generation mode (lepton+A, hadron+A, ...) + + // configuration parameters + double fR0; ///< effective nuclear size param + double fNR; ///< param multiplying the nuclear radius, determining how far to track hadrons beyond the "nuclear boundary" + double fNucRmvE; ///< binding energy to subtract from cascade nucleons + double fDelRPion; ///< factor by which Pion Compton wavelength gets multiplied to become nuclear size enhancement + double fDelRNucleon; ///< factor by which Nucleon Compton wavelength gets multiplied to become nuclear size enhancement + double fHadStep; ///< step size for intranuclear hadron transport + double fNucAbsFac; ///< absorption xsec correction factor (hN Mode) + double fNucCEXFac; ///< charge exchange xsec correction factor (hN Mode) + double fEPreEq; ///< threshold for pre-equilibrium reaction + double fFermiFac; ///< testing parameter to modify fermi momentum + double fFermiMomentum; ///< whether or not particle collision is pauli blocked + bool fDoFermi; ///< whether or not to do fermi mom. + bool fDoMassDiff; ///< whether or not to do mass diff. mode + bool fDoCompoundNucleus; ///< whether or not to do compound nucleus considerations + bool fUseOset; ///< Oset model for low energy pion in hN + bool fAltOset; ///< NuWro's table-based implementation (not recommended) + bool fXsecNNCorr; ///< use nuclear medium correction for NN cross section + + double fChPionMFPScale; ///< tweaking factors for tuning + double fNeutralPionMFPScale; + double fPionFracCExScale; + double fPionFracInelScale; + double fChPionFracAbsScale; + double fNeutralPionFracAbsScale; + double fPionFracPiProdScale; + double fNucleonMFPScale; + double fNucleonFracCExScale; + double fNucleonFracInelScale; + double fNucleonFracAbsScale; + double fNucleonFracPiProdScale; + +}; + +} // genie namespace + +#endif // _INTRANUKE_2025_H_ diff --git a/src/Physics/HadronTransport/LinkDef.h b/src/Physics/HadronTransport/LinkDef.h index 69a34b2a3f..7840ffa1f6 100644 --- a/src/Physics/HadronTransport/LinkDef.h +++ b/src/Physics/HadronTransport/LinkDef.h @@ -10,6 +10,7 @@ #pragma link C++ class genie::INukeHadroData; #pragma link C++ class genie::INukeHadroData2018; +#pragma link C++ class genie::INukeHadroData2025; #pragma link C++ class genie::INukeDeltaPropg; //#pragma link C++ class genie::INukePhotoPropg; @@ -19,8 +20,11 @@ #pragma link C++ class genie::Intranuke; #pragma link C++ class genie::HAIntranuke; #pragma link C++ class genie::Intranuke2018; +#pragma link C++ class genie::Intranuke2025; #pragma link C++ class genie::HAIntranuke2018; #pragma link C++ class genie::HNIntranuke2018; +#pragma link C++ class genie::HAIntranuke2025; +#pragma link C++ class genie::HNIntranuke2025; #pragma link C++ class genie::CascadeReweight; diff --git a/src/Tools/Flux/GAtmoFlux.cxx b/src/Tools/Flux/GAtmoFlux.cxx index c1809d2455..9e37a69a0a 100644 --- a/src/Tools/Flux/GAtmoFlux.cxx +++ b/src/Tools/Flux/GAtmoFlux.cxx @@ -63,6 +63,11 @@ bool GAtmoFlux::GenerateNext(void) double wght = this->Weight(); bool accept = (E<=Emax && E>=Emin && wght>0); + + LOG("Flux", pDEBUG) << "Neutrino w/ energy : " << E; + LOG("Flux", pDEBUG) << "Max : " << Emax; + LOG("Flux", pDEBUG) << "Min : " << Emin; + LOG("Flux", pDEBUG) << "Weight : " << wght; if(accept) return true; } return false;