#ifndef MARS_MHDisp
#define MARS_MHDisp

#ifndef MARS_MH
#include "MH.h"
#endif

#ifndef ROOT_TArrayI
#include <TArrayI.h>
#endif

class TH1F;
class TH2F;
class TProfile;
class MImageParDisp;
class MSrcPosCam;
class MHillas;
class MHillasExt;
class MNewImagePar;
class MMcEvt;
class MPointingPos;
class MHMatrix;
class MParameterD;

class MHDisp : public MH
{
private:

    MImageParDisp *fImageParDisp;  // container with the estimated Disp
    MSrcPosCam    *fSrcPos;
    MHillas       *fHil;
    MHillasExt    *fHilExt;
    MNewImagePar  *fNewPar;
    MMcEvt        *fMcEvt;
    MPointingPos  *fPointing;

    TString fImageParDispName;

    Int_t fSelectedPos;      // flag to select which of the two Disp source position
                             // solutions we want to fill the histograms (see Set function)

    TH1F *fHistEnergy;       // Energy distribution of events
    TH1F *fHistSize;         // Size distribution of events
    TH1F *fHistcosZA;        // cosinus Zenith angle distribution of events
    TH2F *fSkymapXY;         // 2D histogram for Disp estimated source positions
    TH1F *fHistMinPar;       // Histogram of the event Minimization Parameter (= d^2 = 
                             // = distance^2 between Disp estimated and true source position)
    TH2F *fHistDuDv;         // Distribution of longitudinal (Du) and transversal 
                             // (Dv) distances between Disp and true source position    
    TH2F *fHistMinParEnergy; // Minimization Parameter (= d^2) vs. Energy
    TH2F *fHistMinParSize;   // Minimization Parameter (= d^2) vs. Size
    TH2F *fHistDuEnergy;     // Du vs. Energy
    TH2F *fHistDuSize;       // Du vs. Size
    TH2F *fHistDvEnergy;     // Dv vs. Energy
    TH2F *fHistDvSize;       // Dv vs. Size
    TProfile *fEvCorrAssign; // % events with source position well assign vs. Size 


    Double_t fMm2Deg;        // conversion factor from mm to deg

    MHMatrix *fMatrix;       // matrix storing variables needed for the Disp optimization
    TArrayI fMap;            // array storing the matrix mapping column numbers corresponding
                             // to each variable added to fMatrix

    Double_t GetVal(Int_t i) const;

    Int_t fNumEv;            // total number of events
    Double_t fSumMinPar;     // current sum of the minimization parameter   
    MParameterD *fMinPar;    // final minimization parameters of the Disp optimization

public:

    MHDisp(const char *imagepardispname = "MImageParDisp",
	   const char *name=NULL, const char *title=NULL);
    ~MHDisp();

    Bool_t SetupFill(const MParList *plist);
    Bool_t Fill(const MParContainer *par, const Stat_t w=1);
    Bool_t Finalize();  

    void SetSelectedPos(Int_t iflag);

    void SetMatrixMap(MHMatrix *matrix, TArrayI &map);    
    void GetMatrixMap(MHMatrix* &matrix, TArrayI &map);  // get matrix and its mapping array

    void InitMapping(MHMatrix *mat);       // define the matrix of variables
                                           // needed for the Disp optimization

    TH1F *GetHistEnergy()       { return fHistEnergy; } 
    TH1F *GetHistSize()         { return fHistSize; } 
    TH1F *GetHistcosZA()        { return fHistcosZA; } 
    TH2F *GetSkymapXY()         { return fSkymapXY; }
    TH1F *GetHistMinPar()       { return fHistMinPar; }
    TH2F *GetHistDuDv()         { return fHistDuDv; }
    TH2F *GetHistMinParEnergy() { return fHistMinParEnergy; }
    TH2F *GetHistMinParSize()   { return fHistMinParSize; }
    TH2F *GetHistDuEnergy()     { return fHistDuEnergy; }
    TH2F *GetHistDuSize()       { return fHistDuSize; }
    TH2F *GetHistDvEnergy()     { return fHistDvEnergy; }
    TH2F *GetHistDvSize()       { return fHistDvSize; }
    TProfile *GetEvCorrAssign() { return fEvCorrAssign; }

    void Draw(Option_t *opt="");

    ClassDef(MHDisp, 1) // Container holding the Histograms for Disp and
                        // the parameter to minimize in the Disp optimization
};

#endif


