Skip to content
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

Add likelihood that takes coupling as shape parameters #34

Merged
merged 9 commits into from
Dec 8, 2021

Conversation

jingqiangye
Copy link
Contributor

In some cases, we have a bunch of signals that depend on shared couplings. For instance, if we have:

  • signal_a
  • signal_b
  • signal_c

Instead of the rate multipliers of signal a, b, and c, we want to set constraints on the coupling g1 and g2 directly, because in this way:

  • we only need to work on fewer parameters
  • the rate correlation between different signals is properly accounted for

This PR addresses exactly the issue by adding the coupling parameters into the shape parameters. A conversion config conv_config is passed to initialize a new likelihood called UnbinnedLogLikelihoodVaried so that the likelihood knows how to translate the couplings to rate multipliers for each signal source later. The prior constraint on the coupling parameter itself is also possible.

In fact, the new likelihood can handle more than the coupling -- should any shape parameter has a correlation with the signal rate, it can be realized by writing this correlation info in the conversion config.

@kdund kdund requested review from kdund and JelleAalbers October 22, 2021 20:29
@JelleAalbers
Copy link
Owner

Thanks Jingqiang! I can certainly see the use case for this, but without unit tests or an example I can't really tell how this works.

If I understand your current implementation correctly, the likelihood will still have the "shape parameters" that mask rate parameters as actual shape parameters. They won't get any values when called due to your argument filtering, but I imagine you still have to pass anchors to initialize them, interpolators will get created on initialization, called during likelihood calls, etc.

Did you consider instead writing a wrapper/adapter class that keeps an actual likelihood in a private attribute, rather than something inheriting from LogLikelihood? LogLikelihoodSum and LogAncillaryLikelihood are also implemented that way.

@jingqiangye
Copy link
Contributor Author

Hi Jelle, good to hear your comments! Indeed I think it should be cleaner to use a wrapper. I will change it and attach an example notebook when it is done.

@jingqiangye
Copy link
Contributor Author

@JelleAalbers @kdund I uploaded an example notebook in this gist.

A quick summary is I tested it with multiple gaussian peak signals over a flat background, and the fit results are around the true values as expected. I also added a utils.py in the gist, so we don't need to rely on any private packages we develop except for the nice multihist package from you :)

Currently, couplings as shape parameters are not really constrained by the priors as I guess usually we won't put such constraints on the signal couplings? This can be easily done if you think it's necessary. The con is just it takes some time to build the likelihood but it's ok.

@kdund
Copy link
Collaborator

kdund commented Oct 28, 2021

If we want to add some constraint terms, they can be added as separate logAncillaryLikelihoods (

class LogAncillaryLikelihood(object):
), I think ?

@jingqiangye
Copy link
Contributor Author

Ah yeah, could be. Or we just add the constraints on the LogLikelihoodVaried. This is not difficult :)

@jingqiangye
Copy link
Contributor Author

Hi, I added test_likelihood_reparam.py so that we can do some basic tests for LogLikelihoodReParam. It has three tests:

  • Test if the computed likelihood is correct or not, test_likelihood_value()
  • Test if the likelihood is consistent before and after reparameterization, test_likelihoods_before_after_reparam()
  • Test if the new parameters we want to reparameterize are consistent or not, test_consistency_new_params()
    • To see it can raise errors when the new parameters are not consistent, we can use:
      • test_consistency_new_params(use_wrong_config=True) to assign a wrong config, or
      • test_consistency_new_params(use_wrong_conv_config=True) to assign a wrong conv_config

Copy link
Owner

@JelleAalbers JelleAalbers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very nice, thanks for your work Jingqiang! The tests pass for me (after #37).

If you want to be super neat, you can remove the commented def pdf_base_config(self): code and the empty lines at the end of test_likelihood_reparam.py. Your history will be preserved when we rebase.

@jingqiangye
Copy link
Contributor Author

Hey @JelleAalbers, thanks for approving and also the suggestions! Those unnecessary stuff are cleaned up now :D

@jingqiangye
Copy link
Contributor Author

Can we merge this PR? :D @JelleAalbers @kdund

@jingqiangye
Copy link
Contributor Author

@JelleAalbers @kdund Just let you know that I don't have the write access so I can't merge this PR even if it's approved... can any of you merge the PR? Thanks a lot :)

@kdund kdund merged commit 2ab0d0f into JelleAalbers:master Dec 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants