/*
 * TofDedxHCut.cpp
 *
 *  Created on: 5 apr 2011
 *      Author: Nicola Mori
 */

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

#include "TofDedxHCut.h"

const float TofDedxHCut::_S11_SA_params[] = { 1.5, 1.2, -0.15, -2., 0.8, 1.6, 1.2, -0.2, 0., 0.8 };
const float TofDedxHCut::_S12_SA_params[] = { 1.5, 1.2, -0.15, -2., 0.8, 1.6, 1.2, -0.2, 0., 0.8 };
const float TofDedxHCut::_S21_SA_params[] = { 1.6, 1.2, -0.15, -2., 0.8, 1.6, 1.2, -0.2, 0., 0.8 };
const float TofDedxHCut::_S22_SA_params[] = { 1.6, 1.2, -0.15, -2., 0.8, 1.6, 1.2, -0.2, 0., 0.8 };
const float TofDedxHCut::_S31_SA_params[] = { 1.6, 1.2, -0.15, -2., 0.8, 1.6, 1.2, -0.2, 0., 0.8 };
const float TofDedxHCut::_S32_SA_params[] = { 1.6, 1.2, -0.15, -2., 0.8, 1.6, 1.2, -0.2, 0., 0.8 };

const float TofDedxHCut::_S11_SA_params_strict[] = { 1.5, 1.2, -0.15, -1.7, 0.8, 1.6, 1.2, -0.2, -0.8, 0.8 };
const float TofDedxHCut::_S12_SA_params_strict[] = { 1.5, 1.2, -0.15, -1.7, 0.8, 1.6, 1.2, -0.2, -0.8, 0.8 };
const float TofDedxHCut::_S21_SA_params_strict[] = { 1.6, 1.2, -0.15, -1.7, 0.8, 1.6, 1.2, -0.2, -0.8, 0.8 };
const float TofDedxHCut::_S22_SA_params_strict[] = { 1.6, 1.2, -0.15, -1.7, 0.8, 1.6, 1.2, -0.2, -0.8, 0.8 };
const float TofDedxHCut::_S31_SA_params_strict[] = { 1.6, 1.2, -0.15, -1.7, 0.8, 1.6, 1.2, -0.2, -0.8, 0.8 };
const float TofDedxHCut::_S32_SA_params_strict[] = { 1.6, 1.2, -0.15, -1.7, 0.8, 1.6, 1.2, -0.2, -0.8, 0.8 };

TofDedxHCut::TofDedxHCut(const char *cutName, unsigned int layer, bool standAlone, bool strict) :
    PamCut(cutName), _layer(layer), _standAlone(standAlone), _p(NULL) {

  if (strict) {
    switch (_layer) {
    case S11:
      _p = _S11_SA_params_strict;
      break;
    case S12:
      _p = _S12_SA_params_strict;
      break;
    case S21:
      _p = _S21_SA_params_strict;
      break;
    case S22:
      _p = _S22_SA_params_strict;
      break;
    case S31:
      _p = _S31_SA_params_strict;
      break;
    case S32:
      _p = _S32_SA_params_strict;
      break;
    default:
      _p = _S21_SA_params_strict;
    }
  }
  else {
    switch (_layer) {
    case S11:
      _p = _S11_SA_params;
      break;
    case S12:
      _p = _S12_SA_params;
      break;
    case S21:
      _p = _S21_SA_params;
      break;
    case S22:
      _p = _S22_SA_params;
      break;
    case S31:
      _p = _S31_SA_params;
      break;
    case S32:
      _p = _S32_SA_params;
      break;
    default:
      _p = _S21_SA_params;
    }
  }
}

int TofDedxHCut::Check(PamLevel2 *event) {

  static int trkSeqNo;
  static int idx;
  if (_standAlone)
    trkSeqNo = -1;
  else
    trkSeqNo = event->GetTrack(0)->GetTrkTrack()->GetSeqNo();

  for (int i = 0; i < event->GetToFLevel2()->ntrk(); i++) {
    if (event->GetToFLevel2()->GetToFTrkVar(i)->trkseqno == trkSeqNo)
      idx = i;
  }

  float beta = event->GetToFLevel2()->GetToFTrkVar(idx)->beta[12];

  static unsigned int auxLayer;
  static float dEdx;
  static unsigned int currLayer;
  static unsigned int nLayers;

  auxLayer = _layer;
  dEdx = 0;
  currLayer = 0;
  nLayers = 0;
  while (auxLayer > 0) {
    if ((auxLayer & 0x1) == 1) {
      dEdx += event->GetToFLevel2()->GetdEdx(idx, currLayer, 100);
      nLayers++;
      // Patch to exclude S115b
      if (currLayer == 0) {
        ToFTrkVar *tofTrk = event->GetToFLevel2()->GetToFTrkVar(idx);
        bool has8 = false, has9 = false;
        float dedx9 = 0.;
        for (Int_t ib = 0; ib < tofTrk->npmtadc; ib++) {
          if (tofTrk->pmtadc[ib] == 8) {
            has8 = true;
          }
          if (tofTrk->pmtadc[ib] == 9) {
            has9 = true;
            dedx9 = tofTrk->dedx[ib];
          }
        }

        if (has9) {
          dEdx -= (dedx9 / ((int) has8 + 1));
          dEdx *= 2.;
        }
      }
      //End of patch
    }
    currLayer++;
    auxLayer >>= 1;
  }

  dEdx /= nLayers;

  if (dEdx < _p[0] / (_p[1] * beta + _p[2]) + _p[3] + _p[4] * beta)
    return 0;

  if (dEdx > _p[5] / (_p[6] * beta + _p[7]) + _p[8] + _p[9] * beta)
    return 0;

  return CUTOK;
}
