//
// Caryatid.cxx
//
//                    by Anatael Cabrera <anatael.cabrera@physics.ox.ac.uk>
#define Caryatid_cxx

#include <TMath.h>
#include <Caryatid.h>

using namespace std;

CVSID("$Id: Caryatid.cxx,v 1.3 2007/02/12 15:58:30 asousa Exp $");

//Setting DEFAULT values for configuration variables:
Int_t  Caryatid::fSparsFactor = 5;
Int_t  Caryatid::fTruncFactor = 5;
Int_t  Caryatid::fTruncFlag   = 2;

const Int_t Caryatid::CRATEMAX;
const Int_t Caryatid::VARCMAX;
const Int_t Caryatid::VMMMAX;
const Int_t Caryatid::VFBMAX;
const Int_t Caryatid::VAMAX;
const Int_t Caryatid::VACHMAX;

const Int_t Caryatid::TRTHRPMT;
const Int_t Caryatid::TRTHRLGPIN;
const Int_t Caryatid::TRTHRHGPIN;

//-------------------------------------------------------------

Caryatid::Caryatid() { 
  MSG("Caryatid",Msg::kDebug) << "Caryatid constructing..." << endl;

  fcrate = -1;
  fvarc  = -1;
  fvmm   = -1;
  fvfb   = -1;
  fva    = -1;
  fvach  = -1;

  fplane = -1;

  fnumPointsT1 = -1;
  fnumPointsT2 = -1;
  fnumPointsRaw = -1;

  //ftime = -1;
  
  frawMean   = -1;
  frawRms    = -1;

  fmeanTruc1  = -1;
  frmsTrunc1  = -1;
  ftruncthrT1 = -1;

  fmeanTruc2 = -1;
  frmsTrunc2 = -1;

  ferror = -1;

  //fpedDaq    = -1;
  //fsparThDaq = -1;

  //fdeltaSpars = -1;
  //fdeltaPed   = -1;

  MSG("Caryatid",Msg::kDebug) << "Caryatid constructed!" << endl;
}

//-------------------------------------------------------------

Caryatid::~Caryatid() {
  MSG("Caryatid",Msg::kDebug) << "Destructing Caryatid" << endl;
}

//-------------------------------------------------

Bool_t Caryatid::SparsifiedChannel() {

    //Fully sparsifying the following channels - 

    //Unused channel:
    if(fvach==0) return true;
    if(fvach==18 && fva==2) return true;
    if(fcrate==2 && fvarc==0 && fvmm==5 && fvfb==1 && fva!=0) return true;
    if(fcrate==4 && fvarc==0 && fvmm==5 && fvfb==1 && fva!=0) return true;
    return false;
}

//-------------------------------------------------

Bool_t Caryatid::IsLGPIN() {

  if(fvach==18 && fva==0 ) return true;
  return false;
}

//-------------------------------------------------

Bool_t Caryatid::IsHGPIN() {

  if(fvach==18 && fva==1 ) return true;
  return false;
}

//-------------------------------------------------

Bool_t Caryatid::IsTPMTchannel() {

  if(fcrate==1 && fvarc==2 && fvmm==5 && fva==1) return true;
  return false;

}

//-------------------------------------------------

Bool_t Caryatid::IsCMchannel() {

  if(fvach==1 || fvach==19 || fvach==20 || fvach==21 ) return true;
  return false;
}

//-------------------------------------------------------------

void Caryatid::AddressMe(const Int_t crate,
			     const Int_t varc,
			     const Int_t vmm,
			     const Int_t vfb,
			     const Int_t va,
			     const Int_t vach ) {
  fcrate = crate;
  fvarc  = varc;
  fvmm   = vmm;
  fvfb   = vfb;
  fva    = va;
  fvach  = vach;
}

//-------------------------------------------------------------
  
Bool_t  Caryatid::AreYouAt(const Int_t crate,
			       const Int_t varc,
			       const Int_t vmm,
			       const Int_t vfb,
			       const Int_t va,
			       const Int_t vach ) {

  if(crate==fcrate && varc==fvarc && vmm==fvmm && vfb==fvfb && va==fva && vach==vach)
    return true;
  else return false;
}

//-------------------------------------------------------------

void Caryatid::GetSTAT() {

  if(fSPentries_v.size()<=0) {
    MSG("Caryatid",Msg::kError) << "ERROR: No pedestal data has been input for this channel" << endl;
    return;  
  }

  MSG("Caryatid",Msg::kDebug) << "Entries: " << fSPentries_v.size() << endl;

  //Raw pedestal Info:
  fnumPointsRaw = this->GetInfoRaw();

  switch(fTruncFlag) {
  case 0:
    break;
  case 1:
    //Get Pedestal info with truncation 1:
    fnumPointsT1 = this->GetInfoTrunc1();
    break;
  case 2:
    //Get Pedestal info with truncation 2:
    fnumPointsT2 = this->GetInfoTrunc2();
    break;
  }
  return;
}

