/***********************************************************************
 *
 * $Id: StHbtV0.hh,v 1.0 1999/09/07
 *
 * Authors: Helen Caines, Tom Humanic 07-Sep-1999
 *
 ***********************************************************************
 *
 * Description: V0 class with members copied from StV0hbtV0.hh
 *
 ***********************************************************************
 *
 * $Log: StHbtV0.hh,v $
 * Revision 1.13  2003/09/02 17:58:32  perev
 * gcc 3.2 updates + WarnOff
 *
 * Revision 1.12  2003/01/14 09:45:14  renault
 * enable this class to be used for theorical calculations.
 *
 * Revision 1.11  2002/11/19 23:37:56  renault
 * Get V0 daughters helix
 *
 * Revision 1.10  2002/02/09 19:25:36  laue
 * updates (dedx length)
 *
 * Revision 1.9  2001/09/05 20:41:43  laue
 * Updates of the hbtMuDstTree microDSTs
 *
 * Revision 1.8  2000/10/09 21:54:23  laue
 * Helens changes to the V0s
 *
 * Revision 1.7  2000/08/09 14:50:22  laue
 * 'const' removed to compile on solaris
 *
 * Revision 1.6  2000/07/16 21:38:23  laue
 * StHbtCoulomb.cxx StHbtSectoredAnalysis.cxx : updated for standalone version
 * StHbtV0.cc StHbtV0.hh : some cast to prevent compiling warnings
 * StHbtParticle.cc StHbtParticle.hh : pointers mTrack,mV0 initialized to 0
 * StHbtIOBinary.cc : some printouts in #ifdef STHBTDEBUG
 * StHbtEvent.cc : B-Field set to 0.25Tesla, we have to think about a better
 *                 solution
 *
 * Revision 1.5  2000/05/03 17:44:43  laue
 * StHbtEvent, StHbtTrack & StHbtV0 declared friend to StHbtIOBinary
 * StHbtParticle updated for V0 pos,neg track Id
 *
 * Revision 1.4  2000/02/18 21:32:24  laue
 * franksTrackCut changed. If mCharge is set to '0' there will be no cut
 * on charge. This is important for front-loaded cuts.
 *
 * copy constructor implemented for StHbtEvent, StHbtTrack and StHbtV0.
 *
 * franks1HistoD.cxx franks1HistoD.h franks2HistoD.cxx franks2HistoD.h
 * removed. We can now (CC5 on Solaris) use the versions (no D)
 *
 * Revision 1.3  2000/02/01 00:33:32  laue
 * namespaces changed to run on the new Solaris Compiler CC5
 * since we can use member templates in franks1Histo.hh we are doing it
 *
 * Revision 1.2  1999/10/15 02:32:37  lisa
 * Helen has added method StHbtV0::UpdateV0() to fill derived information - this leads to smaller microDSTs
 *
 * Revision 1.1  1999/09/16 18:47:59  lisa
 * replace placeholder HbtV0Track stuff with Helens StHbtV0 classes
 *
 * 
 *
 ***********************************************************************/
#ifndef StHbtV0_hh
#define StHbtV0_hh

#include "Stiostream.h"
#include "StHbtMaker/Infrastructure/StHbtTypes.hh" //same as in StHbtTrack.hh
#include "StarClassLibrary/StPhysicalHelixD.hh" // Gael 12 Sept 02
#ifdef __ROOT__
#include "StStrangeMuDstMaker/StV0MuDst.hh"
#endif
/* Th stuff */
#include "StHbtMaker/Base/StHbtHiddenInfo.hh"

#define  M_PHI  1.019455
#define  L_PHI  1.55E-22
/***/
class StHbtTTreeEvent;
class StHbtTTreeV0;

//_________________
class StHbtV0 {
 public:
  StHbtV0(){/* no-op */}
  StHbtV0( const StHbtV0&); // copy constructor
#ifdef __ROOT__
  StHbtV0( StV0MuDst&); // from strangeness V0 micro dst structure
  StHbtV0(const StHbtTTreeEvent*, const StHbtTTreeV0*);
#endif
  ~StHbtV0(){if(mHiddenInfo) delete mHiddenInfo;}

  //Greg's replacement of standard ROOT function Nint
  int GregsNint(float x);
  int GregsNint(double x);
  

