|
// $Id: BrLocalTrack.cxx,v 1.1.1.1 2001/06/21 14:55:03 hagel Exp $ // $Author: hagel $ // $Date: 2001/06/21 14:55:03 $ // // BrLocalTrack is a BRAHMS data class for storing information for // Localtrack i.e. those created temporarely during local tracking. // The class contains information on associated BrDetectorHit (s) and // Trackgroup (i.e. ghost candidates) // #include <BrLocalTrack.h> #include <BrDetectorHit.h> #include <BrMath.h> #include <iostream.h> #include <iomanip.h> //___________________________________________________________________ ClassImp(BrLocalTrack); //___________________________________________________________________ BrLocalTrack::BrLocalTrack() { fPos = new Float_t [3]; fPosError = new Float_t [3]; fVec = new Float_t [3]; fVecError = new Float_t [3]; for(Int_t i=0;i<3;i++) { fPos[i] = 0.0; fPosError[i] = 0.0; fVec[i] = 0.0; fVecError[i] = 0.0; } fCovar = 0; fVtrack = 0; fTr1 = 0; fTr2 = 0; fNhit = 0; fFlg = 0; fStatus = kOk; fChisq = 0.0; } //___________________________________________________________________ BrLocalTrack::BrLocalTrack(BrLocalTrack* loctra_p) { // // Copy constructor // Int_t i; SetPos(loctra_p->GetPos()); SetVec(loctra_p->GetVec()); SetNhit(loctra_p->GetNhit()); SetFlg(loctra_p->GetFlg()); SetStat(loctra_p->GetStat()); SetChisq(loctra_p->GetChisq()); SetVtrack(loctra_p->GetVtrack()); SetTr1(loctra_p->GetTr1()); SetTr2(loctra_p->GetTr2()); Int_t numtrahit = loctra_p->GetTrackEntries(); for(i=0;i<numtrahit;i++) { AddTrackHit(loctra_p->GetTrackHitAt(i)); } } //___________________________________________________________________ BrLocalTrack::~BrLocalTrack() { //Just clear these hit arrays because they are the responsibility of //someone else to delete them. fDetectorHits.Clear(); fTrahit.Clear(); delete [] fPos; delete [] fPosError; delete [] fVec; delete [] fVecError; if(fCovar) { for(Int_t i = 0;i < 4;i++) delete [] fCovar[i]; delete fCovar; fCovar = 0; } } //________________________________________________________________________ ostream& operator<< (ostream & os, BrLocalTrack *loctra_p) { os<<"Local track; Number of Hits ="<<loctra_p->GetNhit(); os<<"Flag, Stat = "<<loctra_p->GetFlg()<<","<<loctra_p->GetStat()<<endl; os<<"Track origin = ("; os<<setw(8)<<loctra_p->GetPos()[0]<<","; os<<setw(8)<<loctra_p->GetPos()[1]<<","; os<<setw(8)<<loctra_p->GetPos()[2]<<")"; os<<endl; os<<"Track vector = ("; os<<setw(8)<<loctra_p->GetVec()[0]<<","; os<<setw(8)<<loctra_p->GetVec()[1]<<","; os<<setw(8)<<loctra_p->GetVec()[2]<<")"; os<<endl; os <<"Track Hits " << endl; Int_t i = 0; for(i = 0; i < loctra_p->GetNhit(); i++) { const BrDetectorHit *const hit_p = (BrDetectorHit*) loctra_p->GetDetectorHitAt( i ); os << setw(8) << hit_p->GetPos()[0] << setw(8) << hit_p->GetPos()[1] << setw(8) << hit_p->GetPos()[2] << endl; } return os; } //________________________________________________________________________ void BrLocalTrack::Fit() { // Fit the localtrack to the hits // Fill postions and vector in track as well as chisq and covariance matrix // Double_t a[4]; Double_t beta[4][1]; Double_t alpha[4][4]; Double_t *alphaa[4],*betaa[4]; Float_t work[4]; for(int i=0;i<4;i++) { beta[i][0] = (Double_t)0.0; for(int j=0;j<4;j++) { alpha[i][j] = (Double_t)0.0; } } //Is there a more elegant way to do this? for(int i=0;i<4;i++) { alphaa[i] = &alpha[i][0]; betaa [i] = &beta[i][0]; } //Setup matrix equation if(fNhit<2) { cerr<<"Too few points for fitting; this ought not to happen"<<endl; return; } Int_t i = 0; for(i = 0; i < fNhit; i++) { const BrDetectorHit *const hit_p = (BrDetectorHit*) fDetectorHits.At( i ); a[0] = hit_p->GetPos()[2]; a[1] = 1; a[2] = hit_p->GetPos()[2]; a[3] = 1; Float_t dx = hit_p->GetDpos()[0]; if( dx < 0.0001 ) { // This unfortunately do happen at the moment dx = 0.02; // 18May00 Warning( "Fit" , "Hit Width dx == 0" ); } Float_t dy = hit_p->GetDpos()[1]; if( dy < 0.0001 ) { // This unfortunately do happen at the moment dy = 0.02; // 18May00 Warning( "Fit" , "Hit Width dy == 0" ); } for(int i=0;i<2;i++) { for(int j=0;j<2;j++) alpha[i][j] += a[i]*a[j]/dx/dx; beta[i][0] += a[i] * hit_p->GetPos()[0]/dx/dx; } for(int i=2;i<4;i++) { for(int j=2;j<4;j++) alpha[i][j] += a[i]*a[j]/dy/dy; beta[i][0] += a[i] * hit_p->GetPos()[1]/dy/dy; } } //Solve 4x4 matrix for xc,yc and ex,ey vector Int_t ifail; BrMath::DEQINV(4,alphaa,4,work,ifail,1,betaa); // // Update found position... // if ( ifail != 0 ) Error( "BrLocalTrack::Fit", "Inversion of matrix failed!!!!!" ); fPos[0] = beta[1][0]; fPos[1] = beta[3][0]; fPos[2] = 0.0; fVec[0] = beta[0][0]; fVec[1] = beta[2][0]; fVec[2] = 1.0; //Calculate chisqr fChisq = (Float_t)0.0; for(int ic=0; ic< fNhit; ic++) { const BrDetectorHit *const hit_p = (BrDetectorHit*)fDetectorHits.At(ic); a[0] = hit_p->GetPos()[2]; a[1] = 1; a[2] = hit_p->GetPos()[2]; a[3] = 1; Float_t dx = hit_p->GetDpos()[0]; Float_t dy = hit_p->GetDpos()[1]; Float_t dchi1 = (Float_t)(beta[1][0] + beta[0][0]*a[0] - hit_p->GetPos()[0]); Float_t dchi2 = (Float_t)(beta[3][0] + beta[2][0]*a[2] - hit_p->GetPos()[1]); fChisq += dchi1*dchi1/(dx*dx) + dchi2*dchi2/(dy*dy); } if(fNhit == 2) fChisq = 0.0; else fChisq = fChisq/(fNhit-2); if(!fCovar) { fCovar = new Float_t* [4]; for(i=0;i<4;i++) fCovar[i] = new Float_t [4]; } for(i = 0; i < 4; i++) for(Int_t j = 0; j < 4; j++) fCovar[i][j] = alpha[i][j]; // The calculation below is uncessary // The covariance matrix already contains this information and // more , namely the correlations. At this point the data members // are not removed but the calculations skipped and replace by // a simple assignment to the covar matrix elements. // // Calculate the errors on the fit according to Bevington p 108-9 // Bevington, Robinson : // "Data Reduction and Error Analysis for the Physical Sciences" // if x = az + b and ey is known for each point then // // ea = 1/delta * sum z_i^2 / ex_i^2 // eb = 1/delta * sum 1 / ex_i^2 // where // ( sum 1 / ex_i^2 sum z_i / ex_i^2 ) // delta = det ( ) // ( sum z_i / ex_i^2 sum z_i^2 / ex_i^2 ) // // The same method will be employed here. First for x (ipos = 0) // and then for y (ipos = 1) /* for(Int_t ipos = 0; ipos < 2; ipos++) { Double_t deltaMatrix[2][2] = { {0, 0}, {0, 0} }; for(int ihit=0; ihit< fNhit; ihit++) { const BrDetectorHit *const hit_p = (BrDetectorHit*)fDetectorHits.At(ihit); Double_t z = hit_p->GetPos()[2]; Double_t error_2 = TMath::Power(hit_p->GetDpos()[ipos], 2); deltaMatrix[0][0] += 1 / error_2; deltaMatrix[0][1] += z / error_2; deltaMatrix[1][0] += z / error_2; deltaMatrix[1][1] += TMath::Power(z,2) / error_2; } Double_t delta = deltaMatrix[0][0] * deltaMatrix[1][1] - deltaMatrix[0][1] * deltaMatrix[1][0]; Double_t ea = 1 / delta * deltaMatrix[1][1]; Double_t eb = 1/delta * deltaMatrix[0][0]; ea = TMath::Sqrt(1 / delta * deltaMatrix[1][1]); eb = TMath::Sqrt(1/delta * deltaMatrix[0][0]); fVecError[ipos] = ea; fPosError[ipos] = eb; } */ fPosError[0] = TMath::Sqrt(fCovar[0][0]); fVecError[0] = TMath::Sqrt(fCovar[1][1]); fPosError[1] = TMath::Sqrt(fCovar[2][2]); fVecError[1] = TMath::Sqrt(fCovar[3][3]); fVecError[2] = 0.0; fPosError[2] = 0.0; } //________________________________________________________________________ Float_t BrLocalTrack::RelativeOverlap(BrLocalTrack* t2, Float_t zl, Float_t r) { // // Calculate the relative overlap between "this" track and the given track // // Parameters: // In: dt_p pointer to the other track // zl length of detector (in local z direction) // r radius of cylinder around tracks // // Algorithm: // A cylinder of radius r is put around each track. // The relative overlap is defined as the ratio between // the volume of the overlap region of two cylinders // and // the volume of the cylinder around "this" track is calculated. // The cylinders are distorted in order to have a circular intersection // between the cylinders and planes at arbitrary z. // // Requires: // The tracks are parametrized as: // x = ax * z + bx // y = ay * z + by // const Float_t twor = 2*r; const Float_t halfl = zl/2; // Difference between the two tracks const Float_t dax = GetVec()[0] - t2->GetVec()[0]; const Float_t day = GetVec()[1] - t2->GetVec()[1]; const Float_t dbx = GetPos()[0] - t2->GetPos()[0]; const Float_t dby = GetPos()[1] - t2->GetPos()[1]; Float_t overlap = 0; const Float_t a = dax*dax + day*day; if (a == 0) { // Tracks are parallell const Float_t d = BrMath::Sqrt(dbx*dbx+dby*dby)/twor; if (d < 1) overlap = BrMath::ACos(d)-d*BrMath::Sqrt(1-d*d); } else { const Float_t b = (dax*dbx+day*dby)/a; const Float_t c = (dbx*dbx+dby*dby)/a; Float_t d = b*b-c+twor*twor/a; if (d > 0) { // Cylinders intersect d = BrMath::Sqrt(d); Float_t zn = -b - d; Float_t zx = -b + d; if (zn < -halfl) zn = -halfl; if (zx > halfl) zx = halfl; if (zn < zx) { // Cylinders intersect inside the detector // // Integrate // acos(d(z)/(2r))-d(z)/(2r)*sqrt(1-(d(z)/(2r))**2) // where // d(z)/(2r)=sqrt(a*((z+2*b)*z+c))/(2*r) // from zn to zx // // Quick and dirty implementation: Simple N-point rule const Int_t n = 5; const Float_t dz = (zx-zn)/n; for (Int_t i = 0; i < n; i++) { Float_t z = zn + dz*(i+0.5); d = BrMath::Sqrt(a*((z+2*b)*z+c))/twor; overlap += BrMath::ACos(d)-d*BrMath::Sqrt(1-d*d); } overlap *= dz/zl; } } } return overlap/(BrMath::Pi/2); } //________________________________________________________________________ BrVector3D BrLocalTrack::GetDeviationFromFit(const BrDetectorHit *const detHit) const { // // Returns a vector with the deviation in x and y of the hit from // the fitted line. // The deviation is calculated for the same z // and is given as fit - hit. if( fPos == 0 || fVec == 0 ) { Warning("GetDeviatioFromFit", "No fit data"); return BrVector3D(); } BrVector3D origin( fPos ); BrVector3D slope( fVec ); BrVector3D hit( detHit->GetPos() ); return BrVector3D((hit[2] - origin[2])*slope + origin - hit); } //________________________________________________________________________ Bool_t BrLocalTrack::HasHitInRow(Int_t rowNo) const { // // Look through the hits to see if there is hit in the given // row. returns kTRUE if it finds a hit for( Int_t i = 0; i < fNhit; i++ ) { BrDetectorHit* hit_p = (BrDetectorHit*) fDetectorHits.At( i ); if(hit_p->GetRow() == rowNo) return kTRUE; } return kFALSE; } //________________________________________________________________________ Bool_t BrLocalTrack::HasAllHitsBetween(Int_t index,Float_t low, Float_t high) const { // // Look through the hits to see if the index component of all // position coordinates is between low and high // returns kTRUE if it does not find anyone outside // Useful if you only want tracks in a certain region of the TPC, no // matter if it is pad, time or row. if( index < 0 || index > 2 ) { Warning("HasAllHitsBetween", "Not a valid index!"); return kFALSE; } for( Int_t i = 0; i < fNhit; i++ ) { BrDetectorHit* hit_p = (BrDetectorHit*) fDetectorHits.At( i ); if(hit_p->GetPos()[index] < low || hit_p->GetPos()[index] > high) return kFALSE; } return kTRUE; } //________________________________________________________________________ void BrLocalTrack::RemoveDetectorHit(BrDetectorHit *detHit) { if(!fDetectorHits.Remove(detHit)) return; fDetectorHits.Compress(); fNhit--; } //________________________________________________________________________ // $Log: BrLocalTrack.cxx,v $ // Revision 1.1.1.1 2001/06/21 14:55:03 hagel // Initial revision of brat2 // // Revision 1.16 2001/04/14 22:18:58 videbaek // Fix couple of problems: // chisqs might be undefined since fitting could be called with fNhits=2. // The fCovar was not initialized. // Bypassed not necessary calculation of errors - used covar instead. // Added hits to output list of in os << method // // Revision 1.15 2001/02/09 18:13:43 pchristi // Added remove detector hit. // // Revision 1.14 2001/02/01 17:25:46 pchristi // Added calculations of errors to the local track module and changed some // of the member structure. // // Revision 1.13 2001/01/30 10:31:52 pchristi // Added some utility methods to BrLocalTrack. // // Revision 1.11 2000/09/04 14:56:26 videbaek // Add some redundant brackets to make visual C++ ver 6.0 happy. // // Revision 1.10 2000/05/24 07:23:32 pchristi // Method Fit : If hit width = 0, width = 0.02 and Warning. // // Revision 1.9 2000/05/05 09:50:30 bjornhs // Added RelativeOverlap in BrLocalTrack // // Revision 1.8 2000/05/01 14:19:10 videbaek // Fix serious error. fPos and fVec not set. // Thanks to T.Tveter. // // Revision 1.7 2000/04/28 21:18:58 videbaek // Updates to BrLocalTrack. Added fit method; Status is changed. Uses // MarkAsBad, IsBad instead of fixed 999. // Cleanup of BrModuleMatchtrack. Added histohgrams. // Changed LocalTrack and LocalTracking to use IsBad etc. // // Revision 1.6 1999/04/28 15:31:40 hagel // Change destructor to clear fDetectorHits and fTraHit // // Revision 1.5 1999/03/07 22:38:03 videbaek // Added DetectorHit and BrLocalTrackingModule as a more general way to // deal with local tracks and hits. Initial insertion. Not fully debugged. // Cosmetic changes to other modules. // // Revision 1.4 1999/01/15 16:37:27 videbaek // Working version of MRS tracking of mtp1,mtp2 and new general track // classes. Changes also added to BrModuleMatchTrack for this reason. // Updated makeNt for non-cygnus win95 systems // // |
||||||
This page automatically generated by script docBrat by Christian Holm |
Copyright ; 2002 BRAHMS Collaboration
<brahmlib@rcf.rhic.bnl.gov>
|