Received: from d0sgi0.fnal.gov (d0sgi0.fnal.gov [131.225.221.44]) by d0sgim.fnal.gov (980427.SGI.8.8.8/970903.SGI.AUTOCF) via SMTP id OAA13697 for <\meena@d0sgim.fnal.gov>; Tue, 29 Sep 1998 14:35:05 -0500 (CDT)
Received: from FNAL.FNAL.Gov (fnal.fnal.gov [131.225.9.8]) by d0sgi0.fnal.gov (950413.SGI.8.6.12/950213.SGI.AUTOCF) via ESMTP id OAA26829 for <meena@d0sgi0.fnal.gov>; Tue, 29 Sep 1998 14:35:02 -0500
Received: from D0GS01.FNAL.GOV ("port 2181"@d0gs01.fnal.gov)
 by FNAL.FNAL.GOV (PMDF V5.1-10 #3998)
 with SMTP id <01J2DROEW3G00004G9@FNAL.FNAL.GOV> for meena@d0sgi0.fnal.gov;
 Tue, 29 Sep 1998 14:35:01 -0500 CST
Date: Tue, 29 Sep 1998 14:35:01 -0500 (CDT)
From: SERBAN PROTOPOPESCU 344-3721 <"BNLD01::SERBAN"@d0bnl3> (516)
Subject: interface class for physics objects
To: womersley@fnal.gov, meena@fnal.gov, zieminski@ind.physics.INDIANA.EDU,
        daria@ind.physics.INDIANA.EDU, snyder@d0sgif, gwatts@fnal.gov
Message-id: <980929143501.21203971@D0BNL3.FNAL.GOV>
X-Vmsmail-To: @RUN2_ALGO
X-Vmsmail-Cc: SERBAN

                                                            bnld0, 29-SEP-1998

    I think it  is very  important  that we define  at the  next algorithms
meeting the  interface class for D0  physics objects.  After some thought I
came to the conclusion that the interface class should be an abstract class
with pure virtual methods and no attributes. This gives maximum flexibility
to the derived classes while  achieving the primary goal which is a uniform
interface to access information for coding algorithms. The interface should
make no  assumption on  how the  information is  stored, that  is up to the
implementers.   The only   assumptions  is that  all  physics  objects have
4-vector  information, can  return an  integer id (note  that this does not
necessarily imply  that the object  has an integer id  as an attribute) and
some definition of quality. We could return instead of an integer id a more
general object D0PhysObjID, but we  should first understand whether that is
really  necessary and what  its purpose is.  A minimum of  an integer id is
needed because the EDM forces us to  have a way of matching objects without
relying on  pointers. This id is not  a type identifier  but rather a stamp
that identifies the object uniquely within an event.

    One open question is  whether D0PhysObj should  inherit d0_Object. This
ensures all physics  objects are persistent  capable and one can also store 
pointers to them.  My proposed  D0PhysObj.hpp included  below assumes we do
want the pointers to all physics objects to be persistent capable.
    

                                   Serban 


D0PhysObj.hpp:
==============

#ifndef INC_D0PHYSOBJ
#define INC_D0PHYSOBJ
//////////////////////////////////////////////////////////////////////
//  File: D0PhysObj.hpp
//
//  Purpose: define access methods
//           Should be inherited by all constructed objects
//           that have a 4-momentum
//
//  Created: 29-SEP-1998  Serban Protopopescu
//
//////////////////////////////////////////////////////////////////////  
#include "d0om/d0_Object.hpp"

class LorentzVector;
class SpaceVector;
class Quality;

class D0PhysObj: public d0_Object{

  D0_OBJECT_SETUP(D0PhysObj);

 public:

  D0PhysObj(){;}

  virtual ~D0PhysObj(){;}

  //   Interface methods

  float px() const=0;
  float py() const=0;
  float pz() const=0;
  float E() const=0;


  void p4vec(float p4v[4]) const=0;

  LorentzVector l4vec() const=0;

  SpaceVector   s3vec() const=0;

  virtual float pT() const=0; 
 
  virtual float phi() const=0;

  virtual float eta() const=0;

  virtual float theta() const=0;

  virtual float p() const=0;

  virtual integer id() const=0;

  virtual Quality quality()=0;

};
#endif // INC_D0PHYSOBJ
Received: from d0sgi0.fnal.gov (d0sgi0.fnal.gov [131.225.221.44]) by d0sgim.fnal.gov (980427.SGI.8.8.8/970903.SGI.AUTOCF) via SMTP id RAA23461 for <\meena@d0sgim.fnal.gov>; Fri, 9 Oct 1998 17:11:54 -0500 (CDT)
Received: from FNAL.FNAL.Gov (fnal.fnal.gov [131.225.9.8]) by d0sgi0.fnal.gov (950413.SGI.8.6.12/950213.SGI.AUTOCF) via ESMTP id RAA06513; Fri, 9 Oct 1998 17:11:48 -0500
Received: from D04.PHY.BNL.GOV ("port 1045"@d04.phy.bnl.gov)
 by FNAL.FNAL.GOV (PMDF V5.1-10 #3998)
 with SMTP id <01J2RW32V2W0000297@FNAL.FNAL.GOV>; Fri,
 9 Oct 1998 17:11:45 -0500 CST
Date: Fri, 09 Oct 1998 18:09:09 -0400 (EDT)
From: SERBAN PROTOPOPESCU 344-3721 <SERBAN@D01.phy.BNL.gov> (516)
Subject: D0PhysObj
To: "d0bnl3::womersley"@D01.phy.BNL.gov, meena@fnal.gov,
        HEINSON@UCRPH0.UCR.EDU, norman@fnal.gov, blessing@fsheb2.hep.FSU.EDU,
        stichel@fnald0, skulik@fnal.gov, barberis@fnald0, trippe@LBL.gov,
        adams@physics.rice.edu
Cc: SERBAN@D01.phy.BNL.gov
Message-id: <981009180909.20024e@D01.PHY.BNL.GOV>
X-Vmsmail-To: @RUN2_ALGO
X-Vmsmail-Cc: SERBAN

                                                            bnld0,  9-OCT-1998

    I intend  to  proceed creating a  kinem  library with  D0PhysObj.hpp
Eventually kinem  may grow to  include other useful  classes (or functions)
for physics  objects.  Following  Thursday  discussion I have  modified the
proposed D0PhysObj.hpp to the one included below. 
 
   There is one problem that was glossed over during the discussion. It was
suggested that one of access methods return a reference or a pointer to the
Vertex  object which  gives the  position  in space  where the  momentum is
defined. The problem with this is that if we do not want to store a copy of
the Vertex object with the physics  object but only a vertex index then the
method must  have the event  as an argument  so the Vertex  can be fetched.
This seems to me heavy artillery for D0PhysObj and rather inelegant. Rather
than force object  inheriting  D0PhysObj to either  store the Vertex (which
would  lead to  gross  duplication  since  most object  will  have the same
vertex) or  write code to  find the Vertex  given an index  it is better to
have the object simply return the vertex index. There should exist a static
function  which returns  a reference  to the  appropriate  vertex given the
vertex index and  a reference to the  event as input.  This way the code is
written  only once and  can be used  for any  purpose. The  static function
should be supplied by the vertex group. In general the vertex index is more
likely to be  useful than the vertex  object, it is all  we need to know to
decide if it is  appropriate to use the 4-vectors  as belonging to the same
set.

   Note following items:
-  I changed id to index, this is to avoid confusion with particle id.
-  I added typeID, this is the equivalent of particle id. If people prefer
   it could be named particleID but not all D0PhysObj are particles.
   Rather than invent our own typeID's I suggest we use PDG id's and
   invent our own only if an appropriate definition does not exist.
-  errMatrix: we must agree for what variables it is defined otherwise
   it makes no sense to have a general errMatrix. I propose that it
   be for px, py, pz, E even if that are not the best variables to use
   for the particular object. This does not prevent derived classes from
   making available a different access method for an error matrix in a 
   more appropriate set of variables.

There  is a  question of  what to do  if the  object  4-momentum  cannot be
defined at  some vertex  position. I suggest  that in that  case the object
return an illegal value  for vtxindex and it is  up to the derived class to
supply a method  that returns x,y  and z. As a rule  physics objects should
always  return  4-momentum  information  at some  vertex, but  there may be
exceptional  circumstances when this is not  possible. These objects should
be handled by specially derived classes.
    

                                   Serban 


#ifndef INC_D0PHYSOBJ
#define INC_D0PHYSOBJ
//////////////////////////////////////////////////////////////////////
//  File: D0PhysObj.hpp
//
//  Purpose: define access methods
//           Should be inherited by all constructed objects
//           that have a 4-momentum
//
//  Created: 29-SEP-1998  Serban Protopopescu
//
//////////////////////////////////////////////////////////////////////  

class LorentzVector;
class Matrix;
class SpaceVector;
class Quality;

class D0PhysObj{

 public:

  // constructors
  D0PhysObj(){;}

  virtual ~D0PhysObj(){;}

  //   Interface methods

  float px() const=0;
  float py() const=0;
  float pz() const=0;
  float E() const=0;


  void p4vec(float p4v[4]) const=0;

  LorentzVector l4vec() const=0;

  SpaceVector   s3vec() const=0;

  virtual float pT() const=0; 
 
  virtual float phi() const=0;

  virtual float eta() const=0;

  virtual float theta() const=0;

  virtual float p() const=0;

  virtual float charge() const=0;

  virtual integer index() const=0;

  virtual integer typeid() const=0;

  virtual integer vtxindex() const=0;

  virtual Matrix& errMatrix() const=0

  virtual Quality quality() const=0;

};
#endif // INC_D0PHYSOBJ
Received: from d0sgi0.fnal.gov (d0sgi0.fnal.gov [131.225.221.44]) by d0sgim.fnal.gov (980427.SGI.8.8.8/970903.SGI.AUTOCF) via SMTP id NAA29859 for <\meena@d0sgim.fnal.gov>; Mon, 26 Oct 1998 13:50:44 -0600 (CST)
Received: from FNAL.FNAL.Gov (fnal.fnal.gov [131.225.9.8]) by d0sgi0.fnal.gov (950413.SGI.8.6.12/950213.SGI.AUTOCF) via ESMTP id NAA24314; Mon, 26 Oct 1998 13:50:43 -0600
Received: from D04.PHY.BNL.GOV ("port 1139"@d04.phy.bnl.gov)
 by FNAL.FNAL.GOV (PMDF V5.1-10 #3998)
 with SMTP id <01J3FFYY0WDI000GAG@FNAL.FNAL.GOV>; Mon,
 26 Oct 1998 13:50:33 -0600 CST
Date: Mon, 26 Oct 1998 14:51:23 -0500 (EST)
From: SERBAN PROTOPOPESCU 344-3721 <SERBAN@D01.phy.BNL.gov> (516)
Subject: D0PhysObj
To: "d0bnl3::womersley"@D01.phy.BNL.gov, HEINSON@UCRPH0.UCR.EDU,
        norman@fnal.gov, blessing@fsheb2.hep.FSU.EDU, skulik@fnal.gov,
        barberis@fnald0, trippe@LBL.gov, meena@fnal.gov, stichel@fnald0,
        adams@physics.rice.edu
Cc: SERBAN@D01.phy.BNL.gov
Message-id: <981026145123.20200a1d@D01.PHY.BNL.GOV>
X-Vmsmail-To: @RUN2_ALGO
X-Vmsmail-Cc: SERBAN

                                                            bnld0, 26-OCT-1998

    One more  time I am  sending the  D0PhysObj.hpp  proposal for comments.
This is now in the kinem library together with KinemUtil.hpp, and I include
copies of  both below  plus a copy  of the  message I sent  three weeks ago
describing changes made after the algorithms group discussion.

    Let me remind you of the purpose of this interface:

1) Provide  a  uniform   interface  for all  physics objects, thus allowing
   different types to be combined for any calculation.

2) Give complete  freedom on how  those objects are  defined internally, ie
   objects may  for example  store phi, eta  and pT instead  of px,py,pz or
   both if they so wish. However,  duplicate information should not be made
   persistent as disk space is at a premium.

3) Implicit  in  2) is  that  objects   inheriting   D0PhysObj are  free to
   calculate derived quantities in any way they wish.