  /**************************/
  /*         Getters        */
  /**************************/

  ///////////////////
  // V0 parameters //
  ///////////////////
  float decayLengthV0() const { return mDecayLengthV0; }            // 3-d decay distance
  StHbtThreeVector decayVertexV0() const { return mDecayVertexV0; } // Coordinates of decay vertex
  StHbtThreeVector primaryVertex() const { return mPrimaryVertex; } // Coordinates of primary vertex
  float decayVertexV0X() const       { return mDecayVertexV0.x(); } // Coordinates of decay vertex
  float decayVertexV0Y() const       { return mDecayVertexV0.y(); } // Coordinates of decay vertex
  float decayVertexV0Z() const       { return mDecayVertexV0.z(); } // Coordinates of decay vertex
  float dcaV0Daughters() const       { return mDcaV0Daughters; }    // DCA of v0 daughters at decay vertex
  float dcaV0ToPrimVertex() const    { return mDcaV0ToPrimVertex; } // DCA of v0 to primary vertex
  StHbtThreeVector momV0() const     { return mMomV0; }             // Momentum components of V0
  float momV0X() const    { return mMomV0.x(); }       // Momentum components of V0
  float momV0Y() const    { return mMomV0.y(); }       // Momentum components of V0
  float momV0Z() const    { return mMomV0.z(); }       // Momentum components of V0
  float alphaV0() const   { return mAlphaV0; }         // Armenteros-Podolanski variable
  float ptArmV0() const   { return mPtArmV0; }         // Armenteros-Podolanski variable
  float ptV0() const      { return mMomV0.perp(); }    // Transverse momentum
  float ptotV0() const    { return mMomV0.mag(); }     // Total momentum
  float pseudoRapV0() const;

  //Getters of V0 w.r.t. the V0 id
  float eLambda() const;             // Energy assuming lambda hypothesis
  float eK0Short() const;            // Energy assuming k-short hypothesis
  float ePhi() const;
  float massLambda() const;          // Mass assuming lambda hypothesis
  float massAntiLambda() const;      // Mass assuming antilambda hypothesis
  float massK0Short() const;         // Mass assuming k-short hypothesis
  float massPhi() const;
  float dMLambda() const;
  float dMAntiLambda() const;
  float dMK0Short() const;
  float dMPhi() const;
  float rapLambda() const;           // Rapidity assuming (anti) constlambda
  float rapK0Short() const;          // Rapidity assuming k-short
  float rapPhi() const;
  float cTauLambda() const;          // Lifetime (ctau) const assuming (anti) constlambda
  float cTauK0Short() const;         // Lifetime (ctau) const assuming k-short
  float cTauPhi() const;
  float ePosProton() const;          // Energy of pos. daughter assuming proton
  float ePosPion() const;            // Energy of pos. daughter assuming pion
  float ePosKaon() const;
  float eNegProton() const;          // Energy of neg. daughter assuming antiproton
  float eNegPion() const;            // Energy of neg. daughter assuming pion
  float eNegKaon() const;

