Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

KalFit.cxx

Go to the documentation of this file.
00001 
00002 // $Header: /nfs/slac/g/glast/ground/cvs/TkrRecon/src/Attic/KalFit.cxx,v 1.3 2001/10/06 17:26:02 lsrea Exp $
00003 
00004 //----------------------------------------------------------------------
00005 //    
00006 //    Implementation of the Kalman Filter Functions
00007 //               KalTrack - doFit() 
00008 //               KalPlane, KalHit, KalMatrix, KalPar  - related Objects 
00009 //
00010 //               J.A. Hernando, B. Atwood.  Santa Cruz,  7/8/98,
00011 //-----------------------------------------------------------------------
00012 
00013 #include "TkrRecon/KalFit.h"
00014 #include "geometry/Ray.h"
00015 //#include "Event/compConf.h"
00016 #include "TkrRecon/GFcontrol.h"
00017 #include <cmath>
00018 // JAH, HA, error compiling with MVC++, 05/22/00
00019 // using std::abs;
00020 
00021 bool CONTROL_setDeltaEne = false;
00022 double CONTROL_MaxEne = 2.;
00023 int CONTROL_maxPlanesEne = 8;
00024 
00025 //-------------------------------------------------------------------
00026 //  Access Data Functions (keep compatible with LSQFit)
00027 //-------------------------------------------------------------------
00028 
00029 //KalTrack::~KalTrack() {}
00030 
00031 //#####################################
00032 void KalTrack::clear()
00033 //#####################################
00034 {
00035         kplanelist.clear();
00036         ini();
00037 }
00038 /*
00039 //#####################################
00040 void KalTrack::writeOut(std::ostream& out) const
00041 //#####################################
00042 {
00043         if (numDataPoints() <3 || chiSquare() < 0) return;
00044 
00045         out << " --- KalTrack Information --- " << "\n";
00046         out << " IniEne " << iniEnergy() << "\n";
00047         out << " nhits  " << numDataPoints() << "\n";
00048         out << " ngaps  " << numGaps()       << "\n";
00049         out << " chiSQFit " << chiSquare() << "\n";
00050         out << " chiSQSmooth " << chiSquareSmooth()       << "\n";
00051         out << " chiSQsegment " << chiSquareSegment()       << "\n";
00052 
00053         out << " x      " << position(0.)    << "\n";
00054         out << " Slope  " << slope()         << "\n";
00055         out << " errX   " << errorPosition() << "\n";
00056         out << " errSlp " << errorSlope()    << "\n";
00057         out << " errSlpV" << errorSlopeAtVertex() << "\n";
00058         out << " ECene  " << KalEnergy()     << "\n";
00059 
00060         std::cout << " --> KalPlanes:" << "\n";
00061         for (int i = 0; i < 2; i++) kplanelist[i].writeOut(out);
00062 }
00063 */
00064 //#########################################
00065 void KalTrack::drawChiSq(gui::DisplayRep& v, SiCluster::view axis, KalHit::TYPE typ)
00066 //#########################################
00067 {
00068         
00069     // Two dimensional Projection Track Drawing
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     // Two dimensional Projection Track Drawing
00107     //unused:   double XLIMIT = -95.;
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 //      Ox = XLIMIT;
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 //              tanOX = 0.;
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     //  else return Point(FLT_MAX,FLT_MAX,FLT_MAX);
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 void KalTrack::printOn(std::ostream &) const
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 //   Kalman Track Private
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     // Generate the initial hit to start the Kalman Filter
00248     //----------------------------------------------------
00249     KalHit hitf=generateFirstFitHit();
00250     kplanelist[0].setHit(hitf); 
00251     
00252     //  Filter 
00253     //------------
00254     int iplane = 0;  // to be compatible with new scoping rules for (MSC_VER)
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     // Smoother
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     // End the Calculations
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     // Compute the fit variables  
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     //   Energy calculations
00328     eneDetermination();
00329 
00330     // Segment Calculation
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     // if (energy < 0.01) energy =0.01;
00371     double theta0=KalPlane::theta0ms(energy,
00372         cosZ,KalPlane::radLen(kplanelist[0].getIDPlane()));
00373     //  The first error is arbitrary to a degree: choose 10*(ms + 1-plane hit precision)
00374     
00375     double thetaerror=10.*(theta0*(1+slopeguess*slopeguess) + .0025);
00376     //  if (thetaerror>3.1416) thetaerror=3.1416;
00377     thetaerror*=thetaerror;
00378     KalMatrix m(0.,0.,0.,thetaerror); 
00379     //KalMatrix m(0.,0.,0.,0.01);
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         // double factor = 1./(1.+totalRad);
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         // factor - energy loss factor
00417         // sigma/distance - dimensions
00418         // eta - undimesnionless parameters
00419         // cosX, etx - geometrical factors
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     // OSF alpha detected m_energy0 == -NaN here. 
00477     // Paul_Kunz@slac.stanford.edu
00478 #ifndef _MSC_VER
00479     if ( !isnan(m_energy0) ) {                  
00480 #endif
00481         // potential square root of negative number here.
00482         // tburnett@u.washington.edu
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         /*int npoints = 1;
00494         int iplane = 1;
00495         for (iplane = 1; iplane< kplanelist.size(); iplane++) {
00496                 double sigb0 = sqrt(kplanelist[iplane-1].getHit(typ).getCov().getsigb());
00497                 double sigb1 = sqrt(kplanelist[iplane].getHit(typ).getCov().getsigb());
00498                 double delta = (sigb0-sigb1)/sigb0;
00499                 if (abs(delta)>0.15) npoints++;
00500                 else break;
00501         }
00502         if (npoints<3) npoints = 3;
00503         return npoints; */
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 //   Kalman Plane
00554 //-------------------------------------
00555 /*
00556 //#####################################
00557 void KalPlane::writeOut(std::ostream& out) const
00558 //#####################################
00559 {
00560         out << " --- KalPlane Information --- " << "\n";
00561         out << " IDhit    " << getIDHit() << "\n";
00562         out << " IDplane  " << getIDPlane() << "\n";
00563         out << " IDtower  " << getIDTower() << "\n";
00564         out << " z        " << getZPlane() << "\n";
00565         out << " xmeas    " << getHit(KalHit::MEAS).getPar().getPosition() << "\n";
00566         out << " xpred    " << getHit(KalHit::PRED).getPar().getSlope() << "\n";
00567         out << " errXpred " << sqrt(getHit(KalHit::PRED).getCov().getsiga()) << "\n";
00568         
00569         out << " xSm     " << getHit(KalHit::SMOOTH).getPar().getPosition() << "\n";
00570         out << " SlopeSm " << getHit(KalHit::SMOOTH).getPar().getSlope() << "\n";
00571         out << " errxSm  " << sqrt(getHit(KalHit::SMOOTH).getCov().getsiga()) << "\n";
00572         out << " errSlSm " << sqrt(getHit(KalHit::SMOOTH).getCov().getsigb()) << "\n";
00573         out << " chiSqFit " << getDeltaChiSq(KalHit::FIT) << "\n";
00574         out << " chiSqSm  " << getDeltaChiSq(KalHit::SMOOTH) << "\n";
00575         out << " chiSqEne " << getDeltaChiEne(KalHit::PRED)<< "\n";
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     KalMatrix V=hitmeas.getCov();
00741     KalMatrix H(1.,0.,0.,0.);
00742     KalMatrix Ck=hit.getCov();
00743     KalMatrix R=V-(H*(Ck*H));
00744     double xval=1./R.getsiga();
00745     
00746     double pmeas=hitmeas.getPar().getPosition();
00747     double pk=hit.getPar().getPosition();
00748     double delpar=pmeas-pk;
00749     
00750     double deltachi2=delpar*xval*delpar;
00751     
00752     return deltachi2; */
00753 
00754     double delpar =   m_hitmeas.getPar().getPosition() -hit.getPar().getPosition();
00755     double variance = m_hitmeas.getCov().getsiga() -    hit.getCov().getsiga();
00756 
00757     // prevent division by zero: what should it do then?
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 //  Kalman Functions
00767 //-------------------------------------
00768 
00769 //#######################################################
00770 KalHit KalPlane::predicted(KalHit::TYPE typ, double zEnd, int klayer)
00771 //#######################################################
00772 {
00773     // Extrapolate the hit to the plane klayer, with a position zEnd;
00774     // This functions handels UP and DOWN predictions
00775     // The normal GLAST trajectories go down (negative z)
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.; // going up;
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         // double relDeltaZ= GFtutor::traySpacing();
00796         // if (istep==nsteps-1) relDeltaZ=abs(deltaZ)-movedDeltaZ;
00797         // movedDeltaZ+=relDeltaZ;
00798         
00799         // KalMatrix F(1.,-1.*relDeltaZ,0.,1.);
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 //    if (movedDeltaZ != deltaZ) std::cout << " error KalPlane predicted ";
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     // Extrapolate the hit to the plane (delta)
00824     // Note that GLAST trajectory evolutes along negative z values.
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 //    if (movedDeltaZ != deltaZ) std::cout << " error KalPlane predicted ";
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     // Extrapolate the hit to the next Kplane; 
00869     // Note that GLAST trajectory is evolving in negative z coordinates.
00870     // The energy is necessary to compute the MS error.
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     // store the matrix with the material
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     // Weight the hits with their cov matricex
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     // Apply the smoother to a Fited hit!
00949     KalHit hitf0=getHit(KalHit::FIT);
00950     
00951     KalHit hitpred=kplaneLast.getHit(KalHit::PRED);
00952     KalHit hitsm=kplaneLast.getHit(KalHit::SMOOTH);
00953     
00954     // double distance=abs(kplaneLast.getZPlane()-getZPlane());
00955 
00956     // double distance=isteps*GFtutor::traySpacing();
00957     // KalMatrix F(1.,-1.*abs(distance),0.,1.);
00958  
00959     double distance=+kplaneLast.getZPlane()-getZPlane();
00960     // double distance=isteps*GFtutor::traySpacing();
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 // KalPlane Static Functions
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     //  double theta0 = radlen0;  // dimensionless case
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     //  radlen=GFtutor::convRadLen(); //dimensionless case
01006     
01007     return radlen;
01008 }
01009 
01010 //#####################################
01011 KalMatrix KalPlane::Q(double ene, double slope, double orth_slope, double radlen0)
01012 //#####################################
01013 {
01014     // WARNING - this functions uses the angle theta instead of the
01015     // slope==tan(theta) BUT it returns in Q the error for the slope
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     // double ocos=(1./(cosX*CosX));
01020     double ocos=(1./(cosX*cosZ));
01021     double jacovian=ocos*ocos;
01022     KalMatrix Q(0.,theta0*theta0*jacovian,0.);
01023     //  dimensionless case
01024     //  double theta0=KalPlane::theta0ms(ene,slope,radlen);
01025     //  KalMatrix Q(0.,theta0*theta0,0.);
01026     return Q;
01027 }
01028 //-------------------------------------------
01029 //   Kalman Hit 
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 //   Kalman Parameter and Matrix 
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 

Generated at Wed Nov 21 12:21:21 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000