4) Derived objects are of course free to add any other methods that may
   be useful for that particular object.

Items 2  and 3  run  counter to a  desire for   uniformity in  the way some
quantities  should  be  calculated.  KinemUtil.hpp  is meant to  solve that
problem: it is class  with static inline  functions that do simple standard
calculations.  Implementers of physics object  classes should always use
them unless there are very compelling reasons not to do so. 

    At present nothing is frozen (except that a D0PhysObj will exist). I am
open to suggestions for  improvements. Adopting suggestions will have to be
subject to general  discussion in an algorithms  group meeting. If you have
opinions the time  to voice them is  now as this will  be cast in stone for
the December milestone.

                Serban

============================================================================


Previous message:
=================

    I intend  to  proceed with  creating a  kinem  library with  D0PhysObj.
Eventually kinem  may grow to  include other useful  classes (or functions)
for physics  objects.  Following  Thursday  discussion I have  modified the
proposed D0PhysObj.hpp to the one included below. 
 
   There is one problem that was glossed over during the discussion. It was
suggested that one of access methods return a reference or a pointer to the
Vertex  object which  gives the  position  in space  where the  momentum is
defined. The problem with this is that if we do not want to store a copy of
the Vertex object with the physics  object but only a vertex index then the
method must  have the event  as an argument  so the Vertex  can be fetched.
This seems to me heavy artillery for D0PhysObj and rather inelegant. Rather
than force object  inheriting  D0PhysObj to either  store the Vertex (which
would  lead to  gross  duplication  since  most object  will  have the same
vertex) or  write code to  find the Vertex  given an index  it is better to
have the object simply return the vertex index. There should exist a static
function  which returns  a reference  to the  appropriate  vertex given the
vertex index and  a reference to the  event as input.  This way the code is
written  only once and  can be used  for any  purpose. The  static function
should be supplied by the vertex group. In general the vertex index is more
likely to be  useful than the vertex  object, it is all  we need to know to
decide if it is  appropriate to use the 4-vectors  as belonging to the same
set.

   Note following items:
