Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MvtxPrototype2Clusterizer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MvtxPrototype2Clusterizer.cc
2 #include "MvtxPrototype2Geom.h"
3 
4 //#include <g4detectors/PHG4CylinderCellGeom.h>
5 //#include <g4detectors/PHG4CylinderCellGeomContainer.h>
6 //#include <g4detectors/PHG4CylinderGeom.h>
7 //#include <g4detectors/PHG4CylinderGeomContainer.h>
8 
9 #include <mvtx/MvtxDefs.h>
10 #include <mvtx/MvtxHit.h>
11 
14 #include <trackbase/TrkrHitSet.h>
17 
19 #include <phool/PHCompositeNode.h>
20 #include <phool/PHIODataNode.h>
21 #include <phool/PHNodeIterator.h>
22 #include <phool/getClass.h>
23 
24 #include <boost/format.hpp>
25 #include <boost/tuple/tuple.hpp>
26 
27 #include <TMatrixF.h>
28 #include <TVector3.h>
29 
30 #define BOOST_NO_HASH // Our version of boost.graph is incompatible with GCC-4.3 w/o this flag
31 #include <boost/bind.hpp>
32 #include <boost/graph/adjacency_list.hpp>
33 #include <boost/graph/connected_components.hpp>
34 using namespace boost;
35 
36 #include <cmath>
37 #include <iostream>
38 #include <stdexcept>
39 
40 using namespace std;
41 
42 static const float twopi = 2.0 * M_PI;
43 
44 bool MvtxPrototype2Clusterizer::are_adjacent(const std::pair<TrkrDefs::hitkey, TrkrHit*> &lhs, const std::pair<TrkrDefs::hitkey, TrkrHit*> &rhs)
45 {
46  if (GetZClustering())
47  {
48  // column is first, row is second
49  if (fabs( MvtxDefs::getCol(lhs.first) - MvtxDefs::getCol(rhs.first) ) <= 1)
50  {
51  if (fabs( MvtxDefs::getRow(lhs.first) - MvtxDefs::getRow(rhs.first) ) <= 1)
52  {
53  return true;
54  }
55  }
56  }
57  else
58  {
59  if (fabs( MvtxDefs::getCol(lhs.first) - MvtxDefs::getCol(rhs.first) ) == 0)
60  {
61  if (fabs( MvtxDefs::getRow(lhs.first) - MvtxDefs::getRow(rhs.first) ) <= 1)
62  {
63  return true;
64  }
65  }
66  }
67 
68  return false;
69 }
70 
72  : SubsysReco(name)
73  , m_hits(nullptr)
74  , m_clusterlist(nullptr)
75  , m_clusterhitassoc(nullptr)
76  , m_makeZClustering(true)
77 {
78 }
79 
81 {
82  //-----------------
83  // Add Cluster Node
84  //-----------------
85 
86  PHNodeIterator iter(topNode);
87 
88  // Looking for the DST node
89  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
90  if (!dstNode)
91  {
92  cout << PHWHERE << "DST Node missing, doing nothing." << endl;
94  }
95  PHNodeIterator iter_dst(dstNode);
96 
97  // Create the SVX node if required
98  PHCompositeNode *svxNode = dynamic_cast<PHCompositeNode *>(iter_dst.findFirst("PHCompositeNode", "TRKR"));
99  if (!svxNode)
100  {
101  svxNode = new PHCompositeNode("TRKR");
102  dstNode->addNode(svxNode);
103  }
104 
105  // Create the Cluster node if required
106  TrkrClusterContainer *trkrclusters = findNode::getClass<TrkrClusterContainer>(dstNode, "TRKR_CLUSTER");
107  if (!trkrclusters)
108  {
109  PHNodeIterator dstiter(dstNode);
110  PHCompositeNode *DetNode =
111  dynamic_cast<PHCompositeNode *>(dstiter.findFirst("PHCompositeNode", "TRKR"));
112  if (!DetNode)
113  {
114  DetNode = new PHCompositeNode("TRKR");
115  dstNode->addNode(DetNode);
116  }
117 
118  trkrclusters = new TrkrClusterContainer();
119  PHIODataNode<PHObject> *TrkrClusterContainerNode =
120  new PHIODataNode<PHObject>(trkrclusters, "TRKR_CLUSTER", "PHObject");
121  DetNode->addNode(TrkrClusterContainerNode);
122  }
123 
124  TrkrClusterHitAssoc *clusterhitassoc = findNode::getClass<TrkrClusterHitAssoc>(topNode,"TRKR_CLUSTERHITASSOC");
125  if(!clusterhitassoc)
126  {
127  PHNodeIterator dstiter(dstNode);
128  PHCompositeNode *DetNode =
129  dynamic_cast<PHCompositeNode *>(dstiter.findFirst("PHCompositeNode", "TRKR"));
130  if (!DetNode)
131  {
132  DetNode = new PHCompositeNode("TRKR");
133  dstNode->addNode(DetNode);
134  }
135 
136  clusterhitassoc = new TrkrClusterHitAssoc();
137  PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(clusterhitassoc, "TRKR_CLUSTERHITASSOC", "PHObject");
138  DetNode->addNode(newNode);
139  }
140 
141  //----------------
142  // Report Settings
143  //----------------
144 
145  if (Verbosity() > 0)
146  {
147  cout << "====================== MvtxPrototype2Clusterizer::InitRun() =====================" << endl;
148  cout << " Z-dimension Clustering = " << boolalpha << m_makeZClustering << noboolalpha << endl;
149  cout << "===========================================================================" << endl;
150  }
151 
153 }
154 
156 {
157  // get node containing the digitized hits
158  m_hits = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
159  if (!m_hits)
160  {
161  cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << endl;
163  }
164 
165  // get node for clusters
166  m_clusterlist = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
167  if (!m_clusterlist)
168  {
169  cout << PHWHERE << " ERROR: Can't find TRKR_CLUSTER." << endl;
171  }
172 
173  // get node for cluster hit associations
174  m_clusterhitassoc = findNode::getClass<TrkrClusterHitAssoc>(topNode, "TRKR_CLUSTERHITASSOC");
175  if (!m_clusterhitassoc)
176  {
177  cout << PHWHERE << " ERROR: Can't find TRKR_CLUSTERHITASSOC" << endl;
179  }
180 
181  // run clustering
182  ClusterMvtx(topNode);
183  PrintClusters(topNode);
184 
185  // done
187 }
188 
190 {
191 
192  if (Verbosity() > 0)
193  cout << "Entering MvtxPrototype2Clusterizer::ClusterMvtx " << endl;
194 
195  //-----------
196  // Clustering
197  //-----------
198 
199  // loop over each MvtxHitSet object (chip)
200  TrkrHitSetContainer::ConstRange hitsetrange =
202  for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first;
203  hitsetitr != hitsetrange.second;
204  ++hitsetitr)
205  {
206 
207  TrkrHitSet *hitset = hitsetitr->second;
208 
209  if(Verbosity() > 10) cout << "MvtxPrototype2Clusterizer found hitsetkey " << hitsetitr->first << endl;
210 
211  if (Verbosity() > 10)
212  hitset->identify();
213 
214  // fill a vector of hits to make things easier
215  std::vector <std::pair< TrkrDefs::hitkey, TrkrHit*> > hitvec;
216 
217  TrkrHitSet::ConstRange hitrangei = hitset->getHits();
218  for (TrkrHitSet::ConstIterator hitr = hitrangei.first;
219  hitr != hitrangei.second;
220  ++hitr)
221  {
222  hitvec.push_back(make_pair(hitr->first, hitr->second));
223  }
224  if (Verbosity() > 10)
225  cout << "hitvec.size(): " << hitvec.size() << endl;
226 
227  // do the clustering
228  typedef adjacency_list<vecS, vecS, undirectedS> Graph;
229  Graph G;
230 
231  // loop over hits in this chip
232  for (unsigned int i = 0; i < hitvec.size(); i++)
233  {
234  for (unsigned int j = 0; j < hitvec.size(); j++)
235  {
236  if (are_adjacent(hitvec[i], hitvec[j]))
237  add_edge(i, j, G);
238  }
239  }
240 
241  // Find the connections between the vertices of the graph (vertices are the rawhits,
242  // connections are made when they are adjacent to one another)
243  vector<int> component(num_vertices(G));
244 
245  // this is the actual clustering, performed by boost
246  connected_components(G, &component[0]);
247 
248  // Loop over the components(hits) compiling a list of the
249  // unique connected groups (ie. clusters).
250  set<int> cluster_ids; // unique components
251  //multimap<int, pixel> clusters;
252  multimap<int, std::pair<TrkrDefs::hitkey, TrkrHit*> > clusters;
253  for (unsigned int i = 0; i < component.size(); i++)
254  {
255  cluster_ids.insert(component[i]);
256  clusters.insert(make_pair(component[i], hitvec[i]));
257  }
258 
259  // loop over the componenets and make clusters
260  for (set<int>::iterator clusiter = cluster_ids.begin(); clusiter != cluster_ids.end(); ++clusiter)
261  {
262  int clusid = *clusiter;
263  pair<multimap<int, std::pair<TrkrDefs::hitkey, TrkrHit*>>::iterator,
264  multimap<int, std::pair<TrkrDefs::hitkey, TrkrHit*>>::iterator> clusrange = clusters.equal_range(clusid);
265  multimap<int, std::pair<TrkrDefs::hitkey, TrkrHit*>>::iterator mapiter = clusrange.first;
266 
267  if (Verbosity() > 2)
268  cout << "Filling cluster id " << clusid << endl;
269 
270  // make the cluster directly in the node tree
271  TrkrDefs::cluskey ckey = MvtxDefs::genClusKey(hitset->getHitSetKey(), clusid);
272  TrkrClusterv1 *clus = static_cast<TrkrClusterv1 *>((m_clusterlist->findOrAddCluster(ckey))->second);
273 
274  // we need the geometry object for this layer to get the global positions
275  //int layer = TrkrDefs::getLayer(ckey);
276  //int stave = MvtxDefs::getStaveId(ckey);
277  //int chip = MvtxDefs::getChipId(ckey);
278 
279  // determine the size of the cluster in phi and z
280  set<int> phibins;
281  set<int> zbins;
282 
283  // determine the cluster position...
284  // need to define x, y, z coordinate
285  double xsum = 0.0;
286  double ysum = 0.0;
287  double zsum = 0.0;
288  unsigned nhits = 0;
289 
290  double clusx = NAN;
291  double clusy = NAN;
292  double clusz = NAN;
293 
294  for (mapiter = clusrange.first; mapiter != clusrange.second; ++mapiter)
295  {
296  // size
297  int col = MvtxDefs::getCol( (mapiter->second).first);
298  int row = MvtxDefs::getRow( (mapiter->second).first);
299  zbins.insert(col);
300  phibins.insert(row);
301  double gloCoord[3];
302  (MvtxPrototype2Geom::Instance())->detectorToGlobal(hitset->getHitSetKey(), (mapiter->second).first, gloCoord);
303 
304  // zsum += col;
305  // xsum += row;
306  // ysum += 0;
307  xsum += gloCoord[0];
308  ysum += gloCoord[1];
309  zsum += gloCoord[2];
310 
311  // add the association between this cluster key and this hitkey to the table
312  m_clusterhitassoc->addAssoc(ckey, mapiter->second.first);
313 
314  ++nhits;
315  }//mapiter
316 
317  //float thickness = 50.e-4/28e-4; //sensor thickness converted to pixel size
319  float phisize = phibins.size();
320  float zsize = zbins.size();
321 
322  // This is the local position
323  // clusx = xsum/nhits + 0.5;
324  // clusy = ysum/nhits + 0.5;
325  // clusz = zsum/nhits + 0.5;
326  clusx = xsum/nhits;
327  clusy = ysum/nhits;
328  clusz = zsum/nhits;
329  clus->setAdc(nhits);
330 
331  /*
332  cout << "new mvtx clusterizer layer: " << layer << " stave: " << stave << " chip: " << chip
333  << " x: " << clusx << " y: " << clusy << " z: " << clusz << endl;
334  */
335 
336  clus->setPosition(0, clusx);
337  clus->setPosition(1, clusy);
338  clus->setPosition(2, clusz);
339  //clus->setLocal();
340  clus->setGlobal();
341 
342  float invsqrt12 = 1.0 / sqrt(12.0);
343 
344  phisize *= SegmentationAlpide::PitchRow;
346  TMatrixF DIM(3, 3);
347  DIM[0][0] = pow(0.5 * phisize, 2);
348  DIM[0][1] = 0.0;
349  DIM[0][2] = 0.0;
350  DIM[1][0] = 0.0;
351  DIM[1][1] = pow(0.5 * thickness, 2);
352  DIM[1][2] = 0.0;
353  DIM[2][0] = 0.0;
354  DIM[2][1] = 0.0;
355  DIM[2][2] = pow(0.5 * zsize, 2);
356 
357  TMatrixF ERR(3, 3);
358  ERR[0][0] = pow(0.5 * phisize * invsqrt12, 2);
359  ERR[0][1] = 0.0;
360  ERR[0][2] = 0.0;
361  ERR[1][0] = 0.0;
362  ERR[1][1] = pow(0.5 * thickness * invsqrt12, 2);
363  ERR[1][2] = 0.0;
364  ERR[2][0] = 0.0;
365  ERR[2][1] = 0.0;
366  ERR[2][2] = pow(0.5 * zsize * invsqrt12, 2);
367 
368  clus->setSize( 0 , 0 , DIM[0][0] );
369  clus->setSize( 0 , 1 , DIM[0][1] );
370  clus->setSize( 0 , 2 , DIM[0][2] );
371  clus->setSize( 1 , 0 , DIM[1][0] );
372  clus->setSize( 1 , 1 , DIM[1][1] );
373  clus->setSize( 1 , 2 , DIM[1][2] );
374  clus->setSize( 2 , 0 , DIM[2][0] );
375  clus->setSize( 2 , 1 , DIM[2][1] );
376  clus->setSize( 2 , 2 , DIM[2][2] );
377 
378  clus->setError( 0 , 0 , ERR[0][0] );
379  clus->setError( 0 , 1 , ERR[0][1] );
380  clus->setError( 0 , 2 , ERR[0][2] );
381  clus->setError( 1 , 0 , ERR[1][0] );
382  clus->setError( 1 , 1 , ERR[1][1] );
383  clus->setError( 1 , 2 , ERR[1][2] );
384  clus->setError( 2 , 0 , ERR[2][0] );
385  clus->setError( 2 , 1 , ERR[2][1] );
386  clus->setError( 2 , 2 , ERR[2][2] );
387 
388  if (Verbosity() > 2)
389  clus->identify();
390 
391  }
392  }
393 
394  if(Verbosity() > 5)
395  {
396  // check that the associations were written correctly
398  }
399 
400  return;
401 }
402 
404 {
405  if (Verbosity() >= 1)
406  {
407  TrkrClusterContainer *clusterlist = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
408  if (!clusterlist) return;
409 
410  cout << "================= Aftyer MvtxPrototype2Clusterizer::process_event() ====================" << endl;
411 
412  cout << " There are " << clusterlist->size() << " clusters recorded: " << endl;
413 
414  clusterlist->identify();
415 
416  cout << "===========================================================================" << endl;
417  }
418 
419  return;
420 }