Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RawTowerCombiner.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RawTowerCombiner.cc
1 #include "RawTowerCombiner.h"
2 
3 #include <calobase/RawTower.h>
4 #include <calobase/RawTowerContainer.h>
5 #include <calobase/RawTowerDefs.h>
6 #include <calobase/RawTowerGeomContainer.h>
7 #include <calobase/RawTowerGeomv1.h>
8 #include <calobase/RawTowerv1.h>
9 
10 #include <fun4all/Fun4AllBase.h>
12 #include <fun4all/SubsysReco.h>
13 
14 #include <phool/PHCompositeNode.h>
15 #include <phool/PHNode.h>
16 #include <phool/PHNodeIterator.h>
17 #include <phool/getClass.h>
18 
19 #include <CLHEP/Vector/ThreeVector.h>
20 
21 #include <cassert>
22 #include <cmath>
23 #include <cstdlib>
24 #include <exception>
25 #include <iostream>
26 #include <map>
27 #include <stdexcept>
28 #include <utility>
29 #include <vector>
30 
32  : SubsysReco(name)
33  , _tower_node_prefix("SIM")
34  , _n_combine_eta(2)
35  , _n_combine_phi(2)
36  , _towers(nullptr)
37  , detector("NONE")
38 {
39 }
40 
42 {
43  if (_n_combine_eta == 0)
44  {
45  std::cout << __PRETTY_FUNCTION__ << " Fatal error _n_combine_eta==0" << std::endl;
46 
47  exit(1243);
48  }
49 
50  if (_n_combine_phi == 0)
51  {
52  std::cout << __PRETTY_FUNCTION__ << " Fatal error _n_combine_phi==0" << std::endl;
53 
54  exit(1243);
55  }
56 
57  PHNodeIterator iter(topNode);
58 
59  // Looking for the DST node
60  PHCompositeNode *dstNode;
61  dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode",
62  "DST"));
63  if (!dstNode)
64  {
65  std::cout << __PRETTY_FUNCTION__ << "DST Node missing, doing nothing."
66  << std::endl;
67  exit(1);
68  }
69 
70  try
71  {
72  CreateNodes(topNode);
73  }
74  catch (std::exception &e)
75  {
76  std::cout << e.what() << std::endl;
77  // exit(1);
78  }
79 
81 }
82 
84 {
85  assert(_towers);
86 
87  const double input_e_sum = _towers->getTotalEdep();
88  const double input_n_tower = _towers->size();
89 
90  if (Verbosity())
91  {
92  std::cout << __PRETTY_FUNCTION__ << "Process event entered" << std::endl;
93  }
94 
95  using tower_id_t = std::pair<int, int>;
96  using new_tower_map_t = std::map<tower_id_t, RawTower *>;
97  new_tower_map_t new_tower_map;
98 
100  for (RawTowerContainer::ConstIterator it = all_towers.first;
101  it != all_towers.second; ++it)
102  {
103  const RawTower *input_tower = it->second;
104  assert(input_tower);
105 
106  const int intput_eta = input_tower->get_bineta();
107  const int intput_phi = input_tower->get_binphi();
108  const int output_eta = get_output_bin_eta(intput_eta);
109  const int output_phi = get_output_bin_phi(intput_phi);
110 
111  RawTower *output_tower = nullptr;
112  new_tower_map_t::iterator it_new = new_tower_map.find(
113  std::make_pair(output_eta, output_phi));
114 
115  if (it_new == new_tower_map.end())
116  {
117  output_tower = new RawTowerv1(*input_tower);
118  assert(output_tower);
119  new_tower_map[std::make_pair(output_eta, output_phi)] = output_tower;
120 
121  if (Verbosity() >= VERBOSITY_MORE)
122  {
123  std::cout << __PRETTY_FUNCTION__ << "::" << detector << "::"
124  << " new output tower (prior to tower ID assignment): ";
125  output_tower->identify();
126  }
127  }
128  else
129  {
130  output_tower = it_new->second;
131 
132  output_tower->set_energy(
133  output_tower->get_energy() + input_tower->get_energy());
134 
135  output_tower->set_time(
136  (std::abs(output_tower->get_energy()) * output_tower->get_time() + std::abs(input_tower->get_energy()) * input_tower->get_time()) //
137  / (std::abs(output_tower->get_energy()) + std::abs(input_tower->get_energy()) + 1e-9) // avoid devide 0
138  );
139 
140  RawTower::CellConstRange cell_range = input_tower->get_g4cells();
141 
142  for (RawTower::CellConstIterator cell_iter = cell_range.first;
143  cell_iter != cell_range.second; ++cell_iter)
144  {
145  output_tower->add_ecell(cell_iter->first, cell_iter->second);
146  }
147 
148  RawTower::ShowerConstRange shower_range =
149  input_tower->get_g4showers();
150 
151  for (RawTower::ShowerConstIterator shower_iter = shower_range.first;
152  shower_iter != shower_range.second; ++shower_iter)
153  {
154  output_tower->add_eshower(shower_iter->first,
155  shower_iter->second);
156  }
157 
158  if (Verbosity() >= VERBOSITY_MORE)
159  {
160  std::cout << __PRETTY_FUNCTION__ << "::" << detector << "::"
161  << " merget into output tower (prior to tower ID assignment) : ";
162  output_tower->identify();
163  }
164  }
165  }
166 
167  // replace content in tower container
168  _towers->Reset();
169 
170  for (auto &it : new_tower_map)
171  {
172  const int eta = it.first.first;
173  const int phi = it.first.second;
174  RawTower *tower = it.second;
175 
176  _towers->AddTower(eta, phi, tower);
177  }
178 
179  if (Verbosity())
180  {
181  std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
182  << "input sum energy = " << input_e_sum << " from " << input_n_tower << " towers, merged sum energy = "
183  << _towers->getTotalEdep() << " from " << _towers->size() << " towers" << std::endl;
184  assert(input_e_sum == _towers->getTotalEdep());
185  }
186 
188 }
189 
191 {
193 }
194 
196 {
197  PHNodeIterator iter(topNode);
198  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(iter.findFirst(
199  "PHCompositeNode", "RUN"));
200  if (!runNode)
201  {
202  std::cerr << __PRETTY_FUNCTION__ << "Run Node missing, doing nothing."
203  << std::endl;
204  throw std::runtime_error(
205  "Failed to find Run node in RawTowerCombiner::CreateNodes");
206  }
207 
208  const RawTowerDefs::CalorimeterId caloid =
210 
211  const std::string iTowerGeomNodeName = "TOWERGEOM_" + detector;
213  RawTowerGeomContainer>(topNode, iTowerGeomNodeName);
214  if (!towergeom)
215  {
216  std::cerr << __PRETTY_FUNCTION__ << " - " << iTowerGeomNodeName
217  << " Node missing, doing nothing." << std::endl;
218  throw std::runtime_error(
219  "Failed to find input tower geometry node in RawTowerCombiner::CreateNodes");
220  }
221  assert(towergeom);
222 
223  const double r = towergeom->get_radius();
224 
225  const int new_phibins = ceil(
226  double(towergeom->get_phibins()) / double(_n_combine_phi));
227  const int new_etabins = ceil(
228  double(towergeom->get_etabins()) / double(_n_combine_eta));
229 
230  using bound_t = std::pair<double, double>;
231  using bound_map_t = std::vector<bound_t>;
232 
233  bound_map_t eta_bound_map;
234  bound_map_t phi_bound_map;
235 
236  for (int ibin = 0; ibin < new_phibins; ibin++)
237  {
238  const int first_bin = ibin * _n_combine_phi;
239  assert(first_bin >= 0 && first_bin < towergeom->get_phibins());
240 
241  int last_bin = (ibin + 1) * _n_combine_phi - 1;
242  if (last_bin >= towergeom->get_phibins())
243  {
244  last_bin = towergeom->get_phibins();
245  }
246 
247  const std::pair<double, double> range1 = towergeom->get_phibounds(
248  first_bin);
249  const std::pair<double, double> range2 = towergeom->get_phibounds(
250  last_bin);
251 
252  phi_bound_map.push_back(std::make_pair(range1.first, range2.second));
253  }
254 
255  for (int ibin = 0; ibin < new_etabins; ibin++)
256  {
257  const int first_bin = ibin * _n_combine_eta;
258  assert(first_bin >= 0 && first_bin < towergeom->get_etabins());
259 
260  int last_bin = (ibin + 1) * _n_combine_eta - 1;
261  if (last_bin >= towergeom->get_etabins())
262  {
263  last_bin = towergeom->get_etabins();
264  }
265 
266  const std::pair<double, double> range1 = towergeom->get_etabounds(
267  first_bin);
268  const std::pair<double, double> range2 = towergeom->get_etabounds(
269  last_bin);
270 
271  eta_bound_map.push_back(std::make_pair(range1.first, range2.second));
272  }
273 
274  // now update the tower geometry object with the new tower structure.
275  towergeom->Reset();
276 
277  towergeom->set_phibins(new_phibins);
278  towergeom->set_etabins(new_etabins);
279 
280  for (int ibin = 0; ibin < new_phibins; ibin++)
281  {
282  towergeom->set_phibounds(ibin, phi_bound_map[ibin]);
283  }
284  for (int ibin = 0; ibin < new_etabins; ibin++)
285  {
286  towergeom->set_etabounds(ibin, eta_bound_map[ibin]);
287  }
288 
289  // setup location of all towers
290  for (int iphi = 0; iphi < towergeom->get_phibins(); iphi++)
291  {
292  for (int ieta = 0; ieta < towergeom->get_etabins(); ieta++)
293  {
295  RawTowerDefs::encode_towerid(caloid, ieta, iphi));
296 
297  CLHEP::Hep3Vector tower_pos;
298  tower_pos.setRhoPhiEta(r, towergeom->get_phicenter(iphi), towergeom->get_etacenter(ieta));
299 
300  tg->set_center_x(tower_pos.x());
301  tg->set_center_y(tower_pos.y());
302  tg->set_center_z(tower_pos.z());
303 
304  towergeom->add_tower_geometry(tg);
305  }
306  }
307  if (Verbosity() >= VERBOSITY_SOME)
308  {
309  towergeom->identify();
310  }
311 
312  const std::string input_TowerNodeName = "TOWER_" + _tower_node_prefix + "_" + detector;
313  _towers = findNode::getClass<RawTowerContainer>(topNode,
314  input_TowerNodeName);
315  if (!_towers)
316  {
317  std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
318  << " " << input_TowerNodeName << " Node missing, doing bail out!"
319  << std::endl;
320  throw std::runtime_error(
321  "Failed to find " + input_TowerNodeName + " node in RawTowerCombiner::CreateNodes");
322  }
323 
324  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst(
325  "PHCompositeNode", "DST"));
326  if (!dstNode)
327  {
328  std::cerr << __PRETTY_FUNCTION__ << "DST Node missing, doing nothing."
329  << std::endl;
330  throw std::runtime_error(
331  "Failed to find DST node in RawTowerCombiner::CreateNodes");
332  }
333 
334  return;
335 }