00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TkrRecon/KalFit.h"
00014 #include "geometry/Ray.h"
00015
00016 #include "TkrRecon/GFcontrol.h"
00017 #include <cmath>
00018
00019
00020
00021 bool CONTROL_setDeltaEne = false;
00022 double CONTROL_MaxEne = 2.;
00023 int CONTROL_maxPlanesEne = 8;
00024
00025
00026
00027
00028
00029
00030
00031
00032 void KalTrack::clear()
00033
00034 {
00035 kplanelist.clear();
00036 ini();
00037 }
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 void KalTrack::drawChiSq(gui::DisplayRep& v, SiCluster::view axis, KalHit::TYPE typ)
00066
00067 {
00068
00069
00070 int nplanes = kplanelist.size();
00071 for (int iplane=0; iplane<nplanes; iplane++) {
00072 double x = kplanelist[iplane].getHit(typ).getPar().getPosition();
00073 double Ox = kplanelist[iplane].getOrthPar().getPosition();
00074 double z0 = kplanelist[iplane].getZPlane()+0.01;
00075 double x0,y0;
00076 if (axis == SiCluster::X) {
00077 x0 = x;
00078 y0 = Ox;
00079 } else {
00080 x0 = Ox;
00081 y0 = x;
00082 }
00083
00084 double delta= kplanelist[iplane].getDeltaChiSq(typ);
00085 double xl,xr,yl,yr;
00086 if (axis == SiCluster::X) {
00087 xl = x0-0.5*delta;
00088 xr = x0+0.5*delta;
00089 yl = y0;
00090 yr = y0;
00091 } else {
00092 xl = x0;
00093 xr = x0;
00094 yl = y0-0.5*delta;
00095 yr = y0+0.5*delta;
00096 }
00097 v.moveTo(Point(xl,yl,z0));
00098 v.lineTo(Point(xr,yr,z0));
00099 }
00100 }
00101
00102
00103 void KalTrack::drawTrack(gui::DisplayRep& v, SiCluster::view axis, KalHit::TYPE typ)
00104
00105 {
00106
00107
00108 int nplanes = kplanelist.size();
00109 for (int iplane=0; iplane<nplanes-1; iplane++) {
00110 double x = kplanelist[iplane].getHit(typ).getPar().getPosition();
00111 double Ox = kplanelist[iplane].getOrthPar().getPosition();
00112
00113 double z0 = kplanelist[iplane].getZPlane()+0.01;
00114 double x0,y0;
00115 if (axis == SiCluster::X) {
00116 x0 = x;
00117 y0 = Ox;
00118 } else {
00119 x0 = Ox;
00120 y0 = x;
00121 }
00122
00123 double tanx, tany;
00124 double tanX = kplanelist[iplane].getHit(typ).getPar().getSlope();
00125 double tanOX = kplanelist[iplane].getOrthPar().getSlope();
00126
00127 if (axis == SiCluster::X){
00128 tanx = tanX;
00129 tany = tanOX;
00130 } else {
00131 tanx = tanOX;
00132 tany = tanX;
00133 }
00134
00135 Point origin(x0,y0,z0);
00136 Vector dir = Vector(-1.*tanx,-1.*tany,-1.);
00137 double mag = dir.mag();
00138 dir = dir*(1./mag);
00139
00140 Ray segment(origin,dir);
00141 double zstep=kplanelist[iplane+1].getZPlane()-z0;
00142 double cosz=dir.z();
00143 v.moveTo(segment.position(0.));
00144 v.lineTo(segment.position(zstep/cosz));
00145 }
00146 }
00147
00148 int KalTrack::numGaps() const
00149
00150 {
00151 int numGaps =0;
00152 if (numDataPoints() == 0) return numGaps;
00153
00154 numGaps =1+ kplanelist.back().getIDPlane() -
00155 kplanelist.front().getIDPlane() - numDataPoints();
00156
00157 return numGaps;
00158 }
00159
00160
00161 int KalTrack::compareFits(KalTrack& ktrack)
00162
00163 {
00164 int numComData=0;
00165 if (kplanelist.size()==0||ktrack.kplanelist.size()==0)
00166 return numComData;
00167
00168 for (unsigned int i=0;i<kplanelist.size();i++){
00169 for (unsigned int j=0; j<ktrack.kplanelist.size();j++){
00170 if (kplanelist[i].getIDHit()==
00171 ktrack.kplanelist[j].getIDHit()) numComData++;
00172 }
00173 }
00174 return numComData;
00175 }
00176
00177
00178 Point KalTrack::getHit(unsigned ipos)const
00179
00180 {
00181 if (ipos<kplanelist.size()){
00182 return kplanelist[ipos].getPoint(KalHit::MEAS);
00183 }
00184
00185 return Point(-999999.,-999999.,-999999.);
00186 }
00187
00188 unsigned KalTrack::getHitIndex(unsigned ipos)const
00189
00190 {
00191 unsigned index= 0xFFFFFFFF;
00192 if (ipos<kplanelist.size())
00193 index=kplanelist[ipos].getIDHit();
00194 return index;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 double KalTrack::positionAtZ(double const z) const
00204
00205 {
00206 if( kplanelist.empty() ) return 99;
00207 const KalPlane& plane = *kplanelist.begin();
00208 double x = plane.getHit(KalHit::SMOOTH).getPar().getPosition(),
00209 z0 = plane.getZPlane()+0.01,
00210 tanX = plane.getHit(KalHit::SMOOTH).getPar().getSlope();
00211 return x+(z-z0)*tanX;
00212 }
00213
00214
00215 void KalTrack::setIniEnergy(double e)
00216
00217 {
00218 m_energy0 = e;
00219 for (unsigned int iplane = 0; iplane < kplanelist.size(); iplane++)
00220 kplanelist[iplane].setEnergy(m_energy0);
00221 }
00222
00223
00224
00225
00226
00227 KalTrack::KalTrack()
00228 : m_energy0(0), m_x0(0), m_slopeX(0)
00229 , m_chisq(1e6), m_chisqSmooth(1e6)
00230 , m_KalEnergy(0), m_KalThetaMS(0), m_rmsResid(0)
00231 , m_numSegmentPoints(0), m_chisqSegment(0)
00232
00233 {
00234 }
00235
00236 double KalTrack::doFit()
00237
00238 {
00239 ini();
00240
00241 int nplanes=kplanelist.size();
00242 if (nplanes<=2) return m_chisq;
00243
00244 m_chisq = 0.;
00245 m_chisqSmooth = 0.;
00246
00247
00248
00249 KalHit hitf=generateFirstFitHit();
00250 kplanelist[0].setHit(hitf);
00251
00252
00253
00254 int iplane = 0;
00255 for (iplane = 0 ; iplane<nplanes-1;iplane++)
00256 {
00257 filterStep(iplane);
00258 if(iplane > 0) m_chisq+=kplanelist[iplane+1].getDeltaChiSq(KalHit::FIT);
00259 }
00260
00261
00262
00263 KalHit hitsm=(kplanelist[nplanes-1].getHit(KalHit::FIT)).changeType(KalHit::SMOOTH);
00264 kplanelist[nplanes-1].setHit(hitsm);
00265 m_chisqSmooth=kplanelist[nplanes-1].getDeltaChiSq(KalHit::SMOOTH);
00266
00267 for (iplane=nplanes-2; iplane>=0;iplane--)
00268 {
00269 KalHit hitsm=kplanelist[iplane].smoother(kplanelist[iplane+1]);
00270 kplanelist[iplane].setHit(hitsm);
00271 m_chisqSmooth+=kplanelist[iplane].getDeltaChiSq(KalHit::SMOOTH);
00272 }
00273
00274
00275
00276 finish();
00277
00278 return m_chisq;
00279 }
00280
00281
00282 void KalTrack::ini()
00283
00284 {
00285 m_energy0 = 0.;
00286 m_x0 = 0.;
00287 m_slopeX = 0.;
00288 m_rmsResid = 0.;
00289 m_KalEnergy = 0.;
00290 m_chisq = 1e6;
00291 m_chisqSmooth = 1e6;
00292 m_KalThetaMS = 0.;
00293 m_rmsResid = 0.;
00294 m_numSegmentPoints = 0;
00295 m_chisqSegment = 1e6;
00296
00297 unsigned int iplane =0;
00298 for (;iplane < kplanelist.size();iplane++) {
00299 kplanelist[iplane].clean();
00300 }
00301
00302 }
00303
00304 void KalTrack::finish()
00305
00306 {
00307
00308 if (m_chisq>=0){
00309 int nplanes = kplanelist.size();
00310 m_x0=kplanelist[0].getHit(KalHit::SMOOTH).getPar().getPosition();
00311 m_slopeX=kplanelist[0].getHit(KalHit::SMOOTH).getPar().getSlope();
00312 m_rmsResid=-1.;
00313 m_chisq=m_chisq/(1.*nplanes-2.);
00314 m_chisqSmooth/=(1.*nplanes-2.);
00315 m_rmsResid=0.;
00316 int iplane = 0;
00317 for (iplane=0;iplane<nplanes;iplane++){
00318 double res=kplanelist[iplane].
00319 getHit(KalHit::SMOOTH).getPar().getPosition()-
00320 kplanelist[iplane].
00321 getHit(KalHit::MEAS).getPar().getPosition();
00322 m_rmsResid+=res*res;
00323 }
00324 m_rmsResid=sqrt(m_rmsResid/(1.*nplanes));
00325 }
00326
00327
00328 eneDetermination();
00329
00330
00331 if (m_chisq>=0){
00332 m_numSegmentPoints = computeNumSegmentPoints();
00333 m_chisqSegment = computeChiSqSegment(m_numSegmentPoints);
00334 }
00335 }
00336
00337
00338 void KalTrack::filterStep(int iplane)
00339
00340 {
00341 KalHit hitp = kplanelist[iplane].predicted(kplanelist[iplane+1]);
00342 kplanelist[iplane+1].setHit(hitp);
00343 KalHit hitf1 = kplanelist[iplane+1].filter();
00344 kplanelist[iplane+1].setHit(hitf1);
00345
00346 if (CONTROL_setDeltaEne)
00347 kplanelist[iplane+1].setDeltaEne(kplanelist[iplane].getEnergy());
00348
00349 }
00350
00351
00352 KalHit KalTrack::generateFirstFitHit()
00353
00354 {
00355
00356 int nplanes=kplanelist.size();
00357 if (nplanes<2)
00358 std::cout << "ERROR - Kaltrack::generateFirstFitHit" << '\n';
00359
00360 double slopeguess=(kplanelist[1].getHit(KalHit::MEAS).getPar().getPosition()-
00361 kplanelist[0].getHit(KalHit::MEAS).getPar().getPosition())/
00362 (kplanelist[1].getZPlane()-kplanelist[0].getZPlane());
00363 double x0guess=kplanelist[0].getHit(KalHit::MEAS).getPar().getPosition();
00364
00365
00366 double orth_slope = kplanelist[1].getOrthPar().getSlope();
00367 double cosZ = sqrt(1./(1. + slopeguess*slopeguess + orth_slope*orth_slope));
00368 double energy = kplanelist[1].getEnergy();
00369 if (energy == 0.) energy = m_energy0;
00370
00371 double theta0=KalPlane::theta0ms(energy,
00372 cosZ,KalPlane::radLen(kplanelist[0].getIDPlane()));
00373
00374
00375 double thetaerror=10.*(theta0*(1+slopeguess*slopeguess) + .0025);
00376
00377 thetaerror*=thetaerror;
00378 KalMatrix m(0.,0.,0.,thetaerror);
00379
00380
00381 KalPar parguess(x0guess,slopeguess);
00382 KalHit hitf(KalHit::FIT,parguess,
00383 (kplanelist[0].getHit(KalHit::MEAS)).getCov()+m);
00384
00385 return hitf;
00386 }
00387
00388
00389 void KalTrack::eneDetermination()
00390
00391 {
00392 int nplanes = numDataPoints();
00393 int iplane = 2;
00394 double totalRad = 0.;
00395 double eneSum = 0.;
00396 double thetaSum = 0.;
00397 for (iplane = 2; iplane < nplanes; iplane++) {
00398 int idplane = kplanelist[iplane].getIDPlane();
00399 double chie = kplanelist[iplane].getDeltaChiEne(KalHit::PRED);
00400 double eta = ((chie-1.)*(chie-1.)*(chie-1.))/((chie+2.)*(chie+2.));
00401 eta = sqrt(fabs(eta));
00402
00403 double slope = kplanelist[iplane].getHit(KalHit::SMOOTH).getPar().getSlope();
00404 double slope_orth = kplanelist[iplane].getOrthPar().getSlope();
00405 double cosZ= sqrt(1/(1.+ slope*slope+slope_orth*slope_orth));
00406 double cosX= sqrt(1/(1.+ slope*slope));
00407
00408 double radlen = KalPlane::radLen(idplane)/cosZ;
00409 totalRad += radlen;
00410 double factor = 1./(2.-exp(-1.*totalRad));
00411
00412
00413 double sigma = sqrt(kplanelist[iplane].getHit(KalHit::MEAS).getCov().getsiga());
00414 double distance = abs(kplanelist[iplane].getZPlane()-kplanelist[iplane-1].getZPlane());
00415
00416
00417
00418
00419
00420 double theta = factor*(sigma/distance)*eta*(cosX*cosZ*sqrt(cosZ));
00421 theta /= (sqrt(radlen)*(1+0.038*log(radlen)));
00422 thetaSum += theta;
00423
00424 }
00425 m_KalThetaMS = thetaSum/(nplanes-2.);
00426 m_KalEnergy = 0.0136/m_KalThetaMS;
00427 double radlen = KalPlane::radLen(kplanelist[0].getIDPlane());
00428 m_KalThetaMS *= sqrt(radlen)*(1+0.038*log(radlen));
00429 }
00430
00431
00432 double KalTrack::errorPosition() const
00433
00434 {
00435 double error = 0.;
00436 if (m_chisqSmooth == 0) return error;
00437 error = sqrt(kplanelist[0].getHit(KalHit::SMOOTH).getCov().getsiga());
00438 return error;
00439 }
00440
00441 double KalTrack::errorSlope() const
00442
00443 {
00444 double error = 0.;
00445 if (m_chisqSmooth == 0) return error;
00446 error = sqrt(kplanelist[0].getHit(KalHit::SMOOTH).getCov().getsigb());
00447 return error;
00448 }
00449
00450 double KalTrack::errorSlopeAtVertex() const
00451
00452 {
00453 double error = 0.;
00454 if (m_chisqSmooth == 0) return error;
00455
00456 double slope = m_slopeX;
00457 double ene = kplanelist[0].getEnergy();
00458 KalMatrix Cov = kplanelist[0].getHit(KalHit::SMOOTH).getCov();
00459 double orthSlope = kplanelist[0].getOrthPar().getSlope();
00460 int iplane = kplanelist[0].getIDPlane();
00461 double radlen0 = KalPlane::radLen(iplane);
00462 KalMatrix Q=KalPlane::Q(ene,slope,orthSlope,0.5*radlen0);
00463
00464 Cov = Cov + Q;
00465
00466 error = sqrt(Cov.getsigb());
00467 return error;
00468 }
00469
00470
00471 int KalTrack::computeNumSegmentPoints(KalHit::TYPE typ)
00472
00473 {
00474
00475 unsigned int num_ist=0;
00476
00477
00478 #ifndef _MSC_VER
00479 if ( !isnan(m_energy0) ) {
00480 #endif
00481
00482
00483 num_ist = m_energy0>0? static_cast<unsigned int>( 4.*sqrt(m_energy0)): 1000;
00484 #ifndef _MSC_VER
00485 } else {
00486 num_ist = 1000;
00487 }
00488 #endif
00489 if (num_ist <= 2) num_ist = 3;
00490 if (num_ist > kplanelist.size()) num_ist = kplanelist.size();
00491
00492 return num_ist;
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 }
00506
00507 double KalTrack::computeChiSqSegment(int nhits, KalHit::TYPE typ)
00508
00509 {
00510 double chi2 = 0;
00511 int ihit =0;
00512 for (ihit =0; ihit < nhits; ihit++) {
00513 chi2 += kplanelist[ihit].getDeltaChiSq(typ);
00514 }
00515 chi2 /= (nhits-2.);
00516 return chi2;
00517 }
00518
00519 double KalTrack::kink(int iplane) const
00520
00521 {
00522 double kink = 0.;
00523 if (iplane<0 || iplane == numDataPoints()) return kink;
00524
00525 double slope0 = kplanelist[iplane].getHit(KalHit::SMOOTH).getPar().getSlope();
00526 double slope1 = kplanelist[iplane+1].getHit(KalHit::SMOOTH).getPar().getSlope();
00527
00528 kink = slope1-slope0;
00529
00530 return kink;
00531 }
00532
00533 double KalTrack::kinkNorma(int iplane) const
00534
00535 {
00536 double k = 0.;
00537 k = kink(iplane);
00538
00539 if (iplane <0 || iplane >= numDataPoints()) return k;
00540
00541 double errorSQ = kplanelist[iplane+1].getHit(KalHit::SMOOTH).getCov().getsigb();
00542 errorSQ += kplanelist[iplane+1].getQmaterial().getsigb();
00543
00544 double error = sqrt(errorSQ);
00545
00546 double kinkNorma = 0.;
00547 if (error != 0.) kinkNorma = fabs(k)/error;
00548
00549 return kinkNorma;
00550
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 void KalPlane::removeHit()
00581
00582 {
00583 m_IDHit = -1;
00584 m_IDTower = -1;
00585 KalPar pnull(0.,0.);
00586 KalMatrix covnull(0.,0.,0.);
00587 setHit(KalHit(KalHit::MEAS,pnull,covnull));
00588 clean();
00589 }
00590
00591 void KalPlane::clean()
00592
00593 {
00594 KalPar pnull(0.,0.);
00595 KalMatrix covnull(0.,0.,0.);
00596 setHit(KalHit(KalHit::PRED,pnull,covnull));
00597 setHit(KalHit(KalHit::FIT,pnull,covnull));
00598 setHit(KalHit(KalHit::SMOOTH,pnull,covnull));
00599 }
00600
00601 void KalPlane::clear()
00602
00603 {
00604 KalPar pnull(0.,0.);
00605 KalMatrix covnull(0.,0.,0.);
00606
00607 m_eneplane = 0.;
00608 m_IDHit = 0xffffffff;
00609 m_IDPlane = -1;
00610 m_IDTower = -1;
00611 m_OrthPar = pnull;
00612 m_zplane = 0.;
00613
00614 setHit(KalHit(KalHit::MEAS,pnull,covnull));
00615 setHit(KalHit(KalHit::PRED,pnull,covnull));
00616 setHit(KalHit(KalHit::FIT,pnull,covnull));
00617 setHit(KalHit(KalHit::SMOOTH,pnull,covnull));
00618 }
00619
00620 void KalPlane::setHit(const KalHit& hit)
00621
00622 {
00623 KalHit::TYPE type;
00624 switch (type=hit.getType()){
00625 case KalHit::PRED:
00626 m_hitpred=hit;
00627 break;
00628 case KalHit::MEAS:
00629 m_hitmeas=hit;
00630 break;
00631 case KalHit::FIT:
00632 m_hitfit=hit;
00633 break;
00634 case KalHit::SMOOTH:
00635 m_hitsmooth=hit;
00636 break;
00637 case KalHit::UNKNOWN:
00638 break;
00639 }
00640 }
00641
00642
00643 KalHit KalPlane::getHit(KalHit::TYPE type) const
00644
00645 {
00646 KalHit hit(KalHit::UNKNOWN);
00647
00648 switch (type){
00649 case KalHit::PRED:
00650 hit=m_hitpred;
00651 break;
00652 case KalHit::MEAS:
00653 hit=m_hitmeas;
00654 break;
00655 case KalHit::FIT:
00656 hit=m_hitfit;
00657 break;
00658 case KalHit::SMOOTH:
00659 hit=m_hitsmooth;
00660 break;
00661 case KalHit::UNKNOWN:
00662 break;
00663 }
00664
00665 return hit;
00666 }
00667
00668
00669 Point KalPlane::getPoint(KalHit::TYPE type)const
00670
00671 {
00672 KalHit hit=getHit(type);
00673 return Point(hit.getPar().getPosition(),0.,getZPlane());
00674 }
00675
00676
00677 double KalPlane::getDeltaChiEne(KalHit::TYPE type)const
00678
00679 {
00680 KalHit hit=getHit(type);
00681 double delpar=m_hitmeas.getPar().getPosition()-hit.getPar().getPosition();
00682 double sigma2=m_hitmeas.getCov().getsiga();
00683
00684 double variance=(delpar*delpar)/sigma2;
00685 return variance;
00686 }
00687
00688
00689 void KalPlane::setDeltaEne(double ene)
00690
00691 {
00692 double slope = getHit(KalHit::PRED).getPar().getSlope();
00693 double slope_orth = getOrthPar().getSlope();
00694 double cosZ= sqrt(1/(1.+ slope*slope+slope_orth*slope_orth));
00695 double cosX= sqrt(1/(1.+ slope*slope));
00696
00697 double radlen = KalPlane::radLen(getIDPlane())/cosZ;
00698 double factor = exp(-1.*radlen);
00699
00700 setEnergy(ene*factor);
00701 }
00702
00703
00704 double KalPlane::getSigma(KalHit::TYPE type) const
00705
00706 {
00707
00708 double sigma = 1e6;
00709
00710 KalHit hit = getHit(type);
00711 KalHit hitmeas = getHit(KalHit::MEAS);
00712
00713 double deltap = hit.getPar().getPosition()-hitmeas.getPar().getPosition();
00714 double error2 = hit.getCov().getsiga();
00715 sigma = fabs(deltap)/sqrt(error2);
00716
00717 return sigma;
00718 }
00719
00720 double KalPlane::getDeltaChiSq(KalHit::TYPE type) const
00721
00722 {
00723
00724 KalHit hit(KalHit::UNKNOWN);
00725
00726 switch (type){
00727 case KalHit::FIT:
00728 hit=m_hitfit;
00729 break;
00730 case KalHit::SMOOTH:
00731 hit=m_hitsmooth;
00732 break;
00733 case KalHit::MEAS:
00734 case KalHit::PRED:
00735 case KalHit::UNKNOWN:
00736 break;
00737 }
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 double delpar = m_hitmeas.getPar().getPosition() -hit.getPar().getPosition();
00755 double variance = m_hitmeas.getCov().getsiga() - hit.getCov().getsiga();
00756
00757
00758 double chi2 = 0.;
00759 if (variance>0.) chi2 = (delpar*delpar)/variance;
00760 else if (variance<0.) chi2 = 1e6;
00761
00762 return chi2;
00763 }
00764
00765
00766
00767
00768
00769
00770 KalHit KalPlane::predicted(KalHit::TYPE typ, double zEnd, int klayer)
00771
00772 {
00773
00774
00775
00776
00777 KalHit hit=getHit(typ);
00778
00779 KalPar pp=hit.getPar();
00780 KalMatrix Ck=hit.getCov();
00781
00782 double ene =getEnergy();
00783 double slope = pp.getSlope();
00784 double orth_slope = getOrthPar().getSlope();
00785
00786 int nsteps=klayer-getIDPlane();
00787 double down = -1.;
00788 if (nsteps <0 ) down = +1.;
00789 nsteps = abs(nsteps);
00790 double deltaZ=zEnd-getZPlane();
00791 int iplane=getIDPlane();
00792 double movedDeltaZ=0.;
00793
00794 for (int istep=0; istep< abs(nsteps); istep++){
00795
00796
00797
00798
00799
00800
00801 double relDeltaZ = down * GFtutor::trayGap();
00802 if (istep == abs(nsteps) -1) relDeltaZ = deltaZ - movedDeltaZ;
00803 movedDeltaZ+=relDeltaZ;
00804
00805 KalMatrix F(1.,relDeltaZ,0.,1.);
00806 KalMatrix Q=KalPlane::Q(ene, slope, orth_slope, KalPlane::radLen(iplane+1));
00807 pp=F*pp;
00808 if (down == -1.) Ck=(F*(Ck*F.transpose()))+Q;
00809 else if (down == +1) Ck=(F*(Ck+Q)*F.transpose());
00810 }
00811
00812
00813
00814 KalHit hitpred(KalHit::PRED, pp, Ck);
00815
00816 return hitpred;
00817
00818 }
00819
00820 KalHit KalPlane::predicted(KalHit::TYPE typ, int nsteps)
00821
00822 {
00823
00824
00825
00826 KalHit hit=getHit(typ);
00827
00828 KalPar pp=hit.getPar();
00829 KalMatrix Ck=hit.getCov();
00830
00831 double ene =getEnergy();
00832 double slope = pp.getSlope();
00833 double orth_slope = getOrthPar().getSlope();
00834
00835 double down = -1;
00836 if (nsteps < 0) down = +1;
00837 double deltaZ=down*fabs(nsteps)*GFtutor::trayGap();
00838
00839 int iplane=getIDPlane();
00840 double movedDeltaZ=0.;
00841
00842
00843 for (int istep=0; istep<abs(nsteps); istep++){
00844
00845 double relDeltaZ = down*GFtutor::trayGap();
00846 if (istep == abs(nsteps) -1) relDeltaZ = deltaZ - movedDeltaZ;
00847 movedDeltaZ+=relDeltaZ;
00848
00849 KalMatrix F(1.,relDeltaZ,0.,1.);
00850 KalMatrix Q=KalPlane::Q(ene, slope, orth_slope, KalPlane::radLen(iplane+1));
00851 pp=F*pp;
00852 if (down == -1.) Ck=(F*(Ck*F.transpose()))+Q;
00853 else if (down == +1) Ck=(F*(Ck+Q)*F.transpose());
00854 }
00855
00856
00857
00858 KalHit hitpred(KalHit::PRED, pp, Ck);
00859
00860 return hitpred;
00861
00862 }
00863
00864 KalHit KalPlane::predicted(KalPlane& kplaneNext)
00865
00866 {
00867
00868
00869
00870
00871
00872 KalHit hit=getHit(KalHit::FIT);
00873
00874 KalPar pp=hit.getPar();
00875 KalMatrix Ck=hit.getCov();
00876
00877 double ene= getEnergy();
00878 double slope = pp.getSlope();
00879 double orth_slope = getOrthPar().getSlope();
00880
00881 int nsteps=kplaneNext.getIDPlane()-getIDPlane();
00882
00883 double down = -1.;
00884 if (nsteps <0) down = +1.;
00885
00886 double deltaZ=kplaneNext.getZPlane()-getZPlane();
00887 double movedDeltaZ =0.;
00888 int iplane=getIDPlane();
00889
00890 KalMatrix Qaccumul(0.,0.,0.);
00891
00892 for (int istep=0; istep<abs(nsteps); istep++){
00893
00894 double relDeltaZ = down*GFtutor::trayGap();
00895 if (istep == abs(nsteps) -1) relDeltaZ = deltaZ - movedDeltaZ;
00896 movedDeltaZ+=relDeltaZ;
00897
00898 KalMatrix F(1.,relDeltaZ,0.,1.);
00899 KalMatrix Q=KalPlane::Q(ene, slope, orth_slope, KalPlane::radLen(iplane+1));
00900
00901 pp=F*pp;
00902 if (down == -1.) Ck=(F*(Ck*F.transpose()))+Q;
00903 else if (down == +1) Ck=(F*(Ck+Q)*F.transpose());
00904
00905 if (down == -1.) {
00906 Qaccumul = Q + F*(Qaccumul*F.transpose());
00907 }
00908 if (down == +1.) Qaccumul = F*((Qaccumul+Q)*F.transpose());
00909 }
00910
00911 kplaneNext.m_Qmaterial = Qaccumul;
00912
00913 KalHit hitpred(KalHit::PRED, pp, Ck);
00914
00915 return hitpred;
00916
00917 }
00918
00919
00920 KalHit KalPlane::filter()
00921
00922 {
00923
00924
00925 KalHit hit1=getHit(KalHit::MEAS);
00926 KalMatrix H(1.,0.,0.,0.);
00927 KalMatrix G(1./hit1.getCov().getsiga(),0.,0.);
00928 KalPar pmeas=hit1.getPar();
00929
00930 KalHit hit2=getHit(KalHit::PRED);
00931 KalMatrix Ckpred=hit2.getCov();
00932 KalMatrix Ckpredinv=Ckpred.invert();
00933 KalPar ppred=hit2.getPar();
00934
00935 KalMatrix Ck=(Ckpredinv+H*(G*H)).invert();
00936 KalPar pk=((Ck*Ckpredinv)*ppred)+((Ck*G)*pmeas);
00937
00938 KalHit hitfit(KalHit::FIT, pk, Ck);
00939
00940 return hitfit;
00941
00942 }
00943
00944
00945 KalHit KalPlane::smoother(const KalPlane& kplaneLast)
00946
00947 {
00948
00949 KalHit hitf0=getHit(KalHit::FIT);
00950
00951 KalHit hitpred=kplaneLast.getHit(KalHit::PRED);
00952 KalHit hitsm=kplaneLast.getHit(KalHit::SMOOTH);
00953
00954
00955
00956
00957
00958
00959 double distance=+kplaneLast.getZPlane()-getZPlane();
00960
00961 KalMatrix F(1.,distance,0.,1.);
00962
00963 KalMatrix Ck=hitf0.getCov();
00964
00965 KalMatrix Ck1pred=hitpred.getCov();
00966 KalMatrix Ck1sm=hitsm.getCov();
00967
00968 KalPar pk=hitf0.getPar();
00969 KalPar pk1pred=hitpred.getPar();
00970 KalPar pk1sm=hitsm.getPar();
00971
00972 KalMatrix A=Ck*((F.transpose())*Ck1pred.invert());
00973
00974 KalPar psm=pk+A*(pk1sm-pk1pred);
00975 KalMatrix Csm=Ck+A*((Ck1sm-Ck1pred)*A.transpose());
00976
00977 KalHit newhitsm(KalHit::SMOOTH,psm,Csm);
00978
00979 return newhitsm;
00980 }
00981
00982
00983
00984
00985
00986 double KalPlane::theta0ms(double ene, double cosZ, double radlen0)
00987
00988 {
00989 double radlen=radlen0/cosZ;
00990 double theta0=(0.0136/ene)*sqrt(radlen)*(1+0.038*log(radlen));
00991
00992 return theta0;
00993 }
00994
00995
00996 double KalPlane::radLen(int kplane)
00997
00998 {
00999 double foamx0=625., siliconx0=9.36;
01000
01001 int ipln = GFtutor::numPlanes() - 1 - kplane;
01002 double radlen=(GFtutor::convRadLen(ipln)+GFtutor::trayGap()/foamx0+
01003 2.*0.02/18.+2.*GFtutor::siThickness()/siliconx0);
01004
01005
01006
01007 return radlen;
01008 }
01009
01010
01011 KalMatrix KalPlane::Q(double ene, double slope, double orth_slope, double radlen0)
01012
01013 {
01014
01015
01016 double cosZ = sqrt(1./(1.+ slope*slope + orth_slope*orth_slope));
01017 double cosX = sqrt(1./(1.+ slope*slope));
01018 double theta0=KalPlane::theta0ms(ene,cosZ,radlen0);
01019
01020 double ocos=(1./(cosX*cosZ));
01021 double jacovian=ocos*ocos;
01022 KalMatrix Q(0.,theta0*theta0*jacovian,0.);
01023
01024
01025
01026 return Q;
01027 }
01028
01029
01030
01031
01032
01033 KalHit KalHit::changeType(TYPE typ)
01034
01035 {
01036
01037 KalHit hit;
01038
01039 hit.type=typ;
01040 hit.par=par;
01041 hit.cov=cov;
01042
01043 return hit;
01044 }
01045
01046
01047
01048
01049 int KalMatrix::kfdim=2;
01050
01051
01052 double operator*(const KalPar& pa, const KalPar& pb)
01053
01054 {
01055 double po=pa.position*pb.position+pa.slope*pb.slope;
01056 return po;
01057 }
01058
01059
01060 KalPar operator+(const KalPar& pa, const KalPar& pb)
01061
01062 {
01063 KalPar po(pa.position+pb.position,
01064 pa.slope+pb.slope);
01065 return po;
01066 }
01067
01068
01069 KalPar operator-(const KalPar& pa, const KalPar& pb)
01070
01071 {
01072 KalPar po(pa.position-pb.position,
01073 pa.slope-pb.slope);
01074 return po;
01075 }
01076
01077
01078 KalPar operator*(const KalMatrix& m, const KalPar& p)
01079
01080 {
01081 KalPar po(m.a[0][0]*p.position+m.a[0][1]*p.slope,
01082 m.a[1][0]*p.position+m.a[1][1]*p.slope);
01083 return po;
01084 }
01085
01086
01087 KalMatrix operator*(const KalMatrix& ma, const KalMatrix& mb)
01088
01089 {
01090 KalMatrix mc;
01091
01092 for (int i=0;i<KalMatrix::kfdim;i++){
01093 for (int j=0;j<KalMatrix::kfdim;j++){
01094 for (int k=0;k<KalMatrix::kfdim;k++){
01095 mc.a[i][j]+=ma.a[i][k]*mb.a[k][j];
01096 }
01097 }
01098 }
01099
01100 return mc;
01101 }
01102
01103
01104 KalMatrix operator+(const KalMatrix& ma, const KalMatrix& mb)
01105
01106 {
01107 KalMatrix mc;
01108
01109 for (int i=0;i<KalMatrix::kfdim;i++){
01110 for (int j=0;j<KalMatrix::kfdim;j++){
01111 mc.a[i][j]=ma.a[i][j]+mb.a[i][j];
01112 }
01113 }
01114
01115
01116 return mc;
01117 }
01118
01119
01120 KalMatrix operator-(const KalMatrix& ma, const KalMatrix& mb)
01121
01122 {
01123 KalMatrix mc;
01124
01125 for (int i=0;i<KalMatrix::kfdim;i++){
01126 for (int j=0;j<KalMatrix::kfdim;j++){
01127 mc.a[i][j]=ma.a[i][j]-mb.a[i][j];
01128 }
01129 }
01130
01131 return mc;
01132 }
01133
01134
01135 KalMatrix KalMatrix::invert()
01136
01137 {
01138 KalMatrix mc;
01139
01140 double det=a[0][0]*a[1][1]-a[0][1]*a[1][0];
01141 if (det!=0.){
01142 mc.a[0][0]=a[1][1]/det;
01143 mc.a[1][0]=-1.*a[1][0]/det;
01144 mc.a[0][1]=-1.*a[0][1]/det;
01145 mc.a[1][1]=a[0][0]/det;
01146 }
01147
01148 return mc;
01149 }
01150
01151
01152 KalMatrix KalMatrix::transpose()
01153
01154 {
01155 KalMatrix mc;
01156
01157 for (int i=0;i<KalMatrix::kfdim;i++){
01158 for (int j=0;j<KalMatrix::kfdim;j++){
01159 mc.a[i][j]=a[j][i];
01160 }
01161 }
01162
01163 return mc;
01164 }
01165