New qin lf - #89
New qin lf#89cwjames1983 wants to merge 16 commits into
Conversation
Trying to force astropy to work by using python 3.12
profxj
left a comment
There was a problem hiding this comment.
Review scope: the PR diff vs main (e85d656) — 22 files, +1900/−192. This is a big improvement over #87: the iteration.py re-merge from main is clean (I verified minimise_const_only2, the PATH machinery, the ptauw dkis2 coefficients, get_rates() masking, and the lEmax=41.84 default are all restored; Grid.update() stays deleted; grid_kwargs is now actually passed; the MeerTRAP Unicode-minus and the DSA_34 reference in zdm/scripts/slurm/ are fixed; and the new tests all pass). What remains are three small-but-fatal slips that crash exactly the configurations this PR ships, plus a few silent-behavior items and the #87 structural suggestions that are still open.
Blocking — small fixes, but they crash the shipped configurations
-
zdm/iteration.py:750-751— half-applied rename: line 731 defineszt_tomult, but the two use sites now readptaus *= tz_tomult/piws *= tz_tomult(main useszt_tomultin all three). Any run withptauw=True— the option this PR wires intoMCMC_wrap— dies withNameErrorat the first evaluation. -
zdm/iteration.py:1721-1743—calc_likelihoods_2D's pwb block now referencesbweights/wweights, which are only ever defined incalc_likelihoods_1D(lines 544-545); this function defineszbweights/zwweights(1227-1248), which is what main used here. Any run withpwb=Trueon a survey with localized FRBs — exactly what both shipped slurm scripts do (--Pn --pwb) — raisesNameErrorat line 1721. -
zdm/MCMC.py:456—if nthreads < 1:executes before theif nthreads is not None:resolution at 461, and the new default isnthreads=None(both inmcmc_runnerandMCMC_wrap --nthreads), so every default invocation dies withTypeError: '<' not supported between 'NoneType' and 'int'before sampling. Move the guard after the None-resolution. Two adjacent issues while you're there: (a) the comment at 459-460 says numerical libraries are prevented from starting extra threads, but the oldOMP_NUM_THREADSline was deleted rather than implemented, so nothing enforces it; (b) once fixed, the non-Slurm default silently becomesos.cpu_count()fork workers where the old default was 1 — with six-survey grids that's a large memory jump worth an explicit print. -
zdm/energetics.py:321(also ~453, ~611) —result = np.empty_like(Eth)is filled only through the four comparison masks. A NaN element ofEthfails every comparison, so its slot keeps uninitialized heap garbage. Grid thresholds can contain NaN (grid.py itself checks and warns for them), and with LF 0-3 a NaN propagates to NaN and is caught by thenp.isnan(llsum)guard — with LF 4/5/6 you instead get nondeterministic, silently wrong rates.np.full_like(Eth, np.nan)restores the old failure mode. -
papers/FitRepetition2025/slurm/run_mcmc.slurm:32,46— this new file is a byte-for-byte copy of the pre-fixzdm/scripts/slurm/run_mcmc.slurm: it references surveyDSA_34anddata/MCMC/params2.json, neither of which exists (the sibling copy was corrected toDSAin this same PR). As shipped, the paper-reproduction script fails at startup — and once fixed it hits crash #2 via--pwb.
Silent behavior changes — please confirm intent
-
zdm/MCMC.py:249-265— wheng0info is None,grid_kwargsstays{}, socalc_log_posterior's ownnz/ndm/zmax/dmmaxarguments (still in the signature, still forwarded bymcmc_runner) are silently ignored and the grid is built at the 500×1400 default. On main these were always passed. Either seedgrid_kwargsfrom the function arguments in theelsecase or drop the dead parameters. (Also: thezmax = zvals[-1] + dz/2reconstruction is exact only for linear grids — azlog=Trueg0info would reconstruct the wrong zmax.) -
zdm/scripts/run_slice.py:~90— the hard-codedparam_dictnow sets'lEmin': 30.0with the previous fitted value38.394...commented out on the same line, and the oldvals2=[39.0]override loop is gone (moved to the paper script). Every slice now runs with an effective minimum energy nine decades lower — if intentional, worth a comment; if leftover experimentation, worth restoring. -
zdm/energetics.py:58-60—SplineMin−6→−9 andNSpline1000→1500 move every knot of the igamma spline used by the default LF (2): existing fits re-evaluated on this branch will give slightly different likelihoods than main (no parameter changed), and each spline build gets ~70% more expensive (measured 0.14 s → 0.24 s of mpmath). Fine if deliberate — but see #9/#10, which multiply that cost. -
zdm/energetics.py:541(_broken_schechter_upper_gamma) — still no domain guard: the spline is tabulated on [1e-9, 1e6] and the shippedbreak_schechter.jsonpriors (lEb ≥ 36, lEmax ≤ 45) sit exactly at the 1e-9 boundary; any wider prior or directStatecall extrapolates the log-log cubic silently, and thenp.clip(result, 0, 1)at 623 hides the garbage. Validatexagainst10**SplineMin(the machinery already supportsreinit=Truere-tabulation), and demote the clip to a tolerance assertion. -
zdm/MCMC.py:375—energetics.reset()still runs unconditionally at the end of every posterior evaluation, so LF 2/6 runs rebuild the spline every step: 1500 mpmath calls ≈ 0.24 s per evaluation ≈ ~6.7 CPU-hours per 100k evaluations, even when the relevant gamma is not being sampled. Cache keyed on gamma (sparing unchanged keys inreset()), or build once inmcmc_runner.
Structural (carried over from #87, still open — fine as a follow-up PR)
- The LF integer codes are dispatched by magic number in four places that must stay in sync:
grid.init_luminosity_functions(plus twelve near-identical wrapper methods;_broken_schechter_paramsis body-identical to_broken_power_law_params),ConvertToMeaningfulConstant(iteration.py:1933 — whose finalelsesilently computes the gamma-function constant for any unknown code),valid_parameter_combination(MCMC.py:74), and the[1, 2, 6]Emax_boostlist (grid.py:841). One registry inenergetics—code → (functions, params-from-state, constraint, soft_cutoff)— collapses all four. - The
(ratio**gamma − 1)/gammahelper now exists in seven copies with inconsistent gamma≈0 tests (six use== 0,_broken_schechter_lower_integralusesnp.isclose), so LFs disagree about a sampled gamma of 1e-9. One module-level helper. - Constraint enforcement is still split:
valid_parameter_combinationreturns −inf in MCMC, while the energetics functionsraise ValueError— and the protectivetry/exceptincalc_log_posteriorremains commented out (MCMC.py:230), so any non-MCMC caller (a slice scan crossinglEb, cube building) crashes mid-run instead of scoring −inf. - The five
zdm/data/MCMC/*.jsonconfigs are near-copies already drifting (Sbackproject: truein two of five, with no indication whether that's deliberate); a shared base + per-model overrides would prevent silent divergence. papers/FitRepetition2025/run_slice_vs_emin.pyis a ~95% copy of the pre-cleanuprun_slice.py, keeping the deadplot_grids/commasep, ~35 lines of commented-out param dicts, theplot_slice-inside-mkdir quirk, and apkg_resourcesimport that is deprecated on the very Python (≥3.12) this PR now requires. Importinginit/calc_slice/plot_slicefrom the maintained script (or a shared module) keeps the paper reproducible without a fork. Also, passingg0infofrominit()intocalc_log_posteriorwould avoid rebuilding the analytic z-DM grid for every slice point in both scripts.
Tests
test_energetics.py and test_mcmc.py are genuinely useful additions — but note that all of them pass on this branch despite crashes 1-3, because none exercise ptauw, pwb, or a default mcmc_runner call. A smoke test that runs calc_log_posterior once with Pn=True, pwb=True, ptauw=True on a tiny survey, and one mcmc_runner(..., nsteps=1) with default nthreads, would have caught all three and will protect the slurm workflows in future merges.
Review prepared with Claude Code: multi-agent scan of the PR diff cross-checked against the closed PR #87 review; every blocking item was verified by hand at the PR head (the undefined names, the None comparison, the mask-fill gap, and the missing data files).
|
One addendum to my review, from a late-arriving check: |
This is an update featuring all goodies from Qin, but without bugs due to merging from main, and a couple of additions left over from pulling in repeaters