/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$Id$
 * Authors:                                                                  *
 *   PL, Parker C Lund,   UC Irvine                                          *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/


//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// Most general description of B decay time distribution with effects
// of CP violation, mixing and life time differences. This function can 
// be analytically convolved with any RooResolutionModel implementation
// END_HTML
//


#include "RooFit.h"

#include "Riostream.h"
#include "TMath.h"
#include "RooBDecay.h"
#include "RooRealVar.h"
#include "RooRandom.h"

#include "TError.h"

using namespace std;

ClassImp(RooBDecay);


//_____________________________________________________________________________
RooBDecay::RooBDecay(const char *name, const char* title, 
	       RooRealVar& t, RooAbsReal& tau, RooAbsReal& dgamma,
	       RooAbsReal& f0, RooAbsReal& f1, RooAbsReal& f2, RooAbsReal& f3, 
	       RooAbsReal& dm, const RooResolutionModel& model, DecayType type) :
  RooAbsAnaConvPdf(name, title, model, t),
  _t("t", "time", this, t),
  _tau("tau", "Average Decay Time", this, tau),
  _dgamma("dgamma", "Delta Gamma", this, dgamma),
  _f0("f0", "Cosh Coefficient", this, f0),
  _f1("f1", "Sinh Coefficient", this, f1),
  _f2("f2", "Cos Coefficient", this, f2),
  _f3("f3", "Sin Coefficient", this, f3),
  _dm("dm", "Delta Mass", this, dm),
  _type(type)

{
  //Constructor
  switch(type)
    {
    case SingleSided:
      _basisCosh = declareBasis("exp(-@0/@1)*cosh(@0*@2/2)", RooArgList(tau,dgamma));
      _basisSinh = declareBasis("exp(-@0/@1)*sinh(@0*@2/2)", RooArgList(tau,dgamma));
      _basisCos = declareBasis("exp(-@0/@1)*cos(@0*@2)",RooArgList(tau, dm));
      _basisSin = declareBasis("exp(-@0/@1)*sin(@0*@2)",RooArgList(tau, dm));
      break;
    case Flipped:
      _basisCosh = declareBasis("exp(@0/@1)*cosh(@0*@2/2)", RooArgList(tau,dgamma));
      _basisSinh = declareBasis("exp(@0/@1)*sinh(@0*@2/2)", RooArgList(tau,dgamma));
      _basisCos = declareBasis("exp(@0/@1)*cos(@0*@2)",RooArgList(tau, dm));
      _basisSin = declareBasis("exp(@0/@1)*sin(@0*@2)",RooArgList(tau, dm));
      break;
    case DoubleSided:
      _basisCosh = declareBasis("exp(-abs(@0)/@1)*cosh(@0*@2/2)", RooArgList(tau,dgamma));
      _basisSinh = declareBasis("exp(-abs(@0)/@1)*sinh(@0*@2/2)", RooArgList(tau,dgamma));
      _basisCos = declareBasis("exp(-abs(@0)/@1)*cos(@0*@2)",RooArgList(tau, dm));
      _basisSin = declareBasis("exp(-abs(@0)/@1)*sin(@0*@2)",RooArgList(tau, dm));
      break;
    }
}

//_____________________________________________________________________________
RooBDecay::RooBDecay(const RooBDecay& other, const char* name) :
  RooAbsAnaConvPdf(other, name),
  _t("t", this, other._t),
  _tau("tau", this, other._tau),
  _dgamma("dgamma", this, other._dgamma),
  _f0("f0", this, other._f0),
  _f1("f1", this, other._f1),
  _f2("f2", this, other._f2),
  _f3("f3", this, other._f3),
  _dm("dm", this, other._dm),
  _basisCosh(other._basisCosh),
  _basisSinh(other._basisSinh),
  _basisCos(other._basisCos),
  _basisSin(other._basisSin),
  _type(other._type)
{
  //Copy constructor
}



//_____________________________________________________________________________
RooBDecay::~RooBDecay()
{
  //Destructor
}


//_____________________________________________________________________________
Double_t RooBDecay::coefficient(Int_t basisIndex) const
{
  if(basisIndex == _basisCosh)
    {  
      return _f0;
    }
  if(basisIndex == _basisSinh)
    {
      return _f1;
    }
  if(basisIndex == _basisCos)
    {
      return _f2;
    }
  if(basisIndex == _basisSin)
    {
      return _f3;
    }

  return 0 ;
}


//_____________________________________________________________________________
RooArgSet* RooBDecay::coefVars(Int_t basisIndex) const 
{
  if(basisIndex == _basisCosh)
    {  
      return _f0.arg().getVariables();
    }
  if(basisIndex == _basisSinh)
    {
      return _f1.arg().getVariables();
    }
  if(basisIndex == _basisCos)
    {
      return _f2.arg().getVariables();
    }
  if(basisIndex == _basisSin)
    {
      return _f3.arg().getVariables();
    }

  return 0 ;  
}



