ATLAS Offline Software
PixelGangedAmbiguitiesFinder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //***************************************************************************
6 //
7 // Implementation for GlobalPositionMaker
8 //
9 //****************************************************************************
10 
12 
15 
19 
20 #include "GaudiKernel/SmartDataPtr.h"
21 #include "GaudiKernel/MsgStream.h"
22 #include "GaudiKernel/IToolSvc.h"
23 #include <vector>
24 #include <algorithm>
25 #include <cmath>
26 
27 namespace InDet{
28 
29 using namespace InDet;
30 
31 // Constructor with parameters:
33  const std::string &type,
34  const std::string &name,
35  const IInterface *parent) :
37 {
38  declareInterface<PixelGangedAmbiguitiesFinder>(this);
39 }
40 
43 
44  return StatusCode::SUCCESS;
45 }
46 
47 //----------------------------------------------------------------------------
48 // Execute method:
49 // Called by the PixelClusterization algorithms of InDetPrepRawDataFormation
50  // A map containing the pairs of Pixel Clusters which shares the same
51  // ganged pixel is created.
52  // Inputs are the cluster collection of a module, and the map to be filled.
53  // Output is the map.
55  PixelClusterCollection* collection,
56  PixelGangedClusterAmbiguities& theMap) const{
57  if (collection->size()<2) return;
58 
59  ATH_MSG_DEBUG(collection->size() << " clusters");
60  ATH_MSG_DEBUG("The map has " << theMap.size() << " entries already");
61 
62  IdentifierHash elementHash = collection->identifyHash();
63 
64  // Get detector info.
65  // Find detector element for these RDOs
66 
68  const InDetDD::SiDetectorElementCollection* pixelDetEle(*pixelDetEleHandle);
69  if (not pixelDetEleHandle.isValid() or pixelDetEle==nullptr) {
70  ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
71  return;
72  }
73  const InDetDD::SiDetectorElement* element = pixelDetEle->getDetectorElement(elementHash);
74  const InDetDD::PixelModuleDesign* design =(dynamic_cast<const InDetDD::PixelModuleDesign*>(&element->design()));
75  if (not design){
76  ATH_MSG_ERROR("Dynamic cast failed at line "<<__LINE__<<" of PixelGangedAmbiguitiesFinder.cxx.");
77  return;
78  }
79  int rowsPerFE = design->rows()/2;
80  const auto *pHelper = element->getIdHelper();
81  if (pHelper->helper() != AtlasDetectorID::HelperType::Pixel){
82  ATH_MSG_ERROR("The helper type is not Pixel at line "<<__LINE__<<" of PixelGangedAmbiguitiesFinder.cxx.");
83  return;
84  }
85  const PixelID* pixelID =static_cast<const PixelID*>(pHelper);
86  //Pointer list of clusters to be removed
87  std::vector<PixelClusterCollection::iterator> rmList;
88 
89  PixelClusterCollection::iterator cluster=collection->begin();
90  PixelClusterCollection::iterator clend=collection->end();
91 
92  for( ; cluster!=clend ; ++cluster){
93  // check if cluster has not already been flagged to be deleted
94  if ( find(rmList.begin(),rmList.end(),cluster)!=rmList.end() ) continue;
95 
96  // extract from the list of cluster rdo the ganged ones.
97  bool hasGanged = false;
98  int rmin1=999, cmin1=999; // bottom left corner of cluster
99  std::vector<Identifier> gangedPixels;
100  const std::vector<Identifier>& RDOs = (*cluster)->rdoList();
101 
102  std::vector<Identifier>::const_iterator rdo=RDOs.begin();
103  std::vector<Identifier>::const_iterator rdoend=RDOs.end();
104  for( ; rdo != rdoend; ++rdo){
105  Identifier gangedID;
106  bool ganged = isGanged(*rdo,element,gangedID);
107  if(ganged){
108  hasGanged = true;
109  gangedPixels.push_back(gangedID);
110  }
111  int thiscol=pixelID->eta_index(*rdo);
112  if (thiscol<cmin1) cmin1=thiscol;
113  int thisrow=pixelID->phi_index(*rdo);
114  if (thisrow<rmin1) rmin1=thisrow;
115 
116  }
117 
118  // set ganged pixels flag
119  (*cluster)->setGangedPixel(hasGanged);
120  // find out if any other cluster shares any of the ganged pixels
121 
122  if(hasGanged){
123 
124  ATH_MSG_DEBUG("Ganged pixel, find combi...");
125  std::vector<Identifier>::const_iterator gangedPixelsBegin = gangedPixels.begin();
126  std::vector<Identifier>::const_iterator gangedPixelsEnd = gangedPixels.end();
127  PixelClusterCollection::iterator cluster2=cluster+1;
128  for( ; cluster2!=clend; ++cluster2){
129  ATH_MSG_DEBUG("Comparing "
130  << std::hex << (*cluster)->identify()
131  << " and " << (*cluster2)->identify()
132  << std::dec);
133  bool sharedGanged = false;
134  int rmin2=999, cmin2=999; // bottom left corner of cluster2
135  const std::vector<Identifier>& rdos2 = (*cluster2)->rdoList();
136  std::vector<Identifier>::const_iterator rdo2=rdos2.begin();
137  std::vector<Identifier>::const_iterator rdo2end=rdos2.end();
138  for( ; rdo2!=rdo2end; ++rdo2) {
139  if (!sharedGanged) {
140  for( std::vector<Identifier>::const_iterator gangedRDOs=gangedPixelsBegin;
141  gangedRDOs < gangedPixelsEnd; ++gangedRDOs ){
142  if(*rdo2 == *gangedRDOs){
143  sharedGanged = true;
144  break;
145  }
146  }
147  }
148  int thiscol=pixelID->eta_index(*rdo2);
149  if (thiscol<cmin2) cmin2=thiscol;
150  int thisrow=pixelID->phi_index(*rdo2);
151  if (thisrow<rmin2) rmin2=thisrow;
152  //if ( sharedGanged ) break;
153  }
154 
155  if(sharedGanged){
156  // ganged clusters with just one row are likely to
157  // be fake if the ganged image of the same pixel is
158  // part of a cluster with more rows.
159  int drow1=lrint((**cluster).width().colRow().x() );
160  int drow2=lrint((**cluster2).width().colRow().x() );
161  int dcol1=lrint((**cluster).width().colRow().y() );
162  int dcol2=lrint((**cluster2).width().colRow().y() );
163 
164  //std::cout << "drow1: " << drow1 << " drow2: " << drow2 << " dcol1: " << dcol1 << " dcol2: " << dcol2 << " isfake1: " << (*cluster)->isFake() << " isfake2: " << (*cluster2)->isFake() << std::endl;
165  if ( (drow1==1 && drow2>1 && drow2<4) || (dcol2>dcol1 && cmin2<=cmin1 && cmin2+dcol2>=cmin1+dcol1)){
166  // cluster 1 is likely to be fake
167  if (m_internalSolving) {
168  rmList.push_back(cluster);
169  ATH_MSG_DEBUG(std::hex
170  << ": deleted " << (*cluster)->identify()
171  << std::dec);
172  break;
173  }
174  else (*cluster)->setFake(true);
175  }
176  else if ( (drow1>1 && drow1<4 && drow2==1) || (dcol1>dcol2 && cmin1<=cmin2 && cmin1+dcol1>=cmin2+dcol2)){
177  // cluster 2 is likely to be fake
178  if (m_internalSolving) {
179  rmList.push_back(cluster2);
180  ATH_MSG_DEBUG(std::hex
181  << ": deleted " << (*cluster2)->identify()
182  << std::dec);
183  continue;
184  }
185  else (*cluster2)->setFake(true);
186  }
187  else if ( drow2>1 || drow1>1 ) {
188  if (cmin1==cmin2){
189  rdo=RDOs.begin();
190  std::vector<std::vector<int> > myvec(dcol1);
191  for( ; rdo != rdoend; ++rdo){
192  int row=pixelID->phi_index(*rdo);
193  int col=pixelID->eta_index(*rdo);
194  myvec[col-cmin1].push_back(row);
195  }
196  rdo=rdos2.begin();
197  int dcol2=lrint((**cluster2).width().colRow().y() );
198  std::vector<std::vector<int> > myvec2(dcol2);
199  for( ; rdo != rdo2end; ++rdo){
200  int row=pixelID->phi_index(*rdo);
201  int col=pixelID->eta_index(*rdo);
202  myvec2[col-cmin2].push_back(row);
203  }
204  for (auto & i : myvec) if (!i.empty()) std::sort(i.begin(),i.end());
205  for (auto & i : myvec2) if (!i.empty()) std::sort(i.begin(),i.end());
206  int nvictory1=0,nvictory2=0;
207  for (int i=0;i<(int)myvec.size();i++){
208  int maxsize1=0,maxsize2=0,maxsizeleft1=0,maxsizeright1=0,maxsizeleft2=0,maxsizeright2=0,thissize=0,thissizeright=0;
209  bool hasgap1=false,hasgap2=false;
210  for (int j=0;j<(int)myvec[i].size();j++){
211  if (j!=0 && thissize==0) hasgap1=true; // there is a gap between the pixels in this column
212 
213  thissize++;
214  if (myvec[i][j]>=rowsPerFE) thissizeright++;
215 
216  if (thissize>maxsize1) maxsize1=thissize;
217  if (myvec[i][j]<rowsPerFE && thissize>maxsizeleft1) maxsizeleft1=thissize;
218  if (myvec[i][j]>=rowsPerFE && thissizeright>maxsizeright1) maxsizeright1=thissizeright;
219  if (j==(int)myvec[i].size()-1 || myvec[i][j+1]!=myvec[i][j]+1) thissize=thissizeright=0;
220  }
221  thissize=thissizeright=0;
222  for (int j=0;j<(int)myvec2[i].size();j++){
223  if (j!=0 && thissize==0) hasgap2=true;
224  thissize++;
225  if (myvec2[i][j]>=rowsPerFE) thissizeright++;
226  if (thissize>maxsize2) maxsize2=thissize;
227  if (myvec2[i][j]<rowsPerFE && thissize>maxsizeleft2) maxsizeleft2=thissize;
228  if (myvec2[i][j]>=rowsPerFE && thissizeright>maxsizeright2) maxsizeright2=thissizeright;
229  if (j==(int)myvec2[i].size()-1 || myvec2[i][j+1]!=myvec2[i][j]+1) thissize=thissizeright=0;
230 
231  }
232  //std::cout << "maxsize1: " << maxsize1 << " maxsize2: " << maxsize2 << " hasgap1: " << hasgap1 << " hasgap2: " << hasgap2 << std::endl;
233  if (maxsize1>maxsize2 && maxsizeleft1>=maxsizeleft2 && maxsizeright1>=maxsizeright2 && !hasgap1) nvictory1++;
234  else if (maxsize2>maxsize1 && maxsizeleft2>=maxsizeleft1 && maxsizeright2>=maxsizeright1 && !hasgap2) nvictory2++;
235  }
236  //std::cout << "nvictory1: " << nvictory1 << " nvictory2: " << nvictory2 << std::endl;
237 
238  // check if fake image of big clusters in ganged region
239  //if ( (rmin1<rmin2 && (rmin2+drow2-1)<rowsPerFE )
240  // || (rmin1>rmin2 && rmin2>=rowsPerFE ) ) {
241  if (nvictory1>nvictory2){
242  // cluster 2 is likely to be fake
243  if (m_internalSolving) {
244  rmList.push_back(cluster2);
245  ATH_MSG_DEBUG(std::hex
246  << ": deleted " << (*cluster2)->identify()
247  << std::dec);
248  continue;
249  }
250  else {
251  (*cluster2)->setFake(true);
252  //std::cout << "cluster2 fake!" << std::endl;
253  }
254  }
255  else if (nvictory2>nvictory1){
256  // cluster 1 is likely to be fake
257  if (m_internalSolving) {
258  rmList.push_back(cluster);
259  ATH_MSG_DEBUG(std::hex
260  << ": deleted " << (*cluster)->identify()
261  << std::dec);
262  continue;
263  }
264  else {
265  (*cluster)->setFake(true);
266  //std::cout << "cluster1 fake!" << std::endl;
267  }
268  }
269  }
270  }
271  // this point is reached:
272  // - always if m_internalSolving is false
273  // - in case no cluster could be removed
274  // in both cases the clusters are flagged as ambiguous
275  // and an entry in the ambiguity map is added.
276 
277  //GP: temporary not optimal solution not to flag two
278  //subclusters within a cluster as ganged to each other
279  //TO BE FIXED WITH A BETTER TREATMENT
280  if (!((*cluster)->isSplit() && (*cluster2)->isSplit()))
281  {
282  (*cluster)->setAmbiguous(true);
283  (*cluster2)->setAmbiguous(true);
284  // a map is a sorted container with the first element
285  // of the pair as key, for efficient lookup (~logN) need
286  // to add both permutations
287  theMap.insert(std::make_pair(*cluster,*cluster2));
288  theMap.insert(std::make_pair(*cluster2,*cluster));
289  ATH_MSG_DEBUG(std::hex
290  << ": added ambiguity entry"
291  << std::dec);
292  }
293  }
294  }
295  }
296  }
297  ATH_MSG_DEBUG("The map has " << theMap.size() << " entries ");
298 
299  // to remove clusters from the collection, the vector of iterators need to be
300  // sorted. Moreover, when preceeding iterators are removed, one must take into
301  // account the iterator position is changed.
302  int rmNumber=0;
305  std::sort(rmit,rmend);
306  for ( ; rmit!=rmend ; ++rmit){
307  ATH_MSG_DEBUG("Removed " << rmNumber+1 << " cluster: "
308  << std::hex << (*(*rmit-rmNumber))->identify() << std::dec);
309  collection->erase(*rmit-rmNumber); // The position of the iterator
310  rmNumber++;
311  }
312  ATH_MSG_DEBUG(rmNumber << " fake clusters from ganged pixel have been removed");
313 
314 }
315 
316 
317 
318 // Determines if a pixel cell (whose identifier is the first argument) is
319 // a ganged pixel. If this is the case, the last argument assumes the
320 // value of the identifier of the cell it is ganged with.
321 // The second argument is the pixel module the hit belongs to.
322 
324  const InDetDD::SiDetectorElement* element,
325  Identifier& gangedID)
326 {
327  InDetDD::SiCellId cellID = element->cellIdFromIdentifier (rdoID);
328  if (element->numberOfConnectedCells (cellID) > 1) {
329  InDetDD::SiCellId gangedCellID = element->connectedCell (cellID,1);
330  if ( gangedCellID==cellID ) gangedCellID = element->connectedCell (cellID,0);
331  gangedID = element->identifierFromCellId (gangedCellID);
332  return true;
333  } else {
334  gangedID = Identifier();
335  return false;
336  }
337 }
338 
339 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
query_example.row
row
Definition: query_example.py:24
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
PixelID::phi_index
int phi_index(const Identifier &id) const
Definition: PixelID.h:658
InDetDD::SolidStateDetectorElementBase::connectedCell
SiCellId connectedCell(const SiCellId cellId, int number) const
Get the cell ids sharing the readout for this cell.
Definition: SolidStateDetectorElementBase.cxx:250
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:30
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:48
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
AtlasDetectorID::HelperType::Pixel
@ Pixel
InDet::PixelGangedClusterAmbiguities
std::multimap< const SiCluster *, const SiCluster *, ::InDet::compare_SiCluster > PixelGangedClusterAmbiguities
Definition: PixelGangedClusterAmbiguities.h:46
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
InDet::PixelGangedAmbiguitiesFinder::initialize
virtual StatusCode initialize()
Definition: PixelGangedAmbiguitiesFinder.cxx:41
InDet::PixelGangedAmbiguitiesFinder::m_internalSolving
BooleanProperty m_internalSolving
Definition: PixelGangedAmbiguitiesFinder.h:69
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:206
InDet::PixelGangedAmbiguitiesFinder::m_pixelDetEleCollKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
Definition: PixelGangedAmbiguitiesFinder.h:71
xAOD::identify
Identifier identify(const UncalibratedMeasurement *meas)
Returns the associated identifier.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:61
InDetDD::SolidStateDetectorElementBase::getIdHelper
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
InDet::PixelGangedAmbiguitiesFinder::execute
void execute(PixelClusterCollection *collection, PixelGangedClusterAmbiguities &map) const
Definition: PixelGangedAmbiguitiesFinder.cxx:54
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
InDet::PixelGangedAmbiguitiesFinder::isGanged
static bool isGanged(const Identifier &rdoID, const InDetDD::SiDetectorElement *element, Identifier &gangedID)
Definition: PixelGangedAmbiguitiesFinder.cxx:323
AtlasDetectorID.h
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
InDetDD::SiDetectorElement::cellIdFromIdentifier
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
Definition: SiDetectorElement.cxx:120
InDetDD::SolidStateDetectorElementBase::numberOfConnectedCells
int numberOfConnectedCells(const SiCellId cellId) const
Test if readout cell has more than one diode associated with it.
Definition: SolidStateDetectorElementBase.cxx:243
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
InDetDD::SiDetectorElement::identifierFromCellId
virtual Identifier identifierFromCellId(const SiCellId &cellId) const override final
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
Definition: SiDetectorElement.cxx:89
test_pyathena.parent
parent
Definition: test_pyathena.py:15
PixelID::eta_index
int eta_index(const Identifier &id) const
Definition: PixelID.h:664
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
PixelGangedAmbiguitiesFinder.h
InDet::PixelGangedAmbiguitiesFinder::PixelGangedAmbiguitiesFinder
PixelGangedAmbiguitiesFinder(const std::string &type, const std::string &name, const IInterface *parent)
Definition: PixelGangedAmbiguitiesFinder.cxx:32
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
query_example.col
col
Definition: query_example.py:7
SiDetectorElement.h
InDetDD::SiCellId
Definition: SiCellId.h:29
PixelModuleDesign.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
AthAlgTool
Definition: AthAlgTool.h:26
SiCellId.h
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
PixelID
Definition: PixelID.h:67
InDetDD::SiDetectorElementCollection::getDetectorElement
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Definition: SiDetectorElementCollection.cxx:15
InDet::PixelClusterCollection
Trk::PrepRawDataCollection< PixelCluster > PixelClusterCollection
Definition: PixelClusterCollection.h:26
Identifier
Definition: IdentifierFieldParser.cxx:14