/**
 * \file inc/CaloLevel1.h
 * \author Emiliano Mocchiutti
 */
#ifndef CaloLevel1_h
#define CaloLevel1_h
//
// default position used only in CaloStrip for the moment
//
//
// old param
//
//#define CTX 121.1 
//#define CTY 122.6 
//#define CTZ -263.1 
//
// new param
//
//#define CTX 121.2
//#define CTY 122.9 
//#define CTZ -263.1
//
// new param using em showers (E. Taddei paramters)
//
#define CTX 120.6
#define CTY 122.3 
#define CTZ -263.1
//
// Mechanical positions (used with option --use-standard-alig)
//
#define MECHCTX 120.5
#define MECHCTY 121.5
#define MECHCTZ -261.81 
//
// just for testing purpose
//
//#define MECHCTX 0.
//#define MECHCTY 0.
//#define MECHCTZ -263.1
//
#include <sstream>
#include <fstream>
#include <string.h>
#include <TObject.h>
#include <TMath.h>
#include <TClonesArray.h>
#include <TArrayI.h>
#include <TSystem.h>
#include <GLTables.h>
//
extern "C" int millim_(Int_t *, Float_t *);
struct shift {
  Float_t shift;
};
//

/**
 * \brief Calorimeter level1 class
 *
 * This class contains level1 calorimeter variables
 *
**/
class CaloLevel1 : public TObject {

 private:

 public:
    //
    Int_t istrip;      ///< total number of strip hit
    //
    // Number of strip with energy > emip and their value coded with view plane and strip number:
    // view x[y] plane PP strip SS with energy mmmm.iip = +[-] ( PP*10^6 + SS*10^4 + mmmm.iip )
    //
    TArrayI estrip; ///< MIP values for each strip with energy > emin coded with view plane and strip number. NOTICE: precision is limited to the 5 most significative ciphers
    //
    CaloLevel1* GetCaloLevel1(){return this;}; ///< returns pointer to this object
    //
    //
    Float_t GetEstrip(Int_t view, Int_t plane, Int_t strip); ///< returns saved MIP value for the indicated strip.
    Float_t DecodeEstrip(Int_t entry, Int_t &view, Int_t &plane, Int_t &strip); ///< returns saved MIP value for the entry number "entry" of the TArrayI.
    Float_t qtotpl(Int_t nplane); ///< Returns energy released on plane nplane (where 0<= nplane <= 43, 0 = 1Y, 1 = 1X, 2 = 2Y, 3 = 2X, etc. etc.).
    Float_t qtotpl(Int_t view, Int_t plane); ///< Returns energy released on view "view" (0 = X, 1 = Y) and plane "plane" ( 0 <= plane <= 21 ).
    //
    void Clear();
    //
    Float_t GetXalig(){printf(" Obsolete! Use CaloStrip class instead\n");return CTX;}; ///< return X alignement paramenter
    Float_t GetYalig(){printf(" Obsolete! Use CaloStrip class instead\n");return CTY;}; ///< return Y alignement paramenter
    Float_t GetZalig(){printf(" Obsolete! Use CaloStrip class instead\n");return CTZ;}; ///< return Z alignement paramenter
    //
    CaloLevel1(); ///< Constructor.
    //
    ClassDef(CaloLevel1,1);
};

/**
 * \brief Calorimeter strip class, needed to perform operation on a strip level, for example to retrieve the position of the strips or to retrieve the closest strip to a cerain position
 *
 */
class CaloStrip : public TObject {

private:
    CaloLevel1 *c1; //< pointer to level1 object
    Float_t fE; //< energy in mip of the strip
    Float_t fX; //< X position in cm of the strip
    Float_t fY; //< Y position in cm of the strip
    Float_t fZ; //< Z position in cm of the strip
    Int_t fView; ///< view [1-2]
    Int_t fPlane; ///< plane [1-22]
    Int_t fStrip; ///< strip [1-96]
    Bool_t ismech; ///< true = using mechanical alignement, false using experimental alignement parameters
    static Float_t UXal; ///< used X alignement parameter
    static Float_t UYal; ///< used Y alignement parameter
    static Float_t UZal; ///< used Z alignement parameter
    static Bool_t paramload;
   //

public:
    //
    // METHODS
    //
    CaloStrip(); ///< Default Constructor.
    //
    CaloStrip(Bool_t usemechanicalalignement); ///< Default Constructor.
    //
    CaloStrip(CaloLevel1 *c1); ///< Constructor.
    //
    CaloStrip(CaloLevel1 *c1, Bool_t usemechanicalalignement); ///< Constructor.
    //
    Float_t GetE(){return fE;}; ///< Get energy in MIP for setted strip
    //
    Float_t GetX(){return fX;}; ///< Get X strip position
    Float_t GetY(){return fY;}; ///< Get Y strip position
    Float_t GetZ(){return fZ;}; /// Get Z strip position
    //
    Float_t GetXalig(){ return UXal;}; ///< return X alignement paramenter
    Float_t GetYalig(){ return UYal;}; ///< return Y alignement paramenter
    Float_t GetZalig(){ return UZal;}; ///< return Z alignement paramenter
    //
    Int_t GetView(){return (fView-1);}; ///< Get strip view [0-1]
    Int_t GetPlane(){return (fPlane-1);}; ///< Get strip plane [0-22]
    Int_t GetStrip(){return (fStrip-1);}; ///< Get strip number [0-95]
    //
    void Set(Int_t view, Int_t plane, Int_t strip); ///< Set strip giving view [0-1], plane [0-22] and number [0-95]
    //
    void Set(Float_t X, Float_t Y, Float_t Z); ///< Set strip giving position in PAMELA ref sys [cm]
    //
    void UseMechanicalAlig(){ ismech = true; UXal = MECHCTX; UYal = MECHCTY; UZal = MECHCTZ;}; ///< Tells CaloStrip to use mechanical alignement parameters
    void UseStandardAlig(); ///< Tells CaloStrip to use default parameters it will find querying the DB. If connection fails uses parameters hard-coded in this file 
    void SetAlig(Float_t XALIG, Float_t YALIG, Float_t ZALIG){ ismech = false; UXal = XALIG; UYal = YALIG; UZal = ZALIG;};///< User defined alignement parameters
    Bool_t IsMechanicalAlig(){return ismech;}; ///< True is using mechanical alignement parameters, false otherwise
    //
    void Clear(); ///< clear variables
    //
    CaloStrip* GetCaloStrip(){return this;}; ///< returns pointer to this object
    //
    ClassDef(CaloStrip,2);
    //
};

#endif