-  I changed id to index, this is to avoid confusion with particle id.
-  I added typeID, this is the equivalent of particle id. If people prefer
   it could be named particleID but not all D0PhysObj are particles.
   Rather than invent our own typeID's I suggest we use PDG id's and
   invent our own only if an appropriate definition does not exist.
-  errMatrix: we must agree for what variables it is defined otherwise
   it makes no sense to have a general errMatrix. I propose that it
   be for px, py, pz, E even if that are not the best variables to use
   for the particular object. This does not prevent derived classes from
   making available a different access method for an error matrix in a 
   more appropriate set of variables.

There  is a  question of  what to do  if the  object  4-momentum  cannot be
defined at  some vertex  position. I suggest  that in that  case the object
return an illegal value  for vtxindex and it is  up to the derived class to
supply a method  that returns x,y  and z. As a rule  physics objects should
always  return  4-momentum  information  at some  vertex, but  there may be
exceptional  circumstances when this is not  possible. These objects should
be handled by specially derived classes.


D0PhysObj.hpp
=============

#ifndef INC_D0PHYSOBJ
#define INC_D0PHYSOBJ
//////////////////////////////////////////////////////////////////////
//  File: D0PhysObj.hpp
//
//  Purpose: define access methods
//           Should be inherited by all constructed objects
//           that have a 4-momentum
//
//  Created: 29-SEP-1998  Serban Protopopescu
//
//////////////////////////////////////////////////////////////////////  

