-
Notifications
You must be signed in to change notification settings - Fork 188
Merge processes at runtime #267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
4a83cf8
cbd6e7f
3d56d83
b2c6755
5f57af8
5ce7aa8
31c1e5c
d083a1f
a88c577
9e29eec
31354dd
f79ffa9
351229a
521207c
a742eb5
69ba4f3
dd29bd3
f96b253
9397ef7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| #include "TDirectory.h" | ||
| #include "TH1.h" | ||
| #include "TH2.h" | ||
| #include "TString.h" | ||
| #include "CombineHarvester/CombineTools/interface/Observation.h" | ||
| #include "CombineHarvester/CombineTools/interface/Process.h" | ||
| #include "CombineHarvester/CombineTools/interface/Systematic.h" | ||
|
|
@@ -126,16 +127,21 @@ TH1F CombineHarvester::GetShapeWithUncertainty() { | |
| } | ||
|
|
||
| TH1F CombineHarvester::GetShapeWithUncertainty(RooFitResult const* fit, | ||
| unsigned n_samples) { | ||
| return GetShapeWithUncertainty(*fit, n_samples); | ||
| unsigned n_samples, | ||
| const bool& verbose) { | ||
| return GetShapeWithUncertainty(*fit, n_samples, verbose); | ||
| } | ||
|
|
||
| TH1F CombineHarvester::GetShapeWithUncertainty(RooFitResult const& fit, | ||
| unsigned n_samples) { | ||
| unsigned n_samples, | ||
| const bool& verbose) | ||
| { | ||
| auto lookup = GenerateProcSystMap(); | ||
| TH1F shape = GetShapeInternal(lookup); | ||
| std::vector<std::string> full_rand_shape_summary; | ||
| for (int i = 1; i <= shape.GetNbinsX(); ++i) { | ||
| shape.SetBinError(i, 0.0); | ||
| full_rand_shape_summary.push_back(""); | ||
| } | ||
| // Create a backup copy of the current parameter values | ||
| auto backup = GetParameters(); | ||
|
|
@@ -152,22 +158,51 @@ TH1F CombineHarvester::GetShapeWithUncertainty(RooFitResult const& fit, | |
| for (unsigned n = 0; n < p_vec.size(); ++n) { | ||
| r_vec[n] = dynamic_cast<RooRealVar const*>(rands.at(n)); | ||
| p_vec[n] = GetParameter(r_vec[n]->GetName()); | ||
| // if(! p_vec[n]) std::cout << "could not initialize parameter '" << r_vec[n]->GetName() << "'" << std::endl; | ||
| } | ||
|
|
||
| TString tmp; | ||
|
|
||
| // Main loop through n_samples | ||
| for (unsigned i = 0; i < n_samples; ++i) { | ||
| // Randomise and update values | ||
| fit.randomizePars(); | ||
| std::string rand_shape_summary = ""; | ||
| for (int n = 0; n < n_pars; ++n) { | ||
| if (p_vec[n]) p_vec[n]->set_val(r_vec[n]->getVal()); | ||
| if (p_vec[n] && !p_vec[n]->frozen()) { | ||
| p_vec[n]->set_val(r_vec[n]->getVal()); | ||
| tmp.Form("setting parameter '%s' to %f\n", p_vec[n]->name().c_str(), r_vec[n]->getVal()); | ||
| // std::cout << tmp.Data(); | ||
| rand_shape_summary = tmp.Data(); | ||
| // std::cout << rand_shape_summary.c_str() << std::endl; | ||
| TH1F rand_shape = this->GetShapeInternal(lookup); | ||
| for (int j = 1; j <= rand_shape.GetNbinsX(); ++j) { | ||
| tmp.Form("\tBin Content %i: %f\n", j, rand_shape.GetBinContent(j)); | ||
| // std::cout << tmp.Data(); | ||
| full_rand_shape_summary.at(j-1) = rand_shape_summary; | ||
| full_rand_shape_summary.at(j-1) += tmp.Data(); | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like quite a lot of information (checking the updated shape for bin for every updated parameter value). I wonder if it is maybe a bit too much, and could be avoided? But perhaps this was useful in some debugging which I'm simply not aware of. It just seems it would be a lot to even read through for large models, and perhaps targeting more specific information might be better?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes definitely! I originally implemented this when we generated post-fit uncertainty bands for our ttHbb analysis and so some very large fluctuations in the bands. The intend there was really to find the reason for these fluctuations, which is why I wanted to output as much information as possible. I think the comment by Andrew is valid, and it might be better to simply change to toys themselves into a dedicated root file. I can also update this PR accordingly if we want to have something like that from the start, or we can do it at some later point in time |
||
| } | ||
| // else if (!p_vec[n]) { | ||
| // std::cout << "could not find parameter '" << r_vec[n]->GetName() << "'"<< std::endl; | ||
| // } | ||
| } | ||
|
|
||
| TH1F rand_shape = this->GetShapeInternal(lookup); | ||
| for (int i = 1; i <= shape.GetNbinsX(); ++i) { | ||
| for (int j = 1; j <= shape.GetNbinsX(); ++j) { | ||
|
|
||
| double err = | ||
| std::fabs(rand_shape.GetBinContent(i) - shape.GetBinContent(i)); | ||
| shape.SetBinError(i, err*err + shape.GetBinError(i)); | ||
| std::fabs(rand_shape.GetBinContent(j) - shape.GetBinContent(j)); | ||
| if (std::fabs(err/shape.GetBinContent(j)) >= 0.5 and verbose){ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I may be over optimizing here, but perhaps some of these extra steps could be avoided by default when not using the verbose mode? Perhaps just an I'm also wondering if it would be useful to make this 0.5 threshold a configurable parameter? |
||
| std::cout << "rel. error > 0.5 detected in bin " << j << " for toy " << i << std::endl; | ||
| std::cout << "nominal bin content (" << j << "):\t" << shape.GetBinContent(j) <<std::endl; | ||
| std::cout << "randomized bin content (" << j << "):\t" << rand_shape.GetBinContent(j) <<std::endl; | ||
| std::cout << "parameters: " << std::endl; | ||
| std::cout << "random shape evolution" << std::endl; | ||
| std::cout << full_rand_shape_summary.at(j-1).c_str() << std::endl; | ||
| } | ||
| shape.SetBinError(j, err*err + shape.GetBinError(j)); | ||
| } | ||
| this->UpdateParameters(backup); | ||
| } | ||
| for (int i = 1; i <= shape.GetNbinsX(); ++i) { | ||
| shape.SetBinError(i, std::sqrt(shape.GetBinError(i)/double(n_samples))); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deafult behaviour of PostFitShapesFromWorkspace should be to use sampling, and now use of the actual
--samplingflag prints out a warning. So the code should not check the--samplingflag, but rather the--no-samplingflag, and always do sampling unless--no-samplinghas been set.