diff --git a/src/THcDC.cxx b/src/THcDC.cxx index 884f3ed819e2fd561cd4b23891846daeba9031b7..b7c17f39a4813c364f01292f2d9ab668e1e33039 100644 --- a/src/THcDC.cxx +++ b/src/THcDC.cxx @@ -20,6 +20,7 @@ #include "THaTrack.h" #include "TClonesArray.h" #include "TMath.h" +#include "TVectorD.h" #include "THaTrackProj.h" @@ -181,6 +182,11 @@ THaAnalysisObject::EStatus THcDC::Init( const TDatime& date ) return fStatus=status; } } + // Retrieve the fiting coefficients + fPlaneCoeffs = new Double_t* [fNPlanes]; + for(Int_t ip=0; ip<fNPlanes;ip++) { + fPlaneCoeffs[ip] = fPlanes[ip]->GetPlaneCoef(); + } // Replace with what we need for Hall C // const DataDest tmp[NDEST] = { @@ -454,6 +460,7 @@ Int_t THcDC::CoarseTrack( TClonesArray& /* tracks */ ) } // Now link the stubs between chambers LinkStubs(); + if(ntracks_fp > 0) TrackFit(); ApplyCorrections(); @@ -505,7 +512,7 @@ void THcDC::LinkStubs() fNSp++; } } - Int_t ntracks_fp=0; // Number of Focal Plane tracks found + ntracks_fp=0; // Number of Focal Plane tracks found Double_t stubminx = 999999; Double_t stubminy = 999999; Double_t stubminxp = 999999; @@ -637,11 +644,114 @@ void THcDC::LinkStubs() } } } - // Now list all hits on a track. What needs this + // Add the list of hits on the track to the track. + for(Int_t itrack=0;itrack<ntracks_fp;itrack++) { + fTrackSP[itrack].fNHits=0; + fTrackSP[itrack].fHits.clear(); + for(Int_t isp=0;isp<fNSp;isp++) { + for(Int_t ihit=0;ihit<fSp[isp]->GetNHits();ihit++) { + fTrackSP[itrack].fHits.push_back(fSp[isp]->GetHit(ihit)); + fTrackSP[itrack].fNHits++; + } + } + } /// /// cout << "Found " << ntracks_fp << " tracks"<<endl; } +// Primary track fitting routine +void THcDC::TrackFit() +{ + + // Number of ray parameters in focal plane. + const Int_t raycoeffmap[]={4,5,2,3}; + + // Initialize residuals + // Need to make these member variables so they can be histogrammed + // Probably an array of vectors. + Double_t double_resolution[fNPlanes][ntracks_fp]; + Double_t single_resolution[fNPlanes][ntracks_fp]; + Double_t double_res[fNPlanes]; // For the good track + + for(Int_t ip=0;ip<fNPlanes;ip++) { + double_res[ip] = 1000.0; + for(Int_t itrack=0;itrack<ntracks_fp;itrack++) { + double_resolution[ip][itrack] = 1000.0; + single_resolution[ip][itrack] = 1000.0; + } + } + + Double_t dummychi2 = 1.0E4; + for(Int_t itrack=0;itrack<ntracks_fp;itrack++) { + // Double_t chi2 = dummychi2; + // Int_t htrack_fit_num = itrack; + fTrackSP[itrack].fNfree = fTrackSP[itrack].fNHits - NUM_FPRAY; + if(fTrackSP[itrack].fNfree > 0) { + TVectorD TT(NUM_FPRAY); + TMatrixD AA(NUM_FPRAY,NUM_FPRAY); + for(Int_t irayp=0;irayp<NUM_FPRAY;irayp++) { + TT[irayp] = 0.0; + for(Int_t ihit=0;ihit < fTrackSP[itrack].fNHits;ihit++) { + THcDCHit* hit=fTrackSP[itrack].fHits[ihit]; + Int_t plane=hit->GetPlaneIndex(); + TT[irayp] += (hit->GetCoord()* + fPlaneCoeffs[plane][raycoeffmap[irayp]]) + /pow(fSigma[plane],2); + } + } + for(Int_t irayp=0;irayp<NUM_FPRAY;irayp++) { + for(Int_t jrayp=0;jrayp<NUM_FPRAY;jrayp++) { + AA[irayp][jrayp] = 0.0; + if(jrayp<irayp) { // Symmetric + AA[irayp][jrayp] = AA[jrayp][irayp]; + } else { + for(Int_t ihit=0;ihit < fTrackSP[itrack].fNHits;ihit++) { + THcDCHit* hit=fTrackSP[itrack].fHits[ihit]; + Int_t plane=hit->GetPlaneIndex(); + AA[irayp][jrayp] += fPlaneCoeffs[plane][raycoeffmap[irayp]]* + fPlaneCoeffs[plane][raycoeffmap[jrayp]]/ + pow(fSigma[plane],2); + } + } + } + } + + // Solve 4x4 equations + TVectorD dray(NUM_FPRAY); + // Should check that it is invertable + AA.Invert(); + dray = AA*TT; + // cout << "DRAY: " << dray[0] << " "<< dray[1] << " "<< dray[2] << " "<< dray[3] << " " << endl; + // if(bad_determinant) { + // dray[0] = dray[1] = 10000.; dray[2] = dray[3] = 2.0; + // } + Double_t chi2 = 0.0; + // Calculate hit coordinate for each plane for chi2 and efficiency + // calculations + Double_t hdc_track_coord[fNPlanes]; + for(Int_t iplane=0;iplane < fNPlanes; iplane++) { + hdc_track_coord[iplane] = 0.0;// (itrk,pln) + for(Int_t ir=0;ir<NUM_FPRAY;ir++) { + hdc_track_coord[iplane] += fPlaneCoeffs[iplane][raycoeffmap[ir]]*dray[ir]; + } + } + cout << "Residuals:" << endl; + for(Int_t ihit=0;ihit < fTrackSP[itrack].fNHits;ihit++) { + THcDCHit* hit=fTrackSP[itrack].fHits[ihit]; + Int_t plane=hit->GetPlaneIndex(); + Double_t residual = hit->GetCoord() - hdc_track_coord[plane]; + cout << " " << plane << ": " << residual << endl; + chi2 += pow(residual/fSigma[plane],2); + } + + + } + } + + + +} + ClassImp(THcDC) //////////////////////////////////////////////////////////////////////////////// diff --git a/src/THcDC.h b/src/THcDC.h index 12e990342da885e69fa007bc240d0c31d313fc15..b324a08c55b3419d3fe092c066f88d2cb89eb88e 100644 --- a/src/THcDC.h +++ b/src/THcDC.h @@ -15,6 +15,8 @@ #include "THcDriftChamber.h" #include "TMath.h" +#define NUM_FPRAY 4 + //class THaScCalib; class TClonesArray; @@ -77,6 +79,7 @@ protected: // Per-event data Int_t fNhits; + Int_t ntracks_fp; /* Change this to fN something */ // Potential Hall C parameters. Mostly here for demonstration Int_t fNPlanes; @@ -119,6 +122,7 @@ protected: Double_t* fCentralWire; Double_t* fPlaneTimeZero; Double_t* fSigma; + Double_t** fPlaneCoeffs; // Useful derived quantities // double tan_angle, sin_angle, cos_angle; @@ -128,6 +132,9 @@ protected: struct TrackSP { Int_t nSP; /* Number of space points in this track */ Int_t spID[10]; /* List of space points in this track */ + Int_t fNHits; + Int_t fNfree; /* Number of degrees of freedom */ + std::vector<THcDCHit*> fHits; /* List of hits for this track */ } fTrackSP[MAXTRACKS]; std::vector<THcDriftChamberPlane*> fPlanes; // List of plane objects @@ -140,6 +147,7 @@ protected: virtual Int_t ReadDatabase( const TDatime& date ); virtual Int_t DefineVariables( EMode mode = kDefine ); void LinkStubs(); + void TrackFit(); void Setup(const char* name, const char* description); diff --git a/src/THcDriftChamberPlane.cxx b/src/THcDriftChamberPlane.cxx index b68ab8a6115bf9de9b30238183d56ce8771fdd0c..72946486771a2561c3487df9d6db2ac4163b975e 100644 --- a/src/THcDriftChamberPlane.cxx +++ b/src/THcDriftChamberPlane.cxx @@ -180,6 +180,17 @@ Int_t THcDriftChamberPlane::ReadDatabase( const TDatime& date ) fXsp = hychi/denom2; // sin(a) fYsp = -hxchi/denom2; // cos(a) + // Comput track fitting coefficients +#define LOCRAYZT 0.0 + fPlaneCoef[0]= hzchi; // = 0. + fPlaneCoef[1]=-hzchi; // = 0. + fPlaneCoef[2]= hychi*(z0-LOCRAYZT); // sin(a)*(z-hlocrayzt) + fPlaneCoef[3]= hxchi*(LOCRAYZT-z0); // cos(a)*(z-hlocrayzt) + fPlaneCoef[4]= hychi; // sin(a) + fPlaneCoef[5]=-hxchi; // cos(a) + fPlaneCoef[6]= hzchi*hypsi - hychi*hzpsi; // 0. + fPlaneCoef[7]=-hzchi*hxpsi + hxchi*hzpsi; // 0. + fPlaneCoef[8]= hychi*hxpsi - hxchi*hypsi; // 1. cout << fPlaneNum << " " << fNWires << " " << fWireOrder << endl; diff --git a/src/THcDriftChamberPlane.h b/src/THcDriftChamberPlane.h index 9dba31784a3289bba9fa3e15ab84c5207cff59bd..4213b73ddcc7fd0fb2599754b232038598cfb81e 100644 --- a/src/THcDriftChamberPlane.h +++ b/src/THcDriftChamberPlane.h @@ -65,6 +65,7 @@ class THcDriftChamberPlane : public THaSubDetector { Double_t GetSigma() { return fSigma; } Double_t GetPsi0() { return fPsi0; } Double_t* GetStubCoef() { return fStubCoef; } + Double_t* GetPlaneCoef() { return fPlaneCoef; } THcDriftChamberPlane(); // for ROOT I/O protected: @@ -90,6 +91,7 @@ class THcDriftChamberPlane : public THaSubDetector { Double_t fPsi0; Double_t fStubCoef[4]; Double_t fBeta; + Double_t fPlaneCoef[9]; Int_t fReadoutX; Double_t fReadoutCorr;