class LorentzVector;
class Matrix;
class SpaceVector;
class Quality;

class D0PhysObj{

 public:

  // constructors
  D0PhysObj(){;}

  virtual ~D0PhysObj(){;}

  //   Interface methods

  //  return 4-vector components and simple derived quantities
  float px() const=0;
  float py() const=0;
  float pz() const=0;
  float E() const=0;
  virtual float pT() const=0; 
  virtual float phi() const=0;
  virtual float eta() const=0;
  virtual float theta() const=0;
  virtual float p() const=0;

  //  return Lorentz 4-vector as an array
  void p4vec(float p4v[4]) const=0;

  //  return Lorentz 4-vector
  LorentzVector l4vec() const=0;

  //  return the space component of Lorentz 4-vector
  SpaceVector   s3vec() const=0;

  virtual float charge() const=0;

  //  return an identifying index
  virtual integer index() const=0;

  //  return object type
  virtual integer typeid() const=0;

  //  return vertex index
  virtual integer vtxindex() const=0;

  // return error Matrix for px, py, pz (symmetric 3x3)
  virtual Matrix& errMatrix() const=0

  virtual Quality quality() const=0;

};
#endif // INC_D0PHYSOBJ


KinemUtil.hpp
=============

#ifndef INC_KINEMUTIL
#define INC_KINEMUTIL
///////////////////////////////////////////////////////////////////////////////
// File: KinemUtil.hpp
// 
// Purpose:  Provide useful functions for physics objects
//           all functions in this class are static and inline
//
// Created:   12-OCT-1998  Serban Protopopescu
// History:   
///////////////////////////////////////////////////////////////////////////////
// Dependencies (#includes)

