#include "THaVDCCluster.h"
#include "THaVDCHit.h"
#include "THaVDCPlane.h"
#include "THaVDCUVTrack.h"
#include "THaTrack.h"
#include "TMath.h"
#include "TClass.h"
#include <iostream>
using namespace std;
const Double_t THaVDCCluster::kBig = 1e38;
THaVDCCluster::THaVDCCluster( const THaVDCCluster& rhs ) :
TObject(rhs),
fSize(rhs.fSize), fPlane(rhs.fPlane), fSlope(rhs.fSlope),
fSigmaSlope(rhs.fSigmaSlope), fInt(rhs.fInt), fSigmaInt(rhs.fSigmaInt),
fT0(rhs.fT0), fSigmaT0(rhs.fSigmaT0), fPivot(rhs.fPivot),
fTimeCorrection(rhs.fTimeCorrection), fFitOK(rhs.fFitOK),
fLocalSlope(rhs.fLocalSlope), fChi2(rhs.fChi2), fNDoF(rhs.fNDoF)
{
for( int i = 0; i < fSize; i++ ) {
fHits[i] = rhs.fHits[i];
}
}
THaVDCCluster& THaVDCCluster::operator=( const THaVDCCluster& rhs )
{
TObject::operator=( rhs );
if( this != &rhs ) {
fSize = rhs.fSize;
fPlane = rhs.fPlane;
fSlope = rhs.fSlope;
fSigmaSlope = rhs.fSigmaSlope;
fInt = rhs.fInt;
fSigmaInt = rhs.fSigmaInt;
fT0 = rhs.fT0;
fSigmaT0 = rhs.fSigmaT0;
fPivot = rhs.fPivot;
fTimeCorrection = rhs.fTimeCorrection;
fFitOK = rhs.fFitOK;
fLocalSlope = rhs.fLocalSlope;
fChi2 = rhs.fChi2;
fNDoF = rhs.fNDoF;
for( int i = 0; i < fSize; i++ )
fHits[i] = rhs.fHits[i];
}
return *this;
}
THaVDCCluster::~THaVDCCluster()
{
}
void THaVDCCluster::AddHit(THaVDCHit * hit)
{
if (fSize < MAX_SIZE) {
fHits[fSize++] = hit;
} else if( fPlane && fPlane->GetDebug()>0 ) {
Warning( "AddHit()", "Max cluster size reached.");
}
}
void THaVDCCluster::Clear( const Option_t* )
{
ClearFit();
fSize = 0;
fPivot = NULL;
fPlane = NULL;
}
void THaVDCCluster::ClearFit()
{
fSlope = kBig;
fSigmaSlope = kBig;
fInt = kBig;
fSigmaInt = kBig;
fT0 = 0.0;
fSigmaT0 = kBig;
fFitOK = false;
fLocalSlope = kBig;
fChi2 = kBig;
fNDoF = 0.0;
}
Int_t THaVDCCluster::Compare( const TObject* obj ) const
{
if( !obj || IsA() != obj->IsA() )
return -1;
const THaVDCCluster* rhs = static_cast<const THaVDCCluster*>( obj );
if( GetPivotWireNum() < rhs->GetPivotWireNum() )
return -1;
if( GetPivotWireNum() > rhs->GetPivotWireNum() )
return +1;
return 0;
}
void THaVDCCluster::EstTrackParameters()
{
fFitOK = false;
if( fSize == 0 )
return;
Double_t time = 0, minTime = 1000;
for (int i = 0; i < fSize; i++) {
time = fHits[i]->GetTime();
if (time < minTime) {
minTime = time;
fPivot = fHits[i];
}
}
fInt = fPivot->GetPos();
if( fSize > 1 ) {
Double_t conv = fPlane->GetDriftVel();
Double_t dx = conv * (fHits[0]->GetTime() + fHits[fSize-1]->GetTime());
Double_t dy = fHits[0]->GetPos() - fHits[fSize-1]->GetPos();
fSlope = dy / dx;
} else
fSlope = 1.0;
CalcDist();
fLocalSlope = fSlope;
fFitOK = true;
}
void THaVDCCluster::ConvertTimeToDist()
{
for (int i = 0; i < fSize; i++)
fHits[i]->ConvertTimeToDist(fSlope);
}
void THaVDCCluster::CalcDist()
{
for (int j = 0; j < fSize; j++) {
Double_t y = fHits[j]->GetPos();
if (fSlope!=0.) {
Double_t X = (y-fInt)/fSlope;
fHits[j]->SetFitDist(TMath::Abs(X));
} else {
fHits[j]->SetFitDist(kBig);
}
}
}
void THaVDCCluster::FitTrack( EMode )
{
FitSimpleTrack();
CalcDist();
}
void THaVDCCluster::FitSimpleTrack()
{
fFitOK = false;
if( fSize < 3 )
return;
Double_t N = fSize;
Double_t m, sigmaM;
Double_t b, sigmaB;
Double_t sigmaY;
Double_t* xArr = new Double_t[fSize];
Double_t* yArr = new Double_t[fSize];
Double_t bestFit = 0.0;
Int_t pivotNum = 0;
for (int i = 0; i < fSize; i++) {
if (fHits[i] == fPivot) {
pivotNum = i;
}
xArr[i] = fHits[i]->GetDist() + fTimeCorrection;
yArr[i] = fHits[i]->GetPos();
}
const Int_t nSignCombos = 2;
for (int i = 0; i < nSignCombos; i++) {
Double_t sumX = 0.0;
Double_t sumXX = 0.0;
Double_t sumY = 0.0;
Double_t sumXY = 0.0;
Double_t sumDY2 = 0.0;
if (i == 0)
for (int j = pivotNum+1; j < fSize; j++)
xArr[j] = -xArr[j];
else if (i == 1)
xArr[pivotNum] = -xArr[pivotNum];
for (int j = 0; j < fSize; j++) {
Double_t x = xArr[j];
Double_t y = yArr[j];
sumX += x;
sumXX += x * x;
sumY += y;
sumXY += x * y;
}
m = (N * sumXY - sumX * sumY) / (N * sumXX - sumX * sumX);
b = (sumXX * sumY - sumX * sumXY) / (N * sumXX - sumX * sumX);
for (int j = 0; j < fSize; j++) {
Double_t y = yArr[j];
Double_t Y = m * xArr[j] + b;
sumDY2 += (y - Y) * (y - Y);
}
sigmaY = TMath::Sqrt (sumDY2 / (N - 2));
sigmaM = sigmaY * TMath::Sqrt ( N / ( N * sumXX - sumX * sumX) );
sigmaB = sigmaY * TMath::Sqrt (sumXX / ( N * sumXX - sumX * sumX) );
if (i == 0 || sigmaY < bestFit) {
bestFit = sigmaY;
fSlope = m;
fSigmaSlope = sigmaM;
fInt = b;
fSigmaInt = sigmaB;
}
}
Double_t chi2 = 0.;
Int_t nhits = 0;
CalcChisquare(chi2,nhits);
fChi2 = chi2;
fNDoF = nhits-2;
fLocalSlope = fSlope;
fFitOK = true;
delete[] xArr;
delete[] yArr;
}
void THaVDCCluster::FitSimpleTrackWgt()
{
fFitOK = false;
if( fSize < 3 ) {
fChi2 = kBig;
fNDoF = fSize;
return;
}
Double_t m, sigmaM;
Double_t b, sigmaB;
Double_t* xArr = new Double_t[fSize];
Double_t* yArr = new Double_t[fSize];
Double_t* wtArr= new Double_t[fSize];
Double_t bestFit = 0.0;
Int_t pivotNum = 0;
for (int i = 0; i < fSize; i++) {
if (fHits[i] == fPivot) {
pivotNum = i;
}
xArr[i] = fHits[i]->GetPos();
yArr[i] = fHits[i]->GetDist() + fTimeCorrection;
wtArr[i]= fHits[i]->GetdDist();
if (wtArr[i]>0) wtArr[i] = 1./(wtArr[i]*wtArr[i]);
}
const Int_t nSignCombos = 2;
for (int i = 0; i < nSignCombos; i++) {
Double_t F, sigmaF2;
Double_t G, sigmaG2;
Double_t sigmaFG;
Double_t sumX = 0.0;
Double_t sumXW = 0.0;
Double_t sumXX = 0.0;
Double_t sumY = 0.0;
Double_t sumXY = 0.0;
Double_t sumYY = 0.0;
Double_t sumXXW= 0.0;
Double_t W = 0.0;
Double_t WW= 0.0;
if (i == 0)
for (int j = pivotNum+1; j < fSize; j++)
yArr[j] *= -1;
else if (i == 1)
yArr[pivotNum] *= -1;
for (int j = 0; j < fSize; j++) {
Double_t x = xArr[j];
Double_t y = yArr[j];
Double_t w =wtArr[j];
if (w <= 0) continue;
W += w;
WW += w*w;
sumX += x * w;
sumXW += x * w * w;
sumXX += x * x * w;
sumXXW+= x * x * w * w;
sumY += y * w;
sumXY += x * y * w;
sumYY += y * y * w;
}
Double_t Delta = W * sumXX - sumX * sumX;
F = (sumXX * sumY - sumX * sumXY) / Delta;
G = (W * sumXY - sumX * sumY) / Delta;
sigmaF2 = ( sumXX / Delta );
sigmaG2 = ( W / Delta );
sigmaFG = ( sumXW * W * sumXX - sumXXW * W * sumX
- WW * sumX * sumXX + sumXW * sumX * sumX ) / (Delta*Delta);
m = 1/G;
b = - F/G;
sigmaM = m * m * TMath::Sqrt( sigmaG2 );
sigmaB = TMath::Sqrt( sigmaF2/(G*G) + F*F/(G*G*G*G)*sigmaG2 - 2*F/(G*G*G)*sigmaFG);
Double_t chi2 = 0.;
Int_t nhits = 0;
Double_t oldslope = fSlope;
Double_t oldint = fInt;
CalcChisquare(chi2,nhits);
fSlope = oldslope;
fInt = oldint;
sigmaM *= chi2/(nhits - 2);
sigmaB *= chi2/(nhits - 2);
if (i == 0 || chi2 < bestFit) {
bestFit = chi2;
fChi2 = chi2;
fNDoF = nhits-2;
fSlope = m;
fSigmaSlope = sigmaM;
fInt = b;
fSigmaInt = sigmaB;
}
}
fLocalSlope = fSlope;
fFitOK = true;
delete[] xArr;
delete[] yArr;
delete[] wtArr;
}
Int_t THaVDCCluster::GetPivotWireNum() const
{
return fPivot ? fPivot->GetWireNum() : -1;
}
void THaVDCCluster::CalcChisquare(Double_t& chi2, Int_t& nhits ) const
{
Int_t pivotNum = 0;
for (int j = 0; j < fSize; j++) {
if (fHits[j] == fPivot) {
pivotNum = j;
}
}
for (int j = 0; j < fSize; j++) {
Double_t x = fHits[j]->GetDist() + fTimeCorrection;
if (j>pivotNum) x = -x;
Double_t y = fHits[j]->GetPos();
Double_t dx = fHits[j]->GetdDist();
Double_t Y = fSlope * x + fInt;
Double_t dY = fSlope * dx;
if (dx <= 0) continue;
if ( fHits[j] == fPivot ) {
Double_t ox = -x;
Double_t oY = fSlope * ox + fInt;
if ( TMath::Abs(y-Y) > TMath::Abs(y-oY) ) {
x = ox;
Y = oY;
}
}
chi2 += (Y - y)/dY * (Y - y)/dY;
nhits++;
}
}
void THaVDCCluster::Print( Option_t* ) const
{
if( fPlane )
cout << "Plane: " << fPlane->GetPrefix() << endl;
cout << "Size: " << fSize << endl;
cout << "Wire numbers:";
for( int i = 0; i < fSize; i++ ) {
cout << " " << fHits[i]->GetWireNum();
if( fHits[i] == fPivot )
cout << "*";
}
cout << endl;
cout << "Wire raw times:";
for( int i = 0; i < fSize; i++ ) {
cout << " " << fHits[i]->GetRawTime();
if( fHits[i] == fPivot )
cout << "*";
}
cout << endl;
cout << "Wire times:";
for( int i = 0; i < fSize; i++ ) {
cout << " " << fHits[i]->GetTime();
if( fHits[i] == fPivot )
cout << "*";
}
cout << endl;
cout << "Wire positions:";
for( int i = 0; i < fSize; i++ ) {
cout << " " << fHits[i]->GetPos();
if( fHits[i] == fPivot )
cout << "*";
}
cout << endl;
cout << "Wire drifts:";
for( int i = 0; i < fSize; i++ ) {
cout << " " << fHits[i]->GetDist();
if( fHits[i] == fPivot )
cout << "*";
}
cout << endl;
cout << "Int(err), local Slope(err), global slope, t0(err): "
<< fInt << " (" << fSigmaInt << "), "
<< fLocalSlope << " (" << fSigmaSlope << "), "
<< fSlope << ", "
<< fT0 << " (" << fSigmaT0 << "), fit ok: " << fFitOK
<< endl;
}
ClassImp(THaVDCCluster)
Last change: Sat Nov 7 21:26:55 2009
Last generated: 2009-11-07 21:26
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.