18 #include "cetlib_except/exception.h" 19 #include "cetlib/search_path.h" 22 #include "TGraphErrors.h" 24 #include "TDirectory.h" 68 TDirectory* CalibDir =
nullptr;
70 CalibDir = OpenROOTdirectory(path);
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);
136 (TDirectory* SourceDir, std::string GraphName)
const 145 auto graph = details::readROOTobject<TGraphErrors>(SourceDir, GraphName);
149 size_t const N = (size_t) graph->GetN();
152 <<
"No point in graph " << SourceDir->GetPath() <<
"/" << GraphName
157 info.
minE = graph->GetX()[0];
158 info.
maxE = graph->GetX()[N - 1];
174 (TGraph
const* graph)
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) {
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())) {
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());
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());
296 return factor->Eval(boundE);
304 return error->Eval(boundE);
309 std::unique_ptr<ROOT::Math::Interpolator>
311 (
unsigned int N,
double const*
x,
double const*
y)
315 ROOT::Math::Interpolation::Type type;
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());
CalibrationInfo_t Calibration_pi0
neutral pion calibration
virtual Correction_t correction(recob::Shower const &, PDGID_t=unknownID) const override
Returns the correction for a given reconstructed shower.
double minE
lower end of the energy range covered [GeV]
CalibrationInfo_t Calibration_electron
electron/positron calibration
Internal structure containing the calibration information.
double evalError(double E) const
std::unique_ptr< ROOT::Math::Interpolator > error
parametrisation of the correction uncertainty
const std::vector< double > & Energy() const
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.
CalibrationInfo_t Calibration_photon
photon calibration
CalibrationInfo_t Calibration_other
default calibration
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)
CalibrationInfo_t Calibration_muon
muon/antimuon calibration
std::unique_ptr< ROOT::Math::Interpolator > factor
parametrisation of the correction factor
virtual float correctionFactor(recob::Shower const &, PDGID_t=unknownID) const override
Returns a correction factor for a given reconstructed shower.
static constexpr PDGID_t unknownID
A mnemonic constant for unknown particle ID.
int PDGID_t
A type representing a particle ID in Particle Data Group convention.
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.
cet::coded_exception< error, detail::translate > exception