8000 Overriding parameter ranges after PDF has been built · Issue #621 · zfit/zfit · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Overriding parameter ranges after PDF has been built #621

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

Open
acampove opened this issue May 4, 2025 · 3 comments
Open

Overriding parameter ranges after PDF has been built #621

acampove opened this issue May 4, 2025 · 3 comments
Labels
discussion For discussions on concepts and ideas

Comments

@acampove
Copy link
acampove commented May 4, 2025

Is your feature request related to a problem? Please describe.

When we build models, we need a lot of code to get a sum of crystall balls, or gaussians, etc. One way to go around this is to make a model factory like the one here. This allows:

  1. To quickly build new models from existing ones without having to declare every parameter, range etc
  2. Keeps the code clean.

However once the model is built we seem to be unable to do something like:

for par in pdf.params():
    if par.name.startswith(mu_):
        par.update_range(min=3000, max=4000)

In my particular case, the ModelFactory builds models for fitting B meson masses. However I would like to adapt it quickly to fit Jpsi masses.

Describe the solution you'd like

I wonder if a method to override the already built parameter range can be implemented, like:

par.update_range(low=3000, high=4000)

Describe alternatives you've considered

In the model factory I could do:

from dmu.stats.model_factory import ModelFactory

l_pdf = ['cbr'] + 2 * ['cbl']
l_shr = ['mu', 'sg']
d_par={'mu' : mu}

d_fix = {'al_cbl' : 3, 'nr_cbr' : 1} # This is optional and will fix two parameters whose names start with the keys
mod   = ModelFactory(obs = Data.obs, l_pdf = l_pdf, l_shared=l_shr, d_fix=d_fix, d_par=d_par)
pdf   = mod.get_pdf()

i.e. introduce my parameter instead of allowing the factory to build that parameter.

Additional context
Add any other context or screenshots about the feature request here.

@acampove acampove added the discussion For discussions on concepts and ideas label May 4, 2025
@jonas-eschle
Copy link
Contributor

You can actually do that! param.lower = 2 should do the trick and set the limit.

However, I would not, in general, do this. The limits should not really matter. A limit is just there to say that if the value is close to it, it's completely wrong. It's a "if you're here, everything is invalid" limit. Ideally, the limits should be far away from the expected value and the fits should also work fine without any limits. They just help to give an approximate idea (i.e., is the value more between -10, 10 (for a lambda of an exp, or more 5000 - 6000 (for a value of the B mass). You can also set the stepsize on initialization smart, i.e. the order of magnitude should match the expected uncertainty (i.e. for yields of a fit to 100K events, set it to 100, 1000 or something. For lambda of an exp, more like 1e-2 or something.

Did you see any issues? Or anything?

The model factory kinda makes sense. In general, it's better to recreate PDFs than to manipulate existing ones (because of caching and jit), so having a "factory function" (or any other factory) makes a lot of sense!

@acampove
Copy link
Author
acampove commented May 5, 2025

You can actually do that! param.lower = 2 should do the trick and set the limit.

However, I would not, in general, do this. The limits should not really matter. A limit is just there to say that if the value is close to it, it's completely wrong. It's a "if you're here, everything is invalid" limit. Ideally, the limits should be far away from the expected value and the fits should also work fine without any limits.

Limits are optional for parameters? I did not know that.

They just help to give an approximate idea (i.e., is the value more between -10, 10 (for a lambda of an exp, or more 5000 - >6000 (for a value of the B mass). You can also set the stepsize on initialization smart, i.e. the order of magnitude should >match the expected uncertainty (i.e. for yields of a fit to 100K events, set it to 100, 1000 or something. For lambda of an exp, >more like 1e-2 or something.

Oh, I did not know about the stepsize. So the only thing that the fitting framework actually needs is the value and the parameter.

Did you see any issues? Or anything?

I just needed more flexibility to adapt my fitting models to other fits. I just made a small class to do this. This class should talk to a database and get in the way, injecting a custom range. But maybe just not passing any range and letting the fitter figure it out is better.

On the other hand, at least the value should be around the right number. If you have a peak at 10 in your model but the data has it at 100, then when you evaluate the likelihood you are sampling the tail, where the PDF is basically zero. That would give you NaNs and even with modern computer's precision, I think that tail would drop so fast that you would just get a NaN. So, some fancier algorithm or setting numbers by hand will be needed at the end.

The model factory kinda makes sense. In general, it's better to recreate PDFs than to manipulate existing ones (because of caching and jit), so having a "factory function" (or any other factory) makes a lot of sense!

Yeah, to me (and I assume most users) what matters the most is that I spend less time typing stuff and that my code be as small and simple as possible.

@jonas-eschle
Copy link
Contributor

Limits are optional for parameters? I did not know that.

Yes, there is no real reason for them to be there, albeit it's often good to have a dead zone

Oh, I did not know about the stepsize. So the only thing that the fitting framework actually needs is the value and the parameter.

Yes, the minimizer needs an initial value and an "initial step size". That's basically it.

On the other hand, at least the value should be around the right number.

I would even go further: this is the crucial element. The minimizers are local minimizers, they start at the point and go downhill basically until they find a minimium. That's it, no magic or anything. So yes, make sure to start "close enough" (but not on point)

Yeah, to me (and I assume most users) what matters the most is that I spend less time typing stuff and that my code be as small and simple as possible.

Agree!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion For discussions on concepts and ideas
Projects
None yet
Development

No branches or pull requests

2 participants
0