59 ClassImp(RooSpHarmonic);
64 inline double N(
int l,
int m=0) {
65 double n = sqrt(
double(2*l+1)/(4*TMath::Pi())*TMath::Factorial(l-m)/TMath::Factorial(l+m) );
66 return m==0 ? n : TMath::Sqrt2() * n;
72 RooSpHarmonic::RooSpHarmonic() :
81 RooSpHarmonic::RooSpHarmonic(
const char* name,
const char* title, RooAbsReal& ctheta, RooAbsReal& phi,
int l,
int m)
82 : RooLegendre(name, title,ctheta,l,m<0?-m:m)
83 , _phi(
"phi",
"phi", this, phi)
84 , _n( 2*sqrt(TMath::Pi()))
85 , _sgn1( m==0 ? 0 : m<0 ? -1 : +1 )
92 RooSpHarmonic::RooSpHarmonic(
const char* name,
const char* title, RooAbsReal& ctheta, RooAbsReal& phi,
int l1,
int m1,
int l2,
int m2)
93 : RooLegendre(name, title,ctheta,l1, m1<0?-m1:m1,l2,m2<0?-m2:m2)
94 , _phi(
"phi",
"phi", this, phi)
96 , _sgn1( m1==0 ? 0 : m1<0 ? -1 : +1 )
97 , _sgn2( m2==0 ? 0 : m2<0 ? -1 : +1 )
103 RooSpHarmonic::RooSpHarmonic(
const RooSpHarmonic& other,
const char* name)
104 : RooLegendre(other, name)
105 , _phi(
"phi", this,other._phi)
107 , _sgn1( other._sgn1 )
108 , _sgn2( other._sgn2 )
114 Double_t RooSpHarmonic::evaluate()
const
116 double n = _n*N(_l1,_m1)*N(_l2,_m2)*RooLegendre::evaluate();
117 if (_sgn1!=0) n *= (_sgn1<0 ? sin(_m1*_phi) : cos(_m1*_phi) );
118 if (_sgn2!=0) n *= (_sgn2<0 ? sin(_m2*_phi) : cos(_m2*_phi) );
125 Bool_t fullRange(
const RooRealProxy& x,
const char* range, Bool_t phi)
128 return range == 0 || strlen(range) == 0
129 ? std::fabs(x.max() - x.min() - TMath::TwoPi()) < 1.e-8
130 : std::fabs(x.max(range) - x.min(range) - TMath::TwoPi()) < 1.e-8;
133 return range == 0 || strlen(range) == 0
134 ? std::fabs(x.min() + 1.) < 1.e-8 && std::fabs(x.max() - 1.) < 1.e-8
135 : std::fabs(x.min(range) + 1.) < 1.e-8 && std::fabs(x.max(range) - 1.) < 1.e-8;
143 Int_t RooSpHarmonic::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* rangeName)
const
146 Bool_t cthetaOK = fullRange(_ctheta, rangeName, kFALSE);
147 Bool_t phiOK = fullRange(_phi, rangeName, kTRUE );
148 if (cthetaOK && phiOK && matchArgs(allVars, analVars, _ctheta, _phi))
return 3;
149 if ( phiOK && matchArgs(allVars, analVars, _phi))
return 2;
150 return RooLegendre::getAnalyticalIntegral(allVars, analVars, rangeName);
155 Double_t RooSpHarmonic::analyticalIntegral(Int_t code,
const char* range)
const
158 return (_l1==_l2 && _sgn1*_m1==_sgn2*_m2 ) ? _n : 0 ;
159 }
else if (code == 2) {
160 if ( _sgn1*_m1 != _sgn2*_m2)
return 0;
161 return ( _m1==0 ? 2 : 1 ) * TMath::Pi()*_n*N(_l1,_m1)*N(_l2,_m2)*RooLegendre::evaluate();
163 double n = _n*N(_l1,_m1)*N(_l2,_m2)*RooLegendre::analyticalIntegral(code,range);
164 if (_sgn1!=0) n *= (_sgn1<0 ? sin(_m1*_phi) : cos(_m1*_phi) );
165 if (_sgn2!=0) n *= (_sgn2<0 ? sin(_m2*_phi) : cos(_m2*_phi) );
170 Int_t RooSpHarmonic::getMaxVal(
const RooArgSet& vars)
const {
171 return RooLegendre::getMaxVal(vars);
174 Double_t RooSpHarmonic::maxVal( Int_t code)
const {
175 double n = _n*N(_l1,_m1)*N(_l2,_m2);
176 return n*RooLegendre::maxVal(code);