//-------------------------------------------------------------
  
Int_t Caryatid::GetInfoRaw() {

  Int_t rawSum   = 0;
  Int_t rawSumSq = 0;

  Int_t counterRaw = 0;

  //Iterate over the entries in the map:
  vector<Short_t>::iterator iterPedestal = fSPentries_v.begin();

  while(iterPedestal != fSPentries_v.end()) {

    rawSum   += (*iterPedestal);
    rawSumSq += (*iterPedestal)*(*iterPedestal);
    counterRaw++;

    iterPedestal++;
  } //End of the LOOP

  if(counterRaw != 0) {
    frawMean = (Float_t) rawSum  / (Float_t) counterRaw;
    
    frawRms  = (Float_t) rawSumSq/ (Float_t) counterRaw;
    frawRms -= pow(frawMean,2);
    frawRms  = sqrt(TMath::Abs(frawRms));
  }

  MSG("Caryatid",Msg::kDebug) << "Raw: " << frawMean << "-" 
				  << frawRms << "-" << counterRaw << endl;
  return counterRaw;
}


//-------------------------------------------------------------

Int_t Caryatid::GetInfoTrunc1() {

  Int_t sumT1     = 0;
  Int_t sumSqT1   = 0;
  Int_t counterT1 = 0;

  ftruncthrT1 = frawRms * fTruncFactor;

  //Iterate over the entries in the map:
  vector<Short_t>::iterator iterPedestal = fSPentries_v.begin();

  while(iterPedestal!=fSPentries_v.end()) {

    if(TMath::Abs((*iterPedestal)-frawMean)<ftruncthrT1) { //Truncation here.

      sumT1   += (*iterPedestal);
      sumSqT1 += (*iterPedestal)*(*iterPedestal);
      counterT1++;
    }
    iterPedestal++;
  } //End of the LOOP
  
  if(counterT1 != 0) {
    fmeanTruc1 = (Float_t) sumT1  / (Float_t) counterT1;
    
    frmsTrunc1  = (Float_t) sumSqT1/ (Float_t) counterT1;
    frmsTrunc1 -= pow(fmeanTruc1,2);
    frmsTrunc1  = sqrt(TMath::Abs(frmsTrunc1));
  }

  MSG("Caryatid",Msg::kDebug) << "T1: " << fmeanTruc1 
				  << "-" << frmsTrunc1 << "-" << counterT1 << endl;

  return counterT1;
}

//-------------------------------------------------------------

Int_t Caryatid::GetInfoTrunc2() {

  Int_t sumT2     = 0;
  Int_t sumSqT2   = 0;
  Int_t counterT2 = 0;

  //Iterate over the entries in the map:
  vector<Short_t>::iterator iterPedestal = fSPentries_v.begin();

  while(iterPedestal!=fSPentries_v.end()) {
    
    if(TMath::Abs((*iterPedestal) - frawMean) < this->GetTrThresholdT2() ) {
      sumT2   += (*iterPedestal);
      sumSqT2 += (*iterPedestal)*(*iterPedestal);
      counterT2++;
    }
    iterPedestal++;
  } //End of the LOOP

  if(counterT2 != 0) {
    fmeanTruc2 = (Float_t) sumT2  / (Float_t) counterT2;
    
    frmsTrunc2  = (Float_t) sumSqT2/ (Float_t) counterT2;
    frmsTrunc2 -= pow(fmeanTruc2,2);
    frmsTrunc2  = sqrt(TMath::Abs(frmsTrunc2));
  }

  MSG("Caryatid",Msg::kDebug) << "T2: " << fmeanTruc2 << "-" 
				  << frmsTrunc2 << "-" << counterT2 << endl;

  return counterT2;
}

//-------------------------------------------------------------

Int_t Caryatid::GetIDKey() {

  Int_t key = VACHMAX*fva+fvach;
  key      += VACHMAX*VAMAX*fvfb;
  key      += VACHMAX*VAMAX*VFBMAX*fvmm;
  key      += VACHMAX*VAMAX*VFBMAX*VMMMAX*fvarc;
  key      += VACHMAX*VAMAX*VFBMAX*VMMMAX*VARCMAX*fcrate;
  
  return key;
}


//-------------------------------------------------------------

Int_t Caryatid::EncriptMeAKey(const Int_t crate,
				  const Int_t varc,
				  const Int_t vmm,
				  const Int_t vfb,
				  const Int_t va,
				  const Int_t vach ){
  Int_t key = VACHMAX*va+vach;
  key      += VACHMAX*VAMAX*vfb;
  key      += VACHMAX*VAMAX*VFBMAX*vmm;
  key      += VACHMAX*VAMAX*VFBMAX*VMMMAX*varc;
  key      += VACHMAX*VAMAX*VFBMAX*VMMMAX*VARCMAX*crate;
  
  return key;
}

//EOF
