/*
 * CommonDefs.h
 *
 *  Created on: 10-mar-2009
 *      Author: Nicola Mori
 */

/*! @file CommonDefs.h A header file with all the common definitions for the PamCut framework.
 */

#ifndef COMMONDEFS_H_
#define COMMONDEFS_H_

/*! @brief The implementations of PamCut::Check() must return this value if the event satisfy the cut*/
const int CUTOK = -1;

const float POSITIVE = 1.0; ///< Positive sign alias
const float NEGATIVE = -1.0; ///< Negative sign alias

/*! @enum DETECTORCODE
 * The values for each detector correspond to a binary code associated to that detector.
 * These can be arithmetically added to create a binary code for a set of detectors.
 */
enum DETECTORCODE {
  TRK = 1, ///< Code for Tracker
  CALO = 2, ///< Code for Calorimeter level2
  TOF = 4, ///< Code for ToF
  ANT = 8, ///< Code for AntiCoincidence
  TRG = 16, ///< Code for Trigger
  ORB = 32, ///< Code for Orbital Info
  DEFAULT = 63, ///< TRK, CALO, TOF, ANT, TRG, ORB
  ND = 64, ///< Code for Neutron Detector
  CALO_L1 = 128
///< Code for Calorimeter level1
};

/*! @enum TOFLAYERS Flags to identify TOF layers. */
enum TOFLAYERS {
  S11 = 1, ///< S11.
  S12 = 2, ///< S12.
  S21 = 4, ///< S21.
  S22 = 8, ///< S22.
  S31 = 16, ///< S31.
  S32 = 32
///< S32.
};

/*! @enum TRKLAYERS Flags to identify Tracker layers. */
enum TRKLAYERS {
  T1X = 1, ///< T1X.
  T2X = 2, ///< T2X.
  T3X = 4, ///< T3X.
  T4X = 8, ///< T4X.
  T5X = 16, ///< T5X.
  T6X = 32, ///< T6X.
  TX = 63, ///< All the X layers
  T1Y = 64, ///< T1Y.
  T2Y = 128, ///< T2Y.
  T3Y = 256, ///< T3Y.
  T4Y = 512, ///< T4Y.
  T5Y = 1024, ///< T5Y.
  T6Y = 2048, ///< T6Y.
  TY = 4032
///< All the Y layers
};
/*! @var TOFNPADLAYER
 * The number of pads in each ToF layer. S11 corresponds to element 0, S12 to element 1 and so on.
 */
const int TOFNPADLAYER[6] = { 8, 6, 2, 2, 3, 3 };

/*! @var H_MASS
 * Proton mass
 */
const float H_MASS = 0.93827203; // GeV (pdg.web.cern.ch)

/*! @var HE4_MASS
 * Helium 4 mass
 */
const float HE4_MASS = 3.7274; // GeV (http://hyperphysics.phy-astr.gsu.edu/Hbase/pertab/He.html)

/*! @var HE3_MASS
 * Helium 3 mass
 */
const float HE3_MASS = 2.8084; // GeV (http://hyperphysics.phy-astr.gsu.edu/Hbase/pertab/He.html)

/*! @var E_MASS
 * Electron mass
 */
const float E_MASS = 0.000510998; // GeV (from PDG)

/*! @brief A simple matrix class.
 *
 *  This class defines a matrix built by STL vectors. It is basically a variable-dimension
 *  vector of vectors. It is intended as a container and not for algebraic manipulations.
 *  The class provides a standard access operator [] and a resize method.
 */
template<class T>
class SimpleMatrix {

public:
  /*! @brief Constructor
   *
   * The constructor will build an nRows x nCols matrix, initialized with a default value. If T
   * is a class with no default constructor, a default value for T must be provided, which will
   * be replicated in every matrix element.
   *
   * @param nRows The number of rows.
   * @param nCols The number of columns
   * @param elements The initialization value for the matrix elements.
   */
  SimpleMatrix(unsigned int nRows = 0, unsigned int nCols = 0, T elements = T()) :
    _matrix(nRows, std::vector<T>(nCols, elements)) {

  }

  /*! @brief Standard accessor.
   *
   * @param i The desired row.
   * @return The i-th row (a vector).
   */
  std::vector<T>& operator[](int i) {
    return _matrix[i];
  }

  /*! @brief Returns the number of rows.
   *
   * @return The number of rows.
   */
  unsigned int GetNRows() {
    return _matrix.size();
  }

  /*! @brief Returns the number of columns.
   *
   * @return The number of columns.
   */
  unsigned int GetNCols() {
    return _matrix[0].size();
  }

  /*! @brief Resizes the matrix.
   *
   * If new rows or columns are added, they are initialized to the default value; if T
   * is a class with no default constructor, a default value for T must be provided, which will
   * be replicated in every new matrix element. No modification
   * is done to existing elements (except for those that will be eventually removed).
   *
   * @param nRows The new number of rows.
   * @param nCols The new number of columns.
   * @param elements The initialization value for the new matrix elements.
   */
  void Resize(unsigned int nRows, unsigned int nCols, T elements = T()) {

    _matrix.resize(nRows, std::vector<T>(nCols, elements));
    for (unsigned int i = 0; i < _matrix.size(); i++)
      _matrix[i].resize(nCols, elements);
  }

private:

  std::vector<std::vector<T> > _matrix;
};

#endif /* COMMONDEFS_H_ */