  ///////////////////////
  // Positive daughter //
  ///////////////////////
  unsigned short idPos() const   { return mKeyPos; }       // Id of positive track
  unsigned short keyPos() const  { return mKeyPos; }       // Id of positive track
  float ptPos() const        { return mMomPos.perp(); }    // Transverse momentum of pos. daughter
  float ptotPos() const      { return mMomPos.mag(); }     // Total momentum of pos. daughter
  float dedxPos() const      { return mDedxPos; }          // dedx of Positive track
  float numdedxPos() const   { return mNumDedxPos; }       // number of hits in dE/dX track of pos. daughter--Gael04Fev 2002
  float errdedxPos() const   { return mErrDedxPos; }       // error on dedx of Positive track--Gael04Fev 2002
  float lendedxPos() const   { return mLenDedxPos; }       // Length of dE/dX track of pos. daughter--Gael04Fev 2002          
  unsigned short tpcHitsPos() const       { return (unsigned short)mTpcHitsPos; }  // Number of TPC hits on pos. daughter
  unsigned short nHitsFitPos() const      { return (unsigned short)mTpcHitsPos; } 
  unsigned short nHitsPossiblePos() const { return (unsigned short)mNHitsPossiblePos; }
  unsigned short nHitsDedxPos() const     { return (unsigned short)mNumDedxPos; }
  StHbtThreeVector momPos() const  {return mMomPos;}    // Momentum components of pos. daughter
  float momPosX() const      { return mMomPos.x(); }    // Momentum components of pos. daughter
  float momPosY() const      { return mMomPos.y(); }    // Momentum components of pos. daughter
  float momPosZ() const      { return mMomPos.z(); }    // Momentum components of pos. daughter
  float dcaPosToPrimVertex() const  { return mDcaPosToPrimVertex; }  // DCA of pos v0 daughter to pri vertex
  const StPhysicalHelixD& HelixPos() const { return mHelixPos; }
  unsigned int trackTopologyMapPos(unsigned int word) const { return mTrackTopologyMapPos[word]; }
  float nSigmaElectronPos() const  { return (float)mNSigmaElectronPos * 0.01f; }
  float nSigmaPionPos() const      { return (float)mNSigmaPionPos * 0.01f; }
  float nSigmaKaonPos() const      { return (float)mNSigmaKaonPos * 0.01f; }
  float nSigmaProtonPos() const    { return (float)mNSigmaProtonPos * 0.01f; }
  float tofBetaPos() const         { return mTofBetaPos; }
  float pseudoRapPos() const;
  float tofMassSqrPos() const;

  ///////////////////////
  // Negative daughter //
  ///////////////////////
  unsigned short idNeg() const   { return mKeyNeg; }       // Id of negative track
  unsigned short keyNeg() const  { return mKeyNeg; }       // Id of negative track
  float ptNeg() const        { return mMomNeg.perp(); }    // Transverse momentum of neg. daughter
  float ptotNeg() const      { return mMomNeg.mag(); }     // Total momentum of neg. daughter
  float dedxNeg() const      { return mDedxNeg; }          // dedx of Negative track
  float numdedxNeg() const   { return mNumDedxNeg; }       // number of hits in dE/dX track of neg. daughter--Gael04Fev 2002
  float errdedxNeg() const   { return mErrDedxNeg; }       // error on dedx of Negative track--Gael04Fev 2002
  float lendedxNeg() const   { return mLenDedxNeg; }       // Length of dE/dX track of neg. daughter--Gael04Fev 2002
  unsigned short tpcHitsNeg() const       { return (unsigned short)mTpcHitsNeg; }       // Number of TPC hits on neg. daughter
  unsigned short nHitsFitNeg() const      { return (unsigned short)mTpcHitsNeg; }
  unsigned short nHitsPossibleNeg() const { return (unsigned short)mNHitsPossibleNeg; }
  unsigned short nHitsDedxNeg() const     { return (unsigned short)mNumDedxNeg; }
  StHbtThreeVector momNeg() const  { return mMomNeg; }    // Momentum components of neg. daughter
  float momNegX() const        { return mMomNeg.x(); }    // Momentum components of neg. daughter
  float momNegY() const        { return mMomNeg.y(); }    // Momentum components of neg. daughter
  float momNegZ() const        { return mMomNeg.z(); }    // Momentum components of neg. daughter
  float dcaNegToPrimVertex() const  { return mDcaNegToPrimVertex; }   // DCA of neg v0 daughter to pri vertex
  const StPhysicalHelixD& HelixNeg() const { return mHelixNeg; }
  unsigned int trackTopologyMapNeg(unsigned int word) const { return mTrackTopologyMapNeg[word]; }
  float nSigmaElectronNeg() const { return (float)mNSigmaElectronNeg * 0.01f; }
  float nSigmaPionNeg() const     { return (float)mNSigmaPionNeg * 0.01f; }
  float nSigmaKaonNeg() const     { return (float)mNSigmaKaonNeg * 0.01f; }
  float nSigmaProtonNeg() const   { return (float)mNSigmaProtonNeg * 0.01f; }
  float tofBetaNeg() const        { return mTofBetaNeg; }
  float pseudoRapNeg() const;
  float tofMassSqrNeg() const;

  //Fills derived info
  void UpdateV0();

  /**************************/
  /*         Setters        */
  /**************************/
  
