Page MenuHomeHEPForge

No OneTemporary

diff --git a/EvtGenBase/EvtVector4R.hh b/EvtGenBase/EvtVector4R.hh
index 62dbb32..81785a4 100644
--- a/EvtGenBase/EvtVector4R.hh
+++ b/EvtGenBase/EvtVector4R.hh
@@ -1,180 +1,180 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#ifndef EVTVECTOR4R_HH
#define EVTVECTOR4R_HH
#include <iostream>
#include <math.h>
class EvtVector3R;
class EvtVector4R {
inline friend EvtVector4R operator*( double d, const EvtVector4R& v2 );
inline friend EvtVector4R operator*( const EvtVector4R& v2, double d );
inline friend EvtVector4R operator/( const EvtVector4R& v2, double d );
inline friend double operator*( const EvtVector4R& v1, const EvtVector4R& v2 );
inline friend EvtVector4R operator+( const EvtVector4R& v1,
const EvtVector4R& v2 );
inline friend EvtVector4R operator-( const EvtVector4R& v1,
const EvtVector4R& v2 );
public:
EvtVector4R();
EvtVector4R( double e, double px, double py, double pz );
inline void set( int i, double d );
inline void set( double e, double px, double py, double pz );
inline EvtVector4R& operator*=( double c );
inline EvtVector4R& operator/=( double c );
inline EvtVector4R& operator+=( const EvtVector4R& v2 );
inline EvtVector4R& operator-=( const EvtVector4R& v2 );
inline double get( int i ) const;
inline double cont( const EvtVector4R& v4 ) const;
friend std::ostream& operator<<( std::ostream& s, const EvtVector4R& v );
double mass2() const;
double mass() const;
void applyRotateEuler( double alpha, double beta, double gamma );
void applyBoostTo( const EvtVector4R& p4, bool inverse = false );
void applyBoostTo( const EvtVector3R& boost, bool inverse = false );
- EvtVector4R cross( const EvtVector4R& v2 );
+ EvtVector4R cross( const EvtVector4R& v2 ) const;
double dot( const EvtVector4R& v2 ) const;
double d3mag() const;
// Added by AJB - calculate scalars in the rest frame of the current object
double scalartripler3( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3 ) const;
double dotr3( const EvtVector4R& p1, const EvtVector4R& p2 ) const;
double mag2r3( const EvtVector4R& p1 ) const;
double magr3( const EvtVector4R& p1 ) const;
private:
double v[4];
inline double Square( double x ) const { return x * x; }
};
EvtVector4R rotateEuler( const EvtVector4R& rs, double alpha, double beta,
double gamma );
EvtVector4R boostTo( const EvtVector4R& rs, const EvtVector4R& p4,
bool inverse = false );
EvtVector4R boostTo( const EvtVector4R& rs, const EvtVector3R& boost,
bool inverse = false );
inline EvtVector4R& EvtVector4R::operator+=( const EvtVector4R& v2 )
{
v[0] += v2.v[0];
v[1] += v2.v[1];
v[2] += v2.v[2];
v[3] += v2.v[3];
return *this;
}
inline EvtVector4R& EvtVector4R::operator-=( const EvtVector4R& v2 )
{
v[0] -= v2.v[0];
v[1] -= v2.v[1];
v[2] -= v2.v[2];
v[3] -= v2.v[3];
return *this;
}
inline double EvtVector4R::mass2() const
{
return v[0] * v[0] - v[1] * v[1] - v[2] * v[2] - v[3] * v[3];
}
inline EvtVector4R operator*( double c, const EvtVector4R& v2 )
{
return EvtVector4R( v2 ) *= c;
}
inline EvtVector4R operator*( const EvtVector4R& v2, double c )
{
return EvtVector4R( v2 ) *= c;
}
inline EvtVector4R operator/( const EvtVector4R& v2, double c )
{
return EvtVector4R( v2 ) /= c;
}
inline EvtVector4R& EvtVector4R::operator*=( double c )
{
v[0] *= c;
v[1] *= c;
v[2] *= c;
v[3] *= c;
return *this;
}
inline EvtVector4R& EvtVector4R::operator/=( double c )
{
double cinv = 1.0 / c;
v[0] *= cinv;
v[1] *= cinv;
v[2] *= cinv;
v[3] *= cinv;
return *this;
}
inline double operator*( const EvtVector4R& v1, const EvtVector4R& v2 )
{
return v1.v[0] * v2.v[0] - v1.v[1] * v2.v[1] - v1.v[2] * v2.v[2] -
v1.v[3] * v2.v[3];
}
inline double EvtVector4R::cont( const EvtVector4R& v4 ) const
{
return v[0] * v4.v[0] - v[1] * v4.v[1] - v[2] * v4.v[2] - v[3] * v4.v[3];
}
inline EvtVector4R operator-( const EvtVector4R& v1, const EvtVector4R& v2 )
{
return EvtVector4R( v1 ) -= v2;
}
inline EvtVector4R operator+( const EvtVector4R& v1, const EvtVector4R& v2 )
{
return EvtVector4R( v1 ) += v2;
}
inline double EvtVector4R::get( int i ) const
{
return v[i];
}
inline void EvtVector4R::set( int i, double d )
{
v[i] = d;
}
inline void EvtVector4R::set( double e, double p1, double p2, double p3 )
{
v[0] = e;
v[1] = p1;
v[2] = p2;
v[3] = p3;
}
#endif
diff --git a/EvtGenModels/EvtBcVHad.hh b/EvtGenModels/EvtBcVHad.hh
index d047d34..79ffd66 100644
--- a/EvtGenModels/EvtBcVHad.hh
+++ b/EvtGenModels/EvtBcVHad.hh
@@ -1,76 +1,84 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#ifndef EvtBcVHad_HH
#define EvtBcVHad_HH
#include "EvtGenBase/EvtDecayAmp.hh"
#include "EvtGenBase/EvtVector4C.hh"
#include "EvtGenModels/EvtBCVFF2.hh"
#include "EvtGenModels/EvtWHad.hh"
+#include <array>
#include <memory>
#include <string>
class EvtParticle;
// Description: Module to implement Bc -> psi + (n pi) + (m K) decays
class EvtBcVHad : public EvtDecayAmp {
public:
std::string getName() override;
EvtDecayBase* clone() override;
void initProbMax() override;
void init() override;
- void decay( EvtParticle* p ) override;
+ void decay( EvtParticle* parent ) override;
protected:
// Hadronic current function
- EvtVector4C hardCurr( EvtParticle* root_particle ) const;
+ EvtVector4C hardCurr( EvtParticle* parent ) const;
+ void parseDecay();
private:
- // whichfit --- code of the Bc -> VW formfactor set:
- // 1 - SR
- // 2 - PM
- int whichfit;
+ // Code of the Bc -> VW formfactor set:
+ // 1 - SR
+ // 2 - PM
+ int m_whichFit;
- // final vector particle code
- int idVector;
+ // Final vector particle code
+ int m_idVector;
- // out_code: code of the hadronic final state
- // 1 - pi+
- // 2 - pi+ pi0
- // 3 - pi+ pi+ pi-
- // 4 - 4pi
- // 5 - pi+ pi+ pi- pi- pi+
- // 6 - K+ K- pi+
- // 7 - K+ pi+ pi-
- // 8 - K_S0 K+
- // 9 - K+ K- pi+ pi+ pi-
- // 10 - pi+ pi+ pi+ pi+ pi- pi- pi- (7 charged pi)
- // 11 - K+ pi+ pi+ pi- pi-
- int out_code;
+ // Code of the hadronic final state
+ // 1: B_c+ -> V pi+
+ // 2: B_c+ -> V pi+ pi0
+ // 3: B_c+ -> V 2pi+ pi-
+ // 4: B_c+ -> V 2pi+ pi- pi0 (not implemented)
+ // 5: B_c+ -> V 3pi+ 2pi-
+ // 6: B_c+ -> V K+ K- pi+
+ // 7: B_c+ -> V K+ pi+ pi-
+ // 8: B_c+ -> V K_S0 K+
+ // 9: B_c+ -> V K+ K- 2pi+ pi-
+ // 10: B_c+ -> V 4pi+ 3pi-
+ // 11: B_c+ -> V K+ 2pi+ 2pi-
+ int m_outCode;
- std::unique_ptr<EvtBCVFF2> ffmodel;
- std::unique_ptr<EvtWHad> wcurr;
+ std::unique_ptr<EvtBCVFF2> m_FFModel;
+ std::unique_ptr<EvtWHad> m_WCurr;
+
+ std::array<int, 4> m_iPiPlus = { { -1, -1, -1, -1 } };
+ std::array<int, 4> m_iPiMinus = { { -1, -1, -1, -1 } };
+ std::array<int, 4> m_iPiZero = { { -1, -1, -1, -1 } };
+ std::array<int, 4> m_iKPlus = { { -1, -1, -1, -1 } };
+ std::array<int, 4> m_iKMinus = { { -1, -1, -1, -1 } };
};
#endif
diff --git a/EvtGenModels/EvtPhiDalitz.hh b/EvtGenModels/EvtBcVPPHad.hh
similarity index 64%
copy from EvtGenModels/EvtPhiDalitz.hh
copy to EvtGenModels/EvtBcVPPHad.hh
index ada0306..7101141 100644
--- a/EvtGenModels/EvtPhiDalitz.hh
+++ b/EvtGenModels/EvtBcVPPHad.hh
@@ -1,49 +1,64 @@
-
/***********************************************************************
-* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
+* Copyright 1998-2023 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
-#ifndef EVTPHIDALITZ_HH
-#define EVTPHIDALITZ_HH
+#ifndef EvtBcVPPHad_HH
+#define EvtBcVPPHad_HH
#include "EvtGenBase/EvtDecayAmp.hh"
+#include "EvtGenBase/EvtVector4C.hh"
+
+#include "EvtGenModels/EvtBCVFF2.hh"
+#include "EvtGenModels/EvtWHad.hh"
+
+#include <string>
class EvtParticle;
-class EvtPhiDalitz : public EvtDecayAmp {
+// Description: Module to implement Bc -> psi + p + pbar + pi decays
+
+class EvtBcVPPHad : public EvtDecayAmp {
public:
std::string getName() override;
EvtDecayBase* clone() override;
-
- void init() override;
void initProbMax() override;
- void decay( EvtParticle* p ) override;
+ void init() override;
+ void decay( EvtParticle* parent ) override;
+
+ protected:
+ // Hadronic current function
+ EvtVector4C hardCurrPP( EvtParticle* parent, int i1, int i2 ) const;
private:
- double _mRho;
- double _gRho;
- double _aD;
- double _phiD;
- double _aOmega;
- double _phiOmega;
- int _locPip;
- int _locPim;
- int _locPi0;
+ // Code of the Bc -> VW formfactor set:
+ // 1 - SR
+ // 2 - PM
+ int m_whichFit;
+
+ // Final vector particle code
+ int m_idVector;
+
+ // Code of the hadronic final state
+ // 1: p+ p- pi+
+ int m_outCode;
+
+ std::unique_ptr<EvtBCVFF2> m_FFModel;
+ std::unique_ptr<EvtWHad> m_WCurr;
};
#endif
diff --git a/EvtGenModels/EvtPhiDalitz.hh b/EvtGenModels/EvtPhiDalitz.hh
index ada0306..7cafbc5 100644
--- a/EvtGenModels/EvtPhiDalitz.hh
+++ b/EvtGenModels/EvtPhiDalitz.hh
@@ -1,49 +1,51 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#ifndef EVTPHIDALITZ_HH
#define EVTPHIDALITZ_HH
#include "EvtGenBase/EvtDecayAmp.hh"
class EvtParticle;
class EvtPhiDalitz : public EvtDecayAmp {
public:
std::string getName() override;
EvtDecayBase* clone() override;
void init() override;
void initProbMax() override;
void decay( EvtParticle* p ) override;
private:
- double _mRho;
- double _gRho;
- double _aD;
- double _phiD;
- double _aOmega;
- double _phiOmega;
- int _locPip;
- int _locPim;
- int _locPi0;
+ double calc_q( double, double, double ) const;
+
+ double m_mRho;
+ double m_gRho;
+ double m_aD;
+ double m_phiD;
+ double m_aOmega;
+ double m_phiOmega;
+ int m_locPip;
+ int m_locPim;
+ int m_locPi0;
};
#endif
diff --git a/EvtGenModels/EvtWHad.hh b/EvtGenModels/EvtWHad.hh
index cd969b4..5c8f416 100644
--- a/EvtGenModels/EvtWHad.hh
+++ b/EvtGenModels/EvtWHad.hh
@@ -1,125 +1,131 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#ifndef EvtWHad_HH
#define EvtWHad_HH
#include "EvtGenBase/EvtComplex.hh"
+#include "EvtGenBase/EvtDiracSpinor.hh"
#include "EvtGenBase/EvtVector4C.hh"
#include "EvtGenBase/EvtVector4R.hh"
#include <vector>
// Description: Routine to calculate W -> (n pi) + (m K) current
// according to [Kuhn, Was, Acta.Phys.Polon B39 (2008) 147]
class EvtWHad {
public:
EvtWHad();
EvtVector4C WCurrent( const EvtVector4R& q1 ) const;
EvtVector4C WCurrent( const EvtVector4R& q1, const EvtVector4R& q2 ) const;
EvtVector4C WCurrent( const EvtVector4R& q1, const EvtVector4R& q2,
const EvtVector4R& q3 ) const;
EvtVector4C WCurrent( const EvtVector4R& q1, const EvtVector4R& q2,
const EvtVector4R& q3, const EvtVector4R& q4,
const EvtVector4R& q5 ) const;
EvtVector4C WCurrent_5pi( const EvtVector4R& q1, const EvtVector4R& q2,
const EvtVector4R& q3, const EvtVector4R& q4,
const EvtVector4R& q5 ) const;
EvtVector4C WCurrent_KKP( const EvtVector4R& pKplus,
const EvtVector4R& pKminus,
const EvtVector4R& pPiPlus ) const;
EvtVector4C WCurrent_KPP( const EvtVector4R& pKplus,
const EvtVector4R& pPiPlus,
const EvtVector4R& pPiMinus ) const;
EvtVector4C WCurrent_KSK( const EvtVector4R& pKS,
const EvtVector4R& pKplus ) const;
EvtVector4C WCurrent_KKPPP( const EvtVector4R& pKplus,
const EvtVector4R& pKminus,
const EvtVector4R& pPi1Plus,
const EvtVector4R& pPi2Plus,
const EvtVector4R& pPiMinus ) const;
// 1=pi+ 2=pi+ 3=pi+ 4=pi+ 5=pi- 6=pi- 7=pi- with symmetrization of the identical particles
EvtVector4C WCurrent_7pi( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3, const EvtVector4R& p4,
const EvtVector4R& p5, const EvtVector4R& p6,
const EvtVector4R& p7 ) const;
- // 1=K+ 2 = pi+ 3 = pi+ 4 = pi- 5 = pi- with symmetrizatiom
+ // 1=K+ 2 = pi+ 3 = pi+ 4 = pi- 5 = pi- with symmetrization
EvtVector4C WCurrent_K4pi( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3, const EvtVector4R& p4,
const EvtVector4R& p5 ) const;
+ // a1 -> p+ p- pi+
+ EvtVector4C WCurrent_ppPi( const EvtVector4R& p1, const EvtDiracSpinor& sp1,
+ const EvtVector4R& p2, const EvtDiracSpinor& sp2,
+ const EvtVector4R& k ) const;
+
protected:
EvtVector4C JB( const EvtVector4R& q1, const EvtVector4R& q2,
const EvtVector4R& q3, const EvtVector4R& q4,
const EvtVector4R& q5 ) const;
EvtComplex Den( double q, double mR, double gammaR, double gR ) const;
EvtComplex BWa( const EvtVector4R& q ) const;
EvtComplex BWf( const EvtVector4R& q ) const;
EvtComplex BWr( const EvtVector4R& q ) const;
EvtComplex BWKK( double s, int i ) const;
double pi3G( double Q2 ) const;
EvtComplex pcm( double s ) const;
EvtComplex BW( double s, double m, double gamma, double xm1,
double xm2 ) const;
EvtVector4C WCurrent_KKPPP_nosym( const EvtVector4R& pKplus,
const EvtVector4R& pKminus,
const EvtVector4R& pPi1Plus,
const EvtVector4R& pPi2Plus,
const EvtVector4R& pPiMinus ) const;
// a1 -> a1(1=pi+ 2=pi+ 3=pi+ 5=pi- 6=pi-) f0(4=pi+ 7=pi-) without symmetrization of the identical particles
EvtVector4C WCurrent_7pi_nosymm( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3, const EvtVector4R& p4,
const EvtVector4R& p5, const EvtVector4R& p6,
const EvtVector4R& p7 ) const;
// a1 -> K*0 (1=K+ 4=pi-) a1(2=pi+ 3=pi+ 5=pi-)
EvtVector4C WCurrent_K4pi_nosymm( const EvtVector4R& p1,
const EvtVector4R& p2,
const EvtVector4R& p3,
const EvtVector4R& p4,
const EvtVector4R& p5 ) const;
private:
std::vector<double> mRho_, gamma0_, cK_, mK_, gammaK_, gKRho_, gKPi_;
double mPi_, mPiSq_;
};
#endif
diff --git a/History.md b/History.md
index 0b1beb2..892d57f 100644
--- a/History.md
+++ b/History.md
@@ -1,844 +1,850 @@
# History file for EvtGen
From version 2.0.0,
Tabc labels refer to [Maniphest tasks](https://phab.hepforge.org/maniphest/query/nkBRd9OhPCBN/), while
Dxyz labels refer to [Differential code reviews](https://phab.hepforge.org/differential/query/YDY8EgjNGd.e/) on HepForge:
https://phab.hepforge.org/Tabc
https://phab.hepforge.org/Dxyz
===
## R02-0X-00
+3 Feb 2024 John Back
+* T230: Add EvtBcVPPHad model for Bc to Jpsi p pbar pi decays and generalised particle ordering
+ for EvtBcVHad decay files, courtesy of Aleksei Luchinsky, Dmitrii Pereima & Vanya Belyaev (LHCb).
+ Updated EvtPhiDalitz model to use helicity amplitudes and fixed the indices used in
+ EvtVector3R::dot(), courtesy of Arnau Brossa Gonzalo & Antonio Romero Vidal (LHCb).
+
31 Oct 2023 Fernando Abudinen
* D102: Bugfix probmax issue for X38722-+\_PSI\_GAMMA model
- Calculation of amplitude moved to dedicated calcAmp function and fixed initialisation.
- Introduced weighting to compensate for phase-space changes due to resonance width.
- Fixed bugs in rho couplings and loops over photon and vector states.
+ - Calculation of amplitude moved to dedicated calcAmp function and fixed initialisation.
+ - Introduced weighting to compensate for phase-space changes due to resonance width.
+ - Fixed bugs in rho couplings and loops over photon and vector states.
16 Oct 2023 Fernando Abudinen
* D99: Add tests for PHOTOS
- EvtParticle::getAttribute function made const
- Added variables for testing of FSR to testing framework
- Added dedicated tests for FSR with Photos
- Turned off Photos for all other tests
16 Oct 2023 Thomas Latham
* D98: Modernise EvtIdSet and other improvements
- Modernise and greatly simplify EvtIdSet implementation
- Fixes in EvtPropSLPole to avoid unnecessary dynamic allocations
- Other minor fixes and tidy-ups
* Credit to Heather Ratcliffe and Chris Brady for providing
and/or inspiring several of these improvements
22 Aug 2023 Fernando Abudinen
* D97: Bugfix probmax issue and introduced pole compensation for VTOSLL model
- Calculation of amplitude moved to dedicated calcAmp function and fixed initialisation.
+ - Calculation of amplitude moved to dedicated calcAmp function and fixed initialisation.
22 Aug 2023 Tom Latham
* CMake updates
- Update default C++ standard to 17
- Suppress 'up-to-date' messages during install
- Add 'EvtGen' prefix to file names of custom CMake modules
- Remove unused CMake module
* Update CI config
- Update default LCG version to 103
- Add builds for el9 OS using LCG 104
- Allow switching on/off building against each external
- Test stage: attempt to improve selection of commits to diff in different cases
- Update CVMFS tags as per https://cern.service-now.com/service-portal?id=outage&n=OTG0079356
* Fix script for generating src dependencies
- Adapted to behaviour of newer CMake version in LCG 103
* Apply clang-format
- Few small changes after update of CI clang version to 12
- Document version of clang-format to be used
* Updates to install script
- Update to latest Pythia8 and HepMC3 versions
- Fix to ensure dependencies are picked up from the local install
22 Aug 2023 Andrii Verbytskyi
* Patch for finding Pythia8 xmldoc path
21 Aug 2023 Tom Latham
* D96: Work around change of interface for setRndmEnginePtr in Pythia8 310
22 Jun 2023 Ludovico Massaccesi
* T219: Fixed amplitudes for D_DALITZ model of D0 -> pi+ pi- pi0.
1 March 2023 Fernando Abudinen
* D92: Bugfix probmax issue for TENSOR daughter in EvtSSD_DirectCP model.
Calculation of amplitude in EvtSSD_DirectCP model moved to dedicated calcAmp function.
Got rid of a few static variables along the way.
8 Feb 2023 Alexei Sibidanov and Tom Latham
* D90: Apply clang format and enable checking of formatting in gitlab CI
3 Feb 2023 John Back
* D91: Check for non-zero momentum for EvtSLBaryonAmp parent spin density matrix.
Print out integrals of JSON test histograms.
16 Dec 2022 John Back
* D89: Added probabilities for B_c -> V pi+ and V pi+ pi0 EvtBcVHad modes.
16 Dec 2022 Alexei Sibidanov
* D88: Applied clang-tidy modernize-use-nullptr
13 Dec 2022 Fernando Abudinen and Tom Latham
* Various improvements to testing framework
16 Nov 2022 Tom Latham
* T123: Provide documention of how to contribute bug reports, feature requests, new/modified code
8 Sep 2022 Fernando Abudinen, John Back, Michal Kreps, Tom Latham, Alex Ward
* T108: Implement JSON test framework for all decay models
9 June 2022 Michal Kreps
* D84: Improve efficiency of RareLbToLll decay model for final states with e+e- pair.
===
## R02-02-00
12 May 2022 Michal Kreps
* D83: Fix double counting of charmonia with K0 decays for B0.
11 May 2022 Tom Latham
* D80: Add CMake options for enabling clang-tidy static analysis checks during build
14 Apr 2022 John Back
* D82: EvtDecayProb: initialise data members and remove empty destructor
14 Apr 2022 Michal Kreps
* D81: Derive EvtFlatSqDalitz from EvtDecayIncoherent since we directly provide
final kinematics
2nd Mar 2022 John Back
* D78: Add Bc -> J/psi K+ pi- pi+ pi- pi+, Bc -> J/psi K+ K- pi+ pi- pi+ &
Bc -> J/psi 4pi+ 3pi- decay modes to the BC_VHAD model, courtesy of
Aleksei Luchinsky, Anna Danilina, Dmitrii Pereima & Vanya Belyaev (LHCb)
===
## R02-01-01
8th Sep 2021 Michal Kreps
* Update location of web page for Pythia8 download in setup script.
8th Sep 2021 Markus Prim, Lu Cao, Chaoyi Lyu and Michel De Cian (Michal Kreps)
* D73: Add new model for semileptonic B decays with BCL and BGL form-factors
8th June 2021 Michal Kreps
* T110, D71: Fix B+ --> eta' l nu BF which was order of magnitude too high.
Balance the decrease by increasing B+ --> D0 l nu, which is after change
still bit smaller than PDG 2021.
8th Jun 2021 Michal Kreps
* D71: Fix B+ --> eta' l nu BF.
20th Apr 2021 Tom Lathem
* D68: Fix compilation with Pythia 8.304
17th Mar 2021 Michal Kreps
* D62: Improve PI0DALITZ model to dynamically work out maximum probability to
make it usuable also for eta --> llgamma decays.
Remove ETA2MUMUGAMMA since it is a pure one-to-one copy of PI0DALITZ.
15th Jan 2021 Michal Kreps
* D47: Model to generate 4-body phase-space decays in restricted part of the m12-m34 space
12th Jan 2021 Michal Kreps
* D48: Fix bug in calculation of the daughter momentum in decay model EvtBsMuMuKK
7th Jan 2021 Michal Kreps
* D43: Allow to pass particle properties table in form of stringstream to constructor
of EvtGen for use case where these are created on fly.
10th Dec 2020 Michal Kreps
* D36: EvtFlatSqDalitz model to be more efficient and to avoid cut-off around the edges
21st Aug 2020 John Back
* T109: Add EvtEtaLLPiPi model for eta' -> l l pi pi decays (l = e or mu),
- courtesy of Aleksei Luchinsky (LHCb).
29th Jun 2020 Michal Kreps
* T103: Add missing include in EvtGenBase/EvtMatrix.hh.
15th May 2020 Michal Kreps
* D28: Add EvtThreeBodyPhsp (rectangular Dalitz plot selection) and
EvtPhspDecaytimeCut (minimum decay time requirement) models.
* D27: Fix initialisation of constants in EvtBTo3hCP model.
===
## R02-00-00
24th Apr 2020 Michal Kreps
* Update particle properties file evt.pdl to 2019 version of RPP by PDG.
23rd Apr 2020 Tom Latham
* Apply copyright and licence notices to all relevant files.
17th Apr 2020 Tom Latham
* Add text of GNU GPLv3 in COPYING, add (preliminary) list of authors in
AUTHORS, and clean-up all source files, prior to applying copyright and
licence notices.
9th Apr 2020 Tom Latham
* Improve, and document use of, standalone installation script.
* Apply clang-format formatting to all C++ source files.
8th Apr 2020 Tom Latham
* One small modernisation change to EvtPhotosEngine to match that already
applied in EvtTauolaEngine.
8th Apr 2020 John Back
* Fixed NonReson amplitude and the 4-momentum boosts used for angles in
EvtLambdacPHH,
- courtesy of Elisabeth Niel (LHCb).
7th Apr 2020 Gerhard Raven, Tom Latham, Michal Kreps and John Back
* Incorporate C++ modernization changes from Gerhard Raven (LHCb).
- Merged modernize branch into master.
9th Mar 2020 John Back
* Add EvtAbsExternalGen::getDecayProb() to allow external generators to
return a probability that can be used in EvtDecayProb (default = 1).
6th Mar 2020 Andrii Verbytskyi and Tom Latham
* Implement HepMC3 support: EvtHepMCEvent, external engines & cmake files.
15th Nov 2019 John Back
* Added EvtPsi2JpsiPiPi model for psi2S -> J/psi pi+ pi- decays based on hep-ph/1507.07985,
- courtesy of Aleksei Luchinsky (LHCb).
21st August 2019 Michal Kreps
* Added the EvtDToKpienu decay model for D -> K pi e nu decays from BESIII,
- courtesy of Liaoyuan Dong.
16th July 2019 John Back
* Correct imaginary sign for EvtComplex /= (EvtComplex c) operator.
3rd July 2019 John Back
* Added the EvtLambdacPHH decay model for Lc -> p K pi decays with K*(890),
Delta++(1232) and Lambda(1520) resonances, based on the Fermilab E791
analysis hep-ex/9912003v1,
- courtesy of Elisabeth Niel and Patrick Robbe (LHCb).
* Modified EvtResonance2 to accept other barrier factor radii.
3rd July 2019 Michal Kreps
* Make sure minimum mass for resonances with non-zero widths is larger than
1e-4 GeV in EvtRelBreitWignerBarrierFact.
3rd May 2019 John Back
* Corrected EvtSLDiBaryonAmp bugs/issues in the BToDiBaryonlnupQCD model:
- parity, amplitude terms and B momentum reference frame variables.
* Corrected treament of spinor indices in EvtRareLb2Lll,
- courtesy of Tom Blake and Michal Kreps (LHCb).
* Updated the EvtBcVHad model to also handle Bc -> psi Ks K decays,
- courtesy of Aleksei Luchinsky (LHCb).
* Add new decay model EvtBsMuMuKK (BS_MUMUKK) for Bs to J/psi (mu+mu-) K+K-,
- courtesy of Veronika Chobanova, Jeremy Dalseno, Diego Martinez Santos and
Marcos Romero Lamas (LHCb).
* Fix infinite loop during initialisation of the EvtBTo3hCP model via
EvtCBTo3piP00 and EvtCBTo3piMPP,
- courtesy of Peter Richardson (Durham).
15th March 2019 Tom Latham
* Implement cmake build system, replacing the old config method.
30th Jan 2019 John Back
* Fix modernization compiler errors and warnings.
29th Jan 2019 Michal Kreps
* Allow reading decay files which are missing end-of-line before end-of-file.
21st December 2018 John Back
* Imported C++ modernization changes from Gerhard Raven (LHCb).
7th December 2018 John Back
* Added the EvtBLLNuL (BLLNUL) model that generates rare B -> ell ell nu ell
decays, where ell = e or mu,
- courtesy of Anna Danilina and Nikolai Nikitin (LHCb).
* Removed the EvtB2MuMuMuNu (BUTOMMMN) model, since its now replaced
by the more general BLLNuL one.
5th November 2018 John Back
* Added the BToDiBaryonlnupQCD model for generating B to p N* l nu decays,
where N can be any (exited) charged baryon (spin 1/2 or 3/2),
- courtesy of Mark Smith and Ryan Newcombe (LHCb), with added code optimisations.
17th October 2018 John Back
* Added various decay models from LHCb EvtGenExtras package:
- EvtBcVHad ("BC_VHAD"),
- Evtbs2llGammaMNT ("BSTOGLLMNT"),
- Evtbs2llGammaISRFSR ("BSTOGLLISRFSR"),
- EvtbTosllMS ("BTOSLLMS"),
- EvtbTosllMSExt ("BTOSLLMSEXT"),
- EvtLb2Baryonlnu ("Lb2Baryonlnu"),
- EvtLb2plnuLCSR ("Lb2plnuLCSR"),
- EvtLb2plnuLQCD ("Lb2plnuLQCD"),
- EvtFlatSqDalitz ("FLATSQDALITZ"),
- EvtPhspFlatLifetime ("PHSPFLATLIFETIME").
5th October 2018 John Back
* Updated setupEvtGen.sh to work with the new HepForge Phabricator site.
13th March 2018 John Back
* Updated EvtPythiaEngine to correctly handle updates of various particle
properties so that Pythia uses the same information as EvtGen (evt.pdl)
for the generic and alias PYTHIA decay model.
12th March 2018 John Back
* Updated EvtBcXMuNu models (X = Scalar, Vector, Tensor) to generate
Bc to D0(star) mu nu decays, with associated form factors in EvtBCXFF,
- courtesy of Aleksei Luchinsky (LHCb).
* Also generalised the calculation
of their maximum probabilities by reusing the CalcMaxProb method in
EvtSemiLeptonicAmp, which now allows for different Q^2 binning
(default remains at 25 bins).
===
## R01-07-00
13th December 2017 John Back
* New tag incorporating all changes below.
* Recommended external packages are
(as used in the setupEvtGen.sh script):
- HepMC 2.06.09,
- pythia 8.230,
- Photos++ 3.61
- Tauola++ 1.1.6c.
12th December 2017 John Back
* Changed Pythia validation example decay files to use Pythia8 codes.
6th December 2017 John Back
* Modified the examples to use DECAY.DEC (see 25th April 2016) instead of
DECAY_2010.DEC. Changed EvtExternalGenList to assume Pythia8 codes are
used in decay files by default, which is the case for DECAY.DEC. Also
updated the setupEvtGen.sh script to work with Pythia 8.2x versions.
29th November 2017 John Back
* Modified EvtSVP, EvtVVP and EvtTVP models to handle both radiative and
two-lepton decays,
- courtesy of Aleksei Luchinsky (LHCb).
14th July 2017 John Back
* Only create external generator objects if they don't already exist in
EvtExternalGenFactory.
* Modified configure script to work with Pythia 8.2x
5th July 2017 Michal Kreps
* Register the VTOSLL model.
14th June 2017 John Back
* Add isNeutralKaon() boolean function and corrected comments in EvtDDalitz.
8th May 2017 Michal Kreps
* Fix bug in EvtbTosllVectorAmp to recognise Bs --> K*bar mu mu decay as
b --> d ll transition.
8th May 2017 Michal Kreps
* Significantly simplify way how we decide on decay mode and daughters
ordering in DDalitz model.
- With new code by definition all orderings of
daughters in the decay file will yield same output.
4th May 2017 John Back
* Further fixes to DDalitz particle ordering (including charge-conjugates):
- Mode 5: D0 -> K- K0bar K+ and K+ K- K0bar
- Mode 12: D0 -> pi0 pi- pi+ and pi+ pi0 pi-
- Removed unneeded index ordering checks for mode 10 (D+ -> pi- pi+ pi+)
and mode 11 (Ds+ -> pi- pi+ pi+)
27th April 2017 John Back
* Fixed DDalitz particle ordering for mode 7: D+ -> pi+ K- K+ and K+ pi+ K-
and their charge-conjugates
7th April 2017 John Back
* Modified EvtGenExternal/EvtPythiaEngine to ensure that the EvtGen-based
instances of Pythia8 (for generic and alias decays) use the same
particle properties as defined by EvtGen,
- courtesy Patrick Robbe (LHCb).
5th April 2017 Michal Kreps
* Fixed indexing in copy constructor of Evt3Rank3C, which would otherwise
produce an infinite loop;
- bug report from David Grellscheid.
3rd November 2016 John Back
* Modified EvtFlatQ2 model to work for all B -> X lepton lepton modes, as
well as adding an extra phase space factor to correct for the dip at low
q^2, which is enabled by using "FLATQ2 1" instead of just "FLATQ2" in the decay file,
- courtesy of Marcin Chrzaszcz & Thomas Blake (LHCb).
13th October 2016 John Back
* Added the TauolaCurrentOption decfile keyword to select the hadronic
current in Tauola; default is the BaBar-tuned current option (int = 1).
* EvtParticles can store double attributes using the functions
setAttributeDouble(name, double) and getAttributeDouble(name), which can
be useful for storing and retrieving amplitude weights, for example.
- The analogous EvtParticle integer attribute interface remains unchanged:
setAttribute(name, int) and getAttribute(name).
13th September 2016 John Back
* Modified EvtTauolaEngine to use internal Tauola spin matrices for
tau pair events by temporarily setting the PDG id of the mother as a
boson, keeping the same 4-momentum.
* The BaBar hadronic currents are now used by default.
* Also added the ability to change some Tauola parameters
using the "Define" keyword in decay files.
* Added an example decay file
illustrating the new features: validation/TauolaFiles/Btautau.dec
9th September 2016 Michal Kreps
* Reimplement code in EvtBTo3pi.F, EvtBTo3piMPP.F, EvtBTo3piP00.F and
EvtBToKpipi.F in C++ in order to remove dependence on Fortran compiler.
- With this, there is no internal Fortran code in EvtGen.
===
## R01-06-00
1st June 2016 John Back
* New tag incorporating all changes below.
* Recommended external packages are
- HepMC 2.06.09
- pythia 8.186
- Photos++ 3.61
- Tauola++ 1.1.5
28th April 2016 Michal Kreps
* For Ds+ --> 2pi+ pi- there was double counting of branching fraction
resulting in total branching fraction being 1.5 times larger than measured
one.
- Fix by revisiting submodes, which now fill total Ds --> 3pi.
25th April 2016 Michal Kreps
* Added DECAY.DEC/XML, which contain updated semileptonic charm and beauty
branching fractions using the 2014 PDG, tuned to minimize disagreements
between measurements and EvtGen for both inclusive and exclusive decays.
* Updated the evt.pdl particle properties file to the PDG 2014 edition.
* Implemented new LQCD form factors for Lb --> L mu mu from arXiv paper
1602.01399 (EvtRareLbToLllFFlQCD); old LQCD form factors are removed.
18th March 2016 John Back
* Fixed incorrect spinor algebra used in S1 -> 1/2 S2, 1/2 -> S3 S4 decays
in EvtDiracParticle::rotateToHelicityBasis() functions,
- courtesy of Luis Miguel Garcia Martin and the IFIC Valencia LHCb group.
19th Feburary 2016 John Back
* Fixed bug in the definition of the initial spinor term Sinit in
EvtRareLbToLll::HadronicAmpRS(),
- from Tom Blake (LHCb).
12th February 2016 John Back
* From LHCb, added extensions to the EvtHQET2(FF) model for semitauonic
decays from Brian Hamilton, which needs a patch to EvtSemiLeptonicAmp
from Jack Wimberley to ensure that the q^2 range is physical when
finding the maximum amplitude probability.
2nd December 2015 John Back
* From LHCb, added EvtKStopizmumu model for KS -> pi0 mu mu decays based on
JHEP08(1998)004,
- courtesy of Veronika Chobanova, Diego Martinez Santos and Jeremy Dalseno.
* Added EvtConst::Fermi for Fermi coupling constant.
===
## R01-05-00
21st October 2015 John Back
* New tag incorporating all changes below.
* Recommended external packages are
- HepMC 2.06.09
- pythia 8.186
- Photos++ 3.61
- Tauola++ 1.1.5
* Added the EvtB2MuMuMuNu model for simulating the very rare four-leptonic
decays B- -> mu+ mu- anti-nu_mu mu-,
- courtesy Nikolai Nikitin.
16th October 2015 John Back
* Updated the configure script to automatically select the library names
for PHOTOS++; version 3.56 and below uses Fortran, version 3.61 and above
uses C++ only (default). Avoid using v3.60, since it does not work.
This needs the PHOTOS libraries built before EvtGen is configured.
Modified setupEvtGen.sh to use Photos++ v3.61.
7th October 2015 John Back
* Updated EvtGenExternal/EvtPhotosEngine to check that additional particles
from the outgoing vertex are indeed (FSR) photons, since later versions of
PHOTOS introduce pair emission, where particles may not always be photons.
* Added the genRootDecayChain.cc validation program to create ROOT files
containing information about the complete decay tree. Two example test
decay files BKstarGamma.dec and BuDst0rhop.dec can be used with this; the
first tests PHOTOS, the second looks at sequential decay chain storage.
The plotBKstarGamma.C ROOT macro can be used for B -> K* gamma plots.
2nd October 2015 John Back
* Modified EvtSVPHelAmp and added a new EvtSVPHelCPMix model, implementing
the complete mixing phenomenology of Bs to vector gamma decays,
- courtesy of Clara Remon (LHCb).
* EvtD0mixDalitz code: cleanup, inverted q/p for decays of D0bar (simplifies
user decay files) and fixed y parameter bug,
- courtesy of Jordi Tico (LHCb).
* Changed the initialisation order of the infrared cut-off in EvtPhotosEngine.
This actually has no effect, since the exponentiation function sets it to the
same 1e-7 value, but it is now in the correct order if we need to update it.
* Removed all remaining obsolete pragma (Win32) warnings from some classes.
23rd September 2015 Michal Kreps
* Reimplement the real Spence function in C++ and removed its fortran
implementation.
15th September 2015 Michal Kreps
* Fixed accessed uninitialised memory in EvtPDL.cpp, line 213.
* Modified the configure and setupEvtGen.sh scripts to work on Mac; needed
Mac compilation patch files added to the new "platform" subdirectory.
10th September 2015 John Back
* Updated setupEvtGen.sh to use the recommended external packages:
- HepMC 2.06.09, pythia 8.186, Photos++ 3.56 and Tauola++ 1.1.5.
* Fixed form-factor calculations for the BTOSLLBALL model 6 used to generate
b -> sll decays,
- courtesy of Christoph Langenbruch and David Loh (LHCb).
- Affects B->K*ll, B->rholl and B->omegall, particularly the electron modes.
* In the validation directory, added runPhotosTest.sh for testing FSR in
Upsilon(4S) -> e+ e- decays, and changed the plot comparison scripts to
use the 2nd directory "oldRootFiles" (which could be a soft-link) for
including ROOT histograms made from a previous version of EvtGen.
27th August 2015 John Back
* Added Mersenne-Twister random number generator (RNG) EvtMTRandomEngine.
- It requires c++11 compiler features (>= gcc 4.7), which should
automatically be enabled by the configure script.
- Introduced the preprocessor environment variable EVTGEN_CPP11 for c++11
features.
- EvtMTRandomEngine is the default RNG for the validation and test examples
if c++11 features are enabled.
* Added a phase-space test validation/genPHSP.sh and PhaseSpacePlots.C to
visually check the flatness of Dalitz plots in order to ensure that the
RNG is not producing biased results that depend on particle ordering.
* Added the models EvtbsToLLLLAmp and EvtbsToLLLLHyperCP for
B0_q -> l+ l- l+ l- decays (SM and one supersymmetric scenario),
- courtesy of Nikolai Nikitin and Konstantin Toms.
- Documentation provided in doc/evt_BQTOLLLL_model.pdf and
doc/evt_BQTOLLLLHYPERCP_model.pdf.
* Changed the installation and set-up script name to be just setupEvtGen.sh;
it uses the VERSION variable to specify the required tag. List of tags
are available using either "svn ls -v http://svn.cern.ch/guest/evtgen/tags"
or by going to http://svn.cern.ch/guest/evtgen/tags in a web browser.
12th June 2015 John Back
* Changed the width of chi_b1 in evt.pdl from 9.8928 GeV (!) to zero.
1st May 2015 John Back
* Added Bc -> scalar ell nu (EvtBcSMuNu) and Bc -> tensor ell nu
(EvtBcTMuNu) decays,
- courtesy of Jack Wimberley, LHCb.
- Also included the chi_c1 mode for EvtBcVMuNu.
===
## R01-04-00
2nd April 2015 John Back
* Removed the EvtStdlibRandomEngine class since this can produce biases
to kinematic distributions when one or more of the daughters is a
resonance, such as B0 -> K pi psi
- (thanks to Antonio Augusto Alves Jr who discovered this issue).
- EvtSimpleRandomEngine is now the default random number generator in the
validation and test examples.
* Incorporated several additions and modifications from LHCb:
a) From Michal Kreps, Tom Blake & Christoph Langenbruch,
added rare Lb --> Lambda^(*) ell ell models described in
arXiv:1108.6129, with various form factors from Gutsche et al.
(arXiv:1301.3737) and lattice QCD (arXiv:1212.4827)
b) From Andrew Crocombe, implemented Bs --> K* form factors
from Ball-Zwicky and z-parametrization form factors from
arXiv:1006.4945 for EvtbTosllBallFF
c) Christoph Langenbruch fixed the Bs -> phi ll form factors in
EvtbTosllBallFF; T3 showed a non-physical pole at very low
q2 which significantly affected the electron mode
d) From Michal Kreps, removed semicolons from wrong places to
clear warnings when compiled with the "-pedantic" option.
9th October 2014 John Back
* Change svnweb.cern.ch to svn.cern.ch in the setup script.
1st April 2014 John Back
* In EvtReport, modified the logging output severity status flags
to have the "EVTGEN_" prefix, e.g. INFO becomes EVTGEN_INFO.
* The global report() function has been renamed to EvtGenReport().
31st March 2014 John Back
* Added the ability to store named attributes for EvtParticles in the
form of a map<string, int>. The setAttribute(name, value) stores the
required value, while getAttribute(name) retrieves the integer value.
This is used in EvtPhotosEngine to specify the final-state radiation
"FSR" attribute to 1 for any additional photons (EvtPhotonParticles)
created by Photos++. It also stores the "ISR" attribute, but this
is always set to zero, since only FSR photons are created.
If the named attribute does not exist, then getAttribute() returns zero.
29th January 2014 Daniel Craik
* Removed mass assertion on GS shape in EvtDalitzReso to allow it to also
be used for charged rho resonances.
27th January 2014 John Back
* Minor corrections to Vub models to remove further gcc 4.8 warnings.
* Updated configure script to work for MacOS clang (from Genser team).
===
## R01-03-00
9th January 2014 John Back
* New tag version "1.3.0", incorporating all changes below.
* Replaced auto-install script to work with this version as well as
the latest versions of all external generator packages.
* Updated README to mention the new CERN-based web pages for Photos++
and Tauola++.
8th January 2014 John Back
* Fix gcc 4.6 and 4.8 compilation warnings,
- courtesy of Patrick Robbe (LHCb);
- main changes are removal of unused variables.
* Changed the EvtPythiaEngine class and configure script to use new
Pythia 8 header locations; Pythia 8.180 or above is now required.
7th January 2014 John Back
* Modified EvtBCVFF to correct the Kiselev form factors
- from Jack Wimberley (LHCb).
9th October 2013 Daniel Craik
* Added Gounaris-Sakurai and Gaussian shapes to EvtGenericDalitz
and set sensible defaults for LASS parameters.
19th September 2013 John Back
* Modified EvtGenExternal/EvtPythiaEngine to keep track of any new
particles that are added to the default Pythia database to avoid
duplicating particle/anti-particle entries that could override
previously defined Pythia decay chains.
18th September 2013 John Back
* Added Mac OS flags for the configure script and src/Makefile.
15th July 2013 Daniel Craik
* Added flag to turn on scaling of LASS amplitude by M/q in EvtDalitzReso
15th July 2013 Daniel Craik
* EvtParserXML now accepts file names containing environment variables,
exponential non-resonant shape in EvtDalitzReso now defined as exp(-alpha*m^2),
LASS shape in EvtDalitzReso now takes a cutoff parameter
4th July 2013 Daniel Craik
* Added LASS, exponential non-resonant and linear non-resonant shapes to EvtGenericDalitz.
3rd July 2013 Daniel Craik
* Fixed auto-install script for R01-02-00.
1st July 2013 Daniel Craik
* Added auto-install script for R01-02-00.
===
## R01-02-00
15th May 2013 John Back
* New tag, version "1.2.0", incorporating all changes below.
14th May 2013 Michal Kreps
* Added Blatt-Weisskopf barrier factors up to L=5 in
EvtGenBase/EvtBlattWeisskopf::compute().
14th May 2013 John Back
* Added additional entries (appended at the end) to the evt.pdl particle
data file
- courtesy of Romulus Godang and Belle II colleagues.
14th March 2013 John Back
* Added the method EvtParticle::getPDGId() to get the PDG integer for a
particle directly (which just calls EvtPDL::getStdHep()).
* Added a check in EvtPhotosEngine::doDecay to skip Photos if a given
particle has too many daughters (>= 10) to avoid a problem with a
hard coded upper limit in the Photos PHOENE subroutine.
2nd February 2013 Daniel Craik
* Updated EvtDalitzTable to estimate probMax when it is missing from a
Dalitz model.
1st February 2013 John Back
* Added the ability to read in Pythia 6 commands in ascii decay files in
EvtDecayTable::readDecayFile (this was already possible in xml files).
* Modified the Photos++ engine default settings to be more suited to B
decays (from LHCb defaults).
31st January 2013 John Back
* Added the ability to read in Pythia 8 commands in ascii decay files
in EvtDecayTable::readDecayFile. They can be set using the syntax:
"PythiaTypeParam module:variable=value", where Type = Generic, Alias or
Both for specifying whether the parameter is for the generic or alias
Pythia decay engines (or both). The 2nd argument must not contain any
spaces. Fixed the list of commands strings being used in the
EvtPythiaEngine class (i.e. Pythia parameters that can be set via decay
files).
31st January 2013 Daniel Craik
* Added named parameters to various decay models.
30th January 2013 John Back
* Fixed some of the parameter arguments used in the EvtSVSCPiso model.
24th January 2013 John Back
* Set the Photos++ and Tauola++ models to use the EvtGen random number
engine when useEvtGenRandom is set to true in the EvtExternalGenList
constructor.
23rd January 2013 John Back
* Added EvtGenExternal/EvtPythiaRandom to allow the use of the EvtGen
random number engine to also be used for the random engine for Pythia 8.
* Added a boolean (useEvtGenRandom, default = true) within the
EvtExternalGenList constructor to use this feature.
18th December 2012 John Back
* Corrected some wrong daughter ordering assignments for decay modes 5 and
12 in EvtDDalitz. Updated validation/DalitzDecays.xml to also contain
D decay mode 12, as well as various modes that may use K_S0 and K_L0.
* Added validation/genDDalitzModes.sh and updated validation/compareDalitz.C to
do a complete comparison of the D Dalitz modes with the xml versions.
11th December 2012 Daniel Craik
* Updated the Xml parser to support named model parameters.
* Updated the generic Dalitz model to use named model parameters as an example.
15th October 2012 John Back
* Make EvtSimpleRandomEngine inherit from EvtRandomEngine to avoid
crash in EvtGen.cpp when no random engine is defined
- (from Bjoern Spruck).
===
## R01-01-00
4th October 2012 John Back
* New tag, version "1.1.0", incorporating all changes below.
* Provide proper default constructors for EvtVector4R and
EvtPhotonParticle. Modified the validation and test code to also
compile/link in the case of no external generators being included.
3rd October 2012 John Back
* Corrected the t3 vector form factor values for the Ball-Zwicky 2005
model (modelId = 6) in EvtbTosllBallFF::getVectorFF(), which
were set to t3tilde instead.
18th September 2012 John Back
* Moved the external generator engines to a new sub-directory
EvtGenExternal. Building the code now creates 2 libraries:
libEvtGen.so (Base+Models) and libEvtGenExternal.so.
- This allows anyone to ignore using the new external generators
if required (by not creating/loading the 2nd library).
* Added prefix option to the configure script/Makefile to allow the user
to specify an installation directory for the include files, libraries,
DECAY.DEC and evt.pdl files (for Genser).
14th September 2012 Michal Kreps
* Fixed the calculation of the angle between decay planes in the function
EvtKine::EvtDecayAngleChi. Fixed typo in EvtLb2Lll decay model. Only
some NP scenarious could be affected, SM one is definitely unaffected.
13th September 2012 John Back
* Added the use of the environment variables EVTGEN_PHOTOS, EVTGEN_PYTHIA
and EVTGEN_TAUOLA to specify if the Photos, Pythia and/or Tauola engine
classes are used or not. These variables are set by the configure script,
depending if the library paths are specified for these generators.
===
## R01-00-01
12th September 2012 John Back
* New tag incorporating all changes below, since R01-00-00.
11th September 2012 John Back
* Modified the Photos and Tauola engine classes to use the new
Photospp and Tauolapp namespaces that are present in the latest
versions of Photos++(3.5) and Tauola++(1.0.7).
* Updated the configure file to get the correct location of the Tauola++
include files.
* Added the D0->pi+pi-pi0 decay mode in EvtDDalitz
- from Marco Gersabeck and Frederic Dreyer (LHCb).
* Added new decay models/classes from Alexey Luchinsky (LHCb):
EvtBcVMuNu, EvtTVP, EvtWnPi, EvtSVP, EvtXPsiGamma, EvtBcVNpi
29th June 2012 John Back
* Corrected mass(squared) variables filled in the Dalitz TTree in
validation/genExampleRootFiles.
15th May 2012 Daniel Craik
* Updated EvtD0gammaDalitz to deal with D mesons from neutral B->DK
* Added save function to validation/compareDalitz.C.
11th May 2012 Daniel Craik
* Replaced BaBar specific configuration for BlattWeisskopf birth factors.
* Updated XML conversion script to handle new configuration.
* Fixed some bugs in the XML conversion script related to particle
modifications.
9th May 2012 Daniel Craik
* Added latex documentation for xml decay files.
2nd May 2012 Daniel Craik
* Added resDaughters attribute to the Dalitz resonance xml tag to
simplify defining symmetric resonances. Updated validation xml files to
use the new functionality.
27th April 2012 Daniel Craik
* Upgraded EvtGenericDalitz to use EvtDalitzReso for resonances.
* Added validation to compare EvtGenericDalitz to all 11 EvtDDalitz modes.
* Added a root macro to quickly compare two Dalitz decays for validation.
24th April 2012 John Back
* Solved two bugs in the EvtD0gammaDalitz model (from Jordi Tico, LHCb):
configuration of the conjugated model, and using only the B charge
to determine the model used, not the D flavour.
17th April 2012 Daniel Craik
* Updated the GenericDalitz validation code to use the same probMax
values as DDalitz.
* Added XML decay file parsing to EvtGen::readUDecay.
- Dec files are still the default.
30th March 2012 John Back
* Update maximum probability values in EvtDDalitz::initProbMax()
for all DDalitz modes.
23rd March 2012 John Back
* Added the EvtEta2MuMuGamma decay model from LHCb.
21st March 2012 John Back
* Added EvtD0gammaDalitz decay model from LHCb.
20th March 2012 Daniel Craik
* Added backwards compatibility for Pythia 6 commands in the XML configuration.
* Updated decay file conversion tool to convert JetSetPar lines to pythia6Param
tags.
19th March 2012 Daniel Craik
* Added infrastructure to pass commands to external generators.
* XML config now takes Pythia8 configuration commands.
16th March 2012 Daniel Craik
* Added the ability to define particles from the PDL for Dalitz decay
resonances instead of defining mass, width and spin seperately.
* Renamed the lifetime attribute of Dalitz decay resonaces to width to avoid
confusion.
* Added further validation code for the generic Dalitz model.
15th March 2012 Daniel Craik
* Added validation code for xml decay files and the generic Dalitz model.
===
## R01-00-00
6th March 2012 John Back
* First official version for Genser (evtgen 1.0.0) that includes
support for external generators: Pythia8, Photos++ and Tauola++.
* This also includes a preliminary version of creating Dalitz plot
decay models using EvtGenericDalitz.
diff --git a/src/EvtGenBase/EvtVector3R.cpp b/src/EvtGenBase/EvtVector3R.cpp
index 5669f08..ba13ba3 100644
--- a/src/EvtGenBase/EvtVector3R.cpp
+++ b/src/EvtGenBase/EvtVector3R.cpp
@@ -1,110 +1,109 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#include "EvtGenBase/EvtVector3R.hh"
#include "EvtGenBase/EvtPatches.hh"
#include <iostream>
#include <math.h>
using std::ostream;
EvtVector3R::EvtVector3R()
{
v[0] = v[1] = v[2] = 0.0;
}
EvtVector3R::EvtVector3R( double x, double y, double z )
{
v[0] = x;
v[1] = y;
v[2] = z;
}
EvtVector3R rotateEuler( const EvtVector3R& v, double alpha, double beta,
double gamma )
{
EvtVector3R tmp( v );
tmp.applyRotateEuler( alpha, beta, gamma );
return tmp;
}
void EvtVector3R::applyRotateEuler( double phi, double theta, double ksi )
{
double temp[3];
double sp, st, sk, cp, ct, ck;
sp = sin( phi );
st = sin( theta );
sk = sin( ksi );
cp = cos( phi );
ct = cos( theta );
ck = cos( ksi );
temp[0] = ( ck * ct * cp - sk * sp ) * v[0] +
( -sk * ct * cp - ck * sp ) * v[1] + st * cp * v[2];
temp[1] = ( ck * ct * sp + sk * cp ) * v[0] +
( -sk * ct * sp + ck * cp ) * v[1] + st * sp * v[2];
temp[2] = -ck * st * v[0] + sk * st * v[1] + ct * v[2];
v[0] = temp[0];
v[1] = temp[1];
v[2] = temp[2];
}
ostream& operator<<( ostream& s, const EvtVector3R& v )
{
s << "(" << v.v[0] << "," << v.v[1] << "," << v.v[2] << ")";
return s;
}
EvtVector3R cross( const EvtVector3R& p1, const EvtVector3R& p2 )
{
//Calcs the cross product. Added by djl on July 27, 1995.
//Modified for real vectros by ryd Aug 28-96
return EvtVector3R( p1.v[1] * p2.v[2] - p1.v[2] * p2.v[1],
p1.v[2] * p2.v[0] - p1.v[0] * p2.v[2],
p1.v[0] * p2.v[1] - p1.v[1] * p2.v[0] );
}
double EvtVector3R::d3mag() const
-
-// returns the 3 momentum mag.
{
+ // Returns the 3 momentum mag
double temp;
temp = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
temp = sqrt( temp );
return temp;
-} // r3mag
+}
double EvtVector3R::dot( const EvtVector3R& p2 )
{
double temp;
temp = v[0] * p2.v[0];
- temp += v[0] * p2.v[0];
- temp += v[0] * p2.v[0];
+ temp += v[1] * p2.v[1];
+ temp += v[2] * p2.v[2];
return temp;
-} //dot
+}
diff --git a/src/EvtGenBase/EvtVector4R.cpp b/src/EvtGenBase/EvtVector4R.cpp
index ce9b662..45f1b85 100644
--- a/src/EvtGenBase/EvtVector4R.cpp
+++ b/src/EvtGenBase/EvtVector4R.cpp
@@ -1,247 +1,247 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#include "EvtGenBase/EvtVector4R.hh"
#include "EvtGenBase/EvtPatches.hh"
#include "EvtGenBase/EvtTensor4C.hh"
#include "EvtGenBase/EvtVector3R.hh"
#include "EvtGenBase/EvtVector4C.hh"
#include <cmath>
#include <iostream>
using std::ostream;
EvtVector4R::EvtVector4R()
{
v[0] = 0.0;
v[1] = 0.0;
v[2] = 0.0;
v[3] = 0.0;
}
EvtVector4R::EvtVector4R( double e, double p1, double p2, double p3 )
{
v[0] = e;
v[1] = p1;
v[2] = p2;
v[3] = p3;
}
double EvtVector4R::mass() const
{
double m2 = v[0] * v[0] - v[1] * v[1] - v[2] * v[2] - v[3] * v[3];
if ( m2 > 0.0 ) {
return sqrt( m2 );
} else {
return 0.0;
}
}
EvtVector4R rotateEuler( const EvtVector4R& rs, double alpha, double beta,
double gamma )
{
EvtVector4R tmp( rs );
tmp.applyRotateEuler( alpha, beta, gamma );
return tmp;
}
EvtVector4R boostTo( const EvtVector4R& rs, const EvtVector4R& p4, bool inverse )
{
EvtVector4R tmp( rs );
tmp.applyBoostTo( p4, inverse );
return tmp;
}
EvtVector4R boostTo( const EvtVector4R& rs, const EvtVector3R& boost,
bool inverse )
{
EvtVector4R tmp( rs );
tmp.applyBoostTo( boost, inverse );
return tmp;
}
void EvtVector4R::applyRotateEuler( double phi, double theta, double ksi )
{
double sp = sin( phi );
double st = sin( theta );
double sk = sin( ksi );
double cp = cos( phi );
double ct = cos( theta );
double ck = cos( ksi );
double x = ( ck * ct * cp - sk * sp ) * v[1] +
( -sk * ct * cp - ck * sp ) * v[2] + st * cp * v[3];
double y = ( ck * ct * sp + sk * cp ) * v[1] +
( -sk * ct * sp + ck * cp ) * v[2] + st * sp * v[3];
double z = -ck * st * v[1] + sk * st * v[2] + ct * v[3];
v[1] = x;
v[2] = y;
v[3] = z;
}
ostream& operator<<( ostream& s, const EvtVector4R& v )
{
s << "(" << v.v[0] << "," << v.v[1] << "," << v.v[2] << "," << v.v[3] << ")";
return s;
}
void EvtVector4R::applyBoostTo( const EvtVector4R& p4, bool inverse )
{
double e = p4.get( 0 );
EvtVector3R boost( p4.get( 1 ) / e, p4.get( 2 ) / e, p4.get( 3 ) / e );
applyBoostTo( boost, inverse );
return;
}
void EvtVector4R::applyBoostTo( const EvtVector3R& boost, bool inverse )
{
double bx, by, bz, gamma, b2;
bx = boost.get( 0 );
by = boost.get( 1 );
bz = boost.get( 2 );
double bxx = bx * bx;
double byy = by * by;
double bzz = bz * bz;
b2 = bxx + byy + bzz;
if ( b2 > 0.0 && b2 < 1.0 ) {
gamma = 1.0 / sqrt( 1.0 - b2 );
double gb2 = ( gamma - 1.0 ) / b2;
double gb2xy = gb2 * bx * by;
double gb2xz = gb2 * bx * bz;
double gb2yz = gb2 * by * bz;
double gbx = gamma * bx;
double gby = gamma * by;
double gbz = gamma * bz;
double e2 = v[0];
double px2 = v[1];
double py2 = v[2];
double pz2 = v[3];
if ( inverse ) {
v[0] = gamma * e2 - gbx * px2 - gby * py2 - gbz * pz2;
v[1] = -gbx * e2 + gb2 * bxx * px2 + px2 + gb2xy * py2 + gb2xz * pz2;
v[2] = -gby * e2 + gb2 * byy * py2 + py2 + gb2xy * px2 + gb2yz * pz2;
v[3] = -gbz * e2 + gb2 * bzz * pz2 + pz2 + gb2yz * py2 + gb2xz * px2;
} else {
v[0] = gamma * e2 + gbx * px2 + gby * py2 + gbz * pz2;
v[1] = gbx * e2 + gb2 * bxx * px2 + px2 + gb2xy * py2 + gb2xz * pz2;
v[2] = gby * e2 + gb2 * byy * py2 + py2 + gb2xy * px2 + gb2yz * pz2;
v[3] = gbz * e2 + gb2 * bzz * pz2 + pz2 + gb2yz * py2 + gb2xz * px2;
}
}
}
-EvtVector4R EvtVector4R::cross( const EvtVector4R& p2 )
+EvtVector4R EvtVector4R::cross( const EvtVector4R& p2 ) const
{
//Calcs the cross product. Added by djl on July 27, 1995.
//Modified for real vectros by ryd Aug 28-96
EvtVector4R temp;
temp.v[0] = 0.0;
temp.v[1] = v[2] * p2.v[3] - v[3] * p2.v[2];
temp.v[2] = v[3] * p2.v[1] - v[1] * p2.v[3];
temp.v[3] = v[1] * p2.v[2] - v[2] * p2.v[1];
return temp;
}
double EvtVector4R::d3mag() const
// returns the 3 momentum mag.
{
double temp;
temp = v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
temp = sqrt( temp );
return temp;
} // r3mag
double EvtVector4R::dot( const EvtVector4R& p2 ) const
{
//Returns the dot product of the 3 momentum. Added by
//djl on July 27, 1995. for real!!!
double temp;
temp = v[1] * p2.v[1];
temp += v[2] * p2.v[2];
temp += v[3] * p2.v[3];
return temp;
} //dot
// Functions below added by AJB
// Calculate ( \vec{p1} cross \vec{p2} ) \cdot \vec{p3} in rest frame of object
double EvtVector4R::scalartripler3( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3 ) const
{
EvtVector4C lc = dual( EvtGenFunctions::directProd( *this, p1 ) ).cont2( p2 );
EvtVector4R l( real( lc.get( 0 ) ), real( lc.get( 1 ) ),
real( lc.get( 2 ) ), real( lc.get( 3 ) ) );
return -1.0 / mass() * ( l * p3 );
}
// Calculate the 3-d dot product of 4-vectors p1 and p2 in the rest frame of
// 4-vector p0
double EvtVector4R::dotr3( const EvtVector4R& p1, const EvtVector4R& p2 ) const
{
return 1 / mass2() * ( ( *this ) * p1 ) * ( ( *this ) * p2 ) - p1 * p2;
}
// Calculate the 3-d magnitude squared of 4-vector p1 in the rest frame of
// 4-vector p0
double EvtVector4R::mag2r3( const EvtVector4R& p1 ) const
{
return Square( ( *this ) * p1 ) / mass2() - p1.mass2();
}
// Calculate the 3-d magnitude 4-vector p1 in the rest frame of 4-vector p0.
double EvtVector4R::magr3( const EvtVector4R& p1 ) const
{
return sqrt( mag2r3( p1 ) );
}
diff --git a/src/EvtGenModels/EvtBcVHad.cpp b/src/EvtGenModels/EvtBcVHad.cpp
index 18042af..36e6df8 100644
--- a/src/EvtGenModels/EvtBcVHad.cpp
+++ b/src/EvtGenModels/EvtBcVHad.cpp
@@ -1,376 +1,436 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#include "EvtGenModels/EvtBcVHad.hh"
#include "EvtGenBase/EvtIdSet.hh"
#include "EvtGenBase/EvtPDL.hh"
#include "EvtGenBase/EvtParticle.hh"
#include "EvtGenBase/EvtReport.hh"
#include "EvtGenBase/EvtSpinType.hh"
#include "EvtGenBase/EvtTensor4C.hh"
#include "EvtGenBase/EvtVector4R.hh"
#include "EvtGenModels/EvtBCVFF2.hh"
#include "EvtGenModels/EvtWHad.hh"
#include <iostream>
std::string EvtBcVHad::getName()
{
return "BC_VHAD";
}
EvtDecayBase* EvtBcVHad::clone()
{
return new EvtBcVHad;
}
//======================================================
void EvtBcVHad::init()
{
+ // The following decay m_outCodes are supported:
+ // 1: B_c+ -> V pi+
+ // 2: B_c+ -> V pi+ pi0
+ // 3: B_c+ -> V 2pi+ pi-
+ // 4: B_c+ -> V 2pi+ pi- pi0 (not implemented)
+ // 5: B_c+ -> V 3pi+ 2pi-
+ // 6: B_c+ -> V K+ K- pi+
+ // 7: B_c+ -> V K+ pi+ pi-
+ // 8: B_c+ -> V K_S0 K+
+ // 9: B_c+ -> V K+ K- 2pi+ pi-
+ // 10: B_c+ -> V 4pi+ 3pi-
+ // 11: B_c+ -> V K+ 2pi+ 2pi-
+
checkNArg( 1 );
checkSpinParent( EvtSpinType::SCALAR );
checkSpinDaughter( 0, EvtSpinType::VECTOR );
for ( int i = 1; i <= ( getNDaug() - 1 ); i++ ) {
checkSpinDaughter( i, EvtSpinType::SCALAR );
}
- idVector = getDaug( 0 ).getId();
- whichfit = int( getArg( 0 ) + 0.1 );
- ffmodel = std::make_unique<EvtBCVFF2>( idVector, whichfit );
-
- wcurr = std::make_unique<EvtWHad>();
-
- // determine the code of final hadronic state
- EvtIdSet thePis{ "pi+", "pi-", "pi0" };
- EvtIdSet theK{ "K+", "K-", "K_S0" };
- if ( getNDaug() == 2 && thePis.contains( getDaug( 1 ) ) ) {
- out_code = 1; // pi+
- } else if ( getNDaug() == 3 && thePis.contains( getDaug( 1 ) ) &&
- thePis.contains( getDaug( 2 ) ) ) {
- out_code = 2; // pi+ pi0
- } else if ( getNDaug() == 4 && thePis.contains( getDaug( 1 ) ) &&
- thePis.contains( getDaug( 2 ) ) &&
- thePis.contains( getDaug( 3 ) ) ) {
- out_code = 3; // pi+ pi+ pi-
- } else if ( getNDaug() == 5 && thePis.contains( getDaug( 1 ) ) &&
- thePis.contains( getDaug( 2 ) ) &&
- thePis.contains( getDaug( 3 ) ) &&
- thePis.contains( getDaug( 4 ) ) ) {
- out_code = 4; //4pi
- } else if ( getNDaug() == 6 && thePis.contains( getDaug( 1 ) ) &&
- thePis.contains( getDaug( 2 ) ) &&
- thePis.contains( getDaug( 3 ) ) &&
- thePis.contains( getDaug( 4 ) ) &&
- thePis.contains( getDaug( 5 ) ) ) {
- out_code = 5; //5pi
- } else if ( getNDaug() == 4 && theK.contains( getDaug( 1 ) ) &&
- theK.contains( getDaug( 2 ) ) &&
- thePis.contains( getDaug( 3 ) ) ) {
- out_code = 6; //KKpi
- } else if ( getNDaug() == 4 && theK.contains( getDaug( 1 ) ) &&
- thePis.contains( getDaug( 2 ) ) &&
- thePis.contains( getDaug( 3 ) ) ) {
- out_code = 7; // Kpi pi
+ m_idVector = getDaug( 0 ).getId();
+ m_whichFit = int( getArg( 0 ) + 0.1 );
+ m_FFModel = std::make_unique<EvtBCVFF2>( m_idVector, m_whichFit );
+
+ m_WCurr = std::make_unique<EvtWHad>();
+
+ // Determine the code of the final hadronic state
+ parseDecay();
+}
+
+//======================================================
+
+void EvtBcVHad::parseDecay()
+{
+ const EvtIdSet BcPlusID{ "B_c+" }, BcMinusID{ "B_c-" };
+ const EvtIdSet theK{ "K+", "K-", "K_S0" };
+ const int cMode = BcMinusID.contains( getParentId() );
+
+ const EvtIdSet PiPlusID{ cMode == 0 ? "pi+" : "pi-" };
+ const EvtIdSet PiMinusID{ cMode == 0 ? "pi-" : "pi+" };
+ const EvtIdSet PiZeroID{ "pi0" };
+ const EvtIdSet KPlusID{ cMode == 0 ? "K+" : "K-" };
+ const EvtIdSet KMinusID{ cMode == 0 ? "K-" : "K+" };
+ EvtGenReport( EVTGEN_INFO, "EvtBcVHad" )
+ << "parentId = " << getParentId() << std::endl;
+
+ int PiPlusFound = 0, PiMinusFound = 0, PiZeroFound = 0, KPlusFound = 0,
+ KMinusFound = 0;
+ for ( int iDaughter = 0; iDaughter < getNDaug(); ++iDaughter ) {
+ const EvtId daugId = getDaug( iDaughter );
+ EvtGenReport( EVTGEN_INFO, "EvtBcVHad" )
+ << "iDaughter = " << iDaughter
+ << " id = " << getDaug( iDaughter ).getName() << std::endl;
+ if ( PiPlusID.contains( daugId ) && PiPlusFound < 4 ) {
+ m_iPiPlus[PiPlusFound] = iDaughter;
+ PiPlusFound++;
+ } else if ( PiMinusID.contains( daugId ) && PiMinusFound < 4 ) {
+ m_iPiMinus[PiMinusFound] = iDaughter;
+ PiMinusFound++;
+ } else if ( PiZeroID.contains( daugId ) && PiZeroFound < 4 ) {
+ m_iPiZero[PiZeroFound] = iDaughter;
+ PiZeroFound++;
+ } else if ( KPlusID.contains( daugId ) && KPlusFound < 4 ) {
+ m_iKPlus[KPlusFound] = iDaughter;
+ KPlusFound++;
+ } else if ( KMinusID.contains( daugId ) && KMinusFound < 4 ) {
+ m_iKMinus[KMinusFound] = iDaughter;
+ KMinusFound++;
+ }
+ }
+
+ if ( getNDaug() == 2 && PiPlusFound == 1 ) {
+ m_outCode = 1; // pi+
+ } else if ( getNDaug() == 3 && PiPlusFound == 1 && PiZeroFound == 1 ) {
+ m_outCode = 2; // pi+ pi0
+ } else if ( getNDaug() == 4 && PiPlusFound == 2 && PiMinusFound == 1 ) {
+ m_outCode = 3; // pi+ pi+ pi-
+ } else if ( getNDaug() == 5 && PiPlusFound == 2 && PiMinusFound == 1 &&
+ PiZeroFound == 1 ) {
+ m_outCode = 4; // pi+ pi+ pi- pi0
+ } else if ( getNDaug() == 6 && PiPlusFound == 3 && PiMinusFound == 2 ) {
+ m_outCode = 5; // 5pi
+ } else if ( getNDaug() == 4 && KPlusFound == 1 && KMinusFound == 1 &&
+ PiPlusFound == 1 ) {
+ m_outCode = 6; // KKpi
+ } else if ( getNDaug() == 4 && KPlusFound == 1 && PiPlusFound == 1 &&
+ PiMinusFound == 1 ) {
+ m_outCode = 7; // K+ pi+ pi-
} else if ( getNDaug() == 3 && theK.contains( getDaug( 1 ) ) &&
theK.contains( getDaug( 2 ) ) ) {
- out_code = 8; // KK
- } else if ( getNDaug() == 6 && theK.contains( getDaug( 1 ) ) &&
- theK.contains( getDaug( 2 ) ) && thePis.contains( getDaug( 3 ) ) &&
- thePis.contains( getDaug( 4 ) ) &&
- thePis.contains( getDaug( 5 ) ) ) {
- out_code = 9; // KK+3pi
- } else if ( getNDaug() == 8 && thePis.contains( getDaug( 1 ) ) &&
- thePis.contains( getDaug( 2 ) ) &&
- thePis.contains( getDaug( 3 ) ) &&
- thePis.contains( getDaug( 4 ) ) &&
- thePis.contains( getDaug( 5 ) ) &&
- thePis.contains( getDaug( 6 ) ) &&
- thePis.contains( getDaug( 7 ) ) ) {
- out_code = 10; //7pi
- } else if ( getNDaug() == 6 && theK.contains( getDaug( 1 ) ) &&
- thePis.contains( getDaug( 2 ) ) &&
- thePis.contains( getDaug( 3 ) ) &&
- thePis.contains( getDaug( 4 ) ) &&
- thePis.contains( getDaug( 5 ) ) ) {
- out_code = 11; // K+ pi+ pi+ pi- pi-
+ m_outCode = 8; // KK
+ } else if ( getNDaug() == 6 && KPlusFound == 1 && KMinusFound == 1 &&
+ PiPlusFound == 2 && PiMinusFound == 1 ) {
+ m_outCode = 9; // K+ K- pi+ pi+ pi-
+ } else if ( getNDaug() == 8 && PiPlusFound == 4 && PiMinusFound == 3 ) {
+ m_outCode = 10; // 7pi
+ } else if ( getNDaug() == 6 && KPlusFound == 1 && PiPlusFound == 2 &&
+ PiMinusFound == 2 ) {
+ m_outCode = 11; // K+ pi+ pi+ pi- pi-
} else {
- EvtGenReport( EVTGEN_ERROR, "EvtBcHad" )
+ EvtGenReport( EVTGEN_ERROR, "EvtBcVHad" )
<< "Init: unknown decay" << std::endl;
- };
+ }
- EvtGenReport( EVTGEN_INFO, "EvtBcHad" )
- << "out_code = " << out_code << ", whichfit = " << whichfit << std::endl;
+ EvtGenReport( EVTGEN_INFO, "EvtBcVHad" )
+ << "m_outCode = " << m_outCode << ", m_whichFit = " << m_whichFit
+ << std::endl;
+ for ( int i = 0; i < 4; ++i ) {
+ EvtGenReport( EVTGEN_INFO, "EvtBcVHad" )
+ << " i = " << i << ", m_iPiPlus = " << m_iPiPlus[i]
+ << ", m_iPiMinus = " << m_iPiMinus[i]
+ << ", m_iPiZero = " << m_iPiZero[i] << ", m_iKPlus = " << m_iKPlus[i]
+ << ", m_iKMinus = " << m_iKMinus[i] << std::endl;
+ }
+ EvtGenReport( EVTGEN_INFO, "EvtBcVHad" )
+ << "PiPlusFound = " << PiPlusFound << ", PiMinusFound = " << PiMinusFound
+ << ", PiZeroFound = " << PiZeroFound << ", KPlusFound = " << KPlusFound
+ << ", KMinusFound = " << KMinusFound << std::endl;
}
//======================================================
void EvtBcVHad::initProbMax()
{
- if ( out_code == 1 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 &&
- getNDaug() == 2 )
+ if ( m_outCode == 1 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 2 )
setProbMax( 500. );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() &&
- whichfit == 2 && getNDaug() == 2 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 2 )
setProbMax( 300. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 1 && getNDaug() == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 2 )
setProbMax( 17. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 2 && getNDaug() == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 2 )
setProbMax( 40. );
- } else if ( out_code == 2 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 &&
- getNDaug() == 3 )
+ } else if ( m_outCode == 2 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 3 )
setProbMax( 10950. );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() &&
- whichfit == 2 && getNDaug() == 3 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 3 )
setProbMax( 4200. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 1 && getNDaug() == 3 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 3 )
setProbMax( 500. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 2 && getNDaug() == 3 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 3 )
setProbMax( 700. );
- } else if ( out_code == 3 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 &&
- getNDaug() == 4 )
+ } else if ( m_outCode == 3 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 4 )
setProbMax( 42000. );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() &&
- whichfit == 2 && getNDaug() == 4 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 4 )
setProbMax( 90000. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 1 && getNDaug() == 4 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 4 )
setProbMax( 1660. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 2 && getNDaug() == 4 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 4 )
setProbMax( 2600. );
- } else if ( out_code == 5 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 &&
- getNDaug() == 6 )
+ } else if ( m_outCode == 5 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 6 )
setProbMax( 720000. );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() &&
- whichfit == 2 && getNDaug() == 6 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 6 )
setProbMax( 519753. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 1 && getNDaug() == 6 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 && getNDaug() == 6 )
setProbMax( 40000. );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
- whichfit == 2 && getNDaug() == 6 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 && getNDaug() == 6 )
setProbMax( 30000. );
- } else if ( out_code == 6 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 )
+ } else if ( m_outCode == 6 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() && m_whichFit == 1 )
setProbMax( 50000. );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 22000.0 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 1 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 )
setProbMax( 2300.0 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 1700.00 );
- } else if ( out_code == 7 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 )
+ } else if ( m_outCode == 7 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() && m_whichFit == 1 )
setProbMax( 2.2e+06 );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 930000 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 1 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 )
setProbMax( 92000.0 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 93000.0 );
- } else if ( out_code == 8 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 )
+ } else if ( m_outCode == 8 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() && m_whichFit == 1 )
setProbMax( 2e2 );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 80 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 1 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 )
setProbMax( 10 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 10 );
- } else if ( out_code == 9 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 )
+ } else if ( m_outCode == 9 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() && m_whichFit == 1 )
setProbMax( 3e4 );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 18540 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 1 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 )
setProbMax( 0.15 * 1e4 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 2 * 500 );
- } else if ( out_code == 10 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 )
+ } else if ( m_outCode == 10 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() && m_whichFit == 1 )
setProbMax( 2e6 );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 5e6 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 1 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 )
setProbMax( 1.5e5 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 1e5 );
- } else if ( out_code == 11 ) {
- if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 1 )
+ } else if ( m_outCode == 11 ) {
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() && m_whichFit == 1 )
setProbMax( 2.5e8 );
- else if ( idVector == EvtPDL::getId( "J/psi" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 1.4e7 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 1 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 1 )
setProbMax( 2e6 );
- else if ( idVector == EvtPDL::getId( "psi(2S)" ).getId() && whichfit == 2 )
+ else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() &&
+ m_whichFit == 2 )
setProbMax( 8e4 );
} else {
EvtGenReport( EVTGEN_ERROR, "EvtBcHad" )
- << "probmax: Have not yet implemented this final state in BC_VHAD model, out_code = "
- << out_code << std::endl;
- ::abort();
+ << "probmax: Have not yet implemented this final state in BC_VHAD model, m_outCode = "
+ << m_outCode << std::endl;
+ for ( int id = 0; id < ( getNDaug() - 1 ); id++ ) {
+ EvtGenReport( EVTGEN_ERROR, "EvtBcVHad" )
+ << "Daug " << id << " " << EvtPDL::name( getDaug( id ) ).c_str()
+ << std::endl;
+ }
}
}
//======================================================
-EvtVector4C EvtBcVHad::hardCurr( EvtParticle* root_particle ) const
+EvtVector4C EvtBcVHad::hardCurr( EvtParticle* parent ) const
{
EvtVector4C hardCur;
- if ( out_code == 1 ) {
+ if ( m_outCode == 1 ) {
// pi+
- hardCur = wcurr->WCurrent( root_particle->getDaug( 1 )->getP4() );
+ hardCur = m_WCurr->WCurrent( parent->getDaug( m_iPiPlus[0] )->getP4() );
- } else if ( out_code == 2 ) {
+ } else if ( m_outCode == 2 ) {
// pi+ pi0
- hardCur = wcurr->WCurrent( root_particle->getDaug( 1 )->getP4(),
- root_particle->getDaug( 2 )->getP4() );
+ hardCur = m_WCurr->WCurrent( parent->getDaug( m_iPiPlus[0] )->getP4(),
+ parent->getDaug( m_iPiZero[0] )->getP4() );
- } else if ( out_code == 3 ) {
+ } else if ( m_outCode == 3 ) {
// pi+ pi+ pi-
- hardCur = wcurr->WCurrent( root_particle->getDaug( 1 )->getP4(),
- root_particle->getDaug( 2 )->getP4(),
- root_particle->getDaug( 3 )->getP4() );
-
- } else if ( out_code == 5 ) {
- // Bc -> psi pi+ pi+ pi- pi- pi+ from Kuhn, Was, hep-ph/0602162
- hardCur = wcurr->WCurrent( root_particle->getDaug( 1 )->getP4(),
- root_particle->getDaug( 2 )->getP4(),
- root_particle->getDaug( 3 )->getP4(),
- root_particle->getDaug( 4 )->getP4(),
- root_particle->getDaug( 5 )->getP4() );
-
- } else if ( out_code == 6 ) {
+ hardCur = m_WCurr->WCurrent( parent->getDaug( m_iPiPlus[0] )->getP4(),
+ parent->getDaug( m_iPiPlus[1] )->getP4(),
+ parent->getDaug( m_iPiMinus[0] )->getP4() );
+ } else if ( m_outCode == 5 ) {
+ // Bc -> psi pi+ pi+ pi- pi- pi+ from Kuhn & Was, hep-ph/0602162
+ hardCur =
+ m_WCurr->WCurrent_5pi( parent->getDaug( m_iPiPlus[0] )->getP4(),
+ parent->getDaug( m_iPiPlus[1] )->getP4(),
+ parent->getDaug( m_iPiPlus[2] )->getP4(),
+ parent->getDaug( m_iPiMinus[0] )->getP4(),
+ parent->getDaug( m_iPiMinus[1] )->getP4() );
+
+ } else if ( m_outCode == 6 ) {
// K+ K- pi+
- hardCur = wcurr->WCurrent_KKP( root_particle->getDaug( 1 )->getP4(),
- root_particle->getDaug( 2 )->getP4(),
- root_particle->getDaug( 3 )->getP4() );
+ hardCur =
+ m_WCurr->WCurrent_KKP( parent->getDaug( m_iKPlus[0] )->getP4(),
+ parent->getDaug( m_iKMinus[0] )->getP4(),
+ parent->getDaug( m_iPiPlus[0] )->getP4() );
- } else if ( out_code == 7 ) {
+ } else if ( m_outCode == 7 ) {
// K+ pi+ pi-
- hardCur = wcurr->WCurrent_KPP( root_particle->getDaug( 1 )->getP4(),
- root_particle->getDaug( 2 )->getP4(),
- root_particle->getDaug( 3 )->getP4() );
+ hardCur =
+ m_WCurr->WCurrent_KPP( parent->getDaug( m_iKPlus[0] )->getP4(),
+ parent->getDaug( m_iPiPlus[0] )->getP4(),
+ parent->getDaug( m_iPiMinus[0] )->getP4() );
- } else if ( out_code == 8 ) {
+ } else if ( m_outCode == 8 ) {
// K_S0 K+
- hardCur = wcurr->WCurrent_KSK( root_particle->getDaug( 1 )->getP4(),
- root_particle->getDaug( 2 )->getP4() );
+ hardCur = m_WCurr->WCurrent_KSK( parent->getDaug( 1 )->getP4(),
+ parent->getDaug( 2 )->getP4() );
- } else if ( out_code == 9 ) {
+ } else if ( m_outCode == 9 ) {
// K+ K- pi+ pi+ pi-
- hardCur = wcurr->WCurrent_KKPPP(
- root_particle->getDaug( 1 )->getP4(), // K+
- root_particle->getDaug( 2 )->getP4(), // K-
- root_particle->getDaug( 3 )->getP4(), // pi+
- root_particle->getDaug( 4 )->getP4(), // pi+
- root_particle->getDaug( 5 )->getP4() // pi-
+ hardCur = m_WCurr->WCurrent_KKPPP(
+ parent->getDaug( m_iKPlus[0] )->getP4(), // K+
+ parent->getDaug( m_iKMinus[0] )->getP4(), // K-
+ parent->getDaug( m_iPiPlus[0] )->getP4(), // pi+
+ parent->getDaug( m_iPiPlus[1] )->getP4(), // pi+
+ parent->getDaug( m_iPiMinus[0] )->getP4() // pi-
);
- } else if ( out_code == 10 ) {
- // 1=pi+ 2=pi+ 3=pi+ 4=pi+ 5=pi- 6=pi- 7=pi- with symmetrization of the identical particles
- hardCur =
- wcurr->WCurrent_7pi( root_particle->getDaug( 1 )->getP4(), // pi+
- root_particle->getDaug( 2 )->getP4(), // pi+
- root_particle->getDaug( 3 )->getP4(), // pi+
- root_particle->getDaug( 4 )->getP4(), // pi+
- root_particle->getDaug( 5 )->getP4(), // pi-
- root_particle->getDaug( 6 )->getP4(), // pi-
- root_particle->getDaug( 7 )->getP4() // pi-
- );
- } else if ( out_code == 11 ) {
- // 1=K+ 2 = pi+ 3 = pi+ 4 = pi- 5 = pi- with symmetrizatiom
- hardCur = wcurr->WCurrent_K4pi(
- root_particle->getDaug( 1 )->getP4(), // K+
- root_particle->getDaug( 2 )->getP4(), // pi+
- root_particle->getDaug( 3 )->getP4(), // pi+
- root_particle->getDaug( 4 )->getP4(), // pi-
- root_particle->getDaug( 5 )->getP4() // pi-
+ } else if ( m_outCode == 10 ) {
+ // 1=pi+ 2=pi+ 3=pi+ 4=pi+ 5=pi- 6=pi- 7=pi- with symmetrization of identical particles
+ hardCur = m_WCurr->WCurrent_7pi(
+ parent->getDaug( m_iPiPlus[0] )->getP4(), // pi+
+ parent->getDaug( m_iPiPlus[1] )->getP4(), // pi+
+ parent->getDaug( m_iPiPlus[2] )->getP4(), // pi+
+ parent->getDaug( m_iPiPlus[3] )->getP4(), // pi+
+ parent->getDaug( m_iPiMinus[0] )->getP4(), // pi-
+ parent->getDaug( m_iPiMinus[1] )->getP4(), // pi-
+ parent->getDaug( m_iPiMinus[2] )->getP4() // pi-
+ );
+ } else if ( m_outCode == 11 ) {
+ // 1=K+ 2 = pi+ 3 = pi+ 4 = pi- 5 = pi- with symmetrization
+ hardCur = m_WCurr->WCurrent_K4pi(
+ parent->getDaug( m_iKPlus[0] )->getP4(), // K+
+ parent->getDaug( m_iPiPlus[0] )->getP4(), // pi+
+ parent->getDaug( m_iPiPlus[1] )->getP4(), // pi+
+ parent->getDaug( m_iPiMinus[0] )->getP4(), // pi-
+ parent->getDaug( m_iPiMinus[1] )->getP4() // pi-
);
- } else {
- EvtGenReport( EVTGEN_ERROR, "EvtBcHad" )
- << "hardCurr: Have not yet implemented this final state in BC_VHAD model"
- << std::endl;
- // EvtGenReport(EVTGEN_ERROR, "EvtGen") << "Have not yet implemented this final state in BC_VHAD model" << std::endl;
- // EvtGenReport(EVTGEN_ERROR, "EvtGen") << "Ndaug=" << getNDaug() << std::endl;
- for ( int id = 0; id < ( getNDaug() - 1 ); id++ ) {
- // EvtGenReport(EVTGEN_ERROR, "EvtGen") << "Daug " << id << " " << EvtPDL::name(getDaug(id)).c_str() << std::endl;
- }
- ::abort();
}
return hardCur;
}
//======================================================
-void EvtBcVHad::decay( EvtParticle* root_particle )
+void EvtBcVHad::decay( EvtParticle* parent )
{
- root_particle->initializePhaseSpace( getNDaug(), getDaugs() );
+ parent->initializePhaseSpace( getNDaug(), getDaugs() );
// Calculate hadronic current
- const EvtVector4C hardCur = hardCurr( root_particle );
+ const EvtVector4C hardCur = hardCurr( parent );
- EvtParticle* Jpsi = root_particle->getDaug( 0 );
+ EvtParticle* Jpsi = parent->getDaug( 0 );
+ //std::cout<<"4th comp: "<<Jpsi->eps(3)<<std::endl;
- const EvtVector4R p4b( root_particle->mass(), 0., 0., 0. ), // Bc momentum
- p4meson = Jpsi->getP4(), // J/psi momenta
+ const EvtVector4R p4b( parent->mass(), 0., 0., 0. ), // Bc momentum
+ p4meson = Jpsi->getP4(), // J/psi momenta
Q = p4b - p4meson, p4Sum = p4meson + p4b;
const double Q2 = Q.mass2();
// Calculate Bc -> V W form-factors
double a1f( 0.0 ), a2f( 0.0 ), vf( 0.0 ), a0f( 0.0 );
- const double m_meson = Jpsi->mass();
- const double m_b = root_particle->mass();
- const double mVar = m_b + m_meson;
+ const double mMeson = Jpsi->mass();
+ const double mB = parent->mass();
+ const double mVar = mB + mMeson;
- ffmodel->getvectorff( root_particle->getId(), Jpsi->getId(), Q2, m_meson,
- &a1f, &a2f, &vf, &a0f );
+ m_FFModel->getvectorff( parent->getId(), Jpsi->getId(), Q2, mMeson, &a1f,
+ &a2f, &vf, &a0f );
- const double a3f = ( mVar / ( 2.0 * m_meson ) ) * a1f -
- ( ( m_b - m_meson ) / ( 2.0 * m_meson ) ) * a2f;
+ const double a3f = ( mVar / ( 2.0 * mMeson ) ) * a1f -
+ ( ( mB - mMeson ) / ( 2.0 * mMeson ) ) * a2f;
// Calculate Bc -> V W current
EvtTensor4C H = a1f * mVar * EvtTensor4C::g();
H.addDirProd( ( -a2f / mVar ) * p4b, p4Sum );
H += EvtComplex( 0.0, vf / mVar ) *
dual( EvtGenFunctions::directProd( p4Sum, Q ) );
- H.addDirProd( ( a0f - a3f ) * 2.0 * ( m_meson / Q2 ) * p4b, Q );
+ H.addDirProd( ( a0f - a3f ) * 2.0 * ( mMeson / Q2 ) * p4b, Q );
const EvtVector4C Heps = H.cont2( hardCur );
- for ( int i = 0; i < 4; i++ ) {
+ for ( int i = 0; i < 3; i++ ) {
const EvtVector4C eps =
Jpsi->epsParent( i ).conj(); // psi-meson polarization vector
const EvtComplex amp = eps * Heps;
vertex( i, amp );
}
}
diff --git a/src/EvtGenModels/EvtBcVPPHad.cpp b/src/EvtGenModels/EvtBcVPPHad.cpp
new file mode 100644
index 0000000..abdb5b6
--- /dev/null
+++ b/src/EvtGenModels/EvtBcVPPHad.cpp
@@ -0,0 +1,166 @@
+/***********************************************************************
+* Copyright 1998-2023 CERN for the benefit of the EvtGen authors *
+* *
+* This file is part of EvtGen. *
+* *
+* EvtGen is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* EvtGen is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
+***********************************************************************/
+
+#include "EvtGenModels/EvtBcVPPHad.hh"
+
+#include "EvtGenBase/EvtDiracSpinor.hh"
+#include "EvtGenBase/EvtIdSet.hh"
+#include "EvtGenBase/EvtPDL.hh"
+#include "EvtGenBase/EvtParticle.hh"
+#include "EvtGenBase/EvtReport.hh"
+#include "EvtGenBase/EvtSpinType.hh"
+#include "EvtGenBase/EvtTensor4C.hh"
+#include "EvtGenBase/EvtVector4R.hh"
+
+#include <iostream>
+
+std::string EvtBcVPPHad::getName()
+{
+ return "BC_VPPHAD";
+}
+
+EvtDecayBase* EvtBcVPPHad::clone()
+{
+ return new EvtBcVPPHad;
+}
+
+//======================================================
+
+void EvtBcVPPHad::init()
+{
+ checkNArg( 1 );
+ checkSpinParent( EvtSpinType::SCALAR );
+ checkSpinDaughter( 0, EvtSpinType::VECTOR );
+ checkSpinDaughter( 1, EvtSpinType::DIRAC );
+ checkSpinDaughter( 2, EvtSpinType::DIRAC );
+ for ( int i = 3; i <= ( getNDaug() - 1 ); i++ ) {
+ checkSpinDaughter( i, EvtSpinType::SCALAR );
+ }
+
+ m_idVector = getDaug( 0 ).getId();
+ m_whichFit = int( getArg( 0 ) + 0.1 );
+ m_FFModel = std::make_unique<EvtBCVFF2>( m_idVector, m_whichFit );
+
+ m_WCurr = std::make_unique<EvtWHad>();
+
+ // determine the code of final hadronic state
+ const EvtIdSet thePis{ "pi+", "pi-", "pi0" };
+ const EvtIdSet theK{ "K+", "K-", "K_S0" };
+ const EvtIdSet thePs{ "p+", "anti-p-" };
+
+ if ( getNDaug() == 4 && thePs.contains( getDaug( 1 ) ) &&
+ thePs.contains( getDaug( 2 ) ) && thePis.contains( getDaug( 3 ) ) ) {
+ m_outCode = 1; // p+ p- pi+
+ } else {
+ EvtGenReport( EVTGEN_ERROR, "EvtBcPPHad::init has unknown decay mode" );
+ }
+ EvtGenReport( EVTGEN_INFO, "EvtBcVPPHad" )
+ << ": m_outCode = " << m_outCode << ", m_whichFit = " << m_whichFit
+ << std::endl;
+}
+
+//======================================================
+
+void EvtBcVPPHad::initProbMax()
+{
+ if ( m_outCode == 1 ) {
+ // p+ p- pi+
+ if ( m_idVector == EvtPDL::getId( "J/psi" ).getId() ) {
+ if ( m_whichFit == 2 ) {
+ setProbMax( 550.0 );
+ } else {
+ setProbMax( 1100.0 );
+ }
+ } else if ( m_idVector == EvtPDL::getId( "psi(2S)" ).getId() ) {
+ if ( m_whichFit == 2 ) {
+ setProbMax( 7.0 );
+ } else {
+ setProbMax( 50.0 );
+ }
+ }
+ } else {
+ EvtGenReport(
+ EVTGEN_ERROR,
+ "probmax: Have not yet implemented this final state in BC_VPPHAD model, m_outCode = " )
+ << m_outCode << std::endl;
+ }
+}
+
+//======================================================
+EvtVector4C EvtBcVPPHad::hardCurrPP( EvtParticle* parent, int i1, int i2 ) const
+{
+ EvtVector4C hardCur;
+ const EvtVector4R p1 = parent->getDaug( 1 )->getP4();
+ const EvtDiracSpinor sp1 = parent->getDaug( 1 )->spParent( i1 );
+
+ const EvtVector4R p2 = parent->getDaug( 2 )->getP4();
+ const EvtDiracSpinor sp2 = parent->getDaug( 2 )->spParent( i2 );
+
+ if ( m_outCode == 1 ) {
+ const EvtVector4R k = parent->getDaug( 3 )->getP4();
+ hardCur = m_WCurr->WCurrent_ppPi( p1, sp1, p2, sp2, k );
+ }
+ return hardCur;
+}
+
+//======================================================
+void EvtBcVPPHad::decay( EvtParticle* parent )
+{
+ parent->initializePhaseSpace( getNDaug(), getDaugs() );
+
+ EvtParticle* Jpsi = parent->getDaug( 0 );
+
+ const EvtVector4R p4b( parent->mass(), 0., 0., 0. ), // Bc momentum
+ p4meson = Jpsi->getP4(), // J/psi momenta
+ Q = p4b - p4meson, p4Sum = p4meson + p4b;
+ const double Q2 = Q.mass2();
+
+ // Calculate Bc -> V W form-factors
+ double a1f( 0.0 ), a2f( 0.0 ), vf( 0.0 ), a0f( 0.0 );
+
+ const double mMeson = Jpsi->mass();
+ const double mB = parent->mass();
+ const double mVar = mB + mMeson;
+
+ m_FFModel->getvectorff( parent->getId(), Jpsi->getId(), Q2, mMeson, &a1f,
+ &a2f, &vf, &a0f );
+
+ const double a3f = ( mVar / ( 2.0 * mMeson ) ) * a1f -
+ ( ( mB - mMeson ) / ( 2.0 * mMeson ) ) * a2f;
+
+ // Calculate Bc -> V W current
+ EvtTensor4C H = a1f * mVar * EvtTensor4C::g();
+ H.addDirProd( ( -a2f / mVar ) * p4b, p4Sum );
+ H += EvtComplex( 0.0, vf / mVar ) *
+ dual( EvtGenFunctions::directProd( p4Sum, Q ) );
+ H.addDirProd( ( a0f - a3f ) * 2.0 * ( mMeson / Q2 ) * p4b, Q );
+
+ for ( int i1 = 0; i1 < 2; ++i1 ) {
+ for ( int i2 = 0; i2 < 2; ++i2 ) {
+ const EvtVector4C hardCur = hardCurrPP( parent, i1, i2 );
+ const EvtVector4C Heps = H.cont2( hardCur );
+ for ( int i = 0; i < 3; i++ ) {
+ // psi-meson polarization vector
+ const EvtVector4C eps = Jpsi->epsParent( i ).conj();
+ const EvtComplex amp = eps * Heps;
+ vertex( i, i1, i2, amp );
+ }
+ }
+ }
+}
diff --git a/src/EvtGenModels/EvtModelReg.cpp b/src/EvtGenModels/EvtModelReg.cpp
index 17a1371..6ef16bb 100644
--- a/src/EvtGenModels/EvtModelReg.cpp
+++ b/src/EvtGenModels/EvtModelReg.cpp
@@ -1,349 +1,351 @@
/***********************************************************************
* Copyright 1998-2021 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#include "EvtGenModels/EvtModelReg.hh"
#include "EvtGenBase/EvtModel.hh"
#include "EvtGenBase/EvtPDL.hh"
#include "EvtGenBase/EvtParticle.hh"
#include "EvtGenBase/EvtPatches.hh"
#include "EvtGenModels/EvtBBScalar.hh"
#include "EvtGenModels/EvtBHadronic.hh"
#include "EvtGenModels/EvtBLLNuL.hh"
#include "EvtGenModels/EvtBTo3piCP.hh"
#include "EvtGenModels/EvtBTo4piCP.hh"
#include "EvtGenModels/EvtBToDDalitzCPK.hh"
#include "EvtGenModels/EvtBToDiBaryonlnupQCD.hh"
#include "EvtGenModels/EvtBToKpipiCP.hh"
#include "EvtGenModels/EvtBToPlnuBK.hh"
#include "EvtGenModels/EvtBToVlnuBall.hh"
#include "EvtGenModels/EvtBToXElNu.hh"
#include "EvtGenModels/EvtBaryonPCR.hh"
#include "EvtGenModels/EvtBcBsNPi.hh"
#include "EvtGenModels/EvtBcBsStarNPi.hh"
#include "EvtGenModels/EvtBcPsiNPi.hh"
#include "EvtGenModels/EvtBcSMuNu.hh"
#include "EvtGenModels/EvtBcTMuNu.hh"
#include "EvtGenModels/EvtBcToNPi.hh"
#include "EvtGenModels/EvtBcVHad.hh"
#include "EvtGenModels/EvtBcVMuNu.hh"
#include "EvtGenModels/EvtBcVNpi.hh"
+#include "EvtGenModels/EvtBcVPPHad.hh"
#include "EvtGenModels/EvtBsMuMuKK.hh"
#include "EvtGenModels/EvtBsquark.hh"
#include "EvtGenModels/EvtBto2piCPiso.hh"
#include "EvtGenModels/EvtBtoKD3P.hh"
#include "EvtGenModels/EvtBtoKpiCPiso.hh"
#include "EvtGenModels/EvtBtoXsEtap.hh"
#include "EvtGenModels/EvtBtoXsgamma.hh"
#include "EvtGenModels/EvtBtoXsll.hh"
#include "EvtGenModels/EvtCBTo3piMPP.hh"
#include "EvtGenModels/EvtCBTo3piP00.hh"
#include "EvtGenModels/EvtD0gammaDalitz.hh"
#include "EvtGenModels/EvtD0mixDalitz.hh"
#include "EvtGenModels/EvtDDalitz.hh"
#include "EvtGenModels/EvtDMix.hh"
#include "EvtGenModels/EvtDToKpienu.hh"
#include "EvtGenModels/EvtEtaDalitz.hh"
#include "EvtGenModels/EvtEtaLLPiPi.hh"
#include "EvtGenModels/EvtFlatQ2.hh"
#include "EvtGenModels/EvtFlatSqDalitz.hh"
#include "EvtGenModels/EvtFourBodyPhsp.hh"
#include "EvtGenModels/EvtGenericDalitz.hh"
#include "EvtGenModels/EvtGoityRoberts.hh"
#include "EvtGenModels/EvtHQET.hh"
#include "EvtGenModels/EvtHQET2.hh"
#include "EvtGenModels/EvtHelAmp.hh"
#include "EvtGenModels/EvtHypNonLepton.hh"
#include "EvtGenModels/EvtISGW.hh"
#include "EvtGenModels/EvtISGW2.hh"
#include "EvtGenModels/EvtKKLambdaC.hh"
#include "EvtGenModels/EvtKStopizmumu.hh"
#include "EvtGenModels/EvtKstarnunu.hh"
#include "EvtGenModels/EvtKstarstargamma.hh"
#include "EvtGenModels/EvtLNuGamma.hh"
#include "EvtGenModels/EvtLambdaB2LambdaV.hh"
#include "EvtGenModels/EvtLambdaP_BarGamma.hh"
#include "EvtGenModels/EvtLambdacPHH.hh"
#include "EvtGenModels/EvtLb2Baryonlnu.hh"
#include "EvtGenModels/EvtLb2Lll.hh"
#include "EvtGenModels/EvtLb2plnuLCSR.hh"
#include "EvtGenModels/EvtLb2plnuLQCD.hh"
#include "EvtGenModels/EvtMelikhov.hh"
#include "EvtGenModels/EvtMultibody.hh"
#include "EvtGenModels/EvtOmegaDalitz.hh"
#include "EvtGenModels/EvtPVVCPLH.hh"
#include "EvtGenModels/EvtPartWave.hh"
#include "EvtGenModels/EvtPhiDalitz.hh"
#include "EvtGenModels/EvtPhsp.hh"
#include "EvtGenModels/EvtPhspDecaytimeCut.hh"
#include "EvtGenModels/EvtPhspFlatLifetime.hh"
#include "EvtGenModels/EvtPi0Dalitz.hh"
#include "EvtGenModels/EvtPropSLPole.hh"
#include "EvtGenModels/EvtPsi2JpsiPiPi.hh"
#include "EvtGenModels/EvtPto3P.hh"
#include "EvtGenModels/EvtRareLbToLll.hh"
#include "EvtGenModels/EvtSLBKPole.hh"
#include "EvtGenModels/EvtSLN.hh"
#include "EvtGenModels/EvtSLPole.hh"
#include "EvtGenModels/EvtSSDCP.hh"
#include "EvtGenModels/EvtSSD_DirectCP.hh"
#include "EvtGenModels/EvtSSSCP.hh"
#include "EvtGenModels/EvtSSSCPT.hh"
#include "EvtGenModels/EvtSSSCPpng.hh"
#include "EvtGenModels/EvtSTS.hh"
#include "EvtGenModels/EvtSTSCP.hh"
#include "EvtGenModels/EvtSVP.hh"
#include "EvtGenModels/EvtSVPCP.hh"
#include "EvtGenModels/EvtSVPHelAmp.hh"
#include "EvtGenModels/EvtSVPHelCPMix.hh"
#include "EvtGenModels/EvtSVS.hh"
#include "EvtGenModels/EvtSVSCP.hh"
#include "EvtGenModels/EvtSVSCPLH.hh"
#include "EvtGenModels/EvtSVSCPiso.hh"
#include "EvtGenModels/EvtSVSNONCPEIGEN.hh"
#include "EvtGenModels/EvtSVVCP.hh"
#include "EvtGenModels/EvtSVVCPLH.hh"
#include "EvtGenModels/EvtSVVHelAmp.hh"
#include "EvtGenModels/EvtSVVHelCPMix.hh"
#include "EvtGenModels/EvtSVVNONCPEIGEN.hh"
#include "EvtGenModels/EvtSingleParticle.hh"
#include "EvtGenModels/EvtSll.hh"
#include "EvtGenModels/EvtTSS.hh"
#include "EvtGenModels/EvtTVP.hh"
#include "EvtGenModels/EvtTVSPwave.hh"
#include "EvtGenModels/EvtTauHadnu.hh"
#include "EvtGenModels/EvtTauScalarnu.hh"
#include "EvtGenModels/EvtTauVectornu.hh"
#include "EvtGenModels/EvtTaulnunu.hh"
#include "EvtGenModels/EvtThreeBodyPhsp.hh"
#include "EvtGenModels/EvtVPHOtoVISRHi.hh"
#include "EvtGenModels/EvtVSPPwave.hh"
#include "EvtGenModels/EvtVSS.hh"
#include "EvtGenModels/EvtVSSBMixCPT.hh"
#include "EvtGenModels/EvtVSSMix.hh"
#include "EvtGenModels/EvtVVP.hh"
#include "EvtGenModels/EvtVVPIPI_WEIGHTED.hh"
#include "EvtGenModels/EvtVVSPwave.hh"
#include "EvtGenModels/EvtVVpipi.hh"
#include "EvtGenModels/EvtVectorIsr.hh"
#include "EvtGenModels/EvtVll.hh"
#include "EvtGenModels/EvtVtoSll.hh"
#include "EvtGenModels/EvtVub.hh"
#include "EvtGenModels/EvtVubBLNP.hh"
#include "EvtGenModels/EvtVubBLNPHybrid.hh"
#include "EvtGenModels/EvtVubHybrid.hh"
#include "EvtGenModels/EvtVubNLO.hh"
#include "EvtGenModels/EvtXPsiGamma.hh"
#include "EvtGenModels/EvtY3SToY1SpipiMoxhay.hh"
#include "EvtGenModels/EvtYmSToYnSpipiCLEO.hh"
#include "EvtGenModels/EvtbTosllAli.hh"
#include "EvtGenModels/EvtbTosllBall.hh"
#include "EvtGenModels/EvtbTosllMS.hh"
#include "EvtGenModels/EvtbTosllMSExt.hh"
#include "EvtGenModels/Evtbs2llGammaISRFSR.hh"
#include "EvtGenModels/Evtbs2llGammaMNT.hh"
#include "EvtGenModels/EvtbsToLLLL.hh"
#include "EvtGenModels/EvtbsToLLLLHyperCP.hh"
#include <assert.h>
#include <ctype.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <stdlib.h>
using std::cout;
using std::endl;
using std::fstream;
EvtModelReg::EvtModelReg( const std::list<EvtDecayBase*>* extraModels )
{
EvtModel& modelist = EvtModel::instance();
if ( extraModels ) {
for ( std::list<EvtDecayBase*>::const_iterator it = extraModels->begin();
it != extraModels->end(); ++it ) {
modelist.registerModel( *it );
}
}
modelist.registerModel( new EvtBBScalar );
modelist.registerModel( new EvtLambdaP_BarGamma );
modelist.registerModel( new EvtFlatQ2 );
modelist.registerModel( new EvtTauHadnu );
modelist.registerModel( new EvtTauVectornu );
modelist.registerModel( new EvtVVP );
modelist.registerModel( new EvtSLN );
modelist.registerModel( new EvtISGW2 );
modelist.registerModel( new EvtMelikhov );
modelist.registerModel( new EvtSLPole );
modelist.registerModel( new EvtPropSLPole );
modelist.registerModel( new EvtSLBKPole );
modelist.registerModel( new EvtHQET );
modelist.registerModel( new EvtHQET2 );
modelist.registerModel( new EvtISGW );
modelist.registerModel( new EvtBHadronic );
modelist.registerModel( new EvtVSS );
modelist.registerModel( new EvtVSSMix );
modelist.registerModel( new EvtVSSBMixCPT );
modelist.registerModel( new EvtVSPPwave );
modelist.registerModel( new EvtGoityRoberts );
modelist.registerModel( new EvtSVS );
modelist.registerModel( new EvtTSS );
modelist.registerModel( new EvtTVSPwave );
modelist.registerModel( new EvtSVVHelAmp );
modelist.registerModel( new EvtSVPHelAmp );
modelist.registerModel( new EvtSVPCP );
modelist.registerModel( new EvtVVSPwave );
modelist.registerModel( new EvtDDalitz );
modelist.registerModel( new EvtOmegaDalitz );
modelist.registerModel( new EvtEtaDalitz );
modelist.registerModel( new EvtPhsp );
modelist.registerModel( new EvtPhspDecaytimeCut );
modelist.registerModel( new EvtBtoXsgamma );
modelist.registerModel( new EvtBtoXsll );
modelist.registerModel( new EvtBtoXsEtap );
modelist.registerModel( new EvtSSSCP );
modelist.registerModel( new EvtSSSCPpng );
modelist.registerModel( new EvtSTSCP );
modelist.registerModel( new EvtSTS );
modelist.registerModel( new EvtSSSCPT );
modelist.registerModel( new EvtSVSCP );
modelist.registerModel( new EvtSSDCP );
modelist.registerModel( new EvtSVSNONCPEIGEN );
modelist.registerModel( new EvtSVVNONCPEIGEN );
modelist.registerModel( new EvtSVVCP );
modelist.registerModel( new EvtSVVCPLH );
modelist.registerModel( new EvtSVSCPLH );
modelist.registerModel( new EvtSll );
modelist.registerModel( new EvtVll );
modelist.registerModel( new EvtTaulnunu );
modelist.registerModel( new EvtTauScalarnu );
modelist.registerModel( new EvtKstarnunu );
modelist.registerModel( new EvtbTosllBall );
modelist.registerModel( new EvtBto2piCPiso );
modelist.registerModel( new EvtBtoKpiCPiso );
modelist.registerModel( new EvtSVSCPiso );
modelist.registerModel( new EvtSingleParticle );
modelist.registerModel( new EvtVectorIsr );
modelist.registerModel( new EvtPi0Dalitz );
modelist.registerModel( new EvtHelAmp );
modelist.registerModel( new EvtPartWave );
modelist.registerModel( new EvtVVpipi );
modelist.registerModel( new EvtY3SToY1SpipiMoxhay );
modelist.registerModel( new EvtYmSToYnSpipiCLEO );
modelist.registerModel( new EvtBsquark );
modelist.registerModel( new EvtPhiDalitz );
modelist.registerModel( new EvtBToPlnuBK );
modelist.registerModel( new EvtBToVlnuBall );
modelist.registerModel( new EvtVVPIPI_WEIGHTED );
modelist.registerModel( new EvtVPHOtoVISRHi );
modelist.registerModel( new EvtBTo4piCP );
modelist.registerModel( new EvtBTo3piCP );
modelist.registerModel( new EvtCBTo3piP00 );
modelist.registerModel( new EvtCBTo3piMPP );
modelist.registerModel( new EvtBToKpipiCP );
modelist.registerModel( new EvtLb2Lll );
modelist.registerModel( new EvtRareLbToLll );
modelist.registerModel( new EvtHypNonLepton );
modelist.registerModel( new EvtSVVHelCPMix );
modelist.registerModel( new EvtSVPHelCPMix );
modelist.registerModel( new EvtLNuGamma );
modelist.registerModel( new EvtKstarstargamma );
modelist.registerModel( new EvtVub );
modelist.registerModel( new EvtVubHybrid );
modelist.registerModel( new EvtVubNLO );
modelist.registerModel( new EvtVubBLNP );
modelist.registerModel( new EvtVubBLNPHybrid );
modelist.registerModel( new EvtPto3P );
modelist.registerModel( new EvtBtoKD3P );
modelist.registerModel( new EvtKKLambdaC );
modelist.registerModel( new EvtMultibody );
modelist.registerModel( new EvtDMix );
modelist.registerModel( new EvtD0mixDalitz );
modelist.registerModel( new EvtD0gammaDalitz );
modelist.registerModel( new EvtbTosllAli );
modelist.registerModel( new EvtBaryonPCR );
modelist.registerModel( new EvtBToDDalitzCPK );
modelist.registerModel( new EvtLambdaB2LambdaV );
modelist.registerModel( new EvtLambda2PPiForLambdaB2LambdaV );
modelist.registerModel( new EvtV2VpVmForLambdaB2LambdaV );
modelist.registerModel( new EvtPVVCPLH );
modelist.registerModel( new EvtSSD_DirectCP );
- modelist.registerModel( new EvtBcToNPi( true ) ); // true = print author info
+ modelist.registerModel( new EvtBcToNPi );
modelist.registerModel( new EvtBcPsiNPi );
modelist.registerModel( new EvtBcBsNPi );
modelist.registerModel( new EvtBcBsStarNPi );
modelist.registerModel( new EvtBcSMuNu );
modelist.registerModel( new EvtBcVMuNu );
modelist.registerModel( new EvtBcTMuNu );
modelist.registerModel( new EvtBcVNpi );
modelist.registerModel( new EvtSVP );
modelist.registerModel( new EvtTVP );
modelist.registerModel( new EvtXPsiGamma );
modelist.registerModel( new EvtbsToLLLL );
modelist.registerModel( new EvtbsToLLLLHyperCP );
modelist.registerModel( new EvtBLLNuL );
modelist.registerModel( new EvtKStopizmumu );
modelist.registerModel( new EvtVtoSll );
modelist.registerModel( new EvtBsMuMuKK );
- modelist.registerModel( new EvtGenericDalitz() );
+ modelist.registerModel( new EvtGenericDalitz );
modelist.registerModel( new EvtBcVHad );
+ modelist.registerModel( new EvtBcVPPHad );
modelist.registerModel( new Evtbs2llGammaMNT );
modelist.registerModel( new Evtbs2llGammaISRFSR );
modelist.registerModel( new EvtbTosllMS );
modelist.registerModel( new EvtbTosllMSExt );
modelist.registerModel( new EvtLb2plnuLQCD );
modelist.registerModel( new EvtLb2plnuLCSR );
modelist.registerModel( new EvtLb2Baryonlnu );
modelist.registerModel( new EvtBToDiBaryonlnupQCD );
modelist.registerModel( new EvtFlatSqDalitz );
modelist.registerModel( new EvtPhspFlatLifetime );
modelist.registerModel( new EvtLambdacPHH );
modelist.registerModel( new EvtDToKpienu );
modelist.registerModel( new EvtPsi2JpsiPiPi );
modelist.registerModel( new EvtThreeBodyPhsp );
modelist.registerModel( new EvtFourBodyPhsp );
modelist.registerModel( new EvtEtaLLPiPi );
modelist.registerModel( new EvtBToXElNu );
}
diff --git a/src/EvtGenModels/EvtPhiDalitz.cpp b/src/EvtGenModels/EvtPhiDalitz.cpp
index 5c72b0d..2f7408a 100644
--- a/src/EvtGenModels/EvtPhiDalitz.cpp
+++ b/src/EvtGenModels/EvtPhiDalitz.cpp
@@ -1,168 +1,210 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#include "EvtGenModels/EvtPhiDalitz.hh"
#include "EvtGenBase/EvtGenKine.hh"
#include "EvtGenBase/EvtPDL.hh"
#include "EvtGenBase/EvtParticle.hh"
#include "EvtGenBase/EvtPatches.hh"
#include "EvtGenBase/EvtReport.hh"
+#include "EvtGenBase/EvtVector3C.hh"
+#include "EvtGenBase/EvtVector3R.hh"
+#include "EvtGenBase/EvtVector4C.hh"
#include "EvtGenBase/EvtVector4R.hh"
#include <math.h>
#include <stdlib.h>
#include <string>
// Implementation of KLOE measurement
// PL B561: 55-60 (2003) + Erratum B609:449-450 (2005)
// or hep-ex/0303016v2
std::string EvtPhiDalitz::getName()
{
return "PHI_DALITZ";
}
EvtDecayBase* EvtPhiDalitz::clone()
{
return new EvtPhiDalitz;
}
void EvtPhiDalitz::init()
{
// check that there are 0 arguments
checkNArg( 0 );
checkNDaug( 3 );
checkSpinParent( EvtSpinType::VECTOR );
checkSpinDaughter( 0, EvtSpinType::SCALAR );
checkSpinDaughter( 1, EvtSpinType::SCALAR );
checkSpinDaughter( 2, EvtSpinType::SCALAR );
- _mRho = 0.7758;
- _gRho = 0.1439;
- _aD = 0.78;
- _phiD = -2.47;
- _aOmega = 0.0071;
- _phiOmega = -0.22;
+ // results taken from KLOE results: arxiv.org/abs/hep-ex/0303016
+ m_mRho = 0.7758;
+ m_gRho = 0.1439;
+ m_aD = 0.78;
+ m_phiD = -2.47;
+ m_aOmega = 0.0071;
+ m_phiOmega = -0.22;
- _locPip = -1;
- _locPim = -1;
- _locPi0 = -1;
+ m_locPip = -1;
+ m_locPim = -1;
+ m_locPi0 = -1;
for ( int i = 0; i < 3; i++ ) {
if ( getDaug( i ) == EvtPDL::getId( "pi+" ) )
- _locPip = i;
+ m_locPip = i;
if ( getDaug( i ) == EvtPDL::getId( "pi-" ) )
- _locPim = i;
+ m_locPim = i;
if ( getDaug( i ) == EvtPDL::getId( "pi0" ) )
- _locPi0 = i;
+ m_locPi0 = i;
}
- if ( _locPip == -1 || _locPim == -1 || _locPi0 == -1 ) {
+ if ( m_locPip == -1 || m_locPim == -1 || m_locPi0 == -1 ) {
EvtGenReport( EVTGEN_ERROR, "EvtGen" )
<< getModelName()
<< "generator expects daughters to be pi+ pi- pi0\n";
EvtGenReport( EVTGEN_ERROR, "EvtGen" )
<< "Found " << EvtPDL::name( getDaug( 0 ) ) << " "
<< EvtPDL::name( getDaug( 1 ) ) << " "
<< EvtPDL::name( getDaug( 2 ) ) << std::endl;
}
}
void EvtPhiDalitz::initProbMax()
{
- setProbMax( 150.0 );
+ setProbMax( 300.0 );
}
void EvtPhiDalitz::decay( EvtParticle* p )
{
- EvtId PIP = EvtPDL::getId( "pi+" );
- EvtId PIM = EvtPDL::getId( "pi-" );
- EvtId PIZ = EvtPDL::getId( "pi0" );
- EvtId OMEGA = EvtPDL::getId( "omega" );
+ const EvtId PIP = EvtPDL::getId( "pi+" );
+ const EvtId PIM = EvtPDL::getId( "pi-" );
+ const EvtId PIZ = EvtPDL::getId( "pi0" );
+ const EvtId OMEGA = EvtPDL::getId( "omega" );
p->initializePhaseSpace( getNDaug(), getDaugs() );
- EvtVector4R Ppip = p->getDaug( _locPip )->getP4();
- EvtVector4R Ppim = p->getDaug( _locPim )->getP4();
- EvtVector4R Ppi0 = p->getDaug( _locPi0 )->getP4();
- EvtVector4R Qp = ( Ppim + Ppi0 );
- EvtVector4R Qm = ( Ppip + Ppi0 );
- EvtVector4R Q0 = ( Ppip + Ppim );
- double m2_pip = pow( EvtPDL::getMeanMass( PIP ), 2 );
- double m2_pim = pow( EvtPDL::getMeanMass( PIM ), 2 );
- double m2_pi0 = pow( EvtPDL::getMeanMass( PIZ ), 2 );
- double M2rhop = pow( _mRho, 2 );
- double M2rhom = pow( _mRho, 2 );
- double M2rho0 = pow( _mRho, 2 );
- double M2omega = pow( EvtPDL::getMeanMass( OMEGA ), 2 );
-
- double Wrhop = _gRho;
- double Wrhom = _gRho;
- double Wrho0 = _gRho;
- double Womega = EvtPDL::getWidth( OMEGA );
-
- EvtComplex Atot( 0, 0 );
-
- //Rho+ Risonance Amplitude
- double Gp = Wrhop *
- pow( ( ( Qp.mass2() - m2_pim - m2_pi0 ) / 2 - M2rhop / 4 ) /
- ( M2rhop / 4 - ( m2_pim + m2_pi0 ) / 2 ),
- 3 / 2 ) *
- ( M2rhop / Qp.mass2() );
- EvtComplex Drhop( ( Qp.mass2() - M2rhop ), Qp.mass() * Gp );
- EvtComplex A1( M2rhop / Drhop );
-
- //Rho- Risonance Amplitude
- double Gm = Wrhom *
- pow( ( ( Qm.mass2() - m2_pip - m2_pi0 ) / 2 - M2rhom / 4 ) /
- ( M2rhom / 4 - ( m2_pip + m2_pi0 ) / 2 ),
- 3 / 2 ) *
- ( M2rhom / Qm.mass2() );
- EvtComplex Drhom( ( Qm.mass2() - M2rhom ), Qm.mass() * Gm );
- EvtComplex A2( M2rhom / Drhom );
-
- //Rho0 Risonance Amplitude
- double G0 = Wrho0 *
- pow( ( ( Q0.mass2() - m2_pip - m2_pim ) / 2 - M2rho0 / 4 ) /
- ( M2rho0 / 4 - ( m2_pip + m2_pim ) / 2 ),
- 3 / 2 ) *
- ( M2rho0 / Q0.mass2() );
- EvtComplex Drho0( ( Q0.mass2() - M2rho0 ), Q0.mass() * G0 );
- EvtComplex A3( M2rho0 / Drho0 );
-
- //Omega Risonance Amplitude
- EvtComplex OmegaPhase( 0, _phiOmega );
- EvtComplex DOmega( ( Q0.mass2() - M2omega ), Q0.mass() * Womega );
- EvtComplex A4( _aOmega * M2omega * exp( OmegaPhase ) / DOmega );
+ const EvtVector4R Ppip = p->getDaug( m_locPip )->getP4();
+ const EvtVector4R Ppim = p->getDaug( m_locPim )->getP4();
+ const EvtVector4R Ppi0 = p->getDaug( m_locPi0 )->getP4();
+ const EvtVector4R Qm = ( Ppim + Ppi0 );
+ const EvtVector4R Qp = ( Ppip + Ppi0 );
+ const EvtVector4R Q0 = ( Ppip + Ppim );
+ const double m_pip = EvtPDL::getMeanMass( PIP );
+ const double m_pim = EvtPDL::getMeanMass( PIM );
+ const double m_pi0 = EvtPDL::getMeanMass( PIZ );
+ const double Mrhop = m_mRho;
+ const double Mrhom = m_mRho;
+ const double Mrho0 = m_mRho;
+ const double M2rhop = pow( Mrhop, 2 );
+ const double M2rhom = pow( Mrhom, 2 );
+ const double M2rho0 = pow( Mrho0, 2 );
+ const double M2omega = pow( EvtPDL::getMeanMass( OMEGA ), 2 );
+
+ const double Wrhop = m_gRho;
+ const double Wrhom = m_gRho;
+ const double Wrho0 = m_gRho;
+ const double Womega = EvtPDL::getWidth( OMEGA );
+
+ const double QmM = Qm.mass();
+ const double QmM2 = Qm.mass2();
+ const double QpM = Qp.mass();
+ const double QpM2 = Qp.mass2();
+ const double Q0M = Q0.mass();
+ const double Q0M2 = Q0.mass2();
+
+ //Rho- Resonance Amplitude
+ const double qm = calc_q( QmM, m_pim, m_pi0 );
+ const double qm_0 = calc_q( Mrhom, m_pim, m_pi0 );
+ const double Gm = Wrhom * pow( qm / qm_0, 3 ) * ( M2rhom / QmM2 );
+ const EvtComplex Drhom( ( QmM2 - M2rhom ), QmM * Gm );
+ const EvtComplex A1( M2rhom / Drhom );
+
+ //Rho+ Resonance Amplitude
+ const double qp = calc_q( QpM, m_pip, m_pi0 );
+ const double qp_0 = calc_q( Mrhop, m_pip, m_pi0 );
+ const double Gp = Wrhop * pow( qp / qp_0, 3 ) * ( M2rhop / QpM2 );
+ const EvtComplex Drhop( ( QpM2 - M2rhop ), QpM * Gp );
+ const EvtComplex A2( M2rhop / Drhop );
+
+ //Rho0 Resonance Amplitude
+ const double q0 = calc_q( Q0M, m_pip, m_pim );
+ const double q0_0 = calc_q( Mrho0, m_pip, m_pim );
+ const double G0 = Wrho0 * pow( q0 / q0_0, 3 ) * ( M2rho0 / Q0M2 );
+ const EvtComplex Drho0( ( Q0M2 - M2rho0 ), Q0M * G0 );
+ const EvtComplex A3( M2rho0 / Drho0 );
+
+ //Omega Resonance Amplitude
+ const EvtComplex OmegaA( m_aOmega * cos( m_phiOmega ),
+ m_aOmega * sin( m_phiOmega ) );
+ const EvtComplex DOmega( ( Q0M2 - M2omega ), Q0M * Womega );
+ const EvtComplex A4( OmegaA * M2omega / DOmega );
//Direct Decay Amplitude
- EvtComplex DirPhase( 0, _phiD );
- EvtComplex A5( _aD * exp( DirPhase ) );
+ const EvtComplex A5( m_aD * cos( m_phiD ), m_aD * sin( m_phiD ) );
- Atot = A1 + A2 + A3 + A4 + A5;
+ const EvtComplex Atot = A1 + A2 + A3 + A4 + A5;
- vertex( 0, Atot );
- vertex( 1, Atot );
- vertex( 2, Atot );
+ // Polarization
+
+ const EvtVector4C ep0 = p->eps( 0 );
+ const EvtVector4C ep1 = p->eps( 1 );
+ const EvtVector4C ep2 = p->eps( 2 );
+
+ const EvtVector3R p1( Ppip.get( 1 ), Ppip.get( 2 ), Ppip.get( 3 ) );
+ const EvtVector3R p2( Ppim.get( 1 ), Ppim.get( 2 ), Ppim.get( 3 ) );
+ const EvtVector3R q = cross( p1, p2 );
+
+ const EvtVector3C e1( ep0.get( 1 ), ep0.get( 2 ), ep0.get( 3 ) );
+ const EvtVector3C e2( ep1.get( 1 ), ep1.get( 2 ), ep1.get( 3 ) );
+ const EvtVector3C e3( ep2.get( 1 ), ep2.get( 2 ), ep2.get( 3 ) );
+
+ //This is an approximate formula of the maximum value that
+ //|q| can have.
+ const double pM = p->mass();
+ const double mSum = Ppip.mass() + Ppim.mass() + Ppi0.mass();
+ const double norm = 10.26 / ( pM * pM - mSum * mSum );
+
+ vertex( 0, norm * e1 * q * Atot );
+ vertex( 1, norm * e2 * q * Atot );
+ vertex( 2, norm * e3 * q * Atot );
return;
}
+
+double EvtPhiDalitz::calc_q( double M, double m1, double m2 ) const
+{
+ const double m12Sum = m1 + m2;
+
+ if ( M > m12Sum ) {
+ const double MSq = M * M;
+ const double m12Diff = m1 - m2;
+
+ return sqrt( ( MSq - ( m12Sum ) * ( m12Sum ) ) *
+ ( MSq - ( m12Diff ) * ( m12Diff ) ) ) /
+ ( 2.0 * M );
+ } else {
+ return 0.0;
+ }
+}
diff --git a/src/EvtGenModels/EvtWHad.cpp b/src/EvtGenModels/EvtWHad.cpp
index 9d810e3..cc122e4 100644
--- a/src/EvtGenModels/EvtWHad.cpp
+++ b/src/EvtGenModels/EvtWHad.cpp
@@ -1,459 +1,515 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#include "EvtGenModels/EvtWHad.hh"
#include "EvtGenBase/EvtPDL.hh"
#include "EvtGenBase/EvtTensor4C.hh"
EvtWHad::EvtWHad() :
mRho_(),
gamma0_(),
cK_( 0 ),
mK_(),
gammaK_(),
gKRho_(),
gKPi_(),
mPi_( EvtPDL::getMeanMass( EvtPDL::getId( "pi+" ) ) ),
mPiSq_( mPi_ * mPi_ )
{
// cK coefficients from Eur. Phys. J. C39, 41 (2005), arXiv:hep-ph/0409080 [hep-ph]
// rho(770)
mRho_.push_back( EvtPDL::getMeanMass( EvtPDL::getId( "rho0" ) ) );
gamma0_.push_back( EvtPDL::getWidth( EvtPDL::getId( "rho0" ) ) );
cK_.push_back( 1.195 );
// rho(1450)
mRho_.push_back( EvtPDL::getMeanMass( EvtPDL::getId( "rho(2S)0" ) ) );
gamma0_.push_back( EvtPDL::getWidth( EvtPDL::getId( "rho(2S)0" ) ) );
cK_.push_back( -0.112 );
// rho(1700)
mRho_.push_back( EvtPDL::getMeanMass( EvtPDL::getId( "rho(3S)0" ) ) );
gamma0_.push_back( EvtPDL::getWidth( EvtPDL::getId( "rho(3S)0" ) ) );
cK_.push_back( -0.083 );
// rho(2150), PRD 76 092005
mRho_.push_back( 2.150 );
gamma0_.push_back( 0.310 );
cK_.push_back( 0.0 );
// Storing K resonance information
// K(892)
mK_.push_back( EvtPDL::getMeanMass( EvtPDL::getId( "K*0" ) ) );
gammaK_.push_back( EvtPDL::getWidth( EvtPDL::getId( "K*0" ) ) );
gKRho_.push_back( 0.0 );
gKPi_.push_back( 3.26 );
// K1(1270)
mK_.push_back( EvtPDL::getMeanMass( EvtPDL::getId( "K_10" ) ) );
gammaK_.push_back( EvtPDL::getWidth( EvtPDL::getId( "K_10" ) ) );
gKRho_.push_back( 2.71 );
gKPi_.push_back( 0.792 );
// K1(1400)
mK_.push_back( EvtPDL::getMeanMass( EvtPDL::getId( "K'_10" ) ) );
gammaK_.push_back( EvtPDL::getWidth( EvtPDL::getId( "K'_10" ) ) );
gKRho_.push_back( 0.254 );
gKPi_.push_back( 2.509 );
}
EvtComplex EvtWHad::BWKK( double s, int i ) const
{
const double m2 = mRho_[i] * mRho_[i];
const EvtComplex qs = pcm( s );
const EvtComplex qm = pcm( m2 );
if ( abs( qm ) < 1e-10 ) {
return 0;
}
const EvtComplex rat = qs / qm;
const EvtComplex rat3 = rat * rat * rat;
if ( abs( s ) < 1e-10 ) {
return 0;
}
const EvtComplex gamma = m2 * rat3 * gamma0_[i] / s;
const EvtComplex I( 0.0, 1.0 );
const EvtComplex denBW = m2 - s - I * sqrt( s ) * gamma;
if ( abs( denBW ) < 1e-10 ) {
return 0;
}
return cK_[i] * m2 / denBW;
}
EvtVector4C EvtWHad::WCurrent_KSK( const EvtVector4R& pKS,
const EvtVector4R& pKplus ) const
{
const double s = ( pKS + pKplus ).mass2();
const EvtComplex f = BWKK( s, 0 ) + BWKK( s, 1 ) + BWKK( s, 2 );
return f * ( pKS - pKplus );
}
EvtComplex EvtWHad::pcm( double s ) const
{
const double mpi2 = 0.0196; // 0.140*0.140
if ( abs( s ) < 1e-10 )
return 0;
const double pcm2 = 1.0 - 4.0 * mpi2 / s;
EvtComplex result;
if ( pcm2 >= 0.0 ) {
result = EvtComplex( sqrt( pcm2 ), 0.0 );
} else {
result = EvtComplex( 0.0, sqrt( -pcm2 ) );
}
return result;
}
// =================== W+ -> pi_ current ========================================
EvtVector4C EvtWHad::WCurrent( const EvtVector4R& q1 ) const
{
return q1;
}
//====================== W+ -> pi+ pi0 current =========================================
EvtVector4C EvtWHad::WCurrent( const EvtVector4R& q1, const EvtVector4R& q2 ) const
{
return BWr( q1 + q2 ) * ( q1 - q2 );
}
//========================= W+ -> pi+ pi+ pi- current ==============================================
EvtVector4C EvtWHad::WCurrent( const EvtVector4R& q1, const EvtVector4R& q2,
const EvtVector4R& q3 ) const
{
const EvtVector4R Q = q1 + q2 + q3;
const EvtVector4R q13 = q1 - q3, q23 = q2 - q3;
const double Q2 = Q.mass2();
return BWa( Q ) * ( q13 - ( Q * ( Q * q13 ) / Q2 ) * BWr( q2 + q3 ) + q23 -
( Q * ( Q * q23 ) / Q2 ) * BWr( q1 + q3 ) );
}
// ================= W+ -> pi+ pi+ pi- pi- pi+ current with symmetrization ================================
EvtVector4C EvtWHad::WCurrent( const EvtVector4R& q1, const EvtVector4R& q2,
const EvtVector4R& q3, const EvtVector4R& q4,
const EvtVector4R& q5 ) const
{
const EvtVector4C term1 = JB( q1, q2, q3, q4, q5 );
const EvtVector4C term2 = JB( q5, q2, q3, q4, q1 );
const EvtVector4C term3 = JB( q1, q5, q3, q4, q2 );
const EvtVector4C term4 = JB( q1, q2, q4, q3, q5 );
const EvtVector4C term5 = JB( q5, q2, q4, q3, q1 );
const EvtVector4C term6 = JB( q1, q5, q4, q3, q2 );
const EvtVector4C V = term1 + term2 + term3 + term4 + term5 + term6;
return V;
}
// W+ -> pi+ pi+ pi+ pi- pi-
EvtVector4C EvtWHad::WCurrent_5pi( const EvtVector4R& q1, const EvtVector4R& q2,
const EvtVector4R& q3, const EvtVector4R& q4,
const EvtVector4R& q5 ) const
{
return EvtWHad::WCurrent( q1, q2, q4, q5, q3 ); // WCurrent(++--+)
}
// =========================W+ -> K+ K- pi+ current ==================================================
EvtVector4C EvtWHad::WCurrent_KKP( const EvtVector4R& pKplus,
const EvtVector4R& pKminus,
const EvtVector4R& pPiPlus ) const
{
const double mA1( 1.239 ), gammaA1( 0.600 );
const EvtVector4R q = pKplus + pKminus + pPiPlus;
const double q2 = q.mass2();
const EvtVector4R pK = pKminus + pPiPlus;
const double pK2 = pK.mass2();
const EvtComplex I( 0.0, 1.0 );
const EvtComplex den1 = 1.0 / ( q2 - mA1 * mA1 + I * mA1 * gammaA1 );
const EvtComplex den2 = 1.0 / ( pK2 - mK_[0] * mK_[0] +
I * mK_[0] * gammaK_[0] ); //K(892)
const EvtTensor4C ten = EvtTensor4C::g() -
( 1.0 / q2 ) * EvtGenFunctions::directProd( q, q );
EvtVector4C vec = den1 * den2 * ( pKminus - pPiPlus );
vec = ten.cont2( vec );
return vec;
}
// hadronic hurrent W -> K+ K- pi+ pi+ pi- with identical pi+ symmetry
EvtVector4C EvtWHad::WCurrent_KKPPP( const EvtVector4R& pKplus,
const EvtVector4R& pKminus,
const EvtVector4R& pPi1Plus,
const EvtVector4R& pPi2Plus,
const EvtVector4R& pPiMinus ) const
{
return EvtWHad::WCurrent_KKPPP_nosym( pKplus, pKminus, pPi1Plus, pPi2Plus,
pPiMinus ) +
EvtWHad::WCurrent_KKPPP_nosym( pKplus, pKminus, pPi2Plus, pPi1Plus,
pPiMinus );
}
// hadronic hurrent W -> a1(K+ K- pi1+) f0(pi2+ pi-) without identical pi+ symmetry
EvtVector4C EvtWHad::WCurrent_KKPPP_nosym( const EvtVector4R& pKplus,
const EvtVector4R& pKminus,
const EvtVector4R& pPi1Plus,
const EvtVector4R& pPi2Plus,
const EvtVector4R& pPiMinus ) const
{
const EvtVector4R pf0 = pPi2Plus + pPiMinus;
const EvtVector4C epsA1 = EvtWHad::WCurrent_KKP( pKplus, pKminus, pPi1Plus );
const EvtVector4R q = pKplus + pKminus + pPi1Plus + pPi2Plus + pPiMinus;
return BWa( q ) * epsA1 * BWf( pf0 );
}
// 1=pi+ 2=pi+ 3=pi+ 4=pi+ 5=pi- 6=pi- 7=pi- with symmetrization of the identical particles
EvtVector4C EvtWHad::WCurrent_7pi( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3, const EvtVector4R& p4,
const EvtVector4R& p5, const EvtVector4R& p6,
const EvtVector4R& p7 ) const
{
// a1 -> a1(1=pi+ 2=pi+ 3=pi+ 5=pi- 6=pi-) f0(4=pi+ 7=pi-) without symmetrization of the identical particles
// making p4 symmetric with p1, p2, p3
// p7 p5, p6
EvtVector4C eps;
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p2, p3, p4, p5, p6, p7 );
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p2, p4, p3, p5, p6, p7 );
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p4, p3, p2, p5, p6, p7 );
eps += EvtWHad::WCurrent_7pi_nosymm( p4, p2, p3, p1, p5, p6, p7 );
//
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p2, p3, p4, p5, p7, p6 );
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p2, p4, p3, p5, p7, p6 );
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p4, p3, p2, p5, p7, p6 );
eps += EvtWHad::WCurrent_7pi_nosymm( p4, p2, p3, p1, p5, p7, p6 );
//
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p2, p3, p4, p7, p6, p5 );
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p2, p4, p3, p7, p6, p5 );
eps += EvtWHad::WCurrent_7pi_nosymm( p1, p4, p3, p2, p7, p6, p5 );
eps += EvtWHad::WCurrent_7pi_nosymm( p4, p2, p3, p1, p7, p6, p5 );
return eps;
}
// a1 -> a1(1=pi+ 2=pi+ 3=pi+ 5=pi- 6=pi-) f0(4=pi+ 7=pi-) without symmetrization of the identical particles
EvtVector4C EvtWHad::WCurrent_7pi_nosymm(
const EvtVector4R& p1, const EvtVector4R& p2, const EvtVector4R& p3,
const EvtVector4R& p4, const EvtVector4R& p5, const EvtVector4R& p6,
const EvtVector4R& p7 ) const
{
const EvtVector4R qTot = p1 + p2 + p3 + p4 + p5 + p6 + p7;
const EvtVector4C eps1 = EvtWHad::WCurrent_5pi( p1, p2, p3, p5,
p6 ); // pi+ pi+ pi+ pi- pi-
const EvtVector4R pf0 = p4 + p7;
return eps1 * BWa( qTot ) * BWf( pf0 );
-};
+}
// hadronic current W+ -> K+ pi+ pi-
EvtVector4C EvtWHad::WCurrent_KPP( const EvtVector4R& pKplus,
const EvtVector4R& pPiPlus,
const EvtVector4R& pPiMinus ) const
{
const double cK1p = 0.210709, cK1r = -0.0152997, cK2p = 0.0945309,
cK2r = 0.504315;
const double gRho_PiPi = 6.02;
const EvtVector4R q = pKplus + pPiPlus + pPiMinus;
const double q2 = q.mass2();
double pp2( 0.0 );
EvtVector4C curr( 0, 0, 0, 0 ), curr1;
// W+ -> K1+(1270) -> K+ rho0 -> K+ pi+ pi-
pp2 = ( pPiPlus + pPiMinus ).mass2();
curr1 = ( pPiPlus - pPiMinus ) * Den( q2, mK_[1], gammaK_[1], gKRho_[1] ) *
Den( pp2, mRho_[0], gamma0_[0], gRho_PiPi ); //K1(1270) and rho(770)
curr = curr + cK1r * curr1;
// W+ -> K1+(1270) -> K*(892)0 pi+ -> K+ pi- pi-
pp2 = ( pKplus + pPiMinus ).mass2();
curr1 = ( pKplus - pPiMinus ) * Den( q2, mK_[1], gammaK_[1], gKPi_[1] ) *
Den( pp2, mK_[0], gammaK_[0], gKPi_[0] ); //K1(1270) and K(892)
curr = curr + cK1p * curr1;
// W+ -> K1+(1400) -> K+ rho0 -> K+ pi+ pi-
pp2 = ( pPiMinus + pPiPlus ).mass2();
curr1 = ( pPiPlus - pPiMinus ) * Den( q2, mK_[2], gammaK_[2], gKRho_[2] ) *
Den( pp2, mRho_[0], gamma0_[0], gRho_PiPi ); //K1(1400) and rho(770)
curr = curr + cK2r * curr1;
// W+ -> K1+(1400) -> K*(892)0 pi+ -> K+ pi- pi+
pp2 = ( pKplus + pPiMinus ).mass2();
curr1 = ( pKplus - pPiPlus ) * Den( q2, mK_[2], gammaK_[2], gKPi_[2] ) *
Den( pp2, mK_[0], gammaK_[0], gKPi_[0] ); //K1(1400) and K(892)
curr = curr + cK2p * curr1;
const EvtTensor4C ten = EvtTensor4C::g() -
( 1.0 / q2 ) * EvtGenFunctions::directProd( q, q );
curr = ten.cont2( curr );
return curr;
}
EvtComplex EvtWHad::Den( double qSq, const double mR, const double gammaR,
const double gR ) const
{
const EvtComplex I( 0.0, 1.0 );
const EvtComplex tmp = qSq - mR * mR + I * mR * gammaR;
if ( abs( tmp ) < 1e-10 )
return 0;
return gR / tmp;
}
// a1 -> pi+ pi+ pi- BW
EvtComplex EvtWHad::BWa( const EvtVector4R& q ) const
{
const double _mA1( 1.26 ), _GA1( 0.4 );
const double _mA1Sq = _mA1 * _mA1;
const EvtComplex I( 0.0, 1.0 );
const double Q2 = q.mass2();
const double GA1 = _GA1 * pi3G( Q2 ) / pi3G( _mA1Sq );
const EvtComplex denBA1( _mA1Sq - Q2, -1.0 * _mA1 * GA1 );
if ( abs( denBA1 ) < 1e-10 )
return 0;
return _mA1Sq / denBA1;
}
EvtComplex EvtWHad::BWf( const EvtVector4R& q ) const
{
const double mf( 0.8 ), Gf( 0.6 );
const double mfSq = mf * mf;
const EvtComplex I( 0.0, 1.0 );
const double Q2 = q.mass2();
return mfSq / ( mfSq - Q2 - I * mf * Gf );
}
EvtComplex EvtWHad::BWr( const EvtVector4R& q ) const
{
const double beta( -0.108 );
const double s = q.mass2();
const EvtComplex BW_rho = BW( s, mRho_[0], gamma0_[0], mPi_, mPi_ );
const EvtComplex BW_rhopr = BW( s, mRho_[1], gamma0_[1], mPi_, mPi_ );
return ( BW_rho + beta * BW_rhopr ) / ( 1.0 + beta );
}
double EvtWHad::pi3G( double Q2 ) const
{
const double mRhoPi = mRho_[0] + mPi_;
// Parameterisation of scaling factor for a1 (to 3pi) decay width
if ( Q2 < mRhoPi * mRhoPi ) {
const double arg = Q2 - 9. * mPiSq_;
const double arg2 = arg * arg;
const double arg3 = arg * arg2;
return 4.1 * arg3 * ( 1. - 3.3 * arg + 5.8 * arg2 );
} else {
const double Q2Sq = Q2 * Q2;
const double Q2Cu = Q2 * Q2Sq;
return Q2 * ( 1.623 + 10.38 / Q2 - 9.32 / Q2Sq + 0.65 / Q2Cu );
}
}
EvtVector4C EvtWHad::JB( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3, const EvtVector4R& p4,
const EvtVector4R& p5 ) const
{
const EvtVector4R Qtot = p1 + p2 + p3 + p4 + p5, Qa = p1 + p2 + p3;
const EvtTensor4C T = ( 1.0 / Qtot.mass2() ) *
EvtGenFunctions::directProd( Qtot, Qtot ) -
EvtTensor4C::g();
const EvtVector4R p13 = p1 - p3, p23 = p2 - p3;
const EvtVector4R V13 = Qa * ( p2 * p13 ) / Qa.mass2() - p13;
const EvtVector4R V23 = Qa * ( p1 * p23 ) / Qa.mass2() - p23;
return BWa( Qtot ) * BWa( Qa ) * BWf( p4 + p5 ) *
( T.cont1( V13 ) * BWr( p1 + p3 ) + T.cont1( V23 ) * BWr( p2 + p3 ) );
}
EvtComplex EvtWHad::BW( double s, double m, double gamma, double xm1,
double xm2 ) const
{
const double m2 = m * m;
const double xmSum = xm1 + xm2;
const double xmSumSq = xmSum * xmSum;
if ( s > xmSumSq ) {
const double xmDiff = xm1 - xm2;
const double xmDiffSq = xmDiff * xmDiff;
const double qs = sqrt( fabs( ( s - xmSumSq ) * ( s - xmDiffSq ) ) ) /
sqrt( s );
const double qm = sqrt( fabs( ( m2 - xmSumSq ) * ( m2 - xmDiffSq ) ) ) /
m;
const double qRatio = qm > 0.0 ? qs / qm : 0.0;
gamma *= m2 / s * ( qRatio * qRatio * qRatio );
} else
gamma = 0.;
const EvtComplex denBW( m2 - s, -1. * sqrt( s ) * gamma );
return m2 / denBW;
}
EvtVector4C EvtWHad::WCurrent_K4pi( const EvtVector4R& p1, const EvtVector4R& p2,
const EvtVector4R& p3, const EvtVector4R& p4,
const EvtVector4R& p5 ) const
{
return EvtWHad::WCurrent_K4pi_nosymm( p1, p2, p3, p4, p5 ) +
EvtWHad::WCurrent_K4pi_nosymm( p1, p2, p3, p5, p4 );
}
// a1 -> K*0 (1=K+ 4=pi-) a1(2=pi+ 3=pi+ 5=pi-)
EvtVector4C EvtWHad::WCurrent_K4pi_nosymm( const EvtVector4R& p1,
const EvtVector4R& p2,
const EvtVector4R& p3,
const EvtVector4R& p4,
const EvtVector4R& p5 ) const
{
const EvtComplex I( 0, 1 );
const EvtVector4R pKstar = p1 + p4, pa1 = p2 + p3 + p5;
EvtComplex denKstar = pKstar * pKstar - mK_[0] * mK_[0] +
I * mK_[0] * gammaK_[0]; //K(892)
if ( abs( denKstar ) < 1e-10 ) {
denKstar = 1e10;
}
const EvtVector4C epsKstar = 1 / denKstar * ( p1 - p4 );
const EvtVector4C epsA1 = WCurrent( p2, p3, p5 );
const EvtVector4C eps =
dual( EvtGenFunctions::directProd( epsKstar, epsA1 ) ).cont2( pKstar - pa1 );
return eps;
}
+
+EvtVector4C EvtWHad::WCurrent_ppPi( const EvtVector4R& p1,
+ const EvtDiracSpinor& sp1,
+ const EvtVector4R& p2,
+ const EvtDiracSpinor& sp2,
+ const EvtVector4R& k ) const
+{
+ const EvtVector4R q = p1 + p2 + k;
+ const double q2 = q.mass2();
+ const double mp = p1.mass(), mp2 = mp * mp, mpi = k.mass(), mpi2 = mpi * mpi;
+ const double mn = EvtPDL::getMeanMass( EvtPDL::getId( "n0" ) );
+ const double mn2 = mn * mn;
+ const EvtComplex II( 0, 1 );
+
+ const double kp2 = k * p2;
+ const double p1p2 = p1 * p2;
+
+ const double f1 = 1.0;
+ const double f2 = 3.7 / ( 2.0 + mp );
+ const double g1 = 1.25;
+ const double g3 = 2.0 * mp * g1 / ( p1p2 + mp2 );
+
+ const EvtComplex curS = EvtLeptonSCurrent( sp1, sp2 );
+ const EvtComplex curP = EvtLeptonPCurrent( sp1, sp2 );
+ const EvtVector4C curV = EvtLeptonVCurrent( sp1, sp2 );
+ const EvtVector4C curA = EvtLeptonACurrent( sp1, sp2 );
+ const EvtTensor4C curT = EvtLeptonTCurrent( sp1, sp2 );
+
+ const double D1 = 1 / ( 2 * kp2 + mp2 - mn2 + mpi2 ); //(k+p2)^2-mn^2
+
+ // Amplitude: ~U(p1).GA5.Vpp(alpha).prop(-p2-k).V(p2) + permutations
+ // U() and V() are proton and antiproton spinors, prop() is the proton's propagator,
+ // and Vpp(alpha) is the W->pp vertex.
+ // Expand terms to use basic spinor currents (Scalar, Vector, Axial, etc)
+
+ EvtVector4C current;
+ current += curA * ( -( f2 * II ) );
+ current += ( D1 * g1 * II ) * curT.cont2( k );
+ current += -( -0.5 * ( D1 * f1 ) ) * dual( curT ).cont2( k );
+ current += -( D1 * f2 * II * mp ) * dual( curT ).cont2( k );
+ current += k * ( -( D1 * g1 ) ) * curS;
+ current += k * ( -( D1 * f1 ) ) * curP;
+ current += k * ( 2 * D1 * f2 * II * mp ) * curP;
+ current += k * ( curV * k ) * ( D1 * g3 );
+ current += k * ( curA * k ) * ( D1 * f2 * II );
+ current += p1 * ( curV * k ) * ( D1 * g3 );
+ current += p1 * ( curA * k ) * ( -( D1 * f2 * II ) );
+ current += p2 * ( curV * k ) * ( D1 * g3 );
+ current += p2 * ( curA * k ) * ( D1 * f2 * II );
+
+ const EvtTensor4C JT = ( 1.0 / q2 ) * EvtGenFunctions::directProd( q, q ) -
+ EvtTensor4C::g();
+ current = JT.cont2( current );
+
+ return BWa( q ) * current;
+}
diff --git a/test/jsonFiles/BC_VPPHAD1=VLL__Bc_Jpsippbarpi_mumu.json b/test/jsonFiles/BC_VPPHAD1=VLL__Bc_Jpsippbarpi_mumu.json
new file mode 100644
index 0000000..01fcf6b
--- /dev/null
+++ b/test/jsonFiles/BC_VPPHAD1=VLL__Bc_Jpsippbarpi_mumu.json
@@ -0,0 +1,38 @@
+{
+ "parent" : "B_c+",
+ "daughters" : ["J/psi", "p+", "anti-p-", "pi+"],
+ "grand_daughters" : [["mu+", "mu-"], [], [], []],
+ "models" : ["BC_VPPHAD", "VLL", "", "", ""],
+ "parameters" : [["1"], [], [], [], []],
+ "extras" : ["noPhotos"],
+ "events" : 10000,
+ "histograms" : [
+ {"variable" : "prob", "title" : "Prob(BC_VPPHAD)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "prob_daug1", "title" : "Prob(VLL)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "mass", "title" : "m(Jpsi)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 3.0, "xmax" : 3.2},
+ {"variable" : "mass", "title" : "m(Jpsi p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : 3.8, "xmax" : 5.4},
+ {"variable" : "mass", "title" : "m(Jpsi pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : 3.8, "xmax" : 5.4},
+ {"variable" : "mass", "title" : "m(Jpsi pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : 3.0, "xmax" : 4.5},
+ {"variable" : "mass", "title" : "m(p pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : 1.8, "xmax" : 3.2},
+ {"variable" : "mass", "title" : "m(p pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 2.4},
+ {"variable" : "mass", "title" : "m(pbar pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 2.4},
+ {"variable" : "cosHel", "title" : "cosHel(Jpsi, p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(Jpsi, pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(Jpsi, pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(pbar, pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu+,Jpsi)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu-,Jpsi)", "d1" : 2, "d2" : 1, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta(Jpsi)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi", "title" : "phi(Jpsi)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0}
+ ],
+ "outfile" : "BC_VPPHAD1=VLL__Bc_Jpsippbarpi_mumu.root",
+ "reference" : "RefBC_VPPHAD1=VLL__Bc_Jpsippbarpi_mumu.root"
+}
diff --git a/test/jsonFiles/BC_VPPHAD1=VLL__Bc_psi2Sppbarpi_mumu.json b/test/jsonFiles/BC_VPPHAD1=VLL__Bc_psi2Sppbarpi_mumu.json
new file mode 100644
index 0000000..2d49315
--- /dev/null
+++ b/test/jsonFiles/BC_VPPHAD1=VLL__Bc_psi2Sppbarpi_mumu.json
@@ -0,0 +1,38 @@
+{
+ "parent" : "B_c+",
+ "daughters" : ["psi(2S)", "p+", "anti-p-", "pi+"],
+ "grand_daughters" : [["mu+", "mu-"], [], [], []],
+ "models" : ["BC_VPPHAD", "VLL", "", "", ""],
+ "parameters" : [["1"], [], [], [], []],
+ "extras" : ["noPhotos"],
+ "events" : 10000,
+ "histograms" : [
+ {"variable" : "prob", "title" : "Prob(BC_VPPHAD)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "prob_daug1", "title" : "Prob(VLL)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "mass", "title" : "m(psi2S)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 3.684, "xmax" : 3.69},
+ {"variable" : "mass", "title" : "m(psi2S p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : 4.5, "xmax" : 5.3},
+ {"variable" : "mass", "title" : "m(psi2S pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : 4.5, "xmax" : 5.3},
+ {"variable" : "mass", "title" : "m(psi2S pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : 3.7, "xmax" : 4.5},
+ {"variable" : "mass", "title" : "m(p pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : 1.8, "xmax" : 2.5},
+ {"variable" : "mass", "title" : "m(p pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 1.7},
+ {"variable" : "mass", "title" : "m(pbar pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 1.7},
+ {"variable" : "cosHel", "title" : "cosHel(psi2S, p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(psi2S, pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(psi2S, pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(pbar, pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu+,psi2S)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu-,psi2S)", "d1" : 2, "d2" : 1, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta(psi2S)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi", "title" : "phi(psi2S)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0}
+ ],
+ "outfile" : "BC_VPPHAD1=VLL__Bc_psi2Sppbarpi_mumu.root",
+ "reference" : "RefBC_VPPHAD1=VLL__Bc_psi2Sppbarpi_mumu.root"
+}
diff --git a/test/jsonFiles/BC_VPPHAD2=VLL__Bc_Jpsippbarpi_mumu.json b/test/jsonFiles/BC_VPPHAD2=VLL__Bc_Jpsippbarpi_mumu.json
new file mode 100644
index 0000000..5d65bf9
--- /dev/null
+++ b/test/jsonFiles/BC_VPPHAD2=VLL__Bc_Jpsippbarpi_mumu.json
@@ -0,0 +1,38 @@
+{
+ "parent" : "B_c+",
+ "daughters" : ["J/psi", "p+", "anti-p-", "pi+"],
+ "grand_daughters" : [["mu+", "mu-"], [], [], []],
+ "models" : ["BC_VPPHAD", "VLL", "", "", ""],
+ "parameters" : [["2"], [], [], [], []],
+ "extras" : ["noPhotos"],
+ "events" : 10000,
+ "histograms" : [
+ {"variable" : "prob", "title" : "Prob(BC_VPPHAD)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "prob_daug1", "title" : "Prob(VLL)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "mass", "title" : "m(Jpsi)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 3.0, "xmax" : 3.2},
+ {"variable" : "mass", "title" : "m(Jpsi p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : 3.8, "xmax" : 5.4},
+ {"variable" : "mass", "title" : "m(Jpsi pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : 3.8, "xmax" : 5.4},
+ {"variable" : "mass", "title" : "m(Jpsi pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : 3.0, "xmax" : 4.5},
+ {"variable" : "mass", "title" : "m(p pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : 1.8, "xmax" : 3.2},
+ {"variable" : "mass", "title" : "m(p pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 2.4},
+ {"variable" : "mass", "title" : "m(pbar pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 2.4},
+ {"variable" : "cosHel", "title" : "cosHel(Jpsi, p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(Jpsi, pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(Jpsi, pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(pbar, pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu+,Jpsi)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu-,Jpsi)", "d1" : 2, "d2" : 1, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta(Jpsi)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi", "title" : "phi(Jpsi)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0}
+ ],
+ "outfile" : "BC_VPPHAD2=VLL__Bc_Jpsippbarpi_mumu.root",
+ "reference" : "RefBC_VPPHAD2=VLL__Bc_Jpsippbarpi_mumu.root"
+}
diff --git a/test/jsonFiles/BC_VPPHAD2=VLL__Bc_psi2Sppbarpi_mumu.json b/test/jsonFiles/BC_VPPHAD2=VLL__Bc_psi2Sppbarpi_mumu.json
new file mode 100644
index 0000000..1162040
--- /dev/null
+++ b/test/jsonFiles/BC_VPPHAD2=VLL__Bc_psi2Sppbarpi_mumu.json
@@ -0,0 +1,38 @@
+{
+ "parent" : "B_c+",
+ "daughters" : ["psi(2S)", "p+", "anti-p-", "pi+"],
+ "grand_daughters" : [["mu+", "mu-"], [], [], []],
+ "models" : ["BC_VPPHAD", "VLL", "", "", ""],
+ "parameters" : [["2"], [], [], [], []],
+ "extras" : ["noPhotos"],
+ "events" : 10000,
+ "histograms" : [
+ {"variable" : "prob", "title" : "Prob(BC_VPPHAD)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "prob_daug1", "title" : "Prob(VLL)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "mass", "title" : "m(psi2S)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 3.684, "xmax" : 3.69},
+ {"variable" : "mass", "title" : "m(psi2S p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : 4.5, "xmax" : 5.3},
+ {"variable" : "mass", "title" : "m(psi2S pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : 4.5, "xmax" : 5.3},
+ {"variable" : "mass", "title" : "m(psi2S pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : 3.7, "xmax" : 4.5},
+ {"variable" : "mass", "title" : "m(p pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : 1.8, "xmax" : 2.5},
+ {"variable" : "mass", "title" : "m(p pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 1.7},
+ {"variable" : "mass", "title" : "m(pbar pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : 1.0, "xmax" : 1.7},
+ {"variable" : "cosHel", "title" : "cosHel(psi2S, p)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(psi2S, pbar)", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(psi2S, pi)", "d1" : 1, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pbar)", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(p, pi)", "d1" : 2, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel(pbar, pi)", "d1" : 3, "d2" : 4, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu+,psi2S)", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel(mu-,psi2S)", "d1" : 2, "d2" : 1, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta(psi2S)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi", "title" : "phi(psi2S)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "pLab_daug1", "title" : "pLab(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : 0.5, "xmax" : 3.5},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu+)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi_daug1", "title" : "phi(mu-)", "d1" : 2, "d2" : 0, "nbins" : 100, "xmin" : -180.0, "xmax" : 180.0}
+ ],
+ "outfile" : "BC_VPPHAD2=VLL__Bc_psi2Sppbarpi_mumu.root",
+ "reference" : "RefBC_VPPHAD2=VLL__Bc_psi2Sppbarpi_mumu.root"
+}
diff --git a/test/jsonFiles/PHI_DALITZ__phi_pipipi0.json b/test/jsonFiles/PHI_DALITZ__phi_pipipi0.json
index 0e1200c..70f7a6e 100644
--- a/test/jsonFiles/PHI_DALITZ__phi_pipipi0.json
+++ b/test/jsonFiles/PHI_DALITZ__phi_pipipi0.json
@@ -1,22 +1,28 @@
{
"parent" : "phi",
"daughters" : ["pi+", "pi-", "pi0"],
"models" : ["PHI_DALITZ"],
"parameters" : [[]],
"extras" : ["noPhotos"],
"events" : 10000,
"histograms" : [
{"variable" : "prob", "title" : "Probability", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
{"variable" : "mass", "title" : "m(#pi^{+} #pi^{-})", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : 0.2, "xmax" : 1.0},
{"variable" : "mass", "title" : "m(#pi^{+} #pi^{0})", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : 0.2, "xmax" : 1.0},
{"variable" : "mass", "title" : "m(#pi^{-} #pi^{0})", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : 0.2, "xmax" : 1.0},
{"variable" : "massSq", "title" : "Dalitz m^{2}(#pi^{+} #pi^{-}) vs m^{2}(#pi^{+} #pi^{0})", "d1" : 1, "d2" : 2, "nbins" : 50, "xmin" : 0.0, "xmax" : 0.8, "variableY" : "massSq", "d1Y" : 1, "d2Y" : 3, "nbinsY" : 50, "ymin" : 0.0, "ymax" : 0.8},
{"variable" : "massSq", "title" : "Dalitz m^{2}(#pi^{-} #pi^{0}) vs m^{2}(#pi^{+} #pi^{-})", "d1" : 2, "d2" : 3, "nbins" : 50, "xmin" : 0.0, "xmax" : 0.8, "variableY" : "massSq", "d1Y" : 1, "d2Y" : 2, "nbinsY" : 50, "ymin" : 0.0, "ymax" : 0.8},
{"variable" : "mPrime", "title" : "sqDalitz", "d1" : 1, "d2" : 2, "nbins" : 25, "xmin" : 0.0, "xmax" : 1.00, "variableY" : "thetaPrime", "d1Y" : 1, "d2Y" : 2, "nbinsY" : 25, "ymin" : 0.0, "ymax" : 1.0},
{"variable" : "cosHel", "title" : "cosHel12", "d1" : 1, "d2" : 2, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
{"variable" : "cosHel", "title" : "cosHel23", "d1" : 2, "d2" : 3, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
- {"variable" : "cosHel", "title" : "cosHel13", "d1" : 1, "d2" : 3, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0}
+ {"variable" : "cosHel", "title" : "cosHel13", "d1" : 1, "d2" : 3, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta1", "d1" : 1, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta2", "d1" : 2, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta3", "d1" : 3, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi", "title" : "phi1", "d1" : 1, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "phi", "title" : "phi2", "d1" : 2, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "phi", "title" : "phi3", "d1" : 3, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0}
],
"outfile" : "PHI_DALITZ__phi_pipipi0.root",
"reference" : "RefPHI_DALITZ__phi_pipipi0.root"
}
diff --git a/test/jsonFiles/SVS_PHI_DALITZ__Ds_phipi_pipipi0.json b/test/jsonFiles/SVS_PHI_DALITZ__Ds_phipi_pipipi0.json
new file mode 100644
index 0000000..992ea54
--- /dev/null
+++ b/test/jsonFiles/SVS_PHI_DALITZ__Ds_phipi_pipipi0.json
@@ -0,0 +1,38 @@
+{
+ "parent" : "D_s+",
+ "daughters" : ["phi", "pi+"],
+ "grand_daughters" : [["pi+", "pi-", "pi0"], []],
+ "models" : ["SVS", "PHI_DALITZ", ""],
+ "parameters" : [[], [], []],
+ "events" : 10000,
+ "histograms" : [
+ {"variable" : "prob", "title" : "Prob(SVS)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "prob_daug1", "title" : "Prob(PHI_DALITZ)", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 0.0, "xmax" : 1.0},
+ {"variable" : "parMass", "title" : "m(D_s^{+})", "d1" : 0, "d2" : 0, "nbins" : 100, "xmin" : 1.95, "xmax" : 2.0},
+ {"variable" : "mass", "title" : "m(#phi)", "d1" : 1, "d2" : 0, "nbins" : 100, "xmin" : 0.2, "xmax" : 1.0},
+ {"variable" : "mass_daug1", "title" : "m(#pi^{+} #pi^{-}) from #phi", "d1" : 1, "d2" : 2, "nbins" : 100, "xmin" : 0.2, "xmax" : 1.0},
+ {"variable" : "mass_daug1", "title" : "m(#pi^{+} #pi^{0}) from #phi", "d1" : 1, "d2" : 3, "nbins" : 100, "xmin" : 0.2, "xmax" : 1.0},
+ {"variable" : "mass_daug1", "title" : "m(#pi^{-} #pi^{0}) from #phi", "d1" : 2, "d2" : 3, "nbins" : 100, "xmin" : 0.2, "xmax" : 1.0},
+ {"variable" : "massSq_daug1", "title" : "Dalitz m^{2}(#pi^{+} #pi^{-}) vs m^{2}(#pi^{+} #pi^{0})", "d1" : 1, "d2" : 2, "nbins" : 50, "xmin" : 0.0, "xmax" : 0.8, "variableY" : "massSq_daug1", "d1Y" : 1, "d2Y" : 3, "nbinsY" : 50, "ymin" : 0.0, "ymax" : 0.8},
+ {"variable" : "massSq_daug1", "title" : "Dalitz m^{2}(#pi^{-} #pi^{0}) vs m^{2}(#pi^{+} #pi^{-})", "d1" : 2, "d2" : 3, "nbins" : 50, "xmin" : 0.0, "xmax" : 0.8, "variableY" : "massSq_daug1", "d1Y" : 1, "d2Y" : 2, "nbinsY" : 50, "ymin" : 0.0, "ymax" : 0.8},
+ {"variable" : "mPrime_daug1", "title" : "sqDalitz", "d1" : 1, "d2" : 2, "nbins" : 25, "xmin" : 0.0, "xmax" : 1.00, "variableY" : "thetaPrime_daug1", "d1Y" : 1, "d2Y" : 2, "nbinsY" : 25, "ymin" : 0.0, "ymax" : 1.0},
+ {"variable" : "cosThetaResNorm", "title" : "cosThetaResNorm", "d1" : 0, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosBetaRes_daug1", "title" : "cosBetaRes_daug1", "d1" : 0, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel", "title" : "cosHel12", "d1" : 1, "d2" : 2, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel1_12", "d1" : 1, "d2" : 2, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel1_23", "d1" : 2, "d2" : 3, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosHel_daug1", "title" : "cosHel1_13", "d1" : 1, "d2" : 3, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta1", "d1" : 1, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta", "title" : "cosTheta1", "d1" : 2, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta1_1", "d1" : 1, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta1_2", "d1" : 2, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "cosTheta_daug1", "title" : "cosTheta1_3", "d1" : 3, "d2" : 0, "nbins" : 50, "xmin" : -1.0, "xmax" : 1.0},
+ {"variable" : "phi", "title" : "phi1", "d1" : 1, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "phi", "title" : "phi2", "d1" : 2, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "phi_daug1", "title" : "phi1_1", "d1" : 1, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "phi_daug1", "title" : "phi1_2", "d1" : 2, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0},
+ {"variable" : "phi_daug1", "title" : "phi1_3", "d1" : 3, "d2" : 0, "nbins" : 50, "xmin" : -180.0, "xmax" : 180.0}
+ ],
+ "outfile" : "SVS_PHI_DALITZ__Ds_phipi_pipipi0.root",
+ "reference" : "RefSVS_PHI_DALITZ__Ds_phipi_pipipi0.root"
+}
diff --git a/test/testDecayModel.cc b/test/testDecayModel.cc
index de32915..b99ff26 100644
--- a/test/testDecayModel.cc
+++ b/test/testDecayModel.cc
@@ -1,1249 +1,1332 @@
/***********************************************************************
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
* *
* This file is part of EvtGen. *
* *
* EvtGen is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* EvtGen is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
***********************************************************************/
#include "testDecayModel.hh"
#include "EvtGen/EvtGen.hh"
#include "EvtGenBase/EvtAbsRadCorr.hh"
#include "EvtGenBase/EvtConst.hh"
#include "EvtGenBase/EvtDecayBase.hh"
#include "EvtGenBase/EvtId.hh"
#include "EvtGenBase/EvtKine.hh"
#include "EvtGenBase/EvtMTRandomEngine.hh"
#include "EvtGenBase/EvtPDL.hh"
#include "EvtGenBase/EvtParticle.hh"
#include "EvtGenBase/EvtParticleFactory.hh"
#include "EvtGenBase/EvtRandom.hh"
#include "EvtGenBase/EvtVector4R.hh"
#ifdef EVTGEN_EXTERNAL
#include "EvtGenExternal/EvtExternalGenList.hh"
#endif
#include <fstream>
#include <iostream>
#include <list>
#include <memory>
using nlohmann::json;
TestDecayModel::TestDecayModel( const json& config ) : m_config{ config }
{
}
bool TestDecayModel::checkMandatoryFields()
{
const std::array<std::string, 8> mandatoryFields{
"parent", "daughters", "models", "parameters",
"outfile", "events", "reference", "histograms" };
const std::array<std::string, 7> mandatoryHistoFields{
"title", "variable", "d1", "d2", "nbins", "xmin", "xmax" };
const std::array<std::string, 6> extra2DHistoFields{ "variableY", "d1Y",
"d2Y", "nbinsY",
"ymin", "ymax" };
bool allMandatoryFields{ true };
for ( const auto& field : mandatoryFields ) {
if ( !m_config.contains( field ) ) {
std::cerr << "ERROR : json does not contain required field: " << field
<< std::endl;
allMandatoryFields = false;
continue;
}
if ( field == "histograms" ) {
const json& jHistos{ m_config.at( "histograms" ) };
for ( const auto& hInfo : jHistos ) {
for ( const auto& hField : mandatoryHistoFields ) {
if ( !hInfo.contains( hField ) ) {
std::cerr
<< "ERROR : json does not contain required field for histogram definition: "
<< hField << std::endl;
allMandatoryFields = false;
}
}
if ( hInfo.contains( extra2DHistoFields[0] ) ) {
for ( const auto& hField : extra2DHistoFields ) {
if ( !hInfo.contains( hField ) ) {
std::cerr
<< "ERROR : json does not contain required field for 2D histogram definition: "
<< hField << std::endl;
allMandatoryFields = false;
}
}
}
}
}
}
return allMandatoryFields;
}
bool TestDecayModel::run()
{
// Check that we have, and then get all the mandatory fields first
if ( !checkMandatoryFields() ) {
std::cerr << "ERROR : json does not contain all mandatory fields - dumping config for debugging:\n";
std::cerr << m_config << std::endl;
return false;
}
const auto parentName{ m_config.at( "parent" ).get<std::string>() };
const auto daughterNames{
m_config.at( "daughters" ).get<std::vector<std::string>>() };
const auto modelNames{
m_config.at( "models" ).get<std::vector<std::string>>() };
const auto modelParameters{
m_config.at( "parameters" ).get<std::vector<std::vector<std::string>>>() };
const auto outFileName{ m_config.at( "outfile" ).get<std::string>() };
const auto nEvents{ m_config.at( "events" ).get<int>() };
const auto refFileName{ m_config.at( "reference" ).get<std::string>() };
// Then check for optional fields, setting default values if not present
const auto grandDaughterNames{
( m_config.contains( "grand_daughters" ) &&
m_config.at( "grand_daughters" ).is_array() )
? m_config.at( "grand_daughters" )
.get<std::vector<std::vector<std::string>>>()
: std::vector<std::vector<std::string>>{} };
const auto extraCommands{
( m_config.contains( "extras" ) && m_config.at( "extras" ).is_array() )
? m_config.at( "extras" ).get<std::vector<std::string>>()
: std::vector<std::string>{} };
const auto debugFlag{ ( m_config.contains( "debug_flag" ) &&
m_config.at( "debug_flag" ).is_boolean() )
? m_config.at( "debug_flag" ).get<bool>()
: false };
std::vector<bool> doConjDecay;
if ( m_config.contains( "do_conjugate_decay" ) &&
m_config.at( "do_conjugate_decay" ).is_array() ) {
doConjDecay = m_config.at( "do_conjugate_decay" ).get<std::vector<bool>>();
}
if ( doConjDecay.size() != modelNames.size() ) {
doConjDecay.resize( modelNames.size(), false );
}
// Initialise the EvtGen object and hence the EvtPDL tables
// The EvtGen object is used by generateEvents, while the
// latter are also used within createDecFile
// Define the random number generator
auto randomEngine{ std::make_unique<EvtMTRandomEngine>() };
EvtAbsRadCorr* radCorrEngine{ nullptr };
std::list<EvtDecayBase*> extraModels;
#ifdef EVTGEN_EXTERNAL
bool convertPythiaCodes( false );
bool useEvtGenRandom( true );
EvtExternalGenList genList( convertPythiaCodes, "", "gamma", useEvtGenRandom );
radCorrEngine = genList.getPhotosModel();
extraModels = genList.getListOfModels();
#endif
EvtGen theGen( "../DECAY.DEC", "../evt.pdl", randomEngine.get(),
radCorrEngine, &extraModels );
/*! Creates a decay file based on json file input. */
const std::string decFileName{
outFileName.substr( 0, outFileName.size() - 5 ) };
const std::string decFile{ createDecFile( parentName, daughterNames,
grandDaughterNames, modelNames,
modelParameters, doConjDecay,
extraCommands, decFileName ) };
/*! Define the root output file and histograms to be saved. */
std::unique_ptr<TFile> outFile{
TFile::Open( outFileName.c_str(), "recreate" ) };
defineHistos( outFile.get() );
/*! Generate events and fill histograms. */
generateEvents( theGen, decFile, parentName, doConjDecay[0], nEvents,
debugFlag );
// Normalize histograms.
for ( auto& [_, hist] : m_1DhistVect ) {
const double area{ hist->Integral() };
if ( area > 0.0 ) {
hist->Scale( 1.0 / area );
}
}
for ( auto& [_, hist] : m_2DhistVect ) {
const double area{ hist->Integral() };
if ( area > 0.0 ) {
hist->Scale( 1.0 / area );
}
}
/*! Compare with reference histograms. */
compareHistos( refFileName );
// Write output.
outFile->cd();
for ( auto& [_, hist] : m_1DhistVect ) {
hist->Write();
}
for ( auto& [_, hist] : m_2DhistVect ) {
hist->Write();
}
if ( m_mixedHist ) {
m_mixedHist->Write();
}
outFile->Close();
std::cout << "Created output file: " << outFileName.c_str() << std::endl;
return true;
}
std::string TestDecayModel::createDecFile(
const std::string& parent, const std::vector<std::string>& daughterNames,
const std::vector<std::vector<std::string>>& grandDaughterNames,
const std::vector<std::string>& modelNames,
const std::vector<std::vector<std::string>>& parameters,
const std::vector<bool>& doConjDecay,
const std::vector<std::string>& extras, const std::string decFileName ) const
{
// Create (or overwrite) the decay file
std::string decName( decFileName + ".dec" );
std::ofstream decFile;
decFile.open( decName.c_str() );
// Create daughter aliases if needed
std::vector<std::string> aliasPrefix;
for ( long unsigned int daughter_index{ 0 };
daughter_index < daughterNames.size(); daughter_index++ ) {
if ( !grandDaughterNames.empty() &&
!grandDaughterNames[daughter_index].empty() ) {
decFile << "Alias My" << daughterNames[daughter_index] << " "
<< daughterNames[daughter_index] << std::endl;
if ( doConjDecay[daughter_index + 1] ) {
const EvtId daugID{
EvtPDL::getId( daughterNames[daughter_index] ) };
const EvtId daugConjID{ EvtPDL::chargeConj( daugID ) };
const std::string conjName{ daugConjID.getName() };
std::string conjName_Alias{ daugConjID.getName() };
if ( std::find( std::begin( daughterNames ),
std::end( daughterNames ), daugConjID.getName() ) !=
std::end( daughterNames ) ) {
conjName_Alias = conjName_Alias + "_" + daughter_index;
}
decFile << "Alias My" << conjName_Alias << " " << conjName
<< std::endl;
decFile << "ChargeConj My" << daughterNames[daughter_index]
<< " My" << conjName_Alias << std::endl;
} else if ( doConjDecay[0] ) {
decFile << "ChargeConj My" << daughterNames[daughter_index]
<< " My" << daughterNames[daughter_index] << std::endl;
}
aliasPrefix.push_back( "My" );
} else {
aliasPrefix.push_back( "" );
}
}
for ( const auto& iExtra : extras ) {
decFile << iExtra << std::endl;
}
// Parent decay
decFile << "Decay " << parent << std::endl;
decFile << "1.0";
for ( long unsigned int daughter_index{ 0 };
daughter_index < daughterNames.size(); daughter_index++ ) {
decFile << " " << aliasPrefix[daughter_index]
<< daughterNames[daughter_index];
}
decFile << " " << modelNames[0];
for ( const auto& par : parameters[0] ) {
decFile << " " << par;
}
decFile << ";" << std::endl;
decFile << "Enddecay" << std::endl;
if ( doConjDecay[0] ) {
EvtId parID{ EvtPDL::getId( parent ) };
EvtId parConjID{ EvtPDL::chargeConj( parID ) };
decFile << "CDecay " << parConjID.getName() << std::endl;
}
// Daughter decays into granddaughters
for ( long unsigned int daughter_index{ 0 };
daughter_index < grandDaughterNames.size(); daughter_index++ ) {
if ( grandDaughterNames[daughter_index].empty() )
continue;
decFile << "Decay " << aliasPrefix[daughter_index]
<< daughterNames[daughter_index] << std::endl;
decFile << "1.0";
for ( long unsigned int grandDaughter_index{ 0 };
grandDaughter_index < grandDaughterNames[daughter_index].size();
grandDaughter_index++ ) {
decFile << " "
<< grandDaughterNames[daughter_index][grandDaughter_index];
}
decFile << " " << modelNames[daughter_index + 1];
for ( const auto& par : parameters[daughter_index + 1] ) {
decFile << " " << par;
}
decFile << ";" << std::endl;
decFile << "Enddecay" << std::endl;
if ( doConjDecay[daughter_index + 1] ) {
EvtId daugID{ EvtPDL::getId( daughterNames[daughter_index] ) };
EvtId daugConjID{ EvtPDL::chargeConj( daugID ) };
std::string conjName_Alias{ daugConjID.getName() };
if ( std::find( std::begin( daughterNames ),
std::end( daughterNames ), daugConjID.getName() ) !=
std::end( daughterNames ) ) {
conjName_Alias = conjName_Alias + "_" + daughter_index;
}
decFile << "CDecay " << aliasPrefix[daughter_index]
<< conjName_Alias << std::endl;
}
}
decFile << "End" << std::endl;
decFile.close();
return decName;
}
void TestDecayModel::defineHistos( TFile* outFile )
{
// Histogram information
const json& jHistos{ m_config.at( "histograms" ) };
const size_t nHistos{ jHistos.size() };
m_1DhistVect.reserve( nHistos );
m_2DhistVect.reserve( nHistos );
for ( const auto& hInfo : jHistos ) {
const auto varTitle{ hInfo.at( "title" ).get<std::string>() };
const auto varName{ hInfo.at( "variable" ).get<std::string>() };
// Integer values that define what particles need to be used
// for invariant mass combinations or helicity angles etc
const auto d1{ hInfo.at( "d1" ).get<int>() };
const auto d2{ hInfo.at( "d2" ).get<int>() };
const auto nBins{ hInfo.at( "nbins" ).get<int>() };
const auto xmin{ hInfo.at( "xmin" ).get<double>() };
const auto xmax{ hInfo.at( "xmax" ).get<double>() };
std::string histName( varName.c_str() );
if ( d1 != 0 ) {
histName += "_";
histName += std::to_string( d1 );
}
if ( d2 != 0 ) {
histName += "_";
histName += std::to_string( d2 );
}
if ( !hInfo.contains( "variableY" ) ) {
TH1* hist{ new TH1D{ histName.c_str(), varTitle.c_str(), nBins,
xmin, xmax } };
hist->SetDirectory( outFile );
m_1DhistVect.emplace_back(
std::make_pair( TestInfo( varName, d1, d2 ), hist ) );
continue;
} else {
const auto varNameY{ hInfo.at( "variableY" ).get<std::string>() };
const auto d1Y{ hInfo.at( "d1Y" ).get<int>() };
const auto d2Y{ hInfo.at( "d2Y" ).get<int>() };
const auto nBinsY{ hInfo.at( "nbinsY" ).get<int>() };
const auto ymin{ hInfo.at( "ymin" ).get<double>() };
const auto ymax{ hInfo.at( "ymax" ).get<double>() };
histName += "_";
histName += varNameY;
if ( d1Y != 0 ) {
histName += "_";
histName += std::to_string( d1Y );
}
if ( d2Y != 0 ) {
histName += "_";
histName += std::to_string( d2Y );
}
TH2* hist{ new TH2D{ histName.c_str(), varTitle.c_str(), nBins,
xmin, xmax, nBinsY, ymin, ymax } };
hist->SetDirectory( outFile );
m_2DhistVect.emplace_back( std::make_pair(
TestInfo( varName, d1, d2, varNameY, d1Y, d2Y ), hist ) );
}
}
// For the case where the parent is either a neutral B or D add a mixed/unmixed histogram
const auto parentName{ m_config.at( "parent" ).get<std::string>() };
const int parentID{ abs( EvtPDL::getStdHep( EvtPDL::getId( parentName ) ) ) };
if ( parentID == 511 || parentID == 531 || parentID == 421 ) {
const std::string varTitle{ parentName + " mixed" };
m_mixedHist = new TH1D{ "mixed", varTitle.c_str(), 2, 0.0, 2.0 };
// TODO maybe set bin labels?
m_mixedHist->SetDirectory( outFile );
}
}
void TestDecayModel::generateEvents( EvtGen& theGen, const std::string& decFile,
const std::string& parentName,
const bool doConjDecay, const int nEvents,
const bool debug_flag )
{
// Read the decay file
theGen.readUDecay( decFile.c_str() );
// Generate the decays
EvtId parId{ EvtPDL::getId( parentName.c_str() ) };
EvtId conjId{ doConjDecay ? EvtPDL::chargeConj( parId ) : parId };
for ( int i{ 0 }; i < nEvents; i++ ) {
if ( i % 1000 == 0 ) {
std::cout << "Event " << nEvents - i << std::endl;
}
// Initial 4-momentum and particle
EvtVector4R pInit( EvtPDL::getMass( parId ), 0.0, 0.0, 0.0 );
EvtParticle* parent{ nullptr };
if ( EvtRandom::Flat() < 0.5 ) {
parent = EvtParticleFactory::particleFactory( parId, pInit );
} else {
parent = EvtParticleFactory::particleFactory( conjId, pInit );
}
theGen.generateDecay( parent );
// Check for mixing (and fill histogram)
EvtParticle* prodParent{ nullptr };
if ( m_mixedHist ) {
if ( parent->getNDaug() == 1 ) {
prodParent = parent;
parent = prodParent->getDaug( 0 );
m_mixedHist->Fill( 1 );
} else {
m_mixedHist->Fill( 0 );
}
}
// To debug
if ( debug_flag ) {
std::cout << "Parent PDG code: " << parent->getPDGId()
<< " has daughters " << parent->getNDaug() << std::endl;
for ( size_t iDaughter{ 0 }; iDaughter < parent->getNDaug();
iDaughter++ ) {
std::cout << "Parent PDG code of daughter " << iDaughter
<< " : " << parent->getDaug( iDaughter )->getPDGId()
<< " has daughters "
<< parent->getDaug( iDaughter )->getNDaug()
<< std::endl;
for ( size_t iGrandDaughter{ 0 };
iGrandDaughter < parent->getDaug( iDaughter )->getNDaug();
iGrandDaughter++ ) {
std::cout << "Parent PDG code of grand daughter "
<< iGrandDaughter << " : "
<< parent->getDaug( iDaughter )
->getDaug( iGrandDaughter )
->getPDGId()
<< " has daughters "
<< parent->getDaug( iDaughter )
->getDaug( iGrandDaughter )
->getNDaug()
<< std::endl;
}
}
}
// Store information
for ( auto& [info, hist] : m_1DhistVect ) {
const double value{ getValue( parent, info.getName(), info.getd1(),
info.getd2() ) };
if ( hist ) {
hist->Fill( value );
}
}
for ( auto& [info, hist] : m_2DhistVect ) {
const double valueX{ getValue( parent, info.getName(), info.getd1(),
info.getd2() ) };
const double valueY{ getValue( parent, info.getName( 2 ),
info.getd1( 2 ), info.getd2( 2 ) ) };
if ( hist ) {
hist->Fill( valueX, valueY );
}
}
if ( debug_flag ) {
if ( prodParent ) {
prodParent->printTree();
} else {
parent->printTree();
}
}
// Cleanup
if ( prodParent ) {
prodParent->deleteTree();
} else {
parent->deleteTree();
}
}
}
double TestDecayModel::getValue( const EvtParticle* parent,
const std::string& varName, const int d1,
const int d2 ) const
{
double value{ std::numeric_limits<double>::quiet_NaN() };
if ( !parent ) {
return value;
}
const int NDaugMax( parent->getNDaug() );
// If variable name contains "_daugX", we are interested in daughters of daughter X
// Else we are interested in daughters
const EvtParticle* selectedParent{ parent };
std::string selectedVarName{ varName };
if ( varName.find( "_daug" ) != std::string::npos ) {
// Get daughter index from last character in string
const int iDaughter{ varName.back() - '0' };
selectedVarName = varName.substr( 0, varName.size() - 6 );
if ( iDaughter > 0 && iDaughter <= NDaugMax ) {
selectedParent = parent->getDaug( iDaughter - 1 );
} else {
return value;
}
}
const int sel_NDaugMax( selectedParent->getNDaug() );
const EvtParticle* par1{ d1 > 0 && d1 <= sel_NDaugMax
? selectedParent->getDaug( d1 - 1 )
: nullptr };
const EvtParticle* par2{ d2 > 0 && d2 <= sel_NDaugMax
? selectedParent->getDaug( d2 - 1 )
: nullptr };
const EvtParticle* par3{ sel_NDaugMax > 0
? selectedParent->getDaug( sel_NDaugMax - 1 )
: nullptr };
// 4-momenta in parent rest frame
const EvtVector4R p1{ par1 != nullptr ? par1->getP4() : EvtVector4R() };
const EvtVector4R p2{ par2 != nullptr ? par2->getP4() : EvtVector4R() };
const EvtVector4R p3{ par3 != nullptr ? par3->getP4() : EvtVector4R() };
// 4-momenta in lab frame (1st parent in decay tree)
const EvtVector4R p1_lab{ par1 != nullptr ? par1->getP4Lab() : EvtVector4R() };
const EvtVector4R p2_lab{ par2 != nullptr ? par2->getP4Lab() : EvtVector4R() };
const EvtVector4R p3_lab{ par3 != nullptr ? par3->getP4Lab() : EvtVector4R() };
if ( !selectedVarName.compare( "id" ) ) {
// StdHep ID of one of the daughters (controlled by d1) or the parent
if ( par1 ) {
value = par1->getPDGId();
} else {
value = selectedParent->getPDGId();
}
} else if ( !selectedVarName.compare( "parMass" ) ) {
// Parent invariant mass
value = selectedParent->mass();
} else if ( !selectedVarName.compare( "mass" ) ) {
// Invariant mass
if ( d2 != 0 ) {
// Invariant 4-mass combination of particles d1 and d2
value = ( p1 + p2 ).mass();
} else {
// Invariant mass of particle d1 only
value = p1.mass();
}
} else if ( !selectedVarName.compare( "massSq" ) ) {
// Invariant mass
if ( d2 != 0 ) {
// Invariant 4-mass combination of particles d1 and d2
value = ( p1 + p2 ).mass2();
} else {
// Invariant mass of particle d1 only
value = p1.mass2();
}
} else if ( !selectedVarName.compare( "mPrime" ) ) {
// pick up first unused particle rather than last one
if ( sel_NDaugMax != 3 ) {
return -1;
}
int unused{ 0 };
for ( int ii{ 1 }; ii <= sel_NDaugMax; ++ii ) {
if ( ii != d1 && ii != d2 ) {
unused = ii;
break;
}
}
if ( unused == 0 ) {
unused = sel_NDaugMax;
}
const auto parL{ selectedParent->getDaug( unused - 1 ) };
// const auto& pL = parL->getP4();
const double mB{ selectedParent->mass() };
const double m1{ par1->mass() };
const double m2{ par2->mass() };
const double m3{ parL->mass() };
const double m12{ ( p1 + p2 ).mass() };
const double m12norm{
2 * ( ( m12 - ( m1 + m2 ) ) / ( mB - ( m1 + m2 + m3 ) ) ) - 1 };
value = acos( m12norm ) / EvtConst::pi;
} else if ( !selectedVarName.compare( "thetaPrime" ) ) {
// pick up first unused particle rather than last one
if ( sel_NDaugMax != 3 ) {
return -1;
}
int unused{ 0 };
for ( int ii{ 1 }; ii <= sel_NDaugMax; ++ii ) {
if ( ii != d1 && ii != d2 ) {
unused = ii;
break;
}
}
if ( unused == 0 ) {
unused = sel_NDaugMax;
}
const auto parL{ selectedParent->getDaug( unused - 1 ) };
const auto& pL{ parL->getP4() };
const double mB{ selectedParent->mass() };
const double m1{ p1.mass() };
const double m2{ p2.mass() };
const double m3{ pL.mass() };
double mBSq{ mB * mB };
double m1Sq{ m1 * m1 };
double m2Sq{ m2 * m2 };
double m3Sq{ m3 * m3 };
const double m12{ ( p1 + p2 ).mass() };
const double m13{ ( p1 + p3 ).mass() };
const double m12Sq{ m12 * m12 };
const double m13Sq{ m13 * m13 };
double en1{ ( m12Sq - m2Sq + m1Sq ) / ( 2.0 * m12 ) };
double en3{ ( mBSq - m12Sq - m3Sq ) / ( 2.0 * m12 ) };
double p1_12{ std::sqrt( en1 * en1 - m1Sq ) };
double p3_12{ std::sqrt( en3 * en3 - m3Sq ) };
double cosTheta{ ( -m13Sq + m1Sq + m3Sq + 2. * en1 * en3 ) /
( 2. * p1_12 * p3_12 ) };
value = acos( cosTheta ) / EvtConst::pi;
} else if ( !selectedVarName.compare( "pSumSq" ) ) {
// Invariant momentum sum squared
value = ( p1 + p2 ).mass2();
} else if ( !selectedVarName.compare( "pDiffSq" ) ) {
// Invariant momentum difference squared
value = ( p1 - p2 ).mass2();
} else if ( !selectedVarName.compare( "mass3" ) ) {
// Invariant mass of 3 daughters
value = ( p1 + p2 + p3 ).mass();
} else if ( !selectedVarName.compare( "mass3_specified" ) ) {
// Invariant mass of 3 daughters, d1 is first daughter
// second daughter is d1 + 1, d2 is last daughter
const EvtParticle* daug2{ selectedParent->getDaug( d1 ) };
const EvtParticle* daug3{ selectedParent->getDaug( d2 - 1 ) };
const EvtVector4R p2_specified{ daug2 != nullptr ? daug2->getP4Lab()
: EvtVector4R() };
const EvtVector4R p3_specified{ daug3 != nullptr ? daug3->getP4Lab()
: EvtVector4R() };
value = ( p1 + p2_specified + p3_specified ).mass();
} else if ( !selectedVarName.compare( "cosTheta3" ) ) {
// Cosine of the polar angle of the momentum of d1 + d2 + d3
const EvtVector4R p123{ p1 + p2 + p3 };
if ( p123.d3mag() > 0.0 ) {
value = p123.get( 3 ) / p123.d3mag();
}
} else if ( !selectedVarName.compare( "pLab" ) ) {
// Momentum of particle d1 in lab frame
value = p1_lab.d3mag();
} else if ( !selectedVarName.compare( "p" ) ) {
// Momentum of particle d1 in parent rest frame
value = p1.d3mag();
} else if ( !selectedVarName.compare( "pLabSq" ) ) {
// Momentum squared of particle d1 (in lab frame)
const double p1_lab_x{ p1_lab.get( 1 ) };
const double p1_lab_y{ p1_lab.get( 2 ) };
const double p1_lab_z{ p1_lab.get( 3 ) };
value = p1_lab_x * p1_lab_x + p1_lab_y * p1_lab_y + p1_lab_z * p1_lab_z;
} else if ( !selectedVarName.compare( "pSq" ) ) {
// Momentum squared of particle d1 (in lab frame)
const double p1_x{ p1.get( 1 ) };
const double p1_y{ p1.get( 2 ) };
const double p1_z{ p1.get( 3 ) };
value = p1_x * p1_x + p1_y * p1_y + p1_z * p1_z;
} else if ( !selectedVarName.compare( "pxLab" ) ) {
// x momentum of particle d1 in lab frame
value = p1_lab.get( 1 );
} else if ( !selectedVarName.compare( "px" ) ) {
// x momentum of particle d1 in parent frame
value = p1.get( 1 );
} else if ( !selectedVarName.compare( "pyLab" ) ) {
// y momentum of particle d1 in lab frame
value = p1_lab.get( 2 );
} else if ( !selectedVarName.compare( "py" ) ) {
// y momentum of particle d1 in parent frame
value = p1.get( 2 );
} else if ( !selectedVarName.compare( "pzLab" ) ) {
// z momentum of particle d1 in lab frame
value = p1_lab.get( 3 );
} else if ( !selectedVarName.compare( "pz" ) ) {
// z momentum of particle d1 in parent frame
value = p1.get( 3 );
} else if ( !selectedVarName.compare( "cosHel" ) ||
!selectedVarName.compare( "absCosHel" ) ) {
// Cosine of helicity angle
EvtVector4R p12;
EvtVector4R p1Res;
if ( d2 != 0 ) {
// Resonance center-of-mass system (d1 and d2)
p12 = p1_lab + p2_lab;
// Boost vector
const EvtVector4R boost{ p12.get( 0 ), -p12.get( 1 ), -p12.get( 2 ),
-p12.get( 3 ) };
// Momentum of particle d1 in resonance frame, p1Res
p1Res = boostTo( p1_lab, boost );
} else {
// The resonance is d1
p12 = p1;
// Find its first daughter
const EvtParticle* gpar{ par1 != nullptr ? par1->getDaug( 0 )
: nullptr };
p1Res = gpar != nullptr ? gpar->getP4() : EvtVector4R();
}
// Cosine of angle between p1Res and momentum of resonance in parent frame
const double p1ResMag{ p1Res.d3mag() };
const double p12Mag{ p12.d3mag() };
if ( p1ResMag > 0.0 && p12Mag > 0.0 ) {
value = -p1Res.dot( p12 ) / ( p1ResMag * p12Mag );
}
if ( !selectedVarName.compare( "absCosHel" ) ) {
value = std::abs( value );
}
} else if ( !selectedVarName.compare( "cosHelTau" ) ) {
// Works only for B -> X nu_1 tau -> pi nu_2.
// Cosine of helicity angle between pi momentum and opposite W momentum -(nu_1 + tau)
// in the tau rest frame. Index d1 must match with tau.
// p3 (momentum of last daughter) is taken as the neutrino momentum
// W momentum
const EvtVector4R p_W{ p1_lab + p3_lab };
// Index d2 must match the index of the pion (daughter of tau)
const EvtParticle* pion{
selectedParent->getDaug( d1 - 1 )->getDaug( d2 - 1 ) };
const EvtVector4R p_pion{ pion != nullptr ? pion->getP4Lab()
: EvtVector4R() };
// Boost vector to tau frame
const EvtVector4R boost{ p1_lab.get( 0 ), -p1_lab.get( 1 ),
-p1_lab.get( 2 ), -p1_lab.get( 3 ) };
// Boost both momenta to tau frame
const EvtVector4R p_W_boosted{ boostTo( p_W, boost ) };
const EvtVector4R p_pion_boosted{ boostTo( p_pion, boost ) };
// Cosine of angle between opposite W momentum and pion momentum in tau frame
const double p_W_boostedMag{ p_W_boosted.d3mag() };
const double p_pion_boostedMag{ p_pion_boosted.d3mag() };
if ( p_W_boostedMag > 0.0 && p_pion_boostedMag > 0.0 ) {
value = -p_W_boosted.dot( p_pion_boosted ) /
( p_W_boostedMag * p_pion_boostedMag );
}
} else if ( !selectedVarName.compare( "cosHelDiTau" ) ||
!selectedVarName.compare( "cosHelDiTau_over05" ) ||
!selectedVarName.compare( "cosHelDiTau_under05" ) ) {
// Works for B -> tau (pi nu) tau -> (pi nu), B -> phi (-> KK) l l decays,
// B -> 4 pions, or similar decays..
// Cosine of helicity angle between pi momentum and opposite B momentum in tau rest frame.
// Index d1 must match with tau
if ( sel_NDaugMax < 2 || sel_NDaugMax > 4 ) {
return value;
}
// B momentum
const EvtVector4R p_B{ selectedParent->getP4Lab() };
// Index d2 must match the index of the pion (daughter of tau)
const EvtParticle* pion_1{
sel_NDaugMax <= 3
? selectedParent->getDaug( d1 - 1 )->getDaug( d2 - 1 )
: selectedParent->getDaug( d1 - 1 ) };
const EvtVector4R p_pion_1{ pion_1 != nullptr ? pion_1->getP4Lab()
: EvtVector4R() };
const EvtVector4R p_first_daughter{
sel_NDaugMax <= 3 ? selectedParent->getDaug( d1 - 1 )->getP4Lab()
: selectedParent->getDaug( d1 - 1 )->getP4Lab() +
selectedParent->getDaug( d1 )->getP4Lab() };
// Boost vector to tau frame
const EvtVector4R boost_1{ p_first_daughter.get( 0 ),
-p_first_daughter.get( 1 ),
-p_first_daughter.get( 2 ),
-p_first_daughter.get( 3 ) };
// Boost both momenta to tau frame
const EvtVector4R p_B_boosted_1{ boostTo( p_B, boost_1 ) };
const EvtVector4R p_pion_boosted_1{ boostTo( p_pion_1, boost_1 ) };
// Cosine of angle between opposite W momentum and pion momentum in tau frame
const double p_B_boosted_1_Mag{ p_B_boosted_1.d3mag() };
const double p_pion_boosted_1_Mag{ p_pion_boosted_1.d3mag() };
double hel1{ std::numeric_limits<double>::quiet_NaN() };
double hel{ std::numeric_limits<double>::quiet_NaN() };
if ( p_B_boosted_1_Mag > 0.0 && p_pion_boosted_1_Mag > 0.0 ) {
hel1 = -p_B_boosted_1.dot( p_pion_boosted_1 ) /
( p_B_boosted_1_Mag * p_pion_boosted_1_Mag );
}
if ( ( !selectedVarName.compare( "cosHelDiTau_over05" ) ) ||
( !selectedVarName.compare( "cosHelDiTau_under05" ) ) ) {
// Works for B -> tau (pi nu) tau -> (pi nu) or similar decays.
// Cosine of helicity angle between pi momentum and opposite B momentum in tau rest frame
// Index d1 must match with tau; cosHelicity above +0.5 or below -0.5
// Index d2 must match the index of the pion (daughter of tau)
const EvtParticle* pion{
sel_NDaugMax <= 3 ? selectedParent->getDaug( 0 )->getDaug( d2 - 1 )
: selectedParent->getDaug( 0 ) };
const EvtVector4R p_pion{ pion != nullptr ? pion->getP4Lab()
: EvtVector4R() };
// Boost vector to tau frame
const EvtVector4R p_second_daughter{
sel_NDaugMax == 2
? selectedParent->getDaug( 0 )->getP4Lab()
: selectedParent->getDaug( 0 )->getP4Lab() +
selectedParent->getDaug( 1 )->getP4Lab() };
const EvtVector4R boost{ p_second_daughter.get( 0 ),
-p_second_daughter.get( 1 ),
-p_second_daughter.get( 2 ),
-p_second_daughter.get( 3 ) };
// Boost both momenta to tau frame
const EvtVector4R p_B_boosted{ boostTo( p_B, boost ) };
const EvtVector4R p_pion_boosted{ boostTo( p_pion, boost ) };
// Cosine of angle between opposite W momentum and pion momentum in tau frame
const double p_B_boostedMag{ p_B_boosted.d3mag() };
const double p_pion_boostedMag{ p_pion_boosted.d3mag() };
if ( p_B_boostedMag > 0.0 && p_pion_boostedMag > 0.0 ) {
hel = -p_B_boosted.dot( p_pion_boosted ) /
( p_B_boostedMag * p_pion_boostedMag );
}
}
if ( !selectedVarName.compare( "cosHelDiTau" ) ||
( hel > 0.5 && !selectedVarName.compare( "cosHelDiTau_over05" ) ) ||
( hel < -0.5 && !selectedVarName.compare( "cosHelDiTau_under05" ) ) ) {
value = hel1;
}
} else if ( !selectedVarName.compare( "cosAcoplanarityAngle" ) ||
!selectedVarName.compare( "acoplanarityAngle" ) ) {
// Acoplanarity angle or cosine for B -> tau (pi nu) tau -> (pi nu),
// B -> phi (-> KK) l l decays, B -> 4 pions, or similar decays
value = getCosAcoplanarityAngle( selectedParent, sel_NDaugMax, d1, d2 );
if ( !selectedVarName.compare( "acoplanarityAngle" ) ) {
value = std::acos( value ) * 180.0 / EvtConst::pi; // degrees
}
} else if ( !selectedVarName.compare( "cosTheta" ) ) {
// Cosine of polar angle of first daughter in lab frame
const double p1_lab_mag{ p1_lab.d3mag() };
if ( p1_lab_mag > 0.0 ) {
value = p1_lab.get( 3 ) / p1_lab_mag;
}
} else if ( !selectedVarName.compare( "phi" ) ) {
// Azimuthal angle of first daughter in lab frame (degrees)
const double p1_lab_mag{ p1_lab.d3mag() };
if ( p1_lab_mag > 0.0 ) {
value = atan2( p1_lab.get( 1 ), p1_lab.get( 2 ) ) * 180.0 /
EvtConst::pi;
}
} else if ( !selectedVarName.compare( "decayangle" ) ) {
// Polar angle between first and second daughters in lab frame
const EvtVector4R p{ selectedParent->getP4() };
const EvtVector4R q{ p1 + p2 };
const EvtVector4R d{ p1 };
const double cost{ EvtDecayAngle( p, q, d ) };
value = acos( cost ) * 180.0 / EvtConst::pi;
} else if ( !selectedVarName.compare( "decayangle3" ) ) {
// Polar angle between combined first and second daughters
// with the third daughter in lab frame
const EvtVector4R p{ selectedParent->getP4() };
const EvtVector4R q{ p1 + p2 + p3 };
const EvtVector4R d{ p1 + p2 };
const double cost{ EvtDecayAngle( p, q, d ) };
value = acos( cost ) * 180.0 / EvtConst::pi;
} else if ( !selectedVarName.compare( "decayangle_BTO4PI" ) ) {
// Polar angle between first and second daughters in lab frame.
// Used in PIPIPI (BTO4PI_CP) model
const EvtVector4R p{ p1 + p2 + p3 };
const EvtVector4R q{ p1 + p2 };
const EvtVector4R d{ p1 };
const double cost{ EvtDecayAngle( p, q, d ) };
value = acos( cost ) * 180.0 / EvtConst::pi;
} else if ( !selectedVarName.compare( "chi" ) ) {
// Chi angle (degrees) using all 4 daughters and parent 4 mom
const EvtParticle* daug1{ selectedParent->getDaug( d1 - 1 ) };
const EvtParticle* daug2{ selectedParent->getDaug( d1 ) };
const EvtParticle* daug3{ selectedParent->getDaug( d1 + 1 ) };
const EvtParticle* daug4{ selectedParent->getDaug( d1 + 2 ) };
const EvtVector4R p_parent{ selectedParent->getP4() };
const EvtVector4R p_daug1{ daug1 != nullptr ? daug1->getP4()
: EvtVector4R() };
const EvtVector4R p_daug2{ daug2 != nullptr ? daug2->getP4()
: EvtVector4R() };
const EvtVector4R p_daug3{ daug3 != nullptr ? daug3->getP4()
: EvtVector4R() };
const EvtVector4R p_daug4{ daug4 != nullptr ? daug4->getP4()
: EvtVector4R() };
const double chi{
EvtDecayAngleChi( p_parent, p_daug1, p_daug2, p_daug3, p_daug4 ) };
value = chi * 180.0 / EvtConst::pi;
+ } else if ( !selectedVarName.compare( "cosThetaResNorm" ) ) {
+ // P -> R p4 -> (p1 p2 p3) p4, where the resonance R decays to p1 p2 p3.
+ // Theta is the angle between the normal of the plane containing p1, p2 & p3
+ // and the bachelor particle p4 in the rest frame of resonance R.
+ // The normal vector is given by the cross product p3 x p1
+
+ if ( sel_NDaugMax > 1 ) {
+ const EvtParticle* res{ selectedParent->getDaug( 0 ) };
+ const EvtParticle* bac{ selectedParent->getDaug( 1 ) };
+
+ // Check resonance has 3 daughters
+ if ( res != nullptr && res->getNDaug() == 3 ) {
+ const EvtParticle* daug1 = res->getDaug( 0 );
+ const EvtParticle* daug3 = res->getDaug( 2 );
+
+ // 4-momenta in base parent P lab frame
+ const EvtVector4R pRes{ res->getP4Lab() };
+ const EvtVector4R p4{ bac != nullptr ? bac->getP4Lab()
+ : EvtVector4R() };
+ const EvtVector4R p1{ daug1 != nullptr ? daug1->getP4Lab()
+ : EvtVector4R() };
+ const EvtVector4R p3{ daug3 != nullptr ? daug3->getP4Lab()
+ : EvtVector4R() };
+
+ // Boost 4-vector for resonance frame
+ const EvtVector4R boost{ pRes.get( 0 ), -pRes.get( 1 ),
+ -pRes.get( 2 ), -pRes.get( 3 ) };
+
+ // Momentum of p1 and p3 in resonance frame
+ const EvtVector4R p1Res{ boostTo( p1, boost ) };
+ const EvtVector4R p3Res{ boostTo( p3, boost ) };
+
+ // Plane normal vector (just uses 3-momentum components)
+ const EvtVector4R norm{ p3Res.cross( p1Res ) };
+
+ // Momentum of p4 in resonance frame
+ const EvtVector4R p4Res{ boostTo( p4, boost ) };
+
+ // Cosine of the angle between the normal and p4 in the resonance frame
+ const double normMag{ norm.d3mag() };
+ const double p4ResMag{ p4Res.d3mag() };
+ if ( normMag > 0.0 && p4ResMag > 0.0 ) {
+ value = norm.dot( p4Res ) / ( normMag * p4ResMag );
+ }
+ }
+ }
+
+ } else if ( !selectedVarName.compare( "cosBetaRes" ) ) {
+ // For resonance P (parent) -> p1 p2 p3, beta is the
+ // angle between p1 & p3 in the (p1 + p2) rest frame
+ if ( sel_NDaugMax > 2 ) {
+ const EvtParticle* daug1 = selectedParent->getDaug( 0 );
+ const EvtParticle* daug2 = selectedParent->getDaug( 1 );
+ const EvtParticle* daug3 = selectedParent->getDaug( 2 );
+
+ // 4-momenta in base parent frame
+ const EvtVector4R p1{ daug1 != nullptr ? daug1->getP4Lab()
+ : EvtVector4R() };
+ const EvtVector4R p2{ daug2 != nullptr ? daug2->getP4Lab()
+ : EvtVector4R() };
+ const EvtVector4R p3{ daug3 != nullptr ? daug3->getP4Lab()
+ : EvtVector4R() };
+
+ // p1 + p2
+ const EvtVector4R p12{ p1 + p2 };
+
+ // Boost 4-vector for p12 frame
+ const EvtVector4R boost{ p12.get( 0 ), -p12.get( 1 ), -p12.get( 2 ),
+ -p12.get( 3 ) };
+
+ // Momentum of p1 & p3 in p12 frame
+ const EvtVector4R p1_12{ boostTo( p1, boost ) };
+ const EvtVector4R p3_12{ boostTo( p3, boost ) };
+
+ // Cosine of angle between p1 & p3 in p12 frame
+ const double p1_12Mag{ p1_12.d3mag() };
+ const double p3_12Mag{ p3_12.d3mag() };
+ if ( p1_12Mag > 0.0 && p3_12Mag > 0.0 ) {
+ value = p1_12.dot( p3_12 ) / ( p1_12Mag * p3_12Mag );
+ }
+ }
+
} else if ( !selectedVarName.compare( "E" ) ) {
// Energy of first daughter in lab frame
value = p1_lab.get( 0 );
} else if ( !selectedVarName.compare( "E_over_Eparent" ) ) {
// Energy of first daughter w.r.t parent energy (lab frame)
value = p1_lab.get( 0 ) / selectedParent->getP4Lab().get( 0 );
} else if ( !selectedVarName.compare( "E_over_Eparent_over05" ) ) {
// First daughter E_over_Eparent (lab frame) if d2 granddaughter E ratio > 0.5
const double E_over_Eparent_2{
parent->getDaug( 0 )->getDaug( d2 - 1 )->getP4Lab().get( 0 ) /
parent->getDaug( 0 )->getP4Lab().get( 0 ) };
if ( E_over_Eparent_2 > 0.5 ) {
value = p1_lab.get( 0 ) / selectedParent->getP4Lab().get( 0 );
}
} else if ( !selectedVarName.compare( "totE_over_Mparent" ) ) {
// Energy of given daughters w.r.t parent mass (lab frame)
value = ( p1_lab.get( 0 ) + p2_lab.get( 0 ) ) / selectedParent->mass();
} else if ( !selectedVarName.compare( "prob" ) ) {
// Decay probability
const double* dProb{ selectedParent->decayProb() };
if ( dProb ) {
value = *dProb;
}
} else if ( !selectedVarName.compare( "lifetime" ) ) {
// Lifetime of particle d1 (ps)
if ( d1 ) {
value = par1 != nullptr ? par1->getLifetime() * 1e12 / EvtConst::c
: 0.0;
} else {
value = parent != nullptr
? parent->getLifetime() * 1e12 / EvtConst::c
: 0.0;
}
} else if ( !selectedVarName.compare( "deltaT" ) ) {
// Lifetime difference between particles d1 and d2
const double t1{
par1 != nullptr ? par1->getLifetime() * 1e12 / EvtConst::c : 0.0 };
const double t2{
par2 != nullptr ? par2->getLifetime() * 1e12 / EvtConst::c : 0.0 };
value = t1 - t2;
} else if ( !selectedVarName.compare( "decTime" ) ) {
// Decay flight time of particle d1 in picoseconds.
// Decay vertex = position of (1st) decay particle of d1
const EvtParticle* gpar{ par1 != nullptr ? par1->getDaug( 0 ) : nullptr };
const EvtVector4R vtxPos{ gpar != nullptr ? gpar->get4Pos()
: EvtVector4R() };
const double p{ p1_lab.d3mag() };
value = p > 0.0
? 1e12 * vtxPos.d3mag() * p1_lab.mass() / ( p * EvtConst::c )
: 0.0;
} else if ( !selectedVarName.compare( "nFSRPhotons" ) ) {
// Loop over all daughters and get number of FSR photons
double nFSRPhotons{ 0 };
for ( size_t iDaughter{ 0 }; iDaughter < selectedParent->getNDaug();
iDaughter++ ) {
const EvtParticle* iDaug = selectedParent->getDaug( iDaughter );
if ( iDaug->getAttribute( "FSR" ) == 1 )
nFSRPhotons += 1.0;
}
value = nFSRPhotons;
} else if ( !selectedVarName.compare( "totalFSREnergy" ) ) {
// Loop over all daughters and get number of FSR photons
double totalFSREnergy{ 0 };
for ( size_t iDaughter{ 0 }; iDaughter < selectedParent->getNDaug();
iDaughter++ ) {
const EvtParticle* iDaug = selectedParent->getDaug( iDaughter );
if ( iDaug->getAttribute( "FSR" ) == 1 )
totalFSREnergy += iDaug->getP4Lab().get( 0 );
}
value = totalFSREnergy;
} else {
std::cerr << "Warning: Did not recognise variable name "
<< selectedVarName << std::endl;
}
return value;
}
void TestDecayModel::compareHistos( const std::string& refFileName ) const
{
// Compare histograms with the same name, calculating the chi-squared
std::unique_ptr<TFile> refFile{ TFile::Open( refFileName.c_str(), "read" ) };
if ( !refFile ) {
std::cerr << "Could not open reference file " << refFileName << std::endl;
return;
}
// TODO - should we plot the (signed) chisq histogram? and save it as pdf/png?
for ( auto& [_, hist] : m_1DhistVect ) {
const std::string histName{ hist->GetName() };
// Get equivalent reference histogram
const TH1* refHist{
dynamic_cast<TH1*>( refFile->Get( histName.c_str() ) ) };
if ( refHist ) {
double chiSq{ 0.0 };
int nDof{ 0 };
int iGood{ 0 };
const double pValue{
refHist->Chi2TestX( hist, chiSq, nDof, iGood, "WW" ) };
const double integral{ refHist->Integral() };
std::cout << "Histogram " << histName << " chiSq/nDof = " << chiSq
<< "/" << nDof << ", pValue = " << pValue
<< ", integral = " << integral << std::endl;
} else {
std::cerr << "Could not find reference histogram " << histName
<< std::endl;
}
}
for ( auto& [_, hist] : m_2DhistVect ) {
const std::string histName{ hist->GetName() };
// Get equivalent reference histogram
const TH2* refHist{
dynamic_cast<TH2*>( refFile->Get( histName.c_str() ) ) };
if ( refHist ) {
double chiSq{ 0.0 };
int nDof{ 0 };
int iGood{ 0 };
const double pValue{
refHist->Chi2TestX( hist, chiSq, nDof, iGood, "WW" ) };
const double integral{ refHist->Integral() };
std::cout << "Histogram " << histName << " chiSq/nDof = " << chiSq
<< "/" << nDof << ", pValue = " << pValue
<< ", integral = " << integral << std::endl;
} else {
std::cerr << "Could not find reference histogram " << histName
<< std::endl;
}
}
refFile->Close();
}
double TestDecayModel::getCosAcoplanarityAngle( const EvtParticle* selectedParent,
const int sel_NDaugMax,
const int d1, const int d2 ) const
{
// Given a two-body decay, the acoplanarity angle is defined as the angle between the
// two decay planes (normal vectors) in the reference frame of the mother.
// Each normal vector is the cross product of the momentum of one daughter (in the frame of the mother)
// and the momentum of one of the granddaughters (in the reference frame of the daughter).
// In case of 3 daughters, we build an intermediate daughter (2+3) from the last 2 daughters
// (which are then treated as grand daughters), and in case of 4 daughters, we build
// 2 intermediate daughters (1+2) and (3+4)
double cosAco{ 0.0 };
if ( sel_NDaugMax < 2 || sel_NDaugMax > 4 ) {
return cosAco;
}
const EvtParticle* daughter1{ selectedParent->getDaug( 0 ) };
const EvtParticle* daughter2{ selectedParent->getDaug( 1 ) };
const EvtParticle* daughter3{ selectedParent->getDaug( 2 ) };
const EvtParticle* daughter4{ selectedParent->getDaug( 3 ) };
const EvtParticle* grandDaughter1{ daughter1->getDaug( d1 - 1 ) };
const EvtParticle* grandDaughter2{ daughter2->getDaug( d2 - 1 ) };
const EvtVector4R parent4Vector{ selectedParent->getP4Lab() };
const EvtVector4R daughter4Vector1{
sel_NDaugMax <= 3 ? daughter1->getP4Lab()
: daughter1->getP4Lab() + daughter2->getP4Lab() };
const EvtVector4R daughter4Vector2{
- sel_NDaugMax == 2 ? daughter2->getP4Lab()
- : sel_NDaugMax == 3 ? daughter2->getP4Lab() + daughter3->getP4Lab()
- : daughter3->getP4Lab() + daughter4->getP4Lab() };
+ sel_NDaugMax == 2
+ ? daughter2->getP4Lab()
+ : sel_NDaugMax == 3 ? daughter2->getP4Lab() + daughter3->getP4Lab()
+ : daughter3->getP4Lab() + daughter4->getP4Lab() };
const EvtVector4R grandDaughter4Vector1{
sel_NDaugMax <= 3 ? grandDaughter1->getP4Lab() : daughter1->getP4Lab() };
const EvtVector4R grandDaughter4Vector2{
- sel_NDaugMax == 2 ? grandDaughter2->getP4Lab()
- : sel_NDaugMax == 3 ? daughter2->getP4Lab()
- : daughter3->getP4Lab() };
+ sel_NDaugMax == 2 ? grandDaughter2->getP4Lab()
+ : sel_NDaugMax == 3 ? daughter2->getP4Lab()
+ : daughter3->getP4Lab() };
const EvtVector4R parentBoost{ parent4Vector.get( 0 ),
-parent4Vector.get( 1 ),
-parent4Vector.get( 2 ),
-parent4Vector.get( 3 ) };
const EvtVector4R daughter1Boost{ daughter4Vector1.get( 0 ),
-daughter4Vector1.get( 1 ),
-daughter4Vector1.get( 2 ),
-daughter4Vector1.get( 3 ) };
const EvtVector4R daughter2Boost{ daughter4Vector2.get( 0 ),
-daughter4Vector2.get( 1 ),
-daughter4Vector2.get( 2 ),
-daughter4Vector2.get( 3 ) };
// Boosting daughters to reference frame of the mother
- EvtVector4R daughter4Vector1_boosted{
+ const EvtVector4R daughter4Vector1_boosted{
boostTo( daughter4Vector1, parentBoost ) };
- EvtVector4R daughter4Vector2_boosted{
+ const EvtVector4R daughter4Vector2_boosted{
boostTo( daughter4Vector2, parentBoost ) };
// Boosting each granddaughter to reference frame of its mother
- EvtVector4R grandDaughter4Vector1_boosted{
+ const EvtVector4R grandDaughter4Vector1_boosted{
boostTo( grandDaughter4Vector1, daughter1Boost ) };
- EvtVector4R grandDaughter4Vector2_boosted{
+ const EvtVector4R grandDaughter4Vector2_boosted{
boostTo( grandDaughter4Vector2, daughter2Boost ) };
// We calculate the normal vectors of the decay two planes
const EvtVector4R normalVector1{
daughter4Vector1_boosted.cross( grandDaughter4Vector1_boosted ) };
const EvtVector4R normalVector2{
daughter4Vector2_boosted.cross( grandDaughter4Vector2_boosted ) };
const double normalVector1Mag{ normalVector1.d3mag() };
const double normalVector2Mag{ normalVector2.d3mag() };
if ( normalVector1Mag > 0.0 && normalVector2Mag > 0.0 ) {
cosAco = normalVector1.dot( normalVector2 ) /
( normalVector1Mag * normalVector2Mag );
}
return cosAco;
}
int main( int argc, char* argv[] )
{
if ( argc != 2 ) {
std::cerr << "Expecting one argument: json input file" << std::endl;
return 1;
}
/*! Load input file in json format. */
json config;
std::ifstream inputStr{ argv[1] };
inputStr >> config;
inputStr.close();
bool allOK{ true };
if ( config.is_array() ) {
for ( const auto& cc : config ) {
TestDecayModel test{ cc };
allOK &= test.run();
}
} else {
TestDecayModel test{ config };
allOK &= test.run();
}
return allOK ? 0 : 1;
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 19, 8:56 PM (1 d, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3796647
Default Alt Text
(227 KB)

Event Timeline