ATLAS Offline Software
TotPixelClusterSplitter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "GaudiKernel/ServiceHandle.h"
10 
12 
14 #include <algorithm> //minmax_element
15 #include <tuple> //std::tuple
16 
17 InDet::TotPixelClusterSplitter::TotPixelClusterSplitter(const std::string & type, const std::string & name, const IInterface * parent) :
18  base_class(type, name, parent),
19  m_minPixels(3),
20  m_maxPixels(25)
21 {
22 }
23 
25 
26  ATH_CHECK(m_pixelReadout.retrieve());
28 
29  return StatusCode::SUCCESS;
30 }
31 
33  return StatusCode::SUCCESS;
34 }
35 
36 std::vector<InDet::PixelClusterParts>
38 
39  std::vector<InDet::PixelClusterParts> Parts;
40 
41  const std::vector<Identifier> & Rdos = OrigCluster.rdoList();
42  const unsigned int NumPixels = static_cast<unsigned int>(Rdos.size());
43  const InDetDD::SiDetectorElement * Element = OrigCluster.detectorElement();
44 
45  // Check cluster-size bounds.
46  if (NumPixels < m_minPixels || NumPixels > m_maxPixels) return Parts;
47 
48  std::vector<InDetDD::SiCellId> CellIds(NumPixels); //NumPixels entries of default constructed SiCellId
49 
50  auto getCellId=[Element](const Identifier & i){ return Element->cellIdFromIdentifier(i);};
51  std::transform(Rdos.begin(),Rdos.end(), CellIds.begin(), getCellId);
52 
54  const PixelChargeCalibCondData *calibData = *calibDataHandle;
55 
56  // Detect special pixels and exclude them if necessary.
57  // Veto removed on 28-7-2011 by K. Barry - residual-level
58  // studies show RMS improvement when ganged-pixel containing
59  // clusters are split.
60 
61 
62  // Determine maximum and minimum phi and eta indices.
63  auto comparePhi=[](const InDetDD::SiCellId & a, const InDetDD::SiCellId & b){ return (a.phiIndex() < b.phiIndex());};
64  auto compareEta=[](const InDetDD::SiCellId & a, const InDetDD::SiCellId & b){ return (a.etaIndex() < b.etaIndex());};
65  const auto [pMinPhi,pMaxPhi] = std::minmax_element(CellIds.begin(), CellIds.end(), comparePhi);
66  const auto [pMinEta,pMaxEta] = std::minmax_element(CellIds.begin(), CellIds.end(), compareEta);
67  const auto & MinPhiIdx = pMinPhi->phiIndex();
68  const auto & MaxPhiIdx = pMaxPhi->phiIndex();
69  const auto & MinEtaIdx = pMinEta->etaIndex();
70  const auto & MaxEtaIdx = pMaxEta->etaIndex();
71  const int PhiWidth = MaxPhiIdx - MinPhiIdx + 1;
72  const int EtaWidth = MaxEtaIdx - MinEtaIdx + 1;
73 
74  // In the future, might want to add a check here to see if the charge list is empty...
75  const std::vector<float> & Charges = OrigCluster.chargeList();
76 
77  std::vector<float> PhiChargeHist(PhiWidth, 0.);
78  unsigned int NumPhiMinima = 0;
79  std::vector<unsigned int> PhiMinimaLoc(PhiWidth/2);
80  std::vector<float> PhiMinimaQuality(PhiWidth/2);
81  if (PhiWidth > 2)
82  {
83  // Fill up the phi-charge histogram. The values were initialized to zero by the vector constructor.
84  for (unsigned int i = 0; i < NumPixels; i++)
85  PhiChargeHist[CellIds[i].phiIndex() - MinPhiIdx] += Charges[i];
86 
87  // Minima search
88  for (int i = 1; i < PhiWidth - 1; i++)
89  {
90  if (PhiChargeHist[i-1] <= PhiChargeHist[i] || PhiChargeHist[i] >= PhiChargeHist[i+1]) continue;
91 
92  PhiMinimaLoc[NumPhiMinima] = static_cast<unsigned int>(i);
93  PhiMinimaQuality[NumPhiMinima++] = (PhiChargeHist[i+1] + PhiChargeHist[i-1] - 2.*PhiChargeHist[i]) /
94  (PhiChargeHist[i+1] + PhiChargeHist[i-1]);
95  }
96  }
97 
98  std::vector<float> EtaChargeHist(EtaWidth, 0.);
99  unsigned int NumEtaMinima = 0;
100  std::vector<unsigned int> EtaMinimaLoc(EtaWidth/2);
101  std::vector<float> EtaMinimaQuality(EtaWidth/2);
102  const float LongPixScale = 2./3.;
103  if (EtaWidth > 2)
104  {
105  float Scale;
106  // Fill up the eta-charge histogram. The values were initialized to zero by the vector constructor.
107  for (unsigned int i = 0; i < NumPixels; i++)
108  {
109  const int PixType = pixelType(CellIds[i].phiIndex(), CellIds[i].etaIndex());
110  if ( (PixType % 2) == 1 )
111  Scale = LongPixScale;
112  else
113  Scale = 1.;
114  EtaChargeHist[CellIds[i].etaIndex() - MinEtaIdx] += Scale*Charges[i];
115  }
116 
117  // Minima search
118  for (int i = 1; i < EtaWidth - 1; i++)
119  {
120  if (EtaChargeHist[i-1] <= EtaChargeHist[i] || EtaChargeHist[i] >= EtaChargeHist[i+1]) continue;
121 
122  EtaMinimaLoc[NumEtaMinima] = static_cast<unsigned int>(i);
123  EtaMinimaQuality[NumEtaMinima++] = (EtaChargeHist[i+1] + EtaChargeHist[i-1] - 2.*EtaChargeHist[i]) /
124  (EtaChargeHist[i+1] + EtaChargeHist[i-1]);
125  }
126  }
127 
128  // Select the "best" minimum for splitting
129  unsigned int bestMin = 0;
130  float bestQual = -1.;
132  for (unsigned int i = 0; i < NumPhiMinima; i++)
133  {
134  if (PhiMinimaQuality[i] <= bestQual) continue;
135  Type = PhiSplit;
136  bestMin = PhiMinimaLoc[i];
137  bestQual = PhiMinimaQuality[i];
138  }
139  for (unsigned int i = 0; i < NumEtaMinima; i++)
140  {
141  if (EtaMinimaQuality[i] <= bestQual) continue;
142  Type = EtaSplit;
143  bestMin = EtaMinimaLoc[i];
144  bestQual = EtaMinimaQuality[i];
145  }
146  const int SplitIndex = static_cast<int>(bestMin);
147 
148  // Now it's time to do the split!
149  if (Type == NoSplit)
150  {
151  return Parts;
152  }
153  if (Type != PhiSplit && Type != EtaSplit)
154  {
155  // Should never happen...major bug someplace if it does
156  ATH_MSG_ERROR("<InDet::TotPixelClusterSplitter::splitCluster> : Unrecognized SplitType!");
157  return Parts;
158  }
159 
160  int Idx;
161  int (InDetDD::SiCellId:: * const IndexFunc) () const = (Type == PhiSplit) ? &InDetDD::SiCellId::phiIndex
163  const int LowIdx = (Type == PhiSplit) ? MinPhiIdx : MinEtaIdx;
164 
165  // Variables for PixelClusterParts
166  std::vector<Identifier> SplitRdos[2];
167  std::vector<int> Totgroups[2];
168  std::vector<int> Lvl1groups[2];
169 
170  const std::vector<int>& OrigTots = OrigCluster.totList();
171  const int Lvl1a = OrigCluster.LVL1A();
172 
173  const AtlasDetectorID* aid = Element->getIdHelper();
174  if (aid==nullptr)
175  {
176  ATH_MSG_ERROR("Could not get ATLASDetectorID");
177  return Parts;
178  }
179 
181  ATH_MSG_ERROR("Could not get PixelID pointer");
182  return Parts;
183  }
184  const PixelID* pixelIDp=static_cast<const PixelID*>(aid);
185  const PixelID& pixelID = *pixelIDp;
186 
187 
188  for (unsigned int i = 0; i < NumPixels; i++)
189  {
190  Idx = (CellIds[i].*IndexFunc)() - LowIdx;
191  if (Idx < SplitIndex)
192  {
193  SplitRdos[0].push_back(Rdos[i]);
194  Totgroups[0].push_back(OrigTots[i]);
195  Lvl1groups[0].push_back(Lvl1a);
196  }
197  else if (Idx > SplitIndex)
198  {
199  SplitRdos[1].push_back(Rdos[i]);
200  Totgroups[1].push_back(OrigTots[i]);
201  Lvl1groups[1].push_back(Lvl1a);
202  }
203  else // only == remains
204  {
205  for (int j = 0; j < 2; j++)
206  {
207 
208  Identifier pixid = Rdos[i];
209  Identifier moduleID = pixelID.wafer_id(pixid);
210  IdentifierHash moduleHash = pixelID.wafer_hash(moduleID); // wafer hash
211  unsigned int FE = m_pixelReadout->getFE(pixid, moduleID);
212  InDetDD::PixelDiodeType type = m_pixelReadout->getDiodeType(pixid);
213 
214  SplitRdos[j].push_back(Rdos[i]);
215  Totgroups[j].push_back(calibData->getToT(type, moduleHash, FE, Charges[i] / 2.0));
216  Lvl1groups[j].push_back(Lvl1a);
217  }
218  }
219  }
220 
221  Parts.emplace_back(SplitRdos[0], Totgroups[0], Lvl1groups[0]);
222  Parts.emplace_back(SplitRdos[1], Totgroups[1], Lvl1groups[1]);
223 
224  return Parts;
225 }
226 
227 std::vector<InDet::PixelClusterParts> InDet::TotPixelClusterSplitter::splitCluster(
228  const InDet::PixelCluster & OrigCluster,
229  const InDet::PixelClusterSplitProb &) const
230 {
231  return splitCluster(OrigCluster);
232 }
233 
234 int InDet::TotPixelClusterSplitter::pixelType(const int PhiIdx, const int EtaIdx)
235 {
236  if (EtaIdx%18 != 0 && EtaIdx%18 != 17)
237  {
238  if (PhiIdx==152 || PhiIdx==154 || PhiIdx==156 || PhiIdx==158 ||
239  PhiIdx==169 || PhiIdx==171 || PhiIdx==173 || PhiIdx==175)
240  return 4; // short inter-ganged pixel
241  else if (PhiIdx==153 || PhiIdx==155 || PhiIdx==157 || PhiIdx==159 ||
242  (PhiIdx > 159 && PhiIdx < 168) ||
243  PhiIdx==168 || PhiIdx==170 || PhiIdx==172 || PhiIdx==174)
244  return 2; // short ganged pixel
245  else
246  return 0; // short normal pixel
247  }
248  else
249  {
250  if (PhiIdx==152 || PhiIdx==154 || PhiIdx==156 || PhiIdx==158 ||
251  PhiIdx==169 || PhiIdx==171 || PhiIdx==173 || PhiIdx==175)
252  return 5; // long inter-ganged pixel
253  else if (PhiIdx==153 || PhiIdx==155 || PhiIdx==157 || PhiIdx==159 ||
254  (PhiIdx > 159 && PhiIdx < 168) ||
255  PhiIdx==168 || PhiIdx==170 || PhiIdx==172 || PhiIdx==174)
256  return 3; // long ganged pixel
257  else
258  return 1; // long normal pixel
259  }
260 }
261 
PixelChargeCalibCondData::getToT
float getToT(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float Q) const
Definition: PixelChargeCalibCondData.cxx:174
InDet::TotPixelClusterSplitter::EtaSplit
@ EtaSplit
Definition: TotPixelClusterSplitter.h:79
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
AtlasDetectorID::HelperType::Pixel
@ Pixel
InDet::PixelClusterSplitProb
Definition: PixelClusterSplitProb.h:25
PixelCluster.h
InDetDD::PixelDiodeType
PixelDiodeType
Definition: PixelReadoutDefinitions.h:25
Trk::PrepRawData::rdoList
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
InDet::TotPixelClusterSplitter::NoSplit
@ NoSplit
Definition: TotPixelClusterSplitter.h:79
InDet::TotPixelClusterSplitter::pixelType
static int pixelType(const int PhiIdx, const int EtaIdx)
Determine a pixel's type.
Definition: TotPixelClusterSplitter.cxx:234
InDet::TotPixelClusterSplitter::finalize
virtual StatusCode finalize() override
Definition: TotPixelClusterSplitter.cxx:32
TotPixelClusterSplitter.h
InDet::TotPixelClusterSplitter::initialize
virtual StatusCode initialize() override
AthAlgTool interface methods.
Definition: TotPixelClusterSplitter.cxx:24
InDetDD::SiCellId::phiIndex
int phiIndex() const
Get phi index. Equivalent to strip().
Definition: SiCellId.h:122
InDet::TotPixelClusterSplitter::m_chargeDataKey
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
Definition: TotPixelClusterSplitter.h:85
InDet::PixelCluster::totList
const std::vector< int > & totList() const
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:201
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:364
InDet::TotPixelClusterSplitter::splitCluster
virtual std::vector< InDet::PixelClusterParts > splitCluster(const InDet::PixelCluster &OrigCluster) const override
take one, give zero or many
Definition: TotPixelClusterSplitter.cxx:37
InDetDD::SolidStateDetectorElementBase::getIdHelper
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
Muon::PhiIdx
MuonStationIndex::PhiIndex PhiIdx
Definition: MuonTruthHitPlots.cxx:10
GeoPrimitives.h
InDetDD::SiDetectorElement::cellIdFromIdentifier
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
Definition: SiDetectorElement.cxx:120
InDetDD::SiCellId::etaIndex
int etaIndex() const
Get eta index.
Definition: SiCellId.h:114
PixelID::wafer_hash
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition: PixelID.h:387
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
InDet::TotPixelClusterSplitter::m_pixelReadout
ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout
Definition: TotPixelClusterSplitter.h:82
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
PixelChargeCalibCondData
Definition: PixelChargeCalibCondData.h:24
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
test_pyathena.parent
parent
Definition: test_pyathena.py:15
InDet::PixelCluster::LVL1A
int LVL1A() const
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:269
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Scale
void Scale(TH1 *h, double d=1)
Definition: comparitor.cxx:77
xAODType
Definition: ObjectType.h:13
InDet::SiCluster::detectorElement
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
AtlasDetectorID::helper
virtual HelperType helper() const
Type of helper, defaulted to 'Unimplemented'.
Definition: AtlasDetectorID.h:95
EventPrimitives.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
InDet::TotPixelClusterSplitter::TotPixelClusterSplitter
TotPixelClusterSplitter(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
Definition: TotPixelClusterSplitter.cxx:17
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
SiDetectorElement.h
InDetDD::SiCellId
Definition: SiCellId.h:29
eflowRec::phiIndex
unsigned int phiIndex(float phi, float binsize)
calculate phi index for a given phi
Definition: EtaPhiLUT.cxx:23
InDet::PixelCluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:49
InDet::TotPixelClusterSplitter::m_maxPixels
unsigned int m_maxPixels
Maximum size of cluster for which splitting will be attempted.
Definition: TotPixelClusterSplitter.h:91
a
TList * a
Definition: liststreamerinfos.cxx:10
InDet::TotPixelClusterSplitter::PhiSplit
@ PhiSplit
Definition: TotPixelClusterSplitter.h:79
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
PixelID
Definition: PixelID.h:67
AtlasDetectorID
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
Definition: AtlasDetectorID.h:57
InDet::TotPixelClusterSplitter::SplitType
SplitType
Definition: TotPixelClusterSplitter.h:79
InDet::PixelCluster::chargeList
const std::vector< float > & chargeList() const
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:209
Identifier
Definition: IdentifierFieldParser.cxx:14