/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Marcos Lopez  2/2005 <mailto:tbretz@uni-sw.gwdg.de>
!
!   Copyright: MAGIC Software Development, 2000-2002
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//   MFHadAlpha                                                            //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#include "MFHadAlpha.h"


#include <fstream>
#include <TFile.h>
#include "MLog.h"
#include "MLogManip.h"

#include "MParList.h"

#include "MHillas.h"
#include "MHillasSrc.h"
#include "MHadAlphaCut.h"
#include "MEnergyEst.h"
#include "MHadronness.h"
#include "MPointingPos.h"

ClassImp(MFHadAlpha);

using namespace std;


// --------------------------------------------------------------------------
//
MFHadAlpha::MFHadAlpha(const char *name, const char *title)
    : fFilterType(kHadAlphaCut), fFileName("")
{
    fName  = name  ? name  : "MFHadAlpha";
    fTitle = title ? title : "Filter to apply hadroness and alpha cuts for each size and theta bin";
}


// --------------------------------------------------------------------------
//
Int_t MFHadAlpha::PreProcess(MParList *pList)
{
   
    fHillas = (MHillas*)pList->FindObject("MHillas");
    if (!fHillas)
    {
        *fLog << dbginf << "MHillas not found... aborting." << endl;
        return kFALSE;
    } 

    fPointingPos = (MPointingPos*)pList->FindObject("MPointingPos");
    if (!fPointingPos)
    {
        *fLog << dbginf << "MPointingPos not found... aborting." << endl;
        return kFALSE;
    }

    fHadronness = (MHadronness*)pList->FindObject("MHadronness");
    if (!fHadronness)
    {
        *fLog << dbginf << "MHadronness not found... aborting." << endl;
        return kFALSE;
    } 

    fHillasSrc = (MHillasSrc*)pList->FindObject("MHillasSrc");
    if (!fHillasSrc)
    {
        *fLog << dbginf << "MHillasSrc not found... aborting." << endl;
        return kFALSE;
    } 

    fEnergyEst = (MEnergyEst*)pList->FindObject("MEnergyEst");
    if (!fEnergyEst)
    {
        *fLog << dbginf << "MEnergyEst not found... aborting." << endl;
        return kFALSE;
    } 

   
    fHadAlphaCut = (MHadAlphaCut*)pList->FindCreateObj("MHadAlphaCut");
    if (!fHadAlphaCut)
    {
	*fLog << dbginf << "MHadAlphaCut not found... aborting." << endl;
	return kFALSE;
    }
 
    if(fFileName!="")
    {
	TFile f(fFileName);
	fHadAlphaCut->Read("MHadAlphaCut");
    }

    return kTRUE;
}

// --------------------------------------------------------------------------
//
Int_t MFHadAlpha::Process()
{
    //const Float_t size = fHillas->GetSize();
    const Float_t energy = fEnergyEst->GetEnergy();
    const Float_t zd = fPointingPos->GetZd();
    const Float_t alpha = TMath::Abs(fHillasSrc->GetAlpha());
    const Float_t had = fHadronness->GetHadronness();

    const Float_t alphacut = fHadAlphaCut->GetAlphaCut(energy,zd);
    const Float_t hadcut = fHadAlphaCut->GetHadCut(energy,zd);
    
    switch(fFilterType)
    {
	case MFHadAlpha::kAlphaCut:
	    fResult = ( alpha <= alphacut );
	    break;
	case MFHadAlpha::kHadCut:
	    fResult = ( had <= hadcut ); 
	    break;
	case MFHadAlpha::kHadAlphaCut:
	    fResult = ( (alpha <= alphacut)  && (had <= hadcut) );
	    break;
	default:
	    fResult = kTRUE;
    }


    return kTRUE;
}
