20#include "KalFitAlg/lpav/Lpav.h"
21using CLHEP::HepVector;
22using CLHEP::Hep3Vector;
23using CLHEP::HepMatrix;
24using CLHEP::HepSymMatrix;
34static double err_dis_inv(
double x,
double y,
double w,
double a,
double b) {
38 double f =
x * b - y * a;
88 m_wsum_temp = m_wsum + wi;
89 double rri(xi * xi + yi * yi);
90 double wrri(wi * rri);
91 double wsum_inv(1/m_wsum_temp);
92 m_xav = (m_xsum + wi * xi) * wsum_inv;
93 m_yav = (m_ysum + wi * yi) * wsum_inv;
95 double xxav((m_xxsum + wi * xi * xi) * wsum_inv);
96 double yyav((m_yysum + wi * yi * yi) * wsum_inv);
97 double xyav((m_xysum + wi * xi * yi) * wsum_inv);
98 double xrrav((m_xrrsum + xi * wrri) * wsum_inv);
99 double yrrav((m_yrrsum + yi * wrri) * wsum_inv);
100 double rrrrav((m_rrrrsum + wrri * rri) * wsum_inv);
102 calculate_average_n(xxav, yyav, xyav, xrrav, yrrav, rrrrav);
107 if(m_wsum<=0)
return;
108 m_wsum_temp = m_wsum;
109 double wsum_inv(1/m_wsum_temp);
110 m_xav = m_xsum * wsum_inv;
111 m_yav = m_ysum * wsum_inv;
113 double xxav(m_xxsum * wsum_inv);
114 double yyav(m_yysum * wsum_inv);
115 double xyav(m_xysum * wsum_inv);
116 double xrrav(m_xrrsum * wsum_inv);
117 double yrrav(m_yrrsum * wsum_inv);
118 double rrrrav(m_rrrrsum * wsum_inv);
120 calculate_average_n(xxav, yyav, xyav, xrrav, yrrav, rrrrav);
123void Lpav::calculate_average_n(
double xxav,
double yyav,
double xyav,
124 double xrrav,
double yrrav,
double rrrrav) {
125 double xxav_p = xxav - m_xav * m_xav;
126 double yyav_p = yyav - m_yav * m_yav;
127 double xyav_p = xyav - m_xav * m_yav;
128 double rrav_p = xxav_p + yyav_p;
130 double a = std::fabs(xxav_p - yyav_p);
131 double b = 4 * xyav_p * xyav_p;
132 double asqpb = a * a + b;
133 double rasqpb = std::sqrt(asqpb);
134 double splus = 1 + a / rasqpb;
135 double sminus = b / (asqpb*splus);
136 splus = std::sqrt(0.5*splus);
137 sminus = std::sqrt(0.5*sminus);
141 if ( xxav_p <= yyav_p ) {
151 if (xyav_p < 0) m_sinrot = - m_sinrot;
161 if ( m_cosrot*m_xav + m_sinrot*m_yav <= 0 ) {
162 m_cosrot = - m_cosrot;
163 m_sinrot = - m_sinrot;
165 m_rscale = std::sqrt(rrav_p);
166 double cos2 = m_cosrot * m_cosrot;
167 double sin2 = m_sinrot * m_sinrot;
168 double cs2 = 2 * m_sinrot * m_cosrot;
169 double rrav_p_inv(1/rrav_p);
170 m_xxavp = (cos2 * xxav_p + cs2 * xyav_p + sin2 * yyav_p) * rrav_p_inv;
171 m_yyavp = (cos2 * yyav_p - cs2 * xyav_p + sin2 * xxav_p) * rrav_p_inv;
173 double xav2 = m_xav * m_xav;
174 double yav2 = m_yav * m_yav;
175 double xrrav_p = (xrrav - 2 * xxav * m_xav + xav2 * m_xav -
176 2 * xyav * m_yav + m_xav * yav2) - m_xav * rrav_p;
177 double yrrav_p = (yrrav - 2 * yyav * m_yav + yav2 * m_yav -
178 2 * xyav * m_xav + m_yav * xav2) - m_yav * rrav_p;
179 m_xrravp = ( m_cosrot * xrrav_p + m_sinrot * yrrav_p) * rrav_p_inv/m_rscale;
180 m_yrravp = (- m_sinrot * xrrav_p + m_cosrot * yrrav_p) * rrav_p_inv/m_rscale;
182 double rrav = xxav + yyav;
183 double rrrrav_p = rrrrav
184 - 2 * m_yav * yrrav - 2 * m_xav * xrrav
185 + rrav * (xav2 + yav2)
186 - 2 * m_xav * xrrav_p - xav2 * rrav_p
187 - 2 * m_yav * yrrav_p - yav2 * rrav_p;
188 m_rrrravp = rrrrav_p * rrav_p_inv * rrav_p_inv;
193 if(m_wsum<=0)
return;
194 m_wsum_temp = m_wsum + wi;
195 double wsum_inv(1/m_wsum_temp);
196 double rri(xi * xi + yi * yi);
197 m_xav = (m_xsum + wi * xi) * wsum_inv;
198 m_yav = (m_ysum + wi * yi) * wsum_inv;
203 m_xxavp = (m_xxsum + wi * xi * xi) * wsum_inv;
204 m_xyavp = (m_xysum + wi * xi * yi) * wsum_inv;
205 m_yyavp = (m_yysum + wi * yi * yi) * wsum_inv;
206 double wrri(wi * rri);
207 m_xrravp = (m_xrrsum + xi * wrri) * wsum_inv;
208 m_yrravp = (m_yrrsum + yi * wrri) * wsum_inv;
209 m_rrrravp = (m_rrrrsum + rri * wrri) * wsum_inv;
213 if(m_wsum<=0)
return;
214 m_wsum_temp = m_wsum;
215 double wsum_inv(1/m_wsum_temp);
216 m_xav = m_xsum * wsum_inv;
217 m_yav = m_ysum * wsum_inv;
222 m_xxavp = m_xxsum * wsum_inv;
223 m_xyavp = m_xysum * wsum_inv;
224 m_yyavp = m_yysum * wsum_inv;
225 m_xrravp = m_xrrsum * wsum_inv;
226 m_yrravp = m_yrrsum * wsum_inv;
227 m_rrrravp = m_rrrrsum * wsum_inv;
252 o <<
" nc=" << a.m_nc <<
" chisq=" << a.m_chisq <<
" " << (
Lpar&) a;
256double Lpav::solve_lambda(
void) {
257 if (m_rscale<=0)
return -1;
258 double xrrxrr = m_xrravp * m_xrravp;
259 double yrryrr = m_yrravp * m_yrravp;
260 double rrrrm1 = m_rrrravp - 1;
261 double xxyy = m_xxavp * m_yyavp;
263 double c0 = rrrrm1 * xxyy - xrrxrr * m_yyavp - yrryrr * m_xxavp;
264 double c1 = - rrrrm1 + xrrxrr + yrryrr - 4 * xxyy;
265 double c2 = 4 + rrrrm1 - 4 * xxyy;
275 double chiscl = m_wsum_temp * m_rscale * m_rscale;
276 double dlamax = 0.001 / chiscl;
279 double dlambda = dlamax;
280 while ( itry<ntry && std::fabs(dlambda) >= dlamax) {
281 double cpoly = c0 + lambda * (
c1 + lambda *
282 ( c2 + lambda * lambda * c4));
283 double dcpoly =
c1 + lambda * ( c2d + lambda * lambda * c4d);
284 dlambda = - cpoly / dcpoly;
288 lambda = lambda<0 ? 0 : lambda;
292double Lpav::solve_lambda3(
void) {
293 if (m_rscale<=0)
return -1;
294 double xrrxrr = m_xrravp * m_xrravp;
295 double yrryrr = m_yrravp * m_yrravp;
296 double rrrrm1 = m_rrrravp - 1;
297 double xxyy = m_xxavp * m_yyavp;
299 double a = m_rrrravp;
300 double b = xrrxrr + yrryrr - m_rrrravp * (m_xxavp + m_yyavp);
301 double c = m_rrrravp * m_xxavp * m_yyavp
302 - m_yyavp * xrrxrr - m_xxavp * yrryrr
303 + 2 * m_xyavp * m_xrravp * m_yrravp - m_rrrravp * m_xyavp * m_xyavp;
305 return (-b-std::sqrt(b*b-4*a*c))/2/a;
306 }
else if (c>=0 && b>0) {
307 std::cerr <<
" returning " <<-1<<std::endl;
310 return (-b+std::sqrt(b*b-4*a*c))/2/a;
316 double lambda = solve_lambda();
319 if (lambda<0)
return -1;
320 double h11 = m_xxavp - lambda;
321 double h22 = m_yyavp - lambda;
322 if (h11==0.0)
return -1;
323 double h14 = m_xrravp;
324 double h24 = m_yrravp;
325 double h34 = 1 + 2 * lambda;
326 double rootsq = (h14*h14/h11/h11) + 4 * h34;
327 if ( std::fabs(h22) > std::fabs(h24) ) {
328 if(h22==0.0)
return -1;
329 double ratio = h24/h22;
330 rootsq += ratio * ratio ;
331 m_kappa = 1/std::sqrt(rootsq);
332 m_beta = - ratio * m_kappa;
334 if(h24==0.0)
return -1;
335 double ratio = h22 / h24;
336 rootsq = 1 + ratio * ratio * rootsq;
337 m_beta = 1 / std::sqrt(rootsq);
338 m_beta = h24>0 ? -m_beta : m_beta;
339 m_kappa = -ratio * m_beta;
341 m_alpha = - (h14/h11)*m_kappa;
342 m_gamma = - h34 * m_kappa;
358 rotate(m_cosrot, -m_sinrot);
362 move(-m_xav, -m_yav);
363 if (m_yrravp < 0)
neg();
364 if (lambda>=0) m_chisq = lambda * m_wsum_temp * m_rscale * m_rscale;
369 double lambda = solve_lambda3();
372 if (lambda<0)
return -1;
373 double h11 = m_xxavp - lambda;
374 double h22 = m_yyavp - lambda;
375 double h14 = m_xrravp;
376 double h24 = m_yrravp;
378 double h12 = m_xyavp;
379 double det = h11*h22-h12*h12;
381 double r1 = (h14*h22-h24*h12)/(det);
382 double r2 = (h24*h11-h14*h12)/(det);
383 double kinvsq = r1*r1 + r2*r2;
384 m_kappa = std::sqrt(1/kinvsq);
385 if(h11!=0) m_alpha = -m_kappa * r1;
387 if(h22!=0) m_beta = -m_kappa * r2;
391 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);
402 if((m_alpha*m_xav + m_beta*m_yav) *
403 (m_beta*m_xav - m_alpha*m_yav)<0)
neg();
407 if (lambda>=0) m_chisq = lambda * m_wsum_temp * m_rscale * m_rscale;
412 if (m_nc<=3)
return -1;
418 if (
q>0) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
422 if (
q>0) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
428 if (m_nc<=3)
return -1;
434 if (
q>0) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
438 if (
q>0) m_chisq =
q * m_wsum_temp * m_rscale * m_rscale;
444#ifdef BELLE_OPTIMIZED_RETURN
449 HepSymMatrix vret(4);
457 vret(4,1) = m_xrrsum;
458 vret(4,2) = m_yrrsum;
459 vret(4,3) = m_xxsum + m_yysum;
460 vret(4,4) = m_rrrrsum;
466 std::cerr <<
"Lpav::cov:could not invert nc=" << m_nc << vret;
476#ifdef BELLE_OPTIMIZED_RETURN
481 HepSymMatrix vret(3);
486 vret = cov(1).similarity(dldc());
490 THROW(Lpav::cov_c1,Singular_c);
498 std::cerr <<
"Lpav::cov_c:could not invert " << vret;
500 THROW(Lpav::cov_c2,Singular_c);
509 if (m_chisq<0)
return -1;
510 if (xy(r,
x, y)!=0)
return -1;
511 phi = std::atan2(y,
x);
525 double l =
cov().similarity(
v);
527 double ls = std::sqrt(l);
542 if (m_nc<=3)
return -1;
547 v(4) =
x *
x + y * y;
552 l =
cov().similarity(
v);
562void Lpav::add(
double xi,
double yi,
double w,
double a,
double b) {
563 register double wi = err_dis_inv(xi, yi, w, a, b);
568 register double wi) {
572 m_xxsum += wi * xi * xi;
573 m_yysum += wi * yi * yi;
574 m_xysum += wi * xi * yi;
575 register double rri = ( xi * xi + yi * yi );
576 register double wrri = wi * rri;
577 m_xrrsum += wrri * xi;
578 m_yrrsum += wrri * yi;
579 m_rrrrsum += wrri * rri;
584 register double wi = w * a;
588 m_xxsum += wi * xi * xi;
589 m_yysum += wi * yi * yi;
590 m_xysum += wi * xi * yi;
591 register double rri = ( xi * xi + yi * yi );
592 register double wrri = wi * rri;
593 m_xrrsum += wrri * xi;
594 m_yrrsum += wrri * yi;
595 m_rrrrsum += wrri * rri;
599void Lpav::sub(
double xi,
double yi,
double w,
double a,
double b) {
600 register double wi = err_dis_inv(xi, yi, w, a, b);
604 m_xxsum -= wi * xi * xi;
605 m_yysum -= wi * yi * yi;
606 m_xysum -= wi * xi * yi;
607 register double rri = ( xi * xi + yi * yi );
608 register double wrri = wi * rri;
609 m_xrrsum -= wrri * xi;
610 m_yrrsum -= wrri * yi;
611 m_rrrrsum -= wrri * rri;
616 m_wsum += la1.m_wsum;
617 m_xsum += la1.m_xsum;
618 m_ysum += la1.m_ysum;
619 m_xxsum += la1.m_xxsum;
620 m_yysum += la1.m_yysum;
621 m_xysum += la1.m_xysum;
622 m_xrrsum += la1.m_xrrsum;
623 m_yrrsum += la1.m_yrrsum;
624 m_rrrrsum += la1.m_rrrrsum;
630#ifdef BELLE_OPTIMIZED_RETURN
637 la.m_wsum = la1.m_wsum + la2.m_wsum;
638 la.m_xsum = la1.m_xsum + la2.m_xsum;
639 la.m_ysum = la1.m_ysum + la2.m_ysum;
640 la.m_xxsum = la1.m_xxsum + la2.m_xxsum;
641 la.m_yysum = la1.m_yysum + la2.m_yysum;
642 la.m_xysum = la1.m_xysum + la2.m_xysum;
643 la.m_xrrsum = la1.m_xrrsum + la2.m_xrrsum;
644 la.m_yrrsum = la1.m_yrrsum + la2.m_yrrsum;
645 la.m_rrrrsum = la1.m_rrrrsum + la2.m_rrrrsum;
646 la.m_nc = la1.m_nc + la2.m_nc;
651 if (m_nc<=3)
return 0;
652 if (m_chisq<0)
return 0;
654 int nci = (int)m_nc - 3;
655 double p = (double)
prob_(&c, &nci);
660 if (m_nc<=3)
return -1;
661 else return m_chisq/(m_nc-3);
668 double delta = std::sqrt(
d) * w / (1 + sim * w);
float prob_(float *, int *)
****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
std::ostream & operator<<(std::ostream &o, const Lpav &a)
Lpav operator+(const Lpav &la1, const Lpav &la2)
float prob_(float *, int *)
**********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)
void add_point(double x, double y, double w=1)
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)
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