/* ======================================================================== *\
!
! *
! * 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): Harald Kornmayer 1/2001 (harald@mppmu.mpg.de)
!   Author(s): Thomas Bretz  12/2000 (tbretz@uni-sw.gwdg.de)
!
!   Copyright: MAGIC Software Development, 2000-2001
!
!
\* ======================================================================== */

#include "MHMcRate.h" 

#include "MLog.h"

ClassImp(MHMcRate);

void MHMcRate::Init(const char *name, const char *title)
{
    *fName  = name  ? name  : "MMcTriggerRate";
    *fTitle = title ? title : "Task to calc the collection area ";

    fPartId=0;              // Type of particle

    fEnergyMax=0.0;         // Maximum Energy in GeV
    fEnergyMin=1000000.0;   // Minimum Energy in GeV

    fThetaMax=0.0;          // Maximum theta angle of run
    fThetaMin=370.0;        // Minimum theta angle of run
    fPhiMax=0.0;            // Maximum phi angle of run
    fPhiMin=370.0;          // Minimum phi angle of run

    fImpactMax=0.0;         // Maximum impact parameter
    fImpactMin=100000.0;    // Minimum impact parameter

    fBackTrig=-1.0;         // Number of triggers from background
    fBackSim=-1.0;          // Number of simulated showers for the background

    fTrigRate= -1.0;        // Trigger rate in Hz
    fTrigRateError= -1.0;   // Estimated error for the trigger rate in Hz
}

// --------------------------------------------------------------------------
//
//  default constructor
//  fills all member data with initial values
//
MHMcRate::MHMcRate(const char *name, const char *title)
{
    Init(name, title);

    fSpecIndex=0.0;         // dn/dE = k * e^{- fSpecIndex}
    fFlux0=-1.0;            // dn/dE = fFlux0 * E^{-a}

    fShowRate= -1.0;        // Showers rate in Hz
    fShowRateError=0.0;     // Estimated error of shower rate in Hz
}

// --------------------------------------------------------------------------
//
//  overloaded constructor I
//  fills all member data with initial values and sets the rate of
//  incident showers to ShowRate
//
MHMcRate::MHMcRate(Float_t showrate,
                   const char *name, const char *title)
{
    Init(name, title);

    fSpecIndex=0.0;         // dn/dE = k * e^{- fSpecIndex}
    fFlux0=-1.0;            // dn/dE = fFlux0 * E^{-a}

    fShowRate= showrate;               // Showers rate in Hz
    fShowRateError=sqrt(showrate);     // Estimated error of shower rate in Hz
}

// --------------------------------------------------------------------------
//
//  overloaded constructor I
//  fills all member data with initial values and sets the
//  spectral index and the initial flux to SpecIndex and Flux0
//
MHMcRate::MHMcRate(Float_t specindex, Float_t flux0,
                   const char *name, const char *title)
{
    Init(name, title);

    fSpecIndex=specindex;   // dn/dE = k * e^{- fSpecIndex}
    fFlux0=flux0;           // dn/dE = fFlux0 * E^{-a}

    fShowRate= -1.0;
    fShowRateError=0.0;
}

// --------------------------------------------------------------------------
//
//  set the particle that produces the showers in the athmosphere
//
void MHMcRate:: SetParticle(UShort_t part)
{
    fPartId=part;
}

// --------------------------------------------------------------------------
//
//  Set the information about trigger due only to the background conditions
//
void MHMcRate::SetBackground (Float_t showers, Float_t triggers)
{
    fBackTrig=showers;      // Number of triggers from background
    fBackSim=triggers;      // Number of simulated showers for the background
}

// --------------------------------------------------------------------------
//
//  update the limits for energy, theta, phi and impact parameter
//
void MHMcRate::Boundaries(Float_t energy, Float_t theta,
                          Float_t phi, Float_t impact)
{ 
  // It updates the limit values 

  if (fThetaMax<theta) fThetaMax=theta;
  if (fThetaMin>theta) fThetaMin=theta;

  if (fPhiMax<phi) fPhiMax=phi;
  if (fPhiMin>phi) fPhiMin=phi;

  if (fImpactMax<impact) fImpactMax=impact;
  if (fImpactMin>impact) fImpactMin=impact;

  if (fEnergyMax<energy) fEnergyMax=energy;
  if (fEnergyMin>energy) fEnergyMin=energy;

} 

// --------------------------------------------------------------------------
//
//  compute the trigger rate
//
void MHMcRate::CalcRate(Float_t trig, Float_t anal, Float_t simu) 
{ 
    // It computes the trigger rate

    // First one computes the rate of incident showers.
    const Double_t specidx = 1.0-fSpecIndex;

    const Double_t epowmax = pow(fEnergyMax, specidx);
    const Double_t epowmin = pow(fEnergyMin, specidx);

    fShowRate = fFlux0/specidx*(epowmax-epowmin);

    if (fPartId!=1)
        fShowRate *= (fPhiMax-fPhiMin)*(cos(fThetaMax)-cos(fThetaMin));

    const Double_t impactdiff = fImpactMax-fImpactMin;

    fShowRate *= TMath::Pi()*(impactdiff/100.0*impactdiff/100.0);

    fShowRateError = sqrt(fShowRate);

    const Double_t anal2 = 1.0-anal*160.0e-9;
    const Double_t back2 = fBackSim*160.0e-9;

    // Then the trigger rate and its error is evaluated
    if(fBackTrig<0){
        fTrigRateError = sqrt((trig*fShowRate*fShowRate/(simu*simu)) +
                              (anal2*anal2*1/(fBackSim*back2*back2)));
        fBackTrig=0;
    }
    else
        fTrigRateError = sqrt((trig*fShowRate*fShowRate/(simu*simu)) +
                              (anal2*anal2*fBackTrig/(back2*back2)));

    fTrigRate = trig*fShowRate/simu + anal2*fBackTrig/back2;
}

// --------------------------------------------------------------------------
//
//  print the trigger rate
//
void MHMcRate::Print()
{
    *fLog << "Incident rate " << fShowRate << " Hz " << endl;
    *fLog << "Trigger Rate " << fTrigRate << " +- " << fTrigRateError << " Hz" << endl;
}

// --------------------------------------------------------------------------
//
//  draw the trigger rate
//
void MHMcRate::Draw(Option_t* option) 
{ 
  *fLog << "To be iplemented" << endl;
} 
