33 return "FOURBODYPHSP";
42 const double mM,
const double m12,
const double m34,
43 std::array<double, 4>& daughters )
const
45 std::array<double, 4> result;
49 result[0] = result[1] * result[2] * result[3];
67 for (
int i = 0; i < 4; ++i ) {
108 if (
m_m12Max > mMother - mass3 - mass4 ) {
114 if (
m_m34Max > mMother - mass1 - mass2 ) {
133 m_trapCoeff2 = mMother * mMother - 2 * mMother * minSum +
141 const double area2 = 0.5 * pm12Diff *
150 m_trapCoeff2 = mMother * mMother - 2 * mMother * minSum +
160 bool contCond =
true;
166 double funcValue = 0;
169 double currentM12 = startM12;
170 double currentM34 = startM34;
171 funcValue =
phspFactor( mMother, currentM12, currentM34,
175 while ( step > 1e-4 ) {
176 double point1 = currentM12 + step;
180 if ( currentM34 > mMother - point1 ) {
181 point1 = mMother - currentM34;
183 double point2 = currentM12 - step;
187 double value1 =
phspFactor( mMother, point1, currentM34,
189 double value2 =
phspFactor( mMother, point2, currentM34,
191 if ( value1 > funcValue && value1 > value2 ) {
194 }
else if ( value2 > funcValue ) {
201 step = ( mMother - currentM12 -
m_m34Min ) / 100.;
202 while ( step > 1e-4 ) {
203 double point1 = currentM34 + step;
207 if ( point1 > mMother - currentM12 ) {
208 point1 = mMother - currentM12;
210 double point2 = currentM34 - step;
214 double value1 =
phspFactor( mMother, currentM12, point1,
216 double value2 =
phspFactor( mMother, currentM12, point2,
218 if ( value1 > funcValue && value1 > value2 ) {
221 }
else if ( value2 > funcValue ) {
229 double m12Diff = currentM12 - startM12;
230 double m34Diff = currentM34 - startM34;
231 double distSq = m12Diff * m12Diff + m34Diff * m34Diff;
232 if ( distSq < 1e-8 || iteration > 50 ) {
235 startM12 = currentM12;
236 startM34 = currentM34;
246 if ( !massTreeStatus ) {
248 <<
"Failed to generate daughters masses in EvtFourBodyPhsp."
253 double mMother = parent->
mass();
257 double cM12Min, cM12Max;
258 double cM34Min, cM34Max;
269 for (
int i = 0; i < 4; ++i ) {
270 auto daughter = parent->
getDaug( i );
293 const double m12 = masses.first;
294 const double m34 = masses.second;
303 const double sinTheta1 = std::sqrt( 1 - cosTheta1 * cosTheta1 );
305 const double sinTheta3 = std::sqrt( 1 - cosTheta3 * cosTheta3 );
310 const double p1x = probEval[2] * sinTheta1;
311 const double p1z = probEval[2] * cosTheta1;
312 const double p1Sq = probEval[2] * probEval[2];
317 const double p3T = probEval[3] * sinTheta3;
318 const double p3x = p3T * std::cos( phi );
319 const double p3y = p3T * std::sin( phi );
320 const double p3z = probEval[3] * cosTheta3;
321 const double p3Sq = probEval[3] * probEval[3];
332 const double qSq = probEval[1] * probEval[1];
333 const double en12 = std::sqrt( m12 * m12 + qSq );
334 const double en34 = std::sqrt( m34 * m34 + qSq );
352 auto daug = parent->
getDaug( 0 );
353 daug->
init( daug->getId(), mom1 );
355 daug->
init( daug->getId(), mom2 );
357 daug->
init( daug->getId(), mom3 );
359 daug->
init( daug->getId(), mom4 );
363 const double m12Min,
const double m12Max,
const double m34Max,
364 const double mMother )
const
366 double maxY = mMother - m12Min;
367 const bool corner1 = m34Max < maxY;
368 maxY = mMother - m12Max;
369 const bool corner2 = m34Max < maxY;
371 if ( corner1 && corner2 ) {
373 }
else if ( !corner1 && !corner2 ) {
380 const double m12Min,
const double m12Max,
const double m34Min,
381 const double m34Max,
const double mMother,
392 double split, fraction;
397 split = mMother - m34Max;
398 const double area1 = ( split - m12Min ) * ( m34Max - m34Min );
399 const double pm12Diff = m12Max - split;
400 const double area2 = 0.5 * pm12Diff *
401 ( mMother + m34Max - m12Max ) -
403 fraction = area1 / ( area1 + area2 );
412 return std::make_pair( m12Min, m34Min );
418 const double m12Min,
const double m12Max,
const double m34Min,
419 const double m34Max )
const
426 const double m12Min,
const double m12Max,
const double m34Min,
427 const double mMother )
const
429 double norm, coeff1, coeff2;
435 const double m12Diff = m12Max - m12Min;
436 const double minSum = m12Min + m34Min;
437 norm = ( mMother - m34Min ) * m12Diff -
438 0.5 * ( m12Diff * ( m12Max + m12Min ) );
439 coeff1 = mMother - m34Min;
440 coeff2 = mMother * mMother - 2 * mMother * minSum + minSum * minSum;
443 const double m12 = coeff1 - std::sqrt( -2.0 * rnd * norm + coeff2 );
445 return std::make_pair( m12, m34 );
double twoBodyMomentum(const double M, const double m1, const double m2)
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=nullptr)
static const double twoPi
double getArg(unsigned int j)
void setProbMax(double prbmx)
EvtId getParentId() const
EvtId getDaug(int i) const
void checkNDaug(int d1, int d2=-1)
void checkNArg(int a1, int a2=-1, int a3=-1, int a4=-1)
const EvtId * getDaugs() const
void setProb(double prob)
std::pair< double, double > generateTrapezoid(const double m12Min, const double m12Max, const double m34Min, const double mMother) const
std::pair< double, double > generatePairMasses(const double m12Min, const double m12Max, const double m34Min, const double m34Max, const double mMother, const EvtFourBodyPhsp::Shape shape) const
std::array< double, 4 > m_daughterMasses
void decay(EvtParticle *parent) override
double m_pentagonFraction
std::array< double, 4 > phspFactor(const double mM, const double m12, const double m34, std::array< double, 4 > &daughters) const
std::pair< double, double > generateRectangle(const double m12Min, const double m12Max, const double m34Min, const double m34Max) const
std::string getName() const override
EvtDecayBase * clone() const override
void initProbMax() override
Shape determineBoundaryShape(const double m12Min, const double m12Max, const double m34Max, const double mMother) const
static double getWidth(EvtId i)
static double getMaxMass(EvtId i)
static double getMass(EvtId i)
static double getMinMass(EvtId i)
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
EvtParticle * getDaug(const int i)
void makeDaughters(size_t ndaug, const EvtId *id)
void applyRotateEuler(double alpha, double beta, double gamma)
void applyBoostTo(const EvtVector4R &p4, bool inverse=false)