File indexing completed on 2025-08-05 08:12:21
0001 #include "CaloCalibration.h"
0002
0003 #include "PROTOTYPE4_FEM.h"
0004 #include "RawTower_Prototype4.h"
0005
0006 #include <calobase/RawTower.h> // for RawTower
0007 #include <calobase/RawTowerContainer.h>
0008 #include <calobase/RawTowerDefs.h> // for keytype
0009
0010 #include <phparameter/PHParameters.h> // for PHParameters
0011
0012 #include <fun4all/Fun4AllReturnCodes.h>
0013 #include <fun4all/SubsysReco.h> // for SubsysReco
0014
0015 #include <phool/PHCompositeNode.h>
0016 #include <phool/PHIODataNode.h> // for PHIODataNode
0017 #include <phool/PHNode.h> // for PHNode
0018 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0019 #include <phool/PHObject.h> // for PHObject
0020 #include <phool/getClass.h>
0021
0022 #include <boost/format.hpp>
0023
0024 #include <cassert>
0025 #include <cmath> // for NAN, isnan
0026 #include <cstdlib> // for exit
0027 #include <iostream>
0028 #include <limits> // for numeric_limits
0029 #include <map> // for map, _Rb_tree_iter...
0030 #include <stdexcept> // for runtime_error
0031 #include <string>
0032 #include <utility> // for pair
0033 #include <vector> // for vector
0034
0035 using namespace std;
0036
0037
0038 CaloCalibration::CaloCalibration(const std::string &name)
0039 : SubsysReco(string("CaloCalibration_") + name)
0040 , _calib_towers(nullptr)
0041 , _raw_towers(nullptr)
0042 , detector(name)
0043 , _calib_tower_node_prefix("CALIB")
0044 , _raw_tower_node_prefix("RAW")
0045 , _calib_params(name)
0046 , _fit_type(kPowerLawDoubleExpWithGlobalFitConstraint)
0047 {
0048 SetDefaultParameters(_calib_params);
0049 }
0050
0051
0052 int CaloCalibration::InitRun(PHCompositeNode *topNode)
0053 {
0054 CreateNodeTree(topNode);
0055
0056 if (Verbosity())
0057 {
0058 std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
0059 << " - print calibration parameters: " << endl;
0060 _calib_params.Print();
0061 }
0062
0063 return Fun4AllReturnCodes::EVENT_OK;
0064 }
0065
0066
0067 int CaloCalibration::process_event(PHCompositeNode *topNode)
0068 {
0069 if (Verbosity())
0070 {
0071 std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
0072 << "Process event entered" << std::endl;
0073 }
0074
0075 map<int, double> parameters_constraints;
0076 if(detector == "CEMC")
0077 {
0078 std::cout << "hey tim did we get here? " << std::endl;
0079 }
0080 if (_fit_type == kPowerLawDoubleExpWithGlobalFitConstraint and
0081 _raw_towers->size() > 1)
0082 {
0083 if (Verbosity())
0084 {
0085 std::cout
0086 << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
0087 << "Extract global fit parameter for constraining individual fits"
0088 << std::endl;
0089 }
0090
0091
0092
0093 vector<double> vec_signal_samples(PROTOTYPE4_FEM::NSAMPLES, 0);
0094 vector<float> timtest;
0095 vector<vector<float>> timtest2;
0096 int count = 0;
0097
0098 RawTowerContainer::Range begin_end = _raw_towers->getTowers();
0099 RawTowerContainer::Iterator rtiter;
0100 for (rtiter = begin_end.first; rtiter != begin_end.second; ++rtiter)
0101 {
0102 RawTower_Prototype4 *raw_tower =
0103 dynamic_cast<RawTower_Prototype4 *>(rtiter->second);
0104 assert(raw_tower);
0105
0106 ++count;
0107
0108 for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
0109 {
0110 timtest.push_back(raw_tower->get_signal_samples(i));
0111 if (raw_tower->get_signal_samples(i) <= 10 or
0112 raw_tower->get_signal_samples(i) >= ((1 << 14) - 10))
0113 {
0114 vec_signal_samples[i] =
0115 numeric_limits<double>::quiet_NaN();
0116 }
0117 else
0118 {
0119 vec_signal_samples[i] += raw_tower->get_signal_samples(i);
0120 }
0121 }
0122 timtest2.push_back(timtest);
0123 timtest.clear();
0124
0125 }
0126 if (detector=="CEMC")
0127 {
0128 std::cout<< timtest2.size() << std::endl;
0129 }
0130 if (count > 0)
0131 {
0132 for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
0133 {
0134 vec_signal_samples[i] /= count;
0135 }
0136
0137 double peak = NAN;
0138 double peak_sample = NAN;
0139 double pedstal = NAN;
0140 map<int, double> parameters_io;
0141
0142 PROTOTYPE4_FEM::SampleFit_PowerLawDoubleExp(vec_signal_samples, peak,
0143 peak_sample, pedstal,
0144 parameters_io, Verbosity());
0145
0146
0147
0148
0149
0150
0151 parameters_constraints[1] = parameters_io[1];
0152 parameters_constraints[2] = parameters_io[2];
0153 parameters_constraints[3] = parameters_io[3];
0154 parameters_constraints[5] = parameters_io[5];
0155 parameters_constraints[6] = parameters_io[6];
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 }
0178 else
0179 {
0180 std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
0181 << ": Failed to build signal template! Fit each channel "
0182 "individually instead"
0183 << std::endl;
0184 }
0185 }
0186
0187 const double calib_const_scale =
0188 _calib_params.get_double_param("calib_const_scale");
0189 const bool use_chan_calibration =
0190 _calib_params.get_int_param("use_chan_calibration") > 0;
0191
0192 RawTowerContainer::Range begin_end = _raw_towers->getTowers();
0193 RawTowerContainer::Iterator rtiter;
0194 for (rtiter = begin_end.first; rtiter != begin_end.second; ++rtiter)
0195 {
0196 RawTowerDefs::keytype key = rtiter->first;
0197 RawTower_Prototype4 *raw_tower =
0198 dynamic_cast<RawTower_Prototype4 *>(rtiter->second);
0199 assert(raw_tower);
0200
0201 double calibration_const = calib_const_scale;
0202
0203 if (use_chan_calibration)
0204 {
0205
0206 const int column = raw_tower->get_column();
0207 const int row = raw_tower->get_row();
0208
0209 assert(column >= 0);
0210 assert(row >= 0);
0211
0212 string calib_const_name(
0213 (boost::format("calib_const_column%d_row%d") % column % row).str());
0214
0215 calibration_const *= _calib_params.get_double_param(calib_const_name);
0216 }
0217
0218 vector<double> vec_signal_samples;
0219 for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
0220 {
0221 vec_signal_samples.push_back(raw_tower->get_signal_samples(i));
0222 }
0223
0224 double peak = NAN;
0225 double peak_sample = NAN;
0226 double pedstal = NAN;
0227
0228 switch (_fit_type)
0229 {
0230 case kPowerLawExp:
0231 PROTOTYPE4_FEM::SampleFit_PowerLawExp(vec_signal_samples, peak,
0232 peak_sample, pedstal, Verbosity());
0233 break;
0234
0235 case kPeakSample:
0236 PROTOTYPE4_FEM::SampleFit_PeakSample(vec_signal_samples, peak,
0237 peak_sample, pedstal, Verbosity());
0238 break;
0239
0240 case kPowerLawDoubleExp:
0241 {
0242 map<int, double> parameters_io;
0243
0244 PROTOTYPE4_FEM::SampleFit_PowerLawDoubleExp(vec_signal_samples, peak,
0245 peak_sample, pedstal,
0246 parameters_io, Verbosity());
0247 }
0248 break;
0249
0250 case kPowerLawDoubleExpWithGlobalFitConstraint:
0251 {
0252 map<int, double> parameters_io(parameters_constraints);
0253
0254 PROTOTYPE4_FEM::SampleFit_PowerLawDoubleExp(vec_signal_samples, peak,
0255 peak_sample, pedstal,
0256 parameters_io, Verbosity());
0257 }
0258 break;
0259 default:
0260 cout << __PRETTY_FUNCTION__ << " - FATAL error - unkown fit type "
0261 << _fit_type << endl;
0262 exit(3);
0263 break;
0264 }
0265
0266
0267 if (std::isnan(raw_tower->get_energy()))
0268 {
0269
0270
0271 raw_tower->set_energy(peak);
0272 raw_tower->set_time(peak_sample);
0273
0274 if (Verbosity())
0275 {
0276 raw_tower->identify();
0277 }
0278 }
0279
0280
0281 RawTower_Prototype4 *calib_tower = new RawTower_Prototype4(*raw_tower);
0282 calib_tower->set_energy(peak * calibration_const);
0283 calib_tower->set_time(peak_sample);
0284
0285 for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
0286 {
0287 calib_tower->set_signal_samples(i, (vec_signal_samples[i] - pedstal) *
0288 calibration_const);
0289 }
0290
0291 _calib_towers->AddTower(key, calib_tower);
0292
0293 }
0294
0295 if (Verbosity())
0296 {
0297 std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
0298 << "input sum energy = " << _raw_towers->getTotalEdep()
0299 << ", output sum digitalized value = "
0300 << _calib_towers->getTotalEdep() << std::endl;
0301 }
0302
0303 return Fun4AllReturnCodes::EVENT_OK;
0304 }
0305
0306
0307 void CaloCalibration::CreateNodeTree(PHCompositeNode *topNode)
0308 {
0309 PHNodeIterator iter(topNode);
0310
0311 PHCompositeNode *dstNode =
0312 dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0313 if (!dstNode)
0314 {
0315 std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
0316 << "DST Node missing, doing nothing." << std::endl;
0317 throw std::runtime_error(
0318 "Failed to find DST node in RawTowerCalibration::CreateNodes");
0319 }
0320
0321 RawTowerNodeName = "TOWER_" + _raw_tower_node_prefix + "_" + detector;
0322 _raw_towers =
0323 findNode::getClass<RawTowerContainer>(dstNode, RawTowerNodeName.c_str());
0324 if (!_raw_towers)
0325 {
0326 std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
0327 << " " << RawTowerNodeName << " Node missing, doing bail out!"
0328 << std::endl;
0329 throw std::runtime_error("Failed to find " + RawTowerNodeName +
0330 " node in RawTowerCalibration::CreateNodes");
0331 }
0332
0333
0334 PHNodeIterator dstiter(dstNode);
0335 PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(
0336 dstiter.findFirst("PHCompositeNode", detector));
0337 if (!DetNode)
0338 {
0339 DetNode = new PHCompositeNode(detector);
0340 dstNode->addNode(DetNode);
0341 }
0342
0343
0344
0345 CaliTowerNodeName = "TOWER_" + _calib_tower_node_prefix + "_" + detector;
0346 _calib_towers =
0347 findNode::getClass<RawTowerContainer>(DetNode, CaliTowerNodeName.c_str());
0348 if (!_calib_towers)
0349 {
0350 _calib_towers = new RawTowerContainer(_raw_towers->getCalorimeterID());
0351 PHIODataNode<PHObject> *towerNode = new PHIODataNode<PHObject>(
0352 _calib_towers, CaliTowerNodeName.c_str(), "PHObject");
0353 DetNode->addNode(towerNode);
0354 }
0355
0356
0357 PHCompositeNode *parNode =
0358 dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
0359 assert(parNode);
0360 const string paramnodename = string("Calibration_") + detector;
0361
0362
0363
0364 _calib_params.SaveToNodeTree(parNode, paramnodename);
0365 }
0366
0367 void CaloCalibration::SetDefaultParameters(PHParameters ¶m)
0368 {
0369 param.set_int_param("use_chan_calibration", 0);
0370
0371
0372
0373 param.set_double_param("calib_const_scale", 1);
0374 }