#include "MMcEvt.hxx"

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

//==========
// MMcEvt
//    
// This class handles and contains the MonteCarlo information
// with which the events have been generated
// This information exists for each event.
//
// Note: All the azimuth Phi angles in this and other MC classes follow
// the convention in the Corsika program (see Corsika manual). There, phi
// is the azimuth of the momentum vector of particles, and is measured
// from the north direction, anticlockwise (i.e, west is phi=90 degrees).
// When it refers to the telescope orientation, it is the azimuth of a 
// vector along the telescope axis, going from the camera to the mirror. 
// So, fTelescopeTheta=90, fTelescopePhi = 0 means the telescope is 
// pointing horizontally towards South. For an explanation, see also 
// TDAS 02-11. 
//
ClassImp(MMcEvt);

using namespace std;


MMcEvt::MMcEvt()
{
    //
    //  default constructor
    //  set all values to zero
    fName  = "MMcEvt";
    fTitle = "Event info from Monte Carlo";

    Clear();
}

MMcEvt::MMcEvt( UInt_t  fEvtNum,
		UShort_t usPId,
		Float_t  fEner,
		Float_t  fThi0,
		Float_t  fFirTar,
		Float_t  fzFirInt,
		Float_t  fThet, 
		Float_t  fPhii, 
		Float_t  fCorD, 
		Float_t  fCorX, 
		Float_t  fCorY,
		Float_t  fImpa,
		Float_t  fTPhii,
		Float_t  fTThet,
		Float_t  fTFirst,
		Float_t  fTLast,
		Float_t  fL_Nmax,
		Float_t  fL_t0,
		Float_t  fL_tmax,
		Float_t  fL_a,
		Float_t  fL_b,
		Float_t  fL_c,
		Float_t  fL_chi2,
		UInt_t   uiPin, 
		UInt_t   uiPat,  
		UInt_t   uiPre, 
		UInt_t   uiPco,  
		UInt_t   uiPelS,
		UInt_t   uiPelC,
		Float_t  elec,
		Float_t  muon,
		Float_t  other,
		Float_t  fadc_jitter) {

    fName  = "MMcEvt";
    fTitle = "Event info from Monte Carlo";
  //
  //  constuctor II 
  //
  //  All datamembers are parameters. 
  //
  //  Don't use this memberfunction in analysis
  //  

  fEvtNumber = fEvtNum;
  fPartId = usPId  ;
  fEnergy  = fEner  ;
  fThick0 = fThi0;
  fFirstTarget = fFirTar;
  fZFirstInteraction = fzFirInt;

  fTheta   = fThet ;
  fPhi     = fPhii ;

  fCoreD   = fCorD ;
  fCoreX   = fCorX ;
  fCoreY   = fCorY ;
  fImpact  = fImpa ;

  fTelescopePhi = fTPhii;
  fTelescopeTheta = fTThet;
  fTimeFirst = fTFirst;
  fTimeLast = fTLast;
  fLongiNmax = fL_Nmax;
  fLongit0 = fL_t0;
  fLongitmax = fL_tmax;
  fLongia = fL_a;
  fLongib = fL_b;
  fLongic = fL_c;
  fLongichi2 = fL_chi2;


  fPhotIni      = uiPin ;
  fPassPhotAtm  = uiPat ;
  fPassPhotRef  = uiPre ;
  fPassPhotCone = uiPco ;
  fPhotElfromShower = uiPelS ;
  fPhotElinCamera   = uiPelC ;

  fElecCphFraction=elec;
  fMuonCphFraction=muon;
  fOtherCphFraction=other;

  fFadcTimeJitter = fadc_jitter;
}



MMcEvt::~MMcEvt() {
  //
  //  default destructor
  //
}




void MMcEvt::Clear(Option_t *opt)
{
    //
    //  reset all values to values as nonsense as possible
    //
    fPartId = 0;
    fEnergy = -1;

    fTheta = 0;
    fPhi   = 0;

    fCoreD  =  0;
    fCoreX  =  0;
    fCoreY  =  0;
    fImpact = -1;

    fPhotIni          = 0;
    fPassPhotAtm      = 0;
    fPassPhotRef      = 0;
    fPassPhotCone     = 0;
    fPhotElfromShower = 0;
    fPhotElinCamera   = 0;

    fElecCphFraction=0;
    fMuonCphFraction=0;
    fOtherCphFraction=0;
}

