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