Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooNonCPEigenDecay.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitModels *
4 * @(#)root/roofit:$Id$
5 * Authors: *
6 * AH, Andreas Hoecker, Orsay, hoecker@slac.stanford.edu *
7 * SL, Sandrine Laplace, Orsay, laplace@slac.stanford.edu *
8 * JS, Jan Stark, Paris, stark@slac.stanford.edu *
9 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
10 * *
11 * Copyright (c) 2000-2005, Regents of the University of California, *
12 * IN2P3. All rights reserved. *
13 * *
14 * History *
15 * Nov-2001 WV Created initial version *
16 * Dec-2001 SL mischarge correction, direct CPV *
17 * Jan-2002 AH built dedicated generator + code cleaning *
18 * Mar-2002 JS committed debugged version to CVS *
19 * Apr-2002 AH allow prompt (ie, non-Pdf) mischarge treatment *
20 * May-2002 JS Changed the set of CP parameters (mathematically equiv.) *
21 * *
22 * Redistribution and use in source and binary forms, *
23 * with or without modification, are permitted according to the terms *
24 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
25 *****************************************************************************/
26
27/** \class RooNonCPEigenDecay
28 \ingroup Roofit
29
30Time-dependent RooAbsAnaConvPdf for CP violating decays
31to Non-CP eigenstates (eg, \f$ B_0 \rightarrow \rho^\pm \pi^\mp\f$).
32For a description of the physics model see the
33BaBar Physics Book, section 6.5.2.3 .
34The set of CP parameters used in this class is equivalent to
35the one used in the Physics Book, but it is not exactly the
36same. Starting from the set in the BaBar Book, in order to
37get the parameters used here you have to change the sign of both
38\f$a_c^+\f$ and \f$a_c^-\f$, and then substitute:
39\f[
40 a_s^Q = S + Q \cdot \delta S \\
41 a_c^Q = C + Q \cdot \delta C
42\f]
43where Q denotes the charge of the \f$\rho\f$ meson.
44**/
45
46#include "RooRealVar.h"
47#include "RooRandom.h"
48#include "RooNonCPEigenDecay.h"
49#include "RooRealIntegral.h"
50
51
52#define Debug_RooNonCPEigenDecay 1
53
54
55////////////////////////////////////////////////////////////////////////////////
56
57RooNonCPEigenDecay::RooNonCPEigenDecay( const char *name, const char *title,
58 RooRealVar& t,
59 RooAbsCategory& tag,
60 RooAbsReal& tau,
61 RooAbsReal& dm,
68 RooAbsReal& C,
70 RooAbsReal& S,
72 const RooResolutionModel& model,
74 : RooAbsAnaConvPdf( name, title, model, t ),
75 _acp ( "acp", "acp", this, acp ),
76 _avgC ( "C", "C", this, C ),
77 _delC ( "delC", "delC", this, delC ),
78 _avgS ( "S", "S", this, S ),
79 _delS ( "delS", "delS", this, delS ),
80 _avgW ( "avgW", "Average mistag rate",this, avgW ),
81 _delW ( "delW", "Shift mistag rate", this, delW ),
82 _t ( "t", "time", this, t ),
83 _tau ( "tau", "decay time", this, tau ),
84 _dm ( "dm", "mixing frequency", this, dm ),
85 _tag ( "tag", "CP state", this, tag ),
86 _rhoQ ( "rhoQ", "Charge of the rho", this, rhoQ ),
87 _correctQ ( "correctQ", "correction of rhoQ", this, correctQ ),
88 _wQ ( "wQ", "mischarge", this, wQ ),
89 _genB0Frac ( 0 ),
90 _genRhoPlusFrac( 0 ),
91 _type ( type )
92{
93 // Constructor
94 switch(type) {
95 case SingleSided:
96 _basisExp = declareBasis( "exp(-@0/@1)", RooArgList( tau ) );
97 _basisSin = declareBasis( "exp(-@0/@1)*sin(@0*@2)", RooArgList( tau, dm ) );
98 _basisCos = declareBasis( "exp(-@0/@1)*cos(@0*@2)", RooArgList( tau, dm ) );
99 break;
100 case Flipped:
101 _basisExp = declareBasis( "exp(@0)/@1)", RooArgList( tau ) );
102 _basisSin = declareBasis( "exp(@0/@1)*sin(@0*@2)", RooArgList( tau, dm ) );
103 _basisCos = declareBasis( "exp(@0/@1)*cos(@0*@2)", RooArgList( tau, dm ) );
104 break;
105 case DoubleSided:
106 _basisExp = declareBasis( "exp(-abs(@0)/@1)", RooArgList( tau ) );
107 _basisSin = declareBasis( "exp(-abs(@0)/@1)*sin(@0*@2)", RooArgList( tau, dm ) );
108 _basisCos = declareBasis( "exp(-abs(@0)/@1)*cos(@0*@2)", RooArgList( tau, dm ) );
109 break;
110 }
111}
112
113////////////////////////////////////////////////////////////////////////////////
114
115RooNonCPEigenDecay::RooNonCPEigenDecay( const char *name, const char *title,
116 RooRealVar& t,
117 RooAbsCategory& tag,
118 RooAbsReal& tau,
119 RooAbsReal& dm,
125 RooAbsReal& C,
127 RooAbsReal& S,
129 const RooResolutionModel& model,
131 : RooAbsAnaConvPdf( name, title, model, t ),
132 _acp ( "acp", "acp", this, acp ),
133 _avgC ( "C", "C", this, C ),
134 _delC ( "delC", "delC", this, delC ),
135 _avgS ( "S", "S", this, S ),
136 _delS ( "delS", "delS", this, delS ),
137 _avgW ( "avgW", "Average mistag rate",this, avgW ),
138 _delW ( "delW", "Shift mistag rate", this, delW ),
139 _t ( "t", "time", this, t ),
140 _tau ( "tau", "decay time", this, tau ),
141 _dm ( "dm", "mixing frequency", this, dm ),
142 _tag ( "tag", "CP state", this, tag ),
143 _rhoQ ( "rhoQ", "Charge of the rho", this, rhoQ ),
144 _correctQ ( "correctQ", "correction of rhoQ", this, correctQ ),
145 _wQ ( "wQ", "mischarge", this, std::make_unique<RooRealVar>( "wQ", "wQ", 0 ), true, false),
146 _genB0Frac ( 0 ),
147 _genRhoPlusFrac( 0 ),
148 _type ( type )
149{
150 switch(type) {
151 case SingleSided:
152 _basisExp = declareBasis( "exp(-@0/@1)", RooArgList( tau ) );
153 _basisSin = declareBasis( "exp(-@0/@1)*sin(@0*@2)", RooArgList( tau, dm ) );
154 _basisCos = declareBasis( "exp(-@0/@1)*cos(@0*@2)", RooArgList( tau, dm ) );
155 break;
156 case Flipped:
157 _basisExp = declareBasis( "exp(@0)/@1)", RooArgList( tau ) );
158 _basisSin = declareBasis( "exp(@0/@1)*sin(@0*@2)", RooArgList( tau, dm ) );
159 _basisCos = declareBasis( "exp(@0/@1)*cos(@0*@2)", RooArgList( tau, dm ) );
160 break;
161 case DoubleSided:
162 _basisExp = declareBasis( "exp(-abs(@0)/@1)", RooArgList( tau ) );
163 _basisSin = declareBasis( "exp(-abs(@0)/@1)*sin(@0*@2)", RooArgList( tau, dm ) );
164 _basisCos = declareBasis( "exp(-abs(@0)/@1)*cos(@0*@2)", RooArgList( tau, dm ) );
165 break;
166 }
167}
168
169////////////////////////////////////////////////////////////////////////////////
170/// Copy constructor
171
174 _acp ( "acp", this, other._acp ),
175 _avgC ( "C", this, other._avgC ),
176 _delC ( "delC", this, other._delC ),
177 _avgS ( "S", this, other._avgS ),
178 _delS ( "delS", this, other._delS ),
179 _avgW ( "avgW", this, other._avgW ),
180 _delW ( "delW", this, other._delW ),
181 _t ( "t", this, other._t ),
182 _tau ( "tau", this, other._tau ),
183 _dm ( "dm", this, other._dm ),
184 _tag ( "tag", this, other._tag ),
185 _rhoQ ( "rhoQ", this, other._rhoQ ),
186 _correctQ ( "correctQ", this, other._correctQ ),
187 _wQ ( "wQ", this, other._wQ ),
188 _genB0Frac ( other._genB0Frac ),
189 _genRhoPlusFrac( other._genRhoPlusFrac ),
190 _type ( other._type ),
191 _basisExp ( other._basisExp ),
192 _basisSin ( other._basisSin ),
193 _basisCos ( other._basisCos )
194{
195}
196
197////////////////////////////////////////////////////////////////////////////////
198/// - B0 : _tag == -1
199/// - B0bar : _tag == +1
200/// - rho+ : _rhoQ == +1
201/// - rho- : _rhoQ == -1
202/// - the charge correction factor "_correctQ" serves to implement misidentified charges
203
205{
207 assert( rhoQc == 1 || rhoQc == -1 );
208
209 double a_sin_p = _avgS + _delS;
210 double a_sin_m = _avgS - _delS;
211 double a_cos_p = _avgC + _delC;
212 double a_cos_m = _avgC - _delC;
213
214 if (basisIndex == _basisExp) {
215 if (rhoQc == -1 || rhoQc == +1) {
216 return (1 + rhoQc * _acp * (1 - 2 * _wQ)) * (1 + 0.5 * _tag * (2 * _delW));
217 } else {
218 return 1;
219 }
220 }
221
222 if (basisIndex == _basisSin) {
223
224 if (rhoQc == -1) {
225
226 return -((1 - _acp) * a_sin_m * (1 - _wQ) + (1 + _acp) * a_sin_p * _wQ) * (1 - 2 * _avgW) * _tag;
227
228 } else if (rhoQc == +1) {
229
230 return -((1 + _acp) * a_sin_p * (1 - _wQ) + (1 - _acp) * a_sin_m * _wQ) * (1 - 2 * _avgW) * _tag;
231
232 } else {
233 return -_tag * ((a_sin_p + a_sin_m) / 2) * (1 - 2 * _avgW);
234 }
235 }
236
237 if (basisIndex == _basisCos) {
238
239 if (rhoQc == -1) {
240
241 return +((1 - _acp) * a_cos_m * (1 - _wQ) + (1 + _acp) * a_cos_p * _wQ) * (1 - 2 * _avgW) * _tag;
242
243 } else if (rhoQc == +1) {
244
245 return +((1 + _acp) * a_cos_p * (1 - _wQ) + (1 - _acp) * a_cos_m * _wQ) * (1 - 2 * _avgW) * _tag;
246
247 } else {
248 return _tag * ((a_cos_p + a_cos_m) / 2) * (1 - 2 * _avgW);
249 }
250 }
251
252 return 0;
253}
254
255// advertise analytical integration
256
257////////////////////////////////////////////////////////////////////////////////
258
260 RooArgSet& analVars, const char* rangeName ) const
261{
262 if (rangeName) return 0 ;
263
264 if (matchArgs( allVars, analVars, _tag, _rhoQ )) return 3;
265 if (matchArgs( allVars, analVars, _rhoQ )) return 2;
266 if (matchArgs( allVars, analVars, _tag )) return 1;
267
268 return 0;
269}
270
271////////////////////////////////////////////////////////////////////////////////
272/// correct for the right/wrong charge...
273
275 Int_t code, const char* /*rangeName*/ ) const
276{
278
279 double a_sin_p = _avgS + _delS;
280 double a_sin_m = _avgS - _delS;
281 double a_cos_p = _avgC + _delC;
282 double a_cos_m = _avgC - _delC;
283
284 switch(code) {
285
286 // No integration
287 case 0: return coefficient(basisIndex);
288
289 // Integration over 'tag'
290 case 1:
291 if (basisIndex == _basisExp) return 2*(1 + rhoQc*_acp*(1 - 2*_wQ));
292 if (basisIndex == _basisSin || basisIndex==_basisCos) return 0;
293 assert( false );
294
295 // Integration over 'rhoQ'
296 case 2:
297 if (basisIndex == _basisExp) return 2*(1 + 0.5*_tag*(2.*_delW));
298
299 if (basisIndex == _basisSin) {
300
301 return -((1 - _acp) * a_sin_m + (1 + _acp) * a_sin_p) * (1 - 2 * _avgW) * _tag;
302 }
303
304 if (basisIndex == _basisCos) {
305
306 return +((1 - _acp) * a_cos_m + (1 + _acp) * a_cos_p) * (1 - 2 * _avgW) * _tag;
307 }
308
309 assert( false );
310
311 // Integration over 'tag' and 'rhoQ'
312 case 3:
313 if (basisIndex == _basisExp) return 2*2; // for both: tag and charge
314 if (basisIndex == _basisSin || basisIndex==_basisCos) return 0;
315 assert( false );
316
317 default:
318 assert( false );
319 }
320
321 return 0;
322}
323
324////////////////////////////////////////////////////////////////////////////////
325
327 RooArgSet& generateVars, bool staticInitOK ) const
328{
329 if (staticInitOK) {
330 if (matchArgs( directVars, generateVars, _t, _tag, _rhoQ )) return 4;
331 if (matchArgs( directVars, generateVars, _t, _rhoQ )) return 3;
332 if (matchArgs( directVars, generateVars, _t, _tag )) return 2;
333 }
334 if (matchArgs( directVars, generateVars, _t )) return 1;
335 return 0;
336}
337
338////////////////////////////////////////////////////////////////////////////////
339
341{
342 if (code == 2 || code == 4) {
343 // Calculate the fraction of mixed events to generate
344 double sumInt1 = RooRealIntegral( "sumInt1", "sum integral1", *this,
345 RooArgSet( _t.arg(), _tag.arg(), _rhoQ.arg() )
346 ).getVal();
347 _tag = -1;
348 double b0Int1 = RooRealIntegral( "mixInt1", "mix integral1", *this,
349 RooArgSet( _t.arg(), _rhoQ.arg() )
350 ).getVal();
352
353 if (Debug_RooNonCPEigenDecay == 1) {
354 std::cout << " o RooNonCPEigenDecay::initgenerator: genB0Frac : " << _genB0Frac
355 << ", tag dilution: " << (1 - 2 * _avgW) << std::endl;
356 }
357 }
358
359 if (code == 3 || code == 4) {
360 // Calculate the fraction of positive rho's to generate
361 double sumInt2 = RooRealIntegral( "sumInt2", "sum integral2", *this,
362 RooArgSet( _t.arg(), _tag.arg(), _rhoQ.arg() )
363 ).getVal();
364 _rhoQ = 1;
365 double b0Int2 = RooRealIntegral( "mixInt2", "mix integral2", *this,
366 RooArgSet( _t.arg(), _tag.arg() )
367 ).getVal();
369
370 if (Debug_RooNonCPEigenDecay == 1) {
371 std::cout << " o RooNonCPEigenDecay::initgenerator: genRhoPlusFrac: " << _genRhoPlusFrac << std::endl;
372 }
373 }
374}
375
376////////////////////////////////////////////////////////////////////////////////
377
379{
380 // Generate delta-t dependent
381 while (true) {
382
383 // B flavor and rho charge (we do not use the integrated weights)
384 if (code != 1) {
385 if (code != 3) _tag = (RooRandom::uniform()<=0.5) ? -1 : +1;
386 if (code != 2) _rhoQ = (RooRandom::uniform()<=0.5) ? 1 : -1;
387 }
388
389 // opposite charge?
390 // Int_t rhoQc = _rhoQ*int(_correctQ);
391
392 double a_sin_p = _avgS + _delS;
393 double a_sin_m = _avgS - _delS;
394 double a_cos_p = _avgC + _delC;
395 double a_cos_m = _avgC - _delC;
396
397 // maximum probability density
398 double a1 = 1 + sqrt(std::pow(a_cos_m, 2) + std::pow(a_sin_m, 2));
399 double a2 = 1 + sqrt(std::pow(a_cos_p, 2) + std::pow(a_sin_p, 2));
400
401 double maxAcceptProb = (1.10 + std::abs(_acp)) * (a1 > a2 ? a1 : a2);
402 // The 1.10 in the above line is a security feature to prevent crashes close to the limit at 1.00
403
404 double rand = RooRandom::uniform();
405 double tval(0);
406
407 switch(_type) {
408
409 case SingleSided:
410 tval = -_tau*log(rand);
411 break;
412
413 case Flipped:
414 tval = +_tau*log(rand);
415 break;
416
417 case DoubleSided:
418 tval = (rand<=0.5) ? -_tau*log(2*rand) : +_tau*log(2*(rand-0.5));
419 break;
420 }
421
422 // get coefficients
423 double expC = coefficient( _basisExp );
424 double sinC = coefficient( _basisSin );
425 double cosC = coefficient( _basisCos );
426
427 // probability density
428 double acceptProb = expC + sinC*sin(_dm*tval) + cosC*cos(_dm*tval);
429
430 // sanity check...
432
433 // hit or miss...
435
436 if (accept && tval<_t.max() && tval>_t.min()) {
437 _t = tval;
438 break;
439 }
440 }
441}
#define Debug_RooNonCPEigenDecay
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:142
Base class for PDFs that represent a physics model that can be analytically convolved with a resoluti...
Int_t declareBasis(const char *expression, const RooArgList &params)
Declare a basis function for use in this physics model.
friend class RooRealIntegral
Definition RooAbsArg.h:543
A space to attach TBranches.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
bool matchArgs(const RooArgSet &allDeps, RooArgSet &analDeps, const RooArgProxy &a, const Proxies &... proxies) const
Definition RooAbsReal.h:425
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Time-dependent RooAbsAnaConvPdf for CP violating decays to Non-CP eigenstates (eg,...
Int_t getCoefAnalyticalIntegral(Int_t coef, RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=nullptr) const override
Default implementation of function advertising integration capabilities.
double coefAnalyticalIntegral(Int_t coef, Int_t code, const char *rangeName=nullptr) const override
correct for the right/wrong charge...
RooCategoryProxy _rhoQ
RooCategoryProxy _tag
void generateEvent(Int_t code) override
Interface for generation of an event using the algorithm corresponding to the specified code.
double coefficient(Int_t basisIndex) const override
Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, bool staticInitOK=true) const override
Load generatedVars with the subset of directVars that we can generate events for, and return a code t...
void initGenerator(Int_t code) override
Interface for one-time initialization to setup the generator for the specified code.
RooRealProxy _wQ
dummy mischarge (must be set to zero!)
static double uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition RooRandom.cxx:77
Variable that can be changed from the outside.
Definition RooRealVar.h:37
RooResolutionModel is the base class for PDFs that represent a resolution model that can be convolute...
double max(const char *rname=nullptr) const
Query upper limit of range. This requires the payload to be RooAbsRealLValue or derived.
const T & arg() const
Return reference to object held in proxy.
double min(const char *rname=nullptr) const
Query lower limit of range. This requires the payload to be RooAbsRealLValue or derived.