![]() |
Extending SpecTcl's fitting subsystem |
![]() |
|---|
The SpecTcl fit subsystem is extensible. This means that it is possible for users to add custom fit types to the program. This section describes enough of the structure of the SpecTcl fitting subsystem to give you a basic understanding of the steps needed to add a new fit type. The second section of this page describes the step-by-step procedure for adding a new fit type to SpecTcl.
The SpecTcl Fit command is based on several interacting classes. The ones which matter to you are:
The steps you must follow to create a new fit type are to:
The part of the CFit abstract base class interface you need to be concerned with is shown below:
class CFit : public CNamedItem
{
// Public data types.
public:
struct Point { // A point for the fit.
double x;
double y;
};
typedef std::vector PointArray; // Point array is a std::vector of points.
typedef PointArray::iterator PointIterator;
typedef std::pair FitParameter;
typedef std::vector FitParameterList;
typedef FitParameterList::iterator FitParameterIterator;
typedef enum {
Accepting,
Performed
} FitState; //!< State of the fit.
public:
CFit (std::string name, int id = 0); // Constructor.
protected:
void SetFitState(FitState state);
// Class operations:
public:
void AddPoint (Point p) ;
void ClearPoints();
PointIterator begin () ;
PointIterator end () ;
size_t size () ;
FitState GetState () const ;
// Pure virtual functions must be implemented by
// subclasses.
virtual CFit* clone() = 0;
virtual void Perform () = 0 ;
virtual double operator() (double x) =0 ;
virtual FitParameterList GetParameters () =0 ;
virtual std::string Type() const = 0;
virtual std::string makeTclFitScript() = 0;
};
Note that the entire class definition is in <CFit.h>.
Your job will be to implement the pure virtual members of this class:
| clone | This member function should return a new fit object that
is a functional copy of *this. In general, if you have
implemented a copy constructor, this can be
implemented as:
return new CMyFitType(*this);where you must substitute your own fit type for the CMyFitType class above. |
| Perform | Perform the fit. The fit points can be gotten by iterating through them using begin(), and end(). Once successfully performed, SetFitState must be called to set the fit state to CFit::Performed. |
| operator() | Is expected to return the value of the fit evaluated at its parameter. If the fit has not yet been performed, this should throw an error. Note that FitState can be called to determine if the fit has been performed. |
| GetParameters | Should return the list of parameter name value pairs for the fit. If the fit has not yet been performed, this shouldthrow an errror. |
| Type | Must return a string that is the same as the fit type (e.g. the gaussian fit returns "gaussian"). |
| makeTclFitScript | This function must return a Tcl script named fitline that takes a single parameter and returns the height of the fit at that channel. |
Fit creator objects are used by the fit factory to generate the correct type of fit object. In order to add a fit type you will need to create your fit class, and a class that is subclassed from CFitCreator that creates a new object of your fit type.
The fit creator class has the following key interfaces:
class CFitCreator
{
public:
virtual CFit* operator() (std::string name, int id=0) = 0 ;
virtual std::string DescribeFit() = 0;
};
Your fit creator subclass must implement the pure virtual functions as follows:
| operator() | Create and return a new fit of the type you are implementing.
Usually this is done as follows:
return new CMyFit(name id) ;where you must substitute the name of your fit type for CMyFit. |
| DescribeFit | Should return a string that describes the fit type that this creator creates e.g. "gaussianl - Gaussian fit on a linear background". |
Once you have written the classes descdribed above, you must make your fit type known to the fit factory. This is done by associating your fit creator with a fit type keyword. To do this, in your MySpecTclApp.cpp file, in some function such as AddCommands, add a call to CFitCreator::AddFitType e.g:
CFitCreator::AddFitType(string("myfitform"), new CMyFitCreator());
Last Modified: October 23, 2006
by: fox@nscl.msu.edu
© Copyright NSCL 1999, All rights reserved