00001 #include <iostream>
00002 #include <iomanip>
00003 #include <string>
00004 #include <vector>
00005 #include <math.h>
00006 #include "MdcAlignAlg/Alignment.h"
00007 #include "MdcAlignAlg/MdcAlignPar.h"
00008
00009 #include "CLHEP/Matrix/Vector.h"
00010 #include "CLHEP/Matrix/SymMatrix.h"
00011
00012 using namespace std;
00013 using namespace CLHEP;
00014
00015 bool Alignment::gFlagMag;
00016 int Alignment::gNiter;
00017
00018 int Alignment::getEpId(int lay, int iEnd){
00019 int i;
00020 if(lay < 8) i = 0;
00021 else if(lay < 10) i = 1;
00022 else if(lay < 12) i = 2;
00023 else if(lay < 14) i = 3;
00024 else if(lay < 16) i = 4;
00025 else if(lay < 18) i = 5;
00026 else if(lay < 20) i = 6;
00027 else i = 7;
00028
00029 int iEP;
00030 if(1 == iEnd) iEP = i;
00031 else return iEP = i + 8;
00032 return iEP;
00033 }
00034
00035 void Alignment::expd(double veca[3], double vecb[3], double val[3]){
00036 val[0] = veca[1]*vecb[2] - veca[2]*vecb[1];
00037 val[1] = veca[2]*vecb[0] - veca[0]*vecb[2];
00038 val[2] = veca[0]*vecb[1] - veca[1]*vecb[0];
00039 }
00040
00041 int Alignment::dist2Line(double sta[3], double stb[3],
00042 double veca[3], double vecb[3],
00043 double &d, double &za, double &zb, int fgZcal){
00044 int i;
00045 double vst[3];
00046 double vp[3];
00047 double modvp;
00048 double m2;
00049 double seca[3], secb[3];
00050 double tpa = 0.0;
00051 double twb = 0.0;
00052
00053 for(i=0; i<3; i++) vst[i] = sta[i] - stb[i];
00054
00055 Alignment::expd(veca, vecb, vp);
00056
00057 m2 = vp[0]*vp[0] + vp[1]*vp[1] + vp[2]*vp[2];
00058 modvp = sqrt(m2);
00059 for(i=0; i<3; i++) vp[i] /= modvp;
00060
00061 d = 0.0;
00062 for(i=0; i<3; i++) d += vst[i] * vp[i];
00063
00064 if( 0 == fgZcal ) return 1;
00065
00066 double veca00 = veca[0]*veca[0];
00067 double veca11 = veca[1]*veca[1];
00068 double veca22 = veca[2]*veca[2];
00069
00070 double veca01 = veca[0]*veca[1];
00071 double veca02 = veca[0]*veca[2];
00072 double veca12 = veca[1]*veca[2];
00073
00074 double vecb00 = vecb[0]*vecb[0];
00075 double vecb11 = vecb[1]*vecb[1];
00076 double vecb22 = vecb[2]*vecb[2];
00077 double vecb01 = vecb[0]*vecb[1];
00078 double vecb02 = vecb[0]*vecb[2];
00079 double vecb12 = vecb[1]*vecb[2];
00080
00081 seca[0] = veca[1]*vecb01 + veca[2]*vecb02 - veca[0]*(vecb11 + vecb22);
00082 seca[1] = veca[0]*vecb01 + veca[2]*vecb12 - veca[1]*(vecb00 + vecb22);
00083 seca[2] = veca[0]*vecb02 + veca[1]*vecb12 - veca[2]*(vecb00 + vecb11);
00084
00085 secb[0] = vecb[1]*veca01 + vecb[2]*veca02 - vecb[0]*(veca11 + veca22);
00086 secb[1] = vecb[0]*veca01 + vecb[2]*veca12 - vecb[1]*(veca00 + veca22);
00087 secb[2] = vecb[0]*veca02 + vecb[1]*veca12 - vecb[2]*(veca00 + veca11);
00088
00089 for(i=0; i<3; i++){
00090 tpa += seca[i] * (sta[i] - stb[i]);
00091 twb += secb[i] * (stb[i] - sta[i]);
00092 }
00093 tpa /= m2;
00094 twb /= m2;
00095 za = veca[2] * tpa + sta[2];
00096 zb = vecb[2] * twb + stb[2];
00097
00098 return 1;
00099 }
00100
00101 double Alignment::docaLineWire(double trkpar[], double wirest[],
00102 double wirev[], double &zwire, int fgZcal){
00103
00104 double d;
00105 double ztrk;
00106 double ps[3];
00107 double pv[3];
00108
00109 ps[0] = trkpar[0] * cos(trkpar[1]);
00110 ps[1] = trkpar[0] * sin(trkpar[1]);
00111 ps[2] = trkpar[3];
00112
00113 pv[0] = cos(trkpar[1] + HFPI);
00114 pv[1] = sin(trkpar[1] + HFPI);
00115 pv[2] = trkpar[4];
00116
00117 Alignment::dist2Line(ps, wirest, pv, wirev, d, ztrk, zwire, fgZcal);
00118
00119 return d;
00120 }
00121
00122 double Alignment::docaHelixWireNewton(double trkpar[], double wirest[],
00123 double wirev[], double &zwire, double zini){
00124 int ifail;
00125 double x0 = trkpar[0] * cos(trkpar[1]);
00126 double y0 = trkpar[0] * sin(trkpar[1]);
00127 double z0 = trkpar[3];
00128 double phi0 = trkpar[1] + HFPI;
00129 double g = 1000 / (0.3 * BFIELD * trkpar[2]);
00130 double tanl = trkpar[4];
00131
00132 double wx = wirev[0];
00133 double wy = wirev[1];
00134 double wz = wirev[2];
00135
00136 double phi;
00137 double t;
00138
00139 CLHEP::HepVector c(2, 0);
00140 c[0] = phi0 + (zini - z0) / (g * tanl);
00141 c[1] = (zini - wirest[2]) / wz;
00142
00143 phi = c[0];
00144 t = c[1];
00145 double xh = x0 + g * (sin(phi) - sin(phi0));
00146 double yh = y0 + g * (-cos(phi) + cos(phi0));
00147 double zh = z0 + g * tanl * (phi - phi0);
00148 double xw = wirest[0] + wx*t;
00149 double yw = wirest[1] + wy*t;
00150 double zw = wirest[2] + wz*t;
00151 double doca = sqrt( (xh-xw)*(xh-xw) + (yh-yw)*(yh-yw) + (zh-zw)*(zh-zw) );
00152
00153 int iter = 0;
00154
00155
00156 for(iter=0; iter<1000; iter++){
00157 CLHEP::HepVector a(2, 0);
00158 CLHEP::HepSymMatrix omega(2, 0);
00159 phi = c[0];
00160 t = c[1];
00161
00162 a[0] = (x0 - g*sin(phi0) - wirest[0] - wx*t) * cos(phi)
00163 + (y0 + g*cos(phi0) - wirest[1] - wy*t) * sin(phi)
00164 + (z0 + g*tanl*phi - g*tanl*phi0 - wirest[2] - wz*t) * tanl;
00165 a[1] = (x0 + g*sin(phi) - g*sin(phi0) - wirest[0] - wx*t) * wx
00166 + (y0 - g*cos(phi) + g*cos(phi0) - wirest[1] - wy*t) * wy
00167 + (z0 + g*tanl*phi - g*tanl*phi0 - wirest[2] - wz*t) * wz;
00168 omega[0][0] = 0 - (x0 - g*sin(phi0) - wirest[0] - wx*t) * sin(phi)
00169 + (y0 + g*cos(phi0) - wirest[1] - wy*t) * cos(phi) + g*tanl*tanl;
00170 omega[0][1] = -wx*cos(phi) - wy*sin(phi) - wz*tanl;
00171 omega[1][0] = g * (wx*cos(phi) + wy*sin(phi) + wz*tanl);
00172 omega[1][1] = -wx*wx - wy*wy - wz*wz;
00173
00174 HepVector cc(2, 0);
00175 cc = c - omega.inverse(ifail) * a;
00176
00177 phi = c[0];
00178 t = c[1];
00179 xh = x0 + g * (sin(phi) - sin(phi0));
00180 yh = y0 + g * (-cos(phi) + cos(phi0));
00181 zh = z0 + g * tanl * (phi - phi0);
00182 xw = wirest[0] + wx*t;
00183 yw = wirest[1] + wy*t;
00184 zw = wirest[2] + wz*t;
00185 doca = sqrt( (xh-xw)*(xh-xw) + (yh-yw)*(yh-yw) + (zh-zw)*(zh-zw) );
00186
00187
00188
00189
00190
00191 c = cc;
00192 phi = c[0];
00193 t = c[1];
00194 a[0] = (x0 - g*sin(phi0) - wirest[0] - wx*t) * cos(phi)
00195 + (y0 + g*cos(phi0) - wirest[1] - wy*t) * sin(phi)
00196 + (z0 + g*tanl*phi - g*tanl*phi0 - wirest[2] - wz*t) * tanl;
00197 a[1] = (x0 + g*sin(phi) - g*sin(phi0) - wirest[0] - wx*t) * wx
00198 + (y0 - g*cos(phi) + g*cos(phi0) - wirest[1] - wy*t) * wy
00199 + (z0 + g*tanl*phi - g*tanl*phi0 - wirest[2] - wz*t) * wz;
00200 if((fabs(a[0]) < 0.001) && (fabs(a[1]) < 0.001)) break;
00201
00202
00203
00204
00205
00206
00207 }
00208 Alignment::gNiter = iter;
00209
00210 phi = c[0];
00211 t = c[1];
00212 xh = x0 + g * (sin(phi) - sin(phi0));
00213 yh = y0 + g * (-cos(phi) + cos(phi0));
00214 zh = z0 + g * tanl * (phi - phi0);
00215 xw = wirest[0] + wx*t;
00216 yw = wirest[1] + wy*t;
00217 zw = wirest[2] + wz*t;
00218 doca = sqrt( (xh-xw)*(xh-xw) + (yh-yw)*(yh-yw) + (zh-zw)*(zh-zw) );
00219 zwire = zw;
00220 cout << endl;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 return doca;
00245 }
00246
00247 double Alignment::docaHelixWire(double trkpar[], double wirest[],
00248 double wirev[], double &zwire, double phiIni){
00249 double x0 = trkpar[0] * cos(trkpar[1]);
00250 double y0 = trkpar[0] * sin(trkpar[1]);
00251 double z0 = trkpar[3];
00252 double phi0 = trkpar[1] + HFPI;
00253 if(phi0 > PI2) phi0 -= PI2;
00254 double g = 1000 / (0.3 * BFIELD * trkpar[2]);
00255 double tanl = trkpar[4];
00256
00257 double trkst[3];
00258 double trkv[3];
00259
00260 double phi = phiIni;
00261 double dphi;
00262
00263 double doca;
00264 double ztrk;
00265 double phiNew;
00266 int iter = 0;
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 for(iter=0; iter<10; iter++){
00283 dphi = phi - phi0;
00284 if(dphi > PI) dphi -= PI2;
00285 if(dphi < -PI) dphi += PI2;
00286
00287 trkst[0] = x0 + g * (sin(phi) - sin(phi0));
00288 trkst[1] = y0 + g * (-cos(phi) + cos(phi0));
00289
00290 trkst[2] = z0 + g * tanl * dphi;
00291
00292 trkv[0] = cos(phi);
00293 trkv[1] = sin(phi);
00294 trkv[2] = tanl;
00295
00296 dist2Line(trkst, wirest, trkv, wirev, doca, ztrk, zwire);
00297
00298 phiNew = phi0 + (ztrk - z0) / (g*tanl);
00299 if(fabs(phiNew - phi) < 1.0E-8) break;
00300 phi = phiNew;
00301 }
00302
00303 gNiter = iter;
00304
00305 return doca;
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 bool Alignment::getDoca(double trkpar[], double wpos[], double &doca,
00367 double whitPos[], double zini){
00368 int i = 0;
00369 double zp;
00370 double xyz[3];
00371 double dxyz[3];
00372
00373 double ten = wpos[6];
00374 double a = 9.47e-06 / (2 * ten);
00375 double dx = wpos[0] - wpos[3];
00376 double dz = wpos[2] - wpos[5];
00377 double length = sqrt(dx*dx + dz*dz);
00378
00379 double ztan = 0.0;
00380 if(whitPos[2] < 0.5*length) ztan = whitPos[2];
00381
00382 double zc=0.0;
00383 if( Alignment::gFlagMag ) zc = zini;
00384
00385
00386 double sinalf = dx / sqrt(dx*dx + dz*dz);
00387 double cosalf = dz / sqrt(dx*dx + dz*dz);
00388 double tanalf = dx / dz;
00389
00390 double posIni[3];
00391 double rLayer = sqrt((wpos[3] * wpos[3]) + (wpos[4] * wpos[4]));
00392 double phiIni = getPhiIni(trkpar, rLayer, posIni);
00393
00394 if(dz < 50){
00395 std::cout << "ERROR: wire position error in getdocaLine() !!!"
00396 << std::endl;
00397 return false;
00398 }
00399
00400 while( 1 ){
00401 i++;
00402 if(i > 5){
00403 return false;
00404 }
00405 zp = zc / cosalf;
00406
00407 xyz[0] = (zc - wpos[5]) * tanalf + wpos[3];
00408 xyz[1] = a*zp*zp + (wpos[1] - wpos[4])*zp/length
00409 + 0.5*(wpos[1] + wpos[4]) - a*length*length/4.0;
00410 xyz[2] = zc;
00411
00412 dxyz[0] = sinalf;
00413 dxyz[1] = 2.0 * a * zp + (wpos[1] - wpos[4]) / length;
00414 dxyz[2] = cosalf;
00415
00416 if( Alignment::gFlagMag ) doca = docaHelixWire(trkpar, xyz, dxyz, ztan, phiIni);
00417 else doca = docaLineWire(trkpar, xyz, dxyz, ztan);
00418
00419 if( fabs(zc-ztan) < 0.5 ) break;
00420 else if( fabs(ztan) > (0.5*length) ){
00421 doca = 99999.0;
00422 break;
00423 }
00424 zc = ztan;
00425 }
00426 whitPos[2] = ztan;
00427 zp = ztan / cosalf;
00428 whitPos[1] = a*zp*zp + (wpos[1] - wpos[4])*zp/length
00429 + 0.5*(wpos[1] + wpos[4]) - a*length*length/4.0;
00430 whitPos[0] = (ztan - wpos[5]) * tanalf + wpos[3];
00431
00432 return true;
00433 }
00434 double Alignment::getPhiIni(double trkpar[], double rLayer, double pos[]){
00435 double dr = trkpar[0];
00436 double fi0 = trkpar[1];
00437 double kap = trkpar[2];
00438 double rw = rLayer;
00439
00440 double phi0 = fi0 + HFPI;
00441 if(phi0 > PI2) phi0 -= PI2;
00442 double g = 1000 / (0.3 * 1.0 * kap);
00443
00444 double aa = rw*rw - (dr-g)*(dr-g) - g*g;
00445 double bb = 2*g*(dr - g);
00446 double cc = aa/bb;
00447 double dd = acos(cc);
00448
00449 double phi;
00450 if(kap > 0) phi = phi0 + dd;
00451 else phi = phi0 - dd;
00452
00453 if(phi > PI2) phi -= PI2;
00454 if(phi < 0) phi += PI2;
00455
00456 double x0 = dr * cos(fi0);
00457 double y0 = dr * sin(fi0);
00458 pos[0] = x0 + g * (sin(phi) - sin(phi0));
00459 pos[1] = y0 + g * (-cos(phi) + cos(phi0));
00460
00461 if(kap > 0) pos[2] = trkpar[3] + g * trkpar[4] * dd;
00462 else pos[2] = trkpar[3] - g * trkpar[4] * dd;
00463
00464 return phi;
00465 }
00466
00467