73 explicit PDFSet(std::string pdfSetName,
bool alternativeReplicaUncertainty =
false)
74 : m_pdfSetName(std::move(pdfSetName)),
75 m_alternativeReplicaUncertainty(alternativeReplicaUncertainty),
76 m_uncertaintyStrategy_(NullUncertaintyStrategy()),
85 : m_uncertaintyStrategy_(NullUncertaintyStrategy()), m_qcdCoupling(NullQCDCoupling()){};
114 std::lock_guard<std::mutex> lock(m_pdfSetMtx);
115 if (m_PDFSet_.find(member) == m_PDFSet_.end())
119 return m_PDFSet_[member].get();
129 if (m_PDFSet_.find(member) == m_PDFSet_.end())
131 return m_PDFSet_.at(member).get();
143 template <
typename T = Tag,
typename = std::enable_if_t<std::is_same_v<T, TMDPDFTag>>>
144 void Uncertainty(PartonFlavor flavor,
double x,
double kt2,
double mu2,
double cl,
145 PDFUncertainty &resUncertainty)
147 const auto pdfs = CalculatePDFValues(flavor, x, kt2, mu2);
148 PDFUncertaintyInternalEvaluation(pdfs, cl, resUncertainty);
159 template <
typename T = Tag,
typename = std::enable_if_t<std::is_same_v<T, CollinearPDFTag>>>
160 void Uncertainty(PartonFlavor flavor,
double x,
double mu2,
double cl,
161 PDFUncertainty &resUncertainty)
163 const auto pdfs = CalculatePDFValues(flavor, x, mu2);
164 PDFUncertaintyInternalEvaluation(pdfs, cl, resUncertainty);
176 template <
typename T = Tag,
typename = std::enable_if_t<std::is_same_v<T, TMDPDFTag>>>
177 PDFUncertainty
Uncertainty(PartonFlavor flavor,
double x,
double kt2,
double mu2,
178 double cl = NO_REQUESTED_CONFIDENCE_LEVEL)
180 PDFUncertainty resUncertainty;
181 const auto pdfs = CalculatePDFValues(flavor, x, kt2, mu2);
182 PDFUncertaintyInternalEvaluation(pdfs, cl, resUncertainty);
183 return resUncertainty;
195 template <
typename T = Tag,
typename = std::enable_if_t<std::is_same_v<T, CollinearPDFTag>>>
196 PDFUncertainty
Uncertainty(PartonFlavor flavor,
double x,
double mu2,
197 double cl = NO_REQUESTED_CONFIDENCE_LEVEL)
199 PDFUncertainty resUncertainty;
200 const auto pdfs = CalculatePDFValues(flavor, x, mu2);
201 PDFUncertaintyInternalEvaluation(pdfs, cl, resUncertainty);
202 return resUncertainty;
211 void Uncertainty(
const std::vector<double> &values,
double cl, PDFUncertainty &resUncertainty)
213 if (values.size() != m_pdfSetErrorInfo.size)
214 throw InvalidInputError(
"Error in PDFxTMD::PDFSet::Uncertainty. Input vector must "
215 "contain values for all PDF members.");
216 PDFUncertaintyInternalEvaluation(values, cl, resUncertainty);
226 double cl = NO_REQUESTED_CONFIDENCE_LEVEL)
228 if (values.size() != m_pdfSetErrorInfo.size)
229 throw InvalidInputError(
"Error in PDFxTMD::PDFSet::Uncertainty. Input vector must "
230 "contain values for all PDF members.");
231 PDFUncertainty resUncertainty;
232 PDFUncertaintyInternalEvaluation(values, cl, resUncertainty);
233 return resUncertainty;
246 template <
typename T = Tag,
typename = std::enable_if_t<std::is_same_v<T, CollinearPDFTag>>>
247 double Correlation(PartonFlavor flavorA,
double xA,
double mu2A, PartonFlavor flavorB,
248 double xB,
double mu2B)
250 const auto pdfsA = CalculatePDFValues(flavorA, xA, mu2A);
251 const auto pdfsB = CalculatePDFValues(flavorB, xB, mu2B);
252 return m_uncertaintyStrategy_.
Correlation(pdfsA, pdfsB, m_pdfErrInfo.nmemCore());
267 template <
typename T = Tag,
typename = std::enable_if_t<std::is_same_v<T, TMDPDFTag>>>
268 double Correlation(PartonFlavor flavorA,
double xA,
double kt2A,
double mu2A,
269 PartonFlavor flavorB,
double xB,
double kt2B,
double mu2B)
271 const auto pdfsA = CalculatePDFValues(flavorA, xA, kt2A, mu2A);
272 const auto pdfsB = CalculatePDFValues(flavorB, xB, kt2B, mu2B);
273 return m_uncertaintyStrategy_.
Correlation(pdfsA, pdfsB, m_pdfErrInfo.nmemCore());
282 double Correlation(
const std::vector<double> &valuesA,
const std::vector<double> &valuesB)
const
284 if (valuesA.size() != m_pdfSetErrorInfo.size || valuesB.size() != m_pdfSetErrorInfo.size)
285 throw InvalidInputError(
"Error in PDFxTMD::PDFSet::Correlation. Input vectors must "
286 "contain values for all PDF members.");
287 return m_uncertaintyStrategy_.
Correlation(valuesA, valuesB, m_pdfErrInfo.nmemCore());
297 if constexpr (std::is_same_v<Tag, TMDPDFTag>)
299 m_PDFSet_.insert_or_assign(
300 setMember, std::make_unique<PDF_t>(
303 else if constexpr (std::is_same_v<Tag, CollinearPDFTag>)
305 m_PDFSet_.insert_or_assign(
306 setMember, std::make_unique<PDF_t>(
311 static_assert(!std::is_same_v<Tag, Tag>,
"Unsupported Tag");
321 for (
int i = 0; i < m_pdfSetStdInfo.NumMembers; ++i)
323 if (m_PDFSet_.find(i) == m_PDFSet_.end())
336 m_pdfSetName = std::move(pdfSetName);
346 return m_pdfSetStdInfo.NumMembers;
355 return m_pdfSetStdInfo;
364 return m_pdfSetErrorInfo;
389 inline void PDFUncertaintyInternalEvaluation(
const std::vector<double> &pdfs,
double cl,
390 PDFUncertainty &resUncertainty)
392 const double reqCL = ValidateAndGetCL(cl);
394 m_uncertaintyStrategy_.
Uncertainty(pdfs, m_pdfErrInfo.nmemCore(), reqCL, resUncertainty);
395 resUncertainty.central = pdfs[0];
397 ApplyConfidenceLevelScaling(resUncertainty, reqCL);
398 StoreCoreVariationErros(resUncertainty);
399 CalculateParameterVariationErrors(resUncertainty, pdfs);
405 ValidatePDFSetName();
407 InitializeUncertaintyStrategy();
411 void InitializeQCDCoupling()
413 m_qcdCoupling = CouplingFactory().mkCoupling(m_pdfSetName);
417 void ValidatePDFSetName()
419 if (m_pdfSetName.empty())
421 throw InvalidInputError(
422 "PDFxTMD::PDFSet::ValidatePDFSetName: PDF set name cannot be empty.");
429 auto infoPathPair = StandardInfoFilePath(m_pdfSetName);
430 if (infoPathPair.second != ErrorType::None)
431 throw FileLoadException(
432 "PDFxTMD::PDFSet::LoadYamlInfo: Unable to find info file of PDF set " +
436 auto yamlInfoErrPair = YamlErrorInfoReader(*infoPathPair.first);
437 if (yamlInfoErrPair.second != ErrorType::None || !yamlInfoErrPair.first.has_value())
443 m_pdfSetErrorInfo = *yamlInfoErrPair.first;
446 auto yamlStdInfoErrPair = YamlStandardPDFInfoReader(*infoPathPair.first);
447 if (yamlStdInfoErrPair.second != ErrorType::None || !yamlStdInfoErrPair.first.has_value())
453 m_pdfSetStdInfo = *yamlStdInfoErrPair.first;
458 throw InvalidInputError(
"PDFSet: Invalid PDF set '" + m_pdfSetName +
459 "'. Please check the YAML file.");
461 if (!m_pdfSetInfo.loadFromFile(*infoPathPair.first, ConfigWrapper::Format::YAML))
463 throw FileLoadException(
"path: " + *infoPathPair.first +
"not found.");
468 void InitializeUncertaintyStrategy()
470 m_pdfErrInfo = PDFErrInfo::CalculateErrorInfo(m_pdfSetErrorInfo);
471 if (m_pdfErrInfo.nmemCore() <= 0)
473 m_uncertaintyStrategy_ = IUncertainty(NullUncertaintyStrategy());
474 PDFxTMDLOG <<
"Error in PDFxTMD::PDFSet::InitializeUncertaintyStrategy. PDF "
475 "set must contain more than just the central value.";
479 const auto &coreType = m_pdfErrInfo.coreType();
480 if (coreType ==
"replicas")
482 if (m_alternativeReplicaUncertainty)
484 m_uncertaintyStrategy_ = IUncertainty(ReplicasPercentileStrategy());
488 m_uncertaintyStrategy_ = IUncertainty(ReplicasStdDevStrategy());
491 else if (coreType ==
"hessian")
493 m_uncertaintyStrategy_ = IUncertainty(HessianStrategy());
495 else if (coreType ==
"symmhessian" || coreType ==
"symm-hessian")
497 m_uncertaintyStrategy_ = IUncertainty(SymmHessianStrategy());
499 else if (coreType ==
"unknown")
501 m_uncertaintyStrategy_ = IUncertainty(NullUncertaintyStrategy());
505 throw NotSupportError(
506 "PDFxTMD::PDFSet::InitializeUncertaintyStrategy: Unsupported error type '" +
507 coreType +
"' for PDF set " + m_pdfSetName +
".");
511 (coreType !=
"replicas") ? m_pdfSetErrorInfo.ErrorConfLevel / 100.0 : CL1SIGMA / 100.0;
515 template <
typename... Args>
516 std::vector<double> CalculatePDFValues(PartonFlavor flavor, Args... args)
const
518 std::vector<double> pdfs;
519 pdfs.reserve(m_pdfSetStdInfo.NumMembers);
520 for (
size_t i = 0; i <
size(); i++)
522 if constexpr (
sizeof...(args) == 3)
524 pdfs.emplace_back(
operator[](i)->tmd(flavor, args...));
528 pdfs.emplace_back(
operator[](i)->pdf(flavor, args...));
535 double ValidateAndGetCL(
double cl)
const
537 const double reqCL = (cl >= 0) ? cl / 100.0 : m_setCL;
538 if (!in_range(reqCL, 0, 1) || !in_range(m_setCL, 0, 1))
540 throw InvalidInputError(
541 "Error in PDFxTMD::PDFSet::ValidateAndGetCL. Requested or PDF set "
542 "confidence level outside [0,1] range.");
548 void ApplyConfidenceLevelScaling(PDFUncertainty &rtn,
double reqCL)
const
550 if (m_setCL != reqCL && !m_alternativeReplicaUncertainty)
552 double qsetCL = chisquared_quantile(m_setCL, 1);
553 double qreqCL = chisquared_quantile(reqCL, 1);
554 const double scale = std::sqrt(qreqCL / qsetCL);
557 rtn.errplus *= scale;
558 rtn.errminus *= scale;
559 rtn.errsymm *= scale;
564 void StoreCoreVariationErros(PDFUncertainty &resUncertainty)
567 resUncertainty.errplus_pdf = resUncertainty.errplus;
568 resUncertainty.errminus_pdf = resUncertainty.errminus;
569 resUncertainty.errsymm_pdf = resUncertainty.errsymm;
570 resUncertainty.errparts.push_back(
571 {resUncertainty.errplus_pdf,
572 resUncertainty.errminus_pdf});
576 void CalculateParameterVariationErrors(PDFUncertainty &rtn,
577 const std::vector<double> &values)
const
579 double errsq_par_plus = 0.0;
580 double errsq_par_minus = 0.0;
581 size_t index = m_pdfErrInfo.nmemCore();
583 for (
size_t iq = 1; iq < m_pdfErrInfo.qparts.size(); ++iq)
585 const auto &eparts = m_pdfErrInfo.qparts[iq];
586 double vmin = rtn.central;
587 double vmax = rtn.central;
589 for (
const auto &epart : eparts)
591 const bool symm = StartsWith(epart.first,
"$");
592 for (
size_t ie = 0; ie < epart.second; ++ie)
597 vmin = std::min(values[index], vmin);
598 vmax = std::max(values[index], vmax);
602 const double delta = values[index] - rtn.central;
603 vmin = std::min({values[index], rtn.central - delta, vmin});
604 vmax = std::max({values[index], rtn.central - delta, vmax});
609 const double eplus = vmax - rtn.central;
610 const double eminus = rtn.central - vmin;
611 rtn.errparts.push_back({eplus, eminus});
612 errsq_par_plus += SQR(eplus);
613 errsq_par_minus += SQR(eminus);
616 std::string m_pdfSetName;
617 ConfigWrapper m_pdfSetInfo;
618 YamlErrorInfo m_pdfSetErrorInfo;
619 YamlStandardTMDInfo m_pdfSetStdInfo;
620 PDFErrInfo m_pdfErrInfo;
621 std::map<unsigned, std::unique_ptr<PDF_t>> m_PDFSet_;
622 std::vector<unsigned int>
623 m_createdPDFSetsMember;
624 IUncertainty m_uncertaintyStrategy_;
625 IQCDCoupling m_qcdCoupling;
627 bool m_alternativeReplicaUncertainty;
628 bool m_isValid =
false;
629 std::mutex m_pdfSetMtx;