  ///////////////////
  // V0 parameters //
  ///////////////////
  void SetdecayLengthV0(const float x)     { mDecayLengthV0 = x; }
  void SetdecayVertexV0(const StHbtThreeVector v) { mDecayVertexV0 = v; }
  void SetdecayVertexV0X(const float vx)   { mDecayVertexV0.setX(vx); }
  void SetdecayVertexV0Y(const float vy)   { mDecayVertexV0.setY(vy); }
  void SetdecayVertexV0Z(const float vz)   { mDecayVertexV0.setZ(vz); }
  void SetdcaV0Daughters(const float x)    { mDcaV0Daughters = x; }
  void SetdcaV0ToPrimVertex(const float x) { mDcaV0ToPrimVertex = x; }
  void SetmomV0(const StHbtThreeVector x)  { mMomV0 = x; }
  void SetmomV0X(const float px)  { mMomV0.setX(px); }
  void SetmomV0Y(const float py)  { mMomV0.setY(py); } 
  void SetmomV0Z(const float pz)  { mMomV0.setZ(pz); }
  void SetalphaV0(const float x)  { mAlphaV0 = x; }
  void SetptArmV0(const float x)  { mPtArmV0 = x; }
  
  ///////////////////////
  // Positive daughter //
  ///////////////////////
  void SetidPos(const unsigned short& x)   { mKeyPos = (unsigned short)x; }
  void SetkeyPos(const unsigned short& x)  { mKeyPos = (unsigned short)x; }
  void SetdcaPosToPrimVertex(const float x){ mDcaPosToPrimVertex = x; }
  void SetmomPos(const StHbtThreeVector p) { mMomPos = p; }
  void SetmomPosX(const float px)          { mMomPos.setX(px); }
  void SetmomPosY(const float py)          { mMomPos.setY(py); }
  void SetmomPosZ(const float pz)          { mMomPos.setZ(pz); }
  void SettpcHitsPos(const unsigned short n)       { mTpcHitsPos = (unsigned char)n;}
  //void SetnHitsFitPos(const unsigned short n)      { mNHitsFitPos = (unsigned char)n;}
  void SetnHitsPossiblePos(const unsigned short n) { mNHitsPossiblePos = (unsigned char)n;}
  void SetnHitsDedxPos(const unsigned short n)     { mNumDedxPos = (unsigned char)n; }
  void SetdedxPos(const float x)      { mDedxPos = x; }
  void SeterrdedxPos(const float x)   { mErrDedxPos = x; }
  void SetlendedxPos(const float x)   { mLenDedxPos = x; }
  void SetHelixPos(const StPhysicalHelixD& h) { mHelixPos = h; }
  void SetTrackTopologyMapPos(const int word, const unsigned int& m) { mTrackTopologyMapPos[word] = m; }
  void SetnSigmaElectronPos(const float x);
  void SetnSigmaPionPos(const float x);
  void SetnSigmaKaonPos(const float x);
  void SetnSigmaProtonPos(const float x);
  void SetnSigmaElectronPos(const double x);
  void SetnSigmaPionPos(const double x);
  void SetnSigmaKaonPos(const double x);
  void SetnSigmaProtonPos(const double x);
  void SettofBetaPos(const float x)        { mTofBetaPos = x; }

  ///////////////////////
  // Negative daughter //
  ///////////////////////
  void SetidNeg(const unsigned short& x)    { mKeyNeg = (unsigned short)x; }
  void SetkeyNeg(const unsigned short& x)   { mKeyNeg = (unsigned short)x; }
  void SetdcaNegToPrimVertex(const float x) { mDcaNegToPrimVertex = x; } 
  void SetmomNeg(const StHbtThreeVector x)  { mMomNeg = x; } 
  void SetmomNegX(const float px)           { mMomNeg.setX(px); }
  void SetmomNegY(const float py)           { mMomNeg.setY(py); }
  void SetmomNegZ(const float pz)           { mMomNeg.setZ(pz); }
  void SettpcHitsNeg(const unsigned short n)        { mTpcHitsNeg = (unsigned char)n; }
  //void SetnHitsFitNeg(const unsigned short n)       { mNHitsFitNeg = (unsigned char)n; }
  void SetnHitsPossibleNeg(const unsigned short n)  { mNHitsPossibleNeg = (unsigned char)n; }
  void SetnHitsDedxNeg(const unsigned short n)      { mNumDedxNeg = (unsigned char)n; }
  void SetdedxNeg(const float x)     { mDedxNeg = x; }
  void SeterrdedxNeg(const float x)  { mErrDedxNeg = x; }
  void SetlendedxNeg(const float x)  { mLenDedxNeg = x; }
  void SetHelixNeg(const StPhysicalHelixD& h) { mHelixNeg = h; }
  void SetTrackTopologyMapNeg(const int word, const unsigned int& m) { mTrackTopologyMapNeg[word] = m; }
  void SetnSigmaElectronNeg(const float x);
  void SetnSigmaPionNeg(const float x);
  void SetnSigmaKaonNeg(const float x);
  void SetnSigmaProtonNeg(const float x);
  void SetnSigmaElectronNeg(const double x);
  void SetnSigmaPionNeg(const double x);
  void SetnSigmaKaonNeg(const double x);
  void SetnSigmaProtonNeg(const double x);
  void SettofBetaNeg(const float x) { mTofBetaNeg = x; }

