CRingFitter.h
//-----------------------------------------------------------------------------
// $Header: /asis/offline/ceres/cool/project/RCS/CRingFitter.h,v 3.0 1996/10/02 09:40:19 voigt Exp $
//
// COOL Program Library
// Copyright (C) CERES collaboration, 1996
//
// Functor class to fit rings.
//
//-----------------------------------------------------------------------------
#ifndef CRINGFITTER_H
#define CRINGFITTER_H
#include <iostream.h>
#include <float.h>
#include <math.h>
#include "cool.h"
#include "rw/tvordvec.h"
class CRingFitter {
public:
CRingFitter();
~CRingFitter();
public:
//
// Fit methods/algorithms
// After invoking the fit method the initial x, y, r values
// as well as the weights are modified by the procedure. To
// repeat the same fit or try a different algorithm on the
// same data points new initial x, y, r values and weights
// must be set again. The weights are best set by using the
// setWeights(1.) method. The set fit points are left untouched
// until the reset() method is invoked.
//
CBoolean chernov(); // Chernov/Ososkov fit
CBoolean robustFixedRadius(); // iterates on fitFixedRadius() to fit rings
CBoolean robustDoubleRing(); // fixed radius double ring fit
CBoolean robustFreeRadius(); // iterates on fitFreeRadius() to fit rings => Federica
void reset(); // resets only the x/y/weight arrays
void resetAll(); // resets everything
void setWeights(double); // set all weights to same value
void printStatistics(ostream& = cout) const;
//
// Common to all ring fit algorithms
//
inline void addX (double xin) { x.insert(xin); }
inline void addY (double yin) { y.insert(yin); }
inline void addWeight (double win) { w.insert(win); }
inline void setTukey (double val) { valTukey = val; }
inline void setMaxIter (int val) { maxIter = val; }
inline void setXCenter (double val) { xCenter = val; }
inline void setYCenter (double val) { yCenter = val; }
inline void setRadius (double val) { radius = val; }
inline double getXCenter () const { return xCenter ; }
inline double getYCenter () const { return yCenter ; }
inline double getRadius () const { return radius ; }
inline double getVariance() const { return variance; }
inline int getMaxIter () const { return maxIter ; }
inline int getNIter () const { return maxIter - iter ; }
inline int getError () const { return ret ; }
inline int getNFitPoints() { return x.length(); }
//
// Double ring fit only
//
inline void setSecondXCenter (double val) { secondXCenter = val; }
inline void setSecondYCenter (double val) { secondYCenter = val; }
inline double getSecondXCenter() { return secondXCenter; }
inline double getSecondYCenter() { return secondYCenter; }
protected:
CBoolean fitFixedRadius(); // used by robustFixedRadius()
CBoolean fitFreeRadius(); // used by robustFreeRadius() => Federica
CBoolean symmax(double [][4], double[], int); // used by robustDoubleRing()
protected:
//
// input:
//
RWTValOrderedVector<double> x; // coordinates and weights
RWTValOrderedVector<double> y; // of points to be fitted.
RWTValOrderedVector<double> w; // weights are overwritten by fit.
double valTukey; // the constant for Tukey biweight formula (>1)
int maxIter ; // maximal admissible iteration number
//
// input and output:
//
double radius; // can be fixed
double xCenter; // guessed center on input, fitted center on output
double yCenter;
double secondXCenter; // double ring fit only
double secondYCenter;
//
// output:
//
double variance; // the robust estimate of variance
//
// Error diagnostic for robust single ring fits
// 0: ok
// 1: not enough fit points
// 2: determinant of system too small
// 3: sum of weights == 0
// Error diagnostic for robust double ring fits
// 1: not enough fit points
// 2: stopped due to iteration limit
// 3: singular matrix
//
int ret;
private:
RWTValOrderedVector<double> res; // residual vector
RWTValOrderedVector<double> resold; // internal array
int iter;
private:
enum FitAlgorithm { Chernov, RobustFixedRadius, RobustDoubleRing };
FitAlgorithm algorithm;
};
#endif /* CRINGFITTER_H */