18 #include "cetlib_except/exception.h"
19 #include "cetlib/search_path.h"
22 #include "TGraphErrors.h"
24 #include "TDirectory.h"
43 return (
float) corr.evalFactor(E);
68 TDirectory* CalibDir =
nullptr;
70 CalibDir = OpenROOTdirectory(path);
72 catch (cet::exception
const&
e) {
75 (
"ShowerCalibrationGaloreFromPID",
"readCalibration()", e)
76 <<
"Reading calibration from: '" << path <<
"'";
80 (
"ShowerCalibrationGaloreFromPID",
"readCalibration()")
81 <<
"Null directory reading calibration from: '" << path <<
"'";
85 std::unique_ptr<TFile>
InputFile(CalibDir->GetFile());
91 Calibration_pi0 = readParticleCalibration(CalibDir,
"Pi0", 111);
93 Calibration_photon = readParticleCalibration(CalibDir,
"Photon", 22);
96 = readParticleCalibration(CalibDir,
"Electron", { -11, 11 });
98 Calibration_muon = readParticleCalibration(CalibDir,
"Muon", { -13, 13 });
100 Calibration_other = readParticleCalibration(CalibDir,
"Default", unknownID);
117 return Calibration_pi0;
119 return Calibration_photon;
122 return Calibration_electron;
125 return Calibration_muon;
128 return Calibration_other;
136 (TDirectory* SourceDir, std::string GraphName)
const
145 auto graph = details::readROOTobject<TGraphErrors>(SourceDir, GraphName);
147 verifyOrder(graph.get());
149 size_t const N = (size_t) graph->GetN();
151 throw cet::exception(
"ShowerCalibrationGaloreFromPID")
152 <<
"No point in graph " << SourceDir->GetPath() <<
"/" << GraphName
157 info.
minE = graph->GetX()[0];
158 info.
maxE = graph->GetX()[N - 1];
163 info.
factor = createInterpolator(N, graph->GetX(), graph->GetY());
166 info.
error = createInterpolator(N, graph->GetX(), graph->GetEY());
174 (TGraph
const* graph)
178 throw cet::exception(
"ShowerCalibrationGaloreFromPID")
179 <<
"VerifyOrder(): invalid graph specified\n";
182 size_t const N = graph->GetN();
185 Double_t
const*
x = graph->GetX();
187 for (
size_t i = 1; i <
N; ++i) {
189 throw cet::exception(
"ShowerCalibrationGaloreFromPID")
190 <<
"VerifyOrder(): points in graph '" << graph->GetName()
191 <<
"' are not sorted in abscissa\n";
200 (TDirectory* SourceDir, std::string GraphName,
PDGID_t id)
const
210 TDirectory* SourceDir, std::string GraphName,
211 std::initializer_list<PDGID_t> ids
226 std::string filePath, ROOTdirPath;
232 std::string fullFilePath;
233 cet::search_path sp(
"FW_SEARCH_PATH");
235 if (!sp.find_file(filePath, fullFilePath)) fullFilePath = filePath;
240 auto inputFile = std::make_unique<TFile>(fullFilePath.c_str(),
"READ");
241 if (!(inputFile->IsOpen())) {
242 throw cet::exception(
"ShowerCalibrationGaloreFromPID")
243 <<
"ShowerCalibrationGaloreFromPID::OpenROOTdirectory() can't read '"
244 << fullFilePath <<
"' (from '" << filePath <<
"' specification)\n";
250 TDirectory*
dir = ROOTdirPath.empty()?
251 inputFile.get(): inputFile->GetDirectory(ROOTdirPath.c_str());
253 throw cet::exception(
"ShowerCalibrationGaloreFromPID")
254 <<
"ShowerCalibrationGaloreFromPID::OpenROOTdirectory() can't find '"
255 << ROOTdirPath <<
"' in ROOT file '" << inputFile->GetPath() <<
"'\n";
273 auto it = std::lower_bound(appliesTo.begin(), appliesTo.end(), id);
274 if ((it == appliesTo.end()) || (*it !=
id))
275 appliesTo.insert(it,
id);
282 (std::initializer_list<PDGID_t> ids)
284 appliesTo.insert(appliesTo.begin(), ids.begin(), ids.end());
285 std::sort(appliesTo.begin(), appliesTo.end());
295 double const boundE = std::min(maxE, std::max(minE, E));
296 return factor->Eval(boundE);
303 double const boundE = std::min(maxE, std::max(minE, E));
304 return error->Eval(boundE);
309 std::unique_ptr<ROOT::Math::Interpolator>
311 (
unsigned int N,
double const*
x,
double const*
y)
316 if (N >= 5) type = ROOT::Math::Interpolation::kAKIMA;
317 else if (N >= 3) type = ROOT::Math::Interpolation::kCSPLINE;
318 else type = ROOT::Math::Interpolation::kLINEAR;
321 = std::make_unique<ROOT::Math::Interpolator>(std::max(N, 2U),
type);
322 if (N > 1) interp->SetData(N, x, y);
324 double const x_p[2] = { *
x, *x + 1. };
325 double const y_p[2] = { *
y, *y };
326 interp->SetData(2, x_p, y_p);
334 std::pair<std::string, std::string>
336 const std::string suffix =
".root";
339 std::string::size_type iSuffix = std::string::npos;
341 iSuffix = path.rfind(suffix, iSuffix);
342 if (iSuffix == std::string::npos)
return {};
345 auto iAfter = iSuffix + suffix.length();
346 if ((iAfter < path.length())
347 && (path[iAfter] !=
'/')
348 && (path[iAfter] !=
':')
352 if (iSuffix == 0)
return {};
358 std::pair<std::string, std::string> result;
360 result.first = path.substr(0U, iAfter);
361 if (iAfter < path.length())
362 result.second = path.substr(iAfter + 1, path.length());
double minE
lower end of the energy range covered [GeV]
Internal structure containing the calibration information.
process_name opflash particleana ie x
double evalError(double E) const
std::unique_ptr< ROOT::Math::Interpolator > error
parametrisation of the correction uncertainty
CalibrationInfo_t const & selectCorrection(PDGID_t id) const
Returns the correct CalibrationInfo_t for specified id.
static std::unique_ptr< ROOT::Math::Interpolator > createInterpolator(unsigned int N, double const *x, double const *y)
Creates a ROOT interpolator from a set of N points.
A correction factor with global uncertainty.
virtual Correction_t correction(recob::Shower const &, PDGID_t=unknownID) const override
Returns the correction for a given reconstructed shower.
BEGIN_PROLOG triggeremu_data_config_icarus settings PMTADCthresholds sequence::icarus_stage0_multiTPC_TPC physics sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_WestHits_TPC physics producers purityana0 caloskimCalorimetryCryoE physics caloskimCalorimetryCryoW physics path
process_name opflash particleana ie ie y
virtual float correctionFactor(recob::Shower const &shower, PDGID_t PDGID=unknownID) const =0
Returns a correction factor for a given reconstructed shower.
CalibrationInfo_t readParticleCalibration(TDirectory *SourceDir, std::string GraphName) const
Reads and returns calibration information from the specified graph.
static void verifyOrder(TGraph const *graph)
CalibrationInfo_t & applyTo(PDGID_t id)
std::unique_ptr< ROOT::Math::Interpolator > factor
parametrisation of the correction factor
int PDGID_t
A type representing a particle ID in Particle Data Group convention.
process_name largeant stream1 can override from command line with o or output physics producers generator N
const std::vector< double > & Energy() const
Shower energy calibration according to particle type.
double maxE
upper end of the energy range covered [GeV]
std::pair< std::string, std::string > splitROOTpath(std::string path)
Splits path into ROOT file name and directory path.
double evalFactor(double E) const
void readCalibration(std::string path)
Reads the calibration information from the specified file.
static TDirectory * OpenROOTdirectory(std::string path)
Opens the specified ROOT directory, as in path/to/file.root:dir/dir.