void MMcEvt::Fill( UInt_t  fEvtNum,
		   UShort_t usPId, 
		   Float_t  fEner, 
		   Float_t  fThi0,
		   Float_t  fFirTar,
		   Float_t  fzFirInt,
		   Float_t  fThet, 
		   Float_t  fPhii, 
		   Float_t  fCorD, 
		   Float_t  fCorX, 
		   Float_t  fCorY,
		   Float_t  fImpa, 
		   Float_t  fTPhii,
		   Float_t  fTThet,
		   Float_t  fTFirst,
		   Float_t  fTLast,
		   Float_t  fL_Nmax,
		   Float_t  fL_t0,
		   Float_t  fL_tmax,
		   Float_t  fL_a,
		   Float_t  fL_b,
		   Float_t  fL_c,
		   Float_t  fL_chi2,
		   UInt_t   uiPin, 
		   UInt_t   uiPat,  
		   UInt_t   uiPre, 
		   UInt_t   uiPco,  
		   UInt_t   uiPelS,  
		   UInt_t   uiPelC,
		   Float_t  elec,
		   Float_t  muon,
		   Float_t  other,
		   Float_t  fadc_jitter) {
  //
  //  All datamembers are filled with the correspondin parameters. 
  //
  //  Don't use this memberfunction in analysis
  //  

  fEvtNumber = fEvtNum;
  fPartId = usPId  ;
  fEnergy = fEner  ;
  fThick0 = fThi0;
  fFirstTarget = fFirTar;
  fZFirstInteraction = fzFirInt;

  fTheta  = fThet ;
  fPhi    = fPhii ;

  fCoreD  = fCorD ;
  fCoreX  = fCorX ;
  fCoreY  = fCorY ;
  fImpact = fImpa ;

  fTelescopePhi = fTPhii;
  fTelescopeTheta = fTThet;
  fTimeFirst = fTFirst;
  fTimeLast = fTLast;
  fLongiNmax = fL_Nmax;
  fLongit0 = fL_t0;
  fLongitmax = fL_tmax;
  fLongia = fL_a;
  fLongib = fL_b;
  fLongic = fL_c;
  fLongichi2 = fL_chi2;

  fPhotIni      = uiPin ;
  fPassPhotAtm  = fPhotIni-uiPat ;
  fPassPhotRef  = fPassPhotAtm-uiPre ;
  fPassPhotCone = uiPco ;
  fPhotElfromShower = uiPelS ;
  fPhotElinCamera = uiPelC ;

  fElecCphFraction=elec;
  fMuonCphFraction=muon;
  fOtherCphFraction=other;

  fFadcTimeJitter = fadc_jitter;
}

/*
void MMcEvt::AsciiWrite(ofstream &fout) const
{
    fout << fEnergy << " ";
    fout << fTheta ;
}
*/

// --------------------------------------------------------------------------
//
// Print the contents of the container.
//
//  if you specify an option only the requested data members are printed:
//  allowed options are:
//   id, energy, impact
//
void MMcEvt::Print(Option_t *opt) const
{
    //
    //  print out the data member on screen
    //
    TString str(opt);
    if (str.IsNull())
    {
        *fLog << all << endl;
        *fLog << "Monte Carlo output:" << endl;
        *fLog << " Particle Id:    ";
        switch(fPartId)
        {
        case kGAMMA:
            *fLog << "Gamma" << endl;
            break;
        case kPROTON:
            *fLog << "Proton" << endl;
            break;
        case kHELIUM:
            *fLog << "Helium" << endl;
            break;
        }
        *fLog << " Energy:         " << fEnergy << "GeV" << endl;
        *fLog << " Impactpar.:     " << fImpact/100 << "m" << endl;
        *fLog << " Photoelectrons: " << fPhotElfromShower << endl;
        *fLog << endl;
        return;
    }
    if (str.Contains("id", TString::kIgnoreCase))
        switch(fPartId)
        {
        case kGAMMA:
            *fLog << "Particle: Gamma" << endl;
            break;
        case kPROTON:
            *fLog << "Particle: Proton" << endl;
            break;
        case kHELIUM:
            *fLog << "Particle: Helium" << endl;
            break;
        }
    if (str.Contains("energy", TString::kIgnoreCase))
        *fLog << "Energy: " << fEnergy << "GeV" << endl;
    if (str.Contains("impact", TString::kIgnoreCase))
        *fLog << "Impact: " << fImpact << "cm" << endl;
}
