From 7de8ef41e20752df86ba69b04cdd637cad761646 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Tue, 11 Nov 2025 04:54:15 -0500 Subject: [PATCH 01/33] A new amplitude for VecPs. --- .../AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu | 24 ++ src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 229 ++++++++++++++++++ src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h | 93 +++++++ src/programs/AmplitudeAnalysis/fit/fit.cc | 2 + .../AmplitudeAnalysis/fitMPI/fitMPI.cc | 2 + 5 files changed, 350 insertions(+) create mode 100644 src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu create mode 100644 src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc create mode 100644 src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h diff --git a/src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu b/src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu new file mode 100644 index 000000000..3556553e1 --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu @@ -0,0 +1,24 @@ + +#include + +#include "GPUManager/GPUCustomTypes.h" +#include "GPUManager/CUDA-Complex.cuh" + +__global__ void +GPUVecPs_3pi_refl_kernel( GPU_AMP_PROTO ) +{ + int iEvent = GPU_THIS_EVENT; + + WCUComplex ans = { GPU_UVARS(0), GPU_UVARS(1) }; + pcDevAmp[iEvent] = ans; +} + +void +GPUVecPs_3pi_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) + +{ + + GPUVecPs_3pi_refl_kernel<<< dimGrid, dimBlock >>>( GPU_AMP_ARGS ); + +} + diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc new file mode 100644 index 000000000..5eaa543d4 --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc @@ -0,0 +1,229 @@ + +#include +#include +#include +#include +#include + +#include "TLorentzVector.h" +#include "TLorentzRotation.h" +#include "TFile.h" + +#include "IUAmpTools/Kinematics.h" +#include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" +#include "AMPTOOLS_AMPS/clebschGordan.h" +#include "AMPTOOLS_AMPS/wignerD.h" +#include "AMPTOOLS_AMPS/omegapiAngles.h" +#include "AMPTOOLS_AMPS/barrierFactor.h" + +#include "UTILITIES/BeamProperties.h" + +VecPs_3pi_refl::VecPs_3pi_refl( const vector< string >& args ) : +UserAmplitude< VecPs_3pi_refl >( args ) +{ + //assert( args.size() == 11 ); + + + m_j = atoi( args[0].c_str() ); // resonance spin J + m_m = atoi( args[1].c_str() ); // spin projection (Lambda) + m_l = atoi( args[2].c_str() ); // partial wave L + m_r = atoi( args[3].c_str() ); // real (+1) or imaginary (-1) + m_s = atoi( args[4].c_str() ); // sign for polarization in amplitude + + // default polarization information stored in tree + m_polInTree = true; + + // default is 2-body vector decay (set flag in config file for omega->3pi) + m_3pi = false; + + // 5 possibilities to initialize this amplitude: + // (with : total spin, : spin projection, : partial wave, : +1/-1 for real/imaginary part; : +1/-1 sign in P_gamma term) + + // loop over any additional amplitude arguments to change defaults + for(uint ioption=5; ioptionGet( args[7].c_str() ); + assert( polFrac_vs_E != NULL ); + } + else { + cout << "ERROR: VecPs_3pi_refl beam polarization not set" < 0.) { // for fitting with fixed polarization + beam_polFraction = polFraction; + } + else { // for fitting with polarization vs E_gamma from input histogram + int bin = polFrac_vs_E->GetXaxis()->FindBin(pKin[0][0]); + if (bin == 0 || bin > polFrac_vs_E->GetXaxis()->GetNbins()){ + beam_polFraction = 0.; + } else + beam_polFraction = polFrac_vs_E->GetBinContent(bin); + } + } + + //Particles order has been changed to gamma,piplusU,piplusL,piminusB,piminusI,proton + + TLorentzVector recoil ( pKin[5][1], pKin[5][2], pKin[5][3], pKin[5][0] ); + + // common vector and pseudoscalar P4s + TLorentzVector ps(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); // 3rd + TLorentzVector vec, vec_daught1, vec_daught2; // compute for each final state below + + // omega ps proton, omega -> 3pi (6 particles) + // omega pi- Delta++, omega -> 3pi (7 particles) + if(m_3pi) { + TLorentzVector pi0(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); + TLorentzVector pip(pKin[4][1], pKin[4][2], pKin[4][3], pKin[4][0]); + TLorentzVector pim(pKin[5][1], pKin[5][2], pKin[5][3], pKin[5][0]); + vec = pi0 + pip + pim; + vec_daught1 = pip; + vec_daught2 = pim; + } + else { + // omega ps proton, omega -> pi0 g (4 particles) + // omega pi- Delta++, omega -> pi0 g (5 particles) + + // (vec 2-body) ps proton, vec 2-body -> pipi, KK (5 particles) + // (vec 2-body) pi- Delta++, vec 2-body -> pipi, KK (6 particles) + // (vec 2-body) K+ Lambda, vec 2-body -> Kpi (6 particles) + vec_daught1 = TLorentzVector(pKin[1][1], pKin[1][2], pKin[1][3], pKin[1][0]); + vec_daught2 = TLorentzVector(pKin[4][1], pKin[4][2], pKin[4][3], pKin[4][0]); + vec = vec_daught1 + vec_daught2; + } + + // final meson system P4 + TLorentzVector X = vec + ps; + + //////////////////////// Boost Particles and Get Angles////////////////////////////////// + + TLorentzVector target(0,0,0,0.938); + //Helicity coordinate system + TLorentzVector Gammap = beam + target; + + // Calculate decay angles in helicity frame (same for all vectors) + // set beam polarization angle to 0 degrees; apply diamond orientation in calcAmplitude + vector locthetaphi = getomegapiAngles(0, vec, X, beam, Gammap); + + // Calculate vector decay angles (unique for each vector) + vector locthetaphih; + if(m_3pi) locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, vec_daught2); + else locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, TLorentzVector(0,0,0,0)); + + + GDouble cosTheta = TMath::Cos(locthetaphi[0]); + GDouble Phi = locthetaphi[1]; + GDouble cosThetaH = TMath::Cos(locthetaphih[0]); + GDouble PhiH = locthetaphih[1]; + GDouble prod_angle = locthetaphi[2]; + GDouble MX = X.M(); + GDouble MVec = vec.M(); + GDouble MPs = ps.M(); + + complex amplitude(0,0); + complex i(0,1); + + for (int lambda = -1; lambda <= 1; lambda++) { // sum over vector helicity + GDouble hel_amp = clebschGordan(m_l, 1, 0, lambda, m_j, lambda); + amplitude += conj(wignerD( m_j, m_m, lambda, cosTheta, Phi )) * hel_amp * conj(wignerD( 1, lambda, 0, cosThetaH, PhiH )); + } + + GDouble Factor = sqrt(1 + m_s * beam_polFraction); + + + complex< GDouble > zjm = 0; + + complex< GDouble > rotateY = polar( (GDouble)1., (GDouble)(-1.*(prod_angle + beam_polAngle*TMath::DegToRad())) ); // - -> + in prod_angle and polAngle summing + + + if (m_r == 1) + zjm = real(amplitude * rotateY); + if (m_r == -1) + zjm = i*imag(amplitude * rotateY); + + // E852 Nozar thesis has sqrt(2*s+1)*sqrt(2*l+1)*F_l(p_omega)*sqrt(omega) + double kinFactor = barrierFactor(MX, m_l, MVec, MPs); + //kinFactor *= sqrt(3.) * sqrt(2.*m_l + 1.); + Factor *= kinFactor; + + userVars[uv_ampRe] = ( Factor * zjm ).real(); + userVars[uv_ampIm] = ( Factor * zjm ).imag(); + + return; +} + + +////////////////////////////////////////////////// Amplitude Calculation ////////////////////////////////// + +complex< GDouble > +VecPs_3pi_refl::calcAmplitude( GDouble** pKin, GDouble* userVars ) const +{ + return complex< GDouble >( userVars[uv_ampRe], userVars[uv_ampIm] ); +} + + +void VecPs_3pi_refl::updatePar( const AmpParameter& par ){ + + // could do expensive calculations here on parameter updates +} + + +#ifdef GPU_ACCELERATION + +void +VecPs_3pi_refl::launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const { + + GPUVecPs_3pi_refl_exec( dimGrid, dimBlock, GPU_AMP_ARGS ); + +} + +#endif + + diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h new file mode 100644 index 000000000..3c06f4cae --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h @@ -0,0 +1,93 @@ +#if !defined(VECPS_3PI_REFL) +#define VECPS_3PI_REFL + +#include "IUAmpTools/Amplitude.h" +#include "IUAmpTools/UserAmplitude.h" +#include "IUAmpTools/AmpParameter.h" +#include "GPUManager/GPUCustomTypes.h" + +#include "TH1D.h" +#include +#include +#include + +using std::complex; +using namespace std; + +#ifdef GPU_ACCELERATION +void +GPUVecPs_3pi_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ); +#endif + +class Kinematics; + +class VecPs_3pi_refl : public UserAmplitude< VecPs_3pi_refl > +{ + +public: + + VecPs_3pi_refl() : UserAmplitude< VecPs_3pi_refl >() { }; + VecPs_3pi_refl( const vector< string >& args ); + VecPs_3pi_refl( int m_j, int m_m, int m_l, int m_r, int m_s ); + + string name() const { return "VecPs_3pi_refl"; } + + complex< GDouble > calcAmplitude( GDouble** pKin, GDouble* userVars ) const; + + // ********************** + // The following lines are optional and can be used to precalculate + // user-defined data that the amplitudes depend on. + + // Use this for indexing a user-defined data array and notifying + // the framework of the number of user-defined variables. + + //enum UserVars { uv_cosTheta = 0, uv_Phi, uv_cosThetaH, uv_PhiH, + // uv_prod_Phi, uv_MX, uv_MVec, uv_MPs, uv_beam_polFraction, + // uv_beam_polAngle, kNumUserVars }; + enum UserVars { uv_ampRe = 0, uv_ampIm, kNumUserVars }; + unsigned int numUserVars() const { return kNumUserVars; } + + // This function needs to be defined -- see comments and discussion + // in the .cc file. + void calcUserVars( GDouble** pKin, GDouble* userVars ) const; + + // This is an optional addition if the calcAmplitude routine + // can run with only the user-defined data and not the original + // four-vectors. It is used to optimize memory usage in GPU + // based fits. + bool needsUserVarsOnly() const { return true; } + + // This is an optional addition if the UserVars are the same for each + // instance of an amplitude. If it is not used, the memory footprint + // grows dramatically as UserVars values are stored for each instance + // of the amplitude. NOTE: To use this make sure that UserVars only + // depend on kinematics and no arguments provided to the amplitude! + bool areUserVarsStatic() const { return false; } + + void updatePar( const AmpParameter& par ); + +#ifdef GPU_ACCELERATION + + void launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const; + + bool isGPUEnabled() const { return true; } + +#endif // GPU_ACCELERATION + +private: + + int m_j; + int m_m; + int m_l; + int m_r; + int m_s; + int m_3pi; + + //AmpParameter polAngle; + GDouble polFraction; + GDouble polAngle; + bool m_polInTree; + TH1D *polFrac_vs_E; +}; + +#endif diff --git a/src/programs/AmplitudeAnalysis/fit/fit.cc b/src/programs/AmplitudeAnalysis/fit/fit.cc index 17cf5f5c3..c3c2b066d 100644 --- a/src/programs/AmplitudeAnalysis/fit/fit.cc +++ b/src/programs/AmplitudeAnalysis/fit/fit.cc @@ -43,6 +43,7 @@ #include "AMPTOOLS_AMPS/DblRegge_FastPi.h" #include "AMPTOOLS_AMPS/omegapi_amplitude.h" #include "AMPTOOLS_AMPS/Vec_ps_refl.h" +#include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" #include "AMPTOOLS_AMPS/PhaseOffset.h" #include "AMPTOOLS_AMPS/ComplexCoeff.h" #include "AMPTOOLS_AMPS/OmegaDalitz.h" @@ -432,6 +433,7 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( DblRegge_FastPi() ); AmpToolsInterface::registerAmplitude( omegapi_amplitude() ); AmpToolsInterface::registerAmplitude( Vec_ps_refl() ); + AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); AmpToolsInterface::registerAmplitude( PhaseOffset() ); AmpToolsInterface::registerAmplitude( ComplexCoeff() ); AmpToolsInterface::registerAmplitude( OmegaDalitz() ); diff --git a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc index c50c3da08..554f16c4d 100644 --- a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc +++ b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc @@ -39,6 +39,7 @@ #include "AMPTOOLS_AMPS/DblRegge_FastPi.h" #include "AMPTOOLS_AMPS/omegapi_amplitude.h" #include "AMPTOOLS_AMPS/Vec_ps_refl.h" +#include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" #include "AMPTOOLS_AMPS/Piecewise.h" #include "AMPTOOLS_AMPS/Flatte.h" #include "AMPTOOLS_AMPS/PhaseOffset.h" @@ -403,6 +404,7 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( DblRegge_FastPi() ); AmpToolsInterface::registerAmplitude( omegapi_amplitude() ); AmpToolsInterface::registerAmplitude( Vec_ps_refl() ); + AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); AmpToolsInterface::registerAmplitude( Piecewise() ); AmpToolsInterface::registerAmplitude( Flatte() ); AmpToolsInterface::registerAmplitude( PhaseOffset() ); From a274897298aa41710d5afd48ab96fa8451c2161e Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Thu, 13 Nov 2025 11:46:27 -0500 Subject: [PATCH 02/33] A plot generator for VecPs3Pi --- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 147 ++++++++++++++++++ .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h | 36 +++++ 2 files changed, 183 insertions(+) create mode 100644 src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc create mode 100644 src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc new file mode 100644 index 000000000..7014df82a --- /dev/null +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc @@ -0,0 +1,147 @@ +#include "TLorentzVector.h" +#include "TLorentzRotation.h" + +#include "AMPTOOLS_AMPS/omegapiAngles.h" + +#include "AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h" +#include "IUAmpTools/Histogram1D.h" +#include "IUAmpTools/Kinematics.h" + +/* Constructor to display FitResults */ +VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( const FitResults& results, Option opt ) : +PlotGenerator( results, opt ) +{ + createHistograms(); +} + +/* Constructor for event generator (no FitResult) */ +VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( ) : +PlotGenerator( ) +{ + createHistograms(); +} + +void VecPs3PiPlotGenerator::createHistograms( ) { + cout << " calls to bookHistogram go here" << endl; + + bookHistogram( kVecPsMass, new Histogram1D( 200, 0.2, 3.2, "MVecPs", "Invariant Mass of Vec+Ps [GeV]") ); + bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_I", "cos#theta_I" ) ); + bookHistogram( kPhi, new Histogram1D( 50, -1*PI, PI, "Phi_I", "#phi_I [rad.]" ) ); + bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta", "cos#theta" ) ); + bookHistogram( kPhiH, new Histogram1D( 50, -1*PI, PI, "Phi", "#phi [rad.]" ) ); + bookHistogram( kProd_Ang, new Histogram1D( 50, -1*PI, PI, "Prod_Ang", "Prod_Ang [rad.]" ) ); + bookHistogram( kt, new Histogram1D( 100, 0, 2.0 , "t", "-t" ) ); + bookHistogram( kRecoilMass, new Histogram1D( 100, 0.9, 1.9 , "MRecoil", "Invariant Mass of Recoil [GeV]" ) ); + bookHistogram( kProtonPsMass, new Histogram1D( 200, 0.8, 3.8, "MProtonPs", "Invariant Mass of proton and bachelor pi- [GeV]" ) ); + bookHistogram( kRecoilPsMass, new Histogram1D( 200, 1.0, 4.0, "MRecoilPs", "Invariant Mass of recoil and bachelor pi- [GeV]" ) ); + bookHistogram( kLambda, new Histogram1D( 110, 0.0, 1.1, "Lambda", "#lambda_{#omega}" ) ); + bookHistogram( kDalitz, new Histogram2D( 100, -2., 2., 100, -2., 2., "Dalitz", "Dalitz XY" ) ); +} + +void +VecPs3PiPlotGenerator::projectEvent( Kinematics* kin ){ + + // this function will make this class backwards-compatible with older versions + // (v0.10.x and prior) of AmpTools, but will not be able to properly obtain + // the polariation plane in the lab when multiple orientations are used + projectEvent( kin, "" ); +} + +void +VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ + + //cout << "project event" << endl; + TLorentzVector beam = kin->particle( 0 ); + TLorentzVector recoil = kin->particle( 1 ); + TLorentzVector bach = kin->particle( 3 ); + + // default is 2-body vector decay (set flag in config file for omega->3pi) + bool m_3pi = false; + + // min particle index for recoil sum + int min_recoil = 5; + + // check config file for optional parameters -- we assume here that the first amplitude in the list is a Vec_ps_refl amplitude + const vector< string > args = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); + for(uint ioption=5; ioption momentArgs = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); + for (uint ioption=0; ioption pi0 g (4 particles) + // omega pi- Delta++, omega -> pi0 g (5 particles) + + // (vec 2-body) ps proton, vec 2-body -> pipi, KK (5 particles) + // (vec 2-body) pi- Delta++, vec 2-body -> pipi, KK (6 particles) + // (vec 2-body) K+ Lambda, vec 2-body -> Kpi (6 particles) + vec_daught1 = kin->particle( 1 ); + vec_daught2 = kin->particle( 4 ); + vec = vec_daught1 + vec_daught2; + min_recoil = 5; + dalitzx = 0.; + dalitzy = 0.; + + + // final meson system P4 + TLorentzVector X = vec + bach; + + TLorentzVector proton_ps = recoil + bach; + TLorentzVector recoil_ps = proton_ps; + for(uint i=min_recoil; iparticleList().size(); i++) { + // add mesons to recoil system (e.g. Delta or Lambda) + recoil += kin->particle(i); + recoil_ps += kin->particle(i); + } + + // set polarization angle to zero to see shift in Phi_Prod distributions + double polAngle = 0; + TLorentzVector target(0,0,0,0.938); + + // Helicity coordinate system + TLorentzVector Gammap = beam + target; + + // Calculate decay angles in helicity frame (same for all vectors) + vector locthetaphi = getomegapiAngles(polAngle, vec, X, beam, Gammap); + + // Calculate vector decay angles (unique for each vector) + vector locthetaphih; + if(m_3pi) locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, vec_daught2); + else locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, TLorentzVector(0,0,0,0)); + + double Mandt = fabs((target-recoil).M2()); + double recoil_mass = recoil.M(); + + GDouble cosTheta = TMath::Cos(locthetaphi[0]); + GDouble Phi = locthetaphi[1]; + GDouble cosThetaH = TMath::Cos(locthetaphih[0]); + GDouble PhiH = locthetaphih[1]; + GDouble prod_angle = locthetaphi[2]; + GDouble lambda = locthetaphih[2]; + + //cout << "calls to fillHistogram go here" << endl; + fillHistogram( kVecPsMass, X.M() ); + fillHistogram( kCosTheta, cosTheta ); + fillHistogram( kPhi, Phi ); + fillHistogram( kCosThetaH, cosThetaH ); + fillHistogram( kPhiH, PhiH ); + fillHistogram( kProd_Ang, prod_angle ); + fillHistogram( kt, Mandt ); + fillHistogram( kRecoilMass, recoil_mass ); + fillHistogram( kProtonPsMass, proton_ps.M() ); + fillHistogram( kRecoilPsMass, recoil_ps.M() ); + fillHistogram( kLambda, lambda ); + fillHistogram( kDalitz, dalitzx, dalitzy ); + +} diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h new file mode 100644 index 000000000..72995d33d --- /dev/null +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h @@ -0,0 +1,36 @@ +#if !(defined VCPS3PIPLOTGENERATOR) +#define VECPS3PIPLOTGENERATOR + +#include +#include + +#include "IUAmpTools/PlotGenerator.h" + +using namespace std; + +class FitResults; +class Kinematics; + +class VecPs3PiPlotGenerator : public PlotGenerator +{ + +public: + + // create an index for different histograms + enum { kVecPs3PiMass = 0, kCosTheta = 1, kPhi = 2, kCosThetaH = 3, kPhiH = 4, kProd_Ang = 5, kt = 6, kRecoilMass = 7, kProtonPsMass = 8, kRecoilPsMass = 9, kLambda = 10, kDalitz = 11, kNumHists}; + + VecPs3PiPlotGenerator( const FitResults& results, Option opt); + VecPs3PiPlotGenerator( const FitResults& results ); + VecPs3PiPlotGenerator( ); + +private: + + void projectEvent( Kinematics* kin ); + void projectEvent( Kinematics* kin, const string& reactionName ); + + void createHistograms( ); + +}; + +#endif + From 876f80373e63c8670cdb8e1268212793c33595d8 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Wed, 7 Jan 2026 07:38:11 -0500 Subject: [PATCH 03/33] changed order of final state momenta in VecPs_3Pi amp. --- src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 13 +- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 68 ++-- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h | 2 +- src/programs/AmplitudeAnalysis/SConscript | 2 +- .../vecps3pi_plotter/SConscript | 22 ++ .../vecps3pi_plotter/vecps3pi_plotter.cc | 367 ++++++++++++++++++ 6 files changed, 425 insertions(+), 49 deletions(-) create mode 100644 src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript create mode 100644 src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc index 5eaa543d4..0b2498610 100644 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc @@ -109,12 +109,15 @@ VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const { } } - //Particles order has been changed to gamma,piplusU,piplusL,piminusB,piminusI,proton + // Definitions for my previous final state particles order + // TLorentzVector recoil ( pKin[5][1], pKin[5][2], pKin[5][3], pKin[5][0] ); + // TLorentzVector ps(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); // 3rd + //Now, Final state particles order is the following: proton,piminusB,piminusI,piplusU,piplusL + + TLorentzVector recoil ( pKin[1][1], pKin[1][2], pKin[1][3], pKin[1][0] ); - TLorentzVector recoil ( pKin[5][1], pKin[5][2], pKin[5][3], pKin[5][0] ); - // common vector and pseudoscalar P4s - TLorentzVector ps(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); // 3rd + TLorentzVector ps(pKin[2][1], pKin[2][2], pKin[2][3], pKin[2][0]); // 1st after proton TLorentzVector vec, vec_daught1, vec_daught2; // compute for each final state below // omega ps proton, omega -> 3pi (6 particles) @@ -134,7 +137,7 @@ VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const { // (vec 2-body) ps proton, vec 2-body -> pipi, KK (5 particles) // (vec 2-body) pi- Delta++, vec 2-body -> pipi, KK (6 particles) // (vec 2-body) K+ Lambda, vec 2-body -> Kpi (6 particles) - vec_daught1 = TLorentzVector(pKin[1][1], pKin[1][2], pKin[1][3], pKin[1][0]); + vec_daught1 = TLorentzVector(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); vec_daught2 = TLorentzVector(pKin[4][1], pKin[4][2], pKin[4][3], pKin[4][0]); vec = vec_daught1 + vec_daught2; } diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc index 7014df82a..3ce139058 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc @@ -25,17 +25,15 @@ void VecPs3PiPlotGenerator::createHistograms( ) { cout << " calls to bookHistogram go here" << endl; bookHistogram( kVecPsMass, new Histogram1D( 200, 0.2, 3.2, "MVecPs", "Invariant Mass of Vec+Ps [GeV]") ); - bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_I", "cos#theta_I" ) ); - bookHistogram( kPhi, new Histogram1D( 50, -1*PI, PI, "Phi_I", "#phi_I [rad.]" ) ); - bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta", "cos#theta" ) ); - bookHistogram( kPhiH, new Histogram1D( 50, -1*PI, PI, "Phi", "#phi [rad.]" ) ); + bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta", "cos#theta" ) ); + bookHistogram( kPhi, new Histogram1D( 50, -1*PI, PI, "Phi", "#phi [rad.]" ) ); + bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_H", "cos#theta_H" ) ); + bookHistogram( kPhiH, new Histogram1D( 50, -1*PI, PI, "Phi", "#phi_H [rad.]" ) ); bookHistogram( kProd_Ang, new Histogram1D( 50, -1*PI, PI, "Prod_Ang", "Prod_Ang [rad.]" ) ); bookHistogram( kt, new Histogram1D( 100, 0, 2.0 , "t", "-t" ) ); bookHistogram( kRecoilMass, new Histogram1D( 100, 0.9, 1.9 , "MRecoil", "Invariant Mass of Recoil [GeV]" ) ); bookHistogram( kProtonPsMass, new Histogram1D( 200, 0.8, 3.8, "MProtonPs", "Invariant Mass of proton and bachelor pi- [GeV]" ) ); bookHistogram( kRecoilPsMass, new Histogram1D( 200, 1.0, 4.0, "MRecoilPs", "Invariant Mass of recoil and bachelor pi- [GeV]" ) ); - bookHistogram( kLambda, new Histogram1D( 110, 0.0, 1.1, "Lambda", "#lambda_{#omega}" ) ); - bookHistogram( kDalitz, new Histogram2D( 100, -2., 2., 100, -2., 2., "Dalitz", "Dalitz XY" ) ); } void @@ -52,14 +50,26 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName //cout << "project event" << endl; TLorentzVector beam = kin->particle( 0 ); - TLorentzVector recoil = kin->particle( 1 ); + TLorentzVector proton = kin->particle( 5 ); + TLorentzVector piplusL = kin->particle( 2 ); TLorentzVector bach = kin->particle( 3 ); + TLorentzVector vec_daught1 = kin->particle( 1 ); + TLorentzVector vec_daught2 = kin->particle( 4 ); - // default is 2-body vector decay (set flag in config file for omega->3pi) + + + // final meson system P4 + TLorentzVector vec = vec_daught1 + vec_daught2; + TLorentzVector X = vec + bach; + TLorentzVector recoil = proton + piplusL; + + TLorentzVector proton_ps = proton + bach; + TLorentzVector recoil_ps = recoil + bach; + + + // We use only default 2-body vector decay (set flag in config file for omega->3pi) bool m_3pi = false; - // min particle index for recoil sum - int min_recoil = 5; // check config file for optional parameters -- we assume here that the first amplitude in the list is a Vec_ps_refl amplitude const vector< string > args = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); @@ -75,39 +85,16 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName if(option.EqualTo("Vec_ps_moment")) m_3pi = true; } - TLorentzVector vec, vec_daught1, vec_daught2; // compute for each final state below - double dalitz_s, dalitz_t, dalitz_u, dalitz_d, dalitz_sc; - double dalitzx = 0; - double dalitzy = 0; - - // omega ps proton, omega -> pi0 g (4 particles) - // omega pi- Delta++, omega -> pi0 g (5 particles) - - // (vec 2-body) ps proton, vec 2-body -> pipi, KK (5 particles) - // (vec 2-body) pi- Delta++, vec 2-body -> pipi, KK (6 particles) - // (vec 2-body) K+ Lambda, vec 2-body -> Kpi (6 particles) - vec_daught1 = kin->particle( 1 ); - vec_daught2 = kin->particle( 4 ); - vec = vec_daught1 + vec_daught2; - min_recoil = 5; - dalitzx = 0.; - dalitzy = 0.; + //No dalitz plot for a 2-body decay, vec 2-body -> pippim - // final meson system P4 - TLorentzVector X = vec + bach; - TLorentzVector proton_ps = recoil + bach; - TLorentzVector recoil_ps = proton_ps; - for(uint i=min_recoil; iparticleList().size(); i++) { - // add mesons to recoil system (e.g. Delta or Lambda) - recoil += kin->particle(i); - recoil_ps += kin->particle(i); - } + + //CHECK FROM HERE ON !! // set polarization angle to zero to see shift in Phi_Prod distributions double polAngle = 0; - TLorentzVector target(0,0,0,0.938); + TLorentzVector target(0,0,0,0.938272); // Helicity coordinate system TLorentzVector Gammap = beam + target; @@ -117,8 +104,7 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName // Calculate vector decay angles (unique for each vector) vector locthetaphih; - if(m_3pi) locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, vec_daught2); - else locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, TLorentzVector(0,0,0,0)); + locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, TLorentzVector(0,0,0,0)); double Mandt = fabs((target-recoil).M2()); double recoil_mass = recoil.M(); @@ -128,7 +114,7 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName GDouble cosThetaH = TMath::Cos(locthetaphih[0]); GDouble PhiH = locthetaphih[1]; GDouble prod_angle = locthetaphi[2]; - GDouble lambda = locthetaphih[2]; + //cout << "calls to fillHistogram go here" << endl; fillHistogram( kVecPsMass, X.M() ); @@ -141,7 +127,5 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName fillHistogram( kRecoilMass, recoil_mass ); fillHistogram( kProtonPsMass, proton_ps.M() ); fillHistogram( kRecoilPsMass, recoil_ps.M() ); - fillHistogram( kLambda, lambda ); - fillHistogram( kDalitz, dalitzx, dalitzy ); } diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h index 72995d33d..65e58c568 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h @@ -17,7 +17,7 @@ class VecPs3PiPlotGenerator : public PlotGenerator public: // create an index for different histograms - enum { kVecPs3PiMass = 0, kCosTheta = 1, kPhi = 2, kCosThetaH = 3, kPhiH = 4, kProd_Ang = 5, kt = 6, kRecoilMass = 7, kProtonPsMass = 8, kRecoilPsMass = 9, kLambda = 10, kDalitz = 11, kNumHists}; + enum { kVecPsMass = 0, kCosTheta = 1, kPhi = 2, kCosThetaH = 3, kPhiH = 4, kProd_Ang = 5, kt = 6, kRecoilMass = 7, kProtonPsMass = 8, kRecoilPsMass = 9, kNumHists}; VecPs3PiPlotGenerator( const FitResults& results, Option opt); VecPs3PiPlotGenerator( const FitResults& results ); diff --git a/src/programs/AmplitudeAnalysis/SConscript b/src/programs/AmplitudeAnalysis/SConscript index 2e64c9056..a292e3ba5 100644 --- a/src/programs/AmplitudeAnalysis/SConscript +++ b/src/programs/AmplitudeAnalysis/SConscript @@ -3,7 +3,7 @@ import sbms Import('*') -subdirs = ['fit', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'plot_etapi0'] +subdirs = ['fit', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'vecps3pi_plotter', 'plot_etapi0'] SConscript(dirs=subdirs, exports='env osname', duplicate=0) diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript new file mode 100644 index 000000000..7dcb10d85 --- /dev/null +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript @@ -0,0 +1,22 @@ + +import os +import sbms + +# get env object and clone it +Import('*') + +# Verify AMPTOOLS environment variable is set +if os.getenv('AMPTOOLS', 'nada')!='nada' and os.getenv('AMPPLOTTER', 'nada')!='nada': + + env = env.Clone() + + AMPTOOLS_LIBS = "AMPTOOLS_AMPS AMPTOOLS_DATAIO AMPTOOLS_MCGEN UTILITIES" + env.AppendUnique(LIBS = AMPTOOLS_LIBS.split()) + + sbms.AddHDDM(env) + sbms.AddAmpTools(env) + sbms.AddAmpPlotter(env) + sbms.AddUtilities(env) + sbms.AddROOT(env) + + sbms.executable(env) diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc new file mode 100644 index 000000000..748be566b --- /dev/null +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -0,0 +1,367 @@ +#include +#include +#include +#include + +#include "TClass.h" +#include "TApplication.h" +#include "TGClient.h" +#include "TROOT.h" +#include "TH1.h" +#include "TStyle.h" +#include "TClass.h" +#include "TFile.h" +#include "TMultiGraph.h" +#include "TGraphErrors.h" + +#include "IUAmpTools/AmpToolsInterface.h" +#include "IUAmpTools/FitResults.h" + +#include "AmpPlotter/PlotterMainWindow.h" +#include "AmpPlotter/PlotFactory.h" + +#include "AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h" +#include "AMPTOOLS_DATAIO/ROOTDataReader.h" +#include "AMPTOOLS_DATAIO/ROOTDataReaderBootstrap.h" +#include "AMPTOOLS_DATAIO/ROOTDataReaderTEM.h" +#include "AMPTOOLS_DATAIO/FSRootDataReader.h" +#include "AMPTOOLS_AMPS/BreitWigner.h" +#include "AMPTOOLS_AMPS/Uniform.h" +#include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" +#include "AMPTOOLS_AMPS/PhaseOffset.h" +#include "AMPTOOLS_AMPS/ComplexCoeff.h" +#include "AMPTOOLS_AMPS/Piecewise.h" +#include "AMPTOOLS_AMPS/OmegaDalitz.h" +#include "AMPTOOLS_AMPS/Vec_ps_moment.h" + +#include "MinuitInterface/MinuitMinimizationManager.h" +#include "IUAmpTools/ConfigFileParser.h" +#include "IUAmpTools/ConfigurationInfo.h" + +typedef VecPs3PiPlotGenerator vecps_PlotGen; + +void atiSetup(){ + + AmpToolsInterface::registerAmplitude( BreitWigner() ); + AmpToolsInterface::registerAmplitude( Uniform() ); + AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); + AmpToolsInterface::registerAmplitude( PhaseOffset() ); + AmpToolsInterface::registerAmplitude( ComplexCoeff() ); + AmpToolsInterface::registerAmplitude( Piecewise() ); + AmpToolsInterface::registerAmplitude( OmegaDalitz() ); + AmpToolsInterface::registerAmplitude( Vec_ps_moment() ); + + AmpToolsInterface::registerDataReader( ROOTDataReader() ); + AmpToolsInterface::registerDataReader( FSRootDataReader() ); + AmpToolsInterface::registerDataReader( ROOTDataReaderTEM() ); +} + +using namespace std; + +int main( int argc, char* argv[] ){ + + + // ************************ + // usage + // ************************ + + cout << endl << " *** Viewing Results Using AmpPlotter and writing root histograms *** " << endl << endl; + + if (argc < 2){ + cout << "Usage:" << endl << endl; + cout << "\tvecps3pi_plotter -o " << endl << endl; + return 0; + } + + bool showGui = false; + string outName = "vecps3pi_plot.root"; + string resultsName(argv[1]); + for (int i = 2; i < argc; i++){ + + string arg(argv[i]); + + if (arg == "-g"){ + showGui = true; + } + if (arg == "-o"){ + outName = argv[++i]; + } + if (arg == "-h"){ + cout << endl << " Usage for: " << argv[0] << endl << endl; + cout << "\t -o \t output file path" << endl; + cout << "\t -g \t show GUI" << endl; + exit(1); + } + } + + + // ************************ + // parse the command line parameters + // ************************ + + cout << "Fit results file name = " << resultsName << endl; + cout << "Output file name = " << outName << endl << endl; + + // ************************ + // load the results and display the configuration info + // ************************ + + cout << "Loading Fit results" << endl; + FitResults results( resultsName ); + if( !results.valid() ){ + + cout << "Invalid fit results in file: " << resultsName << endl; + exit( 1 ); + } + cout << "Fit results loaded" << endl; + // ************************ + // set up the plot generator + // ************************ + cout << "before atisetup();"<< endl; + atiSetup(); + cout << "Plotgen results"<< endl; + + vecps_PlotGen plotGen( results , PlotGenerator::kNoGenMC ); + cout << " Initialized ati and PlotGen" << endl; + + // ************************ + // set up an output ROOT file to store histograms + // ************************ + + TFile* plotfile = new TFile( outName.c_str(), "recreate"); + TH1::AddDirectory(kFALSE); + + string reactionName = results.reactionList()[0]; + plotGen.enableReaction( reactionName ); + vector sums = plotGen.uniqueSums(); + vector amps = plotGen.uniqueAmplitudes(); + cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; + + vector amphistname = {"0-P"}; //, "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "1-P-", "1-P0", "1-P+"}; + vector reflname = {"PosRefl", "NegRefl"}; + + // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) + for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++){ + + // loop over desired amplitudes + for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++ ) { + + // turn all ampltiudes by default + for (unsigned int jamp = 0; jamp < amps.size(); jamp++ ) { + plotGen.enableAmp( jamp ); + } + + // turn off unwanted amplitudes and sums + if (iamp < amphistname.size()) { + + string locampname = amphistname[iamp]; + + // turn on all sums by default + for (unsigned int i = 0; i < sums.size(); i++) plotGen.enableSum(i); + + // turn off unwanted sums for reflectivity (based on naturality) + //cout<<"refl = "<toRoot(); + thist->SetName(histname.c_str()); + plotfile->cd(); + thist->Write(); + + } + } + } + } + + plotfile->Close(); + + // model parameters + cout << "Checking Parameters" << endl; + + // parameters to check + vector< string > pars; + + // pars.push_back("dsratio"); + + // file for writing parameters (later switch to putting in ROOT file) + ofstream outfile; + outfile.open( "vecps_fitPars.txt" ); + + for(unsigned int i = 0; i fullamps = plotGen.fullAmplitudes(); + for (unsigned int i = 0; i < fullamps.size(); i++){ + vector useamp; useamp.push_back(fullamps[i]); + outfile << "FIT FRACTION " << fullamps[i] << " = " + << results.intensity(useamp).first / + results.intensity().first << " +- " + << results.intensity(useamp).second / + results.intensity().first << endl; + } + + const int nAmps = amphistname.size(); + vector ampsumPosRefl[nAmps]; + vector ampsumNegRefl[nAmps]; + vector< pair > phaseDiffNames; + + for(unsigned int i = 0; i < fullamps.size(); i++){ + + // combine amplitudes with names defined above + for(int iamp=0; iamp phaseDiff = results.phaseDiff( phaseDiffNames[i].first, phaseDiffNames[i].second ); + outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " << phaseDiffNames[i].second << " " << phaseDiff.first << " " << phaseDiff.second << endl; + + } + + // covariance matrix + vector< vector< double > > covMatrix; + covMatrix = results.errorMatrix(); + + // ************************ + // start the GUI + // ************************ + + if(showGui) { + + cout << ">> Plot generator ready, starting GUI..." << endl; + + int dummy_argc = 0; + char* dummy_argv[] = {}; + TApplication app( "app", &dummy_argc, dummy_argv ); + + gStyle->SetFillColor(10); + gStyle->SetCanvasColor(10); + gStyle->SetPadColor(10); + gStyle->SetFillStyle(1001); + gStyle->SetPalette(1); + gStyle->SetFrameFillColor(10); + gStyle->SetFrameFillStyle(1001); + + cout << " Initialized App " << endl; + PlotFactory factory( plotGen ); + cout << " Created Plot Factory " << endl; + PlotterMainWindow mainFrame( gClient->GetRoot(), factory ); + cout << " Main frame created " << endl; + + app.Run(); + cout << " App running" << endl; + } + + return 0; + +} From 277a543542800ca3be2fe7929bebc7120c70a7b2 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Wed, 7 Jan 2026 12:13:38 -0500 Subject: [PATCH 04/33] Updated angles --- src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 251 ++++++++++-------- src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc | 167 ++++++++++++ src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h | 59 ++++ 3 files changed, 368 insertions(+), 109 deletions(-) create mode 100644 src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc create mode 100644 src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc index 0b2498610..e44eb9d3b 100644 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc @@ -13,59 +13,57 @@ #include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" #include "AMPTOOLS_AMPS/clebschGordan.h" #include "AMPTOOLS_AMPS/wignerD.h" -#include "AMPTOOLS_AMPS/omegapiAngles.h" +#include "AMPTOOLS_AMPS/vecPsAngles.h" #include "AMPTOOLS_AMPS/barrierFactor.h" #include "UTILITIES/BeamProperties.h" -VecPs_3pi_refl::VecPs_3pi_refl( const vector< string >& args ) : -UserAmplitude< VecPs_3pi_refl >( args ) -{ - //assert( args.size() == 11 ); - - - m_j = atoi( args[0].c_str() ); // resonance spin J - m_m = atoi( args[1].c_str() ); // spin projection (Lambda) - m_l = atoi( args[2].c_str() ); // partial wave L - m_r = atoi( args[3].c_str() ); // real (+1) or imaginary (-1) - m_s = atoi( args[4].c_str() ); // sign for polarization in amplitude - - // default polarization information stored in tree - m_polInTree = true; - - // default is 2-body vector decay (set flag in config file for omega->3pi) - m_3pi = false; +// Function to check if a string is a valid number +static bool isValidNumber(const string& argInput, double &value){ + char* end = nullptr; + errno = 0; // reset global error + value = std::strtod(argInput.c_str(), &end); + + // Check if + // (1) no conversion was performed + // (2) there are leftover characters + // (3) an overflow/underflow occurred + if(end == argInput.c_str() || *end != '\0' || errno != 0) { + return false; // not a valid number + } + // If end points to the end of string, it's fully numeric + return true; +} - // 5 possibilities to initialize this amplitude: - // (with : total spin, : spin projection, : partial wave, : +1/-1 for real/imaginary part; : +1/-1 sign in P_gamma term) +static double parseValidatedNumber(const string& label, const string& argInput){ + double tmpValue = 0.0; + if(!isValidNumber(argInput, tmpValue)){ + throw std::invalid_argument("Vec_ps_refl: invalid " + label + ": " + argInput); + } + return tmpValue; +} - // loop over any additional amplitude arguments to change defaults - for(uint ioption=5; ioptionGet( args[7].c_str() ); - assert( polFrac_vs_E != NULL ); - } - else { - cout << "ERROR: VecPs_3pi_refl beam polarization not set" <& args ) : +UserAmplitude< VecPs_3pi_refl >( args ){ - } + // 5 possibilities to initialize this amplitude: + // : total spin, + // : spin projection, + // : partial wave, + // : +1/-1 for real/imaginary part; + // : +1/-1 sign in P_gamma term + + // Resonance spin J + m_j = static_cast(parseValidatedNumber("J", args[0])); + // Spin projection (Lambda) + m_m = static_cast(parseValidatedNumber("M", args[1])); + // Partial wave L + m_l = static_cast(parseValidatedNumber("L", args[2])); + // Real (+1) or imaginary (-1) + m_r = static_cast(parseValidatedNumber("Re/Im", args[3])); + // Sign for polarization in amplitude + m_s = static_cast(parseValidatedNumber("P_gamma sign", args[4])); // make sure values are reasonable assert( abs( m_m ) <= m_j ); @@ -75,11 +73,44 @@ UserAmplitude< VecPs_3pi_refl >( args ) // m_s = +1 for 1 + Pgamma // m_s = -1 for 1 - Pgamma assert( abs( m_s ) == 1 ); - + + // Default polarization information stored in tree + m_polInTree = true; + + // Default is 2-body vector decay (set flag in config file for omega->3pi) + m_3pi = false; + + // Loop over any additional amplitude arguments to change defaults + for(uint ioption=5; ioptionGet(args[7].c_str()); + if(polFrac_vs_E != nullptr ){ + throw std::runtime_error( + "VecPs_3pi_refl ERROR: Could not find histogram '" + args[7] + + "' in file " + std::string(polOption.Data())); + } + } + else{ + polFraction = parseValidatedNumber("polarization fraction", args[6]); + } + } + // Check for omega->3pi option + if(option.EqualTo("omega3pi")) m_3pi = true; + } } void -VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const { +VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ TLorentzVector beam; TVector3 eps; @@ -87,42 +118,41 @@ VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const { GDouble beam_polAngle; if(m_polInTree){ - beam.SetPxPyPzE( 0., 0., pKin[0][0], pKin[0][0]); - eps.SetXYZ(pKin[0][1], pKin[0][2], 0.); // beam polarization vector; + beam.SetPxPyPzE( 0.0, 0.0, pKin[0][0], pKin[0][0]); + eps.SetXYZ(pKin[0][1], pKin[0][2], 0.0); // beam polarization vector; beam_polFraction = eps.Mag(); - beam_polAngle = eps.Phi()*TMath::RadToDeg(); + beam_polAngle = eps.Phi(); } - else { + else{ beam.SetPxPyPzE( pKin[0][1], pKin[0][2], pKin[0][3], pKin[0][0] ); beam_polAngle = polAngle; - - if(polFraction > 0.) { // for fitting with fixed polarization + + if(polFraction > 0.0){ // for fitting with fixed polarization beam_polFraction = polFraction; } - else { // for fitting with polarization vs E_gamma from input histogram + else{ // for fitting with polarization vs E_gamma from input histogram int bin = polFrac_vs_E->GetXaxis()->FindBin(pKin[0][0]); if (bin == 0 || bin > polFrac_vs_E->GetXaxis()->GetNbins()){ - beam_polFraction = 0.; - } else + beam_polFraction = 0.0; + } else beam_polFraction = polFrac_vs_E->GetBinContent(bin); } } - - // Definitions for my previous final state particles order - // TLorentzVector recoil ( pKin[5][1], pKin[5][2], pKin[5][3], pKin[5][0] ); - // TLorentzVector ps(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); // 3rd - //Now, Final state particles order is the following: proton,piminusB,piminusI,piplusU,piplusL - TLorentzVector recoil ( pKin[1][1], pKin[1][2], pKin[1][3], pKin[1][0] ); - - // common vector and pseudoscalar P4s - TLorentzVector ps(pKin[2][1], pKin[2][2], pKin[2][3], pKin[2][0]); // 1st after proton - TLorentzVector vec, vec_daught1, vec_daught2; // compute for each final state below + TLorentzVector recoil( pKin[1][1]+pkin[5][1], pKin[1][2]+pkin[5][2], pKin[1][3]+pkin[5][3], pKin[1][0]+pKin[5][0] ); + + // Fill in four-vectors for final state particles + // 1st after proton is always the pseudoscalar meson + TLorentzVector ps(pKin[2][1], pKin[2][2], pKin[2][3], pKin[2][0]); + // Compute vector meson from its decay products + // Make sure the order of daughters is correct in the config file! + TLorentzVector vec, vec_daught1, vec_daught2; + - // omega ps proton, omega -> 3pi (6 particles) - // omega pi- Delta++, omega -> 3pi (7 particles) - if(m_3pi) { + if(m_3pi){ + // Omega ps proton, omega -> 3pi (6 particles) + // Omega pi- Delta++, omega -> 3pi (7 particles) TLorentzVector pi0(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); TLorentzVector pip(pKin[4][1], pKin[4][2], pKin[4][3], pKin[4][0]); TLorentzVector pim(pKin[5][1], pKin[5][2], pKin[5][3], pKin[5][0]); @@ -130,10 +160,10 @@ VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const { vec_daught1 = pip; vec_daught2 = pim; } - else { - // omega ps proton, omega -> pi0 g (4 particles) - // omega pi- Delta++, omega -> pi0 g (5 particles) - + else{ + // Omega ps proton, omega -> pi0 g (4 particles) + // Omega pi- Delta++, omega -> pi0 g (5 particles) + // (vec 2-body) ps proton, vec 2-body -> pipi, KK (5 particles) // (vec 2-body) pi- Delta++, vec 2-body -> pipi, KK (6 particles) // (vec 2-body) K+ Lambda, vec 2-body -> Kpi (6 particles) @@ -142,68 +172,72 @@ VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const { vec = vec_daught1 + vec_daught2; } - // final meson system P4 + // Final meson system P4 TLorentzVector X = vec + ps; - //////////////////////// Boost Particles and Get Angles////////////////////////////////// + ///////////////// Boost Particles and Get Angles///////////////////// TLorentzVector target(0,0,0,0.938); - //Helicity coordinate system - TLorentzVector Gammap = beam + target; + // Helicity coordinate system + TLorentzVector beamP = beam + target; - // Calculate decay angles in helicity frame (same for all vectors) - // set beam polarization angle to 0 degrees; apply diamond orientation in calcAmplitude - vector locthetaphi = getomegapiAngles(0, vec, X, beam, Gammap); + // Calculate decay angles for X in helicity frame (same for all vectors) + // Change getXDecayAngles to get Gottfried-Jackson angles if needed + // Note: it also calculates the production angle + vector xDecayAngles = getXDecayAngles( beam_polAngle, beam, beamP, X, vec); // Calculate vector decay angles (unique for each vector) - vector locthetaphih; - if(m_3pi) locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, vec_daught2); - else locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, TLorentzVector(0,0,0,0)); - + vector vectorDecayAngles; + if(m_3pi){ + vectorDecayAngles = getVectorDecayAngles( beamP, X, vec, + vec_daught1, vec_daught2); + } + else{ + vectorDecayAngles = getVectorDecayAngles( beamP, X, vec, + vec_daught1, TLorentzVector(0,0,0,0)); + } - GDouble cosTheta = TMath::Cos(locthetaphi[0]); - GDouble Phi = locthetaphi[1]; - GDouble cosThetaH = TMath::Cos(locthetaphih[0]); - GDouble PhiH = locthetaphih[1]; - GDouble prod_angle = locthetaphi[2]; - GDouble MX = X.M(); - GDouble MVec = vec.M(); - GDouble MPs = ps.M(); + GDouble cosTheta = TMath::Cos(xDecayAngles[0]); + GDouble phi = xDecayAngles[1]; + GDouble prod_angle = xDecayAngles[2]; // bigPhi + GDouble cosThetaH = TMath::Cos(vectorDecayAngles[0]); + GDouble phiH = vectorDecayAngles[1]; + GDouble m_X = X.M(); + GDouble m_vec = vec.M(); + GDouble m_ps = ps.M(); complex amplitude(0,0); complex i(0,1); for (int lambda = -1; lambda <= 1; lambda++) { // sum over vector helicity GDouble hel_amp = clebschGordan(m_l, 1, 0, lambda, m_j, lambda); - amplitude += conj(wignerD( m_j, m_m, lambda, cosTheta, Phi )) * hel_amp * conj(wignerD( 1, lambda, 0, cosThetaH, PhiH )); - } - - GDouble Factor = sqrt(1 + m_s * beam_polFraction); - - - complex< GDouble > zjm = 0; - - complex< GDouble > rotateY = polar( (GDouble)1., (GDouble)(-1.*(prod_angle + beam_polAngle*TMath::DegToRad())) ); // - -> + in prod_angle and polAngle summing - - + amplitude += conj(wignerD(m_j, m_m, lambda, cosTheta, phi)) * + hel_amp * conj(wignerD(1, lambda, 0, cosThetaH, phiH)); + } + + GDouble factor = sqrt(1 + m_s * beam_polFraction); + complex zjm = 0; + // - -> + in prod_angle + complex rotateY = polar((GDouble)1., (GDouble)(-1. * prod_angle )); + if (m_r == 1) zjm = real(amplitude * rotateY); if (m_r == -1) zjm = i*imag(amplitude * rotateY); // E852 Nozar thesis has sqrt(2*s+1)*sqrt(2*l+1)*F_l(p_omega)*sqrt(omega) - double kinFactor = barrierFactor(MX, m_l, MVec, MPs); + double kinFactor = barrierFactor(m_X, m_l, m_vec, m_ps); //kinFactor *= sqrt(3.) * sqrt(2.*m_l + 1.); - Factor *= kinFactor; + factor *= kinFactor; - userVars[uv_ampRe] = ( Factor * zjm ).real(); - userVars[uv_ampIm] = ( Factor * zjm ).imag(); + userVars[uv_ampRe] = ( factor * zjm ).real(); + userVars[uv_ampIm] = ( factor * zjm ).imag(); return; } -////////////////////////////////////////////////// Amplitude Calculation ////////////////////////////////// +/////////////////////// Amplitude Calculation ////////////////////////// complex< GDouble > VecPs_3pi_refl::calcAmplitude( GDouble** pKin, GDouble* userVars ) const @@ -211,7 +245,6 @@ VecPs_3pi_refl::calcAmplitude( GDouble** pKin, GDouble* userVars ) const return complex< GDouble >( userVars[uv_ampRe], userVars[uv_ampIm] ); } - void VecPs_3pi_refl::updatePar( const AmpParameter& par ){ // could do expensive calculations here on parameter updates diff --git a/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc b/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc new file mode 100644 index 000000000..768987659 --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include +#include +#include "TLorentzVector.h" +#include "TLorentzRotation.h" +#include "TMath.h" +#include "vecPs3PiAngles.h" +#include "IUAmpTools/AmpToolsInterface.h" +#include "IUAmpTools/report.h" + +static const char* kModule = "vecPs3PiAngles"; + +vector getVectorDecayAngles( const TLorentzVector& beamPLab, + const TLorentzVector& particleXLab, + const TLorentzVector& parentLab, + const TLorentzVector& firstDaughterLab, + const TLorentzVector& secondDaughterLab){ + // Calculating the angles of the normal to the piplus+piminus plane + // beamPLab = beam + proton (center of mass), particleXLab = b1, + // parentLab = omega, firstDaughterLab = piplus, secondDaughterLab = piminus + + // Boost all particles to the (beamPLab) center-of-mass frame (cm) + TLorentzVector beam_cm = beamLab; + TLorentzVector particleX_cm = particleXLab; + TLorentzVector parent_cm = parentLab; + TLorentzVector firstDaughter_cm = firstDaughterLab; + TLorentzVector secondDaughter_cm = secondDaughterLab; + TVector3 cmBoostVector = -beamPLab.BoostVector(); + beam_cm.Boost(cmBoostVector); + particleX_cm.Boost(cmBoostVector); + parent_cm.Boost(cmBoostVector); + firstDaughter_cm.Boost(cmBoostVector); + secondDaughter_cm.Boost(cmBoostVector); + + // Boost parent and daughters to rest frame of particle X (x) + TLorentzVector beam_x = beam_cm; + TLorentzVector parent_x = parent_cm; + TLorentzVector firstDaughter_x = firstDaughter_cm; + TLorentzVector secondDaughter_x = secondDaughter_cm; + TVector3 xBoost = -particleX_cm.BoostVector(); + beam_x.Boost(xBoost); + parent_x.Boost(xBoost); + firstDaughter_x.Boost(xBoost); + secondDaughter_x.Boost(xBoost); + + // Boost daughters to parent's rest frame (p) + TLorentzVector firstDaughter_p = firstDaughter_x; + TLorentzVector secondDaughter_p = secondDaughter_x; + TVector3 parentBoost = -parent_x.BoostVector(); + firstDaughter_p.Boost(parentBoost); + secondDaughter_p.Boost(parentBoost); + + // Define the unit vectors for the helicity frame of the parent + TVector3 firstDaughter_p_unit = (firstDaughter_p.Vect()).Unit(); + TVector3 secondDaughter_p_unit = (secondDaughter_p.Vect()).Unit(); + TVector3 normal_p_unit = firstDaughter_p_unit.Cross(secondDaughter_p_unit); + + + // The axis of this helicity frame are defined as follows: + // z-axis is along the direction of the parent in the X rest frame + // y-axis is normal to the plane with the parent and beam vectors in the X rest frame + TVector3 z = (parent_x.Vect()).Unit(); + TVector3 y = ((beam_x.Vect()).Cross(z)).Unit(); + TVector3 x = (y.Cross(z)).Unit(); + + // The decay vector is normal to decay plane for omega->3pi + // In the case of vec->ps1+ps2, the decay vector is one of the ps + TVector3 decayVector; + if(secondDaughterLab.E() > 0) decayVector = normal_p_unit; + else decayVector = firstDaughter_p_unit; + + TVector3 components(decayVector.Dot(x),decayVector.Dot(y),decayVector.Dot(z)); + + double thetaHelicity = components.Theta(); + double phiHelicity = components.Phi(); + + // Compute the variable lambda for the omega->3pi decay + TVector3 daughterCross = (firstDaughter_p.Vect()).Cross(secondDaughter_p.Vect()); + double m0 = 0.1349766; // mass of pi0 + double mq = 0.1395702; // mass of charged pions + double threePiMass = parentLab.M2(); + double lambda_max = (3.0/4.0) * + TMath::Power( (1.0/9.0) * (5*threePiMass + 3*(m0*m0 - 4*mq*mq) - + 4*sqrt(threePiMass * threePiMass + + 3*threePiMass * (m0*m0 - mq*mq))), 2); + double lambda = fabs(daughterCross.Mag2()) / lambda_max; + + return {thetaHelicity, phiHelicity, lambda}; + +} +vector getXDecayAngles( double polAngle, + const TLorentzVector& beamLab, + const TLorentzVector& beamPLab, + const TLorentzVector& particleXLab, + const TLorentzVector& daughterLab){ + // Calculating the helicity angles of omega in the b1 decay + // daughterLab = omega, particleXLab = b1, beamLab = beam, + // beamPLab = beam + proton (center of mass) + + // Boost all particles to the (beamPLab) center-of-mass frame (cm) + TLorentzVector beam_cm = beamLab; + TLorentzVector particleX_cm = particleXLab; + TLorentzVector daughter_cm = daughterLab; + TVector3 cmBoostVector = -beamPLab.BoostVector(); + beam_cm.Boost(cmBoostVector); + particleX_cm.Boost(cmBoostVector); + daughter_cm.Boost(cmBoostVector); + + // Boost daughter to particle X rest frame (x) + TLorentzVector daughter_x = daughter_cm; + TVector3 xBoost = -particleX_cm.BoostVector(); + daughter_x.Boost(xBoost); + + // get the unit vectors in space + TVector3 daughter_x_unit = (daughter_x.Vect()).Unit(); + TVector3 beam_cm_unit = (beam_cm.Vect()).Unit(); + + + + // The axis of this helicity frame are defined as follows: + // z-axis is along the direction of particle X in the center-of-mass frame + // y-axis is normal to the production plane defined by particle X and + // the beam both vectors are expressed in the center-of-mass frame + //TVector3 z = (particleX_cm.Vect()).Unit(); + //TVector3 y = ((beam_cm_unit).Cross(z)).Unit(); + //TVector3 x = (y.Cross(z)).Unit(); + + // One could use the Gottfried-Jackson frame instead of the helicity frame + // The axis would be defined as follows: + // z-axis is along the direction of the beam in the particle X rest frame + // y-axis is normal to the production plane defined by particle X and the beam + // Both vectors are expressed in the Lab frame + // (the same as helicity frame) + TLorentzVector beam_x = beam_cm; + beam_x.Boost(-1.0*xBoost); + TVector3 z = (beam_x.Vect()).Unit(); + TVector3 y = ((beamLab.Vect()).Cross(particleXLab.Vect())).Unit(); + TVector3 x = (y.Cross(z)).Unit(); + + TVector3 components(daughter_x_unit.Dot(x), daughter_x_unit.Dot(y), + daughter_x_unit.Dot(z)); + + double theta = components.Theta(); + double phi = components.Phi(); + + // Compute the production angle (bigPhi) between the polarization + // vector and the normal to the production plane + // But first, make sure the polarization angle is in radians + static bool warned = false; // only warn once + if(!warned && (fabs(polAngle) > 2 * TMath::Pi())){ + report( NOTICE, kModule ) + << " getXDecayAngles(): polAngle = " << polAngle + << " appears to be in degrees. Converting to radians." + << " This message will only be shown once." + << endl; + polAngle = DEG_TO_RAD * polAngle; + warned = true; + } + TVector3 eps(cos(polAngle), sin(polAngle), 0.0); // polarization vector + double bigPhi = atan2(y.Dot(eps), beamLab.Vect().Unit().Dot(eps.Cross(y))); + + return {theta, phi, bigPhi}; +} diff --git a/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h b/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h new file mode 100644 index 000000000..52d1b9679 --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h @@ -0,0 +1,59 @@ +// The purpose of getVectorDecayAngles() is to return the helicity angles +// of the normal to the decay plane of the vector parent particle. +// This function also returns the variable lambda used in the +// omega->3pi decay amplitude. + +// The purpose of getXDecayAngles() is to return the helicity angles of +// particle X in the reaction gamma + p -> X + p. +// This function also returns the angle between the polarization +// vector and the normal to the production plane of particle X. +// Both functions return a vector of doubles containing the polar +// angle theta, the azimuthal angle phi, and either lambda or bigPhi +// The angles are calculated in the helicity frame of the parent +// The code uses b1->omega pi and omega->3pi as an example, +// but can be used for any vector decay. + +// For a two particle decay, the function arguments are the lab +// frame TLorentzVectors of: the daughter particle, the parent +// particle, the inverse of the X-axis and the reference Z-axis. + +// For a three particle decay, the function arguments are the same +// with the addition of a second daughter particle. +// Note that in this case the normal to the decay plane is calculated as +// the cross product between the first daughter and the second daughter vectors. + +// The function could also return the decay angles in +// other frames when called with the appropriate argument change. +// Gottfried-Jackson (commented in code): The z-axis is equal to the +// direction of the incoming beam in the particle X rest frame. +// Adair RF: The z-axis is equal to the direction of the incoming beam +// in the center of mass system. +#if !defined(VECPS3PIANGLES) +#define VECPS3PIANGLES + +#include +#include +#include + +#include "TLorentzVector.h" + +//#include "GPUManager/GPUCustomTypes.h" + +using std::complex; +using namespace std; + +constexpr double DEG_TO_RAD = TMath::Pi() / 180.0; + +vector getVectorDecayAngles( const TLorentzVector& beamPLab, + const TLorentzVector& particleXLab, + const TLorentzVector& parentLab, + const TLorentzVector& firstDaughterLab, + const TLorentzVector& secondDaughterLab); + +vector getXDecayAngles( double polAngle, + const TLorentzVector& beamLab, + const TLorentzVector& beamPLab, + const TLorentzVector& particleXLab, + const TLorentzVector& daughterLab); + +#endif From 3c9852165d3344e6d9c35973f1d130bf7f7df04f Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Thu, 8 Jan 2026 07:56:40 -0500 Subject: [PATCH 05/33] Angles from decayAngles.cc are linked to VecPs_3pi_refl --- src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 2 +- src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc | 167 ------------------ src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h | 59 ------- 3 files changed, 1 insertion(+), 227 deletions(-) delete mode 100644 src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc delete mode 100644 src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc index e44eb9d3b..8e6fe2cea 100644 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc @@ -13,7 +13,7 @@ #include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" #include "AMPTOOLS_AMPS/clebschGordan.h" #include "AMPTOOLS_AMPS/wignerD.h" -#include "AMPTOOLS_AMPS/vecPsAngles.h" +#include "AMPTOOLS_AMPS/ThreePiAnglesPWA.h" #include "AMPTOOLS_AMPS/barrierFactor.h" #include "UTILITIES/BeamProperties.h" diff --git a/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc b/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc deleted file mode 100644 index 768987659..000000000 --- a/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.cc +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "TLorentzVector.h" -#include "TLorentzRotation.h" -#include "TMath.h" -#include "vecPs3PiAngles.h" -#include "IUAmpTools/AmpToolsInterface.h" -#include "IUAmpTools/report.h" - -static const char* kModule = "vecPs3PiAngles"; - -vector getVectorDecayAngles( const TLorentzVector& beamPLab, - const TLorentzVector& particleXLab, - const TLorentzVector& parentLab, - const TLorentzVector& firstDaughterLab, - const TLorentzVector& secondDaughterLab){ - // Calculating the angles of the normal to the piplus+piminus plane - // beamPLab = beam + proton (center of mass), particleXLab = b1, - // parentLab = omega, firstDaughterLab = piplus, secondDaughterLab = piminus - - // Boost all particles to the (beamPLab) center-of-mass frame (cm) - TLorentzVector beam_cm = beamLab; - TLorentzVector particleX_cm = particleXLab; - TLorentzVector parent_cm = parentLab; - TLorentzVector firstDaughter_cm = firstDaughterLab; - TLorentzVector secondDaughter_cm = secondDaughterLab; - TVector3 cmBoostVector = -beamPLab.BoostVector(); - beam_cm.Boost(cmBoostVector); - particleX_cm.Boost(cmBoostVector); - parent_cm.Boost(cmBoostVector); - firstDaughter_cm.Boost(cmBoostVector); - secondDaughter_cm.Boost(cmBoostVector); - - // Boost parent and daughters to rest frame of particle X (x) - TLorentzVector beam_x = beam_cm; - TLorentzVector parent_x = parent_cm; - TLorentzVector firstDaughter_x = firstDaughter_cm; - TLorentzVector secondDaughter_x = secondDaughter_cm; - TVector3 xBoost = -particleX_cm.BoostVector(); - beam_x.Boost(xBoost); - parent_x.Boost(xBoost); - firstDaughter_x.Boost(xBoost); - secondDaughter_x.Boost(xBoost); - - // Boost daughters to parent's rest frame (p) - TLorentzVector firstDaughter_p = firstDaughter_x; - TLorentzVector secondDaughter_p = secondDaughter_x; - TVector3 parentBoost = -parent_x.BoostVector(); - firstDaughter_p.Boost(parentBoost); - secondDaughter_p.Boost(parentBoost); - - // Define the unit vectors for the helicity frame of the parent - TVector3 firstDaughter_p_unit = (firstDaughter_p.Vect()).Unit(); - TVector3 secondDaughter_p_unit = (secondDaughter_p.Vect()).Unit(); - TVector3 normal_p_unit = firstDaughter_p_unit.Cross(secondDaughter_p_unit); - - - // The axis of this helicity frame are defined as follows: - // z-axis is along the direction of the parent in the X rest frame - // y-axis is normal to the plane with the parent and beam vectors in the X rest frame - TVector3 z = (parent_x.Vect()).Unit(); - TVector3 y = ((beam_x.Vect()).Cross(z)).Unit(); - TVector3 x = (y.Cross(z)).Unit(); - - // The decay vector is normal to decay plane for omega->3pi - // In the case of vec->ps1+ps2, the decay vector is one of the ps - TVector3 decayVector; - if(secondDaughterLab.E() > 0) decayVector = normal_p_unit; - else decayVector = firstDaughter_p_unit; - - TVector3 components(decayVector.Dot(x),decayVector.Dot(y),decayVector.Dot(z)); - - double thetaHelicity = components.Theta(); - double phiHelicity = components.Phi(); - - // Compute the variable lambda for the omega->3pi decay - TVector3 daughterCross = (firstDaughter_p.Vect()).Cross(secondDaughter_p.Vect()); - double m0 = 0.1349766; // mass of pi0 - double mq = 0.1395702; // mass of charged pions - double threePiMass = parentLab.M2(); - double lambda_max = (3.0/4.0) * - TMath::Power( (1.0/9.0) * (5*threePiMass + 3*(m0*m0 - 4*mq*mq) - - 4*sqrt(threePiMass * threePiMass + - 3*threePiMass * (m0*m0 - mq*mq))), 2); - double lambda = fabs(daughterCross.Mag2()) / lambda_max; - - return {thetaHelicity, phiHelicity, lambda}; - -} -vector getXDecayAngles( double polAngle, - const TLorentzVector& beamLab, - const TLorentzVector& beamPLab, - const TLorentzVector& particleXLab, - const TLorentzVector& daughterLab){ - // Calculating the helicity angles of omega in the b1 decay - // daughterLab = omega, particleXLab = b1, beamLab = beam, - // beamPLab = beam + proton (center of mass) - - // Boost all particles to the (beamPLab) center-of-mass frame (cm) - TLorentzVector beam_cm = beamLab; - TLorentzVector particleX_cm = particleXLab; - TLorentzVector daughter_cm = daughterLab; - TVector3 cmBoostVector = -beamPLab.BoostVector(); - beam_cm.Boost(cmBoostVector); - particleX_cm.Boost(cmBoostVector); - daughter_cm.Boost(cmBoostVector); - - // Boost daughter to particle X rest frame (x) - TLorentzVector daughter_x = daughter_cm; - TVector3 xBoost = -particleX_cm.BoostVector(); - daughter_x.Boost(xBoost); - - // get the unit vectors in space - TVector3 daughter_x_unit = (daughter_x.Vect()).Unit(); - TVector3 beam_cm_unit = (beam_cm.Vect()).Unit(); - - - - // The axis of this helicity frame are defined as follows: - // z-axis is along the direction of particle X in the center-of-mass frame - // y-axis is normal to the production plane defined by particle X and - // the beam both vectors are expressed in the center-of-mass frame - //TVector3 z = (particleX_cm.Vect()).Unit(); - //TVector3 y = ((beam_cm_unit).Cross(z)).Unit(); - //TVector3 x = (y.Cross(z)).Unit(); - - // One could use the Gottfried-Jackson frame instead of the helicity frame - // The axis would be defined as follows: - // z-axis is along the direction of the beam in the particle X rest frame - // y-axis is normal to the production plane defined by particle X and the beam - // Both vectors are expressed in the Lab frame - // (the same as helicity frame) - TLorentzVector beam_x = beam_cm; - beam_x.Boost(-1.0*xBoost); - TVector3 z = (beam_x.Vect()).Unit(); - TVector3 y = ((beamLab.Vect()).Cross(particleXLab.Vect())).Unit(); - TVector3 x = (y.Cross(z)).Unit(); - - TVector3 components(daughter_x_unit.Dot(x), daughter_x_unit.Dot(y), - daughter_x_unit.Dot(z)); - - double theta = components.Theta(); - double phi = components.Phi(); - - // Compute the production angle (bigPhi) between the polarization - // vector and the normal to the production plane - // But first, make sure the polarization angle is in radians - static bool warned = false; // only warn once - if(!warned && (fabs(polAngle) > 2 * TMath::Pi())){ - report( NOTICE, kModule ) - << " getXDecayAngles(): polAngle = " << polAngle - << " appears to be in degrees. Converting to radians." - << " This message will only be shown once." - << endl; - polAngle = DEG_TO_RAD * polAngle; - warned = true; - } - TVector3 eps(cos(polAngle), sin(polAngle), 0.0); // polarization vector - double bigPhi = atan2(y.Dot(eps), beamLab.Vect().Unit().Dot(eps.Cross(y))); - - return {theta, phi, bigPhi}; -} diff --git a/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h b/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h deleted file mode 100644 index 52d1b9679..000000000 --- a/src/libraries/AMPTOOLS_AMPS/vecPs3PiAngles.h +++ /dev/null @@ -1,59 +0,0 @@ -// The purpose of getVectorDecayAngles() is to return the helicity angles -// of the normal to the decay plane of the vector parent particle. -// This function also returns the variable lambda used in the -// omega->3pi decay amplitude. - -// The purpose of getXDecayAngles() is to return the helicity angles of -// particle X in the reaction gamma + p -> X + p. -// This function also returns the angle between the polarization -// vector and the normal to the production plane of particle X. -// Both functions return a vector of doubles containing the polar -// angle theta, the azimuthal angle phi, and either lambda or bigPhi -// The angles are calculated in the helicity frame of the parent -// The code uses b1->omega pi and omega->3pi as an example, -// but can be used for any vector decay. - -// For a two particle decay, the function arguments are the lab -// frame TLorentzVectors of: the daughter particle, the parent -// particle, the inverse of the X-axis and the reference Z-axis. - -// For a three particle decay, the function arguments are the same -// with the addition of a second daughter particle. -// Note that in this case the normal to the decay plane is calculated as -// the cross product between the first daughter and the second daughter vectors. - -// The function could also return the decay angles in -// other frames when called with the appropriate argument change. -// Gottfried-Jackson (commented in code): The z-axis is equal to the -// direction of the incoming beam in the particle X rest frame. -// Adair RF: The z-axis is equal to the direction of the incoming beam -// in the center of mass system. -#if !defined(VECPS3PIANGLES) -#define VECPS3PIANGLES - -#include -#include -#include - -#include "TLorentzVector.h" - -//#include "GPUManager/GPUCustomTypes.h" - -using std::complex; -using namespace std; - -constexpr double DEG_TO_RAD = TMath::Pi() / 180.0; - -vector getVectorDecayAngles( const TLorentzVector& beamPLab, - const TLorentzVector& particleXLab, - const TLorentzVector& parentLab, - const TLorentzVector& firstDaughterLab, - const TLorentzVector& secondDaughterLab); - -vector getXDecayAngles( double polAngle, - const TLorentzVector& beamLab, - const TLorentzVector& beamPLab, - const TLorentzVector& particleXLab, - const TLorentzVector& daughterLab); - -#endif From 32710fb7aa45abbfddcd4114e5ec0ff8be3af763 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Thu, 8 Jan 2026 08:46:55 -0500 Subject: [PATCH 06/33] Updated vecps3pi_plotter (saves all waves now) --- src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 38 ++++---- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 87 +++++++++---------- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h | 2 +- .../vecps3pi_plotter/vecps3pi_plotter.cc | 24 ++--- 4 files changed, 73 insertions(+), 78 deletions(-) diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc index 8e6fe2cea..8912478f7 100644 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc @@ -13,7 +13,7 @@ #include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" #include "AMPTOOLS_AMPS/clebschGordan.h" #include "AMPTOOLS_AMPS/wignerD.h" -#include "AMPTOOLS_AMPS/ThreePiAnglesPWA.h" +#include "AMPTOOLS_AMPS/decayAngles.h" #include "AMPTOOLS_AMPS/barrierFactor.h" #include "UTILITIES/BeamProperties.h" @@ -174,34 +174,28 @@ VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ // Final meson system P4 TLorentzVector X = vec + ps; + /// Fixed target + TLorentzVector target(0,0,0,0.938272); - ///////////////// Boost Particles and Get Angles///////////////////// - TLorentzVector target(0,0,0,0.938); - // Helicity coordinate system - TLorentzVector beamP = beam + target; + //Calculate production angle in the Gottfried-Jackson frame + GDouble prod_angle = getPhiProd(beam_polAngle, X, beam, target, 2, true); - // Calculate decay angles for X in helicity frame (same for all vectors) - // Change getXDecayAngles to get Gottfried-Jackson angles if needed - // Note: it also calculates the production angle - vector xDecayAngles = getXDecayAngles( beam_polAngle, beam, beamP, X, vec); - - // Calculate vector decay angles (unique for each vector) - vector vectorDecayAngles; + // Calculate decay angles for X in the Gottfried-Jackson frame and for Isobar in the Helicity frame + vector thetaPhiAnglesTwoStep; if(m_3pi){ - vectorDecayAngles = getVectorDecayAngles( beamP, X, vec, - vec_daught1, vec_daught2); + thetaPhiAnglesTwoStep = getTwoStepAngles(X, vec, vec_daught1, vec_daught2, beam, target, 2, true); } else{ - vectorDecayAngles = getVectorDecayAngles( beamP, X, vec, - vec_daught1, TLorentzVector(0,0,0,0)); - } + thetaPhiAnglesTwoStep = getTwoStepAngles(X, vec, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); + } + - GDouble cosTheta = TMath::Cos(xDecayAngles[0]); - GDouble phi = xDecayAngles[1]; - GDouble prod_angle = xDecayAngles[2]; // bigPhi - GDouble cosThetaH = TMath::Cos(vectorDecayAngles[0]); - GDouble phiH = vectorDecayAngles[1]; + + GDouble cosTheta = TMath::Cos(thetaPhiAnglesTwoStep[0]); + GDouble phi = thetaPhiAnglesTwoStep[1]; + GDouble cosThetaH = TMath::Cos(thetaPhiAnglesTwoStep[2]); + GDouble phiH = thetaPhiAnglesTwoStep[3]; GDouble m_X = X.M(); GDouble m_vec = vec.M(); GDouble m_ps = ps.M(); diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc index 3ce139058..72de6212d 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc @@ -1,7 +1,7 @@ #include "TLorentzVector.h" #include "TLorentzRotation.h" -#include "AMPTOOLS_AMPS/omegapiAngles.h" +#include "AMPTOOLS_AMPS/decayAngles.h" #include "AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h" #include "IUAmpTools/Histogram1D.h" @@ -24,16 +24,20 @@ PlotGenerator( ) void VecPs3PiPlotGenerator::createHistograms( ) { cout << " calls to bookHistogram go here" << endl; - bookHistogram( kVecPsMass, new Histogram1D( 200, 0.2, 3.2, "MVecPs", "Invariant Mass of Vec+Ps [GeV]") ); - bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta", "cos#theta" ) ); - bookHistogram( kPhi, new Histogram1D( 50, -1*PI, PI, "Phi", "#phi [rad.]" ) ); - bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_H", "cos#theta_H" ) ); - bookHistogram( kPhiH, new Histogram1D( 50, -1*PI, PI, "Phi", "#phi_H [rad.]" ) ); - bookHistogram( kProd_Ang, new Histogram1D( 50, -1*PI, PI, "Prod_Ang", "Prod_Ang [rad.]" ) ); - bookHistogram( kt, new Histogram1D( 100, 0, 2.0 , "t", "-t" ) ); - bookHistogram( kRecoilMass, new Histogram1D( 100, 0.9, 1.9 , "MRecoil", "Invariant Mass of Recoil [GeV]" ) ); - bookHistogram( kProtonPsMass, new Histogram1D( 200, 0.8, 3.8, "MProtonPs", "Invariant Mass of proton and bachelor pi- [GeV]" ) ); - bookHistogram( kRecoilPsMass, new Histogram1D( 200, 1.0, 4.0, "MRecoilPs", "Invariant Mass of recoil and bachelor pi- [GeV]" ) ); + bookHistogram( kProd_Ang, new Histogram1D( 50, -PI, PI, "ProdAng", "Production Angle Lab frame [rad.]" ) ); + bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta Gottfried-Jackson frame [rad.]" ) ); + bookHistogram( kPhi, new Histogram1D( 50, -PI, PI, "Phi_GJ", "#phi Gottfried-Jackson frame [rad.]" ) ); + bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta Helicity frame [rad.]" ) ); + bookHistogram( kPhiH, new Histogram1D( 50, -PI, PI, "Phi_HF", "#phi Helicity frame [rad.]" ) ); + + bookHistogram( kVecMass, new Histogram1D( 200, 0., 3., "MVec", "m(2#pi) [GeV]") ); + bookHistogram( kVecPsMass, new Histogram1D( 200, 0.2, 3.2, "MVecPs", "m(3#pi) [GeV]") ); + bookHistogram( kt, new Histogram1D( 100, 0, 1.0 , "t", "-t [GeV^{2}]" ) ); + bookHistogram( kRecoilMass, new Histogram1D( 100, 0.9, 1.9 , "ProtonPiplusL_M", "m(p#pi^{+}_{L}) [GeV]" ) ); + + bookHistogram( kProtonPsMass, new Histogram1D( 200, 0.8, 3.8, "ProtonPiminus_M", "m(p#pi^{-}) [GeV]" ) ); + bookHistogram( kRecoilPsMass, new Histogram1D( 200, 1.0, 4.0, "ProtonPiplusLPiminus_M", "m(p#pi^{+}_{L}#pi^{-}) [GeV]" ) ); + } void @@ -48,13 +52,17 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin ){ void VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ + // Fixed target + TLorentzVector target(0,0,0,0.938272); + + //cout << "project event" << endl; TLorentzVector beam = kin->particle( 0 ); - TLorentzVector proton = kin->particle( 5 ); - TLorentzVector piplusL = kin->particle( 2 ); - TLorentzVector bach = kin->particle( 3 ); - TLorentzVector vec_daught1 = kin->particle( 1 ); + TLorentzVector proton = kin->particle( 1 ); + TLorentzVector bach = kin->particle( 2 ); + TLorentzVector vec_daught1 = kin->particle( 3 ); TLorentzVector vec_daught2 = kin->particle( 4 ); + TLorentzVector piplusL = kin->particle( 5 ); @@ -82,49 +90,40 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName const vector < string > momentArgs = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); for (uint ioption=0; ioption pippim - - - - //CHECK FROM HERE ON !! - - // set polarization angle to zero to see shift in Phi_Prod distributions - double polAngle = 0; - TLorentzVector target(0,0,0,0.938272); - - // Helicity coordinate system - TLorentzVector Gammap = beam + target; - - // Calculate decay angles in helicity frame (same for all vectors) - vector locthetaphi = getomegapiAngles(polAngle, vec, X, beam, Gammap); - - // Calculate vector decay angles (unique for each vector) - vector locthetaphih; - locthetaphih = getomegapiAngles(vec_daught1, vec, X, Gammap, TLorentzVector(0,0,0,0)); + //Momentum transfer double Mandt = fabs((target-recoil).M2()); - double recoil_mass = recoil.M(); + + //Calculate production angle in the Gottfried-Jackson frame + GDouble prod_angle = getPhiProd(beam_polAngle, X, beam, target, 2, true); + + // Calculate decay angles for X in the Gottfried-Jackson frame and for Isobar in the Helicity frame + vector thetaPhiAnglesTwoStep = getTwoStepAngles(X, vec, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); - GDouble cosTheta = TMath::Cos(locthetaphi[0]); - GDouble Phi = locthetaphi[1]; - GDouble cosThetaH = TMath::Cos(locthetaphih[0]); - GDouble PhiH = locthetaphih[1]; - GDouble prod_angle = locthetaphi[2]; + GDouble cosTheta = TMath::Cos(thetaPhiAnglesTwoStep[0]); + GDouble phi = thetaPhiAnglesTwoStep[1]; + GDouble cosThetaH = TMath::Cos(thetaPhiAnglesTwoStep[2]); + GDouble phiH = thetaPhiAnglesTwoStep[3]; + + //cout << "calls to fillHistogram go here" << endl; - fillHistogram( kVecPsMass, X.M() ); + fillHistogram( kProd_Ang, prod_angle ); fillHistogram( kCosTheta, cosTheta ); fillHistogram( kPhi, Phi ); fillHistogram( kCosThetaH, cosThetaH ); fillHistogram( kPhiH, PhiH ); - fillHistogram( kProd_Ang, prod_angle ); + + fillHistogram( kVecMass, vec.M() ); + fillHistogram( kVecPsMass, X.M() ); + fillHistogram( kt, Mandt ); - fillHistogram( kRecoilMass, recoil_mass ); + fillHistogram( kRecoilMass, recoil.M() ); fillHistogram( kProtonPsMass, proton_ps.M() ); fillHistogram( kRecoilPsMass, recoil_ps.M() ); diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h index 65e58c568..9a01647a3 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h @@ -17,7 +17,7 @@ class VecPs3PiPlotGenerator : public PlotGenerator public: // create an index for different histograms - enum { kVecPsMass = 0, kCosTheta = 1, kPhi = 2, kCosThetaH = 3, kPhiH = 4, kProd_Ang = 5, kt = 6, kRecoilMass = 7, kProtonPsMass = 8, kRecoilPsMass = 9, kNumHists}; + enum { kProd_Ang = 0, kCosTheta = 1, kPhi = 2, kCosThetaH = 3, kPhiH = 4, kVecMass = 5, kVecPsMass = 6, kt = 7, kRecoilMass = 8, kProtonPsMass = 9, kRecoilPsMass = 10, kNumHists}; VecPs3PiPlotGenerator( const FitResults& results, Option opt); VecPs3PiPlotGenerator( const FitResults& results ); diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc index 748be566b..a7c42b3d4 100644 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -137,7 +137,7 @@ int main( int argc, char* argv[] ){ vector amps = plotGen.uniqueAmplitudes(); cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; - vector amphistname = {"0-P"}; //, "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "1-P-", "1-P0", "1-P+"}; + vector amphistname = {"0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; vector reflname = {"PosRefl", "NegRefl"}; // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) @@ -204,16 +204,18 @@ int main( int argc, char* argv[] ){ // set unique histogram name for each plot (could put in directories...) string histname = ""; - if (ivar == VecPs3PiPlotGenerator::kVecPsMass) histname += "MVecPs"; - else if (ivar == VecPs3PiPlotGenerator::kCosTheta) histname += "CosTheta"; - else if (ivar == VecPs3PiPlotGenerator::kPhi) histname += "Phi"; - else if (ivar == VecPs3PiPlotGenerator::kCosThetaH) histname += "CosTheta_H"; - else if (ivar == VecPs3PiPlotGenerator::kPhiH) histname += "Phi_H"; - else if (ivar == VecPs3PiPlotGenerator::kProd_Ang) histname += "Prod_Ang"; - else if (ivar == VecPs3PiPlotGenerator::kt) histname += "t"; - else if (ivar == VecPs3PiPlotGenerator::kRecoilMass) histname += "MRecoil"; - else if (ivar == VecPs3PiPlotGenerator::kProtonPsMass) histname += "MProtonPs"; - else if (ivar == VecPs3PiPlotGenerator::kRecoilPsMass) histname += "MRecoilPs"; + + if (ivar == VecPs3PiPlotGenerator::kProd_Ang) histname += "Prod_Ang"; + else if (ivar == VecPs3PiPlotGenerator::kCosTheta) histname += "CosTheta_GJ"; + else if (ivar == VecPs3PiPlotGenerator::kPhi) histname += "Phi_GJ"; + else if (ivar == VecPs3PiPlotGenerator::kCosThetaH) histname += "CosTheta_HF"; + else if (ivar == VecPs3PiPlotGenerator::kPhiH) histname += "Phi_HF"; + else if (ivar == VecPs3PiPlotGenerator::kVecMass) histname += "MVec"; + else if (ivar == VecPs3PiPlotGenerator::kVecPsMass) histname += "MVecPs"; + else if (ivar == VecPs3PiPlotGenerator::kt) histname += "minust"; + else if (ivar == VecPs3PiPlotGenerator::kRecoilMass) histname += "ProtonPiplusL_M"; + else if (ivar == VecPs3PiPlotGenerator::kProtonPsMass) histname += "ProtonPiminus_M"; + else if (ivar == VecPs3PiPlotGenerator::kRecoilPsMass) histname += "ProtonPiplusLPiminus_M"; else continue; if (iplot == PlotGenerator::kData) histname += "_data"; From b40e1a0c8bbd7bf00bd6ec88a5aebd8954e2bb4b Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Tue, 20 Jan 2026 08:07:48 -0500 Subject: [PATCH 07/33] 3Pion plotter update. --- src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 2 +- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 148 +++++++++++++----- .../vecps3pi_plotter/vecps3pi_plotter.cc | 60 ++++--- .../vecps_plotter/vecps_plotter.cc | 4 +- 4 files changed, 139 insertions(+), 75 deletions(-) diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc index 8912478f7..88d5f55eb 100644 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc @@ -140,7 +140,7 @@ VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ } } - TLorentzVector recoil( pKin[1][1]+pkin[5][1], pKin[1][2]+pkin[5][2], pKin[1][3]+pkin[5][3], pKin[1][0]+pKin[5][0] ); + TLorentzVector recoil( pKin[1][1]+pKin[5][1], pKin[1][2]+pKin[5][2], pKin[1][3]+pKin[5][3], pKin[1][0]+pKin[5][0] ); // Fill in four-vectors for final state particles // 1st after proton is always the pseudoscalar meson diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc index 72de6212d..0ca8be3e2 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc @@ -7,6 +7,37 @@ #include "IUAmpTools/Histogram1D.h" #include "IUAmpTools/Kinematics.h" + + +// Function to check if a string is a valid number +static bool isValidNumber(const string& argInput, double &value){ + char* end = nullptr; + errno = 0; // reset global error + value = std::strtod(argInput.c_str(), &end); + + // Check if + // (1) no conversion was performed + // (2) there are leftover characters + // (3) an overflow/underflow occurred + if(end == argInput.c_str() || *end != '\0' || errno != 0) { + return false; // not a valid number + } + // If end points to the end of string, it's fully numeric + return true; +} + + +static double parseValidatedNumber(const string& label, const string& argInput){ + double tmpValue = 0.0; + if(!isValidNumber(argInput, tmpValue)){ + throw std::invalid_argument("Vec_ps_refl: invalid " + label + ": " + argInput); + } + return tmpValue; +} + + + + /* Constructor to display FitResults */ VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( const FitResults& results, Option opt ) : PlotGenerator( results, opt ) @@ -24,11 +55,11 @@ PlotGenerator( ) void VecPs3PiPlotGenerator::createHistograms( ) { cout << " calls to bookHistogram go here" << endl; - bookHistogram( kProd_Ang, new Histogram1D( 50, -PI, PI, "ProdAng", "Production Angle Lab frame [rad.]" ) ); - bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta Gottfried-Jackson frame [rad.]" ) ); - bookHistogram( kPhi, new Histogram1D( 50, -PI, PI, "Phi_GJ", "#phi Gottfried-Jackson frame [rad.]" ) ); - bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta Helicity frame [rad.]" ) ); - bookHistogram( kPhiH, new Histogram1D( 50, -PI, PI, "Phi_HF", "#phi Helicity frame [rad.]" ) ); + bookHistogram( kProd_Ang, new Histogram1D( 50, -PI, PI, "ProdAng", "Production Angle [rad.]" ) ); + bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta^{[GJ]} [rad.]" ) ); + bookHistogram( kPhi, new Histogram1D( 50, -PI, PI, "Phi_GJ", "#phi^{[GJ]} [rad.]" ) ); + bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta^{[HF]} [rad.]" ) ); + bookHistogram( kPhiH, new Histogram1D( 50, -PI, PI, "Phi_HF", "#phi^{[HF]} [rad.]" ) ); bookHistogram( kVecMass, new Histogram1D( 200, 0., 3., "MVec", "m(2#pi) [GeV]") ); bookHistogram( kVecPsMass, new Histogram1D( 200, 0.2, 3.2, "MVecPs", "m(3#pi) [GeV]") ); @@ -52,10 +83,13 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin ){ void VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ + // We use only default 2-body vector decay (set flag in config file for omega->3pi) + bool m_3pi = false; + // Fixed target TLorentzVector target(0,0,0,0.938272); - + //cout << "project event" << endl; TLorentzVector beam = kin->particle( 0 ); TLorentzVector proton = kin->particle( 1 ); @@ -63,34 +97,31 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName TLorentzVector vec_daught1 = kin->particle( 3 ); TLorentzVector vec_daught2 = kin->particle( 4 ); TLorentzVector piplusL = kin->particle( 5 ); - - // final meson system P4 - TLorentzVector vec = vec_daught1 + vec_daught2; - TLorentzVector X = vec + bach; + // Final state P4 momenta + TLorentzVector X = vec_daught1 + vec_daught2 + bach; TLorentzVector recoil = proton + piplusL; + + //Momenta for the 1st permutation + TLorentzVector vec_a = vec_daught1 + vec_daught2; + TLorentzVector proton_ps_a = proton + bach; + TLorentzVector recoil_ps_a = recoil + bach; - TLorentzVector proton_ps = proton + bach; - TLorentzVector recoil_ps = recoil + bach; - - - // We use only default 2-body vector decay (set flag in config file for omega->3pi) - bool m_3pi = false; + //Momenta for the 2nd permutation (bach <=> vec_daught1) + TLorentzVector vec_b = bach + vec_daught2; + TLorentzVector proton_ps_b = proton + vec_daught1; + TLorentzVector recoil_ps_b = recoil + vec_daught1; + - // check config file for optional parameters -- we assume here that the first amplitude in the list is a Vec_ps_refl amplitude + // Properly read polarization angle from config file if provided + double beam_polAngle=0; + // Check config file for optional parameters -- we assume here that the first amplitude in the list is a Vec_ps_refl amplitude const vector< string > args = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); for(uint ioption=5; ioption momentArgs = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); - for (uint ioption=0; ioption thetaPhiAnglesTwoStep = getTwoStepAngles(X, vec, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); + // Angles for the 1st permutation + vector thetaPhiAnglesTwoStep_a = getTwoStepAngles(X, vec_a, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); + // Angles for the 2nd permutation (bach <=> vec_daught1) + vector thetaPhiAnglesTwoStep_b = getTwoStepAngles(X, vec_b, bach, TLorentzVector(0,0,0,0), beam, target, 2, true); - GDouble cosTheta = TMath::Cos(thetaPhiAnglesTwoStep[0]); - GDouble phi = thetaPhiAnglesTwoStep[1]; - GDouble cosThetaH = TMath::Cos(thetaPhiAnglesTwoStep[2]); - GDouble phiH = thetaPhiAnglesTwoStep[3]; - + //Symmetrized angles and masses will be passed as vectors of unit length + vector cosTheta_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[0])}; + vector cosTheta_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[0])}; - //cout << "calls to fillHistogram go here" << endl; - fillHistogram( kProd_Ang, prod_angle ); - fillHistogram( kCosTheta, cosTheta ); - fillHistogram( kPhi, Phi ); - fillHistogram( kCosThetaH, cosThetaH ); - fillHistogram( kPhiH, PhiH ); + vector phi_a = {thetaPhiAnglesTwoStep_a[1]}; + vector phi_b = {thetaPhiAnglesTwoStep_b[1]}; - fillHistogram( kVecMass, vec.M() ); - fillHistogram( kVecPsMass, X.M() ); + vector cosThetaH_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[2])}; + vector cosThetaH_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[2])}; + + vector phiH_a = {thetaPhiAnglesTwoStep_a[3]}; + vector phiH_b = {thetaPhiAnglesTwoStep_b[3]}; + + vector vec_mass_a = {vec_a.M()}; + vector vec_mass_b = {vec_b.M()}; + + vector protonps_mass_a = {proton_ps_a.M()}; + vector protonps_mass_b = {proton_ps_b.M()}; + + vector recoilps_mass_a = {recoil_ps_a.M()}; + vector recoilps_mass_b = {recoil_ps_b.M()}; + + + //First, insensitive to the symmetrization quantities + fillHistogram( kProd_Ang, prod_angle ); fillHistogram( kt, Mandt ); fillHistogram( kRecoilMass, recoil.M() ); - fillHistogram( kProtonPsMass, proton_ps.M() ); - fillHistogram( kRecoilPsMass, recoil_ps.M() ); + fillHistogram( kVecPsMass, X.M() ); + + + //Now, symmetrized quantities + fillHistogram( kCosTheta, cosTheta_a, 0.5 ); + fillHistogram( kPhi, phi_a, 0.5 ); + fillHistogram( kCosThetaH, cosThetaH_a, 0.5 ); + fillHistogram( kPhiH, phiH_a, 0.5 ); + + fillHistogram( kVecMass, vec_mass_a, 0.5 ); + fillHistogram( kProtonPsMass, protonps_mass_a, 0.5 ); + fillHistogram( kRecoilPsMass, recoilps_mass_a, 0.5 ); + + fillHistogram( kCosTheta, cosTheta_b, 0.5 ); + fillHistogram( kPhi, phi_b, 0.5 ); + fillHistogram( kCosThetaH, cosThetaH_b, 0.5 ); + fillHistogram( kPhiH, phiH_b, 0.5 ); + + fillHistogram( kVecMass, vec_mass_b, 0.5 ); + fillHistogram( kProtonPsMass, protonps_mass_b, 0.5 ); + fillHistogram( kRecoilPsMass, recoilps_mass_b, 0.5 ); + + + } diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc index a7c42b3d4..2c6475ecd 100644 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -131,6 +131,9 @@ int main( int argc, char* argv[] ){ TFile* plotfile = new TFile( outName.c_str(), "recreate"); TH1::AddDirectory(kFALSE); + TDirectory* plotfiledir = plotfile->mkdir("Contributions"); + + string reactionName = results.reactionList()[0]; plotGen.enableReaction( reactionName ); vector sums = plotGen.uniqueSums(); @@ -139,40 +142,37 @@ int main( int argc, char* argv[] ){ vector amphistname = {"0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; vector reflname = {"PosRefl", "NegRefl"}; - + string locampname; + // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++){ // loop over desired amplitudes for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++ ) { - // turn all ampltiudes by default - for (unsigned int jamp = 0; jamp < amps.size(); jamp++ ) { - plotGen.enableAmp( jamp ); - } + // turn on all ampltiudes by default + for (unsigned int jamp = 0; jamp < amps.size(); jamp++ ) plotGen.enableAmp( jamp ); + + if (iamp < amphistname.size()){ + // amplitude name + locampname = amphistname[iamp]; - // turn off unwanted amplitudes and sums - if (iamp < amphistname.size()) { - - string locampname = amphistname[iamp]; - // turn on all sums by default - for (unsigned int i = 0; i < sums.size(); i++) plotGen.enableSum(i); - - // turn off unwanted sums for reflectivity (based on naturality) - //cout<<"refl = "<toRoot(); thist->SetName(histname.c_str()); - plotfile->cd(); + if (iamp < amphistname.size()) plotfiledir->cd(); + else plotfile->cd(); thist->Write(); } @@ -258,7 +256,7 @@ int main( int argc, char* argv[] ){ // file for writing parameters (later switch to putting in ROOT file) ofstream outfile; - outfile.open( "vecps_fitPars.txt" ); + outfile.open( "vecps3pi__fitPars.txt" ); for(unsigned int i = 0; i 0) break; // TEMPORARY - REMOVE TO ENABLE ALL POL FILES + for (unsigned int polFile = 0; polFile < nReactions; polFile++) { + string reactionName = results.reactionList()[polFile]; outName = reactionName + ".root"; From b9447821c747c29c9c64099403957672feda9e47 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Wed, 21 Jan 2026 12:45:31 -0500 Subject: [PATCH 08/33] Updaate for VecPs3Pi plotter. --- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 28 ++-- .../vecps3pi_plotter/vecps3pi_plotter.cc | 145 ++++++++++-------- .../vecps_plotter/vecps_plotter.cc | 2 +- 3 files changed, 101 insertions(+), 74 deletions(-) diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc index 0ca8be3e2..9aa449bc3 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc @@ -56,9 +56,9 @@ void VecPs3PiPlotGenerator::createHistograms( ) { cout << " calls to bookHistogram go here" << endl; bookHistogram( kProd_Ang, new Histogram1D( 50, -PI, PI, "ProdAng", "Production Angle [rad.]" ) ); - bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta^{[GJ]} [rad.]" ) ); + bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta^{[GJ]}" ) ); bookHistogram( kPhi, new Histogram1D( 50, -PI, PI, "Phi_GJ", "#phi^{[GJ]} [rad.]" ) ); - bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta^{[HF]} [rad.]" ) ); + bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta^{[HF]}" ) ); bookHistogram( kPhiH, new Histogram1D( 50, -PI, PI, "Phi_HF", "#phi^{[HF]} [rad.]" ) ); bookHistogram( kVecMass, new Histogram1D( 200, 0., 3., "MVec", "m(2#pi) [GeV]") ); @@ -83,8 +83,8 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin ){ void VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ - // We use only default 2-body vector decay (set flag in config file for omega->3pi) - bool m_3pi = false; + // We work only with a 2-body vector decay + // Fixed target TLorentzVector target(0,0,0,0.938272); @@ -173,21 +173,25 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName //Now, symmetrized quantities fillHistogram( kCosTheta, cosTheta_a, 0.5 ); - fillHistogram( kPhi, phi_a, 0.5 ); - fillHistogram( kCosThetaH, cosThetaH_a, 0.5 ); - fillHistogram( kPhiH, phiH_a, 0.5 ); - - fillHistogram( kVecMass, vec_mass_a, 0.5 ); - fillHistogram( kProtonPsMass, protonps_mass_a, 0.5 ); - fillHistogram( kRecoilPsMass, recoilps_mass_a, 0.5 ); - fillHistogram( kCosTheta, cosTheta_b, 0.5 ); + + fillHistogram( kPhi, phi_a, 0.5 ); fillHistogram( kPhi, phi_b, 0.5 ); + + fillHistogram( kCosThetaH, cosThetaH_a, 0.5 ); fillHistogram( kCosThetaH, cosThetaH_b, 0.5 ); + + fillHistogram( kPhiH, phiH_a, 0.5 ); fillHistogram( kPhiH, phiH_b, 0.5 ); + + fillHistogram( kVecMass, vec_mass_a, 0.5 ); fillHistogram( kVecMass, vec_mass_b, 0.5 ); + + fillHistogram( kProtonPsMass, protonps_mass_a, 0.5 ); fillHistogram( kProtonPsMass, protonps_mass_b, 0.5 ); + + fillHistogram( kRecoilPsMass, recoilps_mass_a, 0.5 ); fillHistogram( kRecoilPsMass, recoilps_mass_b, 0.5 ); diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc index 2c6475ecd..d97353a14 100644 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -74,7 +74,7 @@ int main( int argc, char* argv[] ){ } bool showGui = false; - string outName = "vecps3pi_plot.root"; + string outName = "vecps3pi_histos.root"; string resultsName(argv[1]); for (int i = 2; i < argc; i++){ @@ -127,65 +127,80 @@ int main( int argc, char* argv[] ){ // ************************ // set up an output ROOT file to store histograms // ************************ + TFile* plotfile = new TFile( outName.c_str(), "recreate"); + TH1::AddDirectory(kFALSE); - TFile* plotfile = new TFile( outName.c_str(), "recreate"); - TH1::AddDirectory(kFALSE); + //************************* + // Loop over different polarization files + // ************************* + size_t nReactions = results.reactionList().size(); - TDirectory* plotfiledir = plotfile->mkdir("Contributions"); + + for (unsigned int polType = 0; polType < nReactions; polType++) { + // if (polType > 0) break; // TEMPORARY + + string reactionName = results.reactionList()[polType]; + + //WRITING SEPARATE FILES FOR DIFF POLS + // outName = reactionName + ".root"; + //TFile* plotfile = new TFile( outName.c_str(), "recreate"); + //TH1::AddDirectory(kFALSE); + + string dirname = "Contributions_"+reactionName; + TDirectory* plotfiledir = plotfile->mkdir(dirname.c_str()); - string reactionName = results.reactionList()[0]; - plotGen.enableReaction( reactionName ); - vector sums = plotGen.uniqueSums(); - vector amps = plotGen.uniqueAmplitudes(); - cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; - - vector amphistname = {"0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; - vector reflname = {"PosRefl", "NegRefl"}; - string locampname; + plotGen.enableReaction( reactionName ); + vector sums = plotGen.uniqueSums(); + vector amps = plotGen.uniqueAmplitudes(); + cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; + + vector amphistname = {"0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; + vector reflname = {"PosRefl", "NegRefl"}; + string locampname; - // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) - for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++){ + // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) + for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++){ - // loop over desired amplitudes - for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++ ) { + // loop over desired amplitudes + for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++ ) { - // turn on all ampltiudes by default - for (unsigned int jamp = 0; jamp < amps.size(); jamp++ ) plotGen.enableAmp( jamp ); + // turn on all ampltiudes by default + for (unsigned int jamp = 0; jamp < amps.size(); jamp++ ) plotGen.enableAmp( jamp ); - if (iamp < amphistname.size()){ - // amplitude name - locampname = amphistname[iamp]; + if (iamp < amphistname.size()){ + // amplitude name + locampname = amphistname[iamp]; - // turn on all sums by default - for (unsigned int jsum = 0; jsum < sums.size(); jsum++) plotGen.enableSum(jsum); + // turn on all sums by default + for (unsigned int jsum = 0; jsum < sums.size(); jsum++) plotGen.enableSum(jsum); - //Arrange the negative and positive reflectivity sums by excluding the opposite reflectivity terms - //Negative reflectivity: "ImagNegSign" & "RealPosSign", as in the config file - //Positive reflectivity: "RealNegSign" & "ImagPosSign", as in the config file + //Arrange the negative and positive reflectivity sums by excluding the opposite reflectivity terms + //Negative reflectivity: "ImagNegSign" & "RealPosSign", as in the config file + //Positive reflectivity: "RealNegSign" & "ImagPosSign", as in the config file - if (irefl < 2) { - for (unsigned int i = 0; i < sums.size(); i++){ - if( reflname[irefl] == "NegRefl" ){ - if(sums[i].find("RealNegSign") != std::string::npos || sums[i].find("ImagPosSign") != std::string::npos){ - plotGen.disableSum(i); - //cout<<"disable sum "<Close(); + //plotfile->Close(); //in case a few 'reaction' files are generated + + // The next calculations only need to happen for the first file + // and we do not need to repeat for each polarization + if (polType > 0) continue; + // model parameters cout << "Checking Parameters" << endl; @@ -256,7 +276,7 @@ int main( int argc, char* argv[] ){ // file for writing parameters (later switch to putting in ROOT file) ofstream outfile; - outfile.open( "vecps3pi__fitPars.txt" ); + outfile.open( "vecps3pi__fitpars.txt" ); for(unsigned int i = 0; i phaseDiff = results.phaseDiff( phaseDiffNames[i].first, phaseDiffNames[i].second ); outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " << phaseDiffNames[i].second << " " << phaseDiff.first << " " << phaseDiff.second << endl; - } + }// end of loop over 'reactions' + + plotfile->Close(); + // covariance matrix vector< vector< double > > covMatrix; covMatrix = results.errorMatrix(); diff --git a/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc b/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc index 00bbdf7fe..efbe83618 100644 --- a/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc @@ -130,7 +130,7 @@ int main(int argc, char* argv[]) { string reactionName = results.reactionList()[polFile]; outName = reactionName + ".root"; - + TFile* plotfile = new TFile(outName.c_str(), "recreate"); TH1::AddDirectory(kFALSE); From a76bf0a5f20f2abfcb442ef73c3977c2494dbcda Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Mon, 2 Feb 2026 09:30:22 -0500 Subject: [PATCH 09/33] vecps3pi_plotter small update --- .../vecps3pi_plotter/vecps3pi_plotter.cc | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc index d97353a14..07cc4fc9c 100644 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -137,7 +137,7 @@ int main( int argc, char* argv[] ){ for (unsigned int polType = 0; polType < nReactions; polType++) { - // if (polType > 0) break; // TEMPORARY + string reactionName = results.reactionList()[polType]; @@ -155,8 +155,8 @@ int main( int argc, char* argv[] ){ vector amps = plotGen.uniqueAmplitudes(); cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; - vector amphistname = {"0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; - vector reflname = {"PosRefl", "NegRefl"}; + vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; + vector reflname = {"Uniform","PosRefl", "NegRefl"}; string locampname; // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) @@ -175,20 +175,27 @@ int main( int argc, char* argv[] ){ // turn on all sums by default for (unsigned int jsum = 0; jsum < sums.size(); jsum++) plotGen.enableSum(jsum); - //Arrange the negative and positive reflectivity sums by excluding the opposite reflectivity terms + //Arrange the negative and positive reflectivity sums //Negative reflectivity: "ImagNegSign" & "RealPosSign", as in the config file //Positive reflectivity: "RealNegSign" & "ImagPosSign", as in the config file - if (irefl < 2) { + if (irefl < 3) { for (unsigned int i = 0; i < sums.size(); i++){ if( reflname[irefl] == "NegRefl" ){ - if(sums[i].find("RealNegSign") != std::string::npos || sums[i].find("ImagPosSign") != std::string::npos){ + if(sums[i].find("RealNegSign") != std::string::npos || sums[i].find("ImagPosSign") != std::string::npos || sums[i].find("UniBG") != std::string::npos){ plotGen.disableSum(i); //cout<<"disable sum "< 0) || (irefl > 0 && iamp == 0); + + if (iplot == PlotGenerator::kGenMC) continue; if ( iplot == PlotGenerator::kData && !singleData ) continue; // only plot data once - + if ( iplot == PlotGenerator::kBkgnd && !singleData ) continue; // only plot background once + if ( iplot == PlotGenerator::kAccMC && singleFlatWave ) continue; // only plot Flat wave once + + + + + // loop over different variables for (unsigned int ivar = 0; ivar < VecPs3PiPlotGenerator::kNumHists; ivar++){ @@ -241,7 +256,7 @@ int main( int argc, char* argv[] ){ histname += "_"; histname += sumName; } - if (iamp < amphistname.size()) { + if (iamp > 0 && iamp < amphistname.size()) { // get name of amp for naming histogram histname += "_"; histname += amphistname[iamp]; @@ -250,8 +265,8 @@ int main( int argc, char* argv[] ){ Histogram* hist = plotGen.projection(ivar, reactionName, iplot); TH1* thist = hist->toRoot(); thist->SetName(histname.c_str()); - if (iamp < amphistname.size()) plotfiledir->cd(); - else plotfile->cd(); + if (iamp > 0 && iamp < amphistname.size()) plotfiledir->cd(); + else plotfile->cd(); thist->Write(); } From eb44b98589f3cf857c6c159d9ea7d5e59d642bf4 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Mon, 2 Feb 2026 11:43:43 -0500 Subject: [PATCH 10/33] Samll update for vecps3pi_plotter --- .../vecps3pi_plotter/vecps3pi_plotter.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc index 07cc4fc9c..d3fb84bdd 100644 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -210,6 +210,8 @@ int main( int argc, char* argv[] ){ } // close if (iamp < amphistname.size()) + + // GENERATE HISTOGRAMS BY MEANS OF PLOT GENERATOR cout << "Looping over input data" << endl; // loop over data, accMC, and genMC @@ -222,9 +224,7 @@ int main( int argc, char* argv[] ){ if ( iplot == PlotGenerator::kBkgnd && !singleData ) continue; // only plot background once if ( iplot == PlotGenerator::kAccMC && singleFlatWave ) continue; // only plot Flat wave once - - // loop over different variables for (unsigned int ivar = 0; ivar < VecPs3PiPlotGenerator::kNumHists; ivar++){ @@ -271,11 +271,13 @@ int main( int argc, char* argv[] ){ } } - } - } + } // end of loop over amplitudes + } // end of loop over sum configurations //plotfile->Close(); //in case a few 'reaction' files are generated + + // CALCULATE INTENSITY FRACTIONS AND PHASE DIFFERENCES // The next calculations only need to happen for the first file // and we do not need to repeat for each polarization @@ -302,7 +304,8 @@ int main( int argc, char* argv[] ){ outfile << "TOTAL EVENTS = " << results.intensity().first << " +- " << results.intensity().second << endl; vector fullamps = plotGen.fullAmplitudes(); for (unsigned int i = 0; i < fullamps.size(); i++){ - vector useamp; useamp.push_back(fullamps[i]); + vector useamp; + useamp.push_back(fullamps[i]); outfile << "FIT FRACTION " << fullamps[i] << " = " << results.intensity(useamp).first / results.intensity().first << " +- " @@ -321,14 +324,14 @@ int main( int argc, char* argv[] ){ for(int iamp=0; iamp Date: Tue, 3 Feb 2026 10:47:09 -0500 Subject: [PATCH 11/33] Minor change --- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 16 +++++----- .../vecps3pi_plotter/vecps3pi_plotter.cc | 30 +++++++++++-------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc index 9aa449bc3..e09b5f941 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc @@ -55,11 +55,11 @@ PlotGenerator( ) void VecPs3PiPlotGenerator::createHistograms( ) { cout << " calls to bookHistogram go here" << endl; - bookHistogram( kProd_Ang, new Histogram1D( 50, -PI, PI, "ProdAng", "Production Angle [rad.]" ) ); + bookHistogram( kProd_Ang, new Histogram1D( 50, -180., 180., "ProdAng", "Production Angle [deg.]" ) ); bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta^{[GJ]}" ) ); - bookHistogram( kPhi, new Histogram1D( 50, -PI, PI, "Phi_GJ", "#phi^{[GJ]} [rad.]" ) ); + bookHistogram( kPhi, new Histogram1D( 50, -180., 180., "Phi_GJ", "#phi^{[GJ]} [deg.]" ) ); bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta^{[HF]}" ) ); - bookHistogram( kPhiH, new Histogram1D( 50, -PI, PI, "Phi_HF", "#phi^{[HF]} [rad.]" ) ); + bookHistogram( kPhiH, new Histogram1D( 50, -180., 180., "Phi_HF", "#phi^{[HF]} [deg.]" ) ); bookHistogram( kVecMass, new Histogram1D( 200, 0., 3., "MVec", "m(2#pi) [GeV]") ); bookHistogram( kVecPsMass, new Histogram1D( 200, 0.2, 3.2, "MVecPs", "m(3#pi) [GeV]") ); @@ -130,7 +130,7 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName double Mandt = fabs((target-recoil).M2()); //Calculate production angle in the Gottfried-Jackson frame - GDouble prod_angle = getPhiProd(beam_polAngle, X, beam, target, 2, true); + double prod_angle = TMath::RadToDeg()*getPhiProd(beam_polAngle, X, beam, target, 2, true); // Calculate decay angles for X in the Gottfried-Jackson frame and for Isobar in the Helicity frame // Angles for the 1st permutation @@ -144,14 +144,14 @@ VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName vector cosTheta_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[0])}; vector cosTheta_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[0])}; - vector phi_a = {thetaPhiAnglesTwoStep_a[1]}; - vector phi_b = {thetaPhiAnglesTwoStep_b[1]}; + vector phi_a = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_a[1]}; + vector phi_b = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_b[1]}; vector cosThetaH_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[2])}; vector cosThetaH_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[2])}; - vector phiH_a = {thetaPhiAnglesTwoStep_a[3]}; - vector phiH_b = {thetaPhiAnglesTwoStep_b[3]}; + vector phiH_a = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_a[3]}; + vector phiH_b = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_b[3]}; vector vec_mass_a = {vec_a.M()}; vector vec_mass_b = {vec_b.M()}; diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc index d3fb84bdd..e0907ece1 100644 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -123,19 +123,26 @@ int main( int argc, char* argv[] ){ vecps_PlotGen plotGen( results , PlotGenerator::kNoGenMC ); cout << " Initialized ati and PlotGen" << endl; - + // ************************ // set up an output ROOT file to store histograms // ************************ TFile* plotfile = new TFile( outName.c_str(), "recreate"); TH1::AddDirectory(kFALSE); + //************************* + // Arrange Amplitude and Sum names + //***************************** + vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; + vector reflname = {"Uniform","PosRefl", "NegRefl"}; + + //************************* - // Loop over different polarization files + // Loop over different polarization types // ************************* size_t nReactions = results.reactionList().size(); - + for (unsigned int polType = 0; polType < nReactions; polType++) { @@ -155,8 +162,6 @@ int main( int argc, char* argv[] ){ vector amps = plotGen.uniqueAmplitudes(); cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; - vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; - vector reflname = {"Uniform","PosRefl", "NegRefl"}; string locampname; // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) @@ -273,15 +278,15 @@ int main( int argc, char* argv[] ){ } } // end of loop over amplitudes } // end of loop over sum configurations + }// end of loop over 'reactions' - //plotfile->Close(); //in case a few 'reaction' files are generated + plotfile->Close(); - // CALCULATE INTENSITY FRACTIONS AND PHASE DIFFERENCES - - // The next calculations only need to happen for the first file - // and we do not need to repeat for each polarization - if (polType > 0) continue; + + // CALCULATE INTENSITY FRACTIONS AND PHASE DIFFERENCES + // Alll 'reactions' are already turned on + // The next calculations only need to happen one time // model parameters cout << "Checking Parameters" << endl; @@ -364,10 +369,9 @@ int main( int argc, char* argv[] ){ pair phaseDiff = results.phaseDiff( phaseDiffNames[i].first, phaseDiffNames[i].second ); outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " << phaseDiffNames[i].second << " " << phaseDiff.first << " " << phaseDiff.second << endl; } - }// end of loop over 'reactions' - plotfile->Close(); + // plotfile->Close(); // covariance matrix vector< vector< double > > covMatrix; From 0e18020bbc02f71cf624ef8e83dee5b5a73630c3 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Mon, 2 Mar 2026 10:40:15 -0500 Subject: [PATCH 12/33] Generalized amplitude for the Isobar-Pseudoscalar production --- .../AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu | 24 + src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc | 234 ++++++++++ src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.h | 93 ++++ src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 2 +- .../AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc | 207 +++++++++ .../AMPTOOLS_DATAIO/IsoPsPlotGenerator.h | 36 ++ .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 7 + src/programs/AmplitudeAnalysis/SConscript | 2 +- .../AmplitudeAnalysis/fitMPI/fitMPI.cc | 2 + .../isops_plotter/SConscript | 22 + .../isops_plotter/isops_plotter.cc | 419 ++++++++++++++++++ .../vecps3pi_plotter/vecps3pi_plotter.cc | 35 +- 12 files changed, 1067 insertions(+), 16 deletions(-) create mode 100644 src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu create mode 100644 src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc create mode 100644 src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.h create mode 100644 src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc create mode 100644 src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.h create mode 100644 src/programs/AmplitudeAnalysis/isops_plotter/SConscript create mode 100644 src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc diff --git a/src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu b/src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu new file mode 100644 index 000000000..34c02acef --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu @@ -0,0 +1,24 @@ + +#include + +#include "GPUManager/GPUCustomTypes.h" +#include "GPUManager/CUDA-Complex.cuh" + +__global__ void +GPUIso_ps_refl_kernel( GPU_AMP_PROTO ) +{ + int iEvent = GPU_THIS_EVENT; + + WCUComplex ans = { GPU_UVARS(0), GPU_UVARS(1) }; + pcDevAmp[iEvent] = ans; +} + +void +GPUIso_ps_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) + +{ + + GPUIso_ps_refl_kernel<<< dimGrid, dimBlock >>>( GPU_AMP_ARGS ); + +} + diff --git a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc new file mode 100644 index 000000000..0e3aed70b --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc @@ -0,0 +1,234 @@ + +#include +#include +#include +#include +#include + +#include "TLorentzVector.h" +#include "TLorentzRotation.h" +#include "TFile.h" + +#include "IUAmpTools/Kinematics.h" +#include "AMPTOOLS_AMPS/Iso_ps_refl.h" +#include "AMPTOOLS_AMPS/clebschGordan.h" +#include "AMPTOOLS_AMPS/wignerD.h" +#include "AMPTOOLS_AMPS/decayAngles.h" +#include "AMPTOOLS_AMPS/barrierFactor.h" + +#include "UTILITIES/BeamProperties.h" + +// Function to check if a string is a valid number +static bool isValidNumber(const string& argInput, double &value){ + char* end = nullptr; + errno = 0; // reset global error + value = std::strtod(argInput.c_str(), &end); + + // Check if + // (1) no conversion was performed + // (2) there are leftover characters + // (3) an overflow/underflow occurred + if(end == argInput.c_str() || *end != '\0' || errno != 0) { + return false; // not a valid number + } + // If end points to the end of string, it's fully numeric + return true; +} + +static double parseValidatedNumber(const string& label, const string& argInput){ + double tmpValue = 0.0; + if(!isValidNumber(argInput, tmpValue)){ + throw std::invalid_argument("Iso_ps_refl: invalid " + label + ": " + argInput); + } + return tmpValue; +} + + +Iso_ps_refl::Iso_ps_refl( const vector< string >& args ) : +UserAmplitude< Iso_ps_refl >( args ){ + + // This function is only for the two-body Isobar decay: xi -> pipi + + // 6 possibilities to initialize this amplitude: + // : isobar spin + // : total spin, + // : total spin projection, + // : partial wave, + // : +1/-1 for real/imaginary part; + // : +1/-1 sign in P_gamma term + + // Isobar spin S + m_s = static_cast(parseValidatedNumber("S",args[0])); + // Resonance spin J + m_j = static_cast(parseValidatedNumber("J", args[1])); + // Spin projection (Lambda) + m_m = static_cast(parseValidatedNumber("M", args[2])); + // Partial wave L + m_l = static_cast(parseValidatedNumber("L", args[3])); + // Real (+1) or imaginary (-1) + m_real = static_cast(parseValidatedNumber("Re/Im", args[4])); + // Sign for polarization in amplitude + m_sign = static_cast(parseValidatedNumber("P_gamma sign", args[5])); + + + // make sure values are reasonable + assert(m_s >= 0 && m_s <= 2); + assert( abs( m_m ) <= m_j ); + // m_real = +1 for real + // m_real = -1 for imag + assert( abs( m_real ) == 1 ); + // m_sign = +1 for 1 + Pgamma + // m_sign = -1 for 1 - Pgamma + assert( abs( m_sign ) == 1 ); + + // Default polarization information stored in tree + m_polInTree = true; + + // Loop over any additional amplitude arguments to change defaults + for(uint ioption=6; ioptionGet(args[8].c_str()); + if(polFrac_vs_E != nullptr ){ + throw std::runtime_error( + "Iso_ps_refl ERROR: Could not find histogram '" + args[8] + + "' in file " + std::string(polOption.Data())); + } + } + else{ + polFraction = parseValidatedNumber("polarization fraction", args[7]); + } + } + } +} + +void +Iso_ps_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ + + TLorentzVector beam; + TVector3 eps; + GDouble beam_polFraction; + GDouble beam_polAngle; + + if(m_polInTree){ + beam.SetPxPyPzE( 0.0, 0.0, pKin[0][0], pKin[0][0]); + eps.SetXYZ(pKin[0][1], pKin[0][2], 0.0); // beam polarization vector; + + beam_polFraction = eps.Mag(); + beam_polAngle = eps.Phi(); + } + else{ + beam.SetPxPyPzE( pKin[0][1], pKin[0][2], pKin[0][3], pKin[0][0] ); + beam_polAngle = polAngle; + + if(polFraction > 0.0){ // for fitting with fixed polarization + beam_polFraction = polFraction; + } + else{ // for fitting with polarization vs E_gamma from input histogram + int bin = polFrac_vs_E->GetXaxis()->FindBin(pKin[0][0]); + if (bin == 0 || bin > polFrac_vs_E->GetXaxis()->GetNbins()){ + beam_polFraction = 0.0; + } else + beam_polFraction = polFrac_vs_E->GetBinContent(bin); + } + } + + + // Fill in four-vectors for final state particles + TLorentzVector target(0,0,0,0.938272); // Fixed target + TLorentzVector recoil( pKin[1][1]+pKin[5][1], pKin[1][2]+pKin[5][2], pKin[1][3]+pKin[5][3], pKin[1][0]+pKin[5][0] ); // Recoiling baryon + TLorentzVector ps(pKin[2][1], pKin[2][2], pKin[2][3], pKin[2][0]); // 1st after proton is always the pseudoscalar meson + + + // Compute isobar meson from its decay products (xi -> pipi) + // Make sure the order of daughters is correct in the config file! + TLorentzVector iso_daught1(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); + TLorentzVector iso_daught2(pKin[4][1], pKin[4][2], pKin[4][3], pKin[4][0]); + TLorentzVector iso = iso_daught1 + iso_daught2; + + // Final meson system P4 + TLorentzVector X = iso + ps; + + + //Calculate production angle in the Gottfried-Jackson frame + GDouble prod_angle = getPhiProd(beam_polAngle, X, beam, target, 2, true); + + // Calculate decay angles for X in the Gottfried-Jackson frame and for Isobar in the Helicity frame + vector thetaPhiAnglesTwoStep; + thetaPhiAnglesTwoStep = getTwoStepAngles(X, iso, iso_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); + + + + GDouble cosTheta = TMath::Cos(thetaPhiAnglesTwoStep[0]); + GDouble phi = thetaPhiAnglesTwoStep[1]; + GDouble cosThetaH = TMath::Cos(thetaPhiAnglesTwoStep[2]); + GDouble phiH = thetaPhiAnglesTwoStep[3]; + GDouble m_X = X.M(); + GDouble m_iso = iso.M(); + GDouble m_ps = ps.M(); + + complex amplitude(0,0); + complex i(0,1); + + for (int lambda = -m_s; lambda <= m_s; lambda++) { // sum over helicities + GDouble hel_amp = clebschGordan(m_l, m_s, 0, lambda, m_j, lambda); + amplitude += conj(wignerD(m_j, m_m, lambda, cosTheta, phi))*hel_amp*conj(wignerD(m_s, lambda, 0, cosThetaH, phiH)); + } + + GDouble factor = sqrt(1 + m_sign * beam_polFraction); + complex zjm = 0; + // - -> + in prod_angle + complex rotateY = polar((GDouble)1., (GDouble)(-1. * prod_angle )); + + if (m_real == 1) + zjm = real(amplitude * rotateY); + if (m_real == -1) + zjm = i*imag(amplitude * rotateY); + + // E852 Nozar thesis has sqrt(2*s+1)*sqrt(2*l+1)*F_l(p_omega)*sqrt(omega) + double kinFactor = barrierFactor(m_X, m_l, m_iso, m_ps); + //kinFactor *= sqrt(2.*m_s + 1.) * sqrt(2.*m_l + 1.); + factor *= kinFactor; + + userVars[uv_ampRe] = ( factor * zjm ).real(); + userVars[uv_ampIm] = ( factor * zjm ).imag(); + + return; +} + + +/////////////////////// Amplitude Calculation ////////////////////////// + +complex< GDouble > +Iso_ps_refl::calcAmplitude( GDouble** pKin, GDouble* userVars ) const +{ + return complex< GDouble >( userVars[uv_ampRe], userVars[uv_ampIm] ); +} + +void Iso_ps_refl::updatePar( const AmpParameter& par ){ + + // could do expensive calculations here on parameter updates +} + + +#ifdef GPU_ACCELERATION + +void +Iso_ps_refl::launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const { + + GPUIso_ps_refl_exec( dimGrid, dimBlock, GPU_AMP_ARGS ); + +} + +#endif + + diff --git a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.h b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.h new file mode 100644 index 000000000..e67be10a6 --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.h @@ -0,0 +1,93 @@ +#if !defined(ISO_PS_REFL) +#define ISO_PS_REFL + +#include "IUAmpTools/Amplitude.h" +#include "IUAmpTools/UserAmplitude.h" +#include "IUAmpTools/AmpParameter.h" +#include "GPUManager/GPUCustomTypes.h" + +#include "TH1D.h" +#include +#include +#include + +using std::complex; +using namespace std; + +#ifdef GPU_ACCELERATION +void +GPUIso_ps_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ); +#endif + +class Kinematics; + +class Iso_ps_refl : public UserAmplitude< Iso_ps_refl > +{ + +public: + + Iso_ps_refl() : UserAmplitude< Iso_ps_refl >() { }; + Iso_ps_refl( const vector< string >& args ); + Iso_ps_refl( int m_s, int m_j, int m_m, int m_l, int m_real, int m_sign ); + + string name() const { return "Iso_ps_refl"; } + + complex< GDouble > calcAmplitude( GDouble** pKin, GDouble* userVars ) const; + + // ********************** + // The following lines are optional and can be used to precalculate + // user-defined data that the amplitudes depend on. + + // Use this for indexing a user-defined data array and notifying + // the framework of the number of user-defined variables. + + //enum UserVars { uv_cosTheta = 0, uv_Phi, uv_cosThetaH, uv_PhiH, + // uv_prod_Phi, uv_MX, uv_MVec, uv_MPs, uv_beam_polFraction, + // uv_beam_polAngle, kNumUserVars }; + enum UserVars { uv_ampRe = 0, uv_ampIm, kNumUserVars }; + unsigned int numUserVars() const { return kNumUserVars; } + + // This function needs to be defined -- see comments and discussion + // in the .cc file. + void calcUserVars( GDouble** pKin, GDouble* userVars ) const; + + // This is an optional addition if the calcAmplitude routine + // can run with only the user-defined data and not the original + // four-vectors. It is used to optimize memory usage in GPU + // based fits. + bool needsUserVarsOnly() const { return true; } + + // This is an optional addition if the UserVars are the same for each + // instance of an amplitude. If it is not used, the memory footprint + // grows dramatically as UserVars values are stored for each instance + // of the amplitude. NOTE: To use this make sure that UserVars only + // depend on kinematics and no arguments provided to the amplitude! + bool areUserVarsStatic() const { return false; } + + void updatePar( const AmpParameter& par ); + +#ifdef GPU_ACCELERATION + + void launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const; + + bool isGPUEnabled() const { return true; } + +#endif // GPU_ACCELERATION + +private: + + int m_s; + int m_j; + int m_m; + int m_l; + int m_real; + int m_sign; + + //AmpParameter polAngle; + GDouble polFraction; + GDouble polAngle; + bool m_polInTree; + TH1D *polFrac_vs_E; +}; + +#endif diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc index 88d5f55eb..2d2e2aa0b 100644 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc @@ -38,7 +38,7 @@ static bool isValidNumber(const string& argInput, double &value){ static double parseValidatedNumber(const string& label, const string& argInput){ double tmpValue = 0.0; if(!isValidNumber(argInput, tmpValue)){ - throw std::invalid_argument("Vec_ps_refl: invalid " + label + ": " + argInput); + throw std::invalid_argument("VecPs_3pi_refl: invalid " + label + ": " + argInput); } return tmpValue; } diff --git a/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc new file mode 100644 index 000000000..7bdc91366 --- /dev/null +++ b/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc @@ -0,0 +1,207 @@ +#include "TLorentzVector.h" +#include "TLorentzRotation.h" + +#include "AMPTOOLS_AMPS/decayAngles.h" + +#include "AMPTOOLS_DATAIO/IsoPsPlotGenerator.h" +#include "IUAmpTools/Histogram1D.h" +#include "IUAmpTools/Kinematics.h" + + + +// Function to check if a string is a valid number +static bool isValidNumber(const string& argInput, double &value){ + char* end = nullptr; + errno = 0; // reset global error + value = std::strtod(argInput.c_str(), &end); + + // Check if + // (1) no conversion was performed + // (2) there are leftover characters + // (3) an overflow/underflow occurred + if(end == argInput.c_str() || *end != '\0' || errno != 0) { + return false; // not a valid number + } + // If end points to the end of string, it's fully numeric + return true; +} + + +static double parseValidatedNumber(const string& label, const string& argInput){ + double tmpValue = 0.0; + if(!isValidNumber(argInput, tmpValue)){ + throw std::invalid_argument("Iso_ps_refl: invalid " + label + ": " + argInput); + } + return tmpValue; +} + + + + +/* Constructor to display FitResults */ +IsoPsPlotGenerator::IsoPsPlotGenerator( const FitResults& results, Option opt ) : +PlotGenerator( results, opt ) +{ + createHistograms(); +} + +IsoPsPlotGenerator::IsoPsPlotGenerator( const FitResults& results ) : +PlotGenerator( results ) +{ + createHistograms(); +} + + +/* Constructor for event generator (no FitResult) */ +IsoPsPlotGenerator::IsoPsPlotGenerator( ) : +PlotGenerator( ) +{ + createHistograms(); +} + +void IsoPsPlotGenerator::createHistograms( ) { + cout << " calls to bookHistogram go here" << endl; + + bookHistogram( kProd_Ang, new Histogram1D( 50, -180., 180., "ProdAng", "Production Angle [deg.]" ) ); + bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta^{[GJ]}" ) ); + bookHistogram( kPhi, new Histogram1D( 50, -180., 180., "Phi_GJ", "#phi^{[GJ]} [deg.]" ) ); + bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta^{[HF]}" ) ); + bookHistogram( kPhiH, new Histogram1D( 50, -180., 180., "Phi_HF", "#phi^{[HF]} [deg.]" ) ); + + bookHistogram( kIsoMass, new Histogram1D( 200, 0., 3., "MIso", "m(2#pi) [GeV]") ); + bookHistogram( kIsoPsMass, new Histogram1D( 200, 0.2, 3.2, "MIsoPs", "m(3#pi) [GeV]") ); + bookHistogram( kt, new Histogram1D( 100, 0, 1.0 , "t", "-t [GeV^{2}]" ) ); + bookHistogram( kRecoilMass, new Histogram1D( 100, 0.9, 1.9 , "ProtonPiplusL_M", "m(p#pi^{+}_{L}) [GeV]" ) ); + + bookHistogram( kProtonPsMass, new Histogram1D( 200, 0.8, 3.8, "ProtonPiminus_M", "m(p#pi^{-}) [GeV]" ) ); + bookHistogram( kRecoilPsMass, new Histogram1D( 200, 1.0, 4.0, "ProtonPiplusLPiminus_M", "m(p#pi^{+}_{L}#pi^{-}) [GeV]" ) ); + +} + +void +IsoPsPlotGenerator::projectEvent( Kinematics* kin ){ + + // this function will make this class backwards-compatible with older versions + // (v0.10.x and prior) of AmpTools, but will not be able to properly obtain + // the polariation plane in the lab when multiple orientations are used + projectEvent( kin, "" ); +} + +void +IsoPsPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ + + // We work only with a 2-body vector decay + + + // Fixed target + TLorentzVector target(0,0,0,0.938272); + + + //cout << "project event" << endl; + TLorentzVector beam = kin->particle( 0 ); + TLorentzVector proton = kin->particle( 1 ); + TLorentzVector bach = kin->particle( 2 ); + TLorentzVector vec_daught1 = kin->particle( 3 ); + TLorentzVector vec_daught2 = kin->particle( 4 ); + TLorentzVector piplusL = kin->particle( 5 ); + + + // Final state P4 momenta + TLorentzVector X = vec_daught1 + vec_daught2 + bach; + TLorentzVector recoil = proton + piplusL; + + //Momenta for the 1st permutation + TLorentzVector vec_a = vec_daught1 + vec_daught2; + TLorentzVector proton_ps_a = proton + bach; + TLorentzVector recoil_ps_a = recoil + bach; + + //Momenta for the 2nd permutation (bach <=> vec_daught1) + TLorentzVector vec_b = bach + vec_daught2; + TLorentzVector proton_ps_b = proton + vec_daught1; + TLorentzVector recoil_ps_b = recoil + vec_daught1; + + + + // Properly read polarization angle from config file if provided + double beam_polAngle=0; + // Check config file for optional parameters -- we assume here that the first amplitude in the list is a Iso_ps_refl amplitude + const vector< string > args = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); + for(uint ioption=5; ioption thetaPhiAnglesTwoStep_a = getTwoStepAngles(X, vec_a, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); + + // Angles for the 2nd permutation (bach <=> vec_daught1) + vector thetaPhiAnglesTwoStep_b = getTwoStepAngles(X, vec_b, bach, TLorentzVector(0,0,0,0), beam, target, 2, true); + + + //Symmetrized angles and masses will be passed as vectors of unit length + vector cosTheta_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[0])}; + vector cosTheta_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[0])}; + + vector phi_a = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_a[1]}; + vector phi_b = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_b[1]}; + + vector cosThetaH_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[2])}; + vector cosThetaH_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[2])}; + + vector phiH_a = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_a[3]}; + vector phiH_b = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_b[3]}; + + vector vec_mass_a = {vec_a.M()}; + vector vec_mass_b = {vec_b.M()}; + + vector protonps_mass_a = {proton_ps_a.M()}; + vector protonps_mass_b = {proton_ps_b.M()}; + + vector recoilps_mass_a = {recoil_ps_a.M()}; + vector recoilps_mass_b = {recoil_ps_b.M()}; + + + + //First, insensitive to the symmetrization quantities + fillHistogram( kProd_Ang, prod_angle ); + fillHistogram( kt, Mandt ); + fillHistogram( kRecoilMass, recoil.M() ); + fillHistogram( kIsoPsMass, X.M() ); + + + //Now, symmetrized quantities + fillHistogram( kCosTheta, cosTheta_a, 0.5 ); + fillHistogram( kCosTheta, cosTheta_b, 0.5 ); + + fillHistogram( kPhi, phi_a, 0.5 ); + fillHistogram( kPhi, phi_b, 0.5 ); + + fillHistogram( kCosThetaH, cosThetaH_a, 0.5 ); + fillHistogram( kCosThetaH, cosThetaH_b, 0.5 ); + + fillHistogram( kPhiH, phiH_a, 0.5 ); + fillHistogram( kPhiH, phiH_b, 0.5 ); + + + fillHistogram( kIsoMass, vec_mass_a, 0.5 ); + fillHistogram( kIsoMass, vec_mass_b, 0.5 ); + + fillHistogram( kProtonPsMass, protonps_mass_a, 0.5 ); + fillHistogram( kProtonPsMass, protonps_mass_b, 0.5 ); + + fillHistogram( kRecoilPsMass, recoilps_mass_a, 0.5 ); + fillHistogram( kRecoilPsMass, recoilps_mass_b, 0.5 ); + + + + +} diff --git a/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.h b/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.h new file mode 100644 index 000000000..0f5123bad --- /dev/null +++ b/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.h @@ -0,0 +1,36 @@ +#if !(defined ISOPSPLOTGENERATOR) +#define ISOPSPLOTGENERATOR + +#include +#include + +#include "IUAmpTools/PlotGenerator.h" + +using namespace std; + +class FitResults; +class Kinematics; + +class IsoPsPlotGenerator : public PlotGenerator +{ + +public: + + // create an index for different histograms + enum { kProd_Ang = 0, kCosTheta = 1, kPhi = 2, kCosThetaH = 3, kPhiH = 4, kIsoMass = 5, kIsoPsMass = 6, kt = 7, kRecoilMass = 8, kProtonPsMass = 9, kRecoilPsMass = 10, kNumHists}; + + IsoPsPlotGenerator( const FitResults& results, Option opt); + IsoPsPlotGenerator( const FitResults& results ); + IsoPsPlotGenerator( ); + +private: + + void projectEvent( Kinematics* kin ); + void projectEvent( Kinematics* kin, const string& reactionName ); + + void createHistograms( ); + +}; + +#endif + diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc index e09b5f941..1c7f8d3d0 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc @@ -45,6 +45,13 @@ PlotGenerator( results, opt ) createHistograms(); } +VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( const FitResults& results ) : +PlotGenerator( results ) +{ + createHistograms(); +} + + /* Constructor for event generator (no FitResult) */ VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( ) : PlotGenerator( ) diff --git a/src/programs/AmplitudeAnalysis/SConscript b/src/programs/AmplitudeAnalysis/SConscript index a292e3ba5..35feaa142 100644 --- a/src/programs/AmplitudeAnalysis/SConscript +++ b/src/programs/AmplitudeAnalysis/SConscript @@ -3,7 +3,7 @@ import sbms Import('*') -subdirs = ['fit', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'vecps3pi_plotter', 'plot_etapi0'] +subdirs = ['fit', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'vecps3pi_plotter', 'isops_plotter', 'plot_etapi0'] SConscript(dirs=subdirs, exports='env osname', duplicate=0) diff --git a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc index 0afa94d8e..65b2b63fe 100644 --- a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc +++ b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc @@ -41,6 +41,7 @@ #include "AMPTOOLS_AMPS/omegapi_amplitude.h" #include "AMPTOOLS_AMPS/Vec_ps_refl.h" #include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" +#include "AMPTOOLS_AMPS/Iso_ps_refl.h" #include "AMPTOOLS_AMPS/Piecewise.h" #include "AMPTOOLS_AMPS/Flatte.h" #include "AMPTOOLS_AMPS/PhaseOffset.h" @@ -406,6 +407,7 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( omegapi_amplitude() ); AmpToolsInterface::registerAmplitude( Vec_ps_refl() ); AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); + AmpToolsInterface::registerAmplitude( Iso_ps_refl() ); AmpToolsInterface::registerAmplitude( Piecewise() ); AmpToolsInterface::registerAmplitude( Flatte() ); AmpToolsInterface::registerAmplitude( PhaseOffset() ); diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/SConscript b/src/programs/AmplitudeAnalysis/isops_plotter/SConscript new file mode 100644 index 000000000..7dcb10d85 --- /dev/null +++ b/src/programs/AmplitudeAnalysis/isops_plotter/SConscript @@ -0,0 +1,22 @@ + +import os +import sbms + +# get env object and clone it +Import('*') + +# Verify AMPTOOLS environment variable is set +if os.getenv('AMPTOOLS', 'nada')!='nada' and os.getenv('AMPPLOTTER', 'nada')!='nada': + + env = env.Clone() + + AMPTOOLS_LIBS = "AMPTOOLS_AMPS AMPTOOLS_DATAIO AMPTOOLS_MCGEN UTILITIES" + env.AppendUnique(LIBS = AMPTOOLS_LIBS.split()) + + sbms.AddHDDM(env) + sbms.AddAmpTools(env) + sbms.AddAmpPlotter(env) + sbms.AddUtilities(env) + sbms.AddROOT(env) + + sbms.executable(env) diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc new file mode 100644 index 000000000..b0626051f --- /dev/null +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -0,0 +1,419 @@ +#include +#include +#include +#include + +#include "TClass.h" +#include "TApplication.h" +#include "TGClient.h" +#include "TROOT.h" +#include "TH1.h" +#include "TStyle.h" +#include "TClass.h" +#include "TFile.h" +#include "TMultiGraph.h" +#include "TGraphErrors.h" + +#include "IUAmpTools/AmpToolsInterface.h" +#include "IUAmpTools/FitResults.h" + +#include "AmpPlotter/PlotterMainWindow.h" +#include "AmpPlotter/PlotFactory.h" + +#include "AMPTOOLS_DATAIO/IsoPsPlotGenerator.h" +#include "AMPTOOLS_DATAIO/ROOTDataReader.h" +#include "AMPTOOLS_DATAIO/ROOTDataReaderBootstrap.h" +#include "AMPTOOLS_DATAIO/ROOTDataReaderTEM.h" +#include "AMPTOOLS_DATAIO/FSRootDataReader.h" +#include "AMPTOOLS_AMPS/BreitWigner.h" +#include "AMPTOOLS_AMPS/Uniform.h" +#include "AMPTOOLS_AMPS/Iso_ps_refl.h" +#include "AMPTOOLS_AMPS/PhaseOffset.h" +#include "AMPTOOLS_AMPS/ComplexCoeff.h" +#include "AMPTOOLS_AMPS/Piecewise.h" +#include "AMPTOOLS_AMPS/OmegaDalitz.h" +#include "AMPTOOLS_AMPS/Vec_ps_moment.h" + +#include "MinuitInterface/MinuitMinimizationManager.h" +#include "IUAmpTools/ConfigFileParser.h" +#include "IUAmpTools/ConfigurationInfo.h" + + + +void atiSetup(){ + + AmpToolsInterface::registerAmplitude( BreitWigner() ); + AmpToolsInterface::registerAmplitude( Uniform() ); + AmpToolsInterface::registerAmplitude( Iso_ps_refl() ); + AmpToolsInterface::registerAmplitude( PhaseOffset() ); + AmpToolsInterface::registerAmplitude( ComplexCoeff() ); + AmpToolsInterface::registerAmplitude( Piecewise() ); + AmpToolsInterface::registerAmplitude( OmegaDalitz() ); + AmpToolsInterface::registerAmplitude( Vec_ps_moment() ); + + AmpToolsInterface::registerDataReader( ROOTDataReader() ); + AmpToolsInterface::registerDataReader( FSRootDataReader() ); + AmpToolsInterface::registerDataReader( ROOTDataReaderTEM() ); +} + +using namespace std; + +int main( int argc, char* argv[] ){ + + + // ************************ + // usage + // ************************ + + cout << endl << " *** Viewing Results Using AmpPlotter and writing root histograms *** " << endl << endl; + + if (argc < 2){ + cout << "Usage:" << endl << endl; + cout << "\tisops_plotter -o " << endl << endl; + return 0; + } + + bool showGui = false; + string outName = "isops_histos.root"; + string resultsName(argv[1]); + for (int i = 2; i < argc; i++){ + + string arg(argv[i]); + + if (arg == "-g"){ + showGui = true; + } + if (arg == "-o"){ + outName = argv[++i]; + } + if (arg == "-h"){ + cout << endl << " Usage for: " << argv[0] << endl << endl; + cout << "\t -o \t output file path" << endl; + cout << "\t -g \t show GUI" << endl; + exit(1); + } + } + + + // ************************ + // parse the command line parameters + // ************************ + + cout << "Fit results file name = " << resultsName << endl; + cout << "Output file name = " << outName << endl << endl; + + // ************************ + // load the results and display the configuration info + // ************************ + + cout << "Loading Fit results" << endl; + FitResults results( resultsName ); + if( !results.valid() ){ + + cout << "Invalid fit results in file: " << resultsName << endl; + exit( 1 ); + } + cout << "Fit results loaded" << endl; + // ************************ + // set up the plot generator + // ************************ + cout << "before atisetup();"<< endl; + atiSetup(); + cout << "Plotgen results"<< endl; + + IsoPsPlotGenerator plotGen( results, PlotGenerator::kNoGenMC ); // optional can be omitted + cout << " Initialized ati and PlotGen" << endl; + + + // ************************* + // Define Amplitude and Sum names + // ***************************** + /* + vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; + vector reflname = {"Uniform","PosRefl", "NegRefl"}; + + + // ************************ + // set up an output ROOT file to store histograms + // ************************ + + TFile* plotfile = new TFile( outName.c_str(), "recreate"); + TH1::AddDirectory(kFALSE); + + + // ************************* + // Loop over different polarization types + // ************************* + size_t nReactions = results.reactionList().size(); + + + for (unsigned int polType = 0; polType < nReactions; polType++) { + + + string reactionName = results.reactionList()[polType]; + + //WRITING SEPARATE FILES FOR DIFF POLS + // outName = reactionName + ".root"; + //TFile* plotfile = new TFile( outName.c_str(), "recreate"); + //TH1::AddDirectory(kFALSE); + + string dirname = "Contributions_"+reactionName; + TDirectory* plotfiledir = plotfile->mkdir(dirname.c_str()); + + + plotGen.enableReaction( reactionName ); + vector sums = plotGen.uniqueSums(); + vector amps = plotGen.uniqueAmplitudes(); + cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; + + string locampname; + + // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) + for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++){ + + // loop over desired amplitudes + for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++ ) { + + // turn on all ampltiudes by default + for (unsigned int jamp = 0; jamp < amps.size(); jamp++ ) plotGen.enableAmp( jamp ); + + if (iamp < amphistname.size()){ + // amplitude name + locampname = amphistname[iamp]; + + // turn on all sums by default + for (unsigned int jsum = 0; jsum < sums.size(); jsum++) plotGen.enableSum(jsum); + + //Arrange the negative and positive reflectivity sums + //Negative reflectivity: "ImagNegSign" & "RealPosSign", as in the config file + //Positive reflectivity: "RealNegSign" & "ImagPosSign", as in the config file + + if (irefl < 3) { + for (unsigned int i = 0; i < sums.size(); i++){ + if( reflname[irefl] == "NegRefl" ){ + if(sums[i].find("RealNegSign") != std::string::npos || sums[i].find("ImagPosSign") != std::string::npos || sums[i].find("UniBG") != std::string::npos){ + plotGen.disableSum(i); + //cout<<"disable sum "< 0) || (irefl > 0 && iamp == 0); + + if (iplot == PlotGenerator::kGenMC) continue; + if ( iplot == PlotGenerator::kData && !singleData ) continue; // only plot data once + if ( iplot == PlotGenerator::kBkgnd && !singleData ) continue; // only plot background once + if ( iplot == PlotGenerator::kAccMC && singleFlatWave ) continue; // only plot Flat wave once + + + + // loop over different variables + for (unsigned int ivar = 0; ivar < IsoPsPlotGenerator::kNumHists; ivar++){ + + // set unique histogram name for each plot (could put in directories...) + string histname = reactionName; + + if (ivar == IsoPsPlotGenerator::kProd_Ang) histname += "_Prod_Ang"; + else if (ivar == IsoPsPlotGenerator::kCosTheta) histname += "_CosTheta_GJ"; + else if (ivar == IsoPsPlotGenerator::kPhi) histname += "_Phi_GJ"; + else if (ivar == IsoPsPlotGenerator::kCosThetaH) histname += "_CosTheta_HF"; + else if (ivar == IsoPsPlotGenerator::kPhiH) histname += "_Phi_HF"; + else if (ivar == IsoPsPlotGenerator::kIsoMass) histname += "_MIso"; + else if (ivar == IsoPsPlotGenerator::kIsoPsMass) histname += "_MIsoPs"; + else if (ivar == IsoPsPlotGenerator::kt) histname += "_minust"; + else if (ivar == IsoPsPlotGenerator::kRecoilMass) histname += "_ProtonPiplusL_M"; + else if (ivar == IsoPsPlotGenerator::kProtonPsMass) histname += "_ProtonPiminus_M"; + else if (ivar == IsoPsPlotGenerator::kRecoilPsMass) histname += "_ProtonPiplusLPiminus_M"; + else continue; + + if (iplot == PlotGenerator::kData) histname += "_data"; + if (iplot == PlotGenerator::kBkgnd) histname += "_bkgnd"; + if (iplot == PlotGenerator::kAccMC) histname += "_acc"; + if (iplot == PlotGenerator::kGenMC) histname += "_gen"; + + if (irefl < reflname.size()){ + // get name of sum for naming histogram + string sumName = reflname[irefl]; + histname += "_"; + histname += sumName; + } + // if (iamp > 0 && iamp < amphistname.size()) { + if (iamp < amphistname.size()) { + // get name of amp for naming histogram + histname += "_"; + histname += amphistname[iamp]; + } + + Histogram* hist = plotGen.projection(ivar, reactionName, iplot); + TH1* thist = hist->toRoot(); + thist->SetName(histname.c_str()); + if (iamp > 0 && iamp < amphistname.size()) plotfiledir->cd(); + else plotfile->cd(); + thist->Write(); + + } + } + } // end of loop over amplitudes + } // end of loop over sum configurations + }// end of loop over 'reactions' + + plotfile->Close(); + + + + // CALCULATE INTENSITY FRACTIONS AND PHASE DIFFERENCES + // All 'reactions' are already turned on + // The next calculations only need to happen one time + + // model parameters + cout << "Checking Parameters" << endl; + + // parameters to check + vector< string > pars; + + // pars.push_back("dsratio"); + + // file for writing parameters (later switch to putting in ROOT file) + ofstream outfile; + outfile.open( "vecps3pi__fitpars.txt" ); + + for(unsigned int i = 0; i fullamps = plotGen.fullAmplitudes(); + for (unsigned int i = 0; i < fullamps.size(); i++){ + vector useamp; + useamp.push_back(fullamps[i]); + outfile << "FIT FRACTION " << fullamps[i] << " = " + << results.intensity(useamp).first / + results.intensity().first << " +- " + << results.intensity(useamp).second / + results.intensity().first << endl; + } + + const int nAmps = amphistname.size(); + vector ampsumPosRefl[nAmps]; + vector ampsumNegRefl[nAmps]; + vector< pair > phaseDiffNames; + + for(unsigned int i = 0; i < fullamps.size(); i++){ + + // combine amplitudes with names defined above + for(int iamp=0; iamp phaseDiff = results.phaseDiff( phaseDiffNames[i].first, phaseDiffNames[i].second ); + outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " << phaseDiffNames[i].second << " " << phaseDiff.first << " " << phaseDiff.second << endl; + } + + + + + // covariance matrix + vector< vector< double > > covMatrix; + covMatrix = results.errorMatrix(); + */ + + + // ************************ + // start the GUI + // ************************ + + if(showGui) { + + cout << ">> Plot generator ready, starting GUI..." << endl; + + int dummy_argc = 0; + char* dummy_argv[] = {}; + TApplication app( "app", &dummy_argc, dummy_argv ); + + gStyle->SetFillColor(10); + gStyle->SetCanvasColor(10); + gStyle->SetPadColor(10); + gStyle->SetFillStyle(1001); + gStyle->SetPalette(1); + gStyle->SetFrameFillColor(10); + gStyle->SetFrameFillStyle(1001); + + cout << " Initialized App " << endl; + PlotFactory factory( plotGen ); + cout << " Created Plot Factory " << endl; + PlotterMainWindow mainFrame( gClient->GetRoot(), factory ); + cout << " Main frame created " << endl; + + app.Run(); + cout << " App running" << endl; + } + + return 0; + +} diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc index e0907ece1..b6c937971 100644 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc @@ -113,7 +113,7 @@ int main( int argc, char* argv[] ){ cout << "Invalid fit results in file: " << resultsName << endl; exit( 1 ); } - cout << "Fit results loaded" << endl; + cout << "Fit results loaded" << endl; // ************************ // set up the plot generator // ************************ @@ -121,23 +121,27 @@ int main( int argc, char* argv[] ){ atiSetup(); cout << "Plotgen results"<< endl; - vecps_PlotGen plotGen( results , PlotGenerator::kNoGenMC ); + vecps_PlotGen plotGen( results, PlotGenerator::kNoGenMC ); // optional can be omitted cout << " Initialized ati and PlotGen" << endl; - + + + // ************************* + // Define Amplitude and Sum names + // ***************************** + /* + vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; + vector reflname = {"Uniform","PosRefl", "NegRefl"}; + + // ************************ // set up an output ROOT file to store histograms // ************************ + TFile* plotfile = new TFile( outName.c_str(), "recreate"); TH1::AddDirectory(kFALSE); - //************************* - // Arrange Amplitude and Sum names - //***************************** - vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; - vector reflname = {"Uniform","PosRefl", "NegRefl"}; - - //************************* + // ************************* // Loop over different polarization types // ************************* size_t nReactions = results.reactionList().size(); @@ -261,7 +265,8 @@ int main( int argc, char* argv[] ){ histname += "_"; histname += sumName; } - if (iamp > 0 && iamp < amphistname.size()) { + // if (iamp > 0 && iamp < amphistname.size()) { + if (iamp < amphistname.size()) { // get name of amp for naming histogram histname += "_"; histname += amphistname[iamp]; @@ -285,7 +290,7 @@ int main( int argc, char* argv[] ){ // CALCULATE INTENSITY FRACTIONS AND PHASE DIFFERENCES - // Alll 'reactions' are already turned on + // All 'reactions' are already turned on // The next calculations only need to happen one time // model parameters @@ -370,12 +375,14 @@ int main( int argc, char* argv[] ){ outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " << phaseDiffNames[i].second << " " << phaseDiff.first << " " << phaseDiff.second << endl; } - - // plotfile->Close(); + + // covariance matrix vector< vector< double > > covMatrix; covMatrix = results.errorMatrix(); + */ + // ************************ // start the GUI From d4cbd60595ec8f0ed3ce97a37627f466fecc7915 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Tue, 3 Mar 2026 06:01:46 -0500 Subject: [PATCH 13/33] Iso_ps_refl is compiled for using with both fit and fitMPI --- src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h | 2 +- src/programs/AmplitudeAnalysis/SConscript | 2 +- src/programs/AmplitudeAnalysis/fit/fit.cc | 2 ++ src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc | 3 ++- src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc | 3 +-- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h index 9a01647a3..c7e6c4383 100644 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h +++ b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h @@ -1,4 +1,4 @@ -#if !(defined VCPS3PIPLOTGENERATOR) +#if !(defined VECPS3PIPLOTGENERATOR) #define VECPS3PIPLOTGENERATOR #include diff --git a/src/programs/AmplitudeAnalysis/SConscript b/src/programs/AmplitudeAnalysis/SConscript index 35feaa142..9b27432f9 100644 --- a/src/programs/AmplitudeAnalysis/SConscript +++ b/src/programs/AmplitudeAnalysis/SConscript @@ -3,7 +3,7 @@ import sbms Import('*') -subdirs = ['fit', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'vecps3pi_plotter', 'isops_plotter', 'plot_etapi0'] +subdirs = ['fit', 'fitMPI', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'vecps3pi_plotter', 'isops_plotter', 'plot_etapi0'] SConscript(dirs=subdirs, exports='env osname', duplicate=0) diff --git a/src/programs/AmplitudeAnalysis/fit/fit.cc b/src/programs/AmplitudeAnalysis/fit/fit.cc index c514f283e..1f9c655ee 100644 --- a/src/programs/AmplitudeAnalysis/fit/fit.cc +++ b/src/programs/AmplitudeAnalysis/fit/fit.cc @@ -44,6 +44,7 @@ #include "AMPTOOLS_AMPS/DblRegge_FastPi.h" #include "AMPTOOLS_AMPS/omegapi_amplitude.h" #include "AMPTOOLS_AMPS/Vec_ps_refl.h" +#include "AMPTOOLS_AMPS/Iso_ps_refl.h" #include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" #include "AMPTOOLS_AMPS/PhaseOffset.h" #include "AMPTOOLS_AMPS/ComplexCoeff.h" @@ -434,6 +435,7 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( DblRegge_FastPi() ); AmpToolsInterface::registerAmplitude( omegapi_amplitude() ); AmpToolsInterface::registerAmplitude( Vec_ps_refl() ); + AmpToolsInterface::registerAmplitude( Iso_ps_refl() ); AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); AmpToolsInterface::registerAmplitude( PhaseOffset() ); AmpToolsInterface::registerAmplitude( ComplexCoeff() ); diff --git a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc index 65b2b63fe..4f199d00d 100644 --- a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc +++ b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc @@ -1,3 +1,4 @@ + #include #include #include @@ -406,8 +407,8 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( DblRegge_FastPi() ); AmpToolsInterface::registerAmplitude( omegapi_amplitude() ); AmpToolsInterface::registerAmplitude( Vec_ps_refl() ); - AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); AmpToolsInterface::registerAmplitude( Iso_ps_refl() ); + AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); AmpToolsInterface::registerAmplitude( Piecewise() ); AmpToolsInterface::registerAmplitude( Flatte() ); AmpToolsInterface::registerAmplitude( PhaseOffset() ); diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index b0626051f..dabdc7f26 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -32,7 +32,7 @@ #include "AMPTOOLS_AMPS/ComplexCoeff.h" #include "AMPTOOLS_AMPS/Piecewise.h" #include "AMPTOOLS_AMPS/OmegaDalitz.h" -#include "AMPTOOLS_AMPS/Vec_ps_moment.h" + #include "MinuitInterface/MinuitMinimizationManager.h" #include "IUAmpTools/ConfigFileParser.h" @@ -49,7 +49,6 @@ void atiSetup(){ AmpToolsInterface::registerAmplitude( ComplexCoeff() ); AmpToolsInterface::registerAmplitude( Piecewise() ); AmpToolsInterface::registerAmplitude( OmegaDalitz() ); - AmpToolsInterface::registerAmplitude( Vec_ps_moment() ); AmpToolsInterface::registerDataReader( ROOTDataReader() ); AmpToolsInterface::registerDataReader( FSRootDataReader() ); From 8434abb02cd97984f847d126f6c917e5aa4d54a8 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Tue, 24 Mar 2026 12:20:04 -0400 Subject: [PATCH 14/33] Minor update in the plotter --- .../isops_plotter/isops_plotter.cc | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index dabdc7f26..63505623f 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -68,27 +68,29 @@ int main( int argc, char* argv[] ){ if (argc < 2){ cout << "Usage:" << endl << endl; - cout << "\tisops_plotter -o " << endl << endl; + cout << "\tisops_plotter -o -t " << endl << endl; return 0; } bool showGui = false; - string outName = "isops_histos.root"; string resultsName(argv[1]); + string outName = "isops_histos.root"; + string outparsName = "isops__fitpars.txt"; + for (int i = 2; i < argc; i++){ string arg(argv[i]); - if (arg == "-g"){ - showGui = true; - } - if (arg == "-o"){ - outName = argv[++i]; - } + if (arg == "-o") outName = argv[++i]; + if (arg == "-t") outparsName = argv[++i]; + if (arg == "-g") showGui = true; + + if (arg == "-h"){ cout << endl << " Usage for: " << argv[0] << endl << endl; - cout << "\t -o \t output file path" << endl; - cout << "\t -g \t show GUI" << endl; + cout << "\t -o \t output root file path" << endl; + cout << "\t -t \t output text file path" << endl; + cout << "\t -g \t show GUI" << endl; exit(1); } } @@ -99,7 +101,8 @@ int main( int argc, char* argv[] ){ // ************************ cout << "Fit results file name = " << resultsName << endl; - cout << "Output file name = " << outName << endl << endl; + cout << "Output root file name = " << outName << endl << endl; + cout << "Output text file name = " << outparsName << endl << endl; // ************************ // load the results and display the configuration info @@ -127,11 +130,16 @@ int main( int argc, char* argv[] ){ // ************************* // Define Amplitude and Sum names // ***************************** - /* - vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; - vector reflname = {"Uniform","PosRefl", "NegRefl"}; - + vector reflname = {"Uniform","PosRefl", "NegRefl"}; + vector amphistname = {"Flat"}; + vector rhoIsobar_comps = {"rhoIso_0-P", "rhoIso_1+S-", "rhoIso_1+S0", "rhoIso_1+S+", "rhoIso_1+D-", "rhoIso_1+D0", "rhoIso_1+D+", "rhoIso_2+D--", "rhoIso_2+D-", "rhoIso_2+D0", "rhoIso_2+D+", "rhoIso_2+D++"}; + vector f2Isobar_comps = {"f2Iso_1+P-","f2Iso_1+P0","f2Iso_1+P+","f2Iso_2+P--","f2Iso_2+P-","f2Iso_2+P0","f2Iso_2+P+","f2Iso_2+P++","f2Iso_2-S--","f2Iso_2-S-","f2Iso_2-S0","f2Iso_2-S+","f2Iso_2-S++"}; + + amphistname.insert(amphistname.end(), rhoIsobar_comps.begin(), rhoIsobar_comps.end()); + amphistname.insert(amphistname.end(), f2Isobar_comps.begin(), f2Isobar_comps.end()); + + // ************************ // set up an output ROOT file to store histograms // ************************ @@ -255,7 +263,7 @@ int main( int argc, char* argv[] ){ if (iplot == PlotGenerator::kData) histname += "_data"; if (iplot == PlotGenerator::kBkgnd) histname += "_bkgnd"; - if (iplot == PlotGenerator::kAccMC) histname += "_acc"; + if (iplot == PlotGenerator::kAccMC) histname += "_fit"; if (iplot == PlotGenerator::kGenMC) histname += "_gen"; if (irefl < reflname.size()){ @@ -302,7 +310,7 @@ int main( int argc, char* argv[] ){ // file for writing parameters (later switch to putting in ROOT file) ofstream outfile; - outfile.open( "vecps3pi__fitpars.txt" ); + outfile.open( outparsName ); for(unsigned int i = 0; i > covMatrix; covMatrix = results.errorMatrix(); - */ + // ************************ From 2eb7922f465c742c938a2be7b1a2ffdc49247190 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Wed, 8 Apr 2026 11:42:34 -0400 Subject: [PATCH 15/33] Optiminzation of the isops_plotter --- .../AmplitudeAnalysis/fitMPI/fitMPI.cc | 4 ++-- .../isops_plotter/isops_plotter.cc | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc index 4f199d00d..022fec5b5 100644 --- a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc +++ b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc @@ -69,7 +69,7 @@ using std::complex; using namespace std; int rank_mpi; -int size; +int mpi_size; double runSingleFit(ConfigurationInfo* cfgInfo, bool useMinos, bool hesse, int maxIter, string seedfile) { AmpToolsInterfaceMPI ati( cfgInfo ); @@ -316,7 +316,7 @@ int main( int argc, char* argv[] ){ MPI_Init( &argc, &argv ); MPI_Comm_rank( MPI_COMM_WORLD, &rank_mpi ); - MPI_Comm_size( MPI_COMM_WORLD, &size ); + MPI_Comm_size( MPI_COMM_WORLD, &mpi_size ); // set default parameters diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index 63505623f..2b37d4d22 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -101,7 +101,7 @@ int main( int argc, char* argv[] ){ // ************************ cout << "Fit results file name = " << resultsName << endl; - cout << "Output root file name = " << outName << endl << endl; + cout << "Output root file name = " << outName << endl; cout << "Output text file name = " << outparsName << endl << endl; // ************************ @@ -134,7 +134,7 @@ int main( int argc, char* argv[] ){ vector reflname = {"Uniform","PosRefl", "NegRefl"}; vector amphistname = {"Flat"}; vector rhoIsobar_comps = {"rhoIso_0-P", "rhoIso_1+S-", "rhoIso_1+S0", "rhoIso_1+S+", "rhoIso_1+D-", "rhoIso_1+D0", "rhoIso_1+D+", "rhoIso_2+D--", "rhoIso_2+D-", "rhoIso_2+D0", "rhoIso_2+D+", "rhoIso_2+D++"}; - vector f2Isobar_comps = {"f2Iso_1+P-","f2Iso_1+P0","f2Iso_1+P+","f2Iso_2+P--","f2Iso_2+P-","f2Iso_2+P0","f2Iso_2+P+","f2Iso_2+P++","f2Iso_2-S--","f2Iso_2-S-","f2Iso_2-S0","f2Iso_2-S+","f2Iso_2-S++"}; + vector f2Isobar_comps = {"f2Iso_1+P-","f2Iso_1+P0","f2Iso_1+P+","f2Iso_2+P--","f2Iso_2+P-","f2Iso_2+P0","f2Iso_2+P+","f2Iso_2+P++","f2Iso_2-S--","f2Iso_2-S-","f2Iso_2-S0","f2Iso_2-S+","f2Iso_2-S++","f2Iso_2-D--","f2Iso_2-D-","f2Iso_2-D0","f2Iso_2-D+","f2Iso_2-D++"}; amphistname.insert(amphistname.end(), rhoIsobar_comps.begin(), rhoIsobar_comps.end()); amphistname.insert(amphistname.end(), f2Isobar_comps.begin(), f2Isobar_comps.end()); @@ -301,13 +301,12 @@ int main( int argc, char* argv[] ){ // The next calculations only need to happen one time // model parameters - cout << "Checking Parameters" << endl; + // cout << "Checking Parameters" << endl; // parameters to check - vector< string > pars; - + vector< string > pars; // pars.push_back("dsratio"); - + // file for writing parameters (later switch to putting in ROOT file) ofstream outfile; outfile.open( outparsName ); @@ -356,10 +355,14 @@ int main( int argc, char* argv[] ){ // second loop over amplitudes to get phase difference names for(unsigned int j = i+1; j < fullamps.size(); j++){ - // only keep amplitudes from the same coherent sum (and ignore constrained Real) - if(fullamps[i].find("Real") != std::string::npos) continue; - if(fullamps[i].find("ImagNegSign") != std::string::npos && fullamps[j].find("ImagNegSign") == std::string::npos) continue; - if(fullamps[i].find("ImagPosSign") != std::string::npos && fullamps[j].find("ImagPosSign") == std::string::npos) continue; + // leave only the Spring2017_PARA_00::ImagPosSign and Spring2017_PARA_00::ImagNegSign coherent sums + if (fullamps[i].find("Spring2017_PARA_00") == std::string::npos || fullamps[j].find("Spring2017_PARA_00") == std::string::npos) continue; + if (fullamps[i].find("UniBG") != std::string::npos || fullamps[j].find("UniBG") != std::string::npos) continue; + if (fullamps[i].find("Real") != std::string::npos || fullamps[j].find("Real") != std::string::npos) continue; + + // only pair amplitudes in the same coherent sums + if (fullamps[i].find("ImagNegSign") != std::string::npos && fullamps[j].find("ImagNegSign") == std::string::npos) continue; + if (fullamps[i].find("ImagPosSign") != std::string::npos && fullamps[j].find("ImagPosSign") == std::string::npos) continue; phaseDiffNames.push_back( std::make_pair(fullamps[i], fullamps[j]) ); From 0a536555ad399fcddda3f07cd854b30289d78141 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Mon, 13 Apr 2026 05:50:15 -0400 Subject: [PATCH 16/33] Implementation of the PiPiSwave amplitude --- src/libraries/AMPTOOLS_AMPS/BreitWigner.cc | 2 - src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc | 2 +- src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc | 171 ++++++++++++++++++ src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h | 74 ++++++++ .../AMPTOOLS_AMPS/breakupMomentumComplex.cc | 20 ++ .../AMPTOOLS_AMPS/breakupMomentumComplex.h | 17 ++ .../isops_plotter/isops_plotter.cc | 70 +++++-- 7 files changed, 333 insertions(+), 23 deletions(-) create mode 100644 src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc create mode 100644 src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h create mode 100644 src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.cc create mode 100644 src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.h diff --git a/src/libraries/AMPTOOLS_AMPS/BreitWigner.cc b/src/libraries/AMPTOOLS_AMPS/BreitWigner.cc index 3dfc84ef1..aeb0ea75f 100644 --- a/src/libraries/AMPTOOLS_AMPS/BreitWigner.cc +++ b/src/libraries/AMPTOOLS_AMPS/BreitWigner.cc @@ -1,5 +1,3 @@ - - #include #include #include diff --git a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc index 0e3aed70b..c435cda8d 100644 --- a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc @@ -61,7 +61,7 @@ UserAmplitude< Iso_ps_refl >( args ){ m_s = static_cast(parseValidatedNumber("S",args[0])); // Resonance spin J m_j = static_cast(parseValidatedNumber("J", args[1])); - // Spin projection (Lambda) + // Resonance spin projection m_m = static_cast(parseValidatedNumber("M", args[2])); // Partial wave L m_l = static_cast(parseValidatedNumber("L", args[3])); diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc new file mode 100644 index 000000000..cff0cad2d --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include + +#include "TLorentzVector.h" +#include "IUAmpTools/Kinematics.h" +#include "breakupMomentumComplex.h" +#include "AMPTOOLS_AMPS/PiPiSWaveAMP.h" + + +// S-wave dipion mass parametrization amplitude based on: +// K.L. Au, D. Morgan and M.R. Pennington," Meson dynamics beyond the quark model: Study of final-state interactions", +// PRD 35 1987 +// +// and are the couplings of a resonance with mass decaying to and . +// Masses of the daughter particles for both relevant channels must be supplied (, ...) and finally the +// channel to be used for calculation is defined by , which can take values 1 or 2. +// +// Usage: +// amplitude :::: PiPiSWaveAMP + +using namespace std; + +PiPiSWaveAMP::PiPiSWaveAMP( const vector &args ) : UserAmplitude(args) +{ + + assert( args.size() == 2 ); + m_daughters = pair (args[0],args[1]); + + // need to register a free parameters so the framework knows about it + // registerParameter(m_mass); + +} + + +void PiPiSWaveAMP::setParametrizationAMP() +{ + _sP.resize(2); + _a11.resize(2); + _a22.resize(2); + _c11.resize(5); + _c22.resize(5); + + + //pole #0 + _sP[0] = -0.0074; // AMP Table 1, M solution: s_0 + _a11[0] = 0.1131; // AMP Table 1, M solution: f_2^2 + _a22[0] = -0.3216; // AMP Table 1, M solution: f_2^3 + + + //pole #1 + _sP[1] = 0.9828; // AMP Table 1, M solution: s_1 + _a11[1] = 0.1968*0.1968; // AMP Table 1, M solution: f_1^1 + _a22[1] = -0.0154*-0.0154; // AMP Table 1, M solution: f_2^1 + + + //polynom: #0th order + _c11[0] = 0.0337; // AMP Table 1, M solution: c_11^0 + _c22[0] = 0.3010; // AMP Table 1, M solution: c_22^0 + + //polynom: #1st order + _c11[1] = -0.3185; // AMP Table 1, M solution: c_11^1 + _c22[1] = -0.5140; // AMP Table 1, M solution: c_22^1 + + //polynom: #2nd order + _c11[2] = -0.0942; // AMP Table 1, M solution: c_11^2 + _c22[2] = 0.1176; // AMP Table 1, M solution: c_22^2 + + //polynom: #3rd order + _c11[3] = -0.5927; // AMP Table 1, M solution: c_11^3 + _c22[3] = 0.5204; // AMP Table 1, M solution: c_22^3 + + //polynom: #4th order + _c11[4] = 0.1957; // AMP Table 1, M solution: c_11^4 + _c22[4] = -0.3977; // AMP Table 1, M solution: c_22^4 + + +} + + + +/////////////////////// Amplitude Calculation ////////////////////////// + +complex PiPiSWaveAMP::calcAmplitude( GDouble** pKin ) const +{ + TLorentzVector pion1_P4, pion2_P4, dipion_P4, temp_P4; + + for( unsigned int ii = 0; ii < m_daughters.first.size(); ++ii ){ + + char num[2]= {m_daughters.first[ii], '\0'}; + int index = atoi(num); + + temp_P4.SetPxPyPzE(pKin[index][1], pKin[index][2], pKin[index][3], pKin[index][0]); + pion1_P4 += temp_P4; + dipion_P4 += temp_P4; + } + + for( unsigned int ii = 0; ii < m_daughters.second.size(); ++ii ){ + + char num[2]= {m_daughters.second[ii], '\0'}; + int index = atoi(num); + + temp_P4.SetPxPyPzE(pKin[index][1], pKin[index][2], pKin[index][3], pKin[index][0]); + pion2_P4 += temp_P4; + dipion_P4 += temp_P4; + } + + + GDouble mass = dipion_P4.M(); + GDouble s = dipion_P4.M2(); + + + if (fabs(s - _sP.back()) < 1.e-6){ + mass += 1.e-6; + s = mass*mass; + } + + + const complex qPiPi = breakupMomentumComplex(mass, _piChargedMass, _piChargedMass ); + const complex qPi0Pi0 = breakupMomentumComplex(mass, _piNeutralMass, _piNeutralMass ); + const complex qKK = breakupMomentumComplex(mass, _kaonChargedMass, _kaonChargedMass); + const complex qK0K0 = breakupMomentumComplex(mass, _kaonNeutralMass, _kaonNeutralMass); + const GDouble scale = (s / (4*_kaonMeanMass*_kaonMeanMass)) - 1; + + + complex rho11 = (qPiPi + qPi0Pi0) / mass; + complex rho22 = (qKK + qK0K0) / mass; + + complex imag(0.,1.); + complex M11(0.,0.),M22(0.,0.),T11(0.,0.); + + //Sum over the poles + for (unsigned int ii = 0; ii < _sP.size(); ++ii){ + M11 += _a11[ii]/(s - _sP[ii]); + M22 += _a22[ii]/(s - _sP[ii]); + } + + //Sum over the polynomial terms + for (unsigned int ii = 0; ii < _c11.size(); ++ii) { + M11 += _c11[ii]*pow(scale, (int)ii); + M22 += _c22[ii]*pow(scale, (int)ii); + } + + //Now calculate the T_{11} matrix element using only diagonal terms + M11 -= imag*rho11; + M22 -= imag*rho22; + + complex amp = 1./M11; + + return amp; +} + + + + +//This function may be used instead of the separate amplitude ' breakupMomentumComplex' +template complex PiPiSWaveAMP::breakupMom(mType m, GDouble mDec1, GDouble mDec2) const{ + complex result = PiPiSWaveAMP::phaseSpaceFac(m, mDec1, mDec2)*m/GDouble(2.); + return result; +} + + +#ifdef GPU_ACCELERATION +void PiPiSWaveAMP::launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const { + + PiPiSWaveAMP_exec( dimGrid, dimBlock, GPU_AMP_ARGS, m_mass, m_g1, m_g2, m_daughter1, m_daughter2); + +} +#endif //GPU_ACCELERATION diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h new file mode 100644 index 000000000..2c7c07fdf --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h @@ -0,0 +1,74 @@ +#if !defined(PIPISWAVEAMP) +#define PIPISWAVEAMP + +#include "particleType.h" +#include "IUAmpTools/UserAmplitude.h" +#include "IUAmpTools/AmpParameter.h" +#include "IUAmpTools/Amplitude.h" +#include "GPUManager/GPUCustomTypes.h" + + +#include +#include +#include +#include +#include + + +#ifdef GPU_ACCELERATION +void PiPiSWaveAMP_exec(dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO, GDouble m_mass, GDouble m_g1, GDouble m_g2, int m_daughter1, int m_daughter2 ); +#endif // GPU_ACCELERATION + + + +using std::complex; +using namespace std; + +class Kinematics; + +class PiPiSWaveAMP : public UserAmplitude{ + + public: + + PiPiSWaveAMP() : UserAmplitude () { } + PiPiSWaveAMP( const vector &args ); + ~PiPiSWaveAMP(){} + + string name() const { return "PiPiSWaveAMP"; } + void setParametrizationAMP(); + complex calcAmplitude( GDouble** pKin ) const; + +#ifdef GPU_ACCELERATION + + void launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const; + bool isGPUEnabled() const { return false; } + +#endif // GPU_ACCELERATION + + private: + + pair< string, string > m_daughters; + + int _vesSheet; + std::vector _sP; + std::vector _a11; + std::vector _a22; + std::vector _c11; + std::vector _c22; + + + const GDouble _piChargedMass = ParticleMass(PiPlus); //0.13957039; + const GDouble _piNeutralMass = ParticleMass(Pi0); //0.13497680; + const GDouble _kaonChargedMass = ParticleMass(KPlus); //0.49367700; + const GDouble _kaonNeutralMass = 0.5*(ParticleMass(KLong) + ParticleMass(KShort)); //0.49761400; + const GDouble _kaonMeanMass = 0.5*(_kaonChargedMass + _kaonNeutralMass); //0.5*(0.49367700 + 0.49761400); + + + + complex phaseSpaceFac( GDouble m, GDouble mDec1, GDouble mDec2 ) const; + template + complex breakupMom( mType m, GDouble mDec1, GDouble mDec2 ) const; + +}; + +#endif diff --git a/src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.cc b/src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.cc new file mode 100644 index 000000000..afe441013 --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.cc @@ -0,0 +1,20 @@ +#include +#include +#include "breakupMomentumComplex.h" + +// mass0 = mass of parent +// mass1 = mass of first daughter +// mass2 = mass of second daughter + +complex breakupMomentumComplex( GDouble mass0, GDouble mass1, GDouble mass2 ){ + + complex q = std::sqrt( mass0*mass0*mass0*mass0 + + mass1*mass1*mass1*mass1 + + mass2*mass2*mass2*mass2 - + 2.0*mass0*mass0*mass1*mass1 - + 2.0*mass0*mass0*mass2*mass2 - + 2.0*mass1*mass1*mass2*mass2 ) / (2.0 * mass0); + + return q; + +} diff --git a/src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.h b/src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.h new file mode 100644 index 000000000..c80bcb451 --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/breakupMomentumComplex.h @@ -0,0 +1,17 @@ +#include "IUAmpTools/Amplitude.h" +#include "IUAmpTools/AmpParameter.h" +#include "IUAmpTools/UserAmplitude.h" +#include "GPUManager/GPUCustomTypes.h" + + + +#if !defined(BREAKUPMOMENTUMCOMPLEX) +#define BREAKUPMOMENTUMCOMPLEX + +// mass0 = mass of parent +// mass1 = mass of first daughter +// mass2 = mass of second daughter + +complex breakupMomentumComplex( GDouble mass0, GDouble mass1, GDouble mass2 ); + +#endif diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index 2b37d4d22..7b1dc8978 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "TClass.h" #include "TApplication.h" @@ -146,14 +147,16 @@ int main( int argc, char* argv[] ){ TFile* plotfile = new TFile( outName.c_str(), "recreate"); TH1::AddDirectory(kFALSE); + TDirectory* plotfiledir = plotfile->mkdir("Contributions"); // ************************* // Loop over different polarization types // ************************* size_t nReactions = results.reactionList().size(); + std::map summedHists; - + for (unsigned int polType = 0; polType < nReactions; polType++) { @@ -164,8 +167,8 @@ int main( int argc, char* argv[] ){ //TFile* plotfile = new TFile( outName.c_str(), "recreate"); //TH1::AddDirectory(kFALSE); - string dirname = "Contributions_"+reactionName; - TDirectory* plotfiledir = plotfile->mkdir(dirname.c_str()); + // string dirname = "Contributions_"+reactionName; + // TDirectory* plotfiledir = plotfile->mkdir(dirname.c_str()); plotGen.enableReaction( reactionName ); @@ -245,20 +248,23 @@ int main( int argc, char* argv[] ){ // loop over different variables for (unsigned int ivar = 0; ivar < IsoPsPlotGenerator::kNumHists; ivar++){ - // set unique histogram name for each plot (could put in directories...) - string histname = reactionName; - - if (ivar == IsoPsPlotGenerator::kProd_Ang) histname += "_Prod_Ang"; - else if (ivar == IsoPsPlotGenerator::kCosTheta) histname += "_CosTheta_GJ"; - else if (ivar == IsoPsPlotGenerator::kPhi) histname += "_Phi_GJ"; - else if (ivar == IsoPsPlotGenerator::kCosThetaH) histname += "_CosTheta_HF"; - else if (ivar == IsoPsPlotGenerator::kPhiH) histname += "_Phi_HF"; - else if (ivar == IsoPsPlotGenerator::kIsoMass) histname += "_MIso"; - else if (ivar == IsoPsPlotGenerator::kIsoPsMass) histname += "_MIsoPs"; - else if (ivar == IsoPsPlotGenerator::kt) histname += "_minust"; - else if (ivar == IsoPsPlotGenerator::kRecoilMass) histname += "_ProtonPiplusL_M"; - else if (ivar == IsoPsPlotGenerator::kProtonPsMass) histname += "_ProtonPiminus_M"; - else if (ivar == IsoPsPlotGenerator::kRecoilPsMass) histname += "_ProtonPiplusLPiminus_M"; + // set reaction name as a prefix to the histogram name if all reactions are saved separately + // set a common name or no name as a prefix to the histogram name if all reactions are summed up + //string histname = reactionName; + string histname = ""; + + + if (ivar == IsoPsPlotGenerator::kProd_Ang) histname += "Prod_Ang"; + else if (ivar == IsoPsPlotGenerator::kCosTheta) histname += "CosTheta_GJ"; + else if (ivar == IsoPsPlotGenerator::kPhi) histname += "Phi_GJ"; + else if (ivar == IsoPsPlotGenerator::kCosThetaH) histname += "CosTheta_HF"; + else if (ivar == IsoPsPlotGenerator::kPhiH) histname += "Phi_HF"; + else if (ivar == IsoPsPlotGenerator::kIsoMass) histname += "MIso"; + else if (ivar == IsoPsPlotGenerator::kIsoPsMass) histname += "MIsoPs"; + else if (ivar == IsoPsPlotGenerator::kt) histname += "minust"; + else if (ivar == IsoPsPlotGenerator::kRecoilMass) histname += "ProtonPiplusL_M"; + else if (ivar == IsoPsPlotGenerator::kProtonPsMass) histname += "ProtonPiminus_M"; + else if (ivar == IsoPsPlotGenerator::kRecoilPsMass) histname += "ProtonPiplusLPiminus_M"; else continue; if (iplot == PlotGenerator::kData) histname += "_data"; @@ -282,16 +288,40 @@ int main( int argc, char* argv[] ){ Histogram* hist = plotGen.projection(ivar, reactionName, iplot); TH1* thist = hist->toRoot(); thist->SetName(histname.c_str()); - if (iamp > 0 && iamp < amphistname.size()) plotfiledir->cd(); - else plotfile->cd(); - thist->Write(); + + // sum histograms across reactions + if (summedHists.find(histname) == summedHists.end()) + summedHists[histname] = (TH1*) thist->Clone(); + else + summedHists[histname]->Add(thist); + + //write separate histogram for each reaction + //if (iamp > 0 && iamp < amphistname.size()) plotfiledir->cd(); + //else plotfile->cd(); + //thist->Write(); + delete thist; } } } // end of loop over amplitudes } // end of loop over sum configurations }// end of loop over 'reactions' + + + //Now, write summed up histograms to the root file + for (auto it = summedHists.begin(); it != summedHists.end(); it++) { + + std::string hsummed_name = it->first; + TH1* hsummed = it->second; + hsummed->SetName(hsummed_name.c_str()); + + if (hsummed_name.find("+") != std::string::npos || hsummed_name.find("-") != std::string::npos) plotfiledir->cd(); + else plotfile->cd(); + hsummed->Write(); + } + + plotfile->Close(); From c6064580677c14356c79623c4f4239e64eb521e2 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Mon, 13 Apr 2026 10:15:11 -0400 Subject: [PATCH 17/33] Kachaev's prescription for the PiPiSwave --- src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc | 61 ++++++++++----------- src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h | 6 +- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc index cff0cad2d..4a1e43ac9 100644 --- a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc @@ -13,11 +13,7 @@ // S-wave dipion mass parametrization amplitude based on: // K.L. Au, D. Morgan and M.R. Pennington," Meson dynamics beyond the quark model: Study of final-state interactions", // PRD 35 1987 -// -// and are the couplings of a resonance with mass decaying to and . -// Masses of the daughter particles for both relevant channels must be supplied (, ...) and finally the -// channel to be used for calculation is defined by , which can take values 1 or 2. -// +// with the modification by I. Kachaev from [arxiv:2305.11711] // Usage: // amplitude :::: PiPiSWaveAMP @@ -35,12 +31,17 @@ PiPiSWaveAMP::PiPiSWaveAMP( const vector &args ) : UserAmplitude PiPiSWaveAMP::calcAmplitude( GDouble** pKin ) const } - const complex qPiPi = breakupMomentumComplex(mass, _piChargedMass, _piChargedMass ); - const complex qPi0Pi0 = breakupMomentumComplex(mass, _piNeutralMass, _piNeutralMass ); - const complex qKK = breakupMomentumComplex(mass, _kaonChargedMass, _kaonChargedMass); - const complex qK0K0 = breakupMomentumComplex(mass, _kaonNeutralMass, _kaonNeutralMass); + const complex qPiPi = breakupMomentumComplex(mass, _piChargedMass, _piChargedMass ); + const complex qPi0Pi0 = breakupMomentumComplex(mass, _piNeutralMass, _piNeutralMass ); const GDouble scale = (s / (4*_kaonMeanMass*_kaonMeanMass)) - 1; complex rho11 = (qPiPi + qPi0Pi0) / mass; - complex rho22 = (qKK + qK0K0) / mass; complex imag(0.,1.); - complex M11(0.,0.),M22(0.,0.),T11(0.,0.); + complex M11(0.,0.),T11(0.,0.); //Sum over the poles - for (unsigned int ii = 0; ii < _sP.size(); ++ii){ + for (unsigned int ii = 0; ii < _sP.size(); ++ii) M11 += _a11[ii]/(s - _sP[ii]); - M22 += _a22[ii]/(s - _sP[ii]); - } //Sum over the polynomial terms - for (unsigned int ii = 0; ii < _c11.size(); ++ii) { + for (unsigned int ii = 0; ii < _c11.size(); ++ii) M11 += _c11[ii]*pow(scale, (int)ii); - M22 += _c22[ii]*pow(scale, (int)ii); - } //Now calculate the T_{11} matrix element using only diagonal terms - M11 -= imag*rho11; - M22 -= imag*rho22; + T11 = M11 - imag*rho11; - complex amp = 1./M11; + complex amp = 1./T11; return amp; } diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h index 2c7c07fdf..6deb6b8e0 100644 --- a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h @@ -35,7 +35,7 @@ class PiPiSWaveAMP : public UserAmplitude{ ~PiPiSWaveAMP(){} string name() const { return "PiPiSWaveAMP"; } - void setParametrizationAMP(); + void setParametrizationAMPK(); complex calcAmplitude( GDouble** pKin ) const; #ifdef GPU_ACCELERATION @@ -52,8 +52,12 @@ class PiPiSWaveAMP : public UserAmplitude{ int _vesSheet; std::vector _sP; std::vector _a11; + std::vector _a12; + std::vector _a21; std::vector _a22; std::vector _c11; + std::vector _c12; + std::vector _c21; std::vector _c22; From d85f5a93b716d108ae03ba414dc6ec3c646d3c15 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Thu, 16 Apr 2026 10:17:53 -0400 Subject: [PATCH 18/33] PiPiSwave: Now, Au Morgan Pennington Kachaev parametrization only --- src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc | 3 +- src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc | 170 ------------------ src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc | 132 ++++++++++++++ .../{PiPiSWaveAMP.h => PiPiSWaveAMPK.h} | 31 ++-- src/programs/AmplitudeAnalysis/fit/fit.cc | 4 +- .../AmplitudeAnalysis/fitMPI/fitMPI.cc | 4 +- .../isops_plotter/isops_plotter.cc | 6 + 7 files changed, 157 insertions(+), 193 deletions(-) delete mode 100644 src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc create mode 100644 src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc rename src/libraries/AMPTOOLS_AMPS/{PiPiSWaveAMP.h => PiPiSWaveAMPK.h} (60%) diff --git a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc index c435cda8d..14a4cb1a8 100644 --- a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc @@ -111,8 +111,7 @@ UserAmplitude< Iso_ps_refl >( args ){ } } -void -Iso_ps_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ +void Iso_ps_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ TLorentzVector beam; TVector3 eps; diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc deleted file mode 100644 index 4a1e43ac9..000000000 --- a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.cc +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include -#include -#include - -#include "TLorentzVector.h" -#include "IUAmpTools/Kinematics.h" -#include "breakupMomentumComplex.h" -#include "AMPTOOLS_AMPS/PiPiSWaveAMP.h" - - -// S-wave dipion mass parametrization amplitude based on: -// K.L. Au, D. Morgan and M.R. Pennington," Meson dynamics beyond the quark model: Study of final-state interactions", -// PRD 35 1987 -// with the modification by I. Kachaev from [arxiv:2305.11711] -// Usage: -// amplitude :::: PiPiSWaveAMP - -using namespace std; - -PiPiSWaveAMP::PiPiSWaveAMP( const vector &args ) : UserAmplitude(args) -{ - - assert( args.size() == 2 ); - m_daughters = pair (args[0],args[1]); - - // need to register a free parameters so the framework knows about it - // registerParameter(m_mass); - -} - - -void PiPiSWaveAMP::setParametrizationAMPK() -{ - _sP.resize(2); - _a11.resize(2); - _a12.resize(2); - _a21.resize(2); - _a22.resize(2); - - _c11.resize(5); - _c12.resize(5); - _c21.resize(5); - _c22.resize(5); - - - //pole #0 - _sP[0] = -0.0074; // AMP Table 1, M solution: s_0 - _a11[0] = 0.1131; // AMP Table 1, M solution: f_2^2 - _a22[0] = -0.3216; // AMP Table 1, M solution: f_2^3 - - - //pole #1 (eliminated) - _sP[1] = 0.9828; // AMP Table 1, M solution: s_1 - _a11[1] = 0.; // -0.1968*0.1968 for the sign-corrected value from AMP Table 1, M solution: f_1^1 - _a22[1] = 0.; // -0.0154*0.0154 for the sign-corrected value from AMP Table 1, M solution: f_2^1 - - - //polynom: #0th order - _c11[0] = 0.0337; // AMP Table 1, M solution: c_11^0 - _c22[0] = 0.3010; // AMP Table 1, M solution: c_22^0 - - //polynom: #1st order - _c11[1] = -0.3185; // AMP Table 1, M solution: c_11^1 - _c22[1] = -0.5140; // AMP Table 1, M solution: c_22^1 - - //polynom: #2nd order - _c11[2] = -0.0942; // AMP Table 1, M solution: c_11^2 - _c22[2] = 0.1176; // AMP Table 1, M solution: c_22^2 - - //polynom: #3rd order - _c11[3] = -0.5927; // AMP Table 1, M solution: c_11^3 - _c22[3] = 0.5204; // AMP Table 1, M solution: c_22^3 - - //polynom: #4th order (eliminated) - _c11[4] = 0.; // 0.1957 from AMP Table 1, M solution: c_11^4 - _c22[4] = 0.; // -0.3977 from AMP Table 1, M solution: c_22^4 - - - //All off-diagonal elements go to zero - _a12 = {0.,0.,0.,0.,0.}; - _a21 = {0.,0.,0.,0.,0.}; - _c12 = {0.,0.,0.,0.,0.}; - _c21 = {0.,0.,0.,0.,0.}; - -} - - - -/////////////////////// Amplitude Calculation ////////////////////////// - -complex PiPiSWaveAMP::calcAmplitude( GDouble** pKin ) const -{ - TLorentzVector pion1_P4, pion2_P4, dipion_P4, temp_P4; - - for( unsigned int ii = 0; ii < m_daughters.first.size(); ++ii ){ - - char num[2]= {m_daughters.first[ii], '\0'}; - int index = atoi(num); - - temp_P4.SetPxPyPzE(pKin[index][1], pKin[index][2], pKin[index][3], pKin[index][0]); - pion1_P4 += temp_P4; - dipion_P4 += temp_P4; - } - - for( unsigned int ii = 0; ii < m_daughters.second.size(); ++ii ){ - - char num[2]= {m_daughters.second[ii], '\0'}; - int index = atoi(num); - - temp_P4.SetPxPyPzE(pKin[index][1], pKin[index][2], pKin[index][3], pKin[index][0]); - pion2_P4 += temp_P4; - dipion_P4 += temp_P4; - } - - - GDouble mass = dipion_P4.M(); - GDouble s = dipion_P4.M2(); - - - if (fabs(s - _sP.back()) < 1.e-6){ - mass += 1.e-6; - s = mass*mass; - } - - - const complex qPiPi = breakupMomentumComplex(mass, _piChargedMass, _piChargedMass ); - const complex qPi0Pi0 = breakupMomentumComplex(mass, _piNeutralMass, _piNeutralMass ); - const GDouble scale = (s / (4*_kaonMeanMass*_kaonMeanMass)) - 1; - - - complex rho11 = (qPiPi + qPi0Pi0) / mass; - - complex imag(0.,1.); - complex M11(0.,0.),T11(0.,0.); - - //Sum over the poles - for (unsigned int ii = 0; ii < _sP.size(); ++ii) - M11 += _a11[ii]/(s - _sP[ii]); - - //Sum over the polynomial terms - for (unsigned int ii = 0; ii < _c11.size(); ++ii) - M11 += _c11[ii]*pow(scale, (int)ii); - - //Now calculate the T_{11} matrix element using only diagonal terms - T11 = M11 - imag*rho11; - - complex amp = 1./T11; - - return amp; -} - - - - -//This function may be used instead of the separate amplitude ' breakupMomentumComplex' -template complex PiPiSWaveAMP::breakupMom(mType m, GDouble mDec1, GDouble mDec2) const{ - complex result = PiPiSWaveAMP::phaseSpaceFac(m, mDec1, mDec2)*m/GDouble(2.); - return result; -} - - -#ifdef GPU_ACCELERATION -void PiPiSWaveAMP::launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const { - - PiPiSWaveAMP_exec( dimGrid, dimBlock, GPU_AMP_ARGS, m_mass, m_g1, m_g2, m_daughter1, m_daughter2); - -} -#endif //GPU_ACCELERATION diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc new file mode 100644 index 000000000..d63dba13e --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include + +#include "TLorentzVector.h" +#include "IUAmpTools/Kinematics.h" +#include "breakupMomentumComplex.h" +#include "AMPTOOLS_AMPS/PiPiSWaveAMPK.h" + + +// S-wave dipion mass parametrization amplitude based on: +// K.L. Au, D. Morgan and M.R. Pennington," Meson dynamics beyond the quark model: Study of final-state interactions", +// PRD 35 1987 +// with the modification by I. Kachaev from [arxiv:2305.11711] +// Usage: +// amplitude :::: PiPiSWaveAMPK + +using namespace std; + +PiPiSWaveAMPK::PiPiSWaveAMPK( const vector &args ) : UserAmplitude(args) +{ + + assert( args.size() == 2 ); + m_daughters = pair (args[0],args[1]); + + setParametrization(); + + // need to register a free parameters so the framework knows about it + // registerParameter(m_mass); + +} + + +void PiPiSWaveAMPK::setParametrization() +{ + + //Adler pole and residue in it + s0 = -0.0074; // AMP Table 1, M solution: s_0 + a11 = 0.1131; // AMP Table 1, M solution: f_2^2 + + //polynom up to the 3rd order + c11.resize(4); + + c11[0] = 0.0337; // AMP Table 1, M solution: c_11^0 + c11[1] = -0.3185; // AMP Table 1, M solution: c_11^1 + c11[2] = -0.0942; // AMP Table 1, M solution: c_11^2 + c11[3] = -0.5927; // AMP Table 1, M solution: c_11^3 + +} + + + +/////////////////////// Amplitude Calculation ////////////////////////// + +complex PiPiSWaveAMPK::calcAmplitude( GDouble** pKin ) const +{ + TLorentzVector pion1_P4, pion2_P4, dipion_P4, temp_P4; + + for( unsigned int ii = 0; ii < m_daughters.first.size(); ++ii ){ + + char num[2]= {m_daughters.first[ii], '\0'}; + int index = atoi(num); + + temp_P4.SetPxPyPzE(pKin[index][1], pKin[index][2], pKin[index][3], pKin[index][0]); + pion1_P4 += temp_P4; + dipion_P4 += temp_P4; + } + + for( unsigned int ii = 0; ii < m_daughters.second.size(); ++ii ){ + + char num[2]= {m_daughters.second[ii], '\0'}; + int index = atoi(num); + + temp_P4.SetPxPyPzE(pKin[index][1], pKin[index][2], pKin[index][3], pKin[index][0]); + pion2_P4 += temp_P4; + dipion_P4 += temp_P4; + } + + + GDouble mass = dipion_P4.M(); + GDouble s = dipion_P4.M2(); + + + if (fabs(s - s0) < 1.e-6){ + mass += 1.e-6; + s = mass*mass; + } + + + const complex qPiPi = breakupMomentumComplex(mass, _piChargedMass, _piChargedMass ); + const complex qPi0Pi0 = breakupMomentumComplex(mass, _piNeutralMass, _piNeutralMass ); + const GDouble scale = (s / (4*_kaonMeanMass*_kaonMeanMass)) - 1; + + + complex rho11 = (qPiPi + qPi0Pi0) / mass; + + complex imag(0.,1.); + complex M11(0.,0.),T11(0.,0.); + + //Add the Adler pole term + M11 += a11/(s - s0); + + //Add the polynomial terms + for (unsigned int ii = 0; ii < c11.size(); ++ii) + M11 += c11[ii]*pow(scale, (int)ii); + + //Now calculate the T_{11} matrix element using the T11 to M11 relation + T11 = 1./(M11 - imag*rho11); + + + return T11; +} + + + + +//This function may be used instead of the separate amplitude ' breakupMomentumComplex' +template complex PiPiSWaveAMPK::breakupMom(mType m, GDouble mDec1, GDouble mDec2) const{ + complex result = PiPiSWaveAMPK::phaseSpaceFac(m, mDec1, mDec2)*m/GDouble(2.); + return result; +} + + +#ifdef GPU_ACCELERATION +void PiPiSWaveAMPK::launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const { + + PiPiSWaveAMPK_exec( dimGrid, dimBlock, GPU_AMP_ARGS, m_mass, m_g1, m_g2, m_daughter1, m_daughter2); + +} +#endif //GPU_ACCELERATION diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h similarity index 60% rename from src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h rename to src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h index 6deb6b8e0..9f5ce8b29 100644 --- a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMP.h +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h @@ -1,5 +1,5 @@ -#if !defined(PIPISWAVEAMP) -#define PIPISWAVEAMP +#if !defined(PIPISWAVEAMPK) +#define PIPISWAVEAMPK #include "particleType.h" #include "IUAmpTools/UserAmplitude.h" @@ -16,7 +16,7 @@ #ifdef GPU_ACCELERATION -void PiPiSWaveAMP_exec(dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO, GDouble m_mass, GDouble m_g1, GDouble m_g2, int m_daughter1, int m_daughter2 ); +void PiPiSWaveAMPK_exec(dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO, GDouble m_mass, GDouble m_g1, GDouble m_g2, int m_daughter1, int m_daughter2 ); #endif // GPU_ACCELERATION @@ -26,16 +26,16 @@ using namespace std; class Kinematics; -class PiPiSWaveAMP : public UserAmplitude{ +class PiPiSWaveAMPK : public UserAmplitude{ public: - PiPiSWaveAMP() : UserAmplitude () { } - PiPiSWaveAMP( const vector &args ); - ~PiPiSWaveAMP(){} + PiPiSWaveAMPK() : UserAmplitude () { } + PiPiSWaveAMPK( const vector &args ); + ~PiPiSWaveAMPK(){} - string name() const { return "PiPiSWaveAMP"; } - void setParametrizationAMPK(); + string name() const { return "PiPiSWaveAMPK"; } + void setParametrization(); complex calcAmplitude( GDouble** pKin ) const; #ifdef GPU_ACCELERATION @@ -49,16 +49,9 @@ class PiPiSWaveAMP : public UserAmplitude{ pair< string, string > m_daughters; - int _vesSheet; - std::vector _sP; - std::vector _a11; - std::vector _a12; - std::vector _a21; - std::vector _a22; - std::vector _c11; - std::vector _c12; - std::vector _c21; - std::vector _c22; + GDouble s0; + GDouble a11; + std::vector c11; const GDouble _piChargedMass = ParticleMass(PiPlus); //0.13957039; diff --git a/src/programs/AmplitudeAnalysis/fit/fit.cc b/src/programs/AmplitudeAnalysis/fit/fit.cc index 1f9c655ee..7efa0edab 100644 --- a/src/programs/AmplitudeAnalysis/fit/fit.cc +++ b/src/programs/AmplitudeAnalysis/fit/fit.cc @@ -37,6 +37,7 @@ #include "AMPTOOLS_AMPS/Zlm.h" #include "AMPTOOLS_AMPS/BreitWigner.h" #include "AMPTOOLS_AMPS/BreitWigner3body.h" +#include "AMPTOOLS_AMPS/PiPiSWaveAMPK.h" #include "AMPTOOLS_AMPS/b1piAngAmp.h" #include "AMPTOOLS_AMPS/Uniform.h" #include "AMPTOOLS_AMPS/polCoef.h" @@ -450,7 +451,8 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( KopfKMatrixRho() ); AmpToolsInterface::registerAmplitude( KopfKMatrixPi1() ); AmpToolsInterface::registerAmplitude( Vec_ps_moment() ); - + AmpToolsInterface::registerAmplitude( PiPiSWaveAMPK() ); + AmpToolsInterface::registerDataReader( ROOTDataReader() ); AmpToolsInterface::registerDataReader( ROOTDataReaderBootstrap() ); AmpToolsInterface::registerDataReader( ROOTDataReaderWithTCut() ); diff --git a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc index 022fec5b5..87d1bce33 100644 --- a/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc +++ b/src/programs/AmplitudeAnalysis/fitMPI/fitMPI.cc @@ -1,4 +1,3 @@ - #include #include #include @@ -33,6 +32,7 @@ #include "AMPTOOLS_AMPS/VecRadiative_SDME.h" #include "AMPTOOLS_AMPS/Zlm.h" #include "AMPTOOLS_AMPS/BreitWigner.h" +#include "AMPTOOLS_AMPS/PiPiSWaveAMPK.h" #include "AMPTOOLS_AMPS/BreitWigner3body.h" #include "AMPTOOLS_AMPS/b1piAngAmp.h" #include "AMPTOOLS_AMPS/Uniform.h" @@ -423,7 +423,9 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( KopfKMatrixRho() ); AmpToolsInterface::registerAmplitude( KopfKMatrixPi1() ); AmpToolsInterface::registerAmplitude( Vec_ps_moment() ); + AmpToolsInterface::registerAmplitude( PiPiSWaveAMPK() ); + AmpToolsInterface::registerDataReader( DataReaderMPI() ); AmpToolsInterface::registerDataReader( DataReaderMPI() ); AmpToolsInterface::registerDataReader( DataReaderMPI() ); diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index 7b1dc8978..0c9d803fc 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -28,6 +28,7 @@ #include "AMPTOOLS_DATAIO/FSRootDataReader.h" #include "AMPTOOLS_AMPS/BreitWigner.h" #include "AMPTOOLS_AMPS/Uniform.h" +#include "AMPTOOLS_AMPS/PiPiSWaveAMPK.h" #include "AMPTOOLS_AMPS/Iso_ps_refl.h" #include "AMPTOOLS_AMPS/PhaseOffset.h" #include "AMPTOOLS_AMPS/ComplexCoeff.h" @@ -35,6 +36,7 @@ #include "AMPTOOLS_AMPS/OmegaDalitz.h" + #include "MinuitInterface/MinuitMinimizationManager.h" #include "IUAmpTools/ConfigFileParser.h" #include "IUAmpTools/ConfigurationInfo.h" @@ -50,7 +52,9 @@ void atiSetup(){ AmpToolsInterface::registerAmplitude( ComplexCoeff() ); AmpToolsInterface::registerAmplitude( Piecewise() ); AmpToolsInterface::registerAmplitude( OmegaDalitz() ); + AmpToolsInterface::registerAmplitude( PiPiSWaveAMPK() ); + AmpToolsInterface::registerDataReader( ROOTDataReader() ); AmpToolsInterface::registerDataReader( FSRootDataReader() ); AmpToolsInterface::registerDataReader( ROOTDataReaderTEM() ); @@ -134,9 +138,11 @@ int main( int argc, char* argv[] ){ vector reflname = {"Uniform","PosRefl", "NegRefl"}; vector amphistname = {"Flat"}; + vector pipiIsobar_comps = {"pipiIso_0-S","pipiIso_1+P-","pipiIso_1+P0","pipiIso_1+P+"}; vector rhoIsobar_comps = {"rhoIso_0-P", "rhoIso_1+S-", "rhoIso_1+S0", "rhoIso_1+S+", "rhoIso_1+D-", "rhoIso_1+D0", "rhoIso_1+D+", "rhoIso_2+D--", "rhoIso_2+D-", "rhoIso_2+D0", "rhoIso_2+D+", "rhoIso_2+D++"}; vector f2Isobar_comps = {"f2Iso_1+P-","f2Iso_1+P0","f2Iso_1+P+","f2Iso_2+P--","f2Iso_2+P-","f2Iso_2+P0","f2Iso_2+P+","f2Iso_2+P++","f2Iso_2-S--","f2Iso_2-S-","f2Iso_2-S0","f2Iso_2-S+","f2Iso_2-S++","f2Iso_2-D--","f2Iso_2-D-","f2Iso_2-D0","f2Iso_2-D+","f2Iso_2-D++"}; + amphistname.insert(amphistname.end(), pipiIsobar_comps.begin(), pipiIsobar_comps.end()); amphistname.insert(amphistname.end(), rhoIsobar_comps.begin(), rhoIsobar_comps.end()); amphistname.insert(amphistname.end(), f2Isobar_comps.begin(), f2Isobar_comps.end()); From 9840e7ca420d691fff1b44d88f7c2f45b3fcee64 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Thu, 30 Apr 2026 11:14:18 -0400 Subject: [PATCH 19/33] Minor change in the plotter and plot generator --- .../AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc | 34 +++++++++---------- .../isops_plotter/isops_plotter.cc | 24 +++++++------ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc index 7bdc91366..956c633fc 100644 --- a/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc +++ b/src/libraries/AMPTOOLS_DATAIO/IsoPsPlotGenerator.cc @@ -70,8 +70,8 @@ void IsoPsPlotGenerator::createHistograms( ) { bookHistogram( kIsoMass, new Histogram1D( 200, 0., 3., "MIso", "m(2#pi) [GeV]") ); bookHistogram( kIsoPsMass, new Histogram1D( 200, 0.2, 3.2, "MIsoPs", "m(3#pi) [GeV]") ); - bookHistogram( kt, new Histogram1D( 100, 0, 1.0 , "t", "-t [GeV^{2}]" ) ); - bookHistogram( kRecoilMass, new Histogram1D( 100, 0.9, 1.9 , "ProtonPiplusL_M", "m(p#pi^{+}_{L}) [GeV]" ) ); + bookHistogram( kt, new Histogram1D( 200, 0, 1.0 , "t", "-t [GeV^{2}]" ) ); + bookHistogram( kRecoilMass, new Histogram1D( 200, 0.9, 1.9 , "ProtonPiplusL_M", "m(p#pi^{+}_{L}) [GeV]" ) ); bookHistogram( kProtonPsMass, new Histogram1D( 200, 0.8, 3.8, "ProtonPiminus_M", "m(p#pi^{-}) [GeV]" ) ); bookHistogram( kRecoilPsMass, new Histogram1D( 200, 1.0, 4.0, "ProtonPiplusLPiminus_M", "m(p#pi^{+}_{L}#pi^{-}) [GeV]" ) ); @@ -101,24 +101,24 @@ IsoPsPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ TLorentzVector beam = kin->particle( 0 ); TLorentzVector proton = kin->particle( 1 ); TLorentzVector bach = kin->particle( 2 ); - TLorentzVector vec_daught1 = kin->particle( 3 ); - TLorentzVector vec_daught2 = kin->particle( 4 ); + TLorentzVector iso_daught1 = kin->particle( 3 ); + TLorentzVector iso_daught2 = kin->particle( 4 ); TLorentzVector piplusL = kin->particle( 5 ); // Final state P4 momenta - TLorentzVector X = vec_daught1 + vec_daught2 + bach; + TLorentzVector X = iso_daught1 + iso_daught2 + bach; TLorentzVector recoil = proton + piplusL; //Momenta for the 1st permutation - TLorentzVector vec_a = vec_daught1 + vec_daught2; + TLorentzVector iso_a = iso_daught1 + iso_daught2; TLorentzVector proton_ps_a = proton + bach; TLorentzVector recoil_ps_a = recoil + bach; - //Momenta for the 2nd permutation (bach <=> vec_daught1) - TLorentzVector vec_b = bach + vec_daught2; - TLorentzVector proton_ps_b = proton + vec_daught1; - TLorentzVector recoil_ps_b = recoil + vec_daught1; + //Momenta for the 2nd permutation (bach <=> iso_daught1) + TLorentzVector iso_b = bach + iso_daught2; + TLorentzVector proton_ps_b = proton + iso_daught1; + TLorentzVector recoil_ps_b = recoil + iso_daught1; @@ -141,10 +141,10 @@ IsoPsPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ // Calculate decay angles for X in the Gottfried-Jackson frame and for Isobar in the Helicity frame // Angles for the 1st permutation - vector thetaPhiAnglesTwoStep_a = getTwoStepAngles(X, vec_a, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); + vector thetaPhiAnglesTwoStep_a = getTwoStepAngles(X, iso_a, iso_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); - // Angles for the 2nd permutation (bach <=> vec_daught1) - vector thetaPhiAnglesTwoStep_b = getTwoStepAngles(X, vec_b, bach, TLorentzVector(0,0,0,0), beam, target, 2, true); + // Angles for the 2nd permutation (bach <=> iso_daught1) + vector thetaPhiAnglesTwoStep_b = getTwoStepAngles(X, iso_b, bach, TLorentzVector(0,0,0,0), beam, target, 2, true); //Symmetrized angles and masses will be passed as vectors of unit length @@ -160,8 +160,8 @@ IsoPsPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ vector phiH_a = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_a[3]}; vector phiH_b = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_b[3]}; - vector vec_mass_a = {vec_a.M()}; - vector vec_mass_b = {vec_b.M()}; + vector iso_mass_a = {iso_a.M()}; + vector iso_mass_b = {iso_b.M()}; vector protonps_mass_a = {proton_ps_a.M()}; vector protonps_mass_b = {proton_ps_b.M()}; @@ -192,8 +192,8 @@ IsoPsPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ fillHistogram( kPhiH, phiH_b, 0.5 ); - fillHistogram( kIsoMass, vec_mass_a, 0.5 ); - fillHistogram( kIsoMass, vec_mass_b, 0.5 ); + fillHistogram( kIsoMass, iso_mass_a, 0.5 ); + fillHistogram( kIsoMass, iso_mass_b, 0.5 ); fillHistogram( kProtonPsMass, protonps_mass_a, 0.5 ); fillHistogram( kProtonPsMass, protonps_mass_b, 0.5 ); diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index 0c9d803fc..ddf69a3ed 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -128,8 +128,9 @@ int main( int argc, char* argv[] ){ atiSetup(); cout << "Plotgen results"<< endl; - IsoPsPlotGenerator plotGen( results, PlotGenerator::kNoGenMC ); // optional can be omitted - cout << " Initialized ati and PlotGen" << endl; + // IsoPsPlotGenerator plotGen( results, PlotGenerator::kNoGenMC ); // optional can be omitted + IsoPsPlotGenerator plotGen( results ); + cout << " Initialized ati and PlotGen" << endl; // ************************* @@ -244,11 +245,11 @@ int main( int argc, char* argv[] ){ bool singleData = irefl == reflname.size() && iamp == amphistname.size(); bool singleFlatWave = (irefl == 0 && iamp > 0) || (irefl > 0 && iamp == 0); - if (iplot == PlotGenerator::kGenMC) continue; + // if (iplot == PlotGenerator::kGenMC) continue; // no acceptance correction if ( iplot == PlotGenerator::kData && !singleData ) continue; // only plot data once if ( iplot == PlotGenerator::kBkgnd && !singleData ) continue; // only plot background once if ( iplot == PlotGenerator::kAccMC && singleFlatWave ) continue; // only plot Flat wave once - + if ( iplot == PlotGenerator::kGenMC && singleFlatWave ) continue; // only plot Flat wave once // loop over different variables @@ -315,15 +316,17 @@ int main( int argc, char* argv[] ){ - //Now, write summed up histograms to the root file + //Now, write (nonzero) summed up histograms to the root file for (auto it = summedHists.begin(); it != summedHists.end(); it++) { std::string hsummed_name = it->first; TH1* hsummed = it->second; - hsummed->SetName(hsummed_name.c_str()); + if (hsummed->Integral() == 0.) continue; + else hsummed->SetName(hsummed_name.c_str()); + if (hsummed_name.find("+") != std::string::npos || hsummed_name.find("-") != std::string::npos) plotfiledir->cd(); - else plotfile->cd(); + else plotfile->cd(); hsummed->Write(); } @@ -391,8 +394,8 @@ int main( int argc, char* argv[] ){ // second loop over amplitudes to get phase difference names for(unsigned int j = i+1; j < fullamps.size(); j++){ - // leave only the Spring2017_PARA_00::ImagPosSign and Spring2017_PARA_00::ImagNegSign coherent sums - if (fullamps[i].find("Spring2017_PARA_00") == std::string::npos || fullamps[j].find("Spring2017_PARA_00") == std::string::npos) continue; + // leave only the Spring2017_PARA_0::ImagPosSign and Spring2017_PARA_0::ImagNegSign coherent sums + if (fullamps[i].find("Spring2017_PARA_0") == std::string::npos || fullamps[j].find("Spring2017_PARA_0") == std::string::npos) continue; if (fullamps[i].find("UniBG") != std::string::npos || fullamps[j].find("UniBG") != std::string::npos) continue; if (fullamps[i].find("Real") != std::string::npos || fullamps[j].find("Real") != std::string::npos) continue; @@ -401,7 +404,8 @@ int main( int argc, char* argv[] ){ if (fullamps[i].find("ImagPosSign") != std::string::npos && fullamps[j].find("ImagPosSign") == std::string::npos) continue; phaseDiffNames.push_back( std::make_pair(fullamps[i], fullamps[j]) ); - + std::cout << "PAIRED:\t" << fullamps[i] << "\t" << fullamps[j] << endl; + } } From 80d86d2e286f8ffbdfd6a06e826e2b549eea3a45 Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Fri, 8 May 2026 09:38:00 -0400 Subject: [PATCH 20/33] Intensities for coherent sums are added. --- .../isops_plotter/isops_plotter.cc | 121 +++++++++++------- 1 file changed, 76 insertions(+), 45 deletions(-) diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index ddf69a3ed..e8800c0d6 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -134,20 +134,23 @@ int main( int argc, char* argv[] ){ // ************************* - // Define Amplitude and Sum names + // Define Amplitudes and Coherent sums // ***************************** - + vector reflname = {"Uniform","PosRefl", "NegRefl"}; - vector amphistname = {"Flat"}; - vector pipiIsobar_comps = {"pipiIso_0-S","pipiIso_1+P-","pipiIso_1+P0","pipiIso_1+P+"}; - vector rhoIsobar_comps = {"rhoIso_0-P", "rhoIso_1+S-", "rhoIso_1+S0", "rhoIso_1+S+", "rhoIso_1+D-", "rhoIso_1+D0", "rhoIso_1+D+", "rhoIso_2+D--", "rhoIso_2+D-", "rhoIso_2+D0", "rhoIso_2+D+", "rhoIso_2+D++"}; - vector f2Isobar_comps = {"f2Iso_1+P-","f2Iso_1+P0","f2Iso_1+P+","f2Iso_2+P--","f2Iso_2+P-","f2Iso_2+P0","f2Iso_2+P+","f2Iso_2+P++","f2Iso_2-S--","f2Iso_2-S-","f2Iso_2-S0","f2Iso_2-S+","f2Iso_2-S++","f2Iso_2-D--","f2Iso_2-D-","f2Iso_2-D0","f2Iso_2-D+","f2Iso_2-D++"}; + vector amphistname = {"Flat"}; + vector pipiIsobar_amps = {"pipiIso_0-S","pipiIso_1+P-","pipiIso_1+P0","pipiIso_1+P+"}; + vector rhoIsobar_amps = {"rhoIso_0-P", "rhoIso_1+S-", "rhoIso_1+S0", "rhoIso_1+S+", "rhoIso_1+D-", "rhoIso_1+D0", "rhoIso_1+D+", "rhoIso_2+D--", "rhoIso_2+D-", "rhoIso_2+D0", "rhoIso_2+D+", "rhoIso_2+D++"}; + vector f2Isobar_amps = {"f2Iso_1+P-","f2Iso_1+P0","f2Iso_1+P+","f2Iso_2+P--","f2Iso_2+P-","f2Iso_2+P0","f2Iso_2+P+","f2Iso_2+P++","f2Iso_2-S--","f2Iso_2-S-","f2Iso_2-S0","f2Iso_2-S+","f2Iso_2-S++","f2Iso_2-D--","f2Iso_2-D-","f2Iso_2-D0","f2Iso_2-D+","f2Iso_2-D++"}; + + amphistname.insert(amphistname.end(), pipiIsobar_amps.begin(), pipiIsobar_amps.end()); + amphistname.insert(amphistname.end(), rhoIsobar_amps.begin(), rhoIsobar_amps.end()); + amphistname.insert(amphistname.end(), f2Isobar_amps.begin(), f2Isobar_amps.end()); - amphistname.insert(amphistname.end(), pipiIsobar_comps.begin(), pipiIsobar_comps.end()); - amphistname.insert(amphistname.end(), rhoIsobar_comps.begin(), rhoIsobar_comps.end()); - amphistname.insert(amphistname.end(), f2Isobar_comps.begin(), f2Isobar_comps.end()); + vector ampsumname = {"pipiIso_0-S","pipiIso_1+P","rhoIso_0-P","rhoIso_1+S","rhoIso_1+D","rhoIso_2+D","f2Iso_1+P","f2Iso_2+P","f2Iso_2-S","f2Iso_2-D"}; + // ************************ // set up an output ROOT file to store histograms // ************************ @@ -346,7 +349,7 @@ int main( int argc, char* argv[] ){ vector< string > pars; // pars.push_back("dsratio"); - // file for writing parameters (later switch to putting in ROOT file) + //Text file for writing the parameters ofstream outfile; outfile.open( outparsName ); @@ -356,41 +359,52 @@ int main( int argc, char* argv[] ){ outfile << parValue << "\t" << parError << "\t" << endl; } - outfile << "TOTAL EVENTS = " << results.intensity().first << " +- " << results.intensity().second << endl; + + + //Define vector with full amplitudes vector fullamps = plotGen.fullAmplitudes(); - for (unsigned int i = 0; i < fullamps.size(); i++){ - vector useamp; - useamp.push_back(fullamps[i]); - outfile << "FIT FRACTION " << fullamps[i] << " = " - << results.intensity(useamp).first / - results.intensity().first << " +- " - << results.intensity(useamp).second / - results.intensity().first << endl; - } + //Define vectors for combining amplitudes with unique JPLMeps const int nAmps = amphistname.size(); - vector ampsumPosRefl[nAmps]; - vector ampsumNegRefl[nAmps]; + vector ampPosRefl[nAmps]; + vector ampNegRefl[nAmps]; vector< pair > phaseDiffNames; - - for(unsigned int i = 0; i < fullamps.size(); i++){ - // combine amplitudes with names defined above + //Define vectors for combining amplitudes with unique JPLeps + const int nSums = ampsumname.size(); + vector ampsumPosRefl[nSums]; + vector ampsumNegRefl[nSums]; + + + for(unsigned int i = 0; i < fullamps.size(); i++){ + + // Split by reflectivities and grab contributions for every JPLM amplitude for(int iamp=0; iamp useamp; + useamp.push_back(fullamps[i]); + outfile << "FIT FRACTION " << fullamps[i] << " = " << results.intensity(useamp).first / results.intensity().first << " +- " << results.intensity(useamp).second / results.intensity().first << endl; + } + cout<<"Computing phase differences"< phaseDiff = results.phaseDiff( phaseDiffNames[i].first, phaseDiffNames[i].second ); outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " << phaseDiffNames[i].second << " " << phaseDiff.first << " " << phaseDiff.second << endl; } + cout<<"Computing intensities of coherent sums"< > covMatrix; From 4a4ff10c7b9497ab5ce67e9c07563735dc46ee5e Mon Sep 17 00:00:00 2001 From: Ilia Belov Date: Thu, 28 May 2026 10:29:40 -0400 Subject: [PATCH 21/33] CUDA part in PiPiSWaveAMPK added --- .../AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu | 10 ++-------- .../AMPTOOLS_AMPS/GPUPiPiSWaveAMPK_kernel.cu | 19 +++++++++++++++++++ src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc | 3 ++- src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc | 8 ++++---- src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h | 16 ++++++++-------- src/programs/AmplitudeAnalysis/SConscript | 3 ++- .../isops_plotter/isops_plotter.cc | 6 +++--- 7 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 src/libraries/AMPTOOLS_AMPS/GPUPiPiSWaveAMPK_kernel.cu diff --git a/src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu b/src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu index 34c02acef..f4578a11f 100644 --- a/src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu +++ b/src/libraries/AMPTOOLS_AMPS/GPUIso_ps_refl_kernel.cu @@ -1,11 +1,9 @@ - #include #include "GPUManager/GPUCustomTypes.h" #include "GPUManager/CUDA-Complex.cuh" -__global__ void -GPUIso_ps_refl_kernel( GPU_AMP_PROTO ) +__global__ void GPUIso_ps_refl_kernel( GPU_AMP_PROTO ) { int iEvent = GPU_THIS_EVENT; @@ -13,12 +11,8 @@ GPUIso_ps_refl_kernel( GPU_AMP_PROTO ) pcDevAmp[iEvent] = ans; } -void -GPUIso_ps_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) - +void GPUIso_ps_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) { - GPUIso_ps_refl_kernel<<< dimGrid, dimBlock >>>( GPU_AMP_ARGS ); - } diff --git a/src/libraries/AMPTOOLS_AMPS/GPUPiPiSWaveAMPK_kernel.cu b/src/libraries/AMPTOOLS_AMPS/GPUPiPiSWaveAMPK_kernel.cu new file mode 100644 index 000000000..ab8f1bb8e --- /dev/null +++ b/src/libraries/AMPTOOLS_AMPS/GPUPiPiSWaveAMPK_kernel.cu @@ -0,0 +1,19 @@ +#include + +#include "GPUManager/GPUCustomTypes.h" +#include "GPUManager/CUDA-Complex.cuh" + +__global__ void GPUPiPiSWaveAMPK_kernel( GPU_AMP_PROTO ) +{ + int iEvent = GPU_THIS_EVENT; + + WCUComplex ans = { GPU_UVARS(0), GPU_UVARS(1) }; + pcDevAmp[iEvent] = ans; +} + +void GPUPiPiSWaveAMPK_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) +{ + + GPUPiPiSWaveAMPK_kernel<<< dimGrid, dimBlock >>>( GPU_AMP_ARGS ); + +} \ No newline at end of file diff --git a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc index 14a4cb1a8..f83c42af7 100644 --- a/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc +++ b/src/libraries/AMPTOOLS_AMPS/Iso_ps_refl.cc @@ -58,7 +58,7 @@ UserAmplitude< Iso_ps_refl >( args ){ // : +1/-1 sign in P_gamma term // Isobar spin S - m_s = static_cast(parseValidatedNumber("S",args[0])); + m_s = static_cast(parseValidatedNumber("S",args[0])); // Resonance spin J m_j = static_cast(parseValidatedNumber("J", args[1])); // Resonance spin projection @@ -183,6 +183,7 @@ void Iso_ps_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ amplitude += conj(wignerD(m_j, m_m, lambda, cosTheta, phi))*hel_amp*conj(wignerD(m_s, lambda, 0, cosThetaH, phiH)); } + GDouble factor = sqrt(1 + m_sign * beam_polFraction); complex zjm = 0; // - -> + in prod_angle diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc index d63dba13e..947195b23 100644 --- a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.cc @@ -28,7 +28,7 @@ PiPiSWaveAMPK::PiPiSWaveAMPK( const vector &args ) : UserAmplitude complex PiPiSWaveAMPK::breakupMom(mType m, GDo #ifdef GPU_ACCELERATION void PiPiSWaveAMPK::launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const { - PiPiSWaveAMPK_exec( dimGrid, dimBlock, GPU_AMP_ARGS, m_mass, m_g1, m_g2, m_daughter1, m_daughter2); - + GPUPiPiSWaveAMPK_exec( dimGrid, dimBlock, GPU_AMP_ARGS); + } -#endif //GPU_ACCELERATION +#endif diff --git a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h index 9f5ce8b29..3a813e276 100644 --- a/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h +++ b/src/libraries/AMPTOOLS_AMPS/PiPiSWaveAMPK.h @@ -7,7 +7,6 @@ #include "IUAmpTools/Amplitude.h" #include "GPUManager/GPUCustomTypes.h" - #include #include #include @@ -15,14 +14,15 @@ #include -#ifdef GPU_ACCELERATION -void PiPiSWaveAMPK_exec(dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO, GDouble m_mass, GDouble m_g1, GDouble m_g2, int m_daughter1, int m_daughter2 ); -#endif // GPU_ACCELERATION +using std::complex; +using namespace std; +#ifdef GPU_ACCELERATION +void GPUPiPiSWaveAMPK_exec(dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ); +#endif + -using std::complex; -using namespace std; class Kinematics; @@ -41,9 +41,9 @@ class PiPiSWaveAMPK : public UserAmplitude{ #ifdef GPU_ACCELERATION void launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const; - bool isGPUEnabled() const { return false; } + bool isGPUEnabled() const { return true; } -#endif // GPU_ACCELERATION +#endif private: diff --git a/src/programs/AmplitudeAnalysis/SConscript b/src/programs/AmplitudeAnalysis/SConscript index 9b27432f9..d2149bdff 100644 --- a/src/programs/AmplitudeAnalysis/SConscript +++ b/src/programs/AmplitudeAnalysis/SConscript @@ -3,10 +3,11 @@ import sbms Import('*') -subdirs = ['fit', 'fitMPI', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'vecps3pi_plotter', 'isops_plotter', 'plot_etapi0'] +subdirs = ['fit', 'twopi_plotter', 'twopi_plotter_amp', 'twopi_plotter_mom', 'twopi_plotter_primakoff', 'twolepton_plotter', 'twoleptonGJ_plotter', 'split_mass', 'split_t', 'threepi_plotter_schilling', 'omega_radiative_plotter', 'project_moments', 'plot_etapi_delta', 'project_moments_polarized', 'Bootstrap_plot_etapi_delta_SPDG_allamps_mass_t_bins', 'Pol_moments_viafittedPW', 'project_moments_SPD_etapi0_posepsilon', 'omegapi_plotter', 'vecps_plotter', 'vecps3pi_plotter', 'isops_plotter', 'plot_etapi0'] SConscript(dirs=subdirs, exports='env osname', duplicate=0) +#fitMPI # Optional targets optdirs = ['fitMPI'] sbms.OptionallyBuild(env, optdirs) diff --git a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc index e8800c0d6..2edc2b6d3 100644 --- a/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc +++ b/src/programs/AmplitudeAnalysis/isops_plotter/isops_plotter.cc @@ -125,7 +125,7 @@ int main( int argc, char* argv[] ){ // set up the plot generator // ************************ cout << "before atisetup();"<< endl; - atiSetup(); + atiSetup(); cout << "Plotgen results"<< endl; // IsoPsPlotGenerator plotGen( results, PlotGenerator::kNoGenMC ); // optional can be omitted @@ -136,7 +136,7 @@ int main( int argc, char* argv[] ){ // ************************* // Define Amplitudes and Coherent sums // ***************************** - + vector reflname = {"Uniform","PosRefl", "NegRefl"}; vector amphistname = {"Flat"}; vector pipiIsobar_amps = {"pipiIso_0-S","pipiIso_1+P-","pipiIso_1+P0","pipiIso_1+P+"}; @@ -490,7 +490,7 @@ int main( int argc, char* argv[] ){ cout << " Created Plot Factory " << endl; PlotterMainWindow mainFrame( gClient->GetRoot(), factory ); cout << " Main frame created " << endl; - + app.Run(); cout << " App running" << endl; } From 8367347d96ac3ed3af282dc9de35d85493b77c20 Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:41:08 +0200 Subject: [PATCH 22/33] Delete src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc --- src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc | 259 ------------------ 1 file changed, 259 deletions(-) delete mode 100644 src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc deleted file mode 100644 index 2d2e2aa0b..000000000 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.cc +++ /dev/null @@ -1,259 +0,0 @@ - -#include -#include -#include -#include -#include - -#include "TLorentzVector.h" -#include "TLorentzRotation.h" -#include "TFile.h" - -#include "IUAmpTools/Kinematics.h" -#include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" -#include "AMPTOOLS_AMPS/clebschGordan.h" -#include "AMPTOOLS_AMPS/wignerD.h" -#include "AMPTOOLS_AMPS/decayAngles.h" -#include "AMPTOOLS_AMPS/barrierFactor.h" - -#include "UTILITIES/BeamProperties.h" - -// Function to check if a string is a valid number -static bool isValidNumber(const string& argInput, double &value){ - char* end = nullptr; - errno = 0; // reset global error - value = std::strtod(argInput.c_str(), &end); - - // Check if - // (1) no conversion was performed - // (2) there are leftover characters - // (3) an overflow/underflow occurred - if(end == argInput.c_str() || *end != '\0' || errno != 0) { - return false; // not a valid number - } - // If end points to the end of string, it's fully numeric - return true; -} - -static double parseValidatedNumber(const string& label, const string& argInput){ - double tmpValue = 0.0; - if(!isValidNumber(argInput, tmpValue)){ - throw std::invalid_argument("VecPs_3pi_refl: invalid " + label + ": " + argInput); - } - return tmpValue; -} - - -VecPs_3pi_refl::VecPs_3pi_refl( const vector< string >& args ) : -UserAmplitude< VecPs_3pi_refl >( args ){ - - // 5 possibilities to initialize this amplitude: - // : total spin, - // : spin projection, - // : partial wave, - // : +1/-1 for real/imaginary part; - // : +1/-1 sign in P_gamma term - - // Resonance spin J - m_j = static_cast(parseValidatedNumber("J", args[0])); - // Spin projection (Lambda) - m_m = static_cast(parseValidatedNumber("M", args[1])); - // Partial wave L - m_l = static_cast(parseValidatedNumber("L", args[2])); - // Real (+1) or imaginary (-1) - m_r = static_cast(parseValidatedNumber("Re/Im", args[3])); - // Sign for polarization in amplitude - m_s = static_cast(parseValidatedNumber("P_gamma sign", args[4])); - - // make sure values are reasonable - assert( abs( m_m ) <= m_j ); - // m_r = +1 for real - // m_r = -1 for imag - assert( abs( m_r ) == 1 ); - // m_s = +1 for 1 + Pgamma - // m_s = -1 for 1 - Pgamma - assert( abs( m_s ) == 1 ); - - // Default polarization information stored in tree - m_polInTree = true; - - // Default is 2-body vector decay (set flag in config file for omega->3pi) - m_3pi = false; - - // Loop over any additional amplitude arguments to change defaults - for(uint ioption=5; ioptionGet(args[7].c_str()); - if(polFrac_vs_E != nullptr ){ - throw std::runtime_error( - "VecPs_3pi_refl ERROR: Could not find histogram '" + args[7] + - "' in file " + std::string(polOption.Data())); - } - } - else{ - polFraction = parseValidatedNumber("polarization fraction", args[6]); - } - } - // Check for omega->3pi option - if(option.EqualTo("omega3pi")) m_3pi = true; - } -} - -void -VecPs_3pi_refl::calcUserVars( GDouble** pKin, GDouble* userVars ) const{ - - TLorentzVector beam; - TVector3 eps; - GDouble beam_polFraction; - GDouble beam_polAngle; - - if(m_polInTree){ - beam.SetPxPyPzE( 0.0, 0.0, pKin[0][0], pKin[0][0]); - eps.SetXYZ(pKin[0][1], pKin[0][2], 0.0); // beam polarization vector; - - beam_polFraction = eps.Mag(); - beam_polAngle = eps.Phi(); - } - else{ - beam.SetPxPyPzE( pKin[0][1], pKin[0][2], pKin[0][3], pKin[0][0] ); - beam_polAngle = polAngle; - - if(polFraction > 0.0){ // for fitting with fixed polarization - beam_polFraction = polFraction; - } - else{ // for fitting with polarization vs E_gamma from input histogram - int bin = polFrac_vs_E->GetXaxis()->FindBin(pKin[0][0]); - if (bin == 0 || bin > polFrac_vs_E->GetXaxis()->GetNbins()){ - beam_polFraction = 0.0; - } else - beam_polFraction = polFrac_vs_E->GetBinContent(bin); - } - } - - TLorentzVector recoil( pKin[1][1]+pKin[5][1], pKin[1][2]+pKin[5][2], pKin[1][3]+pKin[5][3], pKin[1][0]+pKin[5][0] ); - - // Fill in four-vectors for final state particles - // 1st after proton is always the pseudoscalar meson - TLorentzVector ps(pKin[2][1], pKin[2][2], pKin[2][3], pKin[2][0]); - // Compute vector meson from its decay products - // Make sure the order of daughters is correct in the config file! - TLorentzVector vec, vec_daught1, vec_daught2; - - - if(m_3pi){ - // Omega ps proton, omega -> 3pi (6 particles) - // Omega pi- Delta++, omega -> 3pi (7 particles) - TLorentzVector pi0(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); - TLorentzVector pip(pKin[4][1], pKin[4][2], pKin[4][3], pKin[4][0]); - TLorentzVector pim(pKin[5][1], pKin[5][2], pKin[5][3], pKin[5][0]); - vec = pi0 + pip + pim; - vec_daught1 = pip; - vec_daught2 = pim; - } - else{ - // Omega ps proton, omega -> pi0 g (4 particles) - // Omega pi- Delta++, omega -> pi0 g (5 particles) - - // (vec 2-body) ps proton, vec 2-body -> pipi, KK (5 particles) - // (vec 2-body) pi- Delta++, vec 2-body -> pipi, KK (6 particles) - // (vec 2-body) K+ Lambda, vec 2-body -> Kpi (6 particles) - vec_daught1 = TLorentzVector(pKin[3][1], pKin[3][2], pKin[3][3], pKin[3][0]); - vec_daught2 = TLorentzVector(pKin[4][1], pKin[4][2], pKin[4][3], pKin[4][0]); - vec = vec_daught1 + vec_daught2; - } - - // Final meson system P4 - TLorentzVector X = vec + ps; - /// Fixed target - TLorentzVector target(0,0,0,0.938272); - - - //Calculate production angle in the Gottfried-Jackson frame - GDouble prod_angle = getPhiProd(beam_polAngle, X, beam, target, 2, true); - - // Calculate decay angles for X in the Gottfried-Jackson frame and for Isobar in the Helicity frame - vector thetaPhiAnglesTwoStep; - if(m_3pi){ - thetaPhiAnglesTwoStep = getTwoStepAngles(X, vec, vec_daught1, vec_daught2, beam, target, 2, true); - } - else{ - thetaPhiAnglesTwoStep = getTwoStepAngles(X, vec, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); - } - - - - GDouble cosTheta = TMath::Cos(thetaPhiAnglesTwoStep[0]); - GDouble phi = thetaPhiAnglesTwoStep[1]; - GDouble cosThetaH = TMath::Cos(thetaPhiAnglesTwoStep[2]); - GDouble phiH = thetaPhiAnglesTwoStep[3]; - GDouble m_X = X.M(); - GDouble m_vec = vec.M(); - GDouble m_ps = ps.M(); - - complex amplitude(0,0); - complex i(0,1); - - for (int lambda = -1; lambda <= 1; lambda++) { // sum over vector helicity - GDouble hel_amp = clebschGordan(m_l, 1, 0, lambda, m_j, lambda); - amplitude += conj(wignerD(m_j, m_m, lambda, cosTheta, phi)) * - hel_amp * conj(wignerD(1, lambda, 0, cosThetaH, phiH)); - } - - GDouble factor = sqrt(1 + m_s * beam_polFraction); - complex zjm = 0; - // - -> + in prod_angle - complex rotateY = polar((GDouble)1., (GDouble)(-1. * prod_angle )); - - if (m_r == 1) - zjm = real(amplitude * rotateY); - if (m_r == -1) - zjm = i*imag(amplitude * rotateY); - - // E852 Nozar thesis has sqrt(2*s+1)*sqrt(2*l+1)*F_l(p_omega)*sqrt(omega) - double kinFactor = barrierFactor(m_X, m_l, m_vec, m_ps); - //kinFactor *= sqrt(3.) * sqrt(2.*m_l + 1.); - factor *= kinFactor; - - userVars[uv_ampRe] = ( factor * zjm ).real(); - userVars[uv_ampIm] = ( factor * zjm ).imag(); - - return; -} - - -/////////////////////// Amplitude Calculation ////////////////////////// - -complex< GDouble > -VecPs_3pi_refl::calcAmplitude( GDouble** pKin, GDouble* userVars ) const -{ - return complex< GDouble >( userVars[uv_ampRe], userVars[uv_ampIm] ); -} - -void VecPs_3pi_refl::updatePar( const AmpParameter& par ){ - - // could do expensive calculations here on parameter updates -} - - -#ifdef GPU_ACCELERATION - -void -VecPs_3pi_refl::launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const { - - GPUVecPs_3pi_refl_exec( dimGrid, dimBlock, GPU_AMP_ARGS ); - -} - -#endif - - From 34f9b2cfb4457577cf58ba6bea9c9d0c33822fd3 Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:43:13 +0200 Subject: [PATCH 23/33] Delete src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h --- src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h | 93 -------------------- 1 file changed, 93 deletions(-) delete mode 100644 src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h diff --git a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h b/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h deleted file mode 100644 index 3c06f4cae..000000000 --- a/src/libraries/AMPTOOLS_AMPS/VecPs_3pi_refl.h +++ /dev/null @@ -1,93 +0,0 @@ -#if !defined(VECPS_3PI_REFL) -#define VECPS_3PI_REFL - -#include "IUAmpTools/Amplitude.h" -#include "IUAmpTools/UserAmplitude.h" -#include "IUAmpTools/AmpParameter.h" -#include "GPUManager/GPUCustomTypes.h" - -#include "TH1D.h" -#include -#include -#include - -using std::complex; -using namespace std; - -#ifdef GPU_ACCELERATION -void -GPUVecPs_3pi_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ); -#endif - -class Kinematics; - -class VecPs_3pi_refl : public UserAmplitude< VecPs_3pi_refl > -{ - -public: - - VecPs_3pi_refl() : UserAmplitude< VecPs_3pi_refl >() { }; - VecPs_3pi_refl( const vector< string >& args ); - VecPs_3pi_refl( int m_j, int m_m, int m_l, int m_r, int m_s ); - - string name() const { return "VecPs_3pi_refl"; } - - complex< GDouble > calcAmplitude( GDouble** pKin, GDouble* userVars ) const; - - // ********************** - // The following lines are optional and can be used to precalculate - // user-defined data that the amplitudes depend on. - - // Use this for indexing a user-defined data array and notifying - // the framework of the number of user-defined variables. - - //enum UserVars { uv_cosTheta = 0, uv_Phi, uv_cosThetaH, uv_PhiH, - // uv_prod_Phi, uv_MX, uv_MVec, uv_MPs, uv_beam_polFraction, - // uv_beam_polAngle, kNumUserVars }; - enum UserVars { uv_ampRe = 0, uv_ampIm, kNumUserVars }; - unsigned int numUserVars() const { return kNumUserVars; } - - // This function needs to be defined -- see comments and discussion - // in the .cc file. - void calcUserVars( GDouble** pKin, GDouble* userVars ) const; - - // This is an optional addition if the calcAmplitude routine - // can run with only the user-defined data and not the original - // four-vectors. It is used to optimize memory usage in GPU - // based fits. - bool needsUserVarsOnly() const { return true; } - - // This is an optional addition if the UserVars are the same for each - // instance of an amplitude. If it is not used, the memory footprint - // grows dramatically as UserVars values are stored for each instance - // of the amplitude. NOTE: To use this make sure that UserVars only - // depend on kinematics and no arguments provided to the amplitude! - bool areUserVarsStatic() const { return false; } - - void updatePar( const AmpParameter& par ); - -#ifdef GPU_ACCELERATION - - void launchGPUKernel( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) const; - - bool isGPUEnabled() const { return true; } - -#endif // GPU_ACCELERATION - -private: - - int m_j; - int m_m; - int m_l; - int m_r; - int m_s; - int m_3pi; - - //AmpParameter polAngle; - GDouble polFraction; - GDouble polAngle; - bool m_polInTree; - TH1D *polFrac_vs_E; -}; - -#endif From c2dfa9f6dec5547a2e5dd95879155d93c00995d6 Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:43:51 +0200 Subject: [PATCH 24/33] Delete src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu --- .../AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu diff --git a/src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu b/src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu deleted file mode 100644 index 3556553e1..000000000 --- a/src/libraries/AMPTOOLS_AMPS/GPUVecPs_3pi_refl_kernel.cu +++ /dev/null @@ -1,24 +0,0 @@ - -#include - -#include "GPUManager/GPUCustomTypes.h" -#include "GPUManager/CUDA-Complex.cuh" - -__global__ void -GPUVecPs_3pi_refl_kernel( GPU_AMP_PROTO ) -{ - int iEvent = GPU_THIS_EVENT; - - WCUComplex ans = { GPU_UVARS(0), GPU_UVARS(1) }; - pcDevAmp[iEvent] = ans; -} - -void -GPUVecPs_3pi_refl_exec( dim3 dimGrid, dim3 dimBlock, GPU_AMP_PROTO ) - -{ - - GPUVecPs_3pi_refl_kernel<<< dimGrid, dimBlock >>>( GPU_AMP_ARGS ); - -} - From d4c994460398782f884d547a2a0241335064608d Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:45:13 +0200 Subject: [PATCH 25/33] Delete src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc --- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc | 207 ------------------ 1 file changed, 207 deletions(-) delete mode 100644 src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc deleted file mode 100644 index 1c7f8d3d0..000000000 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.cc +++ /dev/null @@ -1,207 +0,0 @@ -#include "TLorentzVector.h" -#include "TLorentzRotation.h" - -#include "AMPTOOLS_AMPS/decayAngles.h" - -#include "AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h" -#include "IUAmpTools/Histogram1D.h" -#include "IUAmpTools/Kinematics.h" - - - -// Function to check if a string is a valid number -static bool isValidNumber(const string& argInput, double &value){ - char* end = nullptr; - errno = 0; // reset global error - value = std::strtod(argInput.c_str(), &end); - - // Check if - // (1) no conversion was performed - // (2) there are leftover characters - // (3) an overflow/underflow occurred - if(end == argInput.c_str() || *end != '\0' || errno != 0) { - return false; // not a valid number - } - // If end points to the end of string, it's fully numeric - return true; -} - - -static double parseValidatedNumber(const string& label, const string& argInput){ - double tmpValue = 0.0; - if(!isValidNumber(argInput, tmpValue)){ - throw std::invalid_argument("Vec_ps_refl: invalid " + label + ": " + argInput); - } - return tmpValue; -} - - - - -/* Constructor to display FitResults */ -VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( const FitResults& results, Option opt ) : -PlotGenerator( results, opt ) -{ - createHistograms(); -} - -VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( const FitResults& results ) : -PlotGenerator( results ) -{ - createHistograms(); -} - - -/* Constructor for event generator (no FitResult) */ -VecPs3PiPlotGenerator::VecPs3PiPlotGenerator( ) : -PlotGenerator( ) -{ - createHistograms(); -} - -void VecPs3PiPlotGenerator::createHistograms( ) { - cout << " calls to bookHistogram go here" << endl; - - bookHistogram( kProd_Ang, new Histogram1D( 50, -180., 180., "ProdAng", "Production Angle [deg.]" ) ); - bookHistogram( kCosTheta, new Histogram1D( 50, -1., 1., "CosTheta_GJ", "cos#theta^{[GJ]}" ) ); - bookHistogram( kPhi, new Histogram1D( 50, -180., 180., "Phi_GJ", "#phi^{[GJ]} [deg.]" ) ); - bookHistogram( kCosThetaH, new Histogram1D( 50, -1., 1., "CosTheta_HF", "cos#theta^{[HF]}" ) ); - bookHistogram( kPhiH, new Histogram1D( 50, -180., 180., "Phi_HF", "#phi^{[HF]} [deg.]" ) ); - - bookHistogram( kVecMass, new Histogram1D( 200, 0., 3., "MVec", "m(2#pi) [GeV]") ); - bookHistogram( kVecPsMass, new Histogram1D( 200, 0.2, 3.2, "MVecPs", "m(3#pi) [GeV]") ); - bookHistogram( kt, new Histogram1D( 100, 0, 1.0 , "t", "-t [GeV^{2}]" ) ); - bookHistogram( kRecoilMass, new Histogram1D( 100, 0.9, 1.9 , "ProtonPiplusL_M", "m(p#pi^{+}_{L}) [GeV]" ) ); - - bookHistogram( kProtonPsMass, new Histogram1D( 200, 0.8, 3.8, "ProtonPiminus_M", "m(p#pi^{-}) [GeV]" ) ); - bookHistogram( kRecoilPsMass, new Histogram1D( 200, 1.0, 4.0, "ProtonPiplusLPiminus_M", "m(p#pi^{+}_{L}#pi^{-}) [GeV]" ) ); - -} - -void -VecPs3PiPlotGenerator::projectEvent( Kinematics* kin ){ - - // this function will make this class backwards-compatible with older versions - // (v0.10.x and prior) of AmpTools, but will not be able to properly obtain - // the polariation plane in the lab when multiple orientations are used - projectEvent( kin, "" ); -} - -void -VecPs3PiPlotGenerator::projectEvent( Kinematics* kin, const string& reactionName ){ - - // We work only with a 2-body vector decay - - - // Fixed target - TLorentzVector target(0,0,0,0.938272); - - - //cout << "project event" << endl; - TLorentzVector beam = kin->particle( 0 ); - TLorentzVector proton = kin->particle( 1 ); - TLorentzVector bach = kin->particle( 2 ); - TLorentzVector vec_daught1 = kin->particle( 3 ); - TLorentzVector vec_daught2 = kin->particle( 4 ); - TLorentzVector piplusL = kin->particle( 5 ); - - - // Final state P4 momenta - TLorentzVector X = vec_daught1 + vec_daught2 + bach; - TLorentzVector recoil = proton + piplusL; - - //Momenta for the 1st permutation - TLorentzVector vec_a = vec_daught1 + vec_daught2; - TLorentzVector proton_ps_a = proton + bach; - TLorentzVector recoil_ps_a = recoil + bach; - - //Momenta for the 2nd permutation (bach <=> vec_daught1) - TLorentzVector vec_b = bach + vec_daught2; - TLorentzVector proton_ps_b = proton + vec_daught1; - TLorentzVector recoil_ps_b = recoil + vec_daught1; - - - - // Properly read polarization angle from config file if provided - double beam_polAngle=0; - // Check config file for optional parameters -- we assume here that the first amplitude in the list is a Vec_ps_refl amplitude - const vector< string > args = cfgInfo()->amplitudeList( reactionName, "", "" ).at(0)->factors().at(0); - for(uint ioption=5; ioption thetaPhiAnglesTwoStep_a = getTwoStepAngles(X, vec_a, vec_daught1, TLorentzVector(0,0,0,0), beam, target, 2, true); - - // Angles for the 2nd permutation (bach <=> vec_daught1) - vector thetaPhiAnglesTwoStep_b = getTwoStepAngles(X, vec_b, bach, TLorentzVector(0,0,0,0), beam, target, 2, true); - - - //Symmetrized angles and masses will be passed as vectors of unit length - vector cosTheta_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[0])}; - vector cosTheta_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[0])}; - - vector phi_a = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_a[1]}; - vector phi_b = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_b[1]}; - - vector cosThetaH_a = {TMath::Cos(thetaPhiAnglesTwoStep_a[2])}; - vector cosThetaH_b = {TMath::Cos(thetaPhiAnglesTwoStep_b[2])}; - - vector phiH_a = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_a[3]}; - vector phiH_b = {TMath::RadToDeg()*thetaPhiAnglesTwoStep_b[3]}; - - vector vec_mass_a = {vec_a.M()}; - vector vec_mass_b = {vec_b.M()}; - - vector protonps_mass_a = {proton_ps_a.M()}; - vector protonps_mass_b = {proton_ps_b.M()}; - - vector recoilps_mass_a = {recoil_ps_a.M()}; - vector recoilps_mass_b = {recoil_ps_b.M()}; - - - - //First, insensitive to the symmetrization quantities - fillHistogram( kProd_Ang, prod_angle ); - fillHistogram( kt, Mandt ); - fillHistogram( kRecoilMass, recoil.M() ); - fillHistogram( kVecPsMass, X.M() ); - - - //Now, symmetrized quantities - fillHistogram( kCosTheta, cosTheta_a, 0.5 ); - fillHistogram( kCosTheta, cosTheta_b, 0.5 ); - - fillHistogram( kPhi, phi_a, 0.5 ); - fillHistogram( kPhi, phi_b, 0.5 ); - - fillHistogram( kCosThetaH, cosThetaH_a, 0.5 ); - fillHistogram( kCosThetaH, cosThetaH_b, 0.5 ); - - fillHistogram( kPhiH, phiH_a, 0.5 ); - fillHistogram( kPhiH, phiH_b, 0.5 ); - - - fillHistogram( kVecMass, vec_mass_a, 0.5 ); - fillHistogram( kVecMass, vec_mass_b, 0.5 ); - - fillHistogram( kProtonPsMass, protonps_mass_a, 0.5 ); - fillHistogram( kProtonPsMass, protonps_mass_b, 0.5 ); - - fillHistogram( kRecoilPsMass, recoilps_mass_a, 0.5 ); - fillHistogram( kRecoilPsMass, recoilps_mass_b, 0.5 ); - - - - -} From c104bff0be4f56717e51fdd8a9d5ae43e9a6ff76 Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:46:33 +0200 Subject: [PATCH 26/33] Delete src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc --- .../vecps3pi_plotter/vecps3pi_plotter.cc | 419 ------------------ 1 file changed, 419 deletions(-) delete mode 100644 src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc deleted file mode 100644 index b6c937971..000000000 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/vecps3pi_plotter.cc +++ /dev/null @@ -1,419 +0,0 @@ -#include -#include -#include -#include - -#include "TClass.h" -#include "TApplication.h" -#include "TGClient.h" -#include "TROOT.h" -#include "TH1.h" -#include "TStyle.h" -#include "TClass.h" -#include "TFile.h" -#include "TMultiGraph.h" -#include "TGraphErrors.h" - -#include "IUAmpTools/AmpToolsInterface.h" -#include "IUAmpTools/FitResults.h" - -#include "AmpPlotter/PlotterMainWindow.h" -#include "AmpPlotter/PlotFactory.h" - -#include "AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h" -#include "AMPTOOLS_DATAIO/ROOTDataReader.h" -#include "AMPTOOLS_DATAIO/ROOTDataReaderBootstrap.h" -#include "AMPTOOLS_DATAIO/ROOTDataReaderTEM.h" -#include "AMPTOOLS_DATAIO/FSRootDataReader.h" -#include "AMPTOOLS_AMPS/BreitWigner.h" -#include "AMPTOOLS_AMPS/Uniform.h" -#include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" -#include "AMPTOOLS_AMPS/PhaseOffset.h" -#include "AMPTOOLS_AMPS/ComplexCoeff.h" -#include "AMPTOOLS_AMPS/Piecewise.h" -#include "AMPTOOLS_AMPS/OmegaDalitz.h" -#include "AMPTOOLS_AMPS/Vec_ps_moment.h" - -#include "MinuitInterface/MinuitMinimizationManager.h" -#include "IUAmpTools/ConfigFileParser.h" -#include "IUAmpTools/ConfigurationInfo.h" - -typedef VecPs3PiPlotGenerator vecps_PlotGen; - -void atiSetup(){ - - AmpToolsInterface::registerAmplitude( BreitWigner() ); - AmpToolsInterface::registerAmplitude( Uniform() ); - AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); - AmpToolsInterface::registerAmplitude( PhaseOffset() ); - AmpToolsInterface::registerAmplitude( ComplexCoeff() ); - AmpToolsInterface::registerAmplitude( Piecewise() ); - AmpToolsInterface::registerAmplitude( OmegaDalitz() ); - AmpToolsInterface::registerAmplitude( Vec_ps_moment() ); - - AmpToolsInterface::registerDataReader( ROOTDataReader() ); - AmpToolsInterface::registerDataReader( FSRootDataReader() ); - AmpToolsInterface::registerDataReader( ROOTDataReaderTEM() ); -} - -using namespace std; - -int main( int argc, char* argv[] ){ - - - // ************************ - // usage - // ************************ - - cout << endl << " *** Viewing Results Using AmpPlotter and writing root histograms *** " << endl << endl; - - if (argc < 2){ - cout << "Usage:" << endl << endl; - cout << "\tvecps3pi_plotter -o " << endl << endl; - return 0; - } - - bool showGui = false; - string outName = "vecps3pi_histos.root"; - string resultsName(argv[1]); - for (int i = 2; i < argc; i++){ - - string arg(argv[i]); - - if (arg == "-g"){ - showGui = true; - } - if (arg == "-o"){ - outName = argv[++i]; - } - if (arg == "-h"){ - cout << endl << " Usage for: " << argv[0] << endl << endl; - cout << "\t -o \t output file path" << endl; - cout << "\t -g \t show GUI" << endl; - exit(1); - } - } - - - // ************************ - // parse the command line parameters - // ************************ - - cout << "Fit results file name = " << resultsName << endl; - cout << "Output file name = " << outName << endl << endl; - - // ************************ - // load the results and display the configuration info - // ************************ - - cout << "Loading Fit results" << endl; - FitResults results( resultsName ); - if( !results.valid() ){ - - cout << "Invalid fit results in file: " << resultsName << endl; - exit( 1 ); - } - cout << "Fit results loaded" << endl; - // ************************ - // set up the plot generator - // ************************ - cout << "before atisetup();"<< endl; - atiSetup(); - cout << "Plotgen results"<< endl; - - vecps_PlotGen plotGen( results, PlotGenerator::kNoGenMC ); // optional can be omitted - cout << " Initialized ati and PlotGen" << endl; - - - // ************************* - // Define Amplitude and Sum names - // ***************************** - /* - vector amphistname = {"Flat","0-P", "1+S-", "1+S0", "1+S+", "1+D-", "1+D0", "1+D+", "2+D--", "2+D-", "2+D0", "2+D+", "2+D++"}; - vector reflname = {"Uniform","PosRefl", "NegRefl"}; - - - // ************************ - // set up an output ROOT file to store histograms - // ************************ - - TFile* plotfile = new TFile( outName.c_str(), "recreate"); - TH1::AddDirectory(kFALSE); - - - // ************************* - // Loop over different polarization types - // ************************* - size_t nReactions = results.reactionList().size(); - - - for (unsigned int polType = 0; polType < nReactions; polType++) { - - - string reactionName = results.reactionList()[polType]; - - //WRITING SEPARATE FILES FOR DIFF POLS - // outName = reactionName + ".root"; - //TFile* plotfile = new TFile( outName.c_str(), "recreate"); - //TH1::AddDirectory(kFALSE); - - string dirname = "Contributions_"+reactionName; - TDirectory* plotfiledir = plotfile->mkdir(dirname.c_str()); - - - plotGen.enableReaction( reactionName ); - vector sums = plotGen.uniqueSums(); - vector amps = plotGen.uniqueAmplitudes(); - cout << "Reaction " << reactionName << " enabled with " << sums.size() << " sums and " << amps.size() << " amplitudes" << endl; - - string locampname; - - // loop over sum configurations (one for each of the individual contributions, and the combined sum of all) - for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++){ - - // loop over desired amplitudes - for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++ ) { - - // turn on all ampltiudes by default - for (unsigned int jamp = 0; jamp < amps.size(); jamp++ ) plotGen.enableAmp( jamp ); - - if (iamp < amphistname.size()){ - // amplitude name - locampname = amphistname[iamp]; - - // turn on all sums by default - for (unsigned int jsum = 0; jsum < sums.size(); jsum++) plotGen.enableSum(jsum); - - //Arrange the negative and positive reflectivity sums - //Negative reflectivity: "ImagNegSign" & "RealPosSign", as in the config file - //Positive reflectivity: "RealNegSign" & "ImagPosSign", as in the config file - - if (irefl < 3) { - for (unsigned int i = 0; i < sums.size(); i++){ - if( reflname[irefl] == "NegRefl" ){ - if(sums[i].find("RealNegSign") != std::string::npos || sums[i].find("ImagPosSign") != std::string::npos || sums[i].find("UniBG") != std::string::npos){ - plotGen.disableSum(i); - //cout<<"disable sum "< 0) || (irefl > 0 && iamp == 0); - - if (iplot == PlotGenerator::kGenMC) continue; - if ( iplot == PlotGenerator::kData && !singleData ) continue; // only plot data once - if ( iplot == PlotGenerator::kBkgnd && !singleData ) continue; // only plot background once - if ( iplot == PlotGenerator::kAccMC && singleFlatWave ) continue; // only plot Flat wave once - - - - // loop over different variables - for (unsigned int ivar = 0; ivar < VecPs3PiPlotGenerator::kNumHists; ivar++){ - - // set unique histogram name for each plot (could put in directories...) - string histname = reactionName; - - if (ivar == VecPs3PiPlotGenerator::kProd_Ang) histname += "_Prod_Ang"; - else if (ivar == VecPs3PiPlotGenerator::kCosTheta) histname += "_CosTheta_GJ"; - else if (ivar == VecPs3PiPlotGenerator::kPhi) histname += "_Phi_GJ"; - else if (ivar == VecPs3PiPlotGenerator::kCosThetaH) histname += "_CosTheta_HF"; - else if (ivar == VecPs3PiPlotGenerator::kPhiH) histname += "_Phi_HF"; - else if (ivar == VecPs3PiPlotGenerator::kVecMass) histname += "_MVec"; - else if (ivar == VecPs3PiPlotGenerator::kVecPsMass) histname += "_MVecPs"; - else if (ivar == VecPs3PiPlotGenerator::kt) histname += "_minust"; - else if (ivar == VecPs3PiPlotGenerator::kRecoilMass) histname += "_ProtonPiplusL_M"; - else if (ivar == VecPs3PiPlotGenerator::kProtonPsMass) histname += "_ProtonPiminus_M"; - else if (ivar == VecPs3PiPlotGenerator::kRecoilPsMass) histname += "_ProtonPiplusLPiminus_M"; - else continue; - - if (iplot == PlotGenerator::kData) histname += "_data"; - if (iplot == PlotGenerator::kBkgnd) histname += "_bkgnd"; - if (iplot == PlotGenerator::kAccMC) histname += "_acc"; - if (iplot == PlotGenerator::kGenMC) histname += "_gen"; - - if (irefl < reflname.size()){ - // get name of sum for naming histogram - string sumName = reflname[irefl]; - histname += "_"; - histname += sumName; - } - // if (iamp > 0 && iamp < amphistname.size()) { - if (iamp < amphistname.size()) { - // get name of amp for naming histogram - histname += "_"; - histname += amphistname[iamp]; - } - - Histogram* hist = plotGen.projection(ivar, reactionName, iplot); - TH1* thist = hist->toRoot(); - thist->SetName(histname.c_str()); - if (iamp > 0 && iamp < amphistname.size()) plotfiledir->cd(); - else plotfile->cd(); - thist->Write(); - - } - } - } // end of loop over amplitudes - } // end of loop over sum configurations - }// end of loop over 'reactions' - - plotfile->Close(); - - - - // CALCULATE INTENSITY FRACTIONS AND PHASE DIFFERENCES - // All 'reactions' are already turned on - // The next calculations only need to happen one time - - // model parameters - cout << "Checking Parameters" << endl; - - // parameters to check - vector< string > pars; - - // pars.push_back("dsratio"); - - // file for writing parameters (later switch to putting in ROOT file) - ofstream outfile; - outfile.open( "vecps3pi__fitpars.txt" ); - - for(unsigned int i = 0; i fullamps = plotGen.fullAmplitudes(); - for (unsigned int i = 0; i < fullamps.size(); i++){ - vector useamp; - useamp.push_back(fullamps[i]); - outfile << "FIT FRACTION " << fullamps[i] << " = " - << results.intensity(useamp).first / - results.intensity().first << " +- " - << results.intensity(useamp).second / - results.intensity().first << endl; - } - - const int nAmps = amphistname.size(); - vector ampsumPosRefl[nAmps]; - vector ampsumNegRefl[nAmps]; - vector< pair > phaseDiffNames; - - for(unsigned int i = 0; i < fullamps.size(); i++){ - - // combine amplitudes with names defined above - for(int iamp=0; iamp phaseDiff = results.phaseDiff( phaseDiffNames[i].first, phaseDiffNames[i].second ); - outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " << phaseDiffNames[i].second << " " << phaseDiff.first << " " << phaseDiff.second << endl; - } - - - - - // covariance matrix - vector< vector< double > > covMatrix; - covMatrix = results.errorMatrix(); - */ - - - // ************************ - // start the GUI - // ************************ - - if(showGui) { - - cout << ">> Plot generator ready, starting GUI..." << endl; - - int dummy_argc = 0; - char* dummy_argv[] = {}; - TApplication app( "app", &dummy_argc, dummy_argv ); - - gStyle->SetFillColor(10); - gStyle->SetCanvasColor(10); - gStyle->SetPadColor(10); - gStyle->SetFillStyle(1001); - gStyle->SetPalette(1); - gStyle->SetFrameFillColor(10); - gStyle->SetFrameFillStyle(1001); - - cout << " Initialized App " << endl; - PlotFactory factory( plotGen ); - cout << " Created Plot Factory " << endl; - PlotterMainWindow mainFrame( gClient->GetRoot(), factory ); - cout << " Main frame created " << endl; - - app.Run(); - cout << " App running" << endl; - } - - return 0; - -} From 8b5a0a8f4a7047e99629d68d97a72c0fe3592a08 Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:47:11 +0200 Subject: [PATCH 27/33] Delete src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h --- .../AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h diff --git a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h b/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h deleted file mode 100644 index c7e6c4383..000000000 --- a/src/libraries/AMPTOOLS_DATAIO/VecPs3PiPlotGenerator.h +++ /dev/null @@ -1,36 +0,0 @@ -#if !(defined VECPS3PIPLOTGENERATOR) -#define VECPS3PIPLOTGENERATOR - -#include -#include - -#include "IUAmpTools/PlotGenerator.h" - -using namespace std; - -class FitResults; -class Kinematics; - -class VecPs3PiPlotGenerator : public PlotGenerator -{ - -public: - - // create an index for different histograms - enum { kProd_Ang = 0, kCosTheta = 1, kPhi = 2, kCosThetaH = 3, kPhiH = 4, kVecMass = 5, kVecPsMass = 6, kt = 7, kRecoilMass = 8, kProtonPsMass = 9, kRecoilPsMass = 10, kNumHists}; - - VecPs3PiPlotGenerator( const FitResults& results, Option opt); - VecPs3PiPlotGenerator( const FitResults& results ); - VecPs3PiPlotGenerator( ); - -private: - - void projectEvent( Kinematics* kin ); - void projectEvent( Kinematics* kin, const string& reactionName ); - - void createHistograms( ); - -}; - -#endif - From c433d3a37bec40a954b00e37ef9022b506f8d7e5 Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:49:21 +0200 Subject: [PATCH 28/33] Delete src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc --- .../vecps_plotter/vecps_plotter.cc | 438 ------------------ 1 file changed, 438 deletions(-) delete mode 100644 src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc diff --git a/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc b/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc deleted file mode 100644 index efbe83618..000000000 --- a/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc +++ /dev/null @@ -1,438 +0,0 @@ -#include -#include -#include -#include - -#include "AMPTOOLS_AMPS/BreitWigner.h" -#include "AMPTOOLS_AMPS/ComplexCoeff.h" -#include "AMPTOOLS_AMPS/OmegaDalitz.h" -#include "AMPTOOLS_AMPS/PhaseOffset.h" -#include "AMPTOOLS_AMPS/Piecewise.h" -#include "AMPTOOLS_AMPS/Uniform.h" -#include "AMPTOOLS_AMPS/Vec_ps_moment.h" -#include "AMPTOOLS_AMPS/Vec_ps_refl.h" -#include "AMPTOOLS_DATAIO/FSRootDataReader.h" -#include "AMPTOOLS_DATAIO/ROOTDataReader.h" -#include "AMPTOOLS_DATAIO/ROOTDataReaderBootstrap.h" -#include "AMPTOOLS_DATAIO/ROOTDataReaderTEM.h" -#include "AMPTOOLS_DATAIO/VecPsPlotGenerator.h" -#include "AmpPlotter/PlotFactory.h" -#include "AmpPlotter/PlotterMainWindow.h" -#include "IUAmpTools/AmpToolsInterface.h" -#include "IUAmpTools/ConfigFileParser.h" -#include "IUAmpTools/ConfigurationInfo.h" -#include "IUAmpTools/FitResults.h" -#include "MinuitInterface/MinuitMinimizationManager.h" -#include "TApplication.h" -#include "TClass.h" -#include "TFile.h" -#include "TGClient.h" -#include "TGraphErrors.h" -#include "TH1.h" -#include "TMultiGraph.h" -#include "TROOT.h" -#include "TStyle.h" - -typedef VecPsPlotGenerator vecps_PlotGen; - -void atiSetup() { - AmpToolsInterface::registerAmplitude(BreitWigner()); - AmpToolsInterface::registerAmplitude(Uniform()); - AmpToolsInterface::registerAmplitude(Vec_ps_refl()); - AmpToolsInterface::registerAmplitude(PhaseOffset()); - AmpToolsInterface::registerAmplitude(ComplexCoeff()); - AmpToolsInterface::registerAmplitude(Piecewise()); - AmpToolsInterface::registerAmplitude(OmegaDalitz()); - AmpToolsInterface::registerAmplitude(Vec_ps_moment()); - - AmpToolsInterface::registerDataReader(ROOTDataReader()); - AmpToolsInterface::registerDataReader(FSRootDataReader()); - AmpToolsInterface::registerDataReader(ROOTDataReaderTEM()); -} - -using namespace std; - -int main(int argc, char* argv[]) { - // ************************ - // usage - // ************************ - - cout << endl - << " *** Viewing Results Using AmpPlotter and writing root histograms " - "*** " - << endl - << endl; - - if (argc < 2) { - cout << "Usage:" << endl << endl; - cout << "\tvecps_plotter -o " - << endl - << endl; - return 0; - } - - bool showGui = false; - string outName = "vecps_plot.root"; - string resultsName(argv[1]); - for (int i = 2; i < argc; i++) { - string arg(argv[i]); - - if (arg == "-g") { - showGui = true; - } - if (arg == "-o") { - outName = argv[++i]; - } - if (arg == "-h") { - cout << endl << " Usage for: " << argv[0] << endl << endl; - cout << "\t -o \t output file path" << endl; - cout << "\t -g \t show GUI" << endl; - exit(1); - } - } - - // ************************ - // parse the command line parameters - // ************************ - - cout << "Fit results file name = " << resultsName << endl; - cout << "Output file name = " << outName << endl << endl; - - // ************************ - // load the results and display the configuration info - // ************************ - cout << "Initializing AmpTools interface..." << endl; - atiSetup(); - cout << "Interface initialized." << endl; - - cout << "Loading Fit results" << endl; - FitResults results(resultsName); - if (!results.valid()) { - cout << "Invalid fit results in file: " << resultsName << endl; - exit(1); - } - cout << "Fit results loaded" << endl; - // ************************ - // set up the plot generator - // ************************ - cout << "Plotgen results" << endl; - vecps_PlotGen plotGen(results, PlotGenerator::kNoGenMC); - cout << " Initialized ati and PlotGen" << endl; - - // ************************ - // set up an output ROOT file to store histograms - // ************************ - // Loop over different polarization files - // the default will remain to just use a single file - // ************************ - size_t nReactions = results.reactionList().size(); - for (unsigned int polFile = 0; polFile < nReactions; polFile++) { - - string reactionName = results.reactionList()[polFile]; - outName = reactionName + ".root"; - - TFile* plotfile = new TFile(outName.c_str(), "recreate"); - TH1::AddDirectory(kFALSE); - - plotGen.enableReaction(reactionName); - vector sums = plotGen.uniqueSums(); - vector amps = plotGen.uniqueAmplitudes(); - cout << "Reaction " << reactionName << " enabled with " << sums.size() - << " sums and " << amps.size() << " amplitudes" << endl; - - const vector amphistname = {"1S-1", "1S+0", "1S+1", "1S", - "1P-1", "1P+0", "1P+1", "1P", - "1D-1", "1D+0", "1D+1", "1D"}; - const vector reflname = {"PosRefl", "NegRefl"}; - - // loop over sum configurations (one for each of the individual - // contributions [when irefl < reflname.size()], and the combined sum - // of all [when irefl == reflname.size()]) - for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++) { - // loop over desired amplitudes (one for each of the individual - // contributions [when iamp < amphistname.size()], and the combined - // sum of all [when iamp == amphistname.size()]) - for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++) { - // turn all ampltiudes by default - for (unsigned int jamp = 0; jamp < amps.size(); jamp++) { - plotGen.enableAmp(jamp); - } - - // turn off unwanted amplitudes and sums - if (iamp < amphistname.size()) { - string locampname = amphistname[iamp]; - - // turn on all sums by default - for (unsigned int i = 0; i < sums.size(); i++) - plotGen.enableSum(i); - - // turn off unwanted sums for reflectivity (based on - // naturality) cout<<"refl = "<toRoot(); - thist->SetName(histname.c_str()); - plotfile->cd(); - thist->Write(); - } - } - } - } - - plotfile->Close(); - - // The next calculations only need to happen for the first file - // and we do not need to repeat for each polarization - if (polFile > 0) continue; - - // model parameters - cout << "Checking Parameters" << endl; - - // parameters to check - vector pars; - - pars.push_back("dsratio"); - - // file for writing parameters (later switch to putting in ROOT file) - ofstream outfile; - outfile.open("vecps_fitPars.txt"); - - for (unsigned int i = 0; i < pars.size(); i++) { - double parValue = results.parValue(pars[i]); - double parError = results.parError(pars[i]); - outfile << parValue << "\t" << parError << "\t" << endl; - } - - outfile << "TOTAL EVENTS = " << results.intensity().first << " +- " - << results.intensity().second << endl; - vector fullamps = plotGen.fullAmplitudes(); - for (unsigned int i = 0; i < fullamps.size(); i++) { - vector useamp; - useamp.push_back(fullamps[i]); - outfile << "FIT FRACTION " << fullamps[i] << " = " - << results.intensity(useamp).first / - results.intensity().first - << " +- " - << results.intensity(useamp).second / - results.intensity().first - << endl; - } - - const int nAmps = amphistname.size(); - vector ampsumPosRefl[nAmps]; - vector ampsumNegRefl[nAmps]; - vector > phaseDiffNames; - - for (unsigned int i = 0; i < fullamps.size(); i++) { - // combine amplitudes with names defined above - for (int iamp = 0; iamp < nAmps; iamp++) { - string locampname = amphistname[iamp]; - - if (fullamps[i].find("::" + locampname) == std::string::npos) - continue; - // cout< phaseDiff = results.phaseDiff( - phaseDiffNames[i].first, phaseDiffNames[i].second); - outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " - << phaseDiffNames[i].second << " " << phaseDiff.first << " " - << phaseDiff.second << endl; - } - } - - // covariance matrix - vector > covMatrix; - covMatrix = results.errorMatrix(); - - // ************************ - // start the GUI - // ************************ - - if (showGui) { - cout << ">> Plot generator ready, starting GUI..." << endl; - - int dummy_argc = 0; - char* dummy_argv[] = {}; - TApplication app("app", &dummy_argc, dummy_argv); - - gStyle->SetFillColor(10); - gStyle->SetCanvasColor(10); - gStyle->SetPadColor(10); - gStyle->SetFillStyle(1001); - gStyle->SetPalette(1); - gStyle->SetFrameFillColor(10); - gStyle->SetFrameFillStyle(1001); - - cout << " Initialized App " << endl; - PlotFactory factory(plotGen); - cout << " Created Plot Factory " << endl; - PlotterMainWindow mainFrame(gClient->GetRoot(), factory); - cout << " Main frame created " << endl; - - app.Run(); - cout << " App running" << endl; - } - - return 0; -} From 94d1a0b017115f79aa396aff2c6d58e41811edcc Mon Sep 17 00:00:00 2001 From: iljatt Date: Fri, 29 May 2026 15:55:24 +0200 Subject: [PATCH 29/33] Delete src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript --- .../vecps3pi_plotter/SConscript | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript diff --git a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript b/src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript deleted file mode 100644 index 7dcb10d85..000000000 --- a/src/programs/AmplitudeAnalysis/vecps3pi_plotter/SConscript +++ /dev/null @@ -1,22 +0,0 @@ - -import os -import sbms - -# get env object and clone it -Import('*') - -# Verify AMPTOOLS environment variable is set -if os.getenv('AMPTOOLS', 'nada')!='nada' and os.getenv('AMPPLOTTER', 'nada')!='nada': - - env = env.Clone() - - AMPTOOLS_LIBS = "AMPTOOLS_AMPS AMPTOOLS_DATAIO AMPTOOLS_MCGEN UTILITIES" - env.AppendUnique(LIBS = AMPTOOLS_LIBS.split()) - - sbms.AddHDDM(env) - sbms.AddAmpTools(env) - sbms.AddAmpPlotter(env) - sbms.AddUtilities(env) - sbms.AddROOT(env) - - sbms.executable(env) From 8b5a155cb41996ab7c61716930d4311078ab1e89 Mon Sep 17 00:00:00 2001 From: Alex Austregesilo Date: Fri, 29 May 2026 10:32:12 -0400 Subject: [PATCH 30/33] Revert "Delete src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc" This reverts commit c433d3a37bec40a954b00e37ef9022b506f8d7e5. --- .../vecps_plotter/vecps_plotter.cc | 438 ++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc diff --git a/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc b/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc new file mode 100644 index 000000000..efbe83618 --- /dev/null +++ b/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc @@ -0,0 +1,438 @@ +#include +#include +#include +#include + +#include "AMPTOOLS_AMPS/BreitWigner.h" +#include "AMPTOOLS_AMPS/ComplexCoeff.h" +#include "AMPTOOLS_AMPS/OmegaDalitz.h" +#include "AMPTOOLS_AMPS/PhaseOffset.h" +#include "AMPTOOLS_AMPS/Piecewise.h" +#include "AMPTOOLS_AMPS/Uniform.h" +#include "AMPTOOLS_AMPS/Vec_ps_moment.h" +#include "AMPTOOLS_AMPS/Vec_ps_refl.h" +#include "AMPTOOLS_DATAIO/FSRootDataReader.h" +#include "AMPTOOLS_DATAIO/ROOTDataReader.h" +#include "AMPTOOLS_DATAIO/ROOTDataReaderBootstrap.h" +#include "AMPTOOLS_DATAIO/ROOTDataReaderTEM.h" +#include "AMPTOOLS_DATAIO/VecPsPlotGenerator.h" +#include "AmpPlotter/PlotFactory.h" +#include "AmpPlotter/PlotterMainWindow.h" +#include "IUAmpTools/AmpToolsInterface.h" +#include "IUAmpTools/ConfigFileParser.h" +#include "IUAmpTools/ConfigurationInfo.h" +#include "IUAmpTools/FitResults.h" +#include "MinuitInterface/MinuitMinimizationManager.h" +#include "TApplication.h" +#include "TClass.h" +#include "TFile.h" +#include "TGClient.h" +#include "TGraphErrors.h" +#include "TH1.h" +#include "TMultiGraph.h" +#include "TROOT.h" +#include "TStyle.h" + +typedef VecPsPlotGenerator vecps_PlotGen; + +void atiSetup() { + AmpToolsInterface::registerAmplitude(BreitWigner()); + AmpToolsInterface::registerAmplitude(Uniform()); + AmpToolsInterface::registerAmplitude(Vec_ps_refl()); + AmpToolsInterface::registerAmplitude(PhaseOffset()); + AmpToolsInterface::registerAmplitude(ComplexCoeff()); + AmpToolsInterface::registerAmplitude(Piecewise()); + AmpToolsInterface::registerAmplitude(OmegaDalitz()); + AmpToolsInterface::registerAmplitude(Vec_ps_moment()); + + AmpToolsInterface::registerDataReader(ROOTDataReader()); + AmpToolsInterface::registerDataReader(FSRootDataReader()); + AmpToolsInterface::registerDataReader(ROOTDataReaderTEM()); +} + +using namespace std; + +int main(int argc, char* argv[]) { + // ************************ + // usage + // ************************ + + cout << endl + << " *** Viewing Results Using AmpPlotter and writing root histograms " + "*** " + << endl + << endl; + + if (argc < 2) { + cout << "Usage:" << endl << endl; + cout << "\tvecps_plotter -o " + << endl + << endl; + return 0; + } + + bool showGui = false; + string outName = "vecps_plot.root"; + string resultsName(argv[1]); + for (int i = 2; i < argc; i++) { + string arg(argv[i]); + + if (arg == "-g") { + showGui = true; + } + if (arg == "-o") { + outName = argv[++i]; + } + if (arg == "-h") { + cout << endl << " Usage for: " << argv[0] << endl << endl; + cout << "\t -o \t output file path" << endl; + cout << "\t -g \t show GUI" << endl; + exit(1); + } + } + + // ************************ + // parse the command line parameters + // ************************ + + cout << "Fit results file name = " << resultsName << endl; + cout << "Output file name = " << outName << endl << endl; + + // ************************ + // load the results and display the configuration info + // ************************ + cout << "Initializing AmpTools interface..." << endl; + atiSetup(); + cout << "Interface initialized." << endl; + + cout << "Loading Fit results" << endl; + FitResults results(resultsName); + if (!results.valid()) { + cout << "Invalid fit results in file: " << resultsName << endl; + exit(1); + } + cout << "Fit results loaded" << endl; + // ************************ + // set up the plot generator + // ************************ + cout << "Plotgen results" << endl; + vecps_PlotGen plotGen(results, PlotGenerator::kNoGenMC); + cout << " Initialized ati and PlotGen" << endl; + + // ************************ + // set up an output ROOT file to store histograms + // ************************ + // Loop over different polarization files + // the default will remain to just use a single file + // ************************ + size_t nReactions = results.reactionList().size(); + for (unsigned int polFile = 0; polFile < nReactions; polFile++) { + + string reactionName = results.reactionList()[polFile]; + outName = reactionName + ".root"; + + TFile* plotfile = new TFile(outName.c_str(), "recreate"); + TH1::AddDirectory(kFALSE); + + plotGen.enableReaction(reactionName); + vector sums = plotGen.uniqueSums(); + vector amps = plotGen.uniqueAmplitudes(); + cout << "Reaction " << reactionName << " enabled with " << sums.size() + << " sums and " << amps.size() << " amplitudes" << endl; + + const vector amphistname = {"1S-1", "1S+0", "1S+1", "1S", + "1P-1", "1P+0", "1P+1", "1P", + "1D-1", "1D+0", "1D+1", "1D"}; + const vector reflname = {"PosRefl", "NegRefl"}; + + // loop over sum configurations (one for each of the individual + // contributions [when irefl < reflname.size()], and the combined sum + // of all [when irefl == reflname.size()]) + for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++) { + // loop over desired amplitudes (one for each of the individual + // contributions [when iamp < amphistname.size()], and the combined + // sum of all [when iamp == amphistname.size()]) + for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++) { + // turn all ampltiudes by default + for (unsigned int jamp = 0; jamp < amps.size(); jamp++) { + plotGen.enableAmp(jamp); + } + + // turn off unwanted amplitudes and sums + if (iamp < amphistname.size()) { + string locampname = amphistname[iamp]; + + // turn on all sums by default + for (unsigned int i = 0; i < sums.size(); i++) + plotGen.enableSum(i); + + // turn off unwanted sums for reflectivity (based on + // naturality) cout<<"refl = "<toRoot(); + thist->SetName(histname.c_str()); + plotfile->cd(); + thist->Write(); + } + } + } + } + + plotfile->Close(); + + // The next calculations only need to happen for the first file + // and we do not need to repeat for each polarization + if (polFile > 0) continue; + + // model parameters + cout << "Checking Parameters" << endl; + + // parameters to check + vector pars; + + pars.push_back("dsratio"); + + // file for writing parameters (later switch to putting in ROOT file) + ofstream outfile; + outfile.open("vecps_fitPars.txt"); + + for (unsigned int i = 0; i < pars.size(); i++) { + double parValue = results.parValue(pars[i]); + double parError = results.parError(pars[i]); + outfile << parValue << "\t" << parError << "\t" << endl; + } + + outfile << "TOTAL EVENTS = " << results.intensity().first << " +- " + << results.intensity().second << endl; + vector fullamps = plotGen.fullAmplitudes(); + for (unsigned int i = 0; i < fullamps.size(); i++) { + vector useamp; + useamp.push_back(fullamps[i]); + outfile << "FIT FRACTION " << fullamps[i] << " = " + << results.intensity(useamp).first / + results.intensity().first + << " +- " + << results.intensity(useamp).second / + results.intensity().first + << endl; + } + + const int nAmps = amphistname.size(); + vector ampsumPosRefl[nAmps]; + vector ampsumNegRefl[nAmps]; + vector > phaseDiffNames; + + for (unsigned int i = 0; i < fullamps.size(); i++) { + // combine amplitudes with names defined above + for (int iamp = 0; iamp < nAmps; iamp++) { + string locampname = amphistname[iamp]; + + if (fullamps[i].find("::" + locampname) == std::string::npos) + continue; + // cout< phaseDiff = results.phaseDiff( + phaseDiffNames[i].first, phaseDiffNames[i].second); + outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " + << phaseDiffNames[i].second << " " << phaseDiff.first << " " + << phaseDiff.second << endl; + } + } + + // covariance matrix + vector > covMatrix; + covMatrix = results.errorMatrix(); + + // ************************ + // start the GUI + // ************************ + + if (showGui) { + cout << ">> Plot generator ready, starting GUI..." << endl; + + int dummy_argc = 0; + char* dummy_argv[] = {}; + TApplication app("app", &dummy_argc, dummy_argv); + + gStyle->SetFillColor(10); + gStyle->SetCanvasColor(10); + gStyle->SetPadColor(10); + gStyle->SetFillStyle(1001); + gStyle->SetPalette(1); + gStyle->SetFrameFillColor(10); + gStyle->SetFrameFillStyle(1001); + + cout << " Initialized App " << endl; + PlotFactory factory(plotGen); + cout << " Created Plot Factory " << endl; + PlotterMainWindow mainFrame(gClient->GetRoot(), factory); + cout << " Main frame created " << endl; + + app.Run(); + cout << " App running" << endl; + } + + return 0; +} From 426271cc52e35be420aa0bd165814df1f520df10 Mon Sep 17 00:00:00 2001 From: Alex Austregesilo Date: Fri, 29 May 2026 10:36:04 -0400 Subject: [PATCH 31/33] revert to master --- .../vecps_plotter/vecps_plotter.cc | 1354 +++++++++++++---- 1 file changed, 1028 insertions(+), 326 deletions(-) diff --git a/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc b/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc index efbe83618..8d1c44e99 100644 --- a/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc +++ b/src/programs/AmplitudeAnalysis/vecps_plotter/vecps_plotter.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "AMPTOOLS_AMPS/BreitWigner.h" #include "AMPTOOLS_AMPS/ComplexCoeff.h" @@ -50,371 +51,1044 @@ void atiSetup() { AmpToolsInterface::registerDataReader(ROOTDataReaderTEM()); } -using namespace std; +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... +// Enum Classes to Simplify Boolean Logic +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... -int main(int argc, char* argv[]) { - // ************************ - // usage - // ************************ +// Classify the sum of the reaction according to reflectivity +enum class ReflSum { + Neither, // something like an incoherent background sum + Positive, + Negative +}; - cout << endl - << " *** Viewing Results Using AmpPlotter and writing root histograms " - "*** " - << endl - << endl; +// Specify the group of amplitudes to be plotted +enum class AmpPlotGroup{ + AllAmps, // for the total fit result + AllReflAmps, // for the total refl + JlFamily, // sum over the m projections + SingleAmp // one amplitude at a time +}; - if (argc < 2) { - cout << "Usage:" << endl << endl; - cout << "\tvecps_plotter -o " - << endl - << endl; - return 0; - } +// Specify the group of sums to be plotted +enum class SumPlotGroup{ + AllSums, // for the total fit results + BothReflSums, // Incoherent sum of both reflectivities + PosReflSum, // one coherent sum + NegReflSum, // one coherent sum + NoReflSum // This could be broken down for multiple non-refl sums +}; +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... +// Structures to Gather Relevant Info Together +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... + +// Store the information from the command line arguments and configuration file +// and allows to easily change the default values of the options +// TODO: add an option for only GUI mode (aka no root file output) +struct ProgramOptions{ + std::string resultsName; + std::string outName = "vecps_plot.root"; bool showGui = false; - string outName = "vecps_plot.root"; - string resultsName(argv[1]); - for (int i = 2; i < argc; i++) { - string arg(argv[i]); + bool mcGen = false; + bool bkgFile = false; + bool sFile = false; + bool skipPlots = false; + bool txtOutput = false; + bool csvOutput = false; +}; - if (arg == "-g") { - showGui = true; - } - if (arg == "-o") { - outName = argv[++i]; - } - if (arg == "-h") { - cout << endl << " Usage for: " << argv[0] << endl << endl; - cout << "\t -o \t output file path" << endl; - cout << "\t -g \t show GUI" << endl; - exit(1); - } +// Store the information needed to identify a wave +struct WaveKey { + std::string ampName; // full amp name (e.g. 1S+1) + std::string jFamily; // Jl family (e.g. 1S) + std::string m; // m projection (e.g. +1) + bool isNumeric; // non-Jl amps do not start with a number +}; + +// Store all the information that identifies an amplitude +struct AmplitudeKey { + std::string fullName; // unparsed AmpTools full name + std::string reactionName; + std::string sumName; + ReflSum reflSum; // Pos/neg refl or neither + WaveKey key; + + // index in uniqueAmplitudes() + size_t ampIndex = std::numeric_limits::max(); + // index in uniqueSums() + size_t sumIndex = std::numeric_limits::max(); +}; + +// Store all the relation between the unique sums and unique amps +// could be extended to global (between reactions) relations +struct Sisterhood{ + // maps to look up the indices of the unique amplitudes and sums + // the key is the string/enum name of the amplitude/sum + std::map> jlIndexMap; + std::map> sumIndexMap; + + // Relationship between sums and each amplitude (index-based) + std::vector> ampToSums; + std::vector> sumToAmps; + // Note: amplitudes that do not have refl are not in the following map + std::map> reflToAmps; + + // Relations for amplitudes based on the full name + std::vector> ampToFull; // uniqueAmp to full indices + std::vector> sumToFull; // uniqueSum to full indices + std::map> reflToFull; + std::map, std::vector> ampReflToFull; + std::map, std::vector> jlReflToFull; +}; + +// Store the information that is static when a reaction is read +// this structure avoids having to parse the string information again +// and it becomes a look up table for the indices of the amplitudes and +// sums when plotting +struct AmplitudeRegistry { + // Collection of all of the amplitudes in the fit file + std::vector ampsList; + + // Parsed unique amplitudes + std::vector uniqueAmps; + size_t nUnqAmps; + // Parsed unique sums + std::vector uniqueSums; + size_t nUnqSums; + // containers to look up the indices of the unique amplitudes and sums + // and their relation to other sums/amps + Sisterhood relations; +}; + +// This stores the specific configuration for a plotting +struct PlotConfig{ + AmpPlotGroup ampGroup; + SumPlotGroup sumGroup; + + // Store the indices to be enable + std::vector ampIndices; + std::vector sumIndices; +}; + +struct PlotLabels{ + std::string human; // human friendly output + std::string histName; // better for saving in a ROOT file + // TODO: add csv format + // std::string csvFormat; // better for saving in a CSV file +}; + +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... +// Helper Functions to Fill the Structures, etc +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... + +// Parse the name of the sum to classify it according to reflectivity +// Note: this follow standard naming conventions for the vec_ps amplitudes +// this means that: +// [ImagNegSign & RealPosSign] = Negative Reflectivity +// [RealNegSign & ImagPosSign] = Positive Reflectivity +// The 3rd option is "Neither", but it can be easily expanded if needed +// dont forget to update the ReflSum enum if you do! +// General naming convention for amps: +// https://halldweb.jlab.org/doc-private/DocDB/ShowDocument?docid=7036 +ReflSum classifyReflSum(const std::string& sumName){ + if (sumName.find("RealNegSign") != std::string::npos || + sumName.find("ImagPosSign") != std::string::npos){ + return ReflSum::Positive; } + else if (sumName.find("RealPosSign") != std::string::npos || + sumName.find("ImagNegSign") != std::string::npos){ + return ReflSum::Negative; + } + else { + return ReflSum::Neither; + } +} - // ************************ - // parse the command line parameters - // ************************ +std::string reflToString(ReflSum r){ + switch(r){ + case ReflSum::Positive: return "PosRefl"; + case ReflSum::Negative: return "NegRefl"; + default: return "Neither"; + } +} - cout << "Fit results file name = " << resultsName << endl; - cout << "Output file name = " << outName << endl << endl; +// Store in a vector the different parts of the full amplitude name, given +// the common delimiter used in AmpTools (::) +std::vector breakDownName(const std::string& fullAmpName, + const std::string& delim){ + std::vector brokenDownName; + size_t start = 0; size_t end; - // ************************ - // load the results and display the configuration info - // ************************ - cout << "Initializing AmpTools interface..." << endl; - atiSetup(); - cout << "Interface initialized." << endl; + while((end = fullAmpName.find(delim, start)) != std::string::npos){ + brokenDownName.push_back(fullAmpName.substr(start, end-start)); + start = end + delim.size(); + } + + brokenDownName.push_back(fullAmpName.substr(start)); + return brokenDownName; +} - cout << "Loading Fit results" << endl; - FitResults results(resultsName); - if (!results.valid()) { - cout << "Invalid fit results in file: " << resultsName << endl; - exit(1); +WaveKey getJlm(const std::string& ampName){ + WaveKey key; + key.ampName = ampName; + // For the standard format "Jl.m" (e.g. "1S+1") + // it splits the m-projection and the Jl family + key.isNumeric = std::isdigit(ampName[0]); + if (!ampName.empty() && key.isNumeric){ + key.jFamily = ampName.substr(0, 2); + key.m = ampName.substr(2); } - cout << "Fit results loaded" << endl; - // ************************ - // set up the plot generator - // ************************ - cout << "Plotgen results" << endl; - vecps_PlotGen plotGen(results, PlotGenerator::kNoGenMC); - cout << " Initialized ati and PlotGen" << endl; - - // ************************ - // set up an output ROOT file to store histograms - // ************************ - // Loop over different polarization files - // the default will remain to just use a single file - // ************************ - size_t nReactions = results.reactionList().size(); - for (unsigned int polFile = 0; polFile < nReactions; polFile++) { - - string reactionName = results.reactionList()[polFile]; - outName = reactionName + ".root"; - - TFile* plotfile = new TFile(outName.c_str(), "recreate"); - TH1::AddDirectory(kFALSE); - - plotGen.enableReaction(reactionName); - vector sums = plotGen.uniqueSums(); - vector amps = plotGen.uniqueAmplitudes(); - cout << "Reaction " << reactionName << " enabled with " << sums.size() - << " sums and " << amps.size() << " amplitudes" << endl; - - const vector amphistname = {"1S-1", "1S+0", "1S+1", "1S", - "1P-1", "1P+0", "1P+1", "1P", - "1D-1", "1D+0", "1D+1", "1D"}; - const vector reflname = {"PosRefl", "NegRefl"}; - - // loop over sum configurations (one for each of the individual - // contributions [when irefl < reflname.size()], and the combined sum - // of all [when irefl == reflname.size()]) - for (unsigned int irefl = 0; irefl <= reflname.size(); irefl++) { - // loop over desired amplitudes (one for each of the individual - // contributions [when iamp < amphistname.size()], and the combined - // sum of all [when iamp == amphistname.size()]) - for (unsigned int iamp = 0; iamp <= amphistname.size(); iamp++) { - // turn all ampltiudes by default - for (unsigned int jamp = 0; jamp < amps.size(); jamp++) { - plotGen.enableAmp(jamp); - } + else { + key.jFamily = ""; + key.m = ""; + } + return key; +} - // turn off unwanted amplitudes and sums - if (iamp < amphistname.size()) { - string locampname = amphistname[iamp]; - - // turn on all sums by default - for (unsigned int i = 0; i < sums.size(); i++) - plotGen.enableSum(i); - - // turn off unwanted sums for reflectivity (based on - // naturality) cout<<"refl = "< tokens = breakDownName(fullAmpName, "::"); + + // Expect exactly 3 tokens: + // [reaction] :: [sum] :: [ampName] + if (tokens.size() != 3){ + std::cerr << "Warning: Unexpected amplitude name format: " + << fullAmpName << "\n"; + ampKey.reactionName = ""; + ampKey.sumName = ""; + ampKey.key.jFamily = ""; + ampKey.key.m = ""; + } + else { + ampKey.reactionName = tokens[0]; + ampKey.sumName = tokens[1]; + ampKey.key = getJlm(tokens[2]); + } + ampKey.reflSum = classifyReflSum(ampKey.sumName); + + return ampKey; +} + +// Just a reminder that the registry is meant to be once per file, and +// it serves as a look up table for everything related to the amps +AmplitudeRegistry buildRegistry(std::unique_ptr& plotResults){ + AmplitudeRegistry registry; + + std::vector uniqueAmps = plotResults->uniqueAmplitudes(); + registry.nUnqAmps = uniqueAmps.size(); + std::vector uniqueSums = plotResults->uniqueSums(); + registry.nUnqSums = uniqueSums.size(); + + // Look up maps for parsed info + std::map ampNameToIndex; + std::map sumNameToIndex; + + std::vector uniqueAmpsParsed; + for (size_t i = 0; i < uniqueAmps.size(); ++i){ + ampNameToIndex[uniqueAmps[i]] = i; + WaveKey key = getJlm(uniqueAmps[i]); + uniqueAmpsParsed.push_back(key); + if(!key.jFamily.empty()) // non-numeric amps have and empty jFamily + registry.relations.jlIndexMap[key.jFamily].push_back(i); + } + registry.uniqueAmps = uniqueAmpsParsed; + + std::vector uniqueSumsParsed; + for (size_t i = 0; i < uniqueSums.size(); ++i){ + sumNameToIndex[uniqueSums[i]] = i; + ReflSum refl = classifyReflSum(uniqueSums[i]); + uniqueSumsParsed.push_back(refl); + registry.relations.sumIndexMap[refl].push_back(i); + } + registry.uniqueSums = uniqueSumsParsed; + + std::vector parsedAmps; + for (const auto& amp : plotResults->fullAmplitudes()){ + AmplitudeKey ampKey = parseAmp(amp); + ampKey.ampIndex = ampNameToIndex[ampKey.key.ampName]; + ampKey.sumIndex = sumNameToIndex[ampKey.sumName]; + ampKey.reflSum = classifyReflSum(ampKey.sumName); + parsedAmps.push_back(ampKey); + } + registry.ampsList = parsedAmps; + + // Sisterhood vectors + std::vector> ampToSums(registry.nUnqAmps); + std::vector> sumToAmps(registry.nUnqSums); + std::map> reflToAmps; + + // Sisterhood vectors for full reference + std::vector> ampToFull(registry.nUnqAmps); + std::vector> sumToFull(registry.nUnqSums); + std::map> reflToFull; + std::map, std::vector> ampReflToFull; + std::map, std::vector> jlReflToFull; + + for(size_t iFull = 0; iFull < registry.ampsList.size(); ++iFull){ + const auto& amp = registry.ampsList[iFull]; + size_t ampIndex = amp.ampIndex; + size_t sumIndex = amp.sumIndex; + + auto& amp2Sum = ampToSums[ampIndex]; + if(std::find(amp2Sum.begin(), amp2Sum.end(), sumIndex) == amp2Sum.end()) + amp2Sum.push_back(sumIndex); + + auto& sum2Amp = sumToAmps[sumIndex]; + if(std::find(sum2Amp.begin(), sum2Amp.end(), ampIndex) == sum2Amp.end()) + sum2Amp.push_back(ampIndex); + + auto& refl2Amp = reflToAmps[amp.reflSum]; + if(std::find(refl2Amp.begin(), refl2Amp.end(), ampIndex) == refl2Amp.end()) + refl2Amp.push_back(ampIndex); + + ampToFull[amp.ampIndex].push_back(iFull); + sumToFull[amp.sumIndex].push_back(iFull); + reflToFull[amp.reflSum].push_back(iFull); + + ampReflToFull[{ampIndex, amp.reflSum}].push_back(iFull); + if(!amp.key.jFamily.empty()) + jlReflToFull[{amp.key.jFamily, amp.reflSum}].push_back(iFull); + } + + registry.relations.ampToSums = ampToSums; + registry.relations.sumToAmps = sumToAmps; + registry.relations.reflToAmps = reflToAmps; - // turn off unwanted amplitudes - for (unsigned int jamp = 0; jamp < amps.size(); jamp++) { - if (amps[jamp].find(locampname.data()) == - std::string::npos) { - plotGen.disableAmp(jamp); - // cout<<"disable amplitude "<& amps, + const std::vector& sums, + const Sisterhood& rel){ + if(amps.empty() || sums.empty()) + return false; + + std::unordered_set sumSet(sums.begin(), sums.end()); + for(size_t a : amps){ + for(size_t s : rel.ampToSums[a]){ + if(sumSet.count(s)) + return true; + } + } + return false; +} + +// The vector that this function outputs contains all the configurations that +// are allowed by the enum classes defined above with the caveat that we +// screen for "physically meaningful" combinations in isNonEmptyConfig() +std::vector generatePlotConfigs(const AmplitudeRegistry& reg){ + std::vector configs; + std::cout << reg.uniqueAmps.size() << " unique amps and " + << reg.uniqueSums.size() << " unique sums." << std::endl; + + const std::vector ampGroups = { + AmpPlotGroup::AllAmps, + AmpPlotGroup::AllReflAmps, + AmpPlotGroup::SingleAmp, + AmpPlotGroup::JlFamily + }; + + const std::vector sumGroups = { + SumPlotGroup::AllSums, + SumPlotGroup::PosReflSum, + SumPlotGroup::NegReflSum, + SumPlotGroup::NoReflSum, + SumPlotGroup::BothReflSums + }; + + std::vector allAmpIndices(reg.nUnqAmps); + std::iota(allAmpIndices.begin(), allAmpIndices.end(), 0); + + std::vector allSumIndices(reg.nUnqSums); + std::iota(allSumIndices.begin(), allSumIndices.end(), 0); + + // Extract the relation from the registry + const auto& rel = reg.relations; + + // These vector is meant to be used with AllReflAmps. Note that generally + // both Positive and Negative share the same wave. But there are situations + // where only one refl is present. So, it's safer to loop over both and + // then remove duplicates + std::vector reflAmps; + if(rel.reflToAmps.count(ReflSum::Positive)) + reflAmps.insert(reflAmps.end(), + rel.reflToAmps.at(ReflSum::Positive).begin(), + rel.reflToAmps.at(ReflSum::Positive).end()); + + if(rel.reflToAmps.count(ReflSum::Negative)) + reflAmps.insert(reflAmps.end(), + rel.reflToAmps.at(ReflSum::Negative).begin(), + rel.reflToAmps.at(ReflSum::Negative).end()); + + // Remove duplicates + std::sort(reflAmps.begin(), reflAmps.end()); + reflAmps.erase(std::unique(reflAmps.begin(), reflAmps.end()), reflAmps.end()); + + // To build all possible combinations we need to loop according to the + // following logic: (AmpPlotGroup × SumPlotGroup) × (ampSets × sumSets) + // the first group, (AmpPlotGroup × SumPlotGroup), tell us what type of + // plot we want; while the second group, (ampSets × sumSets), tell us which + // amplitudes and sums to include in the plot + for(auto aGroup : ampGroups){ + + std::vector> ampSets; + + // build ampSets + switch(aGroup){ + case AmpPlotGroup::AllAmps: + ampSets.push_back(allAmpIndices); + break; + + case AmpPlotGroup::AllReflAmps: + ampSets.push_back(reflAmps); + break; + + case AmpPlotGroup::SingleAmp: + for(size_t i : allAmpIndices) + ampSets.push_back({i}); + break; + + case AmpPlotGroup::JlFamily: + for(const auto& [jl, indices] : rel.jlIndexMap) + ampSets.push_back(indices); + break; + } + + for(auto sGroup : sumGroups){ + // AmpPlotGroup::AllAmps can only be with SumPlotGroup::AllSums + if ((aGroup == AmpPlotGroup::AllAmps) != + (sGroup == SumPlotGroup::AllSums)) + continue; + + // AmpPlotGroup::AllReflAmps can only be with + // SumPlotGroup::PosReflSum, SumPlotGroup::NegReflSum, or + // SumPlotGroup::BothReflSums + if (aGroup == AmpPlotGroup::AllReflAmps) { + if (!(sGroup == SumPlotGroup::PosReflSum || + sGroup == SumPlotGroup::NegReflSum || + sGroup == SumPlotGroup::BothReflSums)) + continue; + } + + std::vector> sumSets; + + // build sumSets + switch(sGroup){ + case SumPlotGroup::AllSums: + sumSets.push_back(allSumIndices); + break; + + case SumPlotGroup::PosReflSum: + if(rel.sumIndexMap.count(ReflSum::Positive)) + sumSets.push_back(rel.sumIndexMap.at(ReflSum::Positive)); + break; + + case SumPlotGroup::NegReflSum: + if(rel.sumIndexMap.count(ReflSum::Negative)) + sumSets.push_back(rel.sumIndexMap.at(ReflSum::Negative)); + break; + + case SumPlotGroup::NoReflSum: + if(rel.sumIndexMap.count(ReflSum::Neither)) + sumSets.push_back(rel.sumIndexMap.at(ReflSum::Neither)); + break; + + case SumPlotGroup::BothReflSums:{ + std::vector posNeg; + + if(rel.sumIndexMap.count(ReflSum::Positive)){ + posNeg.insert(posNeg.end(), + rel.sumIndexMap.at(ReflSum::Positive).begin(), + rel.sumIndexMap.at(ReflSum::Positive).end()); + } + if(rel.sumIndexMap.count(ReflSum::Negative)){ + posNeg.insert(posNeg.end(), + rel.sumIndexMap.at(ReflSum::Negative).begin(), + rel.sumIndexMap.at(ReflSum::Negative).end()); } + sumSets.push_back(posNeg); + break; } + } - cout << "Looping over input data" << endl; - // loop over data, accMC, and genMC - for (unsigned int iplot = 0; iplot < PlotGenerator::kNumTypes; - iplot++) { - if (iplot == PlotGenerator::kGenMC || - iplot == PlotGenerator::kBkgnd) - continue; - bool singleData = - irefl == reflname.size() && iamp == amphistname.size(); - if (iplot == PlotGenerator::kData && !singleData) - continue; // only plot data once - - // loop over different variables - for (unsigned int ivar = 0; - ivar < VecPsPlotGenerator::kNumHists; ivar++) { - // set unique histogram name for each plot (could put in - // directories...) - string histname = ""; - if (ivar == VecPsPlotGenerator::kVecPsMass) - histname += "MVecPs"; - else if (ivar == VecPsPlotGenerator::kCosTheta) - histname += "CosTheta"; - else if (ivar == VecPsPlotGenerator::kPhi) - histname += "Phi"; - else if (ivar == VecPsPlotGenerator::kCosThetaH) - histname += "CosTheta_H"; - else if (ivar == VecPsPlotGenerator::kPhiH) - histname += "Phi_H"; - else if (ivar == VecPsPlotGenerator::kProd_Ang) - histname += "Prod_Ang"; - else if (ivar == VecPsPlotGenerator::kt) - histname += "t"; - else if (ivar == VecPsPlotGenerator::kRecoilMass) - histname += "MRecoil"; - else if (ivar == VecPsPlotGenerator::kProtonPsMass) - histname += "MProtonPs"; - else if (ivar == VecPsPlotGenerator::kRecoilPsMass) - histname += "MRecoilPs"; - else if (ivar == VecPsPlotGenerator::kLambda) - histname += "Lambda"; - else if (ivar == VecPsPlotGenerator::kDalitz) - histname += "Dalitz"; - else if (ivar == VecPsPlotGenerator::kPhi_ProdVsPhi) - histname += "Phi_ProdVsPhi"; - else if (ivar == VecPsPlotGenerator::kPhiOffsetVsPhi) - histname += "PhiOffsetVsPhi"; - else - continue; - - if (iplot == PlotGenerator::kData) histname += "dat"; - if (iplot == PlotGenerator::kBkgnd) histname += "bkgnd"; - if (iplot == PlotGenerator::kAccMC) histname += "acc"; - if (iplot == PlotGenerator::kGenMC) histname += "gen"; - - if (irefl < reflname.size()) { - // get name of sum for naming histogram - string sumName = reflname[irefl]; - histname += "_"; - histname += sumName; - } - if (iamp < amphistname.size()) { - // get name of amp for naming histogram - histname += "_"; - histname += amphistname[iamp]; - } - - Histogram* hist = - plotGen.projection(ivar, reactionName, iplot); - TH1* thist = hist->toRoot(); - thist->SetName(histname.c_str()); - plotfile->cd(); - thist->Write(); - } + // Use the sets to build amp x sum combinations + for(const auto& amps : ampSets){ + for(const auto& sums : sumSets){ + if(!isNonEmptyConfig(amps, sums, rel)) continue; + configs.push_back({aGroup, sGroup, amps, sums}); } } } + } + return configs; +} - plotfile->Close(); +// Rather than reseting the active amps/sums, +// this function checks the active status for them and changes what's needed. +void applyConfig(const PlotConfig& newConfig, const AmplitudeRegistry& reg, + std::unique_ptr& plotResults){ + // Initialize a vector with all entries as false and flip to true the + // indices for the amps that need to be active + std::vector newAmps(reg.nUnqAmps,false); + for(auto a : newConfig.ampIndices) newAmps[a] = true; - // The next calculations only need to happen for the first file - // and we do not need to repeat for each polarization - if (polFile > 0) continue; - - // model parameters - cout << "Checking Parameters" << endl; + for(size_t i=0;iisAmpEnabled(i) && !newAmps[i]) + plotResults->disableAmp(i); + if(!plotResults->isAmpEnabled(i) && newAmps[i]) + plotResults->enableAmp(i); + } - // parameters to check - vector pars; + // Initialize a vector with all entries as false and flip to true the + // indices for the sums that need to be active + std::vector newSums(reg.nUnqSums,false); + for(auto s : newConfig.sumIndices) newSums[s] = true; - pars.push_back("dsratio"); + for(size_t i=0;iisSumEnabled(i) && !newSums[i]) + plotResults->disableSum(i); + if(!plotResults->isSumEnabled(i) && newSums[i]) + plotResults->enableSum(i); + } +} - // file for writing parameters (later switch to putting in ROOT file) - ofstream outfile; - outfile.open("vecps_fitPars.txt"); +PlotLabels makeLabel(const PlotConfig& cfg, const AmplitudeRegistry& reg){ + PlotLabels labels; + std::string amp; + std::string sum; - for (unsigned int i = 0; i < pars.size(); i++) { - double parValue = results.parValue(pars[i]); - double parError = results.parError(pars[i]); - outfile << parValue << "\t" << parError << "\t" << endl; + switch(cfg.ampGroup){ + case AmpPlotGroup::AllAmps: + amp = "All"; + break; + + case AmpPlotGroup::AllReflAmps: + amp = "AllRefl"; + break; + + case AmpPlotGroup::SingleAmp:{ + const auto& ampKey = reg.uniqueAmps[cfg.ampIndices[0]]; + amp = ampKey.ampName; + break; } - outfile << "TOTAL EVENTS = " << results.intensity().first << " +- " - << results.intensity().second << endl; - vector fullamps = plotGen.fullAmplitudes(); - for (unsigned int i = 0; i < fullamps.size(); i++) { - vector useamp; - useamp.push_back(fullamps[i]); - outfile << "FIT FRACTION " << fullamps[i] << " = " - << results.intensity(useamp).first / - results.intensity().first - << " +- " - << results.intensity(useamp).second / - results.intensity().first - << endl; + case AmpPlotGroup::JlFamily:{ + const auto& ampKey = reg.uniqueAmps[cfg.ampIndices[0]]; + amp = ampKey.jFamily; + break; } + } - const int nAmps = amphistname.size(); - vector ampsumPosRefl[nAmps]; - vector ampsumNegRefl[nAmps]; - vector > phaseDiffNames; + switch(cfg.sumGroup){ + case SumPlotGroup::AllSums: + sum = "Full"; + break; - for (unsigned int i = 0; i < fullamps.size(); i++) { - // combine amplitudes with names defined above - for (int iamp = 0; iamp < nAmps; iamp++) { - string locampname = amphistname[iamp]; + case SumPlotGroup::PosReflSum: + sum = "posRefl"; + break; - if (fullamps[i].find("::" + locampname) == std::string::npos) - continue; - // cout<& plotResults, + const std::string& reactionName, + const TFile& plotFile, bool& singleData, + const PlotConfig& cfg, const PlotLabels& cfgLabel){ + // std::cout << "Creating plots for: " << cfgLabel.human << std::endl; + // Loop over data types + for (unsigned int iType = 0; iType < PlotGenerator::kNumTypes; ++iType){ + if (!options.bkgFile && iType == PlotGenerator::kBkgnd) continue; + + if (iType == PlotGenerator::kData){ + if(!singleData) singleData = true; + else if(singleData) continue; // only plot data once } - for (int i = 0; i < nAmps; i++) { - if (ampsumPosRefl[i].empty()) continue; - outfile << "FIT FRACTION (coherent sum) PosRefl " << amphistname[i] - << " = " - << results.intensity(ampsumPosRefl[i]).first / - results.intensity().first - << " +- " - << results.intensity(ampsumPosRefl[i]).second / - results.intensity().first - << endl; - outfile << "FIT FRACTION (coherent sum) NegRefl " << amphistname[i] - << " = " - << results.intensity(ampsumNegRefl[i]).first / - results.intensity().first - << " +- " - << results.intensity(ampsumNegRefl[i]).second / - results.intensity().first - << endl; + std::string dataType; + switch (iType) { + case PlotGenerator::kData: dataType = "dat"; break; + case PlotGenerator::kAccMC: dataType = "acc"; break; + case PlotGenerator::kGenMC: dataType = "gen"; break; + case PlotGenerator::kBkgnd: dataType = "bkgnd"; break; + default: continue; } - cout << "Computing phase differences" << endl; - for (unsigned int i = 0; i < phaseDiffNames.size(); i++) { - pair phaseDiff = results.phaseDiff( - phaseDiffNames[i].first, phaseDiffNames[i].second); - outfile << "PHASE DIFF " << phaseDiffNames[i].first << " " - << phaseDiffNames[i].second << " " << phaseDiff.first << " " - << phaseDiff.second << endl; + // Loop over all histograms defined in VecPsPlotGenerator + // The loop variable should be defined using the first entry in the + // enum, in this case kVecPsMass (change if needed). The last one is + // kNumHists and this one should not change + for (VecPsPlotGenerator::Hist_index ivar = VecPsPlotGenerator::kVecPsMass; + ivar < VecPsPlotGenerator::kNumHists; + ivar = static_cast(ivar + 1)){ + Histogram* hist = plotResults->projection(ivar, reactionName, iType); + if (!hist) continue; // safety skip + TH1* histRoot = hist->toRoot(); + + // Assign proper names to each histogram. Note that the names + // and the translation table are defined in VecPsPlotGenerator + std::string histName = VecPsPlotGenerator::numToString(ivar); + + if(!(iType==PlotGenerator::kData)) + histName += "_" + dataType + cfgLabel.histName; + histRoot->SetName(histName.c_str()); + histRoot->Write(); + } + } + +} + +// This function output a semi-human readable text file with the fit fractions +// and phase differences between amplitudes. It has some patterns to help +// parsing, but csv file might be preferred for that purpose. +// Note: the default behavior is the acceptance corrected intensities +void writeAmpInfo(const AmplitudeRegistry& reg, + std::unique_ptr& results){ + + std::ofstream parsOutputFile("params.txt"); + // This is the total number of events for the acceptance correction + auto total = results->intensity(); + double totalVal = total.first; + double totalErr = total.second; + + parsOutputFile << "################################################\n"; + parsOutputFile << "# All Values are acceptance corrected #\n"; + parsOutputFile << "################################################\n"; + parsOutputFile << "Total Events = " << totalVal << " +- " << totalErr << "\n"; + + // Coherent sums + for(size_t iAmp = 0; iAmp < reg.nUnqAmps; ++iAmp){ + const auto& wave = reg.uniqueAmps[iAmp]; + + // Coherent sums for unique amp based in refl + for(auto refl : {ReflSum::Positive, ReflSum::Negative, ReflSum::Neither}){ + auto key = std::make_pair(iAmp, refl); + if(reg.relations.ampReflToFull.count(key) == 0) + continue; + const auto& fullIndices = reg.relations.ampReflToFull.at(key); + if(fullIndices.empty()) + continue; + // Build full name list + std::vector fullNames; + for(auto idx : fullIndices) + fullNames.push_back(reg.ampsList[idx].fullName); + + auto val = results->intensity(fullNames); + + parsOutputFile << "FIT FRACTION (coherent sum) " + << reflToString(refl) << " " + << wave.ampName << " = " + << val.first / totalVal << " +- " + << val.second / totalVal << "\n"; } } - // covariance matrix - vector > covMatrix; - covMatrix = results.errorMatrix(); + // Coherent sums for Jl families + for(const auto& [key, fullIndices] : reg.relations.jlReflToFull){ + auto [jlFamily, refl] = key; + if(fullIndices.empty()) continue; - // ************************ - // start the GUI - // ************************ + std::vector fullNames; + for(auto idx : fullIndices) + fullNames.push_back(reg.ampsList[idx].fullName); + + auto val = results->intensity(fullNames); + + parsOutputFile << "FIT FRACTION (coherent sum) " + << reflToString(refl) << " " + << jlFamily << " = " + << val.first / totalVal << " +- " + << val.second / totalVal << "\n"; + } + + // Individual amplitudes + for(const auto& ampKey : reg.ampsList){ + + std::vector singleAmp = { ampKey.fullName }; + + auto val = results->intensity(singleAmp); + + parsOutputFile << "FIT FRACTION " << ampKey.fullName << " = " + << val.first / totalVal << " +- " + << val.second / totalVal << "\n"; + } + + parsOutputFile << "################################################\n"; + parsOutputFile << "################################################\n"; + parsOutputFile << "# Phase Differences #\n"; + parsOutputFile << "################################################\n"; + parsOutputFile << "################################################\n"; + + // In general, the phase differences are the same for all + // reactions. This is because the current use case is that + // multiple "reactions" are actually the same physical reaction + // but for a different data set like different run periods or + // beam pol. angle + const auto& firstReaction = results->reactionList()[0]; + + for(size_t i = 0; i < reg.ampsList.size(); ++i){ + const auto& amp1 = reg.ampsList[i]; + + // Only amplitudes in the first reaction to avoid duplicates + if(amp1.reactionName != firstReaction) continue; + if(amp1.reflSum == ReflSum::Neither) continue; + + for(size_t j = i+1; j < reg.ampsList.size(); ++j){ + const auto& amp2 = reg.ampsList[j]; + + if(amp2.reactionName != firstReaction) continue; + if(amp2.reflSum == ReflSum::Neither) continue; + + // Only compare amplitudes in the same coherent sum + if(amp1.sumIndex != amp2.sumIndex) continue; + + auto phaseDiff = results->phaseDiff(amp1.fullName, amp2.fullName); + + parsOutputFile << "PHASE DIFF " + << amp1.fullName << " vs " + << amp2.fullName << " = " + << phaseDiff.first << " +- " + << phaseDiff.second << "\n"; + } + } + + parsOutputFile << "################################################\n"; + parsOutputFile << "################################################\n"; + parsOutputFile << "# Amp Parameters #\n"; + parsOutputFile << "################################################\n"; + parsOutputFile << "################################################\n"; + + // currently plots all parameters, including production amplitudes + // a helper function could be added to filter the parameters of interest + std::vector parNameList = results->parNameList(); + for(const auto& parName : parNameList){ + double parVal = results->parValue(parName); + double parErr = results->parError(parName); + parsOutputFile << parName << ": " + << parVal << " +- " + << parErr << "\n"; + } + parsOutputFile.close(); +} + +void writeAmpInfoCSV(const AmplitudeRegistry& reg, + std::unique_ptr& results){ + std::ofstream csvOutputFile("params.csv"); + // This is the total number of events for the acceptance correction + auto total = results->intensity(); + double totalVal = total.first; + double totalErr = total.second; + + csvOutputFile << "Type,Name,Value,Error\n"; + csvOutputFile << "Total,Acceptance Corrected Events," << totalVal << "," + << totalErr << "\n"; + + // Coherent sums + for(size_t iAmp = 0; iAmp < reg.nUnqAmps; ++iAmp){ + const auto& wave = reg.uniqueAmps[iAmp]; + + // Coherent sums for unique amp based in refl + for(auto refl : {ReflSum::Positive, ReflSum::Negative, ReflSum::Neither}){ + auto key = std::make_pair(iAmp, refl); + if(reg.relations.ampReflToFull.count(key) == 0) continue; + const auto& fullIndices = reg.relations.ampReflToFull.at(key); + if(fullIndices.empty()) continue; + + std::vector fullNames; + for(auto idx : fullIndices) + fullNames.push_back(reg.ampsList[idx].fullName); + + auto val = results->intensity(fullNames); + + csvOutputFile << "CoherentSum," + << reflToString(refl) << " " << wave.ampName << "," + << val.first / totalVal << "," + << val.second / totalVal << "\n"; + } + } + + // Coherent sums for Jl families + for(const auto& [key, fullIndices] : reg.relations.jlReflToFull){ + auto [jlFamily, refl] = key; + if(fullIndices.empty()) continue; + + std::vector fullNames; + for(auto idx : fullIndices) + fullNames.push_back(reg.ampsList[idx].fullName); - if (showGui) { - cout << ">> Plot generator ready, starting GUI..." << endl; + auto val = results->intensity(fullNames); + + csvOutputFile << "CoherentSum," + << reflToString(refl) << " " << jlFamily << "," + << val.first / totalVal << "," + << val.second / totalVal << "\n"; + } + + // Individual amplitudes + for(const auto& ampKey : reg.ampsList){ + std::vector singleAmp = { ampKey.fullName }; + auto val = results->intensity(singleAmp); + + csvOutputFile << "IndividualAmp," + << ampKey.fullName << "," + << val.first / totalVal << "," + << val.second / totalVal << "\n"; + } + + // Phase differences + const auto& firstReaction = results->reactionList()[0]; + + for(size_t i = 0; i < reg.ampsList.size(); ++i){ + const auto& amp1 = reg.ampsList[i]; + if(amp1.reactionName != firstReaction) continue; + if(amp1.reflSum == ReflSum::Neither) continue; + + for(size_t j = i+1; j < reg.ampsList.size(); ++j){ + const auto& amp2 = reg.ampsList[j]; + if(amp2.reactionName != firstReaction) continue; + if(amp2.reflSum == ReflSum::Neither) continue; + if(amp1.sumIndex != amp2.sumIndex) continue; + + auto phaseDiff = results->phaseDiff(amp1.fullName, amp2.fullName); + + csvOutputFile << "PhaseDiff," + << amp1.fullName << " vs " << amp2.fullName << "," + << phaseDiff.first << "," + << phaseDiff.second << "\n"; + } + } + + // currently plots all parameters, including production amplitudes + // a helper function could be added to filter the parameters of interest + std::vector parNameList = results->parNameList(); + for(const auto& parName : parNameList){ + double parVal = results->parValue(parName); + double parErr = results->parError(parName); + csvOutputFile << "Parameter," + << parName << "," + << parVal << "," + << parErr << "\n"; + } + csvOutputFile.close(); +} + +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... +// Main Functions +// ...oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... + +bool parseInputs(int argc, char* argv[], ProgramOptions& options){ + // CLI parsing + if (argc < 2) { + std::cerr << "Usage: \n"; + std::cerr << "\tvecps_plotter " + "-o \n"<< std::endl; + return false; + } + + for (int i = 1; i < argc; i++){ + std::string arg(argv[i]); + if (arg == "-f"){ + options.resultsName = std::string(argv[++i]); + } + else if (arg == "-g"){ + options.showGui = true; + } + else if (arg == "-o"){ + options.outName = std::string(argv[++i]); + } + else if (arg == "-mcGen"){ + options.mcGen = true; + } + else if (arg == "-bkgFile"){ + options.bkgFile = true; + } + else if (arg == "-sFile"){ + options.sFile = true; + } + else if (arg == "-skipPlots"){ + options.skipPlots = true; + } + else if (arg == "-txt"){ + options.txtOutput = true; + } + else if (arg == "-csv"){ + options.csvOutput = true; + } + else if (arg == "-h"){ + std::cout << "\n Usage for: " << argv[0] << "\n\n"; + std::cout << "\t -f \t input fit results file path\n"; + std::cout << "\t -o \t output file path\n"; + std::cout << "\t -g \t show GUI. Default off\n"; + std::cout << "\t -mcGen\t output genMC. Default off\n"; + std::cout << "\t -sFile\t use a single reaction file set. Default off\n"; + std::cout << "\t -skipPlots\t skip generating plots. Default off\n"; + std::cout << "\t -txt\t output text file. Default off\n"; + std::cout << "\t -csv\t output CSV file. Default off\n"; + std::cout << "\t -h\t show this help message\n" + << std::endl; + return false; + } + else { + std::cerr << "Error: Unknown option '" << arg << "'\n"; + std::cerr << "Run with -h for help." << std::endl; + return false; + } + } + + // report used options + std::cout << "Fit results file name = " << options.resultsName << "\n"; + if(!options.skipPlots) + std::cout << "Output file name = " << options.outName << "\n"; + std::cout << "Show GUI? = " + << (options.showGui ? "Yes" : "No") << "\n"; + std::cout << "MC Gen? = " + << (options.mcGen ? "Yes" : "No") << "\n"; + std::cout << "Single File? = " + << (options.sFile ? "Yes" : "No") << "\n"; + std::cout << "Text Output? = " + << (options.txtOutput ? "Yes" : "No") << "\n"; + std::cout << "CSV Output? = " + << (options.csvOutput ? "Yes" : "No") << "\n" + << std::endl; + + return true; +} + +bool initializeAmpTools(ProgramOptions& options, + std::unique_ptr& results, + std::unique_ptr& plotResults, + AmplitudeRegistry& registry){ + // load the results and display the configuration info + std::cout << "Initializing AmpTools interface...\n"; + atiSetup(); + std::cout << "Interface initialized\n"; + std::cout << "Loading Fit results\n"; + results = std::make_unique(options.resultsName); + if (!results->valid()){ + std::cerr << "Invalid fit results in file: " + << options.resultsName << std::endl; + return false; + } + std::cout << "Fit results loaded\n"; + // set up the plot generator + if (options.mcGen){ + std::cout << "Plot results (MC gen on) \n"; + plotResults = + std::make_unique(*results, PlotGenerator::kDefault); + } + else { + std::cout << "Plot results (MC gen off) \n"; + plotResults = + std::make_unique(*results, PlotGenerator::kNoGenMC); + } + std::cout << "Initialized ati and PlotGen" << std::endl; + + // Build amplitude registry (once per file) + registry = buildRegistry(plotResults); + + return true; +} + +void analyzeFitFile(ProgramOptions& options, + std::unique_ptr& results, + std::unique_ptr& plotResults, + AmplitudeRegistry& registry){ + if(options.skipPlots){ + std::cout << "Skipping plot generation.\n"; + return; + } + cout << "\n*** Viewing Results Using AmpPlotter***\n\n"; + // Loop over reactions + // User will have to add the different root file outputs manually + auto reactionList = results->reactionList(); + for (size_t fileSet = 0; fileSet < reactionList.size(); ++fileSet){ + if (options.sFile && fileSet > 0) break; + + std::string reactionName = reactionList[fileSet]; + std::cout << "Processing reaction " << reactionName << " (" + << fileSet + 1 << "/" << reactionList.size() << ")\n"; + + if (!options.sFile){ + options.outName = reactionName + ".root"; + std::cout << "Output file: " << options.outName << std::endl; + } + + TFile* plotFile = new TFile(options.outName.c_str(), "RECREATE"); + TH1::AddDirectory(kFALSE); // avoid automatic ownership for GUI use + + plotResults->enableReaction(reactionName); + // Generate plot configurations + auto plotConfigs = generatePlotConfigs(registry); + // Loop over plot configurations + bool first = true; + bool singleData = false; + for (const auto& cfg : plotConfigs){ + + if (!first){ + applyConfig(cfg, registry, plotResults); + } + else{ + // On first iteration, just enable the relevant amps/sums + for (auto i : cfg.ampIndices) plotResults->enableAmp(i); + for (auto i : cfg.sumIndices) plotResults->enableSum(i); + first = false; + } + + PlotLabels cfgLabel = makeLabel(cfg, registry); + generatePlots(options, plotResults, reactionName, + *plotFile, singleData,cfg, cfgLabel); + } + plotFile->Close(); + } +} + +void startGUI(ProgramOptions& options, + std::unique_ptr& plotResults){ + if(options.skipPlots){ + std::cout << "No plots = No GUI\n"; + return; + } + auto plotResults_local = std::move(plotResults); + // start the GUI + if (options.showGui){ + std::cout << ">> Plot generator ready, starting GUI..." << std::endl; int dummy_argc = 0; char* dummy_argv[] = {}; TApplication app("app", &dummy_argc, dummy_argv); + app.SetReturnFromRun(true); gStyle->SetFillColor(10); gStyle->SetCanvasColor(10); @@ -424,15 +1098,43 @@ int main(int argc, char* argv[]) { gStyle->SetFrameFillColor(10); gStyle->SetFrameFillStyle(1001); - cout << " Initialized App " << endl; - PlotFactory factory(plotGen); - cout << " Created Plot Factory " << endl; - PlotterMainWindow mainFrame(gClient->GetRoot(), factory); - cout << " Main frame created " << endl; - + std::cout << " Initialized App " << std::endl; + auto factory = new PlotFactory(*plotResults_local); + std::cout << " Created Plot Factory " << std::endl; + auto mainFrame = new PlotterMainWindow(gClient->GetRoot(), *factory); + std::cout << " Main frame created " << std::endl; + mainFrame->Connect("CloseWindow()", "TApplication", gApplication, "Terminate()"); + std::cout << " App running" << std::endl; app.Run(); - cout << " App running" << endl; + std::cout << "GUI closed cleanly\n"; } - return 0; } + +int main(int argc, char* argv[]){ + + ProgramOptions options; + if (!parseInputs(argc, argv, options)){ + std::cout << "Error parsing inputs" << std::endl; + return 1; // Parsing failed + } + + std::unique_ptr results; + std::unique_ptr plotResults; + AmplitudeRegistry registry; + if (!initializeAmpTools(options, results, plotResults, registry)){ + std::cout << "Error initializing AmpTools" << std::endl; + return 1; // Parsing failed + } + + analyzeFitFile(options, results, plotResults, registry); + + writeAmpInfo(registry,results); + + writeAmpInfoCSV(registry,results); + + // GUI needs to be started last + startGUI(options, plotResults); + + return 0; +} \ No newline at end of file From dc5cf47165e2890309a5f87a3d9c92668789d64c Mon Sep 17 00:00:00 2001 From: Alex Austregesilo Date: Fri, 29 May 2026 10:43:53 -0400 Subject: [PATCH 32/33] remove reference to VecPs_3pi_refl --- src/programs/AmplitudeAnalysis/fit/fit.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/programs/AmplitudeAnalysis/fit/fit.cc b/src/programs/AmplitudeAnalysis/fit/fit.cc index 7efa0edab..04a4ac5f9 100644 --- a/src/programs/AmplitudeAnalysis/fit/fit.cc +++ b/src/programs/AmplitudeAnalysis/fit/fit.cc @@ -46,7 +46,6 @@ #include "AMPTOOLS_AMPS/omegapi_amplitude.h" #include "AMPTOOLS_AMPS/Vec_ps_refl.h" #include "AMPTOOLS_AMPS/Iso_ps_refl.h" -#include "AMPTOOLS_AMPS/VecPs_3pi_refl.h" #include "AMPTOOLS_AMPS/PhaseOffset.h" #include "AMPTOOLS_AMPS/ComplexCoeff.h" #include "AMPTOOLS_AMPS/OmegaDalitz.h" @@ -437,7 +436,6 @@ int main( int argc, char* argv[] ){ AmpToolsInterface::registerAmplitude( omegapi_amplitude() ); AmpToolsInterface::registerAmplitude( Vec_ps_refl() ); AmpToolsInterface::registerAmplitude( Iso_ps_refl() ); - AmpToolsInterface::registerAmplitude( VecPs_3pi_refl() ); AmpToolsInterface::registerAmplitude( PhaseOffset() ); AmpToolsInterface::registerAmplitude( ComplexCoeff() ); AmpToolsInterface::registerAmplitude( OmegaDalitz() ); From d075fe136dd96be6b0d518210bb111d9f1752749 Mon Sep 17 00:00:00 2001 From: Alex Austregesilo Date: Fri, 29 May 2026 10:50:17 -0400 Subject: [PATCH 33/33] correct format specifier for a double --- src/programs/Simulation/gen_vec_ps/gen_vec_ps.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/programs/Simulation/gen_vec_ps/gen_vec_ps.cc b/src/programs/Simulation/gen_vec_ps/gen_vec_ps.cc index 1205ca433..5e55f3fa6 100644 --- a/src/programs/Simulation/gen_vec_ps/gen_vec_ps.cc +++ b/src/programs/Simulation/gen_vec_ps/gen_vec_ps.cc @@ -567,7 +567,7 @@ int main( int argc, char* argv[] ){ TLorentzVector Gammap = beam + target; if( polAngle == -1 ){ - fprintf(stderr, "Error: do not use amorphous value (got %d)\n", polAngle); + fprintf(stderr, "Error: do not use amorphous value (got %f)\n", polAngle); return -1; } vector xDecayAngles = getXDecayAngles(polAngle, beam, Gammap, isobar, resonance);