StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StPxlClusterMaker.cxx
1 
6 /***************************************************************************
7  *
8  * $Id: StPxlClusterMaker.cxx,v 1.12 2017/09/08 17:37:18 dongx Exp $
9  *
10  * Author: Qiu Hao, Jan 2013, according codes from Xiangming Sun
11  ***************************************************************************
12  *
13  * Description:
14  * Group neighboring pixel raw hits from into clusters.
15  * More information at
16  * https://www.star.bnl.gov/protected/heavy/qiuh/HFT/software/PXL_software.pdf
17  *
18  ***************************************************************************
19  *
20  * $Log: StPxlClusterMaker.cxx,v $
21  * Revision 1.12 2017/09/08 17:37:18 dongx
22  * change std::random_shuffle to std::rand to be consistent with STAR coding
23  *
24  * Revision 1.11 2017/09/01 02:58:33 dongx
25  * Update to ensure idTruth is preserved for MC hits for overlapping scenarios between MC/data and two or more MC hits
26  *
27  * Revision 1.10 2014/02/27 03:50:17 qiuh
28  * *** empty log message ***
29  *
30  * Revision 1.9 2014/02/27 00:44:20 smirnovd
31  * Switch to c++ style array zeroing
32  *
33  * Revision 1.8 2014/02/27 00:44:08 smirnovd
34  * Use constructor initializer list
35  *
36  * Revision 1.7 2014/02/21 21:11:06 smirnovd
37  * Minor style and empty space adjustments
38  *
39  * Revision 1.6 2014/02/21 21:10:58 smirnovd
40  * Move zeroing of mRawHitMap outside the loop. The map is zeroed automatically during the cluster finding
41  *
42  * Revision 1.5 2014/01/28 19:29:35 qiuh
43  * *** empty log message ***
44  *
45  *
46  **************************************************************************/
47 
48 #include <cstdlib>
49 #include <map>
50 
51 #include "StPxlClusterMaker.h"
52 #include "StMessMgr.h"
53 #include "StPxlCluster.h"
54 #include "StPxlClusterCollection.h"
55 #include "StPxlRawHitMaker/StPxlRawHit.h"
56 #include "StPxlRawHitMaker/StPxlRawHitCollection.h"
57 #include "StPxlUtil/StPxlConstants.h"
58 
59 ClassImp(StPxlClusterMaker);
60 
61 //________________________________________________________________________________
62 StPxlClusterMaker::StPxlClusterMaker(const Char_t *name) : StMaker(name),
63  mPxlClusterCollection(0),
64  mRawHitMap()
65 {
66 }
67 //________________________________________________________________________________
68 void StPxlClusterMaker::Clear(const Option_t *)
69 {
71  delete mPxlClusterCollection;
73  }
74  return StMaker::Clear();
75 }
76 //________________________________________________________________________________
78 {
79  // input data
80  TObjectSet *pxlRawHitDataSet = (TObjectSet *)GetDataSet("pxlRawHit");
81  if (! pxlRawHitDataSet) {
82  LOG_WARN << "Make() - there is no pxlRawHitDataSet " << endm;
83  return kStWarn;
84  }
85 
86  StPxlRawHitCollection *pxlRawHitCollection = (StPxlRawHitCollection *)pxlRawHitDataSet->GetObject();
87  if (!pxlRawHitCollection) {
88  LOG_WARN << "Make() - no pxlRawHitCollection." << endm;
89  return kStWarn;
90  }
91 
92  LOG_INFO << " Before clustering. Number of PxlRawHits = " << pxlRawHitCollection->numberOfRawHits() << endm;
93 
94  // output cluster data structures
96  ToWhiteBoard("pxlCluster", mPxlClusterCollection);
97 
98  // Set all elements (pointers) of rawHitMap to 0
99  fill_n(*mRawHitMap, kNumberOfPxlRowsOnSensor * kNumberOfPxlColumnsOnSensor, static_cast<StPxlRawHit*>(0) );
100 
101  // real work
102  int embeddingShortCut = IAttr("EmbeddingShortCut");
103  int nIdTruth = 0;
104  for (int i = 0; i < kNumberOfPxlSectors; i++)
105  for (int j = 0; j < kNumberOfPxlLaddersPerSector; j++)
106  for (int k = 0; k < kNumberOfPxlSensorsPerLadder; k++) {
107 
108  std::map<int, std::vector<int>> firedPixelsMap;
109  for (int iHit=0; iHit < pxlRawHitCollection->numberOfRawHits(i+1, j+1, k+1); ++iHit)
110  {
111  StPxlRawHit const* rawHit = pxlRawHitCollection->rawHit(i + 1, j + 1, k + 1, iHit);
112  int const id = rawHit->row() * 1000 + rawHit->column();
113  firedPixelsMap[id].push_back(iHit);
114  }
115 
116  for(auto& pixel: firedPixelsMap)
117  {
118  std::vector<int> mcHits;
119  for(auto const& rawHitIdx: pixel.second)
120  {
121  StPxlRawHit const* rawHit = pxlRawHitCollection->rawHit(i + 1, j + 1, k + 1, rawHitIdx);
122  if(rawHit->idTruth() > 0) mcHits.push_back(rawHitIdx);
123  }
124 
125  if(!mcHits.empty()) // if any of the hits is MC then pick a random mc hit
126  {
127  int const rnd_idx = std::rand() % static_cast<int>(mcHits.size());
128  StPxlRawHit const* rawHit = pxlRawHitCollection->rawHit(i + 1, j + 1, k + 1, mcHits[rnd_idx]);
129  mRawHitMap[rawHit->row()][rawHit->column()] = rawHit;
130  }
131  else // pick a random hit
132  {
133  int const rnd_idx = std::rand() % static_cast<int>(pixel.second.size());
134  StPxlRawHit const* rawHit = pxlRawHitCollection->rawHit(i + 1, j + 1, k + 1, pixel.second[rnd_idx]);
135  mRawHitMap[rawHit->row()][rawHit->column()] = rawHit;
136  }
137 
138  if(Debug() && pixel.second.size()>1) // in case of overlapping raw pixels
139  {
140  LOG_INFO << " ++ Two or more rawHits found in this pixel row/column = " << pixel.first/1000 << "/" << pixel.first%1000 << endm;
141  for(size_t ih = 0; ih<pixel.second.size(); ++ih)
142  {
143  StPxlRawHit const* rawHit = pxlRawHitCollection->rawHit(i + 1, j + 1, k + 1, pixel.second[ih]);
144  LOG_INFO << " rawHit #" << ih << "\t idTruth=" << rawHit->idTruth() << endm;
145  }
146  LOG_INFO << " => Selected rawHit idTruth = " << mRawHitMap[pixel.first/1000][pixel.first%1000]->idTruth() << endm;
147  }
148  }
149 
150  // find clusters
151  for (int l = 0; l < pxlRawHitCollection->numberOfRawHits(i+1, j+1, k+1); l++) {
152  const StPxlRawHit *rawHit = pxlRawHitCollection->rawHit(i + 1, j + 1, k + 1, l);
153  StPxlCluster cluster;
154  findCluster(&cluster, rawHit->column(), rawHit->row());
155  if (cluster.nRawHits() > 0) {
156  cluster.summarize(embeddingShortCut);
157  mPxlClusterCollection->addCluster(i + 1, j + 1, k + 1, cluster);
158  if(cluster.idTruth()>0) {
159  LOG_DEBUG << " ==> A new cluster added sector/ladder/sensor/row/column = " << i+1 <<"/" << j+1 << "/" << k+1 << "/" << cluster.rowCenter() << "/" << cluster.columnCenter() << "\t nRawHits=" << cluster.nRawHits() << "\t idTruth=" << cluster.idTruth() << endm;
160  nIdTruth++;
161  }
162  }
163  }
164  }
165 
166  LOG_INFO << " After clustering. Number of PxlClusters = " << mPxlClusterCollection->numberOfClusters() << " w/ idTruth = " << nIdTruth << endm;
167 
168  return kStOK;
169 }
170 
171 
178 void StPxlClusterMaker::findCluster(StPxlCluster *cluster, Int_t column, Int_t row)
179 {
180  const StPxlRawHit *rawHit = mRawHitMap[row][column];
181  if ( !rawHit ) return; // skip if already included in another cluster
182 
183  mRawHitMap[row][column] = 0; // unmark this used raw hit
184 
185  // looking at the 8 neighboring pixels, if fired, continue looking from that pixel
186  if ((column - 1) >= 0)
187  findCluster(cluster, column - 1, row);
188 
189  if ((column + 1) < kNumberOfPxlColumnsOnSensor)
190  findCluster(cluster, column + 1, row);
191 
192  if ((row - 1) >= 0)
193  findCluster(cluster, column, row - 1);
194 
195  if ((row + 1) < kNumberOfPxlRowsOnSensor)
196  findCluster(cluster, column, row + 1);
197 
198  if (((column - 1) >= 0) && ((row - 1) >= 0))
199  findCluster(cluster, column - 1, row - 1);
200 
201  if (((column - 1) >= 0) && ((row + 1) < kNumberOfPxlRowsOnSensor))
202  findCluster(cluster, column - 1, row + 1);
203 
204  if (((column + 1) < kNumberOfPxlColumnsOnSensor) && ((row - 1) >= 0))
205  findCluster(cluster, column + 1, row - 1);
206 
207  if (((column + 1) < kNumberOfPxlColumnsOnSensor) && ((row + 1) < kNumberOfPxlRowsOnSensor))
208  findCluster(cluster, column + 1, row + 1);
209 
210  // Add hit to the cluster
211  cluster->addRawHit(rawHit);
212 }
const StPxlRawHit * rawHit(Int_t sector, Int_t ladder, Int_t sensor, Int_t rawHitIndex) const
pionter to a rawHit in the collection
void findCluster(StPxlCluster *cluster, Int_t column, Int_t row)
Int_t numberOfClusters(Int_t sector, Int_t ladder, Int_t sensor) const
number of clusters in a sensor
void summarize(int embeddingShortCut=0)
calculate column center, row center, and most frequent idTruth among raw hits
StPxlClusterCollection * mPxlClusterCollection
pointer to the pxl cluster collection
void addRawHit(const StPxlRawHit *rawHit)
add a raw hit to the cluster
Float_t rowCenter() const
average raw hit row
Definition: StPxlCluster.h:57
Int_t row() const
row 0-927
Definition: StPxlRawHit.cxx:54
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
Int_t idTruth() const
for embedding, 0 as background, most frequent raw hit idTruth as idTruth of the cluster ...
Definition: StPxlCluster.h:58
Int_t column() const
column 0-959
Definition: StPxlRawHit.cxx:55
Int_t nRawHits() const
number of raw hits
Int_t idTruth() const
for embedding, 0 as background
Definition: StPxlRawHit.cxx:56
void addCluster(Int_t sector, Int_t ladder, Int_t sensor, const StPxlCluster &cluster)
add a cluster to the collection
Definition: Stypes.h:42
Definition: Stypes.h:40
Float_t columnCenter() const
average raw hit column
Definition: StPxlCluster.h:56
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TObjectSet.h:56
Int_t numberOfRawHits(Int_t sector, Int_t ladder, Int_t sensor)
number of raw hits in a sensor