CaloCellGeometry

RefCount

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
#ifndef GEOMETRY_CALOGEOMETRY_CALOCELLGEOMETRY_H
#define GEOMETRY_CALOGEOMETRY_CALOCELLGEOMETRY_H 1

#include "Geometry/CaloGeometry/interface/EZArrayFL.h"
#include "DataFormats/GeometryVector/interface/GlobalPoint.h"
#include "DataFormats/GeometryVector/interface/GlobalVector.h"
#include <CLHEP/Geometry/Point3D.h>
#include <CLHEP/Geometry/Transform3D.h>
#include "DataFormats/Math/interface/PtEtaPhiMass.h"

#include <vector>
#include <array>
#include <string>
#include <cassert>
#include <atomic>

/** \class CaloCellGeometry

Abstract base class for an individual cell's geometry.

The base class declares a pure virtual function and also writes a definition (body)
to force conscious acceptance of default behaviour.

If a derived class doesn't choose to override a normal virtual,
it just inherits the base version's behaviour by default. If you want
to provide a default behaviour but not let derived classes just inherit
it "silently" like this, you can make it pure virtual but still provide
a default that the derived class author has to call deliberately if he wants it:

@code
   class B {
     public:
         virtual bool f() = 0;
     };

     bool B::f() {
         return true;  // this is a good default, but
     }                 // shouldn't be used blindly

     class D : public B {
     public:
         bool f() {
             return B::f(); // if D wants the default
         }                  // behaviour, it has to say so
    };
@endcode

\author J. Mans, P. Meridiani
*/

class CaloCellGeometry {
public:
  typedef float CCGFloat;
  typedef HepGeom::Transform3D Tr3D;
  typedef HepGeom::Point3D<CCGFloat> Pt3D;
  typedef std::vector<Pt3D> Pt3DVec;

  typedef EZArrayFL<GlobalPoint> CornersVec;
  typedef EZMgrFL<GlobalPoint> CornersMgr;

  typedef EZArrayFL<CCGFloat> ParVec;
  typedef std::vector<ParVec> ParVecVec;
  typedef EZMgrFL<CCGFloat> ParMgr;

  friend class CaloCellGeometryMayOwnPtr;

  static constexpr unsigned int k_cornerSize = 8;

  using RepCorners = std::array<RhoEtaPhi, k_cornerSize>;

  static const CCGFloat k_ScaleFromDDDtoGeant;

  virtual ~CaloCellGeometry();

  /// Returns the corner points of this cell's volume.
  CornersVec const& getCorners() const {
    assert(not m_corners.uninitialized());
    return m_corners;
  }
  RepCorners const& getCornersREP() const { return m_repCorners; }

  /// Returns the position of reference for this cell
  virtual const GlobalPoint& getPosition() const { return m_refPoint; }
  virtual GlobalPoint getPosition(CCGFloat) const { return m_refPoint; }
  virtual GlobalPoint getPosition(const Pt3D&) const { return m_refPoint; }

  GlobalPoint const& getBackPoint() const { return m_backPoint; }

  RhoEtaPhi const& repPos() const { return m_rep; }
  virtual float rhoPos() const { return m_rep.rho(); }
  virtual float etaPos() const { return m_rep.eta(); }
  virtual float phiPos() const { return m_rep.phi(); }

  virtual float etaSpan() const { return m_dEta; }
  virtual float phiSpan() const { return m_dPhi; }

  /// Returns true if the specified point is inside this cell
  bool inside(const GlobalPoint& point) const;

  bool emptyCorners() const { return m_corners.empty(); }

  const CCGFloat* param() const { return m_parms; }

  static const CCGFloat* checkParmPtr(const std::vector<CCGFloat>& vd, ParVecVec& pvv);

  static const CCGFloat* getParmPtr(const std::vector<CCGFloat>& vd, ParMgr* mgr, ParVecVec& pvv);

  ///----------- only needed by specific utility; overloaded when needed ----
  virtual void getTransform(Tr3D& tr, Pt3DVec* lptr) const;
  //------------------------------------------------------------------------
  void setBackPoint(const GlobalPoint& pos) { m_backPoint = pos; }

  virtual void vocalCorners(Pt3DVec& vec, const CCGFloat* pv, Pt3D& ref) const = 0;

protected:
  CaloCellGeometry(CornersVec::const_reference gp, CornersMgr* mgr, const CCGFloat* par);

  CaloCellGeometry(const CornersVec& cv, const CCGFloat* par);

  CaloCellGeometry();

  CaloCellGeometry(CaloCellGeometry&&) = default;
  CaloCellGeometry(CaloCellGeometry const&) = default;
  CaloCellGeometry& operator=(CaloCellGeometry&&) = default;
  CaloCellGeometry& operator=(CaloCellGeometry const&) = default;
  // MUST be called by children constructors
  void initSpan() {
    initCorners(m_corners);
    m_dEta = std::abs(getCorners()[0].eta() - getCorners()[2].eta());
    m_dPhi = std::abs(getCorners()[0].phi() - getCorners()[2].phi());
    initBack();
    initReps();
  }

  virtual void initCorners(CornersVec&) = 0;

  void setRefPoint(const GlobalPoint& pos) { m_refPoint = pos; }
  void setCornerVec(const std::vector<GlobalPoint>& cor) {
    for (unsigned int k = 0; k < cor.size(); ++k)
      m_corners[k] = cor[k];
  }

private:
  void initBack() {
    // from CaloTower code
    CornersVec const& cv = getCorners();
    m_backPoint = GlobalPoint(0.25 * (cv[4].x() + cv[5].x() + cv[6].x() + cv[7].x()),
                              0.25 * (cv[4].y() + cv[5].y() + cv[6].y() + cv[7].y()),
                              0.25 * (cv[4].z() + cv[5].z() + cv[6].z() + cv[7].z()));
  }
  void initReps() {
    for (auto i = 0U; i < k_cornerSize; ++i)
      m_repCorners[i] = {getCorners()[i].perp(), getCorners()[i].eta(), getCorners()[i].barePhi()};
  }

  //These methods are ONLY used by CaloCellGeometryMayOwnPtr
  void increment() const { ++m_ref.m_count; }
  bool decrement() const { return 0 == --m_ref.m_count; }

  GlobalPoint m_refPoint;
  GlobalPoint m_backPoint;
  CornersVec m_corners;
  const CCGFloat* m_parms;
  RhoEtaPhi m_rep;
  float m_dEta;
  float m_dPhi;
  std::array<RhoEtaPhi, k_cornerSize> m_repCorners;
  struct RefCount {
    RefCount() = default;
    RefCount(RefCount&&) {}
    RefCount(RefCount const&) {}
    RefCount& operator=(RefCount&&) { return *this; }
    RefCount& operator=(const RefCount&) { return *this; }

    mutable std::atomic<unsigned int> m_count = 0;
  } m_ref;
};

std::ostream& operator<<(std::ostream& s, const CaloCellGeometry& cell);

#endif