// -*- mode: c++ -*-
//
// $Id: BrTofSlewingCalModule.h,v 1.9 2002/06/13 19:24:15 videbaek Exp $
// $Author: videbaek $
// $Date: 2002/06/13 19:24:15 $
// $Copyright: (C) 2001 BRAHMS Collaboration <brahmlib@rhic.bnl.gov>
//
#ifndef BRAT_BrTofSlewingCalModule
#define BRAT_BrTofSlewingCalModule

#ifndef BRAT_BrTofCalModule
#include "BrTofCalModule.h"
#endif

class TH1F;
class TH2F;
class TProfile;
class BrEventNode;
//class TMinuit;
class TVirtualFitter;

class BrTofSlewingCalModule : public BrTofCalModule
{
private:

  static BrTofSlewingCalModule* fgInstance;

  Float_t fMaxTofDE;     // energy loss in hodoscope  
  Float_t fMaxWidth;     // cut outliers in time
  Float_t fC1Threshold;  // for Pion selection
  Float_t fRichPionMass; // Rich mean pion mass
  Float_t fRichMassCut;  // cut on pion mass peak (in GeV/c^2)
  Double_t fTimeResolution; // Estimated timeresoultion
  Double_t fNominalLength;  //
  Float_t fMomentumCut;     // upper momentum cur for slewing calc.
  Bool_t fVaryDt;           //control of parameters in Minuit
  Double_t fTimeCut;        // Cut of est vs cal time before using in fitting
  Float_t fTrkOffset[3];    // Similar cuts to timing offset calculations.
  Float_t fTrkCut[3];       // 
  Bool_t fFitMode;

  TObjArray* fSlewHitsTable;
  TObjArray* fCurrentHitTable;
  Int_t fCurrentSlat;
  // histograms
  TProfile** fTSlew;
  TProfile** fBSlew;
  TH2F**     fBOff; 
  TH2F**     fTOff; 
  TH2F**     fBOffCorr; 
  TH2F**     fTOffCorr;
  TH2F*      fTDiffCorr; 
  TH1F*      fTSlew1;
  TH1F*      fBSlew1;
  TH1F*      fTSlew2;
  TH1F*      fBSlew2;
  TH2F*      fTDiff; //
  //
  // Option for different methods

  Bool_t   fUseBbVertex; // Normal HI running requirement
  Bool_t   fUseTd1Time;  // Calibration for pp running
  Bool_t   fUseTMrsTime; // Calibration for pp running

  Bool_t fUseChkv;    // require Cherenkov Cuts
  Bool_t fUseMinuit;  // Flag for new method to get slewing constants

  TVirtualFitter* fMinuit; //

  virtual void FitCurrentSlat(Int_t slat, Double_t* dfit, Double_t* dfitError);
  virtual void FillCorrectedHistograms(Int_t slat, Double_t* par);
  virtual void fcnout(Double_t *par, Double_t &mean, Double_t &meanwt, 
		      Double_t &chisq, Double_t &chisqpdf);
  //
  virtual void SaveAscii();
  virtual void ReadAscii();

  private:
  // Class for hits used for slew fits.
  //

  class BrTofSlewHit : public TObject { 
  public:
    BrTofSlewHit(){ };
    BrTofSlewHit(Float_t tof_up, Float_t tof_down, Float_t adc_up , Float_t adc_down, Float_t t0, Float_t length, Float_t betaCalc) {
      fTofup = tof_up;
      fTofdown = tof_down;
      fAdcup = adc_up;
      fAdcdown = adc_down;
      fT0 = t0;
      fLength = length;
      fBetaCalc=betaCalc;    }
      
    virtual ~BrTofSlewHit() { };

    Double_t fTofup;   // TofUp nsec
    Double_t fTofdown; // TofDown nsec
    Double_t fAdcup;   // Adc_up in channel count
    Double_t fAdcdown; // Adc_down in channel count
    Double_t fT0;       // Start time this track
    Double_t fBetaCalc; // calculated beta for pion with momentum.
    Double_t fLength; //  
    //    ClassDefNested(BrTofSlewHit,1) // a recontructed tof hit
  };

  static void fcn2(Int_t &npar, 
	    Double_t *gin,
	    Double_t &f,
	    Double_t *par,
	    Int_t iflag);

  Double_t func2(Int_t i, Double_t *par);  

public:

  BrTofSlewingCalModule();
  BrTofSlewingCalModule(const Char_t* name, const Char_t* title);
  virtual ~BrTofSlewingCalModule ();

  // Methods related to fitting of data.

