Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MvtxClusterizer.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MvtxClusterizer.C
1 #include "MvtxClusterizer.h"
2 
3 #include "mvtx/MvtxDefUtil.h"
4 #include "mvtx/MvtxHitSetv1.h"
5 
10 
11 
13 #include <phool/PHCompositeNode.h>
14 #include <phool/PHIODataNode.h>
15 #include <phool/PHNodeIterator.h>
16 #include <phool/getClass.h>
21 #include <g4detectors/PHG4CylinderGeom_MAPS.h>
22 #include <g4detectors/PHG4CylinderGeom_Siladders.h>
23 #include <g4detectors/PHG4Cell.h>
25 
26 #include <boost/tuple/tuple.hpp>
27 #include <boost/format.hpp>
28 
29 #include <TMatrixF.h>
30 #include <TVector3.h>
31 
32 #define BOOST_NO_HASH // Our version of boost.graph is incompatible with GCC-4.3 w/o this flag
33 #include <boost/bind.hpp>
34 #include <boost/graph/adjacency_list.hpp>
35 #include <boost/graph/connected_components.hpp>
36 using namespace boost;
37 
38 #include <iostream>
39 #include <stdexcept>
40 #include <cmath>
41 
42 using namespace std;
43 
44 static const float twopi = 2.0 * M_PI;
45 
47  const pixel rhs )
48 {
49 
50  if ( GetZClustering() )
51  {
52  // column is first, row is second
53  if ( fabs(lhs.first - rhs.first) <= 1 )
54  {
55  if ( fabs(lhs.second - rhs.second) <= 1 )
56  {
57  return true;
58  }
59  }
60  }
61  else
62  {
63  if ( fabs(lhs.first - rhs.first) == 0 )
64  {
65  if ( fabs(lhs.second - rhs.second) <= 1 )
66  {
67  return true;
68  }
69  }
70  }
71 
72  return false;
73 }
74 
75 
77  SubsysReco(name),
78  hits_(NULL),
79  clusterlist_(NULL),
80  make_z_clustering_(true),
81  _timer(PHTimeServer::get()->insert_new(name))
82 {
83 
84 }
85 
87 {
88 
89  //-----------------
90  // Add Cluster Node
91  //-----------------
92 
93  PHNodeIterator iter(topNode);
94 
95  // Looking for the DST node
96  PHCompositeNode *dstNode
97  = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
98  if (!dstNode) {
99  cout << PHWHERE << "DST Node missing, doing nothing." << endl;
101  }
102  PHNodeIterator iter_dst(dstNode);
103 
104  // Create the SVX node if required
105  PHCompositeNode* svxNode
106  = dynamic_cast<PHCompositeNode*>(iter_dst.findFirst("PHCompositeNode", "TRKR"));
107  if (!svxNode) {
108  svxNode = new PHCompositeNode("TRKR");
109  dstNode->addNode(svxNode);
110  }
111 
112  // Create the Cluster node if required
113  TrkrClusterContainer *trkrclusters
114  = findNode::getClass<TrkrClusterContainer>(dstNode, "TrkrClusterContainer");
115  if (!trkrclusters) {
116  trkrclusters = new TrkrClusterContainer();
117  PHIODataNode<PHObject> *TrkrClusterContainerNode =
118  new PHIODataNode<PHObject>(trkrclusters, "TrkrClusterContainer", "PHObject");
119  svxNode->addNode(TrkrClusterContainerNode);
120  }
121 
122  //----------------
123  // Report Settings
124  //----------------
125 
126  if (verbosity > 0)
127  {
128  cout << "====================== MvtxClusterizer::InitRun() =====================" << endl;
129  cout << " Z-dimension Clustering = " << boolalpha << make_z_clustering_ << noboolalpha << endl;
130  cout << "===========================================================================" << endl;
131  }
132 
134 }
135 
137 
138  _timer.get()->restart();
139 
140  // get node containing the digitized hits
141  hits_ = findNode::getClass<TrkrHitSetContainer>(topNode, "TrkrHitSetContainer");
142  if (!hits_)
143  {
144  cout << PHWHERE << "ERROR: Can't find node TrkrHitSetContainer" << endl;
146  }
147 
148  // get node for clusters
149  clusterlist_ = findNode::getClass<TrkrClusterContainer>(topNode, "TrkrClusterContainer");
150  if (!clusterlist_)
151  {
152  cout << PHWHERE << " ERROR: Can't find TrkrClusterContainer." << endl;
154  }
155  clusterlist_->Reset();
156 
157  // run clustering
158  ClusterMvtx(topNode);
159  PrintClusters(topNode);
160 
161  // done
162  _timer.get()->stop();
164 }
165 
167 
168  if (verbosity > 0)
169  cout << "Entering MvtxClusterizer::ClusterMvtx " << endl;
170 
171  //----------
172  // Get Nodes
173  //----------
174 
175  //-----------
176  // Clustering
177  //-----------
178 
179  // loop over each MvtxHitSet object (chip)
180  TrkrHitSetContainer::ConstRange hitsetrange =
181  //hits_->GetHitSets(TrkrDefs::TRKRID::mvtx_id);
182  hits_->GetHitSets();
183  for ( TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first;
184  hitsetitr != hitsetrange.second;
185  ++hitsetitr )
186  {
187 
188  MvtxHitSetv1* hitset = static_cast<MvtxHitSetv1*>(hitsetitr->second);
189  if (verbosity>2)
190  hitset->identify();
191 
192  TrkrDefUtil trkrutil;
193  MvtxDefUtil mvtxutil;
194 
195 
196  // fill a vector of hits to make things easier
197  // D. McGlinchey - this probably isn't necessary. Use iterator directly?
198  std::vector<pixel> hitvec;
199  MvtxHitSetv1::ConstRange hitrangei = hitset->GetHits();
200  for ( MvtxHitSetv1::ConstIterator hitr = hitrangei.first;
201  hitr != hitrangei.second;
202  ++hitr)
203  {
204  hitvec.push_back(make_pair(hitr->first, hitr->second));
205  }
206  if ( verbosity>2 )
207  cout << "hitvec.size(): " << hitvec.size() << endl;
208 
209  // do the clustering
210  typedef adjacency_list <vecS, vecS, undirectedS> Graph;
211  Graph G;
212 
213  // loop over hits in this chip
214  for ( unsigned int i = 0; i < hitvec.size(); i++)
215  {
216  for ( unsigned int j = 0; j < hitvec.size(); j++)
217  {
218  if ( are_adjacent(hitvec[i], hitvec[j]) )
219  add_edge(i, j, G);
220  }
221  }
222 
223 
224  // Find the connections between the vertices of the graph (vertices are the rawhits,
225  // connections are made when they are adjacent to one another)
226  vector<int> component(num_vertices(G));
227 
228  // this is the actual clustering, performed by boost
229  connected_components(G, &component[0]);
230 
231  // Loop over the components(hit cells) compiling a list of the
232  // unique connected groups (ie. clusters).
233  set<int> cluster_ids; // unique components
234  multimap<int, pixel> clusters;
235  for (unsigned int i = 0; i < component.size(); i++)
236  {
237  cluster_ids.insert( component[i] );
238  clusters.insert( make_pair(component[i], hitvec[i]) );
239  }
240 
241  // loop over the componenets and make clusters
242  for (set<int>::iterator clusiter = cluster_ids.begin();
243  clusiter != cluster_ids.end();
244  clusiter++ )
245  {
246 
247  int clusid = *clusiter;
248  pair< multimap<int, pixel>::iterator,
249  multimap<int, pixel>::iterator> clusrange = clusters.equal_range(clusid);
250 
251  multimap<int, pixel>::iterator mapiter = clusrange.first;
252 
253  if (verbosity > 2)
254  cout << "Filling cluster id " << clusid << endl;
255 
256  // make cluster
257  TrkrDefs::cluskey ckey = mvtxutil.GenClusKey(hitset->GetHitSetKey(),clusid);
258  TrkrClusterv1* clus = static_cast<TrkrClusterv1*>((clusterlist_->FindOrAddCluster(ckey))->second);
259 
260  // determine the size of the cluster in phi and z
261  set<int> phibins;
262  set<int> zbins;
263 
264  // determine the cluster position...
265  double xsum = 0.0;
266  double ysum = 0.0;
267  double zsum = 0.0;
268  unsigned nhits = 0;
269 
270 
271  for (mapiter = clusrange.first; mapiter != clusrange.second; mapiter++ )
272  {
273 
274  // size
275  zbins.insert((mapiter->second).first);
276  phibins.insert((mapiter->second).second);
277 
278  // find the center of the pixel in local coords
279  xsum += (mapiter->second).second;
280  zsum += (mapiter->second).first + 0.5;
281 
282  ++nhits;
283  } //mapitr
284 
285  float thickness = 50.e-4/28e-4;
286  float phisize = phibins.size();
287  float zsize = zbins.size();
288 
289  double clusx = NAN;
290  double clusy = NAN;
291  double clusz = NAN;
292 
293  clusx = xsum / nhits;
294  clusy = ysum / nhits;
295  clusz = zsum / nhits;
296 
297  clus->SetPosition(0, clusx);
298  clus->SetPosition(1, clusy);
299  clus->SetPosition(2, clusz);
300  clus->SetLocal();
301 
302  clus->SetAdc(nhits);
303 
304  float invsqrt12 = 1.0 / sqrt(12.0);
305 
306  TMatrixF DIM(3, 3);
307  DIM[0][0] = pow(0.5 * phisize, 2);
308 
309  DIM[0][1] = 0.0;
310  DIM[0][2] = 0.0;
311  DIM[1][0] = 0.0;
312  DIM[1][1] = pow(0.5 * thickness, 2);
313  DIM[1][2] = 0.0;
314  DIM[2][0] = 0.0;
315  DIM[2][1] = 0.0;
316  DIM[2][2] = pow(0.5 * zsize, 2);
317 
318  TMatrixF ERR(3, 3);
319  ERR[0][0] = pow(0.5 * phisize * invsqrt12, 2);
320  ERR[0][1] = 0.0;
321  ERR[0][2] = 0.0;
322  ERR[1][0] = 0.0;
323  ERR[1][1] = pow(0.5 * thickness * invsqrt12, 2);
324  ERR[1][2] = 0.0;
325  ERR[2][0] = 0.0;
326  ERR[2][1] = 0.0;
327  ERR[2][2] = pow(0.5 * zsize * invsqrt12, 2);
328 
329 
330  clus->SetSize( 0 , 0 , DIM[0][0] );
331  clus->SetSize( 0 , 1 , DIM[0][1] );
332  clus->SetSize( 0 , 2 , DIM[0][2] );
333  clus->SetSize( 1 , 0 , DIM[1][0] );
334  clus->SetSize( 1 , 1 , DIM[1][1] );
335  clus->SetSize( 1 , 2 , DIM[1][2] );
336  clus->SetSize( 2 , 0 , DIM[2][0] );
337  clus->SetSize( 2 , 1 , DIM[2][1] );
338  clus->SetSize( 2 , 2 , DIM[2][2] );
339 
340  clus->SetError( 0 , 0 , ERR[0][0] );
341  clus->SetError( 0 , 1 , ERR[0][1] );
342  clus->SetError( 0 , 2 , ERR[0][2] );
343  clus->SetError( 1 , 0 , ERR[1][0] );
344  clus->SetError( 1 , 1 , ERR[1][1] );
345  clus->SetError( 1 , 2 , ERR[1][2] );
346  clus->SetError( 2 , 0 , ERR[2][0] );
347  clus->SetError( 2 , 1 , ERR[2][1] );
348  clus->SetError( 2 , 2 , ERR[2][2] );
349 
350 
351  if ( verbosity > 2 )
352  clus->identify();
353 
354  } // clusitr
355  } // hitsetitr
356 
357  return;
358 }
359 
360 
362 {
363 
364  if (verbosity >= 1) {
365 
366  TrkrClusterContainer *clusterlist = findNode::getClass<TrkrClusterContainer>(topNode, "TrkrClusterContainer");
367  if (!clusterlist) return;
368 
369  cout << "================= MvtxClusterizer::process_event() ====================" << endl;
370 
371  cout << " Found and recorded the following " << clusterlist->size() << " clusters: " << endl;
372 
373  clusterlist->identify();
374 
375  cout << "===========================================================================" << endl;
376  }
377 
378  return;
379 }