#include <math.h>
#include <stdlib.h>

#ifndef INC_PI
#define INC_PI
const float PI=3.141592653;
const float TWOPI=6.28318531;
#endif // INC_PI

///////////////////////////////////////////////////////////////////////////////

class KinemUtil{

public:
    
  // Constructors

  KinemUtil();  

  // destructor
  ~KinemUtil();

  //  calculate phi from x, y
  static float phi(float x, float y);

  //  calculate theta from x, y, z
  static float theta(float x, float y, float z);

  //  calculate eta from x, y, z (return also theta)
  static float eta(float x, float y, float z, float &th);

  //  calculate eta from theta
  static float eta(float th);

  // calculate detector eta given vertex and momentum
  static float detector_eta(float vtx[3], float pxyz[3]);
};

inline
KinemUtil::KinemUtil(){
  ;
}

inline
float KinemUtil::phi(float x, float y)
{
  float PHI=atan2(y, x);
  return (PHI>0)? PHI : TWOPI+PHI;
}

inline 
float KinemUtil::theta(float x, float y, float z)
{
  return acos(z/sqrt(x*x+y*y+z*z));
}

inline
float KinemUtil::eta(float x, float y, float z, float &th)
{
  th=theta(x,y,z);
  return eta(th);
}

inline
float KinemUtil::eta(float th)
{
  if(th == 0) return 15.0;
  if(th >= PI-0.0001) return -15.0;
  return -log(tan(th/2.));
}