//_____________________________________________________________________________
Int_t RooBDecay::getCoefAnalyticalIntegral(Int_t coef, RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const 
{
  if(coef == _basisCosh)
    {  
      return _f0.arg().getAnalyticalIntegral(allVars,analVars,rangeName) ;
    }
  if(coef == _basisSinh)
    {
      return _f1.arg().getAnalyticalIntegral(allVars,analVars,rangeName) ;
    }
  if(coef == _basisCos)
    {
      return _f2.arg().getAnalyticalIntegral(allVars,analVars,rangeName) ;
    }
  if(coef == _basisSin)
    {
      return _f3.arg().getAnalyticalIntegral(allVars,analVars,rangeName) ;
    }

  return 0 ;
}



//_____________________________________________________________________________
Double_t RooBDecay::coefAnalyticalIntegral(Int_t coef, Int_t code, const char* rangeName) const 
{
  if(coef == _basisCosh)
    {  
      return _f0.arg().analyticalIntegral(code,rangeName) ;
    }
  if(coef == _basisSinh)
    {
      return _f1.arg().analyticalIntegral(code,rangeName) ;
    }
  if(coef == _basisCos)
    {
      return _f2.arg().analyticalIntegral(code,rangeName) ;
    }
  if(coef == _basisSin)
    {
      return _f3.arg().analyticalIntegral(code,rangeName) ;
    }

  return 0 ;
}



//_____________________________________________________________________________
Int_t RooBDecay::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t /*staticInitOK*/) const
{
  if (matchArgs(directVars, generateVars, _t)) return 1;
  return 0;
}



//_____________________________________________________________________________
void RooBDecay::generateEvent(Int_t code)
{
  R__ASSERT(code==1);
  Double_t gammamin = 1/_tau-TMath::Abs(_dgamma)/2;
  while(1) {
    Double_t t = -log(RooRandom::uniform())/gammamin;
    if (_type == Flipped || (_type == DoubleSided && RooRandom::uniform() <0.5) ) t *= -1;
    if ( t<_t.min() || t>_t.max() ) continue;

    Double_t dgt = _dgamma*t/2;
    Double_t dmt = _dm*t;
    Double_t ft = fabs(t);
    Double_t f = exp(-ft/_tau)*(_f0*cosh(dgt)+_f1*sinh(dgt)+_f2*cos(dmt)+_f3*sin(dmt));
    if(f < 0) {
      cout << "RooBDecay::generateEvent(" << GetName() << ") ERROR: PDF value less than zero" << endl;
      ::abort();
    }
    Double_t w = 1.001*exp(-ft*gammamin)*(TMath::Abs(_f0)+TMath::Abs(_f1)+sqrt(_f2*_f2+_f3*_f3));
    if(w < f) {
      cout << "RooBDecay::generateEvent(" << GetName() << ") ERROR: Envelope function less than p.d.f. " << endl;
      cout << _f0 << endl;
      cout << _f1 << endl;
      cout << _f2 << endl;
      cout << _f3 << endl;
      ::abort();
    }
    if(w*RooRandom::uniform() > f) continue;
    _t = t;
    break;
  }
}




















































 RooBDecay.cxx:1
 RooBDecay.cxx:2
 RooBDecay.cxx:3
 RooBDecay.cxx:4
 RooBDecay.cxx:5
 RooBDecay.cxx:6
 RooBDecay.cxx:7
 RooBDecay.cxx:8
 RooBDecay.cxx:9
 RooBDecay.cxx:10
 RooBDecay.cxx:11
 RooBDecay.cxx:12
 RooBDecay.cxx:13
 RooBDecay.cxx:14
 RooBDecay.cxx:15
 RooBDecay.cxx:16
 RooBDecay.cxx:17
 RooBDecay.cxx:18
 RooBDecay.cxx:19
 RooBDecay.cxx:20
 RooBDecay.cxx:21
 RooBDecay.cxx:22
 RooBDecay.cxx:23
 RooBDecay.cxx:24
 RooBDecay.cxx:25
 RooBDecay.cxx:26
 RooBDecay.cxx:27
 RooBDecay.cxx:28
 RooBDecay.cxx:29
 RooBDecay.cxx:30
 RooBDecay.cxx:31
 RooBDecay.cxx:32
 RooBDecay.cxx:33
 RooBDecay.cxx:34
 RooBDecay.cxx:35
 RooBDecay.cxx:36
 RooBDecay.cxx:37
 RooBDecay.cxx:38
 RooBDecay.cxx:39
 RooBDecay.cxx:40
 RooBDecay.cxx:41
 RooBDecay.cxx:42
 RooBDecay.cxx:43
 RooBDecay.cxx:44
 RooBDecay.cxx:45
 RooBDecay.cxx:46
 RooBDecay.cxx:47
 RooBDecay.cxx:48
 RooBDecay.cxx:49
 RooBDecay.cxx:50
 RooBDecay.cxx:51
 RooBDecay.cxx:52
 RooBDecay.cxx:53
 RooBDecay.cxx:54
 RooBDecay.cxx:55
 RooBDecay.cxx:56
 RooBDecay.cxx:57
 RooBDecay.cxx:58
 RooBDecay.cxx:59
 RooBDecay.cxx:60
 RooBDecay.cxx:61
 RooBDecay.cxx:62
 RooBDecay.cxx:63
 RooBDecay.cxx:64
 RooBDecay.cxx:65
 RooBDecay.cxx:66
 RooBDecay.cxx:67
 RooBDecay.cxx:68
 RooBDecay.cxx:69
 RooBDecay.cxx:70
 RooBDecay.cxx:71
 RooBDecay.cxx:72
 RooBDecay.cxx:73
 RooBDecay.cxx:74
 RooBDecay.cxx:75
 RooBDecay.cxx:76
 RooBDecay.cxx:77
 RooBDecay.cxx:78
 RooBDecay.cxx:79
 RooBDecay.cxx:80
 RooBDecay.cxx:81
 RooBDecay.cxx:82
 RooBDecay.cxx:83
 RooBDecay.cxx:84
 RooBDecay.cxx:85
 RooBDecay.cxx:86
 RooBDecay.cxx:87
 RooBDecay.cxx:88
 RooBDecay.cxx:89
 RooBDecay.cxx:90
 RooBDecay.cxx:91
 RooBDecay.cxx:92
 RooBDecay.cxx:93
 RooBDecay.cxx:94
 RooBDecay.cxx:95
 RooBDecay.cxx:96
 RooBDecay.cxx:97
 RooBDecay.cxx:98
 RooBDecay.cxx:99
 RooBDecay.cxx:100
 RooBDecay.cxx:101
 RooBDecay.cxx:102
 RooBDecay.cxx:103
 RooBDecay.cxx:104
 RooBDecay.cxx:105
 RooBDecay.cxx:106
 RooBDecay.cxx:107
 RooBDecay.cxx:108
 RooBDecay.cxx:109
 RooBDecay.cxx:110
 RooBDecay.cxx:111
 RooBDecay.cxx:112
 RooBDecay.cxx:113
 RooBDecay.cxx:114
 RooBDecay.cxx:115
 RooBDecay.cxx:116
 RooBDecay.cxx:117
 RooBDecay.cxx:118
 RooBDecay.cxx:119
 RooBDecay.cxx:120
 RooBDecay.cxx:121
 RooBDecay.cxx:122
 RooBDecay.cxx:123
 RooBDecay.cxx:124
 RooBDecay.cxx:125
 RooBDecay.cxx:126
 RooBDecay.cxx:127
 RooBDecay.cxx:128
 RooBDecay.cxx:129
 RooBDecay.cxx:130
 RooBDecay.cxx:131
 RooBDecay.cxx:132
 RooBDecay.cxx:133
 RooBDecay.cxx:134
 RooBDecay.cxx:135
 RooBDecay.cxx:136
 RooBDecay.cxx:137
 RooBDecay.cxx:138
 RooBDecay.cxx:139
 RooBDecay.cxx:140
 RooBDecay.cxx:141
 RooBDecay.cxx:142
 RooBDecay.cxx:143
 RooBDecay.cxx:144
 RooBDecay.cxx:145
 RooBDecay.cxx:146
 RooBDecay.cxx:147
 RooBDecay.cxx:148
 RooBDecay.cxx:149
 RooBDecay.cxx:150
 RooBDecay.cxx:151
 RooBDecay.cxx:152
 RooBDecay.cxx:153
 RooBDecay.cxx:154
 RooBDecay.cxx:155
 RooBDecay.cxx:156
 RooBDecay.cxx:157
 RooBDecay.cxx:158
 RooBDecay.cxx:159
 RooBDecay.cxx:160
 RooBDecay.cxx:161
 RooBDecay.cxx:162
 RooBDecay.cxx:163
 RooBDecay.cxx:164
 RooBDecay.cxx:165
 RooBDecay.cxx:166
 RooBDecay.cxx:167
 RooBDecay.cxx:168
 RooBDecay.cxx:169
 RooBDecay.cxx:170
 RooBDecay.cxx:171
 RooBDecay.cxx:172
 RooBDecay.cxx:173
 RooBDecay.cxx:174
 RooBDecay.cxx:175
 RooBDecay.cxx:176
 RooBDecay.cxx:177
 RooBDecay.cxx:178
 RooBDecay.cxx:179
 RooBDecay.cxx:180
 RooBDecay.cxx:181
 RooBDecay.cxx:182
 RooBDecay.cxx:183
 RooBDecay.cxx:184
 RooBDecay.cxx:185
 RooBDecay.cxx:186
 RooBDecay.cxx:187
 RooBDecay.cxx:188
 RooBDecay.cxx:189
 RooBDecay.cxx:190
 RooBDecay.cxx:191
 RooBDecay.cxx:192
 RooBDecay.cxx:193
 RooBDecay.cxx:194
 RooBDecay.cxx:195
 RooBDecay.cxx:196
 RooBDecay.cxx:197
 RooBDecay.cxx:198
 RooBDecay.cxx:199
 RooBDecay.cxx:200
 RooBDecay.cxx:201
 RooBDecay.cxx:202
 RooBDecay.cxx:203
 RooBDecay.cxx:204
 RooBDecay.cxx:205
 RooBDecay.cxx:206
 RooBDecay.cxx:207
 RooBDecay.cxx:208
 RooBDecay.cxx:209
 RooBDecay.cxx:210
 RooBDecay.cxx:211
 RooBDecay.cxx:212
 RooBDecay.cxx:213
 RooBDecay.cxx:214
 RooBDecay.cxx:215
 RooBDecay.cxx:216
 RooBDecay.cxx:217
 RooBDecay.cxx:218
 RooBDecay.cxx:219
 RooBDecay.cxx:220
 RooBDecay.cxx:221
 RooBDecay.cxx:222
 RooBDecay.cxx:223
 RooBDecay.cxx:224
 RooBDecay.cxx:225
 RooBDecay.cxx:226
 RooBDecay.cxx:227
 RooBDecay.cxx:228
 RooBDecay.cxx:229
 RooBDecay.cxx:230
 RooBDecay.cxx:231
 RooBDecay.cxx:232
 RooBDecay.cxx:233
 RooBDecay.cxx:234
 RooBDecay.cxx:235
 RooBDecay.cxx:236
 RooBDecay.cxx:237
 RooBDecay.cxx:238
 RooBDecay.cxx:239
 RooBDecay.cxx:240
 RooBDecay.cxx:241
 RooBDecay.cxx:242
 RooBDecay.cxx:243
 RooBDecay.cxx:244
 RooBDecay.cxx:245
 RooBDecay.cxx:246
 RooBDecay.cxx:247
 RooBDecay.cxx:248
 RooBDecay.cxx:249
 RooBDecay.cxx:250
 RooBDecay.cxx:251
 RooBDecay.cxx:252
 RooBDecay.cxx:253
 RooBDecay.cxx:254
 RooBDecay.cxx:255
 RooBDecay.cxx:256
 RooBDecay.cxx:257
 RooBDecay.cxx:258
 RooBDecay.cxx:259
 RooBDecay.cxx:260
 RooBDecay.cxx:261
 RooBDecay.cxx:262
 RooBDecay.cxx:263
 RooBDecay.cxx:264
 RooBDecay.cxx:265
 RooBDecay.cxx:266
 RooBDecay.cxx:267
 RooBDecay.cxx:268
 RooBDecay.cxx:269
 RooBDecay.cxx:270
 RooBDecay.cxx:271
 RooBDecay.cxx:272
 RooBDecay.cxx:273
 RooBDecay.cxx:274
 RooBDecay.cxx:275
 RooBDecay.cxx:276
 RooBDecay.cxx:277
 RooBDecay.cxx:278
 RooBDecay.cxx:279
 RooBDecay.cxx:280
 RooBDecay.cxx:281
 RooBDecay.cxx:282
 RooBDecay.cxx:283
 RooBDecay.cxx:284
 RooBDecay.cxx:285
 RooBDecay.cxx:286
 RooBDecay.cxx:287
 RooBDecay.cxx:288
 RooBDecay.cxx:289
 RooBDecay.cxx:290
 RooBDecay.cxx:291
 RooBDecay.cxx:292
 RooBDecay.cxx:293
 RooBDecay.cxx:294
 RooBDecay.cxx:295
 RooBDecay.cxx:296
 RooBDecay.cxx:297
 RooBDecay.cxx:298
 RooBDecay.cxx:299
 RooBDecay.cxx:300
 RooBDecay.cxx:301
 RooBDecay.cxx:302
 RooBDecay.cxx:303
 RooBDecay.cxx:304
 RooBDecay.cxx:305