Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GlobalVertexReco.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file GlobalVertexReco.cc
1 #include "GlobalVertexReco.h"
2 
3 #include "GlobalVertex.h" // for GlobalVertex, GlobalVe...
4 #include "GlobalVertexMap.h" // for GlobalVertexMap
5 #include "GlobalVertexMapv1.h"
6 #include "GlobalVertexv2.h"
7 #include "SvtxVertex.h"
8 #include "SvtxVertexMap.h"
9 #include "MbdVertex.h"
10 #include "MbdVertexMap.h"
11 
14 
16 #include <fun4all/SubsysReco.h> // for SubsysReco
17 
18 #include <phool/PHCompositeNode.h>
19 #include <phool/PHIODataNode.h>
20 #include <phool/PHNode.h> // for PHNode
21 #include <phool/PHNodeIterator.h>
22 #include <phool/PHObject.h> // for PHObject
23 #include <phool/getClass.h>
24 #include <phool/phool.h> // for PHWHERE
25 
26 #include <cfloat>
27 #include <cmath>
28 #include <cstdlib> // for exit
29 #include <iostream>
30 #include <set> // for _Rb_tree_const_iterator
31 #include <utility> // for pair
32 
33 using namespace std;
34 
36  : SubsysReco(name)
37 {
38 }
39 
41 {
42  if (Verbosity() > 0)
43  {
44  cout << "======================= GlobalVertexReco::InitRun() =======================" << endl;
45  cout << "===========================================================================" << endl;
46  }
47 
48  return CreateNodes(topNode);
49 }
50 
52 {
53  if (Verbosity() > 1)
54  {
55  cout << "GlobalVertexReco::process_event -- entered" << endl;
56  }
57 
58  //---------------------------------
59  // Get Objects off of the Node Tree
60  //---------------------------------
61  GlobalVertexMap *globalmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
62  if (!globalmap)
63  {
64  cout << PHWHERE << "::ERROR - cannot find GlobalVertexMap" << endl;
65  exit(-1);
66  }
67 
68  SvtxVertexMap *svtxmap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
69  MbdVertexMap *mbdmap = findNode::getClass<MbdVertexMap>(topNode, "MbdVertexMap");
70  SvtxTrackMap *trackmap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
71 
72  // we will make 3 different kinds of global vertexes
73  // (1) SVTX+MBD vertexes - we match SVTX vertex to the nearest MBD vertex within 3 sigma in zvertex
74  // the spatial point comes from the SVTX, the timing from the MBD
75  // number of SVTX+MBD vertexes <= number of SVTX vertexes
76 
77  // (2) SVTX only vertexes - for those cases where the MBD wasn't simulated,
78  // or all the MBD vertexes are outside the 3 sigma matching requirement
79  // we pass forward the 3d point from the SVTX with the default timing info
80 
81  // (3) MBD only vertexes - use the default x,y positions on this module and
82  // pull in the mbd z and mbd t
83 
84  // there may be some quirks as we get to large luminosity and the MBD becomes
85  // untrust worthy, I'm guessing analyzers would resort exclusively to (1) or (2)
86  // in those cases
87 
88  std::set<unsigned int> used_svtx_vtxids;
89  std::set<unsigned int> used_mbd_vtxids;
90 
91  if (svtxmap && mbdmap)
92  {
93  if (Verbosity())
94  {
95  cout << "GlobalVertexReco::process_event - svtxmap && mbdmap" << endl;
96  }
97 
98  for (SvtxVertexMap::ConstIter svtxiter = svtxmap->begin();
99  svtxiter != svtxmap->end();
100  ++svtxiter)
101  {
102  const SvtxVertex *svtx = svtxiter->second;
103 
104  const MbdVertex *mbd_best = nullptr;
105  float min_sigma = FLT_MAX;
106  for (MbdVertexMap::ConstIter mbditer = mbdmap->begin();
107  mbditer != mbdmap->end();
108  ++mbditer)
109  {
110  const MbdVertex *mbd = mbditer->second;
111 
112  float combined_error = sqrt(svtx->get_error(2, 2) + pow(mbd->get_z_err(), 2));
113  float sigma = fabs(svtx->get_z() - mbd->get_z()) / combined_error;
114  if (sigma < min_sigma)
115  {
116  min_sigma = sigma;
117  mbd_best = mbd;
118  }
119  }
120 
121  if (min_sigma > 3.0 || !mbd_best)
122  {
123  continue;
124  }
125 
126  // we have a matching pair
128  vertex->set_id(globalmap->size());
129 
130  vertex->insert_vtx(GlobalVertex::SVTX, svtx);
131  vertex->insert_vtx(GlobalVertex::MBD, mbd_best);
132  used_svtx_vtxids.insert(svtx->get_id());
133  used_mbd_vtxids.insert(mbd_best->get_id());
134  vertex->set_id(globalmap->size());
135 
136  globalmap->insert(vertex);
137 
139  if (trackmap)
140  {
141  for (auto iter = svtx->begin_tracks(); iter != svtx->end_tracks();
142  ++iter)
143  {
144  auto track = trackmap->find(*iter)->second;
145  track->set_vertex_id(vertex->get_id());
146  }
147  }
148 
149  if (Verbosity() > 1)
150  {
151  vertex->identify();
152  }
153  }
154  }
155 
156  // okay now loop over all unused SVTX vertexes (2nd class)...
157  if (svtxmap)
158  {
159  if (Verbosity())
160  {
161  cout << "GlobalVertexReco::process_event - svtxmap " << endl;
162  }
163 
164  for (SvtxVertexMap::ConstIter svtxiter = svtxmap->begin();
165  svtxiter != svtxmap->end();
166  ++svtxiter)
167  {
168  const SvtxVertex *svtx = svtxiter->second;
169 
170  if (used_svtx_vtxids.find(svtx->get_id()) != used_svtx_vtxids.end())
171  {
172  continue;
173  }
174  if (isnan(svtx->get_z()))
175  {
176  continue;
177  }
178 
179  // we have a standalone SVTX vertex
181 
182  vertex->set_id(globalmap->size());
183 
184  vertex->insert_vtx(GlobalVertex::SVTX, svtx);
185  used_svtx_vtxids.insert(svtx->get_id());
186 
188  if (trackmap)
189  {
190  for (auto iter = svtx->begin_tracks(); iter != svtx->end_tracks();
191  ++iter)
192  {
193  auto track = trackmap->find(*iter)->second;
194  track->set_vertex_id(vertex->get_id());
195  }
196  }
197  globalmap->insert(vertex);
198 
199  if (Verbosity() > 1)
200  {
201  vertex->identify();
202  }
203  }
204  }
205 
206  // okay now loop over all unused MBD vertexes (3rd class)...
207  if (mbdmap)
208  {
209  if (Verbosity())
210  {
211  cout << "GlobalVertexReco::process_event - mbdmap" << endl;
212  }
213 
214  for (MbdVertexMap::ConstIter mbditer = mbdmap->begin();
215  mbditer != mbdmap->end();
216  ++mbditer)
217  {
218  const MbdVertex *mbd = mbditer->second;
219 
220  if (used_mbd_vtxids.find(mbd->get_id()) != used_mbd_vtxids.end())
221  {
222  continue;
223  }
224  if (isnan(mbd->get_z()))
225  {
226  continue;
227  }
228 
230  vertex->set_id(globalmap->size());
231 
232  vertex->insert_vtx(GlobalVertex::MBD, mbd);
233  used_mbd_vtxids.insert(mbd->get_id());
234 
235  globalmap->insert(vertex);
236 
237  if (Verbosity() > 1)
238  {
239  vertex->identify();
240  }
241  }
242  }
243 
245  if (trackmap)
246  {
247  for (const auto &[tkey, track] : *trackmap)
248  {
250  auto trackvtxid = track->get_vertex_id();
251  if (globalmap->find(trackvtxid) != globalmap->end())
252  {
253  continue;
254  }
255 
256  float maxdz = std::numeric_limits<float>::max();
257  unsigned int vtxid = std::numeric_limits<unsigned int>::max();
258 
259  for (const auto &[vkey, vertex] : *globalmap)
260  {
261  float dz = track->get_z() - vertex->get_z();
262  if (fabs(dz) < maxdz)
263  {
264  maxdz = dz;
265  vtxid = vkey;
266  }
267  }
268 
269  track->set_vertex_id(vtxid);
270  if (Verbosity())
271  {
272  std::cout << "Associated track with z " << track->get_z() << " to GlobalVertex id " << track->get_vertex_id() << std::endl;
273  }
274  }
275  }
276 
277  if (Verbosity())
278  {
279  globalmap->identify();
280  }
282 }
283 
285 {
286  PHNodeIterator iter(topNode);
287 
288  // Looking for the DST node
289  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
290  if (!dstNode)
291  {
292  cout << PHWHERE << "DST Node missing, doing nothing." << endl;
294  }
295 
296  // store the GLOBAL stuff under a sub-node directory
297  PHCompositeNode *globalNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "GLOBAL"));
298  if (!globalNode)
299  {
300  globalNode = new PHCompositeNode("GLOBAL");
301  dstNode->addNode(globalNode);
302  }
303 
304  // create the GlobalVertexMap
305  GlobalVertexMap *vertexes = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
306  if (!vertexes)
307  {
308  vertexes = new GlobalVertexMapv1();
309  PHIODataNode<PHObject> *VertexMapNode = new PHIODataNode<PHObject>(vertexes, "GlobalVertexMap", "PHObject");
310  globalNode->addNode(VertexMapNode);
311  }
313 }