20#include "KalFitAlg/lpav/Lpav.h"
21using CLHEP::Hep3Vector;
22using CLHEP::HepMatrix;
23using CLHEP::HepSymMatrix;
24using CLHEP::HepVector;
33 static double err_dis_inv(
double x,
double y,
double w,
double a,
double b ) {
34 if ( a == 0 && b == 0 ) {
return w; }
37 double f =
x * b - y * a;
38 double rsq =
x *
x + y * y;
81 if ( m_wsum <= 0 )
return;
82 m_wsum_temp = m_wsum + wi;
83 double rri( xi * xi + yi * yi );
84 double wrri( wi * rri );
85 double wsum_inv( 1 / m_wsum_temp );
86 m_xav = ( m_xsum + wi * xi ) * wsum_inv;
87 m_yav = ( m_ysum + wi * yi ) * wsum_inv;
89 double xxav( ( m_xxsum + wi * xi * xi ) * wsum_inv );
90 double yyav( ( m_yysum + wi * yi * yi ) * wsum_inv );
91 double xyav( ( m_xysum + wi * xi * yi ) * wsum_inv );
92 double xrrav( ( m_xrrsum + xi * wrri ) * wsum_inv );
93 double yrrav( ( m_yrrsum + yi * wrri ) * wsum_inv );
94 double rrrrav( ( m_rrrrsum + wrri * rri ) * wsum_inv );
96 calculate_average_n( xxav, yyav, xyav, xrrav, yrrav, rrrrav );
100 if ( m_wsum <= 0 )
return;
101 m_wsum_temp = m_wsum;
102 double wsum_inv( 1 / m_wsum_temp );
103 m_xav = m_xsum * wsum_inv;
104 m_yav = m_ysum * wsum_inv;
106 double xxav( m_xxsum * wsum_inv );
107 double yyav( m_yysum * wsum_inv );
108 double xyav( m_xysum * wsum_inv );
109 double xrrav( m_xrrsum * wsum_inv );
110 double yrrav( m_yrrsum * wsum_inv );
111 double rrrrav( m_rrrrsum * wsum_inv );
113 calculate_average_n( xxav, yyav, xyav, xrrav, yrrav, rrrrav );
116 void Lpav::calculate_average_n(
double xxav,
double yyav,
double xyav,
double xrrav,
117 double yrrav,
double rrrrav ) {
118 double xxav_p = xxav - m_xav * m_xav;
119 double yyav_p = yyav - m_yav * m_yav;
120 double xyav_p = xyav - m_xav * m_yav;
121 double rrav_p = xxav_p + yyav_p;
123 double a = std::fabs( xxav_p - yyav_p );
124 double b = 4 * xyav_p * xyav_p;
125 double asqpb = a * a + b;
126 double rasqpb = std::sqrt( asqpb );
127 double splus = 1 + a / rasqpb;
128 double sminus = b / ( asqpb * splus );
129 splus = std::sqrt( 0.5 * splus );
130 sminus = std::sqrt( 0.5 * sminus );
134 if ( xxav_p <= yyav_p )
147 if ( xyav_p < 0 ) m_sinrot = -m_sinrot;
157 if ( m_cosrot * m_xav + m_sinrot * m_yav <= 0 )
159 m_cosrot = -m_cosrot;
160 m_sinrot = -m_sinrot;
162 m_rscale = std::sqrt( rrav_p );
163 double cos2 = m_cosrot * m_cosrot;
164 double sin2 = m_sinrot * m_sinrot;
165 double cs2 = 2 * m_sinrot * m_cosrot;
166 double rrav_p_inv( 1 / rrav_p );
167 m_xxavp = ( cos2 * xxav_p + cs2 * xyav_p + sin2 * yyav_p ) * rrav_p_inv;
168 m_yyavp = ( cos2 * yyav_p - cs2 * xyav_p + sin2 * xxav_p ) * rrav_p_inv;
170 double xav2 = m_xav * m_xav;
171 double yav2 = m_yav * m_yav;
173 ( xrrav - 2 * xxav * m_xav + xav2 * m_xav - 2 * xyav * m_yav + m_xav * yav2 ) -
176 ( yrrav - 2 * yyav * m_yav + yav2 * m_yav - 2 * xyav * m_xav + m_yav * xav2 ) -
178 m_xrravp = ( m_cosrot * xrrav_p + m_sinrot * yrrav_p ) * rrav_p_inv / m_rscale;
179 m_yrravp = ( -m_sinrot * xrrav_p + m_cosrot * yrrav_p ) * rrav_p_inv / m_rscale;
181 double rrav = xxav + yyav;
182 double rrrrav_p = rrrrav - 2 * m_yav * yrrav - 2 * m_xav * xrrav + rrav * ( xav2 + yav2 ) -
183 2 * m_xav * xrrav_p - xav2 * rrav_p - 2 * m_yav * yrrav_p -
185 m_rrrravp = rrrrav_p * rrav_p_inv * rrav_p_inv;
190 if ( m_wsum <= 0 )
return;
191 m_wsum_temp = m_wsum + wi;
192 double wsum_inv( 1 / m_wsum_temp );
193 double rri( xi * xi + yi * yi );
194 m_xav = ( m_xsum + wi * xi ) * wsum_inv;
195 m_yav = ( m_ysum + wi * yi ) * wsum_inv;
200 m_xxavp = ( m_xxsum + wi * xi * xi ) * wsum_inv;
201 m_xyavp = ( m_xysum + wi * xi * yi ) * wsum_inv;
202 m_yyavp = ( m_yysum + wi * yi * yi ) * wsum_inv;
203 double wrri( wi * rri );
204 m_xrravp = ( m_xrrsum + xi * wrri ) * wsum_inv;
205 m_yrravp = ( m_yrrsum + yi * wrri ) * wsum_inv;
206 m_rrrravp = ( m_rrrrsum + rri * wrri ) * wsum_inv;
210 if ( m_wsum <= 0 )
return;
211 m_wsum_temp = m_wsum;
212 double wsum_inv( 1 / m_wsum_temp );
213 m_xav = m_xsum * wsum_inv;
214 m_yav = m_ysum * wsum_inv;
219 m_xxavp = m_xxsum * wsum_inv;
220 m_xyavp = m_xysum * wsum_inv;
221 m_yyavp = m_yysum * wsum_inv;
222 m_xrravp = m_xrrsum * wsum_inv;
223 m_yrravp = m_yrrsum * wsum_inv;
224 m_rrrravp = m_rrrrsum * wsum_inv;
247 o <<
" nc=" << a.m_nc <<
" chisq=" << a.m_chisq <<
" " << (
Lpar&)a;
251 double Lpav::solve_lambda(
void ) {
252 if ( m_rscale <= 0 )
return -1;
253 double xrrxrr = m_xrravp * m_xrravp;
254 double yrryrr = m_yrravp * m_yrravp;
255 double rrrrm1 = m_rrrravp - 1;
256 double xxyy = m_xxavp * m_yyavp;
258 double c0 = rrrrm1 * xxyy - xrrxrr * m_yyavp - yrryrr * m_xxavp;
259 double c1 = -rrrrm1 + xrrxrr + yrryrr - 4 * xxyy;
260 double c2 = 4 + rrrrm1 - 4 * xxyy;
270 double chiscl = m_wsum_temp * m_rscale * m_rscale;
271 double dlamax = 0.001 / chiscl;
274 double dlambda = dlamax;
275 while ( itry < ntry && std::fabs( dlambda ) >= dlamax )
277 double cpoly = c0 + lambda * ( c1 + lambda * ( c2 + lambda * lambda * c4 ) );
278 double dcpoly = c1 + lambda * ( c2d + lambda * lambda * c4d );
279 dlambda = -cpoly / dcpoly;
283 lambda = lambda < 0 ? 0 : lambda;
287 double Lpav::solve_lambda3(
void ) {
288 if ( m_rscale <= 0 )
return -1;
289 double xrrxrr = m_xrravp * m_xrravp;
290 double yrryrr = m_yrravp * m_yrravp;
291 double rrrrm1 = m_rrrravp - 1;
292 double xxyy = m_xxavp * m_yyavp;
294 double a = m_rrrravp;
295 double b = xrrxrr + yrryrr - m_rrrravp * ( m_xxavp + m_yyavp );
296 double c = m_rrrravp * m_xxavp * m_yyavp - m_yyavp * xrrxrr - m_xxavp * yrryrr +
297 2 * m_xyavp * m_xrravp * m_yrravp - m_rrrravp * m_xyavp * m_xyavp;
298 if ( c >= 0 && b <= 0 ) {
return ( -b - std::sqrt( b * b - 4 * a * c ) ) / 2 / a; }
299 else if ( c >= 0 && b > 0 )
301 std::cerr <<
" returning " << -1 << std::endl;
304 else if ( c < 0 ) {
return ( -b + std::sqrt( b * b - 4 * a * c ) ) / 2 / a; }
309 double lambda = solve_lambda();
312 if ( lambda < 0 )
return -1;
313 double h11 = m_xxavp - lambda;
314 double h22 = m_yyavp - lambda;
315 if ( h11 == 0.0 )
return -1;
316 double h14 = m_xrravp;
317 double h24 = m_yrravp;
318 double h34 = 1 + 2 * lambda;
319 double rootsq = ( h14 * h14 / h11 / h11 ) + 4 * h34;
320 if ( std::fabs( h22 ) > std::fabs( h24 ) )
322 if ( h22 == 0.0 )
return -1;
323 double ratio = h24 / h22;
324 rootsq += ratio * ratio;
325 m_kappa = 1 / std::sqrt( rootsq );
326 m_beta = -ratio * m_kappa;
330 if ( h24 == 0.0 )
return -1;
331 double ratio = h22 / h24;
332 rootsq = 1 + ratio * ratio * rootsq;
333 m_beta = 1 / std::sqrt( rootsq );
334 m_beta = h24 > 0 ? -m_beta : m_beta;
335 m_kappa = -ratio * m_beta;
337 m_alpha = -( h14 / h11 ) * m_kappa;
338 m_gamma = -h34 * m_kappa;
354 rotate( m_cosrot, -m_sinrot );
358 move( -m_xav, -m_yav );
359 if ( m_yrravp < 0 )
neg();
360 if ( lambda >= 0 ) m_chisq = lambda * m_wsum_temp * m_rscale * m_rscale;
365 double lambda = solve_lambda3();
368 if ( lambda < 0 )
return -1;
369 double h11 = m_xxavp - lambda;
370 double h22 = m_yyavp - lambda;
371 double h14 = m_xrravp;
372 double h24 = m_yrravp;
374 double h12 = m_xyavp;
375 double det = h11 * h22 - h12 * h12;
378 double r1 = ( h14 * h22 - h24 * h12 ) / ( det );
379 double r2 = ( h24 * h11 - h14 * h12 ) / ( det );
380 double kinvsq = r1 * r1 + r2 * r2;
381 m_kappa = std::sqrt( 1 / kinvsq );
382 if ( h11 != 0 ) m_alpha = -m_kappa * r1;
384 if ( h22 != 0 ) m_beta = -m_kappa * r2;
390 if ( h11 != 0 && h22 != 0 )
392 m_beta = 1 / std::sqrt( 1 + h12 * h12 / h11 / h11 );
393 m_alpha = std::sqrt( 1 - m_beta * m_beta );
406 if ( ( m_alpha * m_xav + m_beta * m_yav ) * ( m_beta * m_xav - m_alpha * m_yav ) < 0 )
411 if ( lambda >= 0 ) m_chisq = lambda * m_wsum_temp * m_rscale * m_rscale;
416 if ( m_nc <= 3 )
return -1;
423 if (
q > 0 ) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
429 if (
q > 0 ) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
435 if ( m_nc <= 3 )
return -1;
442 if (
q > 0 ) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
448 if (
q > 0 ) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
454#ifdef BELLE_OPTIMIZED_RETURN
459 HepSymMatrix vret( 4 );
461 vret( 1, 1 ) = m_xxsum;
462 vret( 2, 1 ) = m_xysum;
463 vret( 2, 2 ) = m_yysum;
464 vret( 3, 1 ) = m_xsum;
465 vret( 3, 2 ) = m_ysum;
466 vret( 3, 3 ) = m_wsum;
467 vret( 4, 1 ) = m_xrrsum;
468 vret( 4, 2 ) = m_yrrsum;
469 vret( 4, 3 ) = m_xxsum + m_yysum;
470 vret( 4, 4 ) = m_rrrrsum;
478 std::cerr <<
"Lpav::cov:could not invert nc=" << m_nc << vret;
488#ifdef BELLE_OPTIMIZED_RETURN
493 HepSymMatrix vret( 3 );
499 vret =
cov( 1 ).similarity( dldc() );
502 { THROW( Lpav::cov_c1, Singular_c ); }
511 std::cerr <<
"Lpav::cov_c:could not invert " << vret;
513 THROW( Lpav::cov_c2, Singular_c );
522 if ( m_chisq < 0 )
return -1;
523 if ( xy( r, x, y ) != 0 )
return -1;
524 phi = std::atan2( y, x );
539 double l =
cov().similarity(
v );
542 double ls = std::sqrt( l );
555 if ( m_nc <= 3 )
return -1;
560 v( 4 ) = x * x + y * y;
566 l =
cov().similarity(
v );
574 void Lpav::add(
double xi,
double yi,
double w,
double a,
double b ) {
575 register double wi = err_dis_inv( xi, yi,
w, a, b );
579 void Lpav::add_point(
register double xi,
register double yi,
register double wi ) {
583 m_xxsum += wi * xi * xi;
584 m_yysum += wi * yi * yi;
585 m_xysum += wi * xi * yi;
586 register double rri = ( xi * xi + yi * yi );
587 register double wrri = wi * rri;
588 m_xrrsum += wrri * xi;
589 m_yrrsum += wrri * yi;
590 m_rrrrsum += wrri * rri;
595 register double wi =
w * a;
599 m_xxsum += wi * xi * xi;
600 m_yysum += wi * yi * yi;
601 m_xysum += wi * xi * yi;
602 register double rri = ( xi * xi + yi * yi );
603 register double wrri = wi * rri;
604 m_xrrsum += wrri * xi;
605 m_yrrsum += wrri * yi;
606 m_rrrrsum += wrri * rri;
610 void Lpav::sub(
double xi,
double yi,
double w,
double a,
double b ) {
611 register double wi = err_dis_inv( xi, yi,
w, a, b );
615 m_xxsum -= wi * xi * xi;
616 m_yysum -= wi * yi * yi;
617 m_xysum -= wi * xi * yi;
618 register double rri = ( xi * xi + yi * yi );
619 register double wrri = wi * rri;
620 m_xrrsum -= wrri * xi;
621 m_yrrsum -= wrri * yi;
622 m_rrrrsum -= wrri * rri;
627 m_wsum += la1.m_wsum;
628 m_xsum += la1.m_xsum;
629 m_ysum += la1.m_ysum;
630 m_xxsum += la1.m_xxsum;
631 m_yysum += la1.m_yysum;
632 m_xysum += la1.m_xysum;
633 m_xrrsum += la1.m_xrrsum;
634 m_yrrsum += la1.m_yrrsum;
635 m_rrrrsum += la1.m_rrrrsum;
641#ifdef BELLE_OPTIMIZED_RETURN
648 la.m_wsum = la1.m_wsum + la2.m_wsum;
649 la.m_xsum = la1.m_xsum + la2.m_xsum;
650 la.m_ysum = la1.m_ysum + la2.m_ysum;
651 la.m_xxsum = la1.m_xxsum + la2.m_xxsum;
652 la.m_yysum = la1.m_yysum + la2.m_yysum;
653 la.m_xysum = la1.m_xysum + la2.m_xysum;
654 la.m_xrrsum = la1.m_xrrsum + la2.m_xrrsum;
655 la.m_yrrsum = la1.m_yrrsum + la2.m_yrrsum;
656 la.m_rrrrsum = la1.m_rrrrsum + la2.m_rrrrsum;
657 la.m_nc = la1.m_nc + la2.m_nc;
662 if ( m_nc <= 3 )
return 0;
663 if ( m_chisq < 0 )
return 0;
665 int nci = (int)m_nc - 3;
666 double p = (double)
prob_( &c, &nci );
671 if ( m_nc <= 3 )
return -1;
672 else return m_chisq / ( m_nc - 3 );
677 if ( sim < 0 )
return -1;
678 double d = d0( x, y );
679 double delta = std::sqrt(
d ) *
w / ( 1 + sim *
w );
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")
****INTEGER imax DOUBLE PRECISION m_pi *DOUBLE PRECISION m_amfin DOUBLE PRECISION m_Chfin DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_sinw2 DOUBLE PRECISION m_GFermi DOUBLE PRECISION m_MfinMin DOUBLE PRECISION m_ta2 INTEGER m_out INTEGER m_KeyFSR INTEGER m_KeyQCD *COMMON c_Semalib $ !copy of input $ !CMS energy $ !beam mass $ !final mass $ !beam charge $ !final charge $ !smallest final mass $ !Z mass $ !Z width $ !EW mixing angle $ !Gmu Fermi $ alphaQED at q
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
double d(double x, double y) const
double phi(double r, int dir=0) const
double calculate_lpar3(void)
HepSymMatrix cov_c(int=0) const
void calculate_average3(void)
void calculate_average(void)
double calculate_lpar(void)
void add_point_frac(double x, double y, double w, double f)
void add_point(double x, double y, double w=1)
double delta_chisq(double x, double y, double w=1) const
int extrapolate(double, double &, double &) const
const Lpav & operator+=(const Lpav &)
double similarity(double, double) const
HepSymMatrix cov(int=0) const
Lpav operator+(const Lpav &la1, const Lpav &la2)
float prob_(float *, int *)
std::ostream & operator<<(std::ostream &o, const zav &z)