37 {
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 const InDetDD::PixelModuleDesign& design =
dynamic_cast<const InDetDD::PixelModuleDesign&
>(Element->
design());
45
46
47 if (NumPixels < m_minPixels || NumPixels >
m_maxPixels)
return Parts;
48
49 std::vector<InDetDD::SiCellId> CellIds(NumPixels);
50
52 std::transform(Rdos.begin(),Rdos.end(), CellIds.begin(), getCellId);
53
54 SG::ReadCondHandle<PixelChargeCalibCondData> calibDataHandle(
m_chargeDataKey);
55 const PixelChargeCalibCondData *calibData = *calibDataHandle;
56
57
58
59
60
61
62
63
64 auto comparePhi=[](
const InDetDD::SiCellId &
a,
const InDetDD::SiCellId &
b){
return (
a.phiIndex() <
b.phiIndex());};
65 auto compareEta=[](
const InDetDD::SiCellId &
a,
const InDetDD::SiCellId &
b){
return (
a.etaIndex() <
b.etaIndex());};
66 const auto [pMinPhi,pMaxPhi] = std::minmax_element(CellIds.begin(), CellIds.end(), comparePhi);
67 const auto [pMinEta,pMaxEta] = std::minmax_element(CellIds.begin(), CellIds.end(), compareEta);
68 const auto & MinPhiIdx = pMinPhi->phiIndex();
69 const auto & MaxPhiIdx = pMaxPhi->phiIndex();
70 const auto & MinEtaIdx = pMinEta->etaIndex();
71 const auto & MaxEtaIdx = pMaxEta->etaIndex();
72 const int PhiWidth = MaxPhiIdx - MinPhiIdx + 1;
73 const int EtaWidth = MaxEtaIdx - MinEtaIdx + 1;
74
75
76 const std::vector<float> & Charges = OrigCluster.
chargeList();
77
78 std::vector<float> PhiChargeHist(PhiWidth, 0.);
79 unsigned int NumPhiMinima = 0;
80 std::vector<unsigned int> PhiMinimaLoc(PhiWidth/2);
81 std::vector<float> PhiMinimaQuality(PhiWidth/2);
82 if (PhiWidth > 2)
83 {
84
85 for (
unsigned int i = 0;
i < NumPixels;
i++)
86 PhiChargeHist[CellIds[i].
phiIndex() - MinPhiIdx] += Charges[
i];
87
88
89 for (
int i = 1;
i < PhiWidth - 1;
i++)
90 {
91 if (PhiChargeHist[i-1] <= PhiChargeHist[i] || PhiChargeHist[i] >= PhiChargeHist[i+1]) continue;
92
93 PhiMinimaLoc[NumPhiMinima] =
static_cast<unsigned int>(
i);
94 PhiMinimaQuality[NumPhiMinima++] = (PhiChargeHist[
i+1] + PhiChargeHist[
i-1] - 2.*PhiChargeHist[
i]) /
95 (PhiChargeHist[i+1] + PhiChargeHist[i-1]);
96 }
97 }
98
99 std::vector<float> EtaChargeHist(EtaWidth, 0.);
100 unsigned int NumEtaMinima = 0;
101 std::vector<unsigned int> EtaMinimaLoc(EtaWidth/2);
102 std::vector<float> EtaMinimaQuality(EtaWidth/2);
103 const float LongPixScale = 2./3.;
104 if (EtaWidth > 2)
105 {
107
108 for (
unsigned int i = 0;
i < NumPixels;
i++)
109 {
111 if ( (PixType % 2) == 1 )
112 Scale = LongPixScale;
113 else
115 EtaChargeHist[CellIds[
i].etaIndex() - MinEtaIdx] +=
Scale*Charges[
i];
116 }
117
118
119 for (
int i = 1;
i < EtaWidth - 1;
i++)
120 {
121 if (EtaChargeHist[i-1] <= EtaChargeHist[i] || EtaChargeHist[i] >= EtaChargeHist[i+1]) continue;
122
123 EtaMinimaLoc[NumEtaMinima] =
static_cast<unsigned int>(
i);
124 EtaMinimaQuality[NumEtaMinima++] = (EtaChargeHist[
i+1] + EtaChargeHist[
i-1] - 2.*EtaChargeHist[
i]) /
125 (EtaChargeHist[i+1] + EtaChargeHist[i-1]);
126 }
127 }
128
129
130 unsigned int bestMin = 0;
131 float bestQual = -1.;
133 for (
unsigned int i = 0;
i < NumPhiMinima;
i++)
134 {
135 if (PhiMinimaQuality[i] <= bestQual) continue;
137 bestMin = PhiMinimaLoc[
i];
138 bestQual = PhiMinimaQuality[
i];
139 }
140 for (
unsigned int i = 0;
i < NumEtaMinima;
i++)
141 {
142 if (EtaMinimaQuality[i] <= bestQual) continue;
144 bestMin = EtaMinimaLoc[
i];
145 bestQual = EtaMinimaQuality[
i];
146 }
147 const int SplitIndex = static_cast<int>(bestMin);
148
149
151 {
152 return Parts;
153 }
155 {
156
157 ATH_MSG_ERROR(
"<InDet::TotPixelClusterSplitter::splitCluster> : Unrecognized SplitType!");
158 return Parts;
159 }
160
161 int Idx;
164 const int LowIdx = (
Type ==
PhiSplit) ? MinPhiIdx : MinEtaIdx;
165
166
167 std::vector<Identifier> SplitRdos[2];
168 std::vector<int> Totgroups[2];
169 std::vector<int> Lvl1groups[2];
170
171 const std::vector<int>& OrigTots = OrigCluster.
totList();
172 const int Lvl1a = OrigCluster.
LVL1A();
173
174 const AtlasDetectorID* aid = Element->
getIdHelper();
175 if (aid==nullptr)
176 {
178 return Parts;
179 }
180
183 return Parts;
184 }
185 const PixelID* pixelIDp=static_cast<const PixelID*>(aid);
186 const PixelID& pixelID = *pixelIDp;
188
189 for (
unsigned int i = 0;
i < NumPixels;
i++)
190 {
191 Idx = (CellIds[
i].*IndexFunc)() - LowIdx;
192 if (Idx < SplitIndex)
193 {
194 SplitRdos[0].push_back(Rdos[i]);
195 Totgroups[0].push_back(OrigTots[i]);
196 Lvl1groups[0].push_back(Lvl1a);
197 }
198 else if (Idx > SplitIndex)
199 {
200 SplitRdos[1].push_back(Rdos[i]);
201 Totgroups[1].push_back(OrigTots[i]);
202 Lvl1groups[1].push_back(Lvl1a);
203 }
204 else
205 {
206 for (int j = 0; j < 2; j++)
207 {
208
209 Identifier pixid = Rdos[
i];
211 std::array<InDetDD::PixelDiodeTree::CellIndexType,2> diode_idx
215 std::uint32_t feValue = design.
getFE(si_param);
220 }
221
222 SplitRdos[j].push_back(Rdos[i]);
223 Totgroups[j].push_back(calibData->
getToT(diode_type, moduleHash, feValue, Charges[i] / 2.0));
224 Lvl1groups[j].push_back(Lvl1a);
225 }
226 }
227 }
228
229 Parts.emplace_back(SplitRdos[0], Totgroups[0], Lvl1groups[0]);
230 Parts.emplace_back(SplitRdos[1], Totgroups[1], Lvl1groups[1]);
231
232 return Parts;
233}
virtual HelperType helper() const
Type of helper, defaulted to 'Unimplemented'.
static constexpr std::array< PixelDiodeTree::CellIndexType, 2 > makeCellIndex(T local_x_idx, T local_y_idx)
Create a 2D cell index from the indices in local-x (phi, row) and local-y (eta, column) direction.
PixelDiodeTree::DiodeProxyWithPosition diodeProxyFromIdxCachePosition(const std::array< PixelDiodeTree::IndexType, 2 > &idx) const
virtual int numberOfConnectedCells(const SiReadoutCellId &readoutId) const
readout id -> id of connected diodes
PixelReadoutTechnology getReadoutTechnology() const
virtual SiReadoutCellId readoutIdOfCell(const SiCellId &cellId) const
diode id -> readout id
static InDetDD::PixelDiodeType getDiodeType(const PixelDiodeTree::DiodeProxy &diode_proxy)
static unsigned int getFE(const PixelDiodeTree::DiodeProxy &diode_proxy)
int phiIndex() const
Get phi index. Equivalent to strip().
int etaIndex() const
Get eta index.
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
const std::vector< int > & totList() const
const std::vector< float > & chargeList() const
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...
static int pixelType(const int PhiIdx, const int EtaIdx)
Determine a pixel's type.
float getToT(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float Q) const
int eta_index(const Identifier &id) const
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
int phi_index(const Identifier &id) const
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
void Scale(TH1 *h, double d=1)
unsigned int phiIndex(float phi, float binsize)
calculate phi index for a given phi