  static BrTofSlewingCalModule* Instance() { return fgInstance; }
  Double_t      ChiSquare(Double_t *par);

  void SetDefaultParameters();
  void SetMaxTofDE(Float_t e = 2.)             { fMaxTofDE = e; }
  void SetMaxEnergy(Float_t e = 2.)            { fMaxTofDE = e; }
  void SetC1Threshold(Float_t t = 1.)          { fC1Threshold = t; }
  void SetRichPionMass(Float_t pi = 0.1395679) { fRichPionMass = pi; }
  void SetRichMassCut(Float_t cut = 0.05)      { fRichMassCut = cut; }
  void SetUseBbVertex(Bool_t b = kTRUE)        { fUseBbVertex = b;}
  void SetUseTd1Time(Bool_t b = kFALSE)        { fUseTd1Time=b;}
  void SetUseTMrsTime(Bool_t b = kFALSE)       { fUseTMrsTime=b;}
  void SetUseChkv(Bool_t b = kTRUE)            { fUseChkv = b;}
  void SetUseMinuit(Bool_t b = kFALSE)         { fUseMinuit = b;}
  void SetVaryDt(Bool_t b = kFALSE)            { fVaryDt = b;}
  void SetTimeResolution(Float_t val = 0.08)   { fTimeResolution = val; }
  void SetMomentumCut(Float_t f = 2.0)         { fMomentumCut = f; }
  void SetTimeCut(Float_t f = 0.6)             { fTimeCut = f; }
  void SetTrkCuts(Float_t dx = 100000, Float_t dy = 100000, Float_t dz = 100000) {
    fTrkCut[0] = dx; fTrkCut[1] = dy; fTrkCut[2] = dz; 
  }
  void SetTrkOffsets(Float_t x = 0, Float_t y = 0, Float_t z = 0) {
    fTrkOffset[0] = x; fTrkOffset[1] = y; fTrkOffset[2] = z; 
  }

  virtual void DefineHistograms();
  virtual void Init();
  virtual void Begin();
  virtual void Event(BrEventNode* inNode, BrEventNode* outNode);
  virtual void Finish();
  virtual void Print(Option_t* option="B") const; // *MENU*

  ClassDef(BrTofSlewingCalModule,0) // Slewing correction module for TOFs
};

#endif
//____________________________________________________________________
//
// $Log: BrTofSlewingCalModule.h,v $
// Revision 1.9  2002/06/13 19:24:15  videbaek
// mny modification to timeoffset and slewing modules.
// a) Offset module modified to deal with pp running and Td1, TMrsF start counters.
// b) The  slewing and offset mdoule now has similar cuts in pid, vertex cuts
//    and momentmu cut.
// c) The mrs code had a momentum cut introduced to not contaminate dt spectra with
//    the kaon's and protons.
// d) The slewing modules have added the method to fit  the hits using minuit rather than
//    2D histograms. the old method is kept for consistency (at least a while). As for
//    all slwing data correction rather large statistics is needed.
// e) Note that when using slewing the timeoffsets are still important!!! the first term in the
//    slweing is only a relative term taking into account the offsets created by the 1/sqrt(A) terms.
//    This implies that the same offsets are valid w and /wo slewing being done.
//
// Revision 1.8  2002/04/15 17:15:56  ouerdane
// added SetMaxEnergy(max tof de)
//
// Revision 1.7  2002/03/21 15:04:25  ouerdane
// added fComment member to base class module and method SetComment so that the user can set comments about the calibration at commit time. Removed mean momentum stuff in slewing cal module
//
// Revision 1.6  2002/03/20 19:37:25  videbaek
// Added possibility to calibrate for pp using the TD1 counters rather than
// BB. Also falg possibility to require or not Cherenkovs. This may be useful
// for calibrations in MRS.
//
// Revision 1.5  2001/12/20 15:30:44  ouerdane
// Modified slewing correction, needs now the Rich or C1 pid objects to select only pions (cf calib/tof/TofSlewing.C
//
// Revision 1.4  2001/11/05 06:59:44  ouerdane
// changed to deal with new track classes and fixed some bugs
//
// Revision 1.3  2001/10/02 01:53:28  ouerdane
// Added SetSaveAscii, SetLoadAscii, SetCommitAscii and updated the way parameters are tagged for Use
//
// Revision 1.2  2001/07/31 09:22:08  ouerdane
// Removed all references to a TList member, replaced
// by histogram members, declare ntuple if fNtuple is true (set
// via SetNtuple)
//
// Revision 1.1  2001/06/29 13:52:32  cholm
// Imported TOF classes from Djamel
//
//