  void SetprimaryVertex(const StHbtThreeVector v) { mPrimaryVertex = v; }
  /* Th stuff */
  void SetHiddenInfo(StHbtHiddenInfo* aHiddenInfo) { mHiddenInfo = aHiddenInfo; }
  bool ValidHiddenInfo() const { if(mHiddenInfo) return true; else return false; }
  // Fab private : (official : const StHbtHiddenInfo* HiddenInfo() const;
  StHbtHiddenInfo* getHiddenInfo() const { return mHiddenInfo; }
  /***/
  friend ostream& operator<<(ostream& out, StHbtV0& v0);
  friend istream& operator>>(istream& in,  StHbtV0& v0);

  friend class StHbtIOBinary;
  friend class StHbtTTreeV0;
  friend class StHbtTTreeXi;

 protected:

  StHbtThreeVector mPrimaryVertex;
 
  ///////////////////////
  //   V0 parameters   //
  ///////////////////////
  float mDecayLengthV0;
  StHbtThreeVector mDecayVertexV0;
  StHbtThreeVector mMomV0;
  float mDcaV0Daughters;
  float mDcaV0ToPrimVertex;
  float mChi2V0;
  float mClV0;
  float mAlphaV0;
  float mPtArmV0;

  ///////////////////////
  // Positive daughter //
  ///////////////////////
  unsigned short mKeyPos;
  float mDcaPosToPrimVertex;
  StHbtThreeVector mMomPos;
  StPhysicalHelixD mHelixPos;
  unsigned int  mTrackTopologyMapPos[2];
  unsigned char mTpcHitsPos;
  //unsigned char mNHitsFitPos;
  unsigned char mNHitsPossiblePos;
  unsigned char mNumDedxPos;
  float mChi2Pos;
  float mClPos;
  float mDedxPos;
  float mErrDedxPos;
  float mLenDedxPos;
  short mNSigmaElectronPos;   //nsigmaE * 100
  short mNSigmaPionPos;       //nsigmaPi * 100
  short mNSigmaKaonPos;       //nsigmaK * 100
  short mNSigmaProtonPos;     //nsigmaP * 100
  float mTofBetaPos;

  ///////////////////////
  // Negative daughter //
  ///////////////////////
  unsigned short mKeyNeg;
  float mDcaNegToPrimVertex;
  StHbtThreeVector mMomNeg;
  StPhysicalHelixD mHelixNeg;
  unsigned int  mTrackTopologyMapNeg[2];  
  unsigned char mTpcHitsNeg;
  unsigned char mNumDedxNeg;
  //unsigned char mNHitsFitNeg;
  unsigned char mNHitsPossibleNeg;
  float mChi2Neg;
  float mClNeg;
  float mDedxNeg;
  float mErrDedxNeg;
  float mLenDedxNeg;
  short mNSigmaElectronNeg;    //nsigmaE * 100
  short mNSigmaPionNeg;        //nsigmaPi * 100
  short mNSigmaKaonNeg;        //nsigmaK * 100
  short mNSigmaProtonNeg;      //nsigmaP * 100
  float mTofBetaNeg;
  
  /* Th stuff */
  // Fab private : add mutable
  mutable StHbtHiddenInfo* mHiddenInfo; //!
  /***/
};
#endif


















