/*
 * DataQualCut.cpp
 *
 *  Created on: 10-mar-2009
 *      Author: S. Ricciarini, N. Mori, E. Mocchiutti
 */

/*! @file DataQualCut.cpp The DataQualCut class implementation file */

#include "DataQualCut.h"

Bool_t DataQualCut::CL1IsGood(CaloLevel1 *cl1, CaloLevel2 *cl2){
  //
  // variables
  //
  Int_t view = 0;
  Int_t plane = 0;
  Int_t strip = 0;
  Int_t sview = 0;
  Int_t splane = 0;
  Int_t sstrip = 0;
  Float_t mip = 0.;
  Int_t nstrip = 0;
  //
  // values in calolevel1 are stored following this order: view X first, view Y second / for each view from plane 0 to plane 21 / for each plane from strip 0 to strip 95
  // any incongruence in this order means that the CaloLevel1 event is corrupted
  // the nstrip calculated with CaloLevel1 (excluding plane 18X) must be equal to nstrip in CaloLevel2 (which is not affected by the bug)
  // if they don't match the CaloLevel1 event is corrupted
  // if the vector in CaloLevel1 is ordered and nstrip from CaloLevel1 and CaloLevel2 matches then the CaloLevel1 event can only be corrupted on the values of plane 18X
  // hence it is good if you are not using plane 18X
  //
  for (Int_t i=0; i<cl1->istrip; i++){
    mip=cl1->DecodeEstrip(i,view,plane,strip);
    if ( view < 0 || view > 1 ) return(false);
    if ( plane < 0 || plane > 21 ) return(false);
    if ( strip < 0 || strip > 95 ) return(false);
    if ( i > 0 ){
      if ( view < sview ) return(false);
      if ( view == sview ){
	if ( plane < splane ) return(false);
	if ( plane == splane ){
	  if ( strip <= sstrip ) return(false);
	};
      };
    };
    if ( !(view==0 && plane==18) ) nstrip++;
    sview = view;
    splane = plane;
    sstrip = strip;
  };
  if ( nstrip != cl2->nstrip ) return(false);
  return(true);
}

int DataQualCut::Check(PamLevel2 *event){

  // ++++++++++ TRK ++++++++++
  if ((_cutMask & TRK) == TRK) {
    if (event->GetTrkLevel2()) {
      for (Int_t i=0; i<12; i++) { // check done for each DSP    
        if (!event->GetTrkLevel2()->StatusCheck(i,0x12)) { // decode error OR CRC error
          return TRK;
        }
      }
    }
    else {
      return TRK;
    }
  }
  
  // ++++++++++ CALO LEVEL 2 ++++++++++
  if ((_cutMask & CALO) == CALO) {
    if (event->GetCaloLevel2()) {
      if (!event->GetCaloLevel2()->IsGood(true)) {
        return CALO;
      }
    }
    else {
      return CALO;
    }
  }

  // ++++++++++ CALO LEVEL 1 ++++++++++
  if ((_cutMask & CALO_L1) == CALO_L1) {
    if (! (event->GetCaloLevel1() ) ) {
      return CALO;
    }
    if (! CL1IsGood(event->GetCaloLevel1(),event->GetCaloLevel2()) ){
      return CALO;
    }
  }
  
  // ++++++++++ TOF ++++++++++
  if ((_cutMask & TOF) == TOF) {
    if (event->GetToFLevel2()) {
      if (event->GetToFLevel2()->unpackError) { // "unpackerror" here means "unpackerror !=0"
        return TOF;
      }
    }
    else {
      return TOF;
    }
  }
  
  // ++++++++++ ANT ++++++++++
  if ((_cutMask & ANT) == ANT) {
    if (event->GetAcLevel2()) {
      if (event->GetAcLevel2()->unpackError || ((event->GetAcLevel2()->status[0] >> 2) & 1)
          || ((event->GetAcLevel2()->status[1] >> 2) & 1)) {
        //cout << "ANT" << endl;
        return ANT;
      }
    }
    else {
      return ANT;
    }
  }
  
  // ++++++++++ TRG ++++++++++
  if ((_cutMask & TRG) == TRG) {
    if (event->GetTrigLevel2()) {
      if (event->GetTrigLevel2()->unpackError) {
        return TRG;
      }
    }
    else {
      return TRG;
    }
  }

  // ++++++++++ ND ++++++++++
  if ((_cutMask & ND) == ND) {
    if (event->GetNDLevel2()) {
      if (event->GetNDLevel2()->unpackError) {
        //cout << "ND" << endl;
        return ND;
      }
    }
    else {
      //cout << "ND" << endl;
      return ND;
    }
  }
  
  // ++++++++++ ORB ++++++++++
  if ((_cutMask & ORB) == ORB) {
    if (!event->GetOrbitalInfo()) {
      return ORB;
    }
  }
  
  return CUTOK;
}
