EvtGen 2.2.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
Loading...
Searching...
No Matches
EvtDalitzPlot.cpp
Go to the documentation of this file.
1
2/***********************************************************************
3* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4* *
5* This file is part of EvtGen. *
6* *
7* EvtGen is free software: you can redistribute it and/or modify *
8* it under the terms of the GNU General Public License as published by *
9* the Free Software Foundation, either version 3 of the License, or *
10* (at your option) any later version. *
11* *
12* EvtGen is distributed in the hope that it will be useful, *
13* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15* GNU General Public License for more details. *
16* *
17* You should have received a copy of the GNU General Public License *
18* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19***********************************************************************/
20
22
24#include "EvtGenBase/EvtPDL.hh"
26
27#include <assert.h>
28#include <math.h>
29#include <stdio.h>
30
31using namespace EvtCyclic3;
32
34 m_mA( 0. ), m_mB( 0. ), m_mC( 0. ), m_bigM( 0. ), m_ldel( 0. ), m_rdel( 0. )
35{
36}
37
38EvtDalitzPlot::EvtDalitzPlot( double mA, double mB, double mC, double bigM,
39 double ldel, double rdel ) :
40 m_mA( mA ), m_mB( mB ), m_mC( mC ), m_bigM( bigM ), m_ldel( ldel ), m_rdel( rdel )
41{
43}
44
45EvtDalitzPlot::EvtDalitzPlot( const EvtDecayMode& mode, double ldel, double rdel )
46{
51
52 m_ldel = ldel;
53 m_rdel = rdel;
54
56}
57
59{
60 bool ret = false;
61 if ( m_mA == other.m_mA && m_mB == other.m_mB && m_mC == other.m_mC &&
62 m_bigM == other.m_bigM )
63 ret = true;
64
65 return ret;
66}
67
69{
70 return new EvtDalitzPlot( *this );
71}
72
74{
75 if ( m_mA < 0 || m_mB < 0 || m_mC < 0 || m_bigM <= 0 ||
76 m_bigM - m_mA - m_mB - m_mC < 0. ) {
77 printf( "Invalid Dalitz plot %f %f %f %f\n", m_mA, m_mB, m_mC, m_bigM );
78 assert( 0 );
79 }
80 assert( m_ldel <= 0. );
81 assert( m_rdel >= 0. );
82}
83
84double EvtDalitzPlot::m( Index i ) const
85{
86 double m = m_mA;
87 if ( i == B )
88 m = m_mB;
89 else if ( i == C )
90 m = m_mC;
91
92 return m;
93}
94
95double EvtDalitzPlot::sum() const
96{
97 return m_mA * m_mA + m_mB * m_mB + m_mC * m_mC + m_bigM * m_bigM;
98}
99
101{
102 Index j = first( i );
103 Index k = second( i );
104
105 return ( m( j ) + m( k ) ) * ( m( j ) + m( k ) );
106}
107
109{
110 Index j = other( i );
111 return ( m_bigM - m( j ) ) * ( m_bigM - m( j ) );
112}
113
115{
116 return qAbsMin( i ) - sum() / 3.;
117}
118
120{
121 return qAbsMax( i ) - sum() / 3.;
122}
123
125{
126 Pair j = next( i );
127 Pair k = prev( i );
128 return ( qAbsMin( j ) - qAbsMax( k ) ) / 2.;
129}
130
132{
133 Pair j = next( i );
134 Pair k = prev( i );
135 return ( qAbsMax( j ) - qAbsMin( k ) ) / 2.;
136}
137
139{
140 return sqrt( qAbsMin( i ) );
141}
142
144{
145 return sqrt( qAbsMax( i ) );
146}
147
148// parallel
149
150double EvtDalitzPlot::qMin( Pair i, Pair j, double q ) const
151{
152 if ( i == j )
153 return q;
154
155 else {
156 // Particle pair j defines the rest-frame
157 // 0 - particle common to r.f. and angle calculations
158 // 1 - particle belonging to r.f. but not angle
159 // 2 - particle not belonging to r.f.
160
161 Index k0 = common( i, j );
162 Index k2 = other( j );
163 Index k1 = other( k0, k2 );
164
165 // Energy, momentum of particle common to rest-frame and angle
166 EvtTwoBodyKine jpair( m( k0 ), m( k1 ), sqrt( q ) );
167 double pk = jpair.p();
168 double ek = jpair.e( EvtTwoBodyKine::A, EvtTwoBodyKine::AB );
169
170 // Energy and momentum of the other particle
171 EvtTwoBodyKine mother( sqrt( q ), m( k2 ), bigM() );
172 double ej = mother.e( EvtTwoBodyKine::B, EvtTwoBodyKine::A );
173 double pj = mother.p( EvtTwoBodyKine::A );
174
175 // See PDG 34.4.3.1
176 return ( ek + ej ) * ( ek + ej ) - ( pk + pj ) * ( pk + pj );
177 }
178}
179
180// antiparallel
181
182double EvtDalitzPlot::qMax( Pair i, Pair j, double q ) const
183{
184 if ( i == j )
185 return q;
186 else {
187 // Particle pair j defines the rest-frame
188 // 0 - particle common to r.f. and angle calculations
189 // 1 - particle belonging to r.f. but not angle
190 // 2 - particle not belonging to r.f.
191
192 Index k0 = common( i, j );
193 Index k2 = other( j );
194 Index k1 = other( k0, k2 );
195
196 // Energy, momentum of particle common to rest-frame and angle
197 EvtTwoBodyKine jpair( m( k0 ), m( k1 ), sqrt( q ) );
198 double ek = jpair.e( EvtTwoBodyKine::A, EvtTwoBodyKine::AB );
199 double pk = jpair.p();
200
201 // Energy and momentum of the other particle
202 EvtTwoBodyKine mother( sqrt( q ), m( k2 ), bigM() );
203 double ej = mother.e( EvtTwoBodyKine::B, EvtTwoBodyKine::A );
204 double pj = mother.p( EvtTwoBodyKine::A );
205
206 // See PDG 34.4.3.1
207 return ( ek + ej ) * ( ek + ej ) - ( pk - pj ) * ( pk - pj );
208 }
209}
210
211double EvtDalitzPlot::getArea( int N, Pair i, Pair j ) const
212{
213 // Trapezoidal integral over qi. qj can be calculated.
214 // The first and the last point are zero, so they are not counted
215
216 double dh = ( qAbsMax( i ) - qAbsMin( i ) ) / ( (double)N );
217 double sum = 0;
218
219 int ii;
220 for ( ii = 1; ii < N; ii++ ) {
221 double x = qAbsMin( i ) + ii * dh;
222 double dy = qMax( j, i, x ) - qMin( j, i, x );
223 sum += dy;
224 }
225
226 return sum * dh;
227}
228
230 EvtCyclic3::Pair i2, double q2 ) const
231{
232 if ( i1 == i2 )
233 return 1.;
234
235 double qmax = qMax( i1, i2, q2 );
236 double qmin = qMin( i1, i2, q2 );
237
238 double cos = ( qmax + qmin - 2 * q1 ) / ( qmax - qmin );
239
240 return cos;
241}
242
243double EvtDalitzPlot::e( Index i, Pair j, double q ) const
244{
245 if ( i == other( j ) ) {
246 // i does not belong to pair j
247
248 return ( bigM() * bigM() - q - m( i ) * m( i ) ) / 2 / sqrt( q );
249 } else {
250 // i and k make pair j
251
252 Index k;
253 if ( first( j ) == i )
254 k = second( j );
255 else
256 k = first( j );
257
258 double e = ( q + m( i ) * m( i ) - m( k ) * m( k ) ) / 2 / sqrt( q );
259 return e;
260 }
261}
262
263double EvtDalitzPlot::p( Index i, Pair j, double q ) const
264{
265 double en = e( i, j, q );
266 double p2 = en * en - m( i ) * m( i );
267
268 if ( p2 < 0 ) {
269 printf( "Bad value of p2 %f %d %d %f %f\n", p2, i, j, en, m( i ) );
270 assert( 0 );
271 }
272
273 return sqrt( p2 );
274}
275
277 double q2 ) const
278{
279 if ( i1 == i2 )
280 return q2;
281
282 EvtCyclic3::Index f = first( i1 );
283 EvtCyclic3::Index s = second( i1 );
284 return m( f ) * m( f ) + m( s ) * m( s ) +
285 2 * e( f, i2, q2 ) * e( s, i2, q2 ) -
286 2 * p( f, i2, q2 ) * p( s, i2, q2 ) * cosTh;
287}
288
290{
291 return 2 * p( first( i ), i, q ) *
292 p( other( i ), i, q ); // J(BC) = 2pA*pB = 2pA*pC
293}
294
295EvtTwoBodyVertex EvtDalitzPlot::vD( Pair iRes, double m0, int L ) const
296{
297 return EvtTwoBodyVertex( m( first( iRes ) ), m( second( iRes ) ), m0, L );
298}
299
300EvtTwoBodyVertex EvtDalitzPlot::vB( Pair iRes, double m0, int L ) const
301{
302 return EvtTwoBodyVertex( m0, m( other( iRes ) ), bigM(), L );
303}
304
306{
307 // masses
308 printf( "Mass M %f\n", bigM() );
309 printf( "Mass mA %f\n", m_mA );
310 printf( "Mass mB %f\n", m_mB );
311 printf( "Mass mC %f\n", m_mC );
312 // limits
313 printf( "Limits qAB %f : %f\n", qAbsMin( AB ), qAbsMax( AB ) );
314 printf( "Limits qBC %f : %f\n", qAbsMin( BC ), qAbsMax( BC ) );
315 printf( "Limits qCA %f : %f\n", qAbsMin( CA ), qAbsMax( CA ) );
316 printf( "Sum q %f\n", sum() );
317 printf( "Limit qsum %f : %f\n", qSumMin(), qSumMax() );
318}
void sanityCheck() const
double qHelAbsMax(EvtCyclic3::Pair i) const
double getArea(int N=1000, EvtCyclic3::Pair i=EvtCyclic3::AB, EvtCyclic3::Pair j=EvtCyclic3::BC) const
double qAbsMin(EvtCyclic3::Pair i) const
double qSumMin() const
double jacobian(EvtCyclic3::Pair i, double q) const
double q(EvtCyclic3::Pair i1, double cosTh, EvtCyclic3::Pair i2, double q2) const
void print() const
double sum() const
double mB() const
double qSumMax() const
EvtTwoBodyVertex vD(EvtCyclic3::Pair iRes, double m0, int L) const
const EvtDalitzPlot * clone() const
double bigM() const
EvtTwoBodyVertex vB(EvtCyclic3::Pair iRes, double m0, int L) const
double m(EvtCyclic3::Index i) const
double qHelAbsMin(EvtCyclic3::Pair i) const
double mAbsMax(EvtCyclic3::Pair i) const
double mAbsMin(EvtCyclic3::Pair i) const
double p(EvtCyclic3::Index i, EvtCyclic3::Pair j, double q) const
double qMin(EvtCyclic3::Pair i, EvtCyclic3::Pair j, double q) const
double qAbsMax(EvtCyclic3::Pair i) const
double mA() const
double qMax(EvtCyclic3::Pair i, EvtCyclic3::Pair j, double q) const
bool operator==(const EvtDalitzPlot &other) const
double e(EvtCyclic3::Index i, EvtCyclic3::Pair j, double q) const
double cosTh(EvtCyclic3::Pair i1, double q1, EvtCyclic3::Pair i2, double q2) const
double mC() const
double qResAbsMin(EvtCyclic3::Pair i) const
double qResAbsMax(EvtCyclic3::Pair i) const
const char * mother() const
const char * dau(int i) const
static double getMeanMass(EvtId i)
Definition EvtPDL.cpp:306
static EvtId getId(const std::string &name)
Definition EvtPDL.cpp:283
double p(Index i=AB) const
double e(Index i, Index j) const
Index next(Index i)
Index common(Pair i, Pair j)
Index second(Pair i)
Index prev(Index i)
Index other(Index i, Index j)
Index first(Pair i)