/* ======================================================================== *\
!
! *
! * 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): Robert Wagner <rwagner@mppmu.mpg.de> 10/2002
!
!   Copyright: MAGIC Software Development, 2000-2003
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//  MSigmabarCalc                                                          //
//                                                                         //
//  This task calculates Sigmabar using the MSigmabar container and stores //
//  its extremal values together with the corresponding Theta values       //
//  in MSigmabarParam. For the time being, Theta is taken from a Monte     //
//  Carlo container. This is preliminary and to be changed ASAP.           //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#include "MSigmabarCalc.h"

#include "MLog.h"
#include "MLogManip.h"

#include "MParList.h"
#include "MGeomCam.h"
#include "MPedestalCam.h"
#include "MSigmabar.h"
#include "MSigmabarParam.h"
#include "MMcEvt.hxx"

ClassImp(MSigmabarCalc);

// --------------------------------------------------------------------------
//
// Default constructor. 
//
MSigmabarCalc::MSigmabarCalc(const char *name, const char *title)
{
  fName  = name  ? name  : "MSigmabarCalc";
  fTitle = title ? title : "Task to calculate Sigmabar";

  Reset();
}

MSigmabarCalc::~MSigmabarCalc()
{
  // nothing special yet.
}

// --------------------------------------------------------------------------
//
//  check if necessary containers exists in the Parameter list already.
//  if not create one and add them to the list
//
Bool_t MSigmabarCalc::PreProcess(MParList *pList)
{
    fCam = (MGeomCam*)pList->FindObject("MGeomCam");
    if (!fCam)
    {
        *fLog << dbginf << "MGeomCam not found (no geometry information available)... aborting." << endl;
        return kFALSE;
    }

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

    fSig = (MSigmabar*)pList->FindCreateObj("MSigmabar");
    if (!fSig)
    {
        *fLog << dbginf << "MSigmabar not found... aborting." << endl;
        return kFALSE;
    }

    fSigParam = (MSigmabarParam*)pList->FindCreateObj("MSigmabarParam");
    if (!fSigParam)
    {
        *fLog << dbginf << "MSigmabarParam not found... aborting." << endl;
        return kFALSE;
    }

    fRun = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
    if (!fRun)
    {
        *fLog << dbginf << "MRawRunHeader not found... aborting." << endl;
        return kFALSE;
    }
    
    fMcEvt = (MMcEvt*)pList->FindObject("MMcEvt");
    // This is needed for determining min/max Theta
    if (!fMcEvt)
      {
	*fLog << err << dbginf << "MHSigmabaCalc : MMcEvt not found... aborting." << endl;
	return kFALSE;
      }

    fEvt = (MCerPhotEvt*)pList->FindObject("MCerPhotEvt");
    if (!fEvt)
      {
	*fLog << err << dbginf << "MHSigmabarCalc : MCerPhotEvt not found... aborting." << endl;
	return kFALSE;
      }

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Calculating a new Sigmabar is not necessary on event basis as long as
// we deal with CT1 data. Therefore, the real calculation is done in
// the ReInit function. Process just takes care for finding the extremal
// values. Preliminary.
//
Bool_t MSigmabarCalc::Process()
{
  Float_t rc = fSig->Calc(*fCam, *fPed, *fEvt);    
  fSigmabarMax = TMath::Max((Double_t)rc, fSigmabarMax);
  fSigmabarMin = TMath::Min((Double_t)rc, fSigmabarMin);

  if (fMcEvt->GetTelescopeTheta()*kRad2Deg < 120)
    fThetaMax    = TMath::Max(fMcEvt->GetTelescopeTheta()*kRad2Deg, fThetaMax);
  fThetaMin    = TMath::Min(fMcEvt->GetTelescopeTheta()*kRad2Deg, fThetaMin);

  return kTRUE;
}

// --------------------------------------------------------------------------
//
// Calculates Sigmabar (for CT1 only needed at Reinit, i.e. when reading
// a new file)
//
Bool_t MSigmabarCalc::ReInit(MParList *pList)
{
   
  fSigParam->SetParams(1, fSigmabarMin, fSigmabarMax, fThetaMin, fThetaMax); 
  fSigParam->SetRunNumber(fRun->GetRunNumber());
 
  Reset();
  
  return kTRUE;
}

void MSigmabarCalc::Reset()
{
  fThetaMin = 200;    //there must be a function which gives me the hightest
  fThetaMax = 0;     // value allowed for a certain type!
  fSigmabarMin = 200;
  fSigmabarMax = 0;
}