inline
float KinemUtil::detector_eta(float vtx[3], float pxyz[3])
{
  // add unit vectors
  float s=sqrt(vtx[0]*vtx[0]+vtx[1]*vtx[1]+vtx[2]*vtx[2]);
  float p=sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]+pxyz[2]*pxyz[2]);
  float vadd[3];
  for(int i=0, i<3, i++){
    vadd[i]=vtx[i]/s+pxyz[i]/p;
  }
  th=theta(vadd[0],vadd[1],vadd[2]);
  return eta(th);
}
#endif // INC_KINEMUTIL

    
Received: from d0sgi0.fnal.gov (d0sgi0.fnal.gov [131.225.221.44]) by d0sgim.fnal.gov (980427.SGI.8.8.8/970903.SGI.AUTOCF) via SMTP id LAA19591 for <\meena@d0sgim.fnal.gov>; Wed, 28 Oct 1998 11:18:17 -0600 (CST)
Received: from FNAL.FNAL.Gov (fnal.fnal.gov [131.225.9.8]) by d0sgi0.fnal.gov (950413.SGI.8.6.12/950213.SGI.AUTOCF) via ESMTP id LAA25565; Wed, 28 Oct 1998 11:17:59 -0600
Received: from D04.PHY.BNL.GOV ("port 1198"@d04.phy.bnl.gov)
 by FNAL.FNAL.GOV (PMDF V5.1-10 #3998)
 with SMTP id <01J3I38XLII2000G9F@FNAL.FNAL.GOV>; Wed,
 28 Oct 1998 11:17:55 -0600 CST
Date: Wed, 28 Oct 1998 12:19:24 -0500 (EST)
From: SERBAN PROTOPOPESCU 344-3721 <SERBAN@d01.phy.BNL.gov> (516)
Subject: revised D0PhysObj.hpp
To: "d0bnl3::womersley"@d01.phy.BNL.gov, HEINSON@UCRPH0.UCR.EDU,
        norman@fnal.gov, blessing@fsheb2.hep.FSU.EDU, skulik@fnal.gov,
        barberis@fnald0, trippe@LBL.gov, meena@fnal.gov, stichel@fnald0,
        adams@physics.rice.edu
Cc: SERBAN@d01.phy.BNL.gov
Message-id: <981028121924.20200a25@D01.PHY.BNL.GOV>
X-Vmsmail-To: @RUN2_ALGO
X-Vmsmail-Cc: SERBAN

                                                            bnld0, 28-OCT-1998

    After some e-mail exchanges with Marc and Herb it became clear that
returning complex objects like LorentzVector and Matrix as a reference
is a bad idea as the only way to ensure that this is safe is for the
classes inheriting D0PhysObj to contain such objects. But this exactly
what we are trying to avoid, we do not wish to impose such conditions.
Therefore I changed returns of LorentzVector and SpaceVector to be
by value. These are small objects and the penalty for returning by value
is small. In the case of Matrix the situation is somewhat more complicated
because the way matrix models are implemented in LinearAlgebra the
model choice and matrix filling is done AFTER the matrix is created.
So it is better that the user create the matrix and pass the reference to
the "particle" object which proceeds to declare the matrix symmetric 
and fills it.

Thus the method is

void errMatrix(Matrix &m)const;

The revised version of D0PhysObj.hpp is given below.

                                   Serban 

D0PhysObj.hpp
============

#ifndef INC_D0PHYSOBJ
#define INC_D0PHYSOBJ
//////////////////////////////////////////////////////////////////////
//  File: D0PhysObj.hpp
//
//  Purpose: define a general interface for D0 physics objects
//           Should be inherited by all constructed objects
//           that have a 4-momentum
//
//  Created: 28-OCT-1998  Serban Protopopescu
//
//////////////////////////////////////////////////////////////////////  

class LorentzVector;
class Matrix;
class SpaceVector;
class Quality;

class D0PhysObj{

 public:

  // constructors
  D0PhysObj(){;}

  virtual ~D0PhysObj(){;}

  //   Interface methods

  //  return 4-vector components and simple derived quantities
  virtual float px() const=0;
  virtual float py() const=0;
  virtual float pz() const=0;
  virtual float E() const=0;
  virtual float pT() const=0; 
  virtual float phi() const=0;
  virtual float eta() const=0;
  virtual float theta() const=0;
  virtual float p() const=0;

  //  return Lorentz 4-vector as an array
  virtual void p4vec(float p4v[4]) const=0;

  //  return Lorentz 4-vector
  virtual LorentzVector l4vec() const=0;

  //  return the space component of Lorentz 4-vector
  virtual SpaceVector s3vec() const=0;

  virtual float charge() const=0;

  //  return an identifying index
  virtual int index() const=0;

  //  return object type
  virtual int typeID() const=0;

  //  return vertex index
  virtual int vtxindex() const=0;

  // return error Matrix for px, py, pz (symmetric 3x3)
  virtual void errMatrix(Matrix &m) const=0;

  virtual Quality quality() const=0;

};

#endif // INC_D0PHYSOBJ
Received: from d0sgi0.fnal.gov (d0sgi0.fnal.gov [131.225.221.44]) by d0sgim.fnal.gov (980427.SGI.8.8.8/970903.SGI.AUTOCF) via SMTP id RAA02171 for <\meena@d0sgim.fnal.gov>; Mon, 26 Oct 1998 17:43:07 -0600 (CST)
Received: from FNAL.FNAL.Gov (fnal.fnal.gov [131.225.9.8]) by d0sgi0.fnal.gov (950413.SGI.8.6.12/950213.SGI.AUTOCF) via ESMTP id RAA00836; Mon, 26 Oct 1998 17:43:06 -0600
Received: from D04.PHY.BNL.GOV ("port 1164"@d04.phy.bnl.gov)
 by FNAL.FNAL.GOV (PMDF V5.1-10 #3998)
 with SMTP id <01J3FO4O8UV0000AQ6@FNAL.FNAL.GOV>; Mon,
 26 Oct 1998 17:43:03 -0600 CST
Date: Mon, 26 Oct 1998 18:44:29 -0500 (EST)
From: SERBAN PROTOPOPESCU 344-3721 <SERBAN@D01.phy.BNL.gov> (516)
Subject: revised D0PhysObj.hpp and KinemUtil.hpp
To: "d0bnl3::womersley"@D01.phy.BNL.gov, HEINSON@UCRPH0.UCR.EDU,
        norman@fnal.gov, blessing@fsheb2.hep.FSU.EDU, skulik@fnal.gov,
        barberis@fnald0, trippe@LBL.gov, meena@fnal.gov, stichel@fnald0,
        adams@physics.rice.edu
Cc: SERBAN@D01.phy.BNL.gov
Message-id: <981026184429.20200a1d@D01.PHY.BNL.GOV>
X-Vmsmail-To: @RUN2_ALGO
X-Vmsmail-Cc: SERBAN

                                                            bnld0, 26-OCT-1998

    Following Herb Greenlee's corrections below are revised versions
of D0PhysObj.hpp and KinemUtil.hpp.

                                   Serban 


D0PhysObj.hpp
=============

#ifndef INC_D0PHYSOBJ
#define INC_D0PHYSOBJ
//////////////////////////////////////////////////////////////////////
//  File: D0PhysObj.hpp
//
//  Purpose: define access methods
//           Should be inherited by all constructed objects
//           that have a 4-momentum
//
//  Created: 29-SEP-1998  Serban Protopopescu
//
//////////////////////////////////////////////////////////////////////  

class LorentzVector;
class Matrix;
class SpaceVector;
class Quality;

class D0PhysObj{

 public:

  // constructors
  D0PhysObj(){;}

  virtual ~D0PhysObj(){;}

  //   Interface methods

  //  return 4-vector components and simple derived quantities
  virtual float px() const=0;
  virtual float py() const=0;
  virtual float pz() const=0;
  virtual float E() const=0;
  virtual float pT() const=0; 
  virtual float phi() const=0;
  virtual float eta() const=0;
  virtual float theta() const=0;
  virtual float p() const=0;

  //  return Lorentz 4-vector as an array
  virtual void p4vec(float p4v[4]) const=0;

  //  return Lorentz 4-vector
  virtual const LorentzVector& l4vec() const=0;

  //  return the space component of Lorentz 4-vector
  virtual const SpaceVector& s3vec() const=0;

  virtual float charge() const=0;

  //  return an identifying index
  virtual int index() const=0;

  //  return object type
  virtual int typeID() const=0;

  //  return vertex index
  virtual int vtxindex() const=0;

  // return error Matrix for px, py, pz (symmetric 3x3)
  virtual const Matrix& errMatrix() const=0;

  virtual Quality quality() const=0;

};

#endif // INC_D0PHYSOBJ


#ifndef INC_KINEMUTIL
#define INC_KINEMUTIL
///////////////////////////////////////////////////////////////////////////////
// File: KinemUtil.hpp
// 
// Purpose:  Provide useful functions for physics objects
//           all functions in this class are static and inline
//
// Created:   12-OCT-1998  Serban Protopopescu
// History:   
///////////////////////////////////////////////////////////////////////////////
// Dependencies (#includes)

#include <math.h>
#include <stdlib.h>

#ifndef INC_PI
#define INC_PI
const float PI=2.*acos(0.);
const float TWOPI=2.*PI;
#endif // INC_PI

///////////////////////////////////////////////////////////////////////////////

class KinemUtil{

public:
    
  //  calculate phi from x, y
  static float phi(float x, float y);

  //  calculate theta from x, y, z
  static float theta(float x, float y, float z);

  //  calculate eta from x, y, z (return also theta)
  static float eta(float x, float y, float z);

  //  calculate eta from theta
  static float eta(float th);

private:

  // Not constructable

  KinemUtil();  
};

inline
float KinemUtil::phi(float x, float y)
{
  float PHI=atan2(y, x);
  return (PHI>=0)? PHI : TWOPI+PHI;
}

inline 
float KinemUtil::theta(float x, float y, float z)
{
  return atan2(sqrt(x*x + y*y), z);
}

inline
float KinemUtil::eta(float x, float y, float z)
{
  return (z>0) ?
    log((sqrt(x*x + y*y + z*z) + z) / sqrt(x*x + y*y)) :
    log(sqrt(x*x + y*y) / (sqrt(x*x + y*y + z*z) - z));
}

inline
float KinemUtil::eta(float th)
{
  if(th == 0) return 15.0;
  if(th >= PI-0.0001) return -15.0;
  return -log(tan(th/2.));
}

#endif // INC_KINEMUTIL

