CMS 3D CMS Logo

PositionCalc.h
Go to the documentation of this file.
1 #ifndef RecoEcal_EgammaCoreTools_PositionCalc_h
2 #define RecoEcal_EgammaCoreTools_PositionCalc_h
3 
14 #include <vector>
15 #include <map>
16 
28 
29 class PositionCalc {
30 public:
31  typedef std::vector<std::pair<DetId, float> > HitsAndFractions;
32  typedef std::vector<std::pair<DetId, double> > HitsAndEnergies;
33  // You must call Initialize before you can calculate positions or
34  // covariances.
35 
36  PositionCalc(const edm::ParameterSet& par);
38 
39  const PositionCalc& operator=(const PositionCalc& rhs);
40 
41  // Calculate_Location calculates an arithmetically or logarithmically
42  // weighted average position of a vector of DetIds, which should be
43  // a subset of the map used to Initialize.
44 
45  template <typename HitType>
47  const edm::SortedCollection<HitType>* iRecHits,
48  const CaloSubdetectorGeometry* iSubGeom,
49  const CaloSubdetectorGeometry* iESGeom = nullptr);
50 
51 private:
56  double param_W0_;
57  double param_X0_;
58 
60  bool m_esPlus;
61  bool m_esMinus;
62 };
63 
64 template <typename HitType>
66  const edm::SortedCollection<HitType>* iRecHits,
67  const CaloSubdetectorGeometry* iSubGeom,
68  const CaloSubdetectorGeometry* iESGeom) {
69  typedef edm::SortedCollection<HitType> HitTypeCollection;
70  math::XYZPoint returnValue(0, 0, 0);
71 
72  // Throw an error if the cluster was not initialized properly
73 
74  if (nullptr == iRecHits || nullptr == iSubGeom) {
75  throw cms::Exception("PositionCalc") << "Calculate_Location() called uninitialized or wrong initialization.";
76  }
77 
78  if (!iDetIds.empty() && !iRecHits->empty()) {
79  HitsAndEnergies detIds;
80  detIds.reserve(iDetIds.size());
81 
82  double eTot(0);
83  double eMax(0);
84  DetId maxId;
85 
86  // Check that DetIds are nonzero
87  typename HitTypeCollection::const_iterator endRecHits(iRecHits->end());
88  HitsAndFractions::const_iterator n, endDiDs(iDetIds.end());
89  for (n = iDetIds.begin(); n != endDiDs; ++n) {
90  const DetId dId((*n).first);
91  const float frac((*n).second);
92  if (!dId.null()) {
93  typename HitTypeCollection::const_iterator iHit(iRecHits->find(dId));
94  if (iHit != endRecHits) {
95  const double energy(iHit->energy() * frac);
96  detIds.push_back(std::make_pair(dId, energy));
97  if (0.0 < energy) { // only save positive energies
98  if (eMax < energy) {
99  eMax = energy;
100  maxId = dId;
101  }
102  eTot += energy;
103  }
104  }
105  }
106  }
107 
108  if (0.0 >= eTot) {
109  LogDebug("ZeroClusterEnergy") << "cluster with 0 energy: " << eTot << " size: " << detIds.size()
110  << " , returning (0,0,0)";
111  } else {
112  // first time or when es geom changes set flags
113  if (nullptr != iESGeom && m_esGeom != iESGeom) {
114  m_esGeom = iESGeom;
115  for (uint32_t ic(0); (ic != m_esGeom->getValidDetIds().size()) && ((!m_esPlus) || (!m_esMinus)); ++ic) {
116  const double z(m_esGeom->getGeometry(m_esGeom->getValidDetIds()[ic])->getPosition().z());
117  m_esPlus = m_esPlus || (0 < z);
118  m_esMinus = m_esMinus || (0 > z);
119  }
120  }
121 
122  //Select the correct value of the T0 parameter depending on subdetector
123  auto center_cell(iSubGeom->getGeometry(maxId));
124  const double ctreta(center_cell->getPosition().eta());
125 
126  // for barrel, use barrel T0;
127  // for endcap: if preshower present && in preshower fiducial,
128  // use preshower T0
129  // else use endcap only T0
130  const double preshowerStartEta = 1.653;
131  const int subdet = maxId.subdetId();
132  const double T0(subdet == EcalBarrel ? param_T0_barl_
133  : (((preshowerStartEta < fabs(ctreta)) &&
134  (((0 < ctreta) && m_esPlus) || ((0 > ctreta) && m_esMinus)))
136  : param_T0_endc_));
137 
138  // Calculate shower depth
139  const float maxDepth(param_X0_ * (T0 + log(eTot)));
140  const float maxToFront(center_cell->getPosition().mag()); // to front face
141 
142  // Loop over hits and get weights
143  double total_weight = 0;
144  const double eTot_inv = 1.0 / eTot;
145  const double logETot_inv = (param_LogWeighted_ ? log(eTot_inv) : 0);
146 
147  double xw(0);
148  double yw(0);
149  double zw(0);
150 
151  HitsAndEnergies::const_iterator j, hAndE_end = detIds.end();
152  for (j = detIds.begin(); j != hAndE_end; ++j) {
153  const DetId dId((*j).first);
154  const double e_j((*j).second);
155 
156  double weight = 0;
157  if (param_LogWeighted_) {
158  if (e_j > 0.0) {
159  weight = std::max(0., param_W0_ + log(e_j) + logETot_inv);
160  } else {
161  weight = 0;
162  }
163  } else {
164  weight = e_j * eTot_inv;
165  }
166 
167  auto cell(iSubGeom->getGeometry(dId));
168  const float depth(maxDepth + maxToFront - cell->getPosition().mag());
169 
170  const GlobalPoint pos(cell->getPosition(depth));
171 
172  xw += weight * pos.x();
173  yw += weight * pos.y();
174  zw += weight * pos.z();
175 
176  total_weight += weight;
177  }
178  returnValue = math::XYZPoint(xw / total_weight, yw / total_weight, zw / total_weight);
179  }
180  }
181  return returnValue;
182 }
183 
184 #endif
double param_T0_endc_
Definition: PositionCalc.h:54
double param_W0_
Definition: PositionCalc.h:56
Definition: weight.py:1
std::vector< std::pair< DetId, float > > HitsAndFractions
Definition: PositionCalc.h:31
double param_X0_
Definition: PositionCalc.h:57
const PositionCalc & operator=(const PositionCalc &rhs)
Definition: PositionCalc.cc:15
constexpr bool null() const
is this a null id ?
Definition: DetId.h:59
bool param_LogWeighted_
Definition: PositionCalc.h:52
double param_T0_endcPresh_
Definition: PositionCalc.h:55
virtual const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const
Get a list of valid detector ids (for the given subdetector)
math::XYZPoint Calculate_Location(const HitsAndFractions &iDetIds, const edm::SortedCollection< HitType > *iRecHits, const CaloSubdetectorGeometry *iSubGeom, const CaloSubdetectorGeometry *iESGeom=nullptr)
Definition: PositionCalc.h:65
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
const_iterator end() const
Definition: DetId.h:17
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
double param_T0_barl_
Definition: PositionCalc.h:53
iterator find(key_type k)
auto zw(V v) -> Vec2< typename std::remove_reference< decltype(v[0])>::type >
Definition: ExtVec.h:71
const CaloSubdetectorGeometry * m_esGeom
Definition: PositionCalc.h:59
std::vector< std::pair< DetId, double > > HitsAndEnergies
Definition: PositionCalc.h:32
#define LogDebug(id)