////////////////////////////////////////////////////////////////////////
/// $Id: SkzpFitter.h,v 1.1 2008/02/12 19:22:15 rearmstr Exp $
///
/// (Document me!)
///
/// rearmstr@indiana.edu
////////////////////////////////////////////////////////////////////////
#ifndef SKZPFITTER_H
#define SKZPFITTER_H
#include "TVirtualFitter.h"

#include "MCReweight/MCReweight.h"
#include "JobControl/JobCModule.h"
#include "Registry/Registry.h"

#include "Smooth.h"
#include "SkzpCalculator.h"
#include "Chi2Func.h"

#include "TFile.h"
#include "TGraph.h"
#include "TGraph2D.h"

#include <vector>
#include <map>

class FitPar;
class SkzpFitter : public JobCModule
{
public:
  SkzpFitter();
  ~SkzpFitter();

public:
  // Handle job status changes
  void BeginJob();
  void EndJob();

  // Analysis and Reconstruction methods
  JobCResult Ana(const MomNavigator* mom);
  

  // I/O methods
  JobCResult Get(MomNavigator* mom);
  JobCResult Put(const MomNavigator* mom);

  // Module configuration
  const Registry& DefaultConfig() const;
  void            Config(const Registry& r);

  // User interface methods
  void Help();
  void HandleCommand(JobCommand* c);

  double GetChi2();
  int    GetNDF() {return fNDF;}
  void   SetParameters(vector<double> par);
  bool   ReadInputFile(std::string file);
  void   SetOutputFile(std::string file) {
    fOutputFile=file; if(!fOut) fOut=new TFile(fOutputFile.c_str(),"recreate");
  }
  bool   Setup();
  void   Write();
  void   Test(int n);

  void  Scan(const std::string &cmd);
  void  Scan(const std::string &id,const int index,const int &npoints,
	     const double &start,const double &end,const bool &save,const bool &write);

  inline int GetNParFree() {return fNParFree;}
  inline int GetNParFixed(){return fNParFixed;}
  inline int GetNPar() {return fNPar;}
  inline int GetIteration() {return fIterations;}
  inline void IncrementIteration() {++fIterations;}

private:
  // Module configuration
  std::string fInputFile;
  std::string fOutputFile;
  TFile *fOut;
  TDirectoryFile *fScanDir;

  // Minuit Configurations
  TVirtualFitter           *fitter;
  std::vector<std::string> fCommands; 
  std::vector<int>         fScanList; 

  std::string fFitter;
  int         fIterations;
  int         fMaxIterations;
  double      fTolerance;
  double      fStrategy;
  double      fERRDEF;
  int         fNParFree;
  int         fNParFixed;
  int         fNPar;
  int         fNDF;
  double      arglist[10];
  // List of fit paramters to give minuit
  std::vector<FitPar>    fParameters;


  // Scanning
  int fScanPoints;
  
  // Neugen Configurations
  Bool_t      fUseNeugen;
  
  std::string fNeugenConfigName;
  int         fNeugenVer; 
  double      fMaQE;
  double      fMaRES;
  double      fKNO;
  bool        fUseOldKNO;
  MCReweight  *mcr;
  Registry    *nwc_reg;

  //Smoothing options
  Bool_t      fUseSmoothing;
  std::string fSmoothFunc;
  double      fFuncMin;
  double      fFuncMax;
  double      fNormMin;
  double      fNormMax;
  int         fFuncBins;
  Bool_t      fFuncNorm;
  Smooth      *smooth;
  
  std::vector<Chi2FuncPtr>   fChi2Funcs;
  std::vector<std::string> fChi2FuncNames;

  // Weighting stuff
  SkzpCalculator           *fSkzpCalc;
  std::vector<std::string> fWeightNames;
  std::vector<SkzpWeightPtr>   fSkzpWeights;

  // a list of properties for the chi2funcs
  // and the skzp weights
  std::map<std::string,std::vector<std::string> > fProperties;
  typedef  std::map<std::string,
		    std::vector<std::string> >::iterator PropIter;
  
  std::string fFitParFile;
  


  // Registrys to hold parameters and best fit chi2s
  Registry fPar_reg;
  Registry fChi2_reg;



};
#endif // SKZPFITTER_H
////////////////////////////////////////////////////////////////////////
