#include "MRawEvt.h"

#include <iostream.h>
#include <stdlib.h>

#include "TString.h"
#include "TRandom.h"

#include "MRawPixel.h"

//==========
// MRawEvt 
//    
// One Event is a sample of FADC measurements of different Pixels 
// (Photomultipliers) from the Camera of MAGIC. So all data (FADC) of the 
// interesting pixels are the modules of an event. To describe pixels the 
// class MRawPixel is used.  To define a single events
// some other data members are needed (Time of the events, kind of event..).
//
// To describe one event on the level of FADC values the Class MRawEvt is
// created. It has the following data members: 
//
// ----------
//
// UInt_t    EvtNo    
//
// This it the number of the Event in one 
// data run. The first event in this run get
// the number zero. The next one is one bigger.
//
// Assuming that one run takes 1 hour and a
// triggerrate of 1kHz the number must be able
// to reach 3.6e6 Events. To reach this number
// you need at least 22 bits. This is the reason
// why we use an integer (of root type UInt_t)
// with a range to 4.2e9. 
//
// ----------
//
// ULong_t   fTimeStamp
//   
// Time of the event. 
// The start point of the time determination can be
// the millenium. From that start point the time is
// measured in 200ns-count. One day for example
// contains 432.e9 counts. An unsigned Long is able to 
// contain 1.8e19 200ns-counts. This corresponds to 41.e6
// days. This should be more than the livetime of MAGIC.
//
// ----------
//
// UChar_t   EvtStatus 
//
// Status of Event. 
// This is a Byte (8 bit) to indicated the status of 
// the event (Pedestal, Calibration, etc). 
//
// ----------
//
// UShort_t  Trig1st
//
// Number of first level trigger
// This member counts the number of First Level Trigger
// between the last and this event. May be that due to 
// dead time of the DAQ this number is different from 1.
// If the DAQ is fast enough, this value should be 1. 
// This may be usefull in GammaRayBursts and if we 
// apply a data reduction in the DAQ-chain, which selects
// only good events. 
//
// ----------
//
// UShort_t  MultPixel
//
// Multiplicity of Pixels
// Each event consists of a specific number of 
// pixels. This is the number of pixels in one event. 
// The array of ClonesPixels (taClonesArray) is of this
// size. 
//
// ----------
//
// TClonesArray  *Pixels
//
// Array of Pixels 
// The Clones array is a list of the Pixels used in one
// event with the information about the Pixels. 
//
//

//

ClassImp(MRawEvt)

MRawEvt::MRawEvt(const char *name, const char *title) : MParContainer(name, title)
{
    //
    //   Implementation of the default constructor
    //
    //   set all member to zero, init the pointer to ClonesArray,

    EvtNo       = 0 ;
    fTimeStamp  = 0 ;
    EvtStatus   = 0 ;
    Trig1st     = 0 ;
    MultPixel   = 0 ;

    //
    //   Then we have to initialize the ClonesArray list for the Pixels.
    //   This is neccessary once!
    //
    //   initialize the list to this global pointer

    Pixels = new TClonesArray ("MRawPixel", 2*kCAMERA_PIXELS ) ;

    //  cout << " default constructor " << endl ;
}


MRawEvt::~MRawEvt()
{
    //
    //   Implementation of the default destructor
    //
    delete Pixels ;
    //  cout << " default destructor " << endl ;
}

void MRawEvt::GetFadcNoise ( UChar_t asF[] )
{
    static TRandom Gen ;
    static Float_t z1, z2 ;
    for (Int_t i=0; i<kFADC_SLICES; i++ )
    {
        Gen.Rannor(z1, z2) ;
        asF[i] = 10 + (UChar_t)(z1*4) ;
        // if (asF[i] < 0 ) asF[i] = 0 ;
    }
}

void MRawEvt::Clear(Option_t *t)
{
    //
    //   Implementation of the Clear function
    //
    //   Resets all members to zero, clear the list of Pixels
    //
    EvtNo      = 0 ;
    fTimeStamp = 0 ;
    EvtStatus  = 0 ;
    Trig1st    = 0 ;
    MultPixel  = 0 ;

    Pixels->Clear() ;
}

