Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JetReco.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file JetReco.cc
1 
2 #include "JetReco.h"
3 
4 #include "Jet.h"
5 #include "JetAlgo.h"
6 #include "JetContainer.h"
7 #include "JetContainerv1.h"
8 #include "JetInput.h"
9 #include "JetMap.h"
10 #include "JetMapv1.h"
11 
12 // PHENIX includes
14 #include <fun4all/SubsysReco.h> // for SubsysReco
15 
16 #include <phool/PHCompositeNode.h>
17 #include <phool/PHIODataNode.h>
18 #include <phool/PHNode.h> // for PHNode
19 #include <phool/PHNodeIterator.h>
20 #include <phool/PHObject.h> // for PHObject
22 #include <phool/getClass.h>
23 #include <phool/phool.h> // for PHWHERE
24 
25 // standard includes
26 #include <cstdlib> // for exit
27 #include <iostream>
28 #include <memory> // for allocator_traits<>::value_type
29 #include <vector>
30 #include <fstream>
31 
33  : SubsysReco(name)
34  , which_fill{_which}
35  , use_jetcon{_which == TRANSITION::JET_CONTAINER || _which == TRANSITION::BOTH || _which == TRANSITION::PRETEND_BOTH}
36  , use_jetmap{_which == TRANSITION::JET_MAP || _which == TRANSITION::BOTH}
37 {
38 }
39 /* JetReco::JetReco(const std::string &name, TRANSITION _which) */
40 /* : SubsysReco(name) */
41 /* , which_fill{_which} */
42 /* , use_jetcon{false} */
43 /* , use_jetmap{true} */
44 /* { */
45 /* } */
46 
47 
49 {
50  for (auto &_input : _inputs)
51  {
52  delete _input;
53  }
54  _inputs.clear();
55  for (auto &_algo : _algos)
56  {
57  delete _algo;
58  }
59  _algos.clear();
60  _outputs.clear();
61 }
62 
64 {
65  if (Verbosity() > 0)
66  {
67  std::cout << "========================== JetReco::InitRun() =============================" << std::endl;
68  std::cout << " Input Selections:" << std::endl;
69  for (auto &_input : _inputs) _input->identify();
70  std::cout << " Algorithms:" << std::endl;
71  for (auto &_algo : _algos) _algo->identify();
72  std::cout << "===========================================================================" << std::endl;
73  }
74 
75  return CreateNodes(topNode);
76 }
77 
79 {
80 
81  if (Verbosity() > 1) std::cout << "JetReco::process_event -- entered" << std::endl;
82 
83  //------------------------------------------------------------------
84  // This will also need to go into TClonesArrays in a future revision
85  // Get Objects off of the Node Tree
86  //------------------------------------------------------------------
87 
88  std::vector<Jet *> inputs; // owns memory
89  for (auto &_input : _inputs)
90  {
91  std::vector<Jet *> parts = _input->get_input(topNode);
92  for (auto &part : parts)
93  {
94  inputs.push_back(part);
95  inputs.back()->set_id(inputs.size() - 1); // unique ids ensured
96  }
97  }
98 
99  //---------------------------
100  // Run the jet reconstruction
101  //---------------------------
102  for (unsigned int ialgo = 0; ialgo < _algos.size(); ++ialgo)
103  {
104  // send the output somewhere on the DST
105  /* if (_fill_JetContainer) { */
106  if (use_jetcon)
107  {
108  if (Verbosity() > 5) std::cout << " Verbosity>5:: filling JetContainter for " << JC_name(_outputs[ialgo]) << std::endl;
109  FillJetContainer(topNode, ialgo, inputs);
110  }
111  if (use_jetmap)
112  {
113  if (Verbosity() > 5) std::cout << " Verbosity>5:: filling jetnode for " << _outputs[ialgo] << std::endl;
114  std::vector<Jet *> jets = _algos[ialgo]->get_jets(inputs); // owns memory
115  FillJetNode(topNode, ialgo, jets);
116  }
117 
118  if (false ) { // These printouts were used in comparing the two map methods
119  // It can be removed later
120  if (use_jetmap) {
121  std::fstream fout;
122  fout.open("fixme_jetmap", std::fstream::app);
123  fout << " Printing jet results " << std::endl;
124  JetMap *jetmap = findNode::getClass<JetMap>(topNode, _outputs[ialgo]);
125  int ifixme =0;
126  for (auto _jet = jetmap->begin(); _jet != jetmap->end(); ++_jet) {
127  auto jet = _jet->second;
128  fout << Form(" jet[%2i] ncon:pt:eta:phi [%6i,%6.3f,%6.3f,%6.3f]",
129  ++ifixme, (int)jet->size_comp(), jet->get_pt(), jet->get_eta(), jet->get_phi()) << std::endl;
130  std::vector<std::pair<int,int>> vconst;
131  /*legacy*/ for (auto _comp = jet->begin_comp(); _comp != jet->end_comp(); ++_comp) {
132  vconst.push_back({(int)_comp->first,(int)_comp->second});
133  }
134  std::sort(vconst.begin(), vconst.end(), [](std::pair<int,int> a, std::pair<int,int> b)
135  {
136  if (a.first == b.first) return a.second < b.second;
137  else return a.first < b.first;
138  });
139  fout << " constituents: ";
140  int iconst = 0;
141  for (const auto& p : vconst) {
142  fout << Form(" c(%3i) %3i->%3i", iconst++, p.first, p.second) << std::endl;
143  }
144  fout << std::endl;
145  }
146  }
147  if (use_jetcon) {
148  std::fstream fout;
149  fout.open("fixme_jetcont", std::fstream::app);
150  fout << " Printing jet results" << std::endl;
151  JetContainer *jet_cont = findNode::getClass<JetContainer>(topNode,JC_name(_outputs[ialgo]));
152  int ifixme =0;
153 
154  /* for (auto jet = jet_cont->begin(); jet != jet_cont->end(); ++jet) { */
155  for (auto jet : *jet_cont) {
156  fout << Form(" jet[%2i] ncon:pt:eta:phi [%6i,%6.3f,%6.3f,%6.3f]",
157  ++ifixme, (int)jet->size_comp(), jet->get_pt(), jet->get_eta(), jet->get_phi()) << std::endl;
158 
159  fout << " constituents: ";
160  int iconst = 0;
161  for (const auto& p : jet->get_comp_vec()) {
162  fout << Form(" c(%3i) %3i->%3i", iconst++, p.first, p.second) << std::endl;
163  }
164 
165  fout << std::endl;
166  }
167  }
168  }
169 
170  }
171 
172  // clean up input vector
173  // <- another place where TClonesArray's would make this more efficient
174  for (auto &input : inputs) delete input;
175  inputs.clear();
176 
177  if (Verbosity() > 1) std::cout << "JetReco::process_event -- exited" << std::endl;
178 
180 }
181 
183 {
184  PHNodeIterator iter(topNode);
185 
186  // Looking for the DST node
187  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
188  if (!dstNode)
189  {
190  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
192  }
193 
194  // Create the AntiKt node if required
195  PHCompositeNode *AlgoNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", _algonode));
196  if (!AlgoNode)
197  {
198  AlgoNode = new PHCompositeNode(_algonode);
199  dstNode->addNode(AlgoNode);
200  }
201 
202  // Create the Input node if required
203  PHCompositeNode *InputNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", _inputnode));
204  if (!InputNode)
205  {
206  InputNode = new PHCompositeNode(_inputnode);
207  AlgoNode->addNode(InputNode);
208  }
209 
210  for (auto &_output : _outputs)
211  {
212  if (use_jetcon)
213  {
214  JetContainer *jetconn = findNode::getClass<JetContainer>(topNode, JC_name(_output));
215  if (!jetconn)
216  {
217  jetconn = new JetContainerv1();
218  PHIODataNode<PHObject> *JetContainerNode = new PHIODataNode<PHObject>(jetconn, JC_name(_output), "PHObject");
219  InputNode->addNode(JetContainerNode);
220  }
221  }
222  if (use_jetmap)
223  {
224  JetMap *jets = findNode::getClass<JetMap>(topNode, _output);
225  if (!jets)
226  {
227  jets = new JetMapv1();
228  PHIODataNode<PHObject> *JetMapNode = new PHIODataNode<PHObject>(jets, _output, "PHObject");
229  InputNode->addNode(JetMapNode);
230  }
231  }
232  }
233 
235 }
236 
237 void JetReco::FillJetNode(PHCompositeNode *topNode, int ipos, std::vector<Jet *> jets)
238 {
239  JetMap *jetmap = findNode::getClass<JetMap>(topNode, _outputs[ipos]);
240  if (!jetmap)
241  {
242  std::cout << PHWHERE << " ERROR: Can't find JetMap: " << _outputs[ipos] << std::endl;
243  exit(-1);
244  }
245 
246  jetmap->set_algo(_algos[ipos]->get_algo());
247  jetmap->set_par(_algos[ipos]->get_par());
248  for (auto &_input : _inputs)
249  {
250  jetmap->insert_src(_input->get_src());
251  }
252 
253  for (auto &jet : jets)
254  {
255  jetmap->insert(jet); // map takes ownership, sets unique id
256  }
257 
258  return;
259 }
260 
261 void JetReco::FillJetContainer(PHCompositeNode *topNode, int ipos, std::vector<Jet *> &inputs)
262 {
263  JetContainer *jetconn = findNode::getClass<JetContainer>(topNode, JC_name(_outputs[ipos]));
264  if (!jetconn)
265  {
266  std::cout << PHWHERE << " ERROR: Can't find JetContainer: " << _outputs[ipos] << std::endl;
267  exit(-1);
268  }
269  _algos[ipos]->cluster_and_fill(inputs, jetconn); // fills the jet container with clustered jets
270  for (auto &_input : _inputs)
271  {
272  jetconn->insert_src(_input->get_src());
273  }
274 
275  if (Verbosity() > 7)
276  {
277  std::cout << " Verbosity()>7:: jets in container " << _outputs[ipos] << std::endl;
278  jetconn->print_jets();
279  }
280 
281  return;
282 }
283 
284 JetAlgo *JetReco::get_algo(unsigned int which_algo)
285 {
286  if (_algos.size() == 0)
287  {
288  std::cout << PHWHERE << std::endl
289  << " JetReco has only " << _algos.size() << " JetAlgos; cannot get the one indexed " << which_algo << std::endl;
290  assert(which_algo < _algos.size());
291  return nullptr;
292  }
293  return _algos[which_algo];
294 }