Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CaloCalibration.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CaloCalibration.cc
1 #include "CaloCalibration.h"
2 
3 #include "PROTOTYPE4_FEM.h"
4 #include "RawTower_Prototype4.h"
5 
6 #include <calobase/RawTower.h> // for RawTower
7 #include <calobase/RawTowerContainer.h>
8 #include <calobase/RawTowerDefs.h> // for keytype
9 
10 #include <phparameter/PHParameters.h> // for PHParameters
11 
13 #include <fun4all/SubsysReco.h> // for SubsysReco
14 
15 #include <phool/PHCompositeNode.h>
16 #include <phool/PHIODataNode.h> // for PHIODataNode
17 #include <phool/PHNode.h> // for PHNode
18 #include <phool/PHNodeIterator.h> // for PHNodeIterator
19 #include <phool/PHObject.h> // for PHObject
20 #include <phool/getClass.h>
21 
22 #include <boost/format.hpp>
23 
24 #include <cassert>
25 #include <cmath> // for NAN, isnan
26 #include <cstdlib> // for exit
27 #include <iostream>
28 #include <limits> // for numeric_limits
29 #include <map> // for map, _Rb_tree_iter...
30 #include <stdexcept> // for runtime_error
31 #include <string>
32 #include <utility> // for pair
33 #include <vector> // for vector
34 
35 using namespace std;
36 
37 //____________________________________
39  : SubsysReco(string("CaloCalibration_") + name)
40  , _calib_towers(nullptr)
41  , _raw_towers(nullptr)
42  , detector(name)
43  , _calib_tower_node_prefix("CALIB")
44  , _raw_tower_node_prefix("RAW")
45  , _calib_params(name)
46  , _fit_type(kPowerLawDoubleExpWithGlobalFitConstraint)
47 {
49 }
50 
51 //_____________________________________
53 {
54  CreateNodeTree(topNode);
55 
56  if (Verbosity())
57  {
58  std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
59  << " - print calibration parameters: " << endl;
61  }
62 
64 }
65 
66 //____________________________________
68 {
69  if (Verbosity())
70  {
71  std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
72  << "Process event entered" << std::endl;
73  }
74 
75  map<int, double> parameters_constraints;
76  if(detector == "CEMC")
77  {
78  std::cout << "hey tim did we get here? " << std::endl;
79  }
81  _raw_towers->size() > 1)
82  {
83  if (Verbosity())
84  {
85  std::cout
86  << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
87  << "Extract global fit parameter for constraining individual fits"
88  << std::endl;
89  }
90 
91  // signal template
92 
93  vector<double> vec_signal_samples(PROTOTYPE4_FEM::NSAMPLES, 0);
94  vector<float> timtest;
95  vector<vector<float>> timtest2;
96  int count = 0;
97 
100  for (rtiter = begin_end.first; rtiter != begin_end.second; ++rtiter)
101  {
102  RawTower_Prototype4 *raw_tower =
103  dynamic_cast<RawTower_Prototype4 *>(rtiter->second);
104  assert(raw_tower);
105 
106  ++count;
107 
108  for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
109  {
110  timtest.push_back(raw_tower->get_signal_samples(i));
111  if (raw_tower->get_signal_samples(i) <= 10 or
112  raw_tower->get_signal_samples(i) >= ((1 << 14) - 10))
113  {
114  vec_signal_samples[i] =
115  numeric_limits<double>::quiet_NaN(); // invalidate this sample
116  }
117  else
118  {
119  vec_signal_samples[i] += raw_tower->get_signal_samples(i);
120  }
121  }
122  timtest2.push_back(timtest);
123  timtest.clear();
124  // }
125  }
126  if (detector=="CEMC")
127  {
128  std::cout<< timtest2.size() << std::endl;
129  }
130  if (count > 0)
131  {
132  for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
133  {
134  vec_signal_samples[i] /= count;
135  }
136 
137  double peak = NAN;
138  double peak_sample = NAN;
139  double pedstal = NAN;
140  map<int, double> parameters_io;
141 
142  PROTOTYPE4_FEM::SampleFit_PowerLawDoubleExp(vec_signal_samples, peak,
143  peak_sample, pedstal,
144  parameters_io, Verbosity());
145  // std::map<int, double> &parameters_io, //! IO for fullset of
146  // parameters. If a parameter exist and not an NAN, the fit parameter
147  // will be fixed to that value. The order of the parameters are
148  // ("Amplitude", "Sample Start", "Power", "Peak Time 1", "Pedestal",
149  // "Amplitude ratio", "Peak Time 2")
150 
151  parameters_constraints[1] = parameters_io[1];
152  parameters_constraints[2] = parameters_io[2];
153  parameters_constraints[3] = parameters_io[3];
154  parameters_constraints[5] = parameters_io[5];
155  parameters_constraints[6] = parameters_io[6];
156 
157  // //special constraint if Peak Time 1 == Peak Time 2
158  // if (abs(parameters_constraints[6] - parameters_constraints[3]) <
159  // 0.1)
160  // {
161  // const double average_peak_time = (parameters_constraints[6] +
162  // parameters_constraints[3]) / 2.;
163  //
164  // std::cout << Name() << "::" << detector << "::" <<
165  // __PRETTY_FUNCTION__
166  // << ": two shaping time are too close "
167  // << parameters_constraints[3] << " VS " <<
168  // parameters_constraints[6]
169  // << ". Use average peak time instead: " <<
170  // average_peak_time
171  // << std::endl;
172  //
173  // parameters_constraints[6] = average_peak_time;
174  // parameters_constraints[3] = average_peak_time;
175  // parameters_constraints[5] = 0;
176  // }
177  }
178  else
179  {
180  std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
181  << ": Failed to build signal template! Fit each channel "
182  "individually instead"
183  << std::endl;
184  }
185  }
186 
187  const double calib_const_scale =
188  _calib_params.get_double_param("calib_const_scale");
189  const bool use_chan_calibration =
190  _calib_params.get_int_param("use_chan_calibration") > 0;
191 
194  for (rtiter = begin_end.first; rtiter != begin_end.second; ++rtiter)
195  {
196  RawTowerDefs::keytype key = rtiter->first;
197  RawTower_Prototype4 *raw_tower =
198  dynamic_cast<RawTower_Prototype4 *>(rtiter->second);
199  assert(raw_tower);
200 
201  double calibration_const = calib_const_scale;
202 
203  if (use_chan_calibration)
204  {
205  // channel to channel calibration.
206  const int column = raw_tower->get_column();
207  const int row = raw_tower->get_row();
208 
209  assert(column >= 0);
210  assert(row >= 0);
211 
212  string calib_const_name(
213  (boost::format("calib_const_column%d_row%d") % column % row).str());
214 
215  calibration_const *= _calib_params.get_double_param(calib_const_name);
216  }
217 
218  vector<double> vec_signal_samples;
219  for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
220  {
221  vec_signal_samples.push_back(raw_tower->get_signal_samples(i));
222  }
223 
224  double peak = NAN;
225  double peak_sample = NAN;
226  double pedstal = NAN;
227 
228  switch (_fit_type)
229  {
230  case kPowerLawExp:
231  PROTOTYPE4_FEM::SampleFit_PowerLawExp(vec_signal_samples, peak,
232  peak_sample, pedstal, Verbosity());
233  break;
234 
235  case kPeakSample:
236  PROTOTYPE4_FEM::SampleFit_PeakSample(vec_signal_samples, peak,
237  peak_sample, pedstal, Verbosity());
238  break;
239 
240  case kPowerLawDoubleExp:
241  {
242  map<int, double> parameters_io;
243 
244  PROTOTYPE4_FEM::SampleFit_PowerLawDoubleExp(vec_signal_samples, peak,
245  peak_sample, pedstal,
246  parameters_io, Verbosity());
247  }
248  break;
249 
251  {
252  map<int, double> parameters_io(parameters_constraints);
253 
254  PROTOTYPE4_FEM::SampleFit_PowerLawDoubleExp(vec_signal_samples, peak,
255  peak_sample, pedstal,
256  parameters_io, Verbosity());
257  }
258  break;
259  default:
260  cout << __PRETTY_FUNCTION__ << " - FATAL error - unkown fit type "
261  << _fit_type << endl;
262  exit(3);
263  break;
264  }
265 
266  // store the result - raw_tower
267  if (std::isnan(raw_tower->get_energy()))
268  {
269  // Raw tower was never fit, store the current fit
270 
271  raw_tower->set_energy(peak);
272  raw_tower->set_time(peak_sample);
273 
274  if (Verbosity())
275  {
276  raw_tower->identify();
277  }
278  }
279 
280  // store the result - calib_tower
281  RawTower_Prototype4 *calib_tower = new RawTower_Prototype4(*raw_tower);
282  calib_tower->set_energy(peak * calibration_const);
283  calib_tower->set_time(peak_sample);
284 
285  for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
286  {
287  calib_tower->set_signal_samples(i, (vec_signal_samples[i] - pedstal) *
288  calibration_const);
289  }
290 
291  _calib_towers->AddTower(key, calib_tower);
292 
293  } // for (rtiter = begin_end.first; rtiter != begin_end.second; ++rtiter)
294 
295  if (Verbosity())
296  {
297  std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
298  << "input sum energy = " << _raw_towers->getTotalEdep()
299  << ", output sum digitalized value = "
300  << _calib_towers->getTotalEdep() << std::endl;
301  }
302 
304 }
305 
306 //_______________________________________
308 {
309  PHNodeIterator iter(topNode);
310 
311  PHCompositeNode *dstNode =
312  dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
313  if (!dstNode)
314  {
315  std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
316  << "DST Node missing, doing nothing." << std::endl;
317  throw std::runtime_error(
318  "Failed to find DST node in RawTowerCalibration::CreateNodes");
319  }
320 
321  RawTowerNodeName = "TOWER_" + _raw_tower_node_prefix + "_" + detector;
322  _raw_towers =
323  findNode::getClass<RawTowerContainer>(dstNode, RawTowerNodeName.c_str());
324  if (!_raw_towers)
325  {
326  std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
327  << " " << RawTowerNodeName << " Node missing, doing bail out!"
328  << std::endl;
329  throw std::runtime_error("Failed to find " + RawTowerNodeName +
330  " node in RawTowerCalibration::CreateNodes");
331  }
332 
333  // Create the tower nodes on the tree
334  PHNodeIterator dstiter(dstNode);
335  PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(
336  dstiter.findFirst("PHCompositeNode", detector));
337  if (!DetNode)
338  {
339  DetNode = new PHCompositeNode(detector);
340  dstNode->addNode(DetNode);
341  }
342 
343  // Be careful as a previous calibrator may have been registered for this
344  // detector
346  _calib_towers =
347  findNode::getClass<RawTowerContainer>(DetNode, CaliTowerNodeName.c_str());
348  if (!_calib_towers)
349  {
352  _calib_towers, CaliTowerNodeName.c_str(), "PHObject");
353  DetNode->addNode(towerNode);
354  }
355 
356  // update the parameters on the node tree
357  PHCompositeNode *parNode =
358  dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
359  assert(parNode);
360  const string paramnodename = string("Calibration_") + detector;
361 
362  // this step is moved to after detector construction
363  // save updated persistant copy on node tree
364  _calib_params.SaveToNodeTree(parNode, paramnodename);
365 }
366 
368 {
369  param.set_int_param("use_chan_calibration", 0);
370 
371  // additional scale for the calibration constant
372  // negative pulse -> positive with -1
373  param.set_double_param("calib_const_scale", 1);
374 }