void MRawEvt::Print(Option_t *t)
{
    //
    //  This member function prints all Data of one Event on screen.
    //

    // Prints out the data of one Pixel
    cout << endl << "EventNumber      " << EvtNo          ;
    cout << endl << "Event Time Stamp " << fTimeStamp      ;
    cout << endl << "Event Status     " << (int) EvtStatus      ;
    cout << endl << "Trigger 1. Level " << Trig1st        ;
    cout << endl << "Number of Pixels " << MultPixel      ;

    for (Int_t i=0 ; i<MultPixel; i++ )
    {
        ((MRawPixel *)Pixels->At(i))->Print() ;
    }
}

Int_t MRawEvt::GetPixelId(Int_t iList)
{
    //
    //  returns the pixelId of the iList.th Pixels in the pixels list
    //

    if (iList < MultPixel)
    {
        return (Int_t )  ((MRawPixel *)Pixels->At(iList))->GetPixelId() ;
    }
    else
    {
        cout << "ERROR: MRawEvt::GetPixelId:  iList is bigger than MultPixel"
            << endl ;
        exit(1);
    }
    return 0;
}

UChar_t* MRawEvt::GetPixelData(Int_t iList)
{
    //
    //  returns the pointer to the data of the iList.th pixel in
    //  the pixel list.
    //

    if ( iList < MultPixel )
    {
        return (UChar_t*)  ((MRawPixel *)Pixels->At(iList))->GetPixelData() ;
    }
    else
    {
        cout << "ERROR: MRawEvt::GetPixelId:  iList is bigger than MultPixel"
            << endl ;
        exit(1) ;
    }
    return 0;
}


void MRawEvt::FillRandom ( UInt_t uiN, ULong_t ulT,  UShort_t usMuPi )
{
    //
    //  This is neccessary to fill the MRawEvt Class with randomized FADC
    //  values. The EventNumber, EventTime and the Number of Pixels are given
    //  as parameters.
    //

    EvtNo      = uiN ;
    fTimeStamp  = ulT ;

    UChar_t   ucA[kFADC_SLICES] ;

    for (UShort_t i = 0 ; i< usMuPi; i++ )
    {
        GetFadcNoise ( ucA ) ;

        TClonesArray &caP = *Pixels ;
        new ( caP[MultPixel++] ) MRawPixel((MultPixel), 0, ucA) ;
    }
}

void MRawEvt::FillHeader ( UInt_t uiN, ULong_t ulT, UChar_t ucSta )
{
   
  EvtNo      = uiN;
  fTimeStamp = ulT;
  
  EvtStatus  = ucSta;
  Trig1st    = 0;
  MultPixel  = 0;

  Pixels->Clear();
}

void MRawEvt::FillPixel ( UShort_t uiPix, Float_t *array )
{
  //
  //  This is to fill the data of one pixel to the MRawEvt Class. 
  //  The parameters are the pixelnumber and the FADC_SLICES values of ADCs
  // 

  UChar_t   ucA[kFADC_SLICES] ;

  for (UShort_t i = 0 ; i< kFADC_SLICES ; i++ )
  {
    ucA[i] = (UShort_t) array[i] ; 
  } 
  
  TClonesArray &caP = *Pixels ;
  new ( caP[MultPixel++] ) MRawPixel((uiPix), 0, ucA) ; 
}

void MRawEvt::FillMontCarl ( UInt_t uiN, ULong_t ulT,  Float_t *array )
{
  //
  //  This is neccessary to fill the MRawEvt Class with randomized FADC
  //  values. The EventNumber, EventTime and the Number of Pixels are given 
  //  as parameters. 
  // 

  EvtNo      = uiN ; 
  fTimeStamp  = ulT ; 

  MultPixel = 0 ; 

  UChar_t   ucA[kFADC_SLICES] ;

  for (UShort_t i = 0 ; i< kCAMERA_PIXELS; i++ )
  {
      if ( array[i] > 0. )
      {
          for ( Int_t ii = 0 ; ii < kFADC_SLICES ; ii++ )
          {
              ucA[ii] = 0 ;
          }
          ucA[5] = (UShort_t) (array[i]) ;

          TClonesArray &caP = *Pixels ;
          caP[MultPixel++] = new MRawPixel(i, 0, ucA);
      }
  }
}

UShort_t MRawEvt::GetMultPixel()
{
  //
  //  returns the pixel multiplicity of the Event
  //
  return MultPixel;
}


