00001
00008
00009 #define GM00 0
00010 #define GM01 1
00011 #define GM02 2
00012 #define GM03 3
00013 #define GM04 4
00014
00015 #define GM10 5
00016 #define GM11 6
00017 #define GM12 7
00018 #define GM13 8
00019 #define GM14 9
00020
00021 #define GM20 10
00022 #define GM21 11
00023 #define GM22 12
00024 #define GM23 13
00025 #define GM24 14
00026
00027 #define GM30 15
00028 #define GM31 16
00029 #define GM32 17
00030 #define GM33 18
00031 #define GM34 19
00032
00033 #define GM40 20
00034 #define GM41 21
00035 #define GM42 22
00036 #define GM43 23
00037 #define GM44 24
00038
00039
00040
00041
00042 #define GA00 0
00043 #define GA01 1
00044 #define GA02 2
00045 #define GA03 3
00046 #define GA04 4
00047 #define GA05 5
00048
00049 #define GA10 6
00050 #define GA11 7
00051 #define GA12 8
00052 #define GA13 9
00053 #define GA14 10
00054 #define GA15 11
00055
00056 #define GA20 12
00057 #define GA21 13
00058 #define GA22 14
00059 #define GA23 15
00060 #define GA24 16
00061 #define GA25 17
00062
00063 #define GA30 18
00064 #define GA31 19
00065 #define GA32 20
00066 #define GA33 21
00067 #define GA34 22
00068 #define GA35 23
00069
00070 #define GA40 24
00071 #define GA41 25
00072 #define GA42 26
00073 #define GA43 27
00074 #define GA44 28
00075 #define GA45 29
00076
00077 #define GA50 30
00078 #define GA51 31
00079 #define GA52 32
00080 #define GA53 33
00081 #define GA54 34
00082 #define GA55 35
00083
00084 #include "CbmRichRingFitterEllipseTau.h"
00085
00086
00087
00088 using std::endl;
00089 using std::cout;
00090
00091 CbmRichRingFitterEllipseTau::CbmRichRingFitterEllipseTau()
00092 {
00093
00094 }
00095
00096 CbmRichRingFitterEllipseTau::~CbmRichRingFitterEllipseTau()
00097 {
00098
00099 }
00100
00101 void CbmRichRingFitterEllipseTau::DoFit(
00102 CbmRichRingLight *ring)
00103 {
00104 int nofHits = ring->GetNofHits();
00105
00106 if ( nofHits <= 5) {
00107 ring->SetXYABP(-1., -1., -1., -1., -1.);
00108 ring->SetRadius(-1.);
00109 return;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 InitMatrices(ring);
00119 Taubin();
00120 TransformEllipse(ring);
00121 CalcChi2(ring);
00122 }
00123
00124 void CbmRichRingFitterEllipseTau::Taubin()
00125 {
00126
00127
00128 Inv5x5();
00129 Double_t PQa[25];
00130 AMultB(fP, 25, 5, fQ, 25, 5, PQa);
00131 TMatrixD PQ(5,5,PQa);
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 TMatrixDEigen eig(PQ);
00149 TMatrixD evc = eig.GetEigenVectors();
00150
00151 Double_t AlgParF = 0.;
00152 AlgParF -= evc(0,0) * fM[GA05];
00153 fAlgPar[0] = evc(0,0);
00154
00155 AlgParF -= evc(1,0) * fM[GA15];
00156 fAlgPar[1] = evc(1,0);
00157
00158 AlgParF -= evc(2,0) * fM[GA25];
00159 fAlgPar[2] = evc(2,0);
00160
00161 AlgParF -= evc(3,0) * fM[GA35];
00162 fAlgPar[3] = evc(3,0);
00163
00164 AlgParF -= evc(4,0) * fM[GA45];
00165 fAlgPar[4] = evc(4,0);
00166
00167 fAlgPar[5] = AlgParF;
00168 }
00169
00170 void CbmRichRingFitterEllipseTau::InitMatrices(
00171 CbmRichRingLight* ring)
00172 {
00173 const unsigned int numHits = ring->GetNofHits();
00174 const unsigned int numHits2 = 2* numHits;
00175 const unsigned int numHits3 = 3* numHits;
00176 const unsigned int numHits4 = 4* numHits;
00177 const unsigned int numHits5 = 5* numHits;
00178 const unsigned int numHits6 = 6* numHits;
00179 const double oneOverNumHits = 1./ numHits;
00180 unsigned int i6;
00181 for(unsigned int i = 0; i < numHits; i++){
00182 double x = ring->GetHit(i).fX;
00183 double y = ring->GetHit(i).fY;
00184 i6= i*6;
00185 fZ[i6] = fZT[i] = x*x;
00186 fZ[i6+1] = fZT[i+numHits] = x*y;
00187 fZ[i6+2] = fZT[i+numHits2] = y*y;
00188 fZ[i6+3] = fZT[i+numHits3] = x;
00189 fZ[i6+4] = fZT[i+numHits4] = y;
00190 fZ[i6+5] = fZT[i+numHits5] = 1.;
00191 }
00192 AMultB(fZT, numHits6, numHits, fZ, numHits6, 6, fM);
00193 for (int i = 0; i < numHits6;i++) fM[i] = oneOverNumHits*fM[i];
00194
00195 for (int i = 0; i < 25; i++) fP[i]=0.;
00196
00197 fP[GM00] = fM[GA00] - fM[GA05] * fM[GA05];
00198 fP[GM01] = fP[GM10] = fM[GA01] - fM[GA05] * fM[GA15];
00199 fP[GM02] = fP[GM20] = fM[GA02] - fM[GA05] * fM[GA25];
00200 fP[GM03] = fP[GM30] = fM[GA03] - fM[GA05] * fM[GA35];
00201 fP[GM04] = fP[GM40] = fM[GA04] - fM[GA05] * fM[GA45];
00202
00203 fP[GM11] = fM[GA11] - fM[GA15] * fM[GA15];
00204 fP[GM12] = fP[GM21] = fM[GA12] - fM[GA15] * fM[GA25];
00205 fP[GM13] = fP[GM31] = fM[GA13] - fM[GA15] * fM[GA35];
00206 fP[GM14] = fP[GM41] = fM[GA14] - fM[GA15] * fM[GA45];
00207
00208 fP[GM22] = fM[GA22] - fM[GA25] * fM[GA25];
00209 fP[GM23] = fP[GM32] = fM[GA23] - fM[GA25] * fM[GA35];
00210 fP[GM24] = fP[GM42] = fM[GA24] - fM[GA25] * fM[GA45];
00211
00212 fP[GM33] = fM[GA33] - fM[GA35] * fM[GA35];
00213 fP[GM34] = fP[GM43] = fM[GA34] - fM[GA35] * fM[GA45];
00214
00215 fP[GM44] = fM[GA44] - fM[GA45] * fM[GA45];
00216
00217
00218 for (int i = 0; i < 25; i++) fQ[i]=0.;
00219 fQ[GM00] = 4. * fM[GA50];
00220 fQ[GM01] = fQ[GM10] = 2. * fM[GA51];
00221 fQ[GM03] = fQ[GM30] = 2. * fM[GA53];
00222 fQ[GM11] = fM[GA50]+fM[GA52];
00223 fQ[GM12] = fQ[GM21] = 2. * fM[GA51];
00224 fQ[GM13] = fQ[GM31] = fM[GA54];
00225 fQ[GM14] = fQ[GM41] = fM[GA53];
00226 fQ[GM22] = 4. * fM[GA52];
00227 fQ[GM24] = fQ[GM42] = 2. * fM[GA54];
00228 fQ[GM33] = fQ[GM44] = 1.;
00229 }
00230
00231 void CbmRichRingFitterEllipseTau::TransformEllipse(
00232 CbmRichRingLight *ring)
00233 {
00234 double Pxx = fAlgPar[0];
00235 double Pxy = fAlgPar[1];
00236 double Pyy = fAlgPar[2];
00237 double Px = fAlgPar[3];
00238 double Py = fAlgPar[4];
00239 double P = fAlgPar[5];
00240 CalcChi2(Pxx, Pxy, Pyy, Px, Py, P, ring);
00241 ring->SetABCDEF(Pxx, Pxy, Pyy, Px, Py, P);
00242
00243 double alpha;
00244 double QQx, QQy, Qxx, Qyy, Qx, Qy, Q;
00245 double cosa, sina, cca, ssa, sin2a;
00246 double xc, yc;
00247 if (fabs(Pxx - Pyy) > 0.1e-10) {
00248 alpha = atan(Pxy / (Pxx - Pyy));
00249 alpha = alpha / 2.0;
00250 } else
00251 alpha = 1.57079633;
00252
00253 cosa = cos(alpha);
00254 sina = sin(alpha);
00255 cca = cosa * cosa;
00256 ssa = sina * sina;
00257 sin2a = sin(2. * alpha);
00258 Pxy = Pxy * sin2a / 2.;
00259 Qx = Px * cosa + Py * sina;
00260 Qy = -Px * sina + Py * cosa;
00261 QQx = Qx * Qx;
00262 QQy = Qy * Qy;
00263 Qxx = 1. / (Pxx * cca + Pxy + Pyy * ssa);
00264 Qyy = 1. / (Pxx * ssa - Pxy + Pyy * cca);
00265 Q = -P + Qxx * QQx / 4. + Qyy * QQy / 4.;
00266 xc = Qx * Qxx;
00267 yc = Qy * Qyy;
00268
00269 double axisA = TMath::Sqrt(Q * Qxx);
00270 double axisB = TMath::Sqrt(Q * Qyy);
00271 double centerX = -xc * cosa / 2. + yc * sina / 2.;
00272 double centerY = -xc * sina / 2. - yc * cosa / 2.;
00273
00274 ring->SetXYABP(centerX, centerY, axisA, axisB, alpha);
00275 ring->SetRadius( (axisA + axisB) / 2.);
00276
00277 if (ring->GetAaxis() < ring->GetBaxis()) {
00278 double tmp = ring->GetAaxis();
00279 ring->SetAaxis(ring->GetBaxis());
00280 ring->SetBaxis(tmp);
00281
00282 tmp = ring->GetPhi();
00283 if (ring->GetPhi() <= 0)
00284 ring->SetPhi(ring->GetPhi() + 1.57079633);
00285 else
00286 ring->SetPhi(ring->GetPhi() - 1.57079633);
00287 }
00288 }
00289
00290 void CbmRichRingFitterEllipseTau::Inv5x5()
00291 {
00292
00293 const double det2_23_01 = fP[GM20] * fP[GM31] - fP[GM21] * fP[GM30];
00294 const double det2_23_02 = fP[GM20] * fP[GM32] - fP[GM22] * fP[GM30];
00295 const double det2_23_03 = fP[GM20] * fP[GM33] - fP[GM23] * fP[GM30];
00296 const double det2_23_04 = fP[GM20] * fP[GM34] - fP[GM24] * fP[GM30];
00297 const double det2_23_12 = fP[GM21] * fP[GM32] - fP[GM22] * fP[GM31];
00298 const double det2_23_13 = fP[GM21] * fP[GM33] - fP[GM23] * fP[GM31];
00299 const double det2_23_14 = fP[GM21] * fP[GM34] - fP[GM24] * fP[GM31];
00300 const double det2_23_23 = fP[GM22] * fP[GM33] - fP[GM23] * fP[GM32];
00301 const double det2_23_24 = fP[GM22] * fP[GM34] - fP[GM24] * fP[GM32];
00302 const double det2_23_34 = fP[GM23] * fP[GM34] - fP[GM24] * fP[GM33];
00303 const double det2_24_01 = fP[GM20] * fP[GM41] - fP[GM21] * fP[GM40];
00304 const double det2_24_02 = fP[GM20] * fP[GM42] - fP[GM22] * fP[GM40];
00305 const double det2_24_03 = fP[GM20] * fP[GM43] - fP[GM23] * fP[GM40];
00306 const double det2_24_04 = fP[GM20] * fP[GM44] - fP[GM24] * fP[GM40];
00307 const double det2_24_12 = fP[GM21] * fP[GM42] - fP[GM22] * fP[GM41];
00308 const double det2_24_13 = fP[GM21] * fP[GM43] - fP[GM23] * fP[GM41];
00309 const double det2_24_14 = fP[GM21] * fP[GM44] - fP[GM24] * fP[GM41];
00310 const double det2_24_23 = fP[GM22] * fP[GM43] - fP[GM23] * fP[GM42];
00311 const double det2_24_24 = fP[GM22] * fP[GM44] - fP[GM24] * fP[GM42];
00312 const double det2_24_34 = fP[GM23] * fP[GM44] - fP[GM24] * fP[GM43];
00313 const double det2_34_01 = fP[GM30] * fP[GM41] - fP[GM31] * fP[GM40];
00314 const double det2_34_02 = fP[GM30] * fP[GM42] - fP[GM32] * fP[GM40];
00315 const double det2_34_03 = fP[GM30] * fP[GM43] - fP[GM33] * fP[GM40];
00316 const double det2_34_04 = fP[GM30] * fP[GM44] - fP[GM34] * fP[GM40];
00317 const double det2_34_12 = fP[GM31] * fP[GM42] - fP[GM32] * fP[GM41];
00318 const double det2_34_13 = fP[GM31] * fP[GM43] - fP[GM33] * fP[GM41];
00319 const double det2_34_14 = fP[GM31] * fP[GM44] - fP[GM34] * fP[GM41];
00320 const double det2_34_23 = fP[GM32] * fP[GM43] - fP[GM33] * fP[GM42];
00321 const double det2_34_24 = fP[GM32] * fP[GM44] - fP[GM34] * fP[GM42];
00322 const double det2_34_34 = fP[GM33] * fP[GM44] - fP[GM34] * fP[GM43];
00323
00324
00325 const double det3_123_012 = fP[GM10] * det2_23_12 - fP[GM11] * det2_23_02
00326 + fP[GM12] * det2_23_01;
00327 const double det3_123_013 = fP[GM10] * det2_23_13 - fP[GM11] * det2_23_03
00328 + fP[GM13] * det2_23_01;
00329 const double det3_123_014 = fP[GM10] * det2_23_14 - fP[GM11] * det2_23_04
00330 + fP[GM14] * det2_23_01;
00331 const double det3_123_023 = fP[GM10] * det2_23_23 - fP[GM12] * det2_23_03
00332 + fP[GM13] * det2_23_02;
00333 const double det3_123_024 = fP[GM10] * det2_23_24 - fP[GM12] * det2_23_04
00334 + fP[GM14] * det2_23_02;
00335 const double det3_123_034 = fP[GM10] * det2_23_34 - fP[GM13] * det2_23_04
00336 + fP[GM14] * det2_23_03;
00337 const double det3_123_123 = fP[GM11] * det2_23_23 - fP[GM12] * det2_23_13
00338 + fP[GM13] * det2_23_12;
00339 const double det3_123_124 = fP[GM11] * det2_23_24 - fP[GM12] * det2_23_14
00340 + fP[GM14] * det2_23_12;
00341 const double det3_123_134 = fP[GM11] * det2_23_34 - fP[GM13] * det2_23_14
00342 + fP[GM14] * det2_23_13;
00343 const double det3_123_234 = fP[GM12] * det2_23_34 - fP[GM13] * det2_23_24
00344 + fP[GM14] * det2_23_23;
00345 const double det3_124_012 = fP[GM10] * det2_24_12 - fP[GM11] * det2_24_02
00346 + fP[GM12] * det2_24_01;
00347 const double det3_124_013 = fP[GM10] * det2_24_13 - fP[GM11] * det2_24_03
00348 + fP[GM13] * det2_24_01;
00349 const double det3_124_014 = fP[GM10] * det2_24_14 - fP[GM11] * det2_24_04
00350 + fP[GM14] * det2_24_01;
00351 const double det3_124_023 = fP[GM10] * det2_24_23 - fP[GM12] * det2_24_03
00352 + fP[GM13] * det2_24_02;
00353 const double det3_124_024 = fP[GM10] * det2_24_24 - fP[GM12] * det2_24_04
00354 + fP[GM14] * det2_24_02;
00355 const double det3_124_034 = fP[GM10] * det2_24_34 - fP[GM13] * det2_24_04
00356 + fP[GM14] * det2_24_03;
00357 const double det3_124_123 = fP[GM11] * det2_24_23 - fP[GM12] * det2_24_13
00358 + fP[GM13] * det2_24_12;
00359 const double det3_124_124 = fP[GM11] * det2_24_24 - fP[GM12] * det2_24_14
00360 + fP[GM14] * det2_24_12;
00361 const double det3_124_134 = fP[GM11] * det2_24_34 - fP[GM13] * det2_24_14
00362 + fP[GM14] * det2_24_13;
00363 const double det3_124_234 = fP[GM12] * det2_24_34 - fP[GM13] * det2_24_24
00364 + fP[GM14] * det2_24_23;
00365 const double det3_134_012 = fP[GM10] * det2_34_12 - fP[GM11] * det2_34_02
00366 + fP[GM12] * det2_34_01;
00367 const double det3_134_013 = fP[GM10] * det2_34_13 - fP[GM11] * det2_34_03
00368 + fP[GM13] * det2_34_01;
00369 const double det3_134_014 = fP[GM10] * det2_34_14 - fP[GM11] * det2_34_04
00370 + fP[GM14] * det2_34_01;
00371 const double det3_134_023 = fP[GM10] * det2_34_23 - fP[GM12] * det2_34_03
00372 + fP[GM13] * det2_34_02;
00373 const double det3_134_024 = fP[GM10] * det2_34_24 - fP[GM12] * det2_34_04
00374 + fP[GM14] * det2_34_02;
00375 const double det3_134_034 = fP[GM10] * det2_34_34 - fP[GM13] * det2_34_04
00376 + fP[GM14] * det2_34_03;
00377 const double det3_134_123 = fP[GM11] * det2_34_23 - fP[GM12] * det2_34_13
00378 + fP[GM13] * det2_34_12;
00379 const double det3_134_124 = fP[GM11] * det2_34_24 - fP[GM12] * det2_34_14
00380 + fP[GM14] * det2_34_12;
00381 const double det3_134_134 = fP[GM11] * det2_34_34 - fP[GM13] * det2_34_14
00382 + fP[GM14] * det2_34_13;
00383 const double det3_134_234 = fP[GM12] * det2_34_34 - fP[GM13] * det2_34_24
00384 + fP[GM14] * det2_34_23;
00385 const double det3_234_012 = fP[GM20] * det2_34_12 - fP[GM21] * det2_34_02
00386 + fP[GM22] * det2_34_01;
00387 const double det3_234_013 = fP[GM20] * det2_34_13 - fP[GM21] * det2_34_03
00388 + fP[GM23] * det2_34_01;
00389 const double det3_234_014 = fP[GM20] * det2_34_14 - fP[GM21] * det2_34_04
00390 + fP[GM24] * det2_34_01;
00391 const double det3_234_023 = fP[GM20] * det2_34_23 - fP[GM22] * det2_34_03
00392 + fP[GM23] * det2_34_02;
00393 const double det3_234_024 = fP[GM20] * det2_34_24 - fP[GM22] * det2_34_04
00394 + fP[GM24] * det2_34_02;
00395 const double det3_234_034 = fP[GM20] * det2_34_34 - fP[GM23] * det2_34_04
00396 + fP[GM24] * det2_34_03;
00397 const double det3_234_123 = fP[GM21] * det2_34_23 - fP[GM22] * det2_34_13
00398 + fP[GM23] * det2_34_12;
00399 const double det3_234_124 = fP[GM21] * det2_34_24 - fP[GM22] * det2_34_14
00400 + fP[GM24] * det2_34_12;
00401 const double det3_234_134 = fP[GM21] * det2_34_34 - fP[GM23] * det2_34_14
00402 + fP[GM24] * det2_34_13;
00403 const double det3_234_234 = fP[GM22] * det2_34_34 - fP[GM23] * det2_34_24
00404 + fP[GM24] * det2_34_23;
00405
00406
00407 const double det4_0123_0123 = fP[GM00] * det3_123_123 - fP[GM01]
00408 * det3_123_023 + fP[GM02] * det3_123_013 - fP[GM03] * det3_123_012;
00409 const double det4_0123_0124 = fP[GM00] * det3_123_124 - fP[GM01]
00410 * det3_123_024 + fP[GM02] * det3_123_014 - fP[GM04] * det3_123_012;
00411 const double det4_0123_0134 = fP[GM00] * det3_123_134 - fP[GM01]
00412 * det3_123_034 + fP[GM03] * det3_123_014 - fP[GM04] * det3_123_013;
00413 const double det4_0123_0234 = fP[GM00] * det3_123_234 - fP[GM02]
00414 * det3_123_034 + fP[GM03] * det3_123_024 - fP[GM04] * det3_123_023;
00415 const double det4_0123_1234 = fP[GM01] * det3_123_234 - fP[GM02]
00416 * det3_123_134 + fP[GM03] * det3_123_124 - fP[GM04] * det3_123_123;
00417 const double det4_0124_0123 = fP[GM00] * det3_124_123 - fP[GM01]
00418 * det3_124_023 + fP[GM02] * det3_124_013 - fP[GM03] * det3_124_012;
00419 const double det4_0124_0124 = fP[GM00] * det3_124_124 - fP[GM01]
00420 * det3_124_024 + fP[GM02] * det3_124_014 - fP[GM04] * det3_124_012;
00421 const double det4_0124_0134 = fP[GM00] * det3_124_134 - fP[GM01]
00422 * det3_124_034 + fP[GM03] * det3_124_014 - fP[GM04] * det3_124_013;
00423 const double det4_0124_0234 = fP[GM00] * det3_124_234 - fP[GM02]
00424 * det3_124_034 + fP[GM03] * det3_124_024 - fP[GM04] * det3_124_023;
00425 const double det4_0124_1234 = fP[GM01] * det3_124_234 - fP[GM02]
00426 * det3_124_134 + fP[GM03] * det3_124_124 - fP[GM04] * det3_124_123;
00427 const double det4_0134_0123 = fP[GM00] * det3_134_123 - fP[GM01]
00428 * det3_134_023 + fP[GM02] * det3_134_013 - fP[GM03] * det3_134_012;
00429 const double det4_0134_0124 = fP[GM00] * det3_134_124 - fP[GM01]
00430 * det3_134_024 + fP[GM02] * det3_134_014 - fP[GM04] * det3_134_012;
00431 const double det4_0134_0134 = fP[GM00] * det3_134_134 - fP[GM01]
00432 * det3_134_034 + fP[GM03] * det3_134_014 - fP[GM04] * det3_134_013;
00433 const double det4_0134_0234 = fP[GM00] * det3_134_234 - fP[GM02]
00434 * det3_134_034 + fP[GM03] * det3_134_024 - fP[GM04] * det3_134_023;
00435 const double det4_0134_1234 = fP[GM01] * det3_134_234 - fP[GM02]
00436 * det3_134_134 + fP[GM03] * det3_134_124 - fP[GM04] * det3_134_123;
00437 const double det4_0234_0123 = fP[GM00] * det3_234_123 - fP[GM01]
00438 * det3_234_023 + fP[GM02] * det3_234_013 - fP[GM03] * det3_234_012;
00439 const double det4_0234_0124 = fP[GM00] * det3_234_124 - fP[GM01]
00440 * det3_234_024 + fP[GM02] * det3_234_014 - fP[GM04] * det3_234_012;
00441 const double det4_0234_0134 = fP[GM00] * det3_234_134 - fP[GM01]
00442 * det3_234_034 + fP[GM03] * det3_234_014 - fP[GM04] * det3_234_013;
00443 const double det4_0234_0234 = fP[GM00] * det3_234_234 - fP[GM02]
00444 * det3_234_034 + fP[GM03] * det3_234_024 - fP[GM04] * det3_234_023;
00445 const double det4_0234_1234 = fP[GM01] * det3_234_234 - fP[GM02]
00446 * det3_234_134 + fP[GM03] * det3_234_124 - fP[GM04] * det3_234_123;
00447 const double det4_1234_0123 = fP[GM10] * det3_234_123 - fP[GM11]
00448 * det3_234_023 + fP[GM12] * det3_234_013 - fP[GM13] * det3_234_012;
00449 const double det4_1234_0124 = fP[GM10] * det3_234_124 - fP[GM11]
00450 * det3_234_024 + fP[GM12] * det3_234_014 - fP[GM14] * det3_234_012;
00451 const double det4_1234_0134 = fP[GM10] * det3_234_134 - fP[GM11]
00452 * det3_234_034 + fP[GM13] * det3_234_014 - fP[GM14] * det3_234_013;
00453 const double det4_1234_0234 = fP[GM10] * det3_234_234 - fP[GM12]
00454 * det3_234_034 + fP[GM13] * det3_234_024 - fP[GM14] * det3_234_023;
00455 const double det4_1234_1234 = fP[GM11] * det3_234_234 - fP[GM12]
00456 * det3_234_134 + fP[GM13] * det3_234_124 - fP[GM14] * det3_234_123;
00457
00458
00459 const double det = fP[GM00] * det4_1234_1234 - fP[GM01] * det4_1234_0234
00460 + fP[GM02] * det4_1234_0134 - fP[GM03] * det4_1234_0124 + fP[GM04]
00461 * det4_1234_0123;
00462
00463
00464
00465
00466
00467
00468
00469 const double oneOverDet = 1.0 / det;
00470 const double mn1OverDet = -oneOverDet;
00471
00472 fP[GM00] = det4_1234_1234 * oneOverDet;
00473 fP[GM01] = det4_0234_1234 * mn1OverDet;
00474 fP[GM02] = det4_0134_1234 * oneOverDet;
00475 fP[GM03] = det4_0124_1234 * mn1OverDet;
00476 fP[GM04] = det4_0123_1234 * oneOverDet;
00477
00478 fP[GM10] = det4_1234_0234 * mn1OverDet;
00479 fP[GM11] = det4_0234_0234 * oneOverDet;
00480 fP[GM12] = det4_0134_0234 * mn1OverDet;
00481 fP[GM13] = det4_0124_0234 * oneOverDet;
00482 fP[GM14] = det4_0123_0234 * mn1OverDet;
00483
00484 fP[GM20] = det4_1234_0134 * oneOverDet;
00485 fP[GM21] = det4_0234_0134 * mn1OverDet;
00486 fP[GM22] = det4_0134_0134 * oneOverDet;
00487 fP[GM23] = det4_0124_0134 * mn1OverDet;
00488 fP[GM24] = det4_0123_0134 * oneOverDet;
00489
00490 fP[GM30] = det4_1234_0124 * mn1OverDet;
00491 fP[GM31] = det4_0234_0124 * oneOverDet;
00492 fP[GM32] = det4_0134_0124 * mn1OverDet;
00493 fP[GM33] = det4_0124_0124 * oneOverDet;
00494 fP[GM34] = det4_0123_0124 * mn1OverDet;
00495
00496 fP[GM40] = det4_1234_0123 * oneOverDet;
00497 fP[GM41] = det4_0234_0123 * mn1OverDet;
00498 fP[GM42] = det4_0134_0123 * oneOverDet;
00499 fP[GM43] = det4_0124_0123 * mn1OverDet;
00500 fP[GM44] = det4_0123_0123 * oneOverDet;
00501 }
00502
00503 void CbmRichRingFitterEllipseTau::AMultB(
00504 const double * const ap,
00505 int na,
00506 int ncolsa,
00507 const double * const bp,
00508 int nb,
00509 int ncolsb,
00510 double *cp)
00511 {
00512
00513
00514 const double *arp0 = ap;
00515 while (arp0 < ap+na) {
00516 for (const double *bcp = bp; bcp < bp+ncolsb; ) {
00517 const double *arp = arp0;
00518 double cij = 0;
00519 while (bcp < bp+nb) {
00520 cij += *arp++ * *bcp;
00521 bcp += ncolsb;
00522 }
00523 *cp++ = cij;
00524 bcp -= nb-1;
00525 }
00526 arp0 += ncolsa;
00527 }
00528 }
00529
00530 #define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);a[k][l]=h+s*(g-h*tau)
00531 #define MAXSWEEP 50
00532 void CbmRichRingFitterEllipseTau::Jacobi(
00533 double a[5][5],
00534 double d[5],
00535 double v[5][5])
00536 {
00537 double tresh, theta, tau, t, sm, s, h, g, c;
00538
00539 double b[5], z[5];
00540 unsigned int ip, iq, i,j;
00541 for (ip = 0; ip < 5; ip++) {
00542 for (iq = 0; iq < 5; iq++)
00543 v[ip][iq] = 0.;
00544 v[ip][ip] = 1.;
00545 }
00546
00547 for (ip = 0; ip < 5; ip++) {
00548 b[ip] = a[ip][ip];
00549 z[ip] = 0.;
00550 }
00551
00552 int nrot = 0;
00553
00554 for (i = 1; i <= MAXSWEEP; i++) {
00555
00556 for (sm = 0., ip = 0; ip < 5; ip++)
00557 for (iq = ip + 1; iq < 5; iq++)
00558 sm += fabs(a[ip][iq]);
00559 if (sm == 0.) {
00560 return;
00561 }
00562
00563 tresh = (i < 4 ? 0.2 * sm / (5 * 5) : 0.);
00564
00565 for (ip = 0; ip < 4; ip++)
00566 for (iq = ip + 1; iq < 5; iq++) {
00567
00568 g = 100. * fabs(a[ip][iq]);
00569 if (i > 4 && (float) fabs(d[ip] + g) == (float) fabs(d[ip])
00570 && (float) fabs(d[iq] + g) == (float) fabs(d[iq]))
00571 a[ip][iq] = 0.;
00572
00573 else if (fabs(a[ip][iq]) > tresh) {
00574 h = d[ip] - d[iq];
00575
00576 if ((float) (fabs(h) + g) == (float) fabs(h))
00577 t = a[ip][iq] / h;
00578 else {
00579 theta = 0.5 * h / a[ip][iq];
00580 t = 1. / (fabs(theta) + sqrt(1. + theta * theta));
00581 if (theta < 0.)
00582 t = -t;
00583 }
00584 c = 1. / sqrt(1 + t * t);
00585 s = t * c;
00586 tau = s / (1. + c);
00587 h = t * a[ip][iq];
00588 z[ip] -= h;
00589 z[iq] += h;
00590 d[ip] -= h;
00591 d[iq] += h;
00592 a[ip][iq] = 0.;
00593 for (j = 0; j < ip; j++) {
00594 ROTATE(a,j,ip,j,iq);
00595 }
00596 for (j = ip + 1; j < iq; j++) {
00597 ROTATE(a,ip,j,iq,j);
00598 }
00599 for (j = iq + 1; j < 5; j++) {
00600 ROTATE(a,ip,j,j,iq);
00601 }
00602 for (j = 0; j < 5; j++) {
00603 ROTATE(v,j,ip,j,iq);
00604 }
00605 ++nrot;
00606 }
00607 }
00608 for (ip = 0; ip < 5; ip++) {
00609 b[ip] += z[ip];
00610 d[ip] = b[ip];
00611 z[ip] = 0.;
00612 }
00613 }
00614 }
00615
00616 void CbmRichRingFitterEllipseTau::Eigsrt(
00617 double d[5],
00618 double v[5][5])
00619 {
00620 double p;
00621 int i,k,j;
00622 for (i = 0; i < 5; i++) {
00623 p = d[k = i];
00624 for (j = i + 1; j < 5; j++)
00625 if (d[j] >= p)
00626 p = d[k = j];
00627 if (k != i) {
00628 d[k] = d[i];
00629 d[i] = p;
00630 for (j = 0; j < 5; j++) {
00631 p = v[j][i];
00632 v[j][i] = v[j][k];
00633 v[j][k] = p;
00634 }
00635 }
00636 }
00637 }