JohannesBuchner / UltraNest

Fit and compare complex models reliably and rapidly. Advanced nested sampling.
https://johannesbuchner.github.io/UltraNest/
Other
153 stars 30 forks source link

Access chains / intermediary results for run in progess? #111

Closed OGdodge closed 1 year ago

OGdodge commented 1 year ago

Description

Describe what you were trying to get done. Tell us what happened, what went wrong, and what you expected to happen.

Sorry this is more of a question rather than a bug. Apologies if I am missing something obvious, but I've been trying to work this out for a few days. Is it possible to have Ultranest save the chains / results files at a set number of iterations in addition to producing the nicelogger output? I see the points file is produced / updated for runs in progress, but the chains are not.

Ideally I'm aiming to produce intermediate corner / trace plots for the run in progress (either using the inbuilt plotting or anesthetic) as well as take the current best likelihood / a posteriori likelihood point and produce models using it, ie. extract it and run it through a seperate program.

I've tried using run_iter, but haven't got anywhere. I've taken a look at the source code and have noticied I could possible harness _update_result() but I'm not entirely clear on how to use run_iter to trigger something every 100 iterations or so - I tried for iter, result in sampler.run_iter(): if iter % 100 == 0: print('TEST') and similar but couldn't get anything out.

Is this possible and if so what have I missed! Again apologies for a fairly specific request / question.

JohannesBuchner commented 1 year ago

If you only want corner / trace plots, then I think you can copy the code of nicelogger and see how it accesses the live points (points['p'], for example), and run with run(..., viz_callback=mynewfunction)

https://github.com/JohannesBuchner/UltraNest/blob/master/ultranest/viz.py#L85

If you want to not have a callback on every run, keep a counter and skip.

def myfunc():
    myfunc.mycounter += 1
    if myfunc.mycounter % 10 == 0: print("Hello")

myfunc.mycounter = 0
myfunc()
myfunc()
myfunc()
myfunc()

If you really want the full chains rather than the live points, then you can do run and limit the number of iterations with max_iters. API doc: https://johannesbuchner.github.io/UltraNest/ultranest.html#ultranest.integrator.ReactiveNestedSampler You can do that in a loop, successively increasing max_iters, and get the results. Should set max_num_improvement_loops=0.

I am not sure the chains are insightful though, since all of the posterior weight will be concentrated in the maximum likelihood point.