/** * @file funcs.hh * @author Christoph Langenbruch, Renata Kopecna * @date 2009-03-18 * */ #ifndef FUNCS_H #define FUNCS_H #include #include #include #include #include #include #include #include #include namespace fcnc { //Forward declaration, fully defined in options.hh class options; class event; } namespace fcnc { typedef ROOT::Math::PxPyPzEVector LorentzVector; typedef ROOT::Math::Boost LorentzBoost; typedef ROOT::Math::DisplacementVector3D > Vector3; TMatrixDSym get_bsz_invcov(); TMatrixDSym get_bsz_cov(); TMatrixD get_bsz_mu_invcov(); double eff_paper(const double& q2, const double& ctl, const double& ctk, const double& phi); double get_sliding_error(double xmeas, double xth, double eup, double edown); double crystalball(double m, double mean, double sigma, double alpha, double n); double twotailedcrystalball(double m, double mean, double sigma, double alpha1, double alpha2, double n1, double n2); //blinding double evaluate_unblind_uniform(double valueSeenByAnalist, const char* blindingString, double scale); double evaluate_unblind_uniform_angle(double valueSeenByAnalist, const char* blindingString, double scale); double sqr(double x); //basic trigonometric functions double costheta2(double costheta); double cos2theta(double costheta); double sintheta2(double costheta); double sintheta_abs(double costheta); double sin2theta(double costheta); double chebyshev(double x, int n); void chebyshev(double x, int n, std::vector& results); void chebyshev_to_poly(const std::vector& chebychev, std::vector& poly); void correct_poly(const std::vector& poly, std::vector& correct, double min, double max); double legendre(double x, int n); void legendre(double x, int n, std::vector& results); void orthonormal_legendre(double x, int n, std::vector& results); void legendre_to_poly(const std::vector& legendre, std::vector& poly); ///calculates the associated legendre polynomial for l,m order double assoc_legendre(unsigned int l, unsigned int m, double x); ///calculates the real part of the spherical harmonics for l, m double spherical_harmonic_re(unsigned int l, unsigned int m, double theta, double phi); ///calculates the imaginary part of the spherical harmonics for l, m double spherical_harmonic_im(unsigned int l, unsigned int m, double theta, double phi); ///function calculates the angles in the transversity base using the momenta of the final state particles void calculate_transversity_angles(const LorentzVector& mu_minus, const LorentzVector& mu_plus, const LorentzVector& k_minus, const LorentzVector& k_plus, double & cos_theta, double & angle_phi, double & cos_psi); ///this function calculates the convolution sin(angle) from 0 to pi double convoluted_sin(double angle, double sigma); double convoluted_cos_sin(double angle, double sigma); double convoluted_cos(double angle, double sigma);//not used double convoluted_cos_2(double angle, double sigma);//not used double convoluted_sin_2(double angle, double sigma);//used by s wave double convoluted_2_sin(double angle, double sigma);//used by s wave double convoluted_2_cos(double angle, double sigma);//not used double convoluted_cos_2_sin(double angle, double sigma); double convoluted_2_sin_sin(double angle, double sigma); double convoluted_sin_3(double angle, double sigma); //this integrates the above expressions (vonvolution before has been from 0 to pi double int_convoluted_sin(double angle, double sigma); double int_convoluted_cos_sin(double angle, double sigma); double int_convoluted_cos_2_sin(double angle, double sigma); double int_convoluted_2_sin_sin(double angle, double sigma); double int_convoluted_sin_3(double angle, double sigma); double int_convoluted_sin_2(double angle, double sigma);//used by s wave double int_convoluted_2_sin(double angle, double sigma);//used by s wave //convolutions for phi. this is easier due to the wraparound at +-pi -> convolution from -int to inf double inf_convoluted_sin(double angle, double sigma); double inf_convoluted_cos(double angle, double sigma); double inf_convoluted_cos_2(double angle, double sigma); double inf_convoluted_sin_2(double angle, double sigma); double inf_convoluted_2_sin(double angle, double sigma); //integral of above double int_inf_convoluted_const(double angle, double sigma); double int_inf_convoluted_sin(double angle, double sigma); double int_inf_convoluted_cos(double angle, double sigma); double int_inf_convoluted_cos_2(double angle, double sigma); double int_inf_convoluted_sin_2(double angle, double sigma); double int_inf_convoluted_2_sin(double angle, double sigma); //integrals from -inf to inf over the convolution from 0 to pi with acceptance double int_convoluted_sin_cos_n(int n, double sigma); double int_convoluted_sin_3_cos_n(int n, double sigma); double int_convoluted_cos_2_sin_cos_n(int n, double sigma); double int_convoluted_2_sin_sin_cos_n(int n, double sigma); double int_convoluted_cos_sin_cos_n(int n, double sigma); double int_convoluted_sin_2_cos_n(int n, double sigma); //integrals from 0 to pi over the convolution from -inf to inf with acceptance double int_inf_convoluted_const_x_n(int n, double sigma); double int_inf_convoluted_cos_2_x_n(int n, double sigma); double int_inf_convoluted_sin_2_x_n(int n, double sigma); double int_inf_convoluted_sin_x_n(int n, double sigma); double int_inf_convoluted_2_sin_x_n(int n, double sigma); double int_inf_convoluted_cos_x_n(int n, double sigma); ///function gives the result of exp(-ct/tau)*sin(delta_m*ct) and exp(-ct/tau)*cos(delta_m*ct) convoluted with a gaussian with width sigma void convoluted_exp_sincos(double ct, double sigma, double tau, double deltam, double& one, double& two); ///function gives the norm of the expression exp(-ct/tau)*sin(delta_m*ct) and exp(-ct/tau)*cos(delta_m*ct) convoluted with a gaussian with width sigma void norm_convoluted_exp_sincos(double tau, double deltam, double& one, double& two); ///function calculates exp(-ct/tau) convoluted with a gaussian with width sigma double convoluted_exp(double ct, double sigma_ct, double S); ///function calculates exp(-ct/tau) depending on the parameters normalized or not double expdecay(double t, double tau, bool normalized); ///function calculates 1/(sqrt(2*pi)*exp(-(x-mean)^2/(2*sigma^2))) double gauss(double x, double sigma, double mean); ///function calculates a normed gaussian between the values min and max used in the mass pdfs double normed_gauss(double x, double sigma, double mean, double min, double max); ///integrate gauss from a to b double linear(double x, double min, double max, double slope); ///very important helper function, the error function with complex argument. This is probably one of the performance bottlenecks. Probably much faster with a lookup table and interpolation double threshold(double x, double thr, double n); double int_threshold(double a, double b, double thr, double n); //see arxiv 1207.4004 /* std::complex bw_kstar_amp(double mkpi_squared, double gammakstar, double mkstar); std::complex bw_kstarzero_amp(double mkpisquared, double gk_re, double gk_im, double gammak, double mk, double gammakstarzero, double mkstarzero); double bw_kstar_amp_squared(double mkpisquared, double gammakstar, double mkstar); std::complex bw_kstar_amp_kstarzero_amp_bar(double mkpisquared, double gammakstar, double mkstar, double gk_re, double gk_im, double gammak, double mk, double gammakstarzero, double mkstarzero); double bw_kstarzero_amp_squared(double mkpisquared, double gk_re, double gk_im, double gammak, double mk, double gammakstarzero, double mkstarzero); */ double daughtermom(double m, double m1, double m2); std::complex mkpi_simple_bw_kstar_amp(double mkpi, double qsquared, double gammakstar, double mkstar); double mkpi_simple_bw_kstar_amp_squared(double mkpi, double qsquared, double gammakstar, double mkstar); double gsl_mkpi_simple_bw_kstar_amp_squared(double x, void* par); double int_mkpi_simple_bw_kstar_amp_squared(const double& mkpia, const double& mkpib, const double& qsquared, const double& gammakstar, const double& mkstar); std::complex mkpi_simple_kstarzero_amp(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero); double mkpi_simple_kstarzero_amp_squared(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero); double gsl_mkpi_simple_kstarzero_amp_squared(double x, void* par); double int_mkpi_simple_kstarzero_amp_squared(const double& mkpia, const double& mkpib, const double& qsquared, const double& f800mag, const double& f800phase, const double& gammaf800, const double& mf800, const double& gammakstarzero, const double& mkstarzero); std::complex mkpi_simple_bw_kstar_amp_kstarzero_amp_bar(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero); std::complex mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero); std::complex int_mkpi_simple_bw_kstar_amp_kstarzero_amp_bar(const double& mkpia, const double& mkpib, const double& qsquared, const double& gammakstar, const double& mkstar, const double& asphase, const double& f800mag, const double& f800phase, const double& gammaf800, const double& mf800, const double& gammakstarzero, const double& mkstarzero); std::complex int_mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(const double& mkpia, const double& mkpib, const double& qsquared, const double& gammakstar, const double& mkstar, const double& asphase, const double& f800mag, const double& f800phase, const double& gammaf800, const double& mf800, const double& gammakstarzero, const double& mkstarzero); double gsl_mkpi_simple_re_bw_kstar_amp_kstarzero_amp_bar(double x, void* par); double gsl_mkpi_simple_im_bw_kstar_amp_kstarzero_amp_bar(double x, void* par); double gsl_mkpi_simple_re_bw_kstar_amp_bar_kstarzero_amp(double x, void* par); double gsl_mkpi_simple_im_bw_kstar_amp_bar_kstarzero_amp(double x, void* par); std::complex mkpi_bw_kstar_amp(double mkpi, double qsquared, double gammakstar, double mkstar, double R); std::complex mkpi_kstarzero_lass_amp(double mkpi, double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); std::complex mkpi_bw_kstar_amp_kstarzero_lass_amp_bar(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); std::complex mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); double mkpi_bw_kstar_amp_squared(double mkpi, double qsquared, double gammakstar, double mkstar, double R); double mkpi_kstarzero_lass_amp_squared(double mkpi, double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); std::complex mkpi_kstarzero_isobar_amp(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); double mkpi_kstarzero_isobar_amp_squared(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); std::complex mkpi_bw_kstar_amp_kstarzero_isobar_amp_bar(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); std::complex mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); double gsl_mkpi_kstarzero_isobar_amp_squared(double x, void* par); double gsl_mkpi_re_bw_kstar_amp_kstarzero_isobar_amp_bar(double x, void* par); double gsl_mkpi_im_bw_kstar_amp_kstarzero_isobar_amp_bar(double x, void* par); double gsl_mkpi_re_bw_kstar_amp_bar_kstarzero_isobar_amp(double x, void* par); double gsl_mkpi_im_bw_kstar_amp_bar_kstarzero_isobar_amp(double x, void* par); double gsl_mkpi_bw_kstar_amp_squared(double x, void* par); double gsl_mkpi_kstarzero_lass_amp_squared(double x, void* par); double gsl_mkpi_re_bw_kstar_amp_kstarzero_lass_amp_bar(double x, void* par); double gsl_mkpi_im_bw_kstar_amp_kstarzero_lass_amp_bar(double x, void* par); double gsl_mkpi_re_bw_kstar_amp_bar_kstarzero_lass_amp(double x, void* par); double gsl_mkpi_im_bw_kstar_amp_bar_kstarzero_lass_amp(double x, void* par); double int_mkpi_bw_kstar_amp_squared(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double R); double int_mkpi_bw_kstar_amp_squared(double qsquared, double gammakstar, double mkstar, double R); double int_mkpi_kstarzero_lass_amp_squared(double mkpia, double mkpib, double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); double int_mkpi_kstarzero_lass_amp_squared(double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_kstarzero_lass_amp_bar(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_kstarzero_lass_amp_bar(double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R); double int_mkpi_kstarzero_isobar_amp_squared(double mkpia, double mkpib, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); double int_mkpi_kstarzero_isobar_amp_squared(double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_kstarzero_isobar_amp_bar(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_kstarzero_isobar_amp_bar(double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); std::complex int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(double qsquared, double gammakstar, double mkstar, double asphase, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R); double rndgauss(TRandom3* rnd, double mean, double width, double min, double max); double rndgauss(TRandom3* rnd, double mean, double widthlo, double widthhi, double min, double max); void moments_to_observables(TRandom3* rnd, std::vector mom, std::vector momcov, double fsext, double dfsext, std::vector& obs, std::vector& obscov, bool usefsext = true ); template struct NumberGreaterThan { bool operator()(const T a, const T b) const { return std::abs(a) > std::abs(b); } }; template typename iterator::value_type add_numbers(iterator begin, iterator end){ typedef typename iterator::value_type T; if (end == begin) return 0.; std::make_heap(begin, end, NumberGreaterThan()); for (; begin + 1 < end; ) { T x = *begin; std::pop_heap(begin, end--, NumberGreaterThan()); do { x += *begin; std::pop_heap(begin, end--, NumberGreaterThan()); } while (std::abs(*begin) >= std::abs(x) && begin < end); *end++ = x; std::push_heap(begin, end, NumberGreaterThan()); } return *begin; }; std::vectorGetNOutOfM(UInt_t N, UInt_t M, Int_t Seed, bool DoubleCounts, bool PoissonFluctuate); template typename iterator::value_type add_numbers(iterator begin, iterator end); int throw_multivariate_normal(const unsigned int ndim, const unsigned int ntoys, const std::vector& xi, const std::vector& cov, std::vector >& results); int get_mean_cov(const std::vector >& meas, std::vector& mean, std::vector& cov); void sis_to_pis(TRandom3* rnd, std::vector sis, std::vector sicorrs, std::vector& pis, std::vector& picorrs); std::complex cErrF(const std::complex& x); ///implementation 2 of the complex error function std::complex cErrF_2(const std::complex& x); std::complex ErrF_2(const std::complex& x); ///implementation 3 of the complex error function std::complex cErrF_3(const std::complex& x); ///the faddeeva function function std::complex Faddeeva_2 (const std::complex& z); ///used by cErrF, does the actual calculations std::complex wErrF(const std::complex& arg); ///This is another version of the complex error function, used in the newer cdf code std::complex nwwerf(const std::complex z); } #endif