CMS 3D CMS Logo

List of all members | Public Member Functions
DoubleCrystalBallGenerator Class Reference

#include <DoubleCrystalBallGenerator.h>

Public Member Functions

 DoubleCrystalBallGenerator ()
 
double shoot (double mu, double sigma, double aL, double nL, double aR, double nR, RandomEngineAndDistribution const *random)
 
virtual ~DoubleCrystalBallGenerator ()
 

Detailed Description

Definition at line 12 of file DoubleCrystalBallGenerator.h.

Constructor & Destructor Documentation

DoubleCrystalBallGenerator::DoubleCrystalBallGenerator ( )
inline

Definition at line 16 of file DoubleCrystalBallGenerator.h.

16 { }
virtual DoubleCrystalBallGenerator::~DoubleCrystalBallGenerator ( )
inlinevirtual

Definition at line 18 of file DoubleCrystalBallGenerator.h.

References RPCpg::mu, random, and shoot().

18 {}

Member Function Documentation

double DoubleCrystalBallGenerator::shoot ( double  mu,
double  sigma,
double  aL,
double  nL,
double  aR,
double  nR,
RandomEngineAndDistribution const *  random 
)

Definition at line 11 of file DoubleCrystalBallGenerator.cc.

References PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi::dR, RandomEngineAndDistribution::flatShoot(), N, Pi, x, and y.

Referenced by ~DoubleCrystalBallGenerator().

12  {
13  if(nL<=1 || nR<=1) return 0; //n>1 required
14 
15  double dL = nL/aL;
16  double dR = nR/aR;
17  double N = 1/(sigma*(nL/aL*1/(nL-1)*Exp(-aL*aL/2) + Sqrt(Pi()/2)*(Erf(aL/Sqrt(2))+Erf(aR/Sqrt(2))) + nR/aR*1/(nR-1)*Exp(-aR*aR/2)));
18 
19  //start x as NaN
20  double x = 0./0.;
21  while(!Finite(x)){
22  //shoot a flat random number
23  double y = random->flatShoot();
24 
25  //check range
26  //crystal ball CDF changes at (x-mu)/sigma = -aL && (x-mu)/sigma = aR
27  //compute this in pieces because it is awful
28  double AL = dL/(nL-1)*Exp(-aL*aL/2);
29  double CL = Sqrt(Pi()/2)*Erf(aL/Sqrt(2));
30  double CR = Sqrt(Pi()/2)*Erf(aR/Sqrt(2));
31  if(y < sigma*N*AL){//below lower boundary, use inverted power law CDF (left side)
32  double BL = dL/(nL-1)*Exp(-aL*aL/2);
33  x = mu + sigma*(-dL*Power(y/(sigma*N*BL),1/(-nL+1)) - aL + dL);
34  }
35  else if(y > sigma*N*(AL+CL+CR)){//above lower boundary, use inverted power law CDF (right side)
36  double AR = dR/(nR-1)*Exp(-aR*aR/2);
37  double BR = dR/(1-nR)*Exp(-aR*aR/2);
38  double D = (y/(sigma*N)-AL-CL-CR-AR)/BR;
39  x = mu + sigma*(dR*Power(D,1/(-nR+1)) + aR - dR);
40  }
41  else{//between boundaries, use gaussian CDF with proper normalization (in terms of erfc)
42  double D = 1 - Sqrt(2/Pi())*(y/(sigma*N)-AL-CL);
43  x = mu + sigma*Sqrt(2)*ErfcInverse(D);
44  }
45  }
46  return x;
47 }
const double Pi
TRandom random
Definition: MVATrainer.cc:138
const int mu
Definition: Constants.h:22
#define N
Definition: blowfish